/* ========== GLOBAL LAYOUT & BASE COLORS ========== */
:root { --app-dvh: 100vh; }
:root { --app-dvh: 100svh; }

:root {
  /* Palette vento — sincronizzata con Windy/Ventusky (20 bin, km/h)
     Source of truth: vedi WIND_BINS (color-utils.js), WIND_SCALE (helpers/wind.php),
     WIND_GRADIENT_PALETTE (config.php). Modifica qui per restyle. */
  --wind-lvl-00:  #6271b7; /*   0–3    */
  --wind-lvl-04:  #3961a9; /*   4–10   */
  --wind-lvl-11:  #4a94a9; /*  11–17   */
  --wind-lvl-18:  #4d8d7b; /*  18–24   */
  --wind-lvl-25:  #53a553; /*  25–31   */
  --wind-lvl-32:  #359f35; /*  32–39   */
  --wind-lvl-40:  #a79d51; /*  40–46   */
  --wind-lvl-47:  #9f7f3a; /*  47–53   */
  --wind-lvl-54:  #a16c5c; /*  54–60   */
  --wind-lvl-61:  #813a4e; /*  61–67   */
  --wind-lvl-68:  #af5088; /*  68–75   */
  --wind-lvl-76:  #754a93; /*  76–85   */
  --wind-lvl-86:  #6d61a3; /*  86–96   */
  --wind-lvl-97:  #44698d; /*  97–103  */
  --wind-lvl-104: #5c9098; /* 104–129  */
  --wind-lvl-130: #7d44a5; /* 130–165  */
  --wind-lvl-166: #e7d7d7; /* 166–183  */
  --wind-lvl-184: #dbd487; /* 184–276  */
  --wind-lvl-277: #cdca70; /* 277–373  */
  --wind-lvl-374: #808080; /*   ≥374   */

  /* Alias di compatibilità (se altrove usi ancora --wind-c1..5) */
  --wind-c1: var(--wind-lvl-11);  /* brezza */
  --wind-c2: var(--wind-lvl-25);  /* moderato */
  --wind-c3: var(--wind-lvl-32);  /* teso (verde pieno) */
  --wind-c4: var(--wind-lvl-54);  /* forte */
  --wind-c5: var(--wind-lvl-97);  /* molto forte */

  /* APPLE WEATHER STYLE - Fase 1: Palette colori desaturati */
  /* Cieli sereni - Desaturati e naturali */
  --apple-sky-blue: #87ceeb;
  --apple-sky-light: #b0d4f1;
  --apple-sky-soft: #d5e9fb;

  /* Nuvoloso - Grigio soft */
  --apple-cloud-gray: #dfe6e9;
  --apple-cloud-light: #e8ebed;
  --apple-cloud-soft: #f1f2f5;

  /* Notte - Blu profondo */
  --apple-night-deep: #1a1a2e;
  --apple-night-blue: #16213e;
  --apple-night-soft: #0f3460;

  /* Sole - Giallo naturale */
  --apple-sun-yellow: #ffd93d;
  --apple-sun-light: #ffed4e;
  --apple-sun-soft: #fff3a0;

  /* Tramonto - Rosa pesca */
  --apple-sunset-pink: #ff9a9e;
  --apple-sunset-peach: #fad0c4;
  --apple-sunset-soft: #fbc2eb;

  /* Inverno - Blu ghiaccio */
  --apple-winter-blue: #a2d2ff;
  --apple-winter-light: #b8d4ff;
  --apple-winter-soft: #cfe2ff;

  /* Estate - Blu cristallino */
  --apple-summer-blue: #5dade2;
  --apple-summer-light: #85c1e9;
  --apple-summer-soft: #aed6f1;

  /* Effetti glass (Fase 2) */
  --apple-glass-bg: var(--white-08);
  --apple-glass-border: var(--white-12);
  --apple-glass-hover: var(--white-12);

  /* ===== COLORI BASE CON OPACITÀ ===== */
  /* Bianco con opacità */
  --white-100: #fff;
  --white-98: rgba(255, 255, 255, 0.98);
  --white-95: rgba(255, 255, 255, 0.95);
  --white-92: rgba(255, 255, 255, 0.92);
  --white-90: rgba(255, 255, 255, 0.90);
  --white-88: rgba(255, 255, 255, 0.88);
  --white-85: rgba(255, 255, 255, 0.85);
  --white-80: rgba(255, 255, 255, 0.80);
  --white-78: rgba(255, 255, 255, 0.78);
  /* Margine interno dei widget, ripreso dalle hero (22/10/2026). */
  --widget-pad: 12px;
  --white-75: rgba(255, 255, 255, 0.75);
  --white-70: rgba(255, 255, 255, 0.70);
  --white-65: rgba(255, 255, 255, 0.65);
  --white-60: rgba(255, 255, 255, 0.60);
  --white-55: rgba(255, 255, 255, 0.55);
  --white-50: rgba(255, 255, 255, 0.50);
  --white-45: rgba(255, 255, 255, 0.45);
  --white-40: rgba(255, 255, 255, 0.40);
  --white-35: rgba(255, 255, 255, 0.35);
  --white-32: rgba(255, 255, 255, 0.32);
  --white-30: rgba(255, 255, 255, 0.30);
  --white-25: rgba(255, 255, 255, 0.25);
  --white-22: rgba(255, 255, 255, 0.22);
  --white-20: rgba(255, 255, 255, 0.20);
  --white-18: rgba(255, 255, 255, 0.18);
  --white-16: rgba(255, 255, 255, 0.16);
  --white-15: rgba(255, 255, 255, 0.15);
  --white-12: rgba(255, 255, 255, 0.12);
  --white-10: rgba(255, 255, 255, 0.10);
  --white-08: rgba(255, 255, 255, 0.08);
  --white-06: rgba(255, 255, 255, 0.06);
  --white-05: rgba(255, 255, 255, 0.05);
  --white-04: rgba(255, 255, 255, 0.04);
  --white-03: rgba(255, 255, 255, 0.03);
  --white-02: rgba(255, 255, 255, 0.02);

  /* Nero con opacità */
  --black-90: rgba(0, 0, 0, 0.90);
  --black-78: rgba(0, 0, 0, 0.78);
  --black-60: rgba(0, 0, 0, 0.60);
  --black-45: rgba(0, 0, 0, 0.45);
  --black-38: rgba(0, 0, 0, 0.38);
  --black-35: rgba(0, 0, 0, 0.35);
  --black-32: rgba(0, 0, 0, 0.32);
  --black-30: rgba(0, 0, 0, 0.30);
  --black-28: rgba(0, 0, 0, 0.28);
  --black-25: rgba(0, 0, 0, 0.25);
  --black-24: rgba(0, 0, 0, 0.24);
  --black-22: rgba(0, 0, 0, 0.22);
  --black-20: rgba(0, 0, 0, 0.20);
  --black-18: rgba(0, 0, 0, 0.18);
  --black-15: rgba(0, 0, 0, 0.15);
  --black-12: rgba(0, 0, 0, 0.12);
  --black-10: rgba(0, 0, 0, 0.10);
  --black-06: rgba(0, 0, 0, 0.06);
  --black-05: rgba(0, 0, 0, 0.05);
  --black-04: rgba(0, 0, 0, 0.04);

  /* ===== COLORI SEMANTICI ===== */
  --color-success: #10b981;
  --color-success-dark: #059669;
  --color-warning: #f59e0b;
  --color-warning-dark: #d97706;
  --color-danger: #ef4444;
  --color-danger-dark: #dc2626;
  --color-info: #3b82f6;
  --color-info-dark: #2563eb;
  --color-muted: #6b7280;
  --color-muted-light: #9ca3af;

  /* ===== BREAKPOINTS (documentazione - usare valori in @media) ===== */
  /* Mobile small:  360px  - iPhone SE, piccoli Android */
  /* Mobile:        375px  - iPhone standard */
  /* Mobile large:  430px  - iPhone Pro Max */
  /* Tablet:        768px  - iPad portrait */
  /* Desktop:      1024px  - iPad landscape, laptop */
  /* Desktop lg:   1280px  - Desktop standard */
  /* Desktop xl:   1536px  - Desktop large */

  /* APPLE WEATHER STYLE - Fase 3: Animazioni e transizioni */
  /* Timing functions Apple - Curva di Bezier naturale e fluida */
  --apple-easing: cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --apple-easing-in: cubic-bezier(0.42, 0, 1, 1);
  --apple-easing-out: cubic-bezier(0, 0, 0.58, 1);
  --apple-easing-in-out: cubic-bezier(0.42, 0, 0.58, 1);

  /* Durate transizioni Apple */
  --apple-duration-fast: 150ms;
  --apple-duration-normal: 300ms;
  --apple-duration-slow: 500ms;
  --apple-duration-slower: 800ms;

  /* Fallback pieno dei widget: il gradiente completo viene applicato alle card
     più sotto; questa tinta copre browser senza color-mix o gradienti CSS. */
  --widget-bg-solid: color-mix(in srgb, var(--meteo-color, #5393C8) 55%, #000);

  /* Larghezza massima della chrome flottante. La leggono la navbar e la riga
     bassa dei pannelli mappa: erano due misure separate e su desktop divergevano
     (a 1280px la navbar si fermava a 1100, il player del radar arrivava a 1250). */
  --chrome-max-width: 1100px;
  /* Bordo sinistro della chrome flottante, in coordinate viewport: 10px finche'
     c'e' spazio, poi il margine che centra un blocco largo --chrome-max-width.
     E' la stessa geometria che la navbar ottiene con left:50% + translateX(-50%),
     che qui NON si puo' usare: il containing block di un .mappa-control e'
     l'angolo .mappa-bottom, che e' dimensione-contenuto, non il viewport. */
  --chrome-edge: max(10px, calc((100vw - var(--chrome-max-width)) / 2));
  /* Margine laterale delle card sul tablet, in entrambi gli orientamenti. */
  --tablet-bordo: 40px;
  /* Barra in basso a pillola (22/10/2026, stile Instagram): rientra rispetto
     ai widget e non si allarga oltre il necessario per cinque voci. Non segue
     piu' --chrome-max-width: in mappa il player del radar le passa sopra largo. */
  --nav-inset: 20px;
  --nav-max-width: 440px;

  /* ===== TYPOGRAPHY TOKENS (consolidamento CSS 2026-05-01) ===== */
  /* Font weights — regular, medium, semibold, bold */
  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-bold: 700;

  /* Font sizes — rem su html 100% (16px). Dynamic Type. Micro-floor xs/sm. */
  --fs-xs: 0.6875rem;   /* 11px (floor da 10) */
  --fs-sm: 0.75rem;     /* 12px (floor da 11) */
  --fs-base: 0.75rem;   /* 12px */
  --fs-md: 0.8125rem;   /* 13px */
  --fs-lg: 0.875rem;    /* 14px */
  --fs-xl: 1rem;        /* 16px */
  --fs-2xl: 1.125rem;   /* 18px */
  --fs-3xl: 1.25rem;    /* 20px */
  --fs-4xl: 1.375rem;   /* 22px */
  --fs-5xl: 1.5rem;     /* 24px */
  --fs-6xl: 1.75rem;    /* 28px */
  --fs-7xl: 2rem;       /* 32px */

  /* Hero typography */
  --hero-text-shadow: 0 1px 4px var(--black-12);

  /* Spacing — base 4px */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-8: 32px;
  --sp-10: 40px;

  /* Border radius */
  --r-sm: 4px;
  --r-md: 8px;
  --r-lg: 12px;
  --r-xl: 16px;
  --r-2xl: 20px;
  --r-pill: 999px;

  /* ===== BREAKPOINT TOKENS (documentazione, usare in @media) ===== */
  /* iPhone 5/SE base   320px */
  /* iPhone 6/7/8/SE2   375px */
  /* iPhone 12/13/14 Pro 390px */
  /* iPhone XR/11/Plus  414px */
  /* iPhone 15 Pro Max  430px */
  /* iPad mini          744px */
  /* iPad Air           820px */
  /* iPad Pro 11"      1024px */
  /* Desktop large     1366px */

  /* Larghezza delle hero da 768px in su: quella delle card (23/10/2026, provata
     sull'iPad Pro 11). 640 fissi e poi 58vw con tetto a 960 lasciavano la hero
     stretta in mezzo a card larghe 1500. */
  --hero-larghezza: 100%;
}

/* Weather background gradient transition */
.weather-background {
  transition: background var(--apple-duration-slower) var(--apple-easing);
  position: relative;
}

/* ========== APPLE DAWN/DUSK OVERLAYS - Universal System ==========
   INERTE dal 2026-07-22: il wash alba/tramonto e' cotto dentro --meteo-gradient
   dal motore (applyTimeWash + TIME_WASH_STOPS in weather-gradient-engine.js,
   che replicano 1:1 i valori qui sotto).

   Perche': queste regole usano mix-blend-mode (soft-light / overlay). Un layer
   con blend non-normal promuove lo sfondo meteo in un gruppo composito che il
   backdrop-filter delle superfici UI non campiona piu' -> ad alba/tramonto il vetro
   delle card sfocava il vuoto. Le card ora sono solide; il blur resta solo sulle
   superfici tecniche quando il profilo performance lo consente.
   blur 8px 4.19 contro blur 0 4.17 = blur inerte; con overlay nascosto 2.16.

   Il display:none e' il punto unico di spegnimento: le classi continuano a
   essere messe da DUE manager distinti (weather-fx/managers/dawn-dusk-overlay.js
   e la copia dentro weather-fx/weather-fx-integration.js), quindi neutralizzarli
   in JS avrebbe richiesto due modifiche e ne sarebbe bastata una dimenticata per
   riportare il blend. Le regole restano come riferimento dei valori bakeati.
   NB: non basta togliere il background — mix-blend-mode su un elemento anche
   trasparente crea comunque il gruppo composito. */
.weather-time-overlay {
  display: none;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--apple-duration-slower) var(--apple-easing);
  /* Sopra gradient + depth + clouds, sotto canvas (particelle) */
  z-index: 6;
}

.weather-time-overlay.active {
  opacity: 1;
}

/* Dawn Overlay (Alba) - Rosa pesca caldo, arancio soft */
.weather-time-overlay.dawn {
  background: linear-gradient(
    180deg,
    rgba(255, 190, 155, 0.24) 0%,      /* Albicocca soft */
    rgba(255, 178, 150, 0.20) 28%,     /* Rosa pesca tenue */
    rgba(255, 170, 145, 0.16) 52%,     /* Calore basso, meno saturo */
    rgba(250, 208, 196, 0.13) 78%,     /* Rosa pesca chiaro */
    rgba(235, 215, 245, 0.07) 100%     /* Lavanda molto soft */
  );
  mix-blend-mode: soft-light;
}

/* Dawn Overlay - Variante estiva (più calda) */
.weather-time-overlay.dawn.summer {
  background: linear-gradient(
    180deg,
    rgba(255, 205, 175, 0.28) 0%,
    rgba(255, 190, 165, 0.23) 32%,
    rgba(255, 180, 155, 0.18) 62%,
    rgba(250, 214, 206, 0.13) 86%,
    rgba(238, 220, 246, 0.06) 100%
  );
}

/* Dawn Overlay - Variante invernale (più fredda, meno satura) */
.weather-time-overlay.dawn.winter {
  background: linear-gradient(
    180deg,
    rgba(235, 185, 175, 0.20) 0%,
    rgba(228, 176, 170, 0.17) 32%,
    rgba(222, 168, 164, 0.14) 62%,
    rgba(225, 196, 192, 0.11) 86%,
    rgba(220, 210, 220, 0.06) 100%
  );
}

/* Dusk Overlay (Tramonto) - Rosa/viola drammatico, arancio intenso */
.weather-time-overlay.dusk {
  background: linear-gradient(
    180deg,
    rgba(255, 170, 165, 0.24) 0%,      /* Rosa corallo soft */
    rgba(250, 212, 200, 0.20) 22%,     /* Pesca tenue */
    rgba(244, 206, 232, 0.17) 44%,     /* Lavanda rosata */
    rgba(170, 160, 206, 0.14) 66%,     /* Viola desaturato */
    rgba(150, 140, 190, 0.10) 84%,     /* Viola profondo soft */
    rgba(132, 122, 176, 0.07) 100%     /* Viola scuro, quasi impercettibile */
  );
  mix-blend-mode: soft-light;
}

/* Dusk Overlay - Variante estiva (più vibrante) */
.weather-time-overlay.dusk.summer {
  background: linear-gradient(
    180deg,
    rgba(255, 176, 170, 0.28) 0%,
    rgba(250, 214, 206, 0.23) 26%,
    rgba(244, 206, 232, 0.20) 46%,
    rgba(170, 160, 206, 0.15) 68%,
    rgba(150, 140, 190, 0.11) 86%,
    rgba(122, 112, 170, 0.07) 100%
  );
}

/* Dusk Overlay - Variante invernale (più tenue) */
.weather-time-overlay.dusk.winter {
  background: linear-gradient(
    180deg,
    rgba(232, 168, 165, 0.21) 0%,
    rgba(235, 206, 200, 0.18) 26%,
    rgba(232, 198, 224, 0.15) 46%,
    rgba(170, 166, 202, 0.12) 68%,
    rgba(160, 154, 192, 0.09) 86%,
    rgba(148, 142, 178, 0.05) 100%
  );
}

/* Overlay per condizioni meteo intense (temporale, pioggia forte) */
/* Usa overlay mode per maggiore drammaticità */
.weather-time-overlay.intense {
  mix-blend-mode: overlay;
  opacity: 0.7;
}

/* Overlay per condizioni meteo soft (nebbia, nuvoloso) */
/* Usa screen mode per effetto più tenue */
.weather-time-overlay.soft {
  /* Su nuvoloso/pioggia lo screen tende a "sparire": soft-light è più naturale e visibile */
  mix-blend-mode: soft-light;
  opacity: 0.50;
}

/* Accessibility: Rispetta preferenze utente per reduced motion */
html {
  box-sizing: border-box;
}

html, body {
  height: 100%;
  overscroll-behavior-y: none;
  /* Disable text selection to prevent accidental selection during touch gestures */
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none; /* Disable iOS callout menu on long-press */
 }

*,
*::before,
*::after {
  box-sizing: inherit;
}

body > main {
  min-height: var(--app-dvh, 100dvh);
}

/* ========== MAIN CONTENT - View Transition Animations ========== */
#main-content {
  opacity: 1;
  overflow-x: hidden;
  /* Transition will be set dynamically by JS during view changes */
}

/* Support for prefers-reduced-motion (accessibility) */
@media (prefers-reduced-motion: reduce) {
  #main-content {
    opacity: 1 !important;
  }
}

/* Ancora rem per Dynamic Type: 100% = 16px browser. Bump solo tablet (vedi sotto). */
html { font-size: 100%; }
/* Bump tipografico responsive (Apple Dynamic Type): solo tablet+, phone resta 100%. */
@media (min-width: 768px)  { html { font-size: 106.25%; } } /* 17px root */
@media (min-width: 1024px) { html { font-size: 112.5%;  } } /* 18px root */

body {
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
   Roboto, Helvetica, Arial, sans-serif;
  font-size: var(--fs-base);
  color: #fff;
  min-height: 100vh;
  background-color: #1b425c;
  overflow-anchor: none;
  padding-top: 0 !important;
  padding-bottom: 0 !important;
  scrollbar-width: none;      /* Firefox - hide scrollbar */
}

/* Chrome, Safari, Edge - hide scrollbar */
body::-webkit-scrollbar {
  display: none;
}

/* FIX TASK NT-20: Variabili globali per le safe areas (iOS notch/dynamic island) */
:root {
  /* Safe area insets - iOS notch, dynamic island, home indicator */
  /* iOS 27+ disegna uno scrim di sistema sopra la status bar nelle PWA
     standalone: si somma alla safe area e, senza margine, copre location bar
     e nastro bussola. L'extra vale 0 ovunque tranne li'. */
  --ios-scrim-extra: 0px;
  --safe-top: calc(env(safe-area-inset-top, 0px) + var(--ios-scrim-extra));
  --safe-right: env(safe-area-inset-right, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);

  /* Padding effettivo che vogliamo garantire (minimo 5px anche senza safe-area) */
  --ui-bottom-pad: 5px; /* fallback legacy: max() non supportato su iOS <13.4 */
  --ui-bottom-pad: max(5px, var(--safe-bottom));
  --ui-top-pad: 0px;
  --ui-top-pad: max(0px, var(--safe-top));

  /* Padding laterale per landscape mode con notch laterale */
  --ui-left-pad: 0px;
  --ui-left-pad: max(0px, var(--safe-left));
  --ui-right-pad: 0px;
  --ui-right-pad: max(0px, var(--safe-right));
}

/* Solo PWA installata su iOS 27+: lo scrim di sistema sfuma sopra la status
   bar e va scavalcato abbassando il contenuto in cima. Il valore e' TARATO A
   SCHERMO su iPhone 15 Pro Max iOS 27.0 (safe area 59px): a 40px il contenuto
   scendeva troppo, a 28px la sfumatura mangiava ancora il bordo alto (17/09),
   30px e' il punto in cui le etichette escono pulite. Unico numero da
   ritoccare: tutto cio' che sta in cima deve leggere `--safe-top`, non
   `env(safe-area-inset-top)`, o resta sotto lo scrim. La classe la mette la shell
   (`partials/common/header.php`), non il CSS: non esiste media query per la
   versione di iOS. */
html.ios-scrim-alto {
  --ios-scrim-extra: 30px;
}

/* ================= LOW POWER OVERRIDES ================= */

/* FIX TASK NT-34: Box-Shadow CSS Custom Properties for Consolidation */
:root {
  /* Common shadow patterns (reduces CSS by ~2-3KB) */
  --shadow-none: none;
  --shadow-subtle: 0 1px 3px var(--black-12);
  --shadow-sm: 0 2px 4px var(--black-20);
  --shadow-md: 0 2px 6px var(--black-25);
  --shadow-lg: 0 3px 8px var(--black-30);
  --shadow-card: 0 2px 8px var(--black-10);
  --shadow-elevated: 0 6px 18px rgba(16, 28, 48, 0.12);
  --shadow-popup: 0 4px 12px var(--black-15);
  --shadow-inset: 0 0 0 1px var(--black-35);
}

.offcanvas:not(.show),
.search-panel:not(.show) {
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}

/* Reduced-motion: disattiva animazioni/transizioni globalmente + azzera blur */
@media (prefers-reduced-motion: reduce) {
  * {
    animation: none !important;
    transition: none !important;
  }
}
/* Gli spinner veri restano animati: dicono che qualcosa sta arrivando. */
html[data-power="low"] *:not(canvas, svg, video, .loader-spinner, .chart-loading-spinner, .modello-pro-loader, .spinner-border),
body.battery-saver *:not(canvas, svg, video, .loader-spinner, .chart-loading-spinner, .modello-pro-loader, .spinner-border) {
  animation: none !important;
  transition: none !important;
}

/* Reduced-transparency (Apple §14): via il blur, chrome flottante solidificata */
@media (prefers-reduced-transparency: reduce) {
  * {
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
  .navbar-bottom-nav {
    background-color: var(--widget-bg-solid, rgb(18 34 50 / 94%)) !important;
    background-image: none !important;
  }
  .search-panel { background: rgb(117 126 140 / 96%) !important; }
  .app-menu-panel { background: rgb(117 126 140 / 96%) !important; }
}

/* Low-power: riduci ombre/filtri superflui */
html[data-power="low"] .widget {
  box-shadow: var(--shadow-none) !important;
}
html[data-power="low"] .weather-svg-icon,
html[data-power="low"] .widget .weather-svg-icon,
html[data-power="low"] .widget-weather-icon-small {
  filter: none !important;
}




/* Velo di avvio — markup e spegnimento in partials/common/header.php.
   Copre il primo paint: sotto, il gradiente meteo puo' comparire senza che si
   veda il passaggio dal fondo fisso della shell. Sopra ogni cosa, anche il
   loader delle view (2000), perche' e' la schermata di avvio. */
#boot-veil {
  position: fixed;
  inset: 0;
  z-index: 2600;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #0c2a41; /* stesso fondo di .weather-background: nessun colore nuovo */
  opacity: 1;
  transition: opacity 0.5s cubic-bezier(0.4, 0, 0.2, 1);
  pointer-events: none;
}

/* Lo spinner entra solo se l'avvio dura: su una partenza veloce lampeggerebbe. */
#boot-veil .loader-spinner {
  opacity: 0;
  animation: spin 1s linear infinite, boot-veil-spinner 0.25s ease 500ms forwards;
}

#boot-veil.boot-veil--via {
  opacity: 0;
}

@keyframes boot-veil-spinner {
  to {
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  #boot-veil {
    transition: none;
  }
  #boot-veil .loader-spinner {
    animation: none;
    opacity: 1;
  }
}
.loader-spinner {
  width: 54px;
  height: 54px;
  border: 7px solid #2196f3;
  border-top-color: #1976d2;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  /* box-shadow: 0 0 10px #1976d2; */
  box-shadow: none;
  border-width:6px;
}
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* ========== WEATHER BACKGROUND ========== */
.bg-paused .weather-overlay { animation-play-state: paused !important; }

html[data-power="low"] .weather-overlay {
  animation: none !important;
  opacity: 0.45;
}
@media (prefers-reduced-motion: reduce) {
  .weather-overlay {
    opacity: 0.45; /* leggera riduzione per coerenza visiva */
  }
}

.weather-background {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  pointer-events: none;
  z-index: 0;
  overflow: hidden;
  isolation: isolate;
  background: #0c2a41;
  contain: size layout style;
}

.weather-background::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 5; /* sopra clouds/overlay, sotto canvas */
  pointer-events: none;
  background: linear-gradient(
    180deg,
    rgba(0, 0, 0, var(--meteo-contrast-top, 0)) 0%,
    rgba(0, 0, 0, var(--meteo-contrast-mid, 0)) 42%,
    rgba(0, 0, 0, 0) 100%
  );
  transition: background 1.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.weather-gradient {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  background: var(--meteo-gradient, linear-gradient(180deg, #1565C0 0%, #0D47A1 45%, #0A3A7C 100%));
  /*animation: skyBreath 19s ease-in-out infinite;*/
  transition: background 1.3s cubic-bezier(0.4, 0, 0.2, 1), opacity .6s ease;
  pointer-events: none;
  /* Evita filter fullscreen di default (costoso su GPU): il look è gestito dal motore gradienti */
  filter: none;
  contain: paint;
}

.weather-canvas {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 7;  /* Sopra time-overlay e clouds */
  display: block;
  pointer-events: none;
  contain: paint;
}

.weather-depth {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 3;
  pointer-events: none;
  background: var(--meteo-overlay, none);
  mix-blend-mode: normal;
  opacity: 1;
  transition: opacity 0.8s ease, background 1.5s cubic-bezier(0.4, 0, 0.2, 1);
  will-change: opacity, background;
  backface-visibility: hidden;
  contain: strict;
}

.weather-overlay {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 4;
  pointer-events: none;
  opacity: 0.6;
  contain: paint;
  /* Velo di foschia. Sotto le nuvole il cielo e' vuoto e l'attacco si vedeva:
     non come un salto di luminanza (li' eravamo gia' nei numeri di Apple) ma
     come una FRANGIA frastagliata — il bordo dell'alpha degli asset — a una
     quota precisa. Gli asset una coda ce l'hanno gia' (l'alpha scende dal 50%
     del picco a zero nell'8-24% della propria altezza), ma finisce e sotto non
     c'e' piu' niente. Questa maschera la allunga: energia di frangia nella
     fascia 20-52vh **-22%**, corpo delle nuvole invariato (0/-1%).
     Le due quote non sono libere: resta piena fino a 16vh, cioe' sopra il
     bordo alto di OGNI riquadro (il piu' basso e' a 9,5vh), e arriva a zero a
     54vh, oltre il p90 dei bordi inferiori (46,4vh). Rampe piu' aggressive
     tolgono piu' frangia ma spengono le nuvole: il salto nuvola-cielo sulla
     fascia 2-35vh passa da 90/89 a 80/83 con questa (Apple, La Chapelle: 81),
     e scenderebbe a 75/79 o 68/74 con le due varianti provate.
     Nessun colore: la nuvola si dissolve nel cielo che ha dietro, quindi vale
     di giorno, di notte e al tramonto senza saperne nulla. La `-webkit-` serve
     a Chrome < 120; dove manca del tutto si ricade sul comportamento di prima,
     che e' una degradazione, non una rottura. Contratto:
     `_dev/tests/nuvole-velo.test.js`. */
  -webkit-mask-image: linear-gradient(to bottom,
    #000 0, #000 16vh,
    rgba(0, 0, 0, 0.86) 26vh,
    rgba(0, 0, 0, 0.58) 36vh,
    rgba(0, 0, 0, 0.26) 45vh,
    transparent 54vh);
  mask-image: linear-gradient(to bottom,
    #000 0, #000 16vh,
    rgba(0, 0, 0, 0.86) 26vh,
    rgba(0, 0, 0, 0.58) 36vh,
    rgba(0, 0, 0, 0.26) 45vh,
    transparent 54vh);
}

/* Nuvole di notte. La classe `night` la porta il BODY (weather-fx-loader), non
   l'overlay: la vecchia regola `.weather-overlay.night` non ha mai agito e di
   notte le nuvole restavano al valore diurno. Misurato sui riferimenti Apple
   notturni, la nuvola sta 16-37 punti di luminanza sopra il cielo (Jinzhong
   36,8 - Tokyo 33,2 - Kaunas 16,2); da noi ne stava 98-121. A 0.15 il salto
   torna a 30-40. Due selettori perche' i due pittori del cielo marcano il body
   in modo diverso: `night` da weather-fx-loader, `meteo-time-night` dal
   WeatherGradientManager. */
body.night .weather-overlay,
body.meteo-time-night .weather-overlay {
  opacity: 0.15;
}

/* ========== CLOUDS PARALLAX (multi-layer) ========== */
/* Attivato solo quando BackgroundManager applica più immagini cloud */
.weather-overlay.clouds-anim {
  animation: clouds-drift var(--cloud-drift-duration, 30s) ease-in-out infinite alternate;
}

@keyframes clouds-drift {
  from { background-position: var(--cloud-pos-start); }
  to { background-position: var(--cloud-pos-end); }
}

/* Disabilita drift clouds quando low-power / reduced-motion */
html[data-power="low"] .weather-overlay.clouds-anim {
  animation: none !important;
}
/* GPU optimization: applica compositing solo quando serve (animazioni attive) */
.weather-background.is-animating .weather-gradient,
.weather-background.is-animating .weather-canvas,
.weather-background.is-animating .weather-depth,
.weather-background.is-animating .weather-overlay {
  will-change: opacity, transform;
  backface-visibility: hidden;
  transform: translateZ(0);
}
.weather-background:not(.is-animating) .weather-gradient,
.weather-background:not(.is-animating) .weather-canvas,
.weather-background:not(.is-animating) .weather-depth,
.weather-background:not(.is-animating) .weather-overlay {
  will-change: auto;
  transform: none;
}

/* Content sopra weather-bg */
body > .container-custom,
body > .container-fluid,
body > main,
body > section,
body > .navbar,
body > header {
  position: relative;
  z-index: 20;
}

/* Gradienti meteo gestiti via custom property (Task NT-4). */

/* ======= REMOVED: Legacy .weather-overlay.meteo-XX classes (~530 lines) =======
 * These classes were part of the old gradient system and are never applied by the
 * parametric gradient system. All background styles are now applied inline via
 * JavaScript in weather-background.js _applyCloudImages() method.
 * Removed: meteo-1, 2, 3, 45, 48, 51, 53, 55, 61, 63, 65, 66, 67, 71, 73, 75,
 *          77, 80, 81, 82, 85, 86, 95, 96, 99 and all related @keyframes animations
 *
 * NOTE: .weather-gradient.sunset::before and .sunrise::before removed (2026-01-22)
 *       These were never activated - buildCssClasses() never called.
 *       Dawn/dusk effects handled by .weather-time-overlay system instead.
 */

/* ========== MAIN VIEW ========== */
.container-custom {
  padding: 0 10px;
  max-width: 980px;
  margin: auto;
  position: relative;
  z-index: 10;
  /* Pill flottante: ~65px navbar + 12px margin + safe-area + 20px aria respiro = ~95px */
  padding-bottom: calc(95px + var(--safe-bottom));
}

body.view-mappa #weatherBg,
body.view-mappa #weatherOverlay,
body.view-mappa .location-bar {
  display: none !important;
}

body.view-mappa .container-custom {
  padding: 0;
}

/* Vars di default (verranno sovrascritte via JS) */
#stazioni-map {
  --top: 0px; /* altezza location-bar */
  --bottom: var(--nav-h, 0px); /* altezza navbar */
  --app-dvh: 100vh; /* fallback legacy */
  --app-dvh: 100dvh; /* override moderno */
}

/* FIX TASK NT-20: Map container con safe-area completo (verticale + laterale) */
#stazioni-map .mappa-map-widget,
#map-container {
  /* Safe-area verticale: top + bottom */
  block-size: calc(
    var(--app-dvh, 100dvh) - var(--top) - var(--bottom) - var(--safe-top) - var(--safe-bottom)
  );
  min-block-size: 320px; /* sicurezza su schermi piccolissimi */
  /* Safe-area laterale per landscape mode */
  padding-left: var(--safe-left);
  padding-right: var(--safe-right);
}

/* Previeni FOUC durante inizializzazione mappa */
/* TEMPORANEAMENTE DISABILITATO - DEBUG MAPPA INVISIBILE */
/* #stazioni-map {
  opacity: 0;
  transition: opacity 0.4s ease-in-out;
}

#stazioni-map.map-ready {
  opacity: 1;
} */

/* Nascondi layer control durante init per evitare flash */
#stazioni-map:not(.map-ready) .mappa-control-layers {
  opacity: 0 !important;
  pointer-events: none;
}

/* Nascondi layer control quando c'è il loader mappa locale */
/* #stazioni-map.map-busy .mappa-control-layers {
  opacity: 0 !important;
  pointer-events: none !important;
} */

/* Nascondi sempre il control layers quando loader globale è attivo */
.app-busy #stazioni-map .mappa-control-layers {
  opacity: 0 !important;
  pointer-events: none !important;
}

/* Barra di caricamento layer mappa (vento, marea, onde, radar, init).
   Sostituisce l'overlay scuro + spinner: 2px in cima al container, non copre
   la mappa e non intercetta i tap. Riempimento gestito da LoaderManager
   (ui-helpers.js): il progresso reale non e' noto, avanza fino al 92% e
   chiude a 100% quando l'ultima chiave si libera. */
#stazioni-map .map-progress {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  pointer-events: none;
  opacity: 0;
}

#stazioni-map .map-progress.is-active {
  opacity: 1;
}

/* Ritardo sulla dissolvenza: prima si vede la barra chiudere a 100% */
#stazioni-map .map-progress.is-done {
  opacity: 0;
  transition: opacity 0.25s ease 0.12s;
}

#stazioni-map .map-progress__bar {
  width: 0;
  height: 100%;
  border-radius: 0 2px 2px 0;
  background: linear-gradient(90deg, rgba(11, 132, 255, 0.45), #0b84ff);
  box-shadow: 0 0 6px rgba(11, 132, 255, 0.55);
  transition: width 0.32s var(--apple-easing);
}

/* FIX TASK NT-20: Body padding laterale per safe-area landscape (notch laterale iPhone) */
/* NB: padding-bottom resta 0 (reset sopra, :389) — clearance navbar fixed-bottom
   è gestita da .container-custom (calc(95px + safe-bottom)), non dal body. */
body {
  padding-left: var(--safe-left);
  padding-right: var(--safe-right);
}

/* ========== LOCATION BAR ========== */
/* FIX TASK NT-20: Location bar con safe-area completo (top + laterale) */
.location-bar {
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;
  color: var(--white-100);
  padding-bottom: 20px;
  /* Safe-area: minimo 12px o safe-top se maggiore */
  padding-top: 12px !important; /* fallback legacy */
  padding-top: max(12px, var(--safe-top)) !important;
  /* Safe-area laterale per landscape mode */
  padding-left: var(--safe-left);
  padding-right: var(--safe-right);
}
/* iOS 12: gap non funziona in flexbox, uso margin */
.location-bar > * + * { margin-left: 10px; }

/* In PWA (standalone) usa solo la safe-area reale senza minimo */
@media (display-mode: standalone) {
  .location-bar {
    padding-top: var(--ui-top-pad) !important;
  }
}

.location-bar .loc-labels {
  text-align: right;
  line-height: 125%;
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  max-width: 230px;
}

.location-bar .loc-labels .loc-name-wrapper {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  width: 100%;
}
.location-bar .loc-labels .loc-name-wrapper > * + * { margin-top: 2px; }

.location-bar .loc-labels .loc-name-row {
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  min-width: 0;
  max-width: 100%;
}

.location-bar .loc-favorite-btn {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--white-75);
  padding: 0 5px 0 0;
  line-height: 1;
  flex: 0 0 auto;
}

.location-bar .loc-favorite-btn .ic-star.ic-piena {
  color: #ffe598;
}

.location-bar .loc-favorite-btn:disabled {
  opacity: .45;
}

.location-bar .loc-labels .loc-name {
  font-size: var(--fs-sm);
  display: inline-flex;
  align-items: baseline;
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
}

.location-bar .loc-labels .loc-name::before {
  content: attr(data-location);
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1 1 auto;
  min-width: 0;
  margin-right: 5px;
}

.location-bar .loc-labels .loc-elev {
  color: var(--white-75);
  font-size: var(--fs-sm);
  flex-shrink: 0;
  white-space: nowrap;
}

.location-bar .loc-labels .loc-update-time {
  color: var(--white-75);
  font-size: var(--fs-xs);
  display: block;
}

.location-bar .loc-labels .update-time {
  font-size: var(--fs-xs);
}

/* Badge del modello meteo, appena prima dell'orario e dentro lo stesso span:
   tutti gli scrittori JS toccano .update-time con textContent, mai il
   contenitore, quindi un fratello prima di quello sopravvive agli aggiornamenti.
   Il separatore e' un ::after, non un nodo di testo. */
.location-bar .loc-labels .loc-modello {
  font-size: var(--fs-xs);
  color: var(--white-75);
  white-space: nowrap;
}
.location-bar .loc-labels .loc-modello::after {
  content: " \00b7 ";
}

.location-bar .loc-labels .update-time.ok {
  /* color: #198754; /* verde bootstrap */ */
}
.location-bar .loc-labels .update-time.offline {
  color: rgba(144, 0, 14, 0.39); /* rosso */
  color: rgb(144 0 14 / 39%); /* rosso */
}
.location-bar .loc-labels .update-time.stale {
  color: #ffe598; /* giallo */
}

.location-bar .loc-actions {
  display: flex;
  flex-shrink: 0;
  align-items: center;
}
.location-bar .loc-actions > * + * { margin-left: 5px; }

.location-bar .loc-actions a,
.location-bar .loc-actions button {
  /* Misura fissa, pari a quella col font delle icone caricato: senza, finche'
     il font delle icone non arriva il bottone prende la misura del glifo di
     ripiego e poi scatta. Stessa cosa nei blocchi 768 e 1024. */
  width: 30px;
  height: 30px;
  color: var(--white-85);
  text-decoration: none;
  padding: 8px;
  border-radius: var(--r-sm);
  background-color: var(--ui-panel-bg, rgb(38 54 76 / 90%));
  line-height: 100%;
  font-size: var(--fs-lg);
  flex-shrink: 0;
  border: none;
  cursor: pointer;
  font-family: inherit;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.location-bar .loc-actions a:hover,
.location-bar .loc-actions button:hover {
  background-color: var(--white-30);
}

/* Ottimizzazioni per schermi molto piccoli (iPhone 5/SE) — solo size/spacing.
   Override su font-size .dfr-* spostato in fondo file per source-order. */
@media (max-width: 374px) {
  .location-bar > * + * { margin-left: 8px; }

  .location-bar .loc-actions a,
  .location-bar .loc-actions button {
    padding: 6px;
  }
}

/* FIX TASK NT-20: Search panel offcanvas con safe-area completo */
.search-panel {
  height: calc(100vh - var(--safe-top)) !important;
  height: calc(100dvh - var(--safe-top)) !important;
  padding-top: calc(35px + var(--safe-top)) !important;
  /* Safe-area laterale per landscape mode */
  padding-left: 10px !important; /* fallback legacy */
  padding-left: max(10px, var(--safe-left)) !important;
  padding-right: 10px !important;
  padding-right: max(10px, var(--safe-right)) !important;
  background-color: rgb(117 126 140 / 92%);
  background-image:
    linear-gradient(rgb(0 0 0 / 32%), rgb(0 0 0 / 32%)),
    var(--meteo-gradient, linear-gradient(180deg, #1565C0 0%, #0D47A1 45%, #0A3A7C 100%));
  background-attachment: fixed;
  background-position: 0 0;
  background-size: 100vw 100vh;
  background-repeat: no-repeat;
  color: #fff;
}

.search-panel,
.search-panel .offcanvas-header,
.search-panel .offcanvas-body {
  padding: 0 10px;
}

.search-panel .offcanvas-header {
  margin-bottom: 15px;
  justify-content: space-between;
}

.search-panel .offcanvas-header h5 {
}

.search-panel .offcanvas-header .btn {
  color: #fff;
  padding: 0;
}

.search-panel .offcanvas-body .form-control {
  border-radius: 5px;
}

.search-panel .offcanvas-body .list-group {
  border-radius: 5px;
}

.search-panel .offcanvas-body .list-group .list-group-item {
  background-color: var(--white-10);
  border: none;
  color: #fff;
  font-size: var(--fs-base);
  border-bottom: 1px solid var(--white-10);
}

.search-panel .offcanvas-body .list-group .list-group-item .text-muted {
  color: var(--white-35) !important;
}

/* ========== CERCA LOCALITA': campo, risultati, preferiti (22/10/2026) ==========
   Campo in testa e risultati subito sotto, preferiti nascosti mentre si cerca.
   Stesso linguaggio delle card dei preferiti: fondo --white-08, raggio 14,
   padding 12; nei risultati la stella sta nella colonna da 28px dell'icona
   meteo delle card, cosi' i nomi partono dallo stesso bordo.
   Contratto: _dev/tests/ricerca-localita.test.js */
.loc-cerca {
  position: relative;
  margin-bottom: 8px;
}
.loc-cerca .ic-search {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  font-size: var(--fs-xl);
  color: var(--white-60);
  pointer-events: none;
}
#loc-input {
  -webkit-appearance: none;
  appearance: none;
  height: 46px;
  padding: 0 14px 0 44px;
  border: 1px solid var(--white-15);
  border-radius: 14px;
  background-color: var(--white-10);
  color: #fff;
  font-size: var(--fs-lg);
  box-shadow: none;
}
#loc-input::placeholder {
  color: var(--white-50);
}
#loc-input:focus {
  background-color: var(--white-15);
  border-color: transparent;
  outline: 2px solid var(--white-60);
  /* dentro il campo: il corpo dell'offcanvas scorre e taglierebbe il bordo */
  outline-offset: -2px;
  box-shadow: none;
}
/* La × nativa di type="search" (blu su WebKit) non c'entra con il pannello. */
#loc-input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}
#loc-search .offcanvas-body:has(#loc-results:not(:empty)) #loc-favorites-section {
  display: none !important;
}
#loc-results {
  border-radius: 14px;
  overflow: hidden;
}
#loc-results:not(:empty) {
  margin-bottom: 20px;
}
#loc-search .offcanvas-body #loc-results .list-group-item {
  padding: 11px 12px;
  background-color: var(--white-08);
  border-bottom: 1px solid var(--white-08);
  line-height: 1.3;
}
#loc-search .offcanvas-body #loc-results .list-group-item:last-child {
  border-bottom: 0;
}
#loc-results .favorite-star {
  flex: 0 0 28px;
  width: 28px;
  margin-right: 8px !important;
  text-align: center;
  font-size: var(--fs-xl) !important;
}
#loc-results strong {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
}
#loc-search .offcanvas-body #loc-results .text-muted {
  margin-top: 1px;
  font-size: var(--fs-sm);
  color: var(--white-60) !important;
}
/* !important: il bottone porta .text-danger di Bootstrap, che lo e' gia'. */
#loc-favorites-section .home-favorites-list .favorite-remove {
  color: var(--white-60) !important;
}
@media (hover: hover) and (pointer: fine) {
  #loc-favorites-section .home-favorites-list .favorite-remove:hover {
    color: #ff8b8b !important;
  }
}
#loc-favorites-section {
  margin-top: 20px;
}

/* Search Panel - Favorites Section */
#loc-favorites-section h6 {
  font-size: var(--fs-sm);
  font-weight: var(--fw-regular);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  opacity: 0.7;
  margin-bottom: 0.5rem;
}

/* ========== PREFERITI DEL PANNELLO DI RICERCA: card stile Apple ==========
   Misurato sugli screenshot dell'utente (entrambi 1290x2796, quindi
   confrontabili direttamente). Apple: card separate alte **100px** con gap
   12px, raggio ~14, nome ~20px e **temperatura ~42px**; niente icona meteo —
   il cielo della card fa da icona. Noi avevamo una lista fitta: righe da
   **49px** senza gap ne' raggio, nome 13px e temperatura **16px**, cioe' 2,6
   volte piu' piccola della loro e indistinguibile dal resto.
   Qui le righe diventano card, con la gerarchia di Apple: nome in alto a
   sinistra, temperatura grande in alto a destra, condizione e min/max sotto.
   La card resta pero' **piu' bassa della loro** (72px contro 100): il loro
   elenco e' una schermata intera, il nostro sta sopra il campo di ricerca in
   un offcanvas, e con la tastiera aperta quattro card da 100px lo spingono
   fuori schermo (4x112 = 448px contro i 195 di prima).
   Tutto scopato su `#loc-favorites-section`, e il prefisso non e' cosmetico: il
   blocco base `.home-favorites .home-favorites-list ...` sta piu' in BASSO nel
   foglio, quindi a pari specificita' vincerebbe lui — misurato, togliendo il
   prefisso l'impronta del pannello cambia in 1940 punti.
   `display:contents` su `.hf-main`/`.hf-readout` fa partecipare i loro figli
   alla griglia della card, cosi' nome e temperatura stanno sulla stessa riga
   senza toccare il markup che il costruttore JS emette. */
/* Il padding laterale della sezione (10px per lato, `@media (max-width:429px)`)
   qui e' controproducente: sul telefono e' proprio dove lo spazio manca, e
   toglierlo restituisce 20px al nome — con la card che ha gia' un padding suo.
   Resta alla vista Pro, dove la sezione e' una card dentro un widget. */
#loc-favorites-section {
  padding-left: 0;
  padding-right: 0;
}

#loc-favorites-section .home-favorites-list .home-favorite-item {
  display: grid;
  /* Colonne FISSE, uguali in ogni riga: ogni card e' una griglia a se', e con
     `auto` la colonna dei dati prendeva la larghezza del proprio contenuto
     («7°» contro «14°», cestino contro segnaposto) — sul 15 Pro Max righe
     disallineate e nomi troncati a lunghezze diverse. 76px reggono
     «↑-2°  ↓-10°» a 12px. */
  grid-template-columns: 28px minmax(0, 1fr) 76px 32px;
  grid-template-rows: auto auto;
  align-items: center;
  column-gap: 8px;
  row-gap: 1px;
  padding: 13px 12px;
  margin-bottom: 8px;
  border: none;
  border-radius: 14px;
  background-color: var(--white-08);
}
#loc-favorites-section .home-favorites-list .home-favorite-item:last-child {
  margin-bottom: 0;
}
#loc-favorites-section .home-favorites-list .home-favorite-item:hover,
#loc-favorites-section .home-favorites-list .home-favorite-item:focus {
  background-color: var(--white-12);
}
#loc-favorites-section .home-favorites-list .home-favorite-item--current {
  background-color: var(--white-12);
}

#loc-favorites-section .home-favorites-list .hf-main,
#loc-favorites-section .home-favorites-list .hf-readout {
  display: contents;
}

#loc-favorites-section .home-favorites-list .hf-icon {
  grid-column: 1;
  grid-row: 1 / span 2;
  flex: none;
  width: 28px;
  height: 28px;
}
#loc-favorites-section .home-favorites-list .hf-name {
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  grid-column: 2;
  grid-row: 1;
  font-size: 17px;
  font-weight: var(--fw-semibold, 600);
  line-height: 1.15;
  /* Centrato nella riga alta (che la definisce la temperatura, piu' alta):
     misurato sullo screenshot Apple, la cima del numero sta ~3pt SOPRA la
     cima del nome, non 14 come veniva allineando i due in basso. */
  align-self: center;
}
#loc-favorites-section .home-favorites-list .hf-cond {
  grid-column: 2;
  grid-row: 2;
  font-size: 12px;
  opacity: 0.72;
  line-height: 1.2;
  align-self: start;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#loc-favorites-section .home-favorites-list .hf-temp {
  grid-column: 3;
  grid-row: 1;
  justify-self: end;
  align-self: start;
  font-size: 28px;
  font-weight: 200;
  line-height: 1;
  letter-spacing: -0.5px;
  font-variant-numeric: tabular-nums;
}
#loc-favorites-section .home-favorites-list .hf-minmax {
  grid-column: 3;
  grid-row: 2;
  justify-self: end;
  align-self: start;
  font-size: 12px;
  opacity: 0.8;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
#loc-favorites-section .home-favorites-list .favorite-remove,
#loc-favorites-section .home-favorites-list .hf-current-badge {
  grid-column: 4;
  grid-row: 1 / span 2;
  align-self: center;
  justify-self: center;
}

/* L'uscita collassa max-height, opacity e padding (vedi `animateFavoriteRowsOut`):
   con le card serve anche il margine, o resta un vuoto di 8px che salta al
   re-render. Lo zero lo mette il CSS, cosi' il JS condiviso non cambia. */
#loc-favorites-section .home-favorites-list .home-favorite-item.hf-leaving {
  margin-bottom: 0;
  transition: max-height 220ms ease, opacity 180ms ease,
              padding-top 220ms ease, padding-bottom 220ms ease,
              margin-bottom 220ms ease;
}

.search-panel .list-group-item .favorite-star {
  transition: opacity 0.2s ease, transform 0.2s ease;
  opacity: 0.7;
}

@media (hover: hover) and (pointer: fine) {
  .search-panel .list-group-item:hover .favorite-star {
    opacity: 1;
    transform: scale(1.1);
  }
}

.search-panel .list-group-item .favorite-remove {
  opacity: 0.5;
  transition: opacity 0.2s ease;
  padding: 0.25rem 0.5rem;
}

@media (hover: hover) and (pointer: fine) {
  .search-panel .list-group-item:hover .favorite-remove {
    opacity: 0.8;
  }
  .search-panel .list-group-item .favorite-remove:hover {
    background-color: rgba(220, 53, 69, 0.1);
  }
}

/* Favorite star animation */
.favorite-star.ic-star.ic-piena {
  animation: starPop 0.3s ease;
}

@keyframes starPop {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.3);
  }
  100% {
    transform: scale(1);
  }
}

/* ========== APP MENU PANEL ========== */
.app-menu-panel {
  width: min(320px, 85vw) !important;
  height: 100vh !important;
  height: 100dvh !important;
  background-color: rgb(117 126 140 / 41%);
  background-image:
    linear-gradient(rgb(0 0 0 / 30%), rgb(0 0 0 / 30%)),
    var(--meteo-gradient, linear-gradient(180deg, #1565C0 0%, #0D47A1 45%, #0A3A7C 100%));
  background-attachment: fixed;
  background-position: 0 0;
  background-size: 100vw 100vh;
  background-repeat: no-repeat;
  color: #fff;
}

.app-menu-panel .offcanvas-header,
.app-menu-panel .offcanvas-body {
  padding: 20px;
}

.app-menu-panel .offcanvas-header {
  border-bottom: 1px solid var(--white-10);
  align-items: center;
}

.app-menu-panel .offcanvas-header h5 {
  font-size: var(--fs-3xl);
  font-weight: var(--fw-bold);
  margin-bottom: 0;
}

.app-menu-panel .offcanvas-header .btn {
  color: #fff;
  padding: 0;
  display: inline-flex;
  align-items: center;
  /* La X a destra, col bordo del glifo su quello dell'elenco sotto: il bottone
     resta da 40px per il tocco, il glifo si appoggia al suo lato destro. */
  margin-left: auto;
  justify-content: flex-end;
  min-width: 40px;
  min-height: 40px;
  line-height: 1;
}

.app-menu-panel .offcanvas-body {
  display: flex;
  flex-direction: column;
}

.app-menu-panel .list-group {
  border-radius: var(--r-md);
  overflow: hidden;
}

.app-menu-panel .list-group-item {
  background-color: var(--white-10);
  border: none;
  border-bottom: 1px solid var(--white-05);
  padding: 0;
  transition: background-color 0.2s ease;
}

.app-menu-panel .list-group-item:last-child {
  border-bottom: none;
}

.app-menu-panel .list-group-item:hover {
  background-color: var(--white-15);
}

.app-menu-panel .menu-link {
  display: flex;
  align-items: center;
  padding: 14px 16px;
  color: #fff;
  text-decoration: none;
  font-size: var(--fs-lg);
  transition: color 0.2s ease, background-color 0.2s ease;
}

.app-menu-panel .menu-link i {
  font-size: var(--fs-2xl);
  color: var(--white-75);
  transition: color 0.2s ease;
}

.app-menu-panel .list-group-item:hover .menu-link i {
  color: #fff;
}

.app-menu-panel .app-info {
  margin-top: auto;
  color: var(--white-70) !important;
  border-color: var(--white-10) !important;
}

.app-menu-panel .app-info p {
  line-height: 1.5;
  color: var(--white-70) !important;
}

/* ========== INFO PAGES (GUIDA, PRIVACY, ETC.) ========== */
.info-page {
  padding: 20px 16px 40px;
  max-width: 800px;
  width: 100%;
  margin: 12px auto 40px;
  background-color: var(--widget-bg-solid, rgb(38 54 76 / 90%));
  background-image:
    linear-gradient(rgb(0 0 0 / 28%), rgb(0 0 0 / 28%)),
    var(--meteo-gradient, linear-gradient(180deg, #1565C0 0%, #0D47A1 45%, #0A3A7C 100%));
  /* Come .widget: iOS ignora `fixed` e su una card alta molte viewport il
     cielo finiva dopo i primi 100vh. L'offset lo scrive WeatherGradientManager. */
  background-attachment: scroll;
  background-position: 0 var(--meteo-bg-position-y, 0px);
  background-size: 100vw 100vh;
  background-repeat: no-repeat;
  border: 1px solid var(--white-10);
  border-radius: var(--r-lg);
  overflow: hidden;
  color: #fff;
}

.info-header {
  margin-bottom: 25px;
  padding-bottom: 15px;
  border-bottom: 1px solid var(--white-15);
}

.info-header h1 {
  font-size: var(--fs-3xl);
  font-weight: var(--fw-bold);
  margin-bottom: 8px;
  display: flex;
  align-items: center;
}

.info-header h1 i {
  font-size: var(--fs-2xl);
  opacity: 0.9;
}

.info-header .lead {
  font-size: var(--fs-lg);
  opacity: 0.75;
  margin-bottom: 5px;
}

.info-content {
  line-height: 1.6;
}

.info-section {
  margin-bottom: 25px;
}

.info-section h2 {
  font-size: 1rem;
  font-weight: var(--fw-bold);
  margin-bottom: 10px;
  margin-top: 15px;
  color: var(--white-95);
}

.info-section h3 {
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  margin-bottom: 8px;
  margin-top: 12px;
  color: var(--white-90);
}

.info-section p {
  margin-bottom: 10px;
  color: var(--white-85);
  font-size: var(--fs-lg);
}

.info-section ul,
.info-section ol {
  margin-bottom: 12px;
  padding-left: 22px;
}

.info-section li {
  margin-bottom: 6px;
  color: var(--white-85);
  font-size: var(--fs-md);
}

.info-section li strong {
  color: var(--white-95);
}

.info-section a {
  color: #90caf9;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.info-section a:hover {
  color: #bbdefb;
}

.info-page .text-muted {
  color: var(--white-70) !important;
}

.info-section .text-muted {
  color: var(--white-70) !important;
  font-size: var(--fs-md);
}

.info-section .small {
  font-size: var(--fs-md);
}

.info-section .alert {
  background-color: rgb(255 193 7 / 20%);
  border: 1px solid rgba(255, 193, 7, 0.3);
  border: 1px solid rgb(255 193 7 / 30%);
  border-radius: 6px;
  padding: 10px 12px;
  color: #fff;
  font-size: var(--fs-md);
}

.info-section .badge {
  font-size: var(--fs-sm);
  padding: 3px 8px;
  font-weight: var(--fw-bold);
}

.info-section .table {
  color: #fff;
  font-size: var(--fs-md);
  margin-top: 12px;
  background-color: var(--black-20);
  border-color: var(--white-15);
}

.info-section .table th {
  background-color: var(--white-15);
  border-color: var(--white-20);
  padding: 8px;
  font-weight: var(--fw-bold);
  font-size: var(--fs-md);
  color: #fff;
}

.info-section .table td {
  border-color: var(--white-15);
  padding: 8px;
  color: var(--white-90);
  font-size: var(--fs-md);
  background-color: transparent;
}

.info-section .credit-item {
  padding-left: 12px;
  border-left: 2px solid var(--white-20);
}

.info-section .credit-item h3 {
  font-size: var(--fs-lg);
  margin-bottom: 5px;
}

.info-section .border-top {
  border-top: 1px solid var(--white-15);
  margin-top: 30px;
  padding-top: 20px;
}

.info-section .text-center {
  text-align: center;
}

/* Info Pages - Responsive */
@media (max-width: 767px) {
  .info-page {
    padding: 15px 12px 30px;
  }

  .info-header h1 {
    font-size: var(--fs-2xl);
  }

  .info-section h2 {
    font-size: 15px;
  }

  .info-section h3 {
    font-size: var(--fs-lg);
  }

  .info-section p,
  .info-section li {
    font-size: var(--fs-md);
  }
}

/* ========== GENERIC ICONS & UTILS ========== */
.weather-svg-icon {
  width: 48px;
  height: 48px;
  display: block;
}

/* ========== TOOLTIPS ========== */
.tooltip-inner {
  text-align: left;
  line-height: 130%;
  font-size: var(--fs-base);
}
.tooltip-inner .tooltip-block {
  margin-bottom: 5px;
}
[data-bs-toggle="tooltip"] {
  cursor: pointer;
  touch-action: manipulation;
  display: block;
}

/* ========== WIDGET CONTAINER BASE ========== */
.widget {
  background-color: var(--widget-bg-solid, rgb(38 54 76 / 90%));
  border: 1px solid rgba(187, 187, 187, 0.08);
  border: 1px solid rgb(187 187 187 / 8%);
  border-radius: var(--r-md);
  padding: var(--widget-pad);
  color: #ffffff;
  margin-bottom: 15px;
  overflow: hidden;
  width: 100%;
  transition: opacity var(--apple-duration-normal) var(--apple-easing);
}

/* Il gradiente è quello completo del cielo, fissato alla viewport come
   #weatherBg: ogni card resta opaca e segue posizione e tonalità dello sfondo
   senza il costo GPU del backdrop-filter. Il colore sopra il gradiente migliora
   la leggibilità mantenendo visibile l'integrazione con il meteo animato. */
.widget,
.st-table {
  background-color: var(--widget-bg-solid, rgb(38 54 76 / 90%));
  background-image:
    linear-gradient(rgb(0 0 0 / 22%), rgb(0 0 0 / 22%)),
    var(--meteo-gradient, linear-gradient(180deg, #1565C0 0%, #0D47A1 45%, #0A3A7C 100%));
  /* background-attachment: fixed è incoerente su Safari/iOS durante lo scroll.
     WeatherGradientManager aggiorna l'offset per-card in --meteo-bg-position-y. */
  background-attachment: scroll;
  background-position: 0 var(--meteo-bg-position-y, 0px);
  background-size: 100vw 100vh;
  background-repeat: no-repeat;
}

/* Anche l'header sticky della tabella deve usare lo stesso punto del cielo. */
.widget .st-thead,
.st-table .st-thead {
  background-attachment: scroll;
  background-position: 0 var(--meteo-bg-position-y, 0px);
}

.widget .widget-header .weather-svg-icon,
.widget.widget-riga .weather-svg-icon {
  width: 44px;
  height: 44px;
  filter: drop-shadow(0 1px 2px var(--black-20));
}

#dayForecastCarousel .widget-header .weather-svg-icon {
  width: 54px;
  height: 54px;
}

.widget .widget-header,
.widget .widget-footer .data-row,
.widget .widget-cont {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.widget .widget-header {
  margin-bottom: 10px;
  color: #ffffff;
}

.widget .widget-header .widget-action {
  font-size: var(--fs-sm);
  vertical-align: middle;
  opacity: 0.7;
  display: block;
  padding-left: 10px;
  color: var(--white-80);
}

.widget.widget-riga .widget-header {
  margin-bottom: 0;
}

.widget.widget-riga .widget-header .wi {
  line-height: 145%;
}

.widget .widget-title {
  letter-spacing: 0.6px;
  font-size: var(--fs-sm);
  text-transform: uppercase;
  text-align: left;
  font-weight: var(--fw-regular);
  color: rgba(255, 255, 255, 0.70);
}

/* Stazioni: nome stazione e' un proper noun, non una label uppercase. */
.station-card .widget-header .widget-title {
  text-transform: none;
  letter-spacing: normal;
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
  color: #fff;
  line-height: 1.3;
}

.widget .widget-header .widget-title strong {
  color: #fff;
}

.widget .widget-footer {
  border-top: 1px solid var(--white-15);
  padding-top: 5px;
  margin-top: 10px;
}

.widget .widget-footer .data-row {
  margin-top: 8px;
  color: var(--white-75);
  font-size: var(--fs-sm);
  flex-wrap: nowrap;
}
.widget .widget-footer .data-row > * + * { margin-left: 8px; }

.widget .widget-footer .data-row.fishing-period-row {
  margin-top: 15px;
}

.widget .widget-footer .data-row .widget-value {
  color: #ffffff;
  text-align: right;
}

/* Gruppo icone allineate a destra nei periodi pesca */
.widget-icons-group {
  display: flex;
  align-items: center;
  margin-left: auto;
  flex-shrink: 0;
  white-space: nowrap;
}
.widget-icons-group > * + * { margin-left: 6px; }

/* Widget text nei periodi pesca - consente troncamento se necessario */
.widget .widget-footer .data-row .widget-text {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.widget.day-forecast .widget-footer .data-row .widget-text small {
  display: block;
  
}

.widget.day-forecast .widget-footer .data-row .widget-text .score {
  display: inline-block;
  color: #ffffff;
  padding: 3px 5px;
  border-radius: 4px;
}

/* Icona meteo piccola nei periodi pesca */
.widget-weather-icon-small {
  width: 25px;
  height: 25px;
  filter: drop-shadow(0 1px 2px var(--black-20));
  flex-shrink: 0;
}
.widget-air-quality .aqi-content {
  flex-direction: column;
  align-items: stretch;
}

.widget-air-quality .aqi-bar-wrap {
  width: 100%;
  margin-top: 4px;
  padding: 4px 0;
}

.widget-air-quality .aqi-bar {
  position: relative;
  height: 5px;
  border-radius: 2.5px;
  background: linear-gradient(
    to right,
    #34c759 0%,
    #30d158 12%,
    #63da38 20%,
    #a8d84e 28%,
    #ffd60a 36%,
    #ffb340 44%,
    #ff9f0a 52%,
    #ff6723 60%,
    #ff453a 70%,
    #d62d5e 80%,
    #bf5af2 90%,
    #6e2b8b 100%
  );
}

.widget-air-quality .aqi-indicator {
  position: absolute;
  top: 50%;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #fff;
  border: 1.5px solid var(--black-20);
  box-shadow: 0 0 3px var(--black-25);
  transform: translate(-50%, -50%);
}

.widget-air-quality .aqi-desc {
  font-size: var(--fs-base);
  color: var(--white-55);
  margin-top: 4px;
  line-height: 1.4;
}

/* Layout righe periodi pesca con box score verticale */
.fishing-period-row {
  display: flex;
  align-items: stretch;
  padding: 0;
}
.fishing-period-row > * + * { margin-left: 10px; }

/* Box score colorato verticale */
.fishing-score-box {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3px 6px;
  border-radius: 3px;
  font-weight: var(--fw-bold);
  font-size: var(--fs-sm);
  color: #ffffff;
  flex-shrink: 0;
}

/* Info periodo con tipo e orari */
.fishing-period-info {
  display: flex;
  flex-direction: column;
  justify-content: center;
  flex: 1;
  min-width: 0;
}
.fishing-period-info > * + * { margin-top: 2px; }

/* Tipo periodo (MAJOR/MINOR) */
.fishing-period-type {
  font-weight: var(--fw-bold);
  font-size: var(--fs-base);
  color: var(--white-95);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  line-height: 1.2;
}

/* Orari periodo */
.fishing-period-time {
  font-size: var(--fs-xs);
  color: var(--white-70);
  line-height: 1.2;
}

.widget .widget-cont {
  color: #ffffff;
  text-align: right;
}

.day-forecast-scroll {
  display: flex;
  overflow-x: auto;
  scroll-behavior: smooth;
  /* Affordance scroll-x: fade ai bordi 16px → suggerisce contenuto scrollabile */
  -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 16px), transparent 100%);
  mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 16px), transparent 100%);
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
  scrollbar-width: none; /* Firefox */
}
.day-forecast-scroll > * + * { margin-left: 15px; }

/* ========== WIDGET-RIGA GRID (Apple Weather style) ========== */
/* Mobile: stack verticale */
.widget-riga-grid {
  display: flex;
  flex-direction: column;
  margin-bottom: 15px;
}
.widget-riga-grid > * + * { margin-top: 12px; }

.widget-riga-grid > .widget-riga {
  margin-bottom: 0;
}

.day-forecast-scroll .widget-riga {
    min-width: 100%;
flex: 0 0 100%;
scroll-snap-align: start;
}

.day-forecast-scroll .widget-riga .widget-header.btn-accordion .widget-cont.accordion-toggle,
#dayForecastCarousel .widget-riga .widget-header .widget-cont {
  width: 100%;
}

.day-forecast-scroll::-webkit-scrollbar {
  display: none; /* Chrome, Safari */
}

.day-forecast-scroll .widget.day-forecast {
  min-width: 75%;
  flex: 0 0 75%;
  scroll-snap-align: start;
}

.day-forecast-scroll .widget.day-forecast.full {
  min-width: 100%;
  flex: 0 0 100%;
}

.day-forecast-scroll.pesca .widget.day-forecast .widget-cont {
  align-items: center;
}

.day-forecast-scroll.pesca .widget.day-forecast .widget-cont .widget-value strong,
.day-forecast-scroll.pesca .widget.day-forecast .widget-cont .widget-delta strong {
  font-size: var(--fs-lg);
}

.day-forecast-scroll.pesca .widget.day-forecast .widget-cont .widget-delta.fishing {
  padding: 4px 7px;
  border-radius: 3px;
  text-shadow: 0 1px 3px var(--black-20);
}

/* Fishing forecast - Adaptive weights badge */
.badge-adaptive-weights {
  font-size: var(--fs-xs);
  margin-left: 4px;
  background: #ff9800;
  color: white;
  padding: 2px 6px;
  border-radius: 3px;
  display: inline-flex;
  align-items: center;
}
.badge-adaptive-weights > * + * { margin-left: 3px; }

/* Fishing forecast - Reliability bar */
.fishing-reliability-bar {
  margin: 8px 0;
  padding: 0 8px;
}

.fishing-reliability-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 3px;
}

.fishing-reliability-label {
  font-size: var(--fs-sm);
  opacity: 0.8;
}

.fishing-reliability-value {
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
}

.fishing-reliability-track {
  background: var(--black-10);
  border-radius: 4px;
  height: 6px;
  overflow: hidden;
}

.fishing-reliability-fill {
  height: 100%;
  border-radius: 4px;
  transition: width 0.3s ease;
}

/* Reliability level colors based on data attribute */
.fishing-reliability-fill[data-level="high"] {
  background: #28a745;
}

.fishing-reliability-fill[data-level="good"] {
  background: #8bc34a;
}

.fishing-reliability-fill[data-level="moderate"] {
  background: #ffc107;
}

.fishing-reliability-fill[data-level="low"] {
  background: #ff9800;
}

/* Fishing rating colors - Dynamic background colors based on score */
.widget-delta.fishing[data-level="excellent"] {
  background: #1e7e34 !important;
}

.widget-delta.fishing[data-level="good"] {
  background: #558b2f !important;
}

.widget-delta.fishing[data-level="fair"] {
  background: #ffc107 !important;
}

.widget-delta.fishing[data-level="poor"] {
  background: #ff9800 !important;
}

/* Il punteggio qui vive in uno <strong> che .widget .widget-cont ... strong
   dipinge di bianco: su giallo/arancio va riportato scuro, e l'ombra del
   testo (pensata per il bianco) va spenta. */
.widget .widget-cont .widget-delta.fishing[data-level="fair"] strong,
.widget .widget-cont .widget-delta.fishing[data-level="poor"] strong {
  color: #212529;
  text-shadow: none;
}

.widget-delta.fishing[data-level="bad"] {
  background: #616161 !important;
}

/* Fishing period score box colors.
   Verdi scuriti (2026-07-28) per il testo bianco: #28a745 dava 3,1:1 e
   #8bc34a appena 2,1:1. Ora 5,1:1 e 4,1:1, con "excellent" che resta il
   piu' scuro dei due. Toccati solo i fondi: dove gli stessi verdi sono
   COLORE DI TESTO su fondo scuro (.solunar-press-*) restano chiari, li'
   scurire peggiorerebbe. */
.fishing-score-box[data-level="excellent"] {
  background-color: #1e7e34;
}

.fishing-score-box[data-level="good"] {
  background-color: #558b2f;
}

/* Giallo e arancio restano vividi (sono i colori-semaforo della scala): col
   bianco erano a 1,6:1 e 2,2:1, col testo scuro salgono a 9,5:1 e 7,2:1.
   Scurirli fino a reggere il bianco li avrebbe portati sul marrone. */
.fishing-score-box[data-level="fair"] {
  background-color: #ffc107;
  color: #212529;
}

.fishing-score-box[data-level="poor"] {
  background-color: #ff9800;
  color: #212529;
}

/* Grigio "minima": col bianco era 2,7:1, ora 6,2:1 e resta il piu' spento. */
.fishing-score-box[data-level="bad"] {
  background-color: #616161;
}

/* Solunar widget — pill pesca inline nella riga pressione */
.solunar-press-pesca {
  font-weight: var(--fw-bold);
}
.solunar-press-excellent { color: #28a745; }
.solunar-press-good      { color: #8bc34a; }
.solunar-press-fair      { color: #ffc107; }
.solunar-press-poor      { color: #ff9800; }
.solunar-press-bad       { color: #c0c0c0; }

.widget.day-forecast .widget-cont {
  color: #fff;
  font-weight: var(--fw-bold);
  display: flex;
  align-items: center;
}

.widget.day-forecast .weather-svg-icon {
  width: 64px;
  height: 64px;
  filter: drop-shadow(0 1px 2px var(--black-20));
}

.widget.day-forecast .widget-cont span small.text-muted {
  color: #fff !important;
  font-weight: var(--fw-regular);
}

.widget .widget-cont .widget-data-preview {
  text-align: right;
  font-size: var(--fs-sm);
}

.widget .widget-cont .widget-value {
  text-align: left;
}

.widget .widget-cont .widget-delta {
  text-align: right;
}

.widget .widget-cont .widget-value strong,
.widget .widget-cont .widget-delta strong {
  color: #fff;
  font-weight: var(--fw-bold);
  font-size: var(--fs-2xl);
}

.widget .btn-accordion {
  width: 100%;
  background-color: transparent;
  border: none;
  padding: 0;
}

.widget .btn-accordion[aria-expanded="true"] .arrow-accordion {
  transform: rotate(180deg);
  display: block;
  transition: transform 0.25s ease;
}

.widget .btn-accordion .widget-cont {
  color: var(--white-75);
}

.widget .btn-accordion .widget-cont .widget-title {
  color: #ffffff;
}

.widget .btn-accordion .widget-cont strong {
  color: #ffffff;
  font-weight: var(--fw-bold);
}

ul.day-hourly-list {
  display: flex;
  flex-direction: column;
  padding: 0;
  margin: 0;
  margin-top: 15px;
  width: 100%;
  max-height: 192px;
  overflow-y: auto;
  /* Blocca swipe orizzontale, permetti solo scroll verticale */
  touch-action: pan-y;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

/* Container accordion - blocca swipe orizzontale quando aperto */
.day-forecast-collapse {
  touch-action: pan-y;
}

ul.day-hourly-list li.day-hourly-row {
  display: flex;
  align-items: center;
  padding-top: 8px;
  padding-bottom: 8px;
  border-bottom: 1px dotted var(--white-25);
  justify-content: space-between;
}

ul.day-hourly-list li.day-hourly-row:last-child {
  border-bottom: none;
}

/* Tide badge – intense blue */
.badge-tide {
  background: rgb(30 90 170 / 85%);
  color: #fff;
}

/* ==========================================================================
   STAZIONI — DASHBOARD TABLE v2 (pivot corretto, 2026-05-22 sera)
   Stazioni = righe (nome sticky-left)
   Sensori  = colonne (icone in header sticky-top con tooltip)
   Zone     = bande accordion orizzontali che collassano le righe sottostanti
   ========================================================================== */
:root {
  --st-name-col-w: 130px;
  --st-sensor-col-w: 56px;
  --st-row-h: 44px;
  --st-band-h: 32px;
  --st-hdr-h: 44px;
}

.st-table {
  /* Superficie allineata alla tabella Pro (.dt-widget vive in .widget):
     stesso tono-su-tono adattivo alla condizione meteo, angoli widget. */
  background-color: var(--widget-bg-solid, rgb(38 54 76 / 90%));
  border: 0;
  border-radius: var(--r-lg);
  overflow: hidden;
  margin: 0 0 14px;
  /* Flex item dentro .col-12: la larghezza deve venire dal contenitore, non
     dal contenuto. Serve perche' .st-scroll e' un container di query e il
     contenimento inline-size gli toglie il contributo del contenuto: senza
     queste due righe la tabella misura 0px. */
  flex: 1 1 auto;
  min-width: 0;
}

/* Card solide adattive: il gradiente segue il meteo e il browser non deve
   rasterizzare un backdrop-filter per ogni widget durante lo scroll. */

.st-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  /* Container di query per il pannello storico: gli serve la larghezza
     VISIBILE dello scroller, che nessuna percentuale sa dare (100% e' la
     larghezza del contenuto, 100vw ignora i margini della card). */
  container-type: inline-size;
}
/* Scrollbar nascosta come nella Pro (.dt-scroll) */
.st-scroll::-webkit-scrollbar { display: none; }

.st-inner { min-width: max-content; }

/* ---------- Header row (sensor icons sticky-top) ---------- */
.st-thead {
  display: grid;
  grid-template-columns: var(--st-name-col-w) repeat(12, var(--st-sensor-col-w));
  height: var(--st-hdr-h);
  background-color: var(--widget-bg-solid);
  background-image:
    linear-gradient(rgb(0 0 0 / 22%), rgb(0 0 0 / 22%)),
    var(--meteo-gradient, linear-gradient(180deg, #1565C0 0%, #0D47A1 45%, #0A3A7C 100%));
  background-attachment: fixed;
  background-position: 0 0;
  background-size: 100vw 100vh;
  background-repeat: no-repeat;
  border-bottom: 1px solid var(--white-08);
  position: sticky;
  top: 0;
  z-index: 3;
}

/* Celle sensore: nessun bordo verticale — la heatmap colore fa da separatore,
   come nella Pro (.dt-cell). */
.st-th {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-xl);
  color: var(--white-95);
}
.st-th-name {
  justify-content: flex-start;
  padding-left: 14px;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--white-55);
  position: sticky;
  left: 0;
  /* Stesso tono/ombra della sidebar Pro (.dt-label): bordo morbido, non linea dura */
  background: rgb(58, 76, 102);
  border-right: 1px solid var(--white-08);
  box-shadow: 6px 0 10px -6px var(--black-45);
  z-index: 2;
}

/* ---------- Zone band (accordion) ---------- */
/* Band: full-width grid che copre tutte le colonne, label sticky-left
   per restare visibile durante scroll orizzontale. */
.st-band {
  display: grid;
  grid-template-columns: 1fr;
  align-items: center;
  height: var(--st-band-h);
  /* Stessa grammatica delle sezioni accordion della tabella Pro. */
  background: linear-gradient(90deg, rgba(106, 169, 224, 0.32) 0%, rgba(106, 169, 224, 0.18) 100%);
  border-top: 0.5px solid rgba(106, 169, 224, 0.45);
  border-bottom: 0;
  cursor: pointer;
  width: 100%;
  min-width: max-content;
  color: var(--white-95);
  font-size: var(--fs-sm);
  font-weight: var(--fw-regular);
  letter-spacing: 0.6px;
  text-transform: uppercase;
  opacity: 0.7;
  user-select: none;
  transition: filter 160ms ease;
}
@media (hover: hover) and (pointer: fine) {
  .st-band:hover { filter: brightness(1.15); }
}
.st-band:focus-visible { outline: 2px solid rgba(255, 200, 87, 0.55); outline-offset: -2px; }
.st-band[aria-expanded="false"] { filter: saturate(0.6) brightness(0.9); }
.st-band.is-pref {
  background: linear-gradient(90deg, rgba(224, 185, 106, 0.32) 0%, rgba(224, 185, 106, 0.18) 100%);
  border-top-color: rgba(224, 185, 106, 0.45);
  color: #f4dfa9;
}

/* Wrapper sticky che contiene icona + label + count + chev */
.st-band > .st-band-inner {
  position: sticky;
  left: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 12px;
  height: 100%;
  width: max-content;
  max-width: 100%;
}

.st-band .icon { color: inherit; font-size: var(--fs-sm); }
.st-band .label { flex: 0 0 auto; }
.st-band .count {
  font-size: 10px;
  color: var(--white-55);
  font-weight: var(--fw-regular);
  letter-spacing: 0.3px;
  text-transform: none;
}
.st-band.is-pref .count { color: rgba(255, 213, 122, 0.75); }
.st-band .chev {
  color: var(--white-55);
  font-size: var(--fs-sm);
  transition: transform 220ms ease;
}
.st-band[aria-expanded="false"] .chev { transform: rotate(-90deg); }

.st-rows[hidden] { display: none; }
.st-rows {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  min-width: 0;
}

/* ---------- Station row ---------- */
.st-row {
  display: grid;
  grid-template-columns: var(--st-name-col-w) repeat(12, var(--st-sensor-col-w));
  min-height: var(--st-row-h);
  /* Separatore riga tenue come la Pro (.dt-row + .dt-row) */
  border-top: 0.5px solid var(--white-03);
  transition: background-color 120ms ease;
}
.st-row:first-of-type { border-top: 0; }
@media (hover: hover) and (pointer: fine) {
  .st-row:hover { background: var(--white-04); }
}

/* Tablet+: la griglia riempie il container.
   Le colonne a larghezza fissa sommano 130 + 12x56 = 802px; .st-table vive in
   un .col-12 che .row.gx-3 > [class^="col"] rende flex row, quindi la card si
   dimensionava al contenuto e su iPad si fermava a 802px lasciando ~230px di
   vuoto a destra. Qui la card prende tutta la larghezza e le colonne sensore
   crescono oltre il minimo; sotto i 768px resta lo scroll orizzontale. */
@media (min-width: 768px) {
  .st-table { width: 100%; }
  .st-inner { min-width: 100%; }

  .st-thead,
  .st-row {
    grid-template-columns:
      var(--st-name-col-w) repeat(12, minmax(var(--st-sensor-col-w), 1fr));
  }
}

/* iPad portrait (768-1023): il minimo delle colonne deve starci nel container.
   `minmax(min, 1fr)` cresce oltre il minimo solo se il minimo ci sta: la somma
   130 + 12x56 = 802px supera i 720px utili a 768 e i 780px a 820, quindi in
   portrait la griglia continuava a scrollare invece di riempire. Con il nome a
   170px la somma saliva a 842 e lo sforamento peggiorava (122px a 768, 62px a
   820) rispetto ai 130px di partenza. Qui il minimo scende a 48px: 130 + 12x48
   = 706px sta in entrambi e le colonne si risolvono a ~49px (768) e ~54px
   (820), riempiendo la card. */
@media (min-width: 768px) and (max-width: 1023px) {
  :root { --st-sensor-col-w: 48px; }
}

/* iPad landscape e desktop (≥1024): 130 + 12x56 = 802px ci sta largamente nei
   ~1004px utili, quindi il minimo resta 56px e il nome puo' permettersi i
   170px che tengono su una riga i toponimi veneziani piu' lunghi. */
@media (min-width: 1024px) {
  :root { --st-name-col-w: 170px; }
}

.st-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: var(--white-95);
  padding: 2px 4px;
}

.st-cell.is-empty {
  color: rgba(255, 255, 255, 0.22);
  font-weight: var(--fw-regular);
}
.st-cell.hm { color: #fff; }
/* Freccia di tendenza della marea (storico a database): cresce o cala
   rispetto alla rilevazione archiviata precedente; stazionaria, niente freccia. Testo unicode,
   non un'icona del font su CDN. Stessa classe nel popup della mappa. */
.st-trend {
  margin-left: 3px;
  font-size: 0.9em;
  font-weight: var(--fw-bold);
  line-height: 1;
}
.st-cell.hm-soft { background: var(--white-04); }
.st-cell.dir {
  flex-direction: column;
  gap: 1px;
  line-height: 1;
  font-size: 10px;
  font-weight: var(--fw-regular);
  padding: 4px 2px;
}
.st-cell.dir .arrow {
  font-size: var(--fs-lg);
  color: var(--white-90);
  transform-origin: center;
  line-height: 1;
}
.st-cell.dir .compass {
  font-size: 9px;
  color: var(--white-55);
  letter-spacing: 0.2px;
  line-height: 1;
}

/* Cella nome (sticky-left) — layout uniforme 2 righe:
   - Riga 1 (.top-line): stella + km compatti (top, dim)
   - Riga 2 (.name-text): nome full-width (wrap max 2 righe) */
.st-cell-name {
  padding: 4px 10px 4px 12px;
  flex-direction: column;
  align-items: stretch;
  justify-content: center;
  gap: 1px;
  font-weight: var(--fw-regular);
  font-size: var(--fs-sm);
  position: sticky;
  left: 0;
  /* Stessa sidebar della Pro (.dt-label): slate morbido + ombra bordo, non navy duro */
  background: rgb(58, 76, 102);
  border-right: 1px solid var(--white-08);
  box-shadow: 6px 0 10px -6px var(--black-45);
  z-index: 1;
  text-align: left;
  line-height: 1.14;
}
.st-cell-name .bottom-line {
  display: flex;
  align-items: center;
  gap: 5px;
  width: 100%;
}
.st-cell-name .name-text {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  white-space: normal;
  word-break: break-word;
  font-size: var(--fs-sm);
  color: var(--white-95);
  font-weight: var(--fw-bold);
  line-height: 1.14;
  width: 100%;
}
.st-cell-name .dist-line {
  font-size: var(--fs-xs);
  color: var(--white-55);
  font-weight: var(--fw-regular);
  line-height: 1.1;
  flex: 1 1 auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.st-cell-name .fav-btn {
  width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  padding: 0;
  color: var(--white-40);
  cursor: pointer;
  font-size: var(--fs-sm);
  flex-shrink: 0;
  transition: color 160ms ease, transform 120ms ease;
}
@media (hover: hover) and (pointer: fine) {
  .st-cell-name .fav-btn:hover { color: #ffc857; }
}
.st-cell-name .fav-btn:active { transform: scale(0.88); }
.st-cell-name .fav-btn.is-fav { color: #ffc857; }

/* Bottone storico: gemello della stella, stessa cassa e stesso peso visivo.
   Senza queste regole resterebbe un <button> nativo, con fondo e bordo del
   browser in mezzo a due controlli piatti. */
.st-cell-name .history-btn {
  width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  padding: 0;
  margin-left: 6px;
  color: var(--white-40);
  cursor: pointer;
  font-size: var(--fs-sm);
  flex-shrink: 0;
  transition: color 160ms ease, transform 120ms ease;
}
@media (hover: hover) and (pointer: fine) {
  .st-cell-name .history-btn:hover { color: #64b5f6; }
}
.st-cell-name .history-btn:active { transform: scale(0.88); }
.st-cell-name .history-btn[aria-expanded="true"] { color: #64b5f6; }
.st-cell-name .history-btn:focus-visible {
  outline: 2px solid rgba(100, 181, 246, .8);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Cella aggiornato (timestamp) */
.st-cell-ts {
  gap: 4px;
  font-size: var(--fs-xs);
  font-weight: var(--fw-regular);
  color: var(--white-75);
}
.st-cell-ts .fresh-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
}
.st-cell-ts .fresh-dot.fresh   { background: #4caf50; }
.st-cell-ts .fresh-dot.recent  { background: #ffb74d; }
.st-cell-ts .fresh-dot.stale   { background: #ef5350; }
.st-cell-ts .fresh-dot.unknown { background: var(--white-30); }
.st-cell-ts .ts-txt { white-space: nowrap; }

/* Cella provider */
.st-cell-prov .prov {
  display: inline-block;
  font-size: 9px;
  font-weight: var(--fw-bold);
  letter-spacing: 0.3px;
  padding: 2px 6px;
  border-radius: 3px;
}
.st-cell-prov .prov.ve { background: rgba(95, 179, 227, 0.28); color: #b8def0; }
.st-cell-prov .prov.is { background: rgba(255, 200, 87, 0.22); color: #ffcd6c; }
.st-cell-prov .prov.mx { background: rgba(79, 195, 168, 0.22); color: #7cd8be; }
.st-cell-prov .prov.na { background: var(--white-10); color: var(--white-55); }

/* Empty preferiti */
.st-empty {
  grid-column: 1 / -1;
  padding: 14px 18px;
  color: var(--white-55);
  font-size: var(--fs-base);
  text-align: center;
  position: sticky;
  left: 0;
  width: 100%;
  min-width: max-content;
  box-sizing: border-box;
}

/* ---------- Inline storico stazione: layout condiviso con i grafici Pro ---------- */
.st-history-panel {
  grid-column: 1 / -1;
  /* Il pannello sta dentro uno scroller orizzontale largo quanto le tredici
     colonne: senza sticky scorrerebbe via con loro e resterebbe fuori
     schermo appena si guarda un sensore a destra. */
  position: sticky;
  left: 0;
  width: 100cqw;
  max-width: 100cqw;
  box-sizing: border-box;
  min-width: 0;
  overflow: hidden;
  padding: 0;
  border-top: 1px solid var(--white-08);
  background: rgb(38 54 76 / 54%);
}
.st-history-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-width: 0;
  padding: 10px 14px 6px;
}
.st-history-title {
  min-width: 0;
  margin: 0;
  overflow: hidden;
  color: var(--white-95);
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  line-height: 1.25;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.st-history-close {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  margin-left: 10px;
  padding: 0;
  border: 1px solid var(--white-12);
  border-radius: var(--r-md);
  color: var(--white-75);
  background: var(--white-06);
  cursor: pointer;
}
.st-history-close:hover { color: #fff; background: var(--white-12); }
.st-history-close:focus-visible,
.st-history-panel .chart-pill:focus-visible {
  outline: 2px solid rgba(100, 181, 246, .75);
  outline-offset: 2px;
}
.st-history-status {
  min-height: 20px;
  padding: 0 14px 6px;
  color: var(--white-55);
  font-size: var(--fs-sm);
  line-height: 1.35;
}
.st-history-status[data-state="ready"] { color: var(--white-70); }
.st-history-panel[data-history-chart="off"] .st-history-panes { display: none; }
/* Durante l'attesa l'area del grafico resta al suo posto, con lo spinner dei
   grafici Pro. Senza, il pannello nasceva alto 143px con una riga di testo e
   saltava a 535 a grafico pronto (misurato su iPhone 15 Pro Max il 17/09/2026:
   553 ms a freddo, 190 a caldo; iPad Pro 11 1,2 s a freddo). L'altezza e' il
   grafico 240 + la riga delle letture, che nasce solo col grafico e scala col
   font: 323px sull'iPhone (root 16), 326 sull'iPad (root 18). Lo spinner entra
   dopo 150 ms: a caldo non lampeggia. */
.st-history-panel[data-history-chart="off"] .st-history-status[data-state="loading"] ~ .st-history-panes {
  display: block;
}
.st-history-status[data-state="loading"] ~ .st-history-panes .st-history-chart {
  min-height: calc(299px + 1.5rem);
}
.st-history-status[data-state="loading"] ~ .st-history-panes .chart-container canvas {
  visibility: hidden;
}
.st-history-status[data-state="loading"] ~ .st-history-panes .chart-container::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 40px;
  height: 40px;
  margin: -20px 0 0 -20px;
  box-sizing: border-box;
  border: 3px solid var(--white-10);
  border-top-color: var(--white-60);
  border-radius: 50%;
  opacity: 0;
  animation: chart-spin 0.8s linear infinite, st-history-loader-in 0.2s ease 150ms forwards;
}
@keyframes st-history-loader-in {
  to { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .st-history-status[data-state="loading"] ~ .st-history-panes .chart-container::after {
    animation: st-history-loader-in 0.2s ease 150ms forwards;
  }
}
.st-history-status[data-state="error"] { color: #ffc107; }
.st-history-status[data-state="empty"] { color: var(--white-55); }
.st-history-meta {
  /* altezza di una riga anche vuota: si riempie a dati arrivati */
  min-height: calc(1.35em + 6px);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  min-width: 0;
  padding: 0 14px 6px;
  color: var(--white-55);
  font-size: var(--fs-xs);
  line-height: 1.35;
}
.st-history-meta > * + * { margin-left: 10px; }
.st-history-panel .chart-pill-row {
  min-width: 0;
  padding: 6px 10px 10px;
  border-bottom: 1px solid var(--white-08);
}
.st-history-panel .chart-pill-bar {
  display: flex;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.st-history-panel .chart-pill-bar::-webkit-scrollbar { display: none; }
/* La regola globale `canvas { touch-action: none !important }` fa del grafico
   una zona morta per lo scroll: 240px di schermo dove il dito non muove la
   pagina (misurato su iPhone 15 Pro Max il 17/09/2026). In verticale scorre la
   pagina; in orizzontale il gesto resta al grafico, che ci fa la lettura. */
.st-history-chart canvas { touch-action: pan-y !important; }
/* le pill delle grandezze arrivano col catalogo: la riga le aspetta */
.st-history-metric-pills .chart-pill-bar { min-height: 34px; }
.st-history-panel .chart-pill + .chart-pill { margin-left: 6px; }
.st-history-panel .chart-pill {
  flex: 0 0 auto;
  min-height: 34px;
  padding: 6px 12px;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  color: var(--white-75);
  background: var(--white-06);
  cursor: pointer;
  font-size: var(--fs-sm);
  line-height: 1.2;
  white-space: nowrap;
}
.st-history-panel .chart-pill.active {
  border-color: rgba(100, 181, 246, .55);
  color: #fff;
  background: rgba(100, 181, 246, .22);
}
.st-history-panel .chart-panes {
  min-width: 0;
  padding: 8px 10px 12px;
}
.st-history-panel .chart-container,
.st-history-chart .chart-container {
  width: 100%;
  height: 240px;
  min-height: 240px;
  min-width: 0;
}

@media (max-width: 429px) {
  .st-history-header { align-items: flex-start; }
  .st-history-title { white-space: normal; }
  .st-history-meta > * + * { margin-left: 0; }
  .st-history-meta > * { margin-right: 10px; }
  .st-history-panel .chart-pill-row {
    overflow: hidden;
  }
}

/* Mobile: colonne più strette su viewport tight */
@media (max-width: 374px) {
  :root {
    --st-name-col-w: 110px;
    --st-sensor-col-w: 48px;
    --st-row-h: 40px;
  }
  .st-cell { font-size: var(--fs-xs); padding: 2px 2px; }
  .st-cell-name { padding-left: 10px; }
  .st-cell-name .name-text { font-size: var(--fs-xs); }
}

/* ========== STAZIONI (LISTA DATI) ========== */
.station-data .data-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 0;
  padding-top: 8px;
  padding-bottom: 8px;
  border-bottom: 1px dotted var(--white-25);
  color: var(--white-75);
  font-size: var(--fs-sm);
  flex-wrap: nowrap;
}
/* iOS 12: gap non funziona in flexbox */
.station-data .data-row > * + * { margin-left: 8px; }
.station-data .data-row .widget-value {
  color: #fff;
  text-align: right;
}
.station-data .data-row:last-child {
  border-bottom: none;
}

.station-filters .station-filters-body {
  padding: 10px 12px 12px;
}
.station-filters .station-filters-search {
  width: 100%;
  height: 38px;
  background: var(--white-10);
  border: 1px solid var(--white-15);
  color: #fff;
  border-radius: var(--r-md);
  padding: 0 12px;
}
.station-filters .station-filters-search::placeholder {
  color: var(--white-45);
}
.station-filters .station-filters-search:focus {
  background: var(--white-15);
  border-color: var(--white-30);
  color: #fff;
  box-shadow: none;
}
.station-filters .station-filters-row {
  display: flex;
  align-items: center;
}
/* iOS 12: gap non funziona in flexbox */
.station-filters .station-filters-row > * + * { margin-left: 10px; }
.station-filters .station-filters-row + .station-filters-row {
  margin-top: 10px;
}
.station-filters .station-filters-reset {
  flex: 0 0 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--white-10);
  border: 1px solid var(--white-15);
  color: var(--white-70);
  border-radius: var(--r-md);
}
.station-filters .station-filters-reset:hover {
  background: var(--white-18);
  color: #fff;
}
.station-filters .station-filters-selects {
  flex-wrap: wrap;
}
.station-filters .station-filters-selects .form-select {
  flex: 1 1 140px;
  height: 38px;
  background-color: var(--white-10);
  border: 1px solid var(--white-15);
  color: #fff;
  border-radius: var(--r-md);
  padding: 0 10px;
  /* FIX iOS: Ensure selects are interactive */
  -webkit-appearance: menulist;
  appearance: menulist;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-touch-callout: none;
}
.station-filters .station-filters-selects .form-select:focus {
  background-color: var(--white-15);
  border-color: var(--white-30);
  color: #fff;
  box-shadow: none;
}
.station-filters .station-filters-selects .form-select option {
  background: #2c3e50;
  color: #fff;
}

/* FIX iOS: Ensure filter inputs are focusable and responsive */
@supports (-webkit-touch-callout: none) {
  .station-filters .form-select,
  .station-filters .form-control {
    font-size: var(--fs-xl) !important; /* Prevent iOS zoom on focus */
  }
}

/* Freshness indicator dot */
.station-freshness {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 8px;
  flex-shrink: 0;
}
.station-freshness.fresh { background: #4caf50; }
.station-freshness.recent { background: #ffeb3b; }
.station-freshness.stale { background: #f44336; }
.station-freshness.unknown { background: #6b7280; }

/* Station preview strip (always visible, between header and collapse) */
.station-preview {
  padding-top: 4px;
  margin-top: 4px;
  border-top: 1px solid var(--white-08);
}
.station-preview .data-row .widget-text {
  flex: 1;
  min-width: 0;
}
/* Ensure identical icon + font size in both preview and accordion data rows */
.station-data .data-row .widget-text .wi,
.station-data .data-row .widget-text .ic {
  font-size: var(--fs-md);
}

/* Station header: star + accordion row */
.station-header-row {
  display: flex;
  align-items: stretch;
  margin-left: -12px;
}
.station-header-row .widget-header {
  flex: 1;
  min-width: 0;
}
.station-header-row .station-fav-btn {
  flex: 0 0 44px;
  min-height: 44px;
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  color: var(--white-40);
  font-size: var(--fs-xl);
  cursor: pointer;
  padding: 0;
  transition: color 0.15s;
}
/* Tap area accordion header card stazione ≥44px */
.station-card .widget-header {
  min-height: 44px;
  padding-top: 6px;
  padding-bottom: 6px;
}
.station-header-row .station-fav-btn:hover {
  color: var(--white-70);
}
.station-header-row .station-fav-btn.active {
  color: #facc15;
}
.station-header-row .station-fav-btn.active .ic-star {
  font-variation-settings: 'FILL' 1;
}

.station-sort-note {
  font-size: var(--fs-sm);
  color: var(--white-45);
  text-align: left;
  margin: 8px 0 14px;
  line-height: 1.8;
  padding-left: 2px;
}
.station-section-header {
  font-size: var(--fs-sm);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: inherit;
  opacity: 0.7;
  /* Mantieni il padding orizzontale del col-12 Bootstrap (compensazione gutter row);
     override solo verticale per non sbordare a sx fuori dallo schermo. */
  padding-top: 10px;
  padding-bottom: 4px;
  margin: 0;
}
.station-sort-note .station-freshness {
  vertical-align: middle;
  position: relative;
  top: -1px;
}

.station-distance {
  color: var(--white-55);
}
.station-filter-chip {
  border: 1px solid var(--white-18);
  cursor: pointer;
  -webkit-tap-highlight-color: var(--white-10);
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
  transition: transform 120ms ease-out, filter 120ms ease, border-color 120ms ease, box-shadow 120ms ease;
}
.station-filter-chip:active { transform: scale(0.96); }
.station-filter-chip.active {
  filter: brightness(1.05);
  border-color: var(--white-40);
  box-shadow: 0 0 0 2px var(--white-10);
}

/* ========== STATION DATA BADGES - High contrast for dark theme ========== */
/* Livello Mare / Onde - bg-info-subtle text-info → darker blue + white text */
.station-data .badge.bg-info-subtle {
  background-color: rgba(13, 110, 170, 0.85);
  color: #fff;
}

/* Umidità - same as info, consistent with "water" theme */
.station-data .badge.bg-info-subtle.text-info {
  background-color: rgba(13, 110, 170, 0.85);
  color: #fff;
}

/* Pressione - bg-secondary-subtle text-secondary → darker gray + white text */
.station-data .badge.bg-secondary-subtle {
  background-color: rgba(90, 98, 104, 0.9);
  color: #fff;
}

/* Pioggia - bg-primary-subtle text-primary → darker blue + white text */
.station-data .badge.bg-primary-subtle {
  background-color: rgba(13, 110, 253, 0.75);
  color: #fff;
}

/* Temperatura - bg-danger-subtle text-danger → warmer red/orange + white text */
.station-data .badge.bg-danger-subtle {
  background-color: rgba(200, 60, 60, 0.85);
  color: #fff;
}

/* Warning badge (marea alta) - ensure high contrast */
.station-data .badge.bg-warning {
  background-color: rgba(255, 193, 7, 0.95);
  color: #000;
}

/* Danger badge (marea critica) - ensure high contrast */
.station-data .badge.bg-danger {
  background-color: rgba(220, 53, 69, 0.95);
  color: #fff;
}

/* Provider badges */
.station-data .badge.bg-primary {
  background-color: rgba(13, 110, 253, 0.9);
  color: #fff;
}

.station-data .badge.bg-secondary {
  background-color: rgba(108, 117, 125, 0.9);
  color: #fff;
}

ul.day-hourly-list li.day-hourly-row .list-container {
  display: flex;
  align-items: center;
}

ul.day-hourly-list li.day-hourly-row .list-container.bottom {
  align-items: end;
}

ul.day-hourly-list li.day-hourly-row .weather-svg-icon-xs {
  width: 26px;
  margin-right: 5px;
  filter: drop-shadow(0 1px 2px var(--black-20));
}

ul.day-hourly-list li.day-hourly-row .hour-label {
  font-weight: var(--fw-regular);
  margin-right: 5px;
}

ul.day-hourly-list li.day-hourly-row .hour-desc {
  font-weight: var(--fw-regular);
  color: var(--white-75);
  font-size: var(--fs-xs);
}

ul.day-hourly-list li.day-hourly-row .hour-desc strong {
  font-weight: var(--fw-regular);
  display: block;
  color: var(--white-85);
  font-size: var(--fs-xs);
}

.windbar-box {
  display: grid;
  gap: 4px;
  width: 65px;
  text-align: center;
}

.list-container .windbar-box {
 margin-right: 10px;
}

.windbar-box .windbar-bar {
  width: 100%;
  height: 5px;
  border-radius: 4px;
  display: block;
}

.windbar-label {
  font-size: var(--fs-xs);
  color: var(--white-85);
}

.windbar-label .wi-direction-up {
  display: inline-block;
  transform-origin: center;
  font-size: var(--fs-base);
  margin: 0 3px;
}

.windbar-label .wind-dir-text {
  font-size: var(--fs-xs);
  opacity: 0.9;
}

ul.day-hourly-list li.day-hourly-row .badge {
  width: 55px;
  border-radius: 4px;
  font-size: var(--fs-xs);
  padding: 3px;
}

.widget.domani {
  background: rgba(223, 223, 223, 0.1);
  background: linear-gradient(0deg,rgba(223, 223, 223, 0.1) 0%, rgba(223, 223, 223, 0) 100%);
}

.widget.domani .widget-semafori {
  margin-bottom: 10px;
  border-radius: 5px;
}

/* widget domani – nascondi scrollbar */
.widget.domani .widget-footer {
  border-top: none;
  margin-top: 0;
  display: flex;
  /*   height: 238px; */
  overflow-y: auto;
  overflow-x: hidden;
  scroll-behavior: smooth;

  /* Firefox */
  scrollbar-width: none; /* nasconde la track */
  /* Edge/IE legacy */
  
  box-shadow: none;
  -webkit-backdrop-filter:none;
  backdrop-filter:none;
}

/* Chrome, Safari, Edge (Chromium) */
.widget.domani .widget-footer::-webkit-scrollbar {
  width: 0;
  height: 0; /* per sicurezza in orizzontale */
}

.widget.domani ul.day-hourly-list {
  margin-top: 0;
}

.day-forecast-accordion-list .widget .weather-svg-icon {
  margin-right: 5px;
}

.day-forecast-accordion-list .widget-title {
  line-height: 135%;
}

/* 1. ogni col-* dentro la .row diventa un flex-container */
.row.gx-3 > [class^="col"] {
  display: flex; /* le colonne si allungano fino all'altezza maggiore */
}

/* ========== ATTUALE (CURRENT) ========== */
.current-weather {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 15px;
  width: 100%;
}
/* .current-weather.today {
  padding: 10px;
} */

/* ========== HERO REFINEMENT (.current-weather.today) ==========
   Solo respiro, dimensioni temp/icona, gestione testi lunghi della
   descrizione meteo. Nessun container/glass: vive direttamente sulla
   pagina. */
.current-weather.today {
  align-items: center;
  gap: 14px;
  margin: 18px 0 32px;
  text-shadow: var(--hero-text-shadow);
}
@media (max-width: 374px) {
  .current-weather.today {
    margin: 12px 0 24px;
    gap: 10px;
  }
}

/* ========== HERO METEO LAYOUT (.current-weather.today.meteo-hero) ==========
   Layout Apple-style: colonna singola centrata, senza icona meteo,
   senza sunrise/sunset, max/min in riga inline sotto percepita.
   Scope esclusivo alla vista Meteo via modifier class, non impatta
   marea-hero / pesca-hero che riusano lo stesso base selector. */
.current-weather.today.meteo-hero,
.current-weather.today.marea-hero,
.current-weather.today.luna-corrente-hero,
.current-weather.today.pro-hero {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  text-align: left;
  /* Glow scuro per leggibilità su sfondi cielo/foto. */
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), 0 2px 12px rgba(0, 0, 0, 0.35);
  width: 100%;
  max-width: 100%;
  margin: 40px 0 52px;
  gap: 20px;
}

/* ========== HERO UNIFORMI (Oggi, Laguna, Pesca · 22/10/2026) ==========
   Uno schema solo (SPEC-hero-uniformi): icona, stato in grassetto con riga
   piccola, numero grande a destra, separatore, due coppie etichetta/valore.
   Markup da partials/common/hero-uniforme.php. Le regole sopra su
   .meteo-hero/.marea-hero/.luna-corrente-hero restano per margini e ombra del
   testo; qui la sezione torna a colonna. */
.current-weather.today.hero-uniforme {
  /* Tre colonne in alto (icona, testo, numero); sotto, linea e coppie a
     tutta larghezza con la prima coppia sul bordo sinistro e la seconda sul
     bordo destro del numero. row-gap a zero: il `gap` delle regole sopra
     varrebbe anche fra le righe. */
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  column-gap: 12px;
  row-gap: 0;
  align-items: center;
  color: #fff;
  /* Stesso rientro del contenuto dei widget sotto: a filo della colonna la
     hero sporgeva rispetto al loro testo. */
  padding-inline: var(--widget-pad);
  /* Niente ombra: sul telefono anche quella corta impastava il testo (22/10).
     Toglie anche l'alone largo (0 2px 12px) delle regole sopra. */
  text-shadow: none;
}
.hero-uniforme .hu-top {
  display: contents;
}
.hero-uniforme .hu-icona {
  /* Le SVG Meteocons hanno margine interno: sotto i 96 px il disegno
     sembrava un'icona di lista (stessa cascata delle hero di prima). */
  width: 96px;
  height: 96px;
  flex: 0 0 96px;
  display: block;
  filter: drop-shadow(0 6px 18px rgba(0, 0, 0, 0.32));
}
.hero-uniforme .hu-mid {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.hero-uniforme .hu-stato {
  /* Didascalia del numero, non suo concorrente: a 24 px «Gibbosa Crescente»
     su due righe pesava quanto il 95% accanto. */
  font-size: var(--fs-3xl);
  font-weight: var(--fw-semibold, 600);
  line-height: 1.2;
  /* Una parola piu' larga della colonna va a capo sillabata invece di coprire
     il numero: «Prevalentemente sereno» con -12° a 393 px. Solo le parole
     lunghe (12 lettere, 6 per parte): senza limite il browser spezzava anche
     «Cre-scente», che a capo stava intera. */
  overflow-wrap: anywhere;
  hyphens: auto;
  hyphenate-limit-chars: 12 6 6;
  -webkit-hyphenate-limit-before: 6;
  -webkit-hyphenate-limit-after: 6;
}
.hero-uniforme .hu-sotto {
  font-size: var(--fs-md);
  line-height: 1.35;
  margin-top: 3px;
  color: var(--white-85);
}
.hero-uniforme .hu-num {
  flex: 0 0 auto;
  font-size: 44px;
  font-weight: 300;
  line-height: 1;
  letter-spacing: -0.02em;
  white-space: nowrap;
  text-align: right;
}
.hero-uniforme .hu-unita {
  font-size: 16px;
  font-weight: var(--fw-regular);
  margin-left: 2px;
  color: var(--white-85);
}
.hero-uniforme .hu-sep,
.hero-uniforme .hu-griglia {
  grid-column: 1 / -1;
}
.hero-uniforme .hu-sep {
  height: 1px;
  background: rgba(255, 255, 255, 0.22);
  margin: 14px 0 12px;
}
.hero-uniforme .hu-griglia {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px 16px;
  margin: 0;
}
.hero-uniforme .hu-coppia {
  min-width: 0;
}
.hero-uniforme .hu-coppia:nth-child(2) {
  text-align: right;
}
.hero-uniforme .hu-coppia:nth-child(2) .hu-v {
  justify-content: flex-end;
}
.hero-uniforme .hu-k {
  /* Il linguaggio delle etichette dei widget (.widget-title): maiuscolo e
     spaziato, cosi' si stacca dal valore senza un'altra taglia. */
  font-size: var(--fs-sm);
  font-weight: var(--fw-regular);
  line-height: 1.3;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--white-85);
}
.hero-uniforme .hu-v {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 4px 0 0;
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold, 600);
  line-height: 1.3;
  overflow-wrap: break-word;
}
.hero-uniforme .hu-nota {
  margin: 2px 0 0;
  font-size: var(--fs-sm);
  line-height: 1.3;
  color: var(--white-85);
}
.hero-uniforme .hu-pallino {
  flex: 0 0 10px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25);
}
/* Stessi colori dei box del voto nella lista di pesca. */
.hero-uniforme .hu-pallino[data-level="excellent"] { background: #1e7e34; }
.hero-uniforme .hu-pallino[data-level="good"] { background: #558b2f; }
.hero-uniforme .hu-pallino[data-level="fair"] { background: #ffc107; }
.hero-uniforme .hu-pallino[data-level="poor"] { background: #ff9800; }
.hero-uniforme .hu-pallino[data-level="bad"] { background: #616161; }
.hero-uniforme .hu-azione {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0;
  white-space: nowrap;
  border: 0;
  background: none;
  color: var(--white-85);
  font: inherit;
  font-weight: var(--fw-regular);
  text-shadow: inherit;
  cursor: pointer;
}
/* Area di tocco di 44 px senza alzare la riga: con l'altezza sul bottone la
   riga dei valori da ospite aveva piu' aria delle altre viste. */
.hero-uniforme .hu-azione::before {
  content: "";
  position: absolute;
  inset: -12px -8px;
}
@media (min-width: 414px) {
  .hero-uniforme .hu-icona {
    width: 108px;
    height: 108px;
    flex-basis: 108px;
  }
}
@media (min-width: 430px) {
  .hero-uniforme .hu-icona {
    width: 116px;
    height: 116px;
    flex-basis: 116px;
  }
}
/* Sotto i 375 px lo stato ha ~90 px accanto a icona e numero. */
@media (max-width: 374px) {
  .hero-uniforme .hu-icona {
    width: 84px;
    height: 84px;
    flex-basis: 84px;
  }
  .hero-uniforme .hu-stato {
    font-size: var(--fs-2xl);
  }
  .hero-uniforme .hu-num {
    font-size: 38px;
  }
}
@media (max-width: 767px) {
  /* La Pro mostra un intervallo («15–16°»), largo il doppio di una
     temperatura: a 44px mandava a capo stato e riga sotto. */
  .hero-uniforme.pro-hero .hu-num {
    font-size: 36px;
  }
}
@media (max-width: 374px) {
  .hero-uniforme.pro-hero .hu-num {
    font-size: 32px;
  }
}
@media (min-width: 768px) {
  /* Stessa larghezza e centrata, non fit-content: passando da una vista
     all'altra le tre hero restano allineate. */
  .current-weather.today.hero-uniforme {
    width: var(--hero-larghezza);
    margin-inline: auto;
  }
}

/* ========== HERO PESCA (vista /pesca · 2026-04-25)
   Riusa .current-weather.today: stesse dimensioni e spaziature.
   Override: icona di sistema (ic-target), stelle
   colorate al posto di .now-feels, period come .now-suntimes. */
/* ph-icon (Bootstrap Icon font): font-size uniformato a meteo-hero icon dims. */
.current-weather.today.pesca-hero .ph-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 96px;
  line-height: 1;
  color: var(--bs-primary, #0d6efd);
  filter: drop-shadow(0 4px 14px var(--black-24));
}

@media (max-width: 374px) {
  .current-weather.today.pesca-hero .ph-icon {
    font-size: 84px;
  }
}

@media (min-width: 414px) {
  .current-weather.today.pesca-hero .ph-icon {
    font-size: 108px;
  }
}

@media (min-width: 430px) {
  .current-weather.today.pesca-hero .ph-icon {
    font-size: 116px;
  }
}

@media (min-width: 768px) {
  .current-weather.today.pesca-hero .ph-icon {
    font-size: 128px;
  }
}

@media (min-width: 1024px) {
  .current-weather.today.pesca-hero .ph-icon {
    font-size: 140px;
  }
}

.current-weather.today.pesca-hero .now-feels.ph-stars {
  color: #ffc107;
  letter-spacing: 1px;
  opacity: 1;
  margin-bottom: 6px;
}

/* ========== WIDGET SOLE E LUNA (vista /pesca · 2026-05-17)
   Pattern Apple Weather "Sole e Luna": 2 archi astronomici (sole/luna)
   con orari rise/set di domani + fase lunare di domani + 2 prossime fasi.
   Riusa .widget base (background, bordo, radius). SVG inline per archi
   per evitare asset esterni. Mobile-first, scales fino a iPad. */

.sole-luna-widget .sl-arcs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-3);
  margin-bottom: var(--sp-3);
}

/* Cap della colonna anche sul telefono (il perche' e' nel cap iPad piu' sotto):
   a 235px il marker veniva 52px, quanto l'icona di fase (54), e l'arco prendeva
   un terzo del widget. A 180px il marker sta sui 40, fra .sl-next-icon e
   .sl-phase-icon. */
.sole-luna-widget .sl-arc-col {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  min-width: 0;
  max-width: 180px;
  width: 100%;
  margin-inline: auto;
}

.sole-luna-widget .sl-arc {
  width: 100%;
  height: auto;
  display: block;
  overflow: visible;
}

/* Track: arco completo tenue tratteggiato (futuro, "tempo che deve passare") */
.sole-luna-widget .sl-arc-track {
  fill: none;
  stroke: rgba(255, 255, 255, 0.22);
  stroke-width: 1.25;
  stroke-linecap: round;
  stroke-dasharray: 3 4;
}

/* Progress: porzione bright dell'arco (passato, "tempo trascorso") */
.sole-luna-widget .sl-arc-progress {
  fill: none;
  stroke-width: 2.5;
  stroke-linecap: round;
  transition: stroke-dasharray 0.8s cubic-bezier(0.4, 0, 0.2, 1);
}

.sole-luna-widget .sl-arc-progress--sun {
  stroke: url(#sl-grad-sun-past);
  filter: drop-shadow(0 0 4px rgba(255, 199, 66, 0.35))
          drop-shadow(0 1px 2px var(--black-20));
}

.sole-luna-widget .sl-arc-progress--moon {
  stroke: url(#sl-grad-moon-past);
  filter: drop-shadow(0 0 4px rgba(220, 228, 242, 0.25))
          drop-shadow(0 1px 2px var(--black-20));
}

.sole-luna-widget .sl-baseline {
  stroke: rgba(255, 255, 255, 0.12);
  stroke-width: 1;
}

.sole-luna-widget .sl-arc-icon {
  filter: drop-shadow(0 1px 3px var(--black-25));
  transition: transform 0.8s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.4s ease;
}

.sole-luna-widget .sl-sun-icon {
  filter: drop-shadow(0 0 6px rgba(255, 199, 66, 0.45))
          drop-shadow(0 1px 2px var(--black-25));
}

.sole-luna-widget .sl-moon-icon {
  filter: drop-shadow(0 0 5px rgba(220, 228, 242, 0.35))
          drop-shadow(0 1px 2px var(--black-25));
}

.sole-luna-widget .sl-arc-icon--below {
  opacity: 0.35;
  filter: drop-shadow(0 1px 2px var(--black-25)) grayscale(0.4);
}

/* Reduced motion: disabilita transition dasharray (può apparire jittery) */
@media (prefers-reduced-motion: reduce) {
  .sole-luna-widget .sl-arc-progress,
  .sole-luna-widget .sl-arc-icon {
    transition: none;
  }
}

.sole-luna-widget .sl-arc-times {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-2);
  margin-top: var(--sp-1);
}

.sole-luna-widget .sl-time-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 1.2;
  min-width: 0;
}

.sole-luna-widget .sl-time {
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  color: #ffffff;
  letter-spacing: -0.01em;
}

.sole-luna-widget .sl-time-label {
  font-size: var(--fs-xs);
  color: var(--white-55, rgba(255, 255, 255, 0.55));
  margin-top: 2px;
}

.sole-luna-widget .sl-divider {
  border-top: 1px solid var(--white-15);
  margin: var(--sp-3) 0;
}

.sole-luna-widget .sl-phase-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-bottom: var(--sp-3);
}

.sole-luna-widget .sl-phase-icon {
  width: 54px;
  height: 54px;
  flex-shrink: 0;
  filter: drop-shadow(0 1px 2px var(--black-20));
}

.sole-luna-widget .sl-phase-text {
  display: flex;
  flex-direction: column;
  line-height: 1.25;
  min-width: 0;
}

/* Punto focale della parte luna: un gradino sopra orari (14) e prossime fasi (13). */
.sole-luna-widget .sl-phase-name {
  font-size: var(--fs-xl);
  font-weight: var(--fw-bold);
  color: #ffffff;
}

.sole-luna-widget .sl-phase-day {
  font-size: var(--fs-sm);
  color: var(--white-55, rgba(255, 255, 255, 0.55));
  margin-top: 2px;
}

.sole-luna-widget .sl-next-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-3);
}

.sole-luna-widget .sl-next-cell {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3) var(--sp-2) var(--sp-2);
  background: rgba(255, 255, 255, 0.04);
  /* Bordo come quello del widget (8%): al 15% le card interne pesavano piu'
     del contenitore. */
  border: 1px solid var(--white-08);
  border-radius: var(--r-md);
  min-width: 0;
}

.sole-luna-widget .sl-next-icon {
  width: 38px;
  height: 38px;
  flex-shrink: 0;
  filter: drop-shadow(0 1px 2px var(--black-20));
  margin-top: 2px;
}

.sole-luna-widget .sl-next-text {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
  min-width: 0;
  overflow: hidden;
  gap: 2px;
}

.sole-luna-widget .sl-next-name {
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
  color: #ffffff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sole-luna-widget .sl-next-date {
  font-size: var(--fs-xs);
  color: var(--white-55, rgba(255, 255, 255, 0.55));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sole-luna-widget .sl-next-meta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
  flex-wrap: wrap;
}

.sole-luna-widget .sl-next-illum {
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  color: var(--white-75, rgba(255, 255, 255, 0.75));
}

.sole-luna-widget .sl-next-meta .fishing-score-box {
  font-size: var(--fs-xs);
  padding: 1px 6px;
  line-height: 1.4;
}

.sole-luna-widget .sl-next-fam {
  font-size: var(--fs-xs);
  color: var(--white-55, rgba(255, 255, 255, 0.55));
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Schermi molto stretti (≤ 340px): mini-card su singola colonna */
@media (max-width: 340px) {
  .sole-luna-widget .sl-next-row {
    grid-template-columns: 1fr;
  }
}

/* iPad+: respiro extra */
@media (min-width: 744px) {
  .sole-luna-widget .sl-arcs {
    gap: var(--sp-5);
  }

  /* Cap della colonna arco.
     .sl-arc e' un SVG con viewBox 200x115 e width 100%: le icone di sole e luna
     sono 44 unita', quindi la loro dimensione resa cresce con la colonna. A
     1146px la colonna arrivava a 483px e il marker a 106px — quasi quanto
     l'icona hero della vista Meteo (140px) e quasi il doppio dell'icona di fase
     (60px). Il cap tiene il marker sui ~53px, in scala con .sl-next-icon (38px)
     e .sl-phase-icon (60px). Si capa la colonna e non il solo SVG perche' gli
     orari sotto l'arco devono restare allineati ai suoi estremi. */
  .sole-luna-widget .sl-arc-col {
    max-width: 240px;
    margin-inline: auto;
  }
  .sole-luna-widget .sl-time {
    font-size: var(--fs-xl);
  }
  .sole-luna-widget .sl-phase-icon {
    width: 60px;
    height: 60px;
  }
}

/* ========== WIDGET LUNA COMPATTA (pesca + laguna) ==========
   Stile condiviso: nome fase più piccolo del default widget, icona luna
   più grande, illuminazione + trend ridotti. Fix size, no scaling
   responsive — l'unica info davvero protagonista è l'icona della luna. */
.widget.luna-compatta .widget-cont {
  align-items: center;
  gap: 12px;
}
.widget.luna-compatta .widget-cont .weather-svg-icon {
  width: 72px;
  height: 72px;
  flex: 0 0 72px;
}
.widget.luna-compatta .widget-cont .widget-value strong {
  font-size: var(--fs-xl);
  font-weight: var(--fw-bold);
  line-height: 1.2;
}
.widget.luna-compatta .widget-cont .widget-value small {
  font-size: var(--fs-base);
  opacity: 0.78;
}
@media (min-width: 430px) {
  .widget.luna-compatta .widget-cont .weather-svg-icon {
    width: 84px;
    height: 84px;
    flex-basis: 84px;
  }
}

/* ========== WIDGET STAZIONI LIVE LAGUNA (vista /laguna · 2026-04-26)
   Suddivisione per metrica (T. acqua, Vento e raffiche, Onda). Ogni
   blocco ha un'etichetta + righe data-row con badge zona + nome corto. */
.stazioni-laguna-live .sl-metric + .sl-metric {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--white-15, var(--white-12));
}

.stazioni-laguna-live .sl-trend {
  margin-left: 4px;
  font-weight: var(--fw-bold);
}
.stazioni-laguna-live .sl-metric-label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-regular);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  opacity: 0.7;
  margin-bottom: 8px;
}

.stazioni-laguna-live .sl-metric .data-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  padding: 5px 0;
  font-size: var(--fs-sm);
  color: var(--white-75);
  border-bottom: 1px dashed var(--white-18);
}

.stazioni-laguna-live .sl-metric .data-row:last-child {
  border-bottom: 0;
}

.stazioni-laguna-live .data-row .widget-text {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  flex: 1 1 auto;
}

.stazioni-laguna-live .station-zone {
  display: inline-block;
  min-width: 16px;
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--white-10);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  text-align: center;
  letter-spacing: 0.5px;
  opacity: 0.8;
}

.stazioni-laguna-live .data-row .widget-value {
  text-align: right;
  white-space: normal;
  font-variant-numeric: tabular-nums;
  color: #fff;
  flex: 0 0 auto;
  margin-left: auto;
}

/* Tablet+: righe live alla scala delle righe dati della vista Meteo.
   .stazioni-laguna-live .data-row non sta dentro .widget-footer, quindi si
   perdeva il bump a 768px che scala tutte le altre righe dati e restava a
   --fs-sm (13.5px a root 18) contro i 14.625px delle righe del widget vento
   della vista Meteo. Stessa cosa per l'etichetta di sezione; il badge zona
   sale di un gradino per non restare sproporzionato accanto al nome. */
@media (min-width: 768px) {
  .stazioni-laguna-live .sl-metric-label,
  .stazioni-laguna-live .sl-metric .data-row {
    font-size: var(--fs-md);
  }

  .stazioni-laguna-live .station-zone {
    font-size: var(--fs-sm);
  }
}

.stazioni-laguna-live + .station-cta-banner {
  display: flex;
  margin-top: 4px;
}

.station-cta-banner {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 10px;
  padding: 12px 14px;
  border-radius: var(--r-md);
  background-color: var(--widget-bg-solid, rgb(38 54 76 / 90%));
  border: 1px solid var(--white-12);
  color: inherit;
  text-decoration: none;
  transition: background 0.15s ease, transform 0.1s ease;
  background-image:
    linear-gradient(rgb(0 0 0 / 16%), rgb(0 0 0 / 16%)),
    var(--meteo-gradient, linear-gradient(180deg, #1565C0 0%, #0D47A1 45%, #0A3A7C 100%));
  background-attachment: scroll;
  background-position: 0 var(--meteo-bg-position-y, 0px);
  background-size: 100vw 100vh;
  background-repeat: no-repeat;
}

.station-cta-banner:hover,
.station-cta-banner:focus-visible {
  background-color: var(--widget-bg-solid, rgb(38 54 76 / 90%));
  text-decoration: none;
  color: inherit;
  background-image:
    linear-gradient(rgb(0 0 0 / 8%), rgb(0 0 0 / 8%)),
    var(--meteo-gradient, linear-gradient(180deg, #1565C0 0%, #0D47A1 45%, #0A3A7C 100%));
  background-attachment: scroll;
  background-position: 0 var(--meteo-bg-position-y, 0px);
  background-size: 100vw 100vh;
  background-repeat: no-repeat;
}

.station-cta-banner:active {
  transform: scale(0.99);
}

.station-cta-banner .cta-icon {
  font-size: var(--fs-4xl);
  opacity: 0.9;
  flex: 0 0 auto;
}

.station-cta-banner .cta-body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
  gap: 2px;
}

.station-cta-banner .cta-title {
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
  line-height: 1.2;
}

.station-cta-banner .cta-desc {
  font-size: var(--fs-sm);
  opacity: 0.7;
  line-height: 1.3;
}

.station-cta-banner .cta-arrow {
  font-size: var(--fs-lg);
  opacity: 0.6;
  flex: 0 0 auto;
}

/* ========== ARROW E ICON ========== */

.btn-accordion-alert {
  background: none;
  border: none;
  color: inherit;
  padding: 4px 6px;
  display: flex;
  align-items: center;
  transition: background 0.2s;
}
.btn-accordion-alert:focus {
  outline: none;
  box-shadow: none;
  background: none;
}


/* Il bollettino e' una card sua, sopra l'alert: l'alert dice che c'e' qualcosa
   da guardare, il bollettino racconta la fascia. La fascia in testa evita che
   «minima 14°» letto alle 18:00 si scambi per la minima del giorno. */
.widget-bollettino {
  /* Rientro dei widget: a 15 px il testo stava 3 px fuori asse con la hero. */
  padding: 10px var(--widget-pad);
}
.widget-bollettino .bollettino-testo {
  margin: 0;
  font-size: var(--fs-md);
  line-height: 150%;
  color: var(--white-85);
}
.widget-bollettino .bollettino-testo + .bollettino-testo {
  margin-top: var(--sp-1);
}

/* Avviso marea (22/10/2026): la superficie del bollettino, perche' il riquadro
   giallo pieno non si integrava con la hero. Il livello lo dicono il testo e il
   colore della sola icona. Contratto: _dev/tests/alert-widget-colors.test.js */
.avviso-marea {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}
.avviso-marea__icona {
  flex: 0 0 auto;
  font-size: var(--fs-xl);
  /* allinea il glifo alla prima riga (line-height 150%) */
  margin-top: 0.15em;
}
.avviso-marea--warning .avviso-marea__icona {
  color: #ffc266;
}
.avviso-marea--danger .avviso-marea__icona {
  color: #ff8b8b;
}
.avviso-marea .bollettino-testo strong {
  color: #fff;
  font-weight: var(--fw-semibold);
}
.avviso-marea__agg {
  margin: var(--sp-1) 0 0;
  font-size: var(--fs-sm);
  color: var(--white-60);
}

/* Alert variants — bordo colorato + sfondo trasparente, mai pieno (riduce rumore visivo, allineato a .pro-row-alert) */

/* Sicurezza/comfort: stessa superficie degli altri widget (gradiente del cielo,
   niente bordo). Era `background:` pieno, che cancellava il gradiente e la
   rendeva piu' scura delle card vicine (12/10/2026). */
.widget-semafori {
  border: 0;
}

/* Le card standard non devono creare una linea d'ombra sul bordo sinistro;
   gli alert mantengono invece i propri bordi semantici. */
.widget:not(.alert-widget):not(.pro-row-alert) {
  border-left-color: transparent;
  box-shadow: none;
}

/* Per le card standard l'integrazione con lo sfondo non deve avere un
   perimetro scuro: il semaforo conserva invece il proprio bordo. */
.widget:not(.alert-widget):not(.pro-row-alert):not(.widget-semafori) {
  border: 0;
}


/* Riduci motion se utente lo richiede */
/* ========== P6: HOME DASHBOARD (chip overview) ========== */
/* Overview dashboard with clickable chips linking to core views.
   Mobile-first stacked layout; 2-col grid on tablet/desktop.
   Chips use subtle glass background + colored icon badges per tipo. */

.home-dashboard {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 8px 0 24px;
}

/* Sezione Preferiti — dal 2026-09-05 l'unico montaggio e' il pannello di
   ricerca (`#loc-favorites-section`), che porta anche questa classe. */
.home-favorites {
  margin-bottom: 22px;
}

/* Lista preferiti senza bordi/padding extra all'interno del widget */
.home-favorites .home-favorites-list {
  margin-bottom: 0;
  background: transparent;
}

.home-favorites .home-favorites-list .list-group-item {
  background-color: transparent;
  border: none;
  border-bottom: 1px solid var(--white-06);
  color: #fff;
  padding: 8px 4px;
}

.home-favorites .home-favorites-list .list-group-item:last-child {
  border-bottom: none;
}

.home-favorites .home-favorites-list .list-group-item:hover,
.home-favorites .home-favorites-list .list-group-item:focus {
  background-color: var(--white-05);
}

.home-favorites .home-favorites-list .home-favorite-item--current {
  background-color: var(--white-04);
}

/* Box preferito stile Apple Weather: icona · nome+condizione · temp+min/max */
.home-favorites .home-favorites-list .home-favorite-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 6px;
}

/* O1 — entrata/uscita riga box preferiti (add/remove). Solo la riga cambiata
   anima: .hf-enter one-shot sulla nuova riga, .hf-leaving collassa quella
   rimossa prima del re-render. Il blanket reduced-motion azzera keyframe e
   transition → add/remove tornano istantanei (comportamento accessibile). */
.home-favorites .home-favorites-list .home-favorite-item.hf-enter {
  animation: hf-row-in 220ms var(--apple-easing, ease) both;
}
@keyframes hf-row-in {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}
.home-favorites .home-favorites-list .home-favorite-item.hf-leaving {
  overflow: hidden;
  transition: max-height 220ms ease, opacity 180ms ease,
              padding-top 220ms ease, padding-bottom 220ms ease;
}

.home-favorites .home-favorites-list .hf-icon {
  flex: 0 0 30px;
  width: 30px;
  height: 30px;
  object-fit: contain;
}

.home-favorites .home-favorites-list .hf-main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.home-favorites .home-favorites-list .hf-name {
  color: #fff;
  font-weight: var(--fw-bold);
  font-size: var(--fs-lg);
  line-height: 1.15;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.home-favorites .home-favorites-list .hf-cond {
  color: var(--white-60);
  font-size: var(--fs-xs);
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.home-favorites .home-favorites-list .hf-readout {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  margin-left: 4px;
}

.home-favorites .home-favorites-list .hf-temp {
  color: #fff;
  font-weight: 600;
  font-size: 1rem;
  line-height: 1;
  letter-spacing: -0.3px;
}

.home-favorites .home-favorites-list .hf-minmax {
  color: var(--white-55);
  font-size: var(--fs-xs);
  line-height: 1.1;
  white-space: nowrap;
}

/* Riga posizione attuale: marcatore pin (non rimovibile) al posto del cestino */
.home-favorites .home-favorites-list .hf-current-badge {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  padding: 4px 6px;
  font-size: var(--fs-sm);
  color: var(--white-55);
  pointer-events: none;
}

/* Testo nome località bianco, dettaglio (regione/paese) bianco al 60% */
.home-favorites .home-favorites-list .list-group-item strong {
  color: #fff;
  font-weight: var(--fw-bold);
  font-size: var(--fs-lg);
}

.home-favorites .home-favorites-list .list-group-item .text-muted {
  color: var(--white-60) !important;
  font-size: var(--fs-base);
}

/* Bottone rimuovi: rosso più sobrio, no bg */
.home-favorites .home-favorites-list .favorite-remove {
  color: rgba(220, 90, 90, 0.7);
  padding: 4px 6px;
}

.home-favorites .home-favorites-list .favorite-remove:hover,
.home-favorites .home-favorites-list .favorite-remove:focus {
  color: rgba(245, 110, 110, 1);
  background-color: rgba(220, 90, 90, 0.12);
  border-radius: 6px;
}

/* Tablet / desktop: stessa stack verticale del mobile.
   2-col grid rimossa (2026-05-23) — vista Pro mantiene flex-column
   ereditato dalla baseline anche su iPad. */

/* ========== P5: CHART UNIFICATO (pill selector) ========== */
.chart-unified {
  padding: 0;
}
.chart-unified .chart-unified-header {
  padding: 10px 14px 6px;
}

/* Variante accordion: header cliccabile, panel collassabile */
.chart-unified-accordion .chart-unified-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  padding: 12px 14px;
  background: transparent;
  border: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color 160ms ease, transform 120ms ease-out;
}
.chart-unified-accordion .chart-unified-toggle:active { transform: scale(0.99); }
.chart-unified-accordion .chart-unified-toggle:hover,
.chart-unified-accordion .chart-unified-toggle:focus-visible {
  background-color: var(--white-04);
  outline: none;
}
.chart-unified-accordion .chart-unified-toggle .widget-cont {
  display: inline-flex;
  align-items: center;
  gap: 0;
}
.chart-unified-accordion .cu-chevron {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-base);
  opacity: 0.55;
  transition: transform 220ms ease, opacity 160ms ease;
}
.chart-unified-accordion .chart-unified-toggle[aria-expanded="true"] .cu-chevron {
  transform: rotate(180deg);
  opacity: 0.9;
}
/* Accordion grafici Pro: apertura E chiusura simmetriche (fade + slide).
   Tiene la semantica display:none — l'IntersectionObserver dei chart lazy
   inizializza solo quando il panel è display:block, quindi il lazy-mount resta
   invariato. Su iOS < 17.4 (niente @starting-style / allow-discrete) degrada
   allo swap istantaneo di prima (progressive enhancement). Il blanket
   reduced-motion azzera comunque la transizione. */
.chart-unified-accordion .chart-unified-panel {
  border-top: 1px solid var(--white-06);
  opacity: 1;
  transform: translateY(0);
  transition: opacity 220ms ease, transform 220ms ease,
              display 220ms allow-discrete;
}
.chart-unified-accordion .chart-unified-panel[hidden] {
  display: none;
  opacity: 0;
  transform: translateY(-4px);
}
@starting-style {
  .chart-unified-accordion .chart-unified-panel:not([hidden]) {
    opacity: 0;
    transform: translateY(-4px);
  }
}
/* La riga e' il wrapper: tiene padding e bordo (prima stavano sulla pill-bar,
   che ora e' solo la parte scrollabile e non arriva piu' a fine riga). */
.chart-unified .chart-pill-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px 10px;
  border-bottom: 1px solid var(--white-08);
}
.chart-unified .chart-pill-bar {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  /* min-width:0 = puo' rimpicciolirsi sotto la larghezza delle pill, altrimenti
     un flex item sfonda la riga invece di scrollare al suo interno. */
  flex: 1 1 auto;
  min-width: 0;
}
.chart-unified .chart-pill-bar::-webkit-scrollbar { display: none; }

.chart-unified .chart-pill {
  flex: 0 0 auto;
  padding: 6px 12px;
  font-size: var(--fs-base);
  line-height: 1.2;
  color: var(--white-75);
  background: var(--white-06);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s ease, color 0.15s ease, transform 120ms ease-out;
}
.chart-unified .chart-pill i { margin-right: 4px; }
@media (pointer: coarse) {
  .chart-unified .chart-pill {
    padding: 8px 12px;
  }
}
@media (hover: hover) and (pointer: fine) {
  .chart-unified .chart-pill:hover {
    background: var(--white-12);
    color: #fff;
  }
}
.chart-unified .chart-pill.active {
  background: rgba(100, 181, 246, 0.22);
  border-color: rgba(100, 181, 246, 0.55);
  color: #fff;
}

/* Selettore modello vista Pro: <select> nativo stilato. Il box chiuso e' nostro,
   il menu aperto e' il picker OS (mobile-first, regge 13 voci). */
.modello-pro-wrap {
  padding: 0 0 8px;
}
.modello-pro-label {
  display: block;
  font-size: var(--fs-sm);
  color: var(--white-55);
  margin-bottom: 4px;
}
.modello-pro-select {
  width: 100%;
  padding: 8px 34px 8px 12px;
  font-size: var(--fs-base);
  color: #fff;
  background-color: var(--widget-bg-solid, rgb(38 54 76 / 90%));
  border: 1px solid var(--white-12);
  border-radius: var(--r-md);
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  /* freccia disegnata (l'appearance:none toglie quella nativa) */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%23ffffff88' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-image:
    linear-gradient(rgb(0 0 0 / 22%), rgb(0 0 0 / 22%)),
    var(--meteo-gradient, linear-gradient(180deg, #1565C0 0%, #0D47A1 45%, #0A3A7C 100%)),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%23ffffff88' d='M1 1l5 5 5-5%3E%3C/svg%3E");
  /* Come .widget: iOS ignora `fixed` e mostrava solo la cima del cielo, la più
     scura. L'offset lo scrive WeatherGradientManager.syncWidgetBackgrounds(). */
  background-attachment: scroll;
  background-position: 0 var(--meteo-bg-position-y, 0px), 0 var(--meteo-bg-position-y, 0px), right 12px center;
  background-size: 100vw 100vh, 100vw 100vh, auto;
  background-repeat: no-repeat;
}
.modello-pro-select:focus-visible {
  outline: 2px solid rgba(100, 181, 246, .55);
  outline-offset: -2px;   /* inset: sopravvive a container che clippano */
}

/* Riga select + toggle passo (1h/3h) */
.modello-pro-riga {
  display: flex;
  gap: 8px;
  align-items: stretch;
}
.modello-pro-select-box {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;  /* senza, il <select> non scende sotto il suo min-content (le opzioni piu' lunghe) e spinge il toggle fuori viewport */
}
.modello-pro-riga .modello-pro-select {
  width: 100%;
  height: 100%;
}
.modello-pro-loader {
  display: none;
  position: absolute;
  top: 50%;
  right: 12px;
  width: 16px;
  height: 16px;
  margin-top: -8px;
  border: 2px solid var(--white-25);
  border-top-color: #fff;
  border-radius: 50%;
  pointer-events: none;
  animation: spin .7s linear infinite;
}
.modello-pro-select-box.is-loading .modello-pro-select {
  cursor: wait;
  opacity: .72;
  background-image: none;
}
.modello-pro-select-box.is-loading .modello-pro-loader {
  display: block;
}
.modello-pro-riga.is-loading .passo-btn {
  cursor: wait;
  opacity: .55;
}
.passo-toggle {
  display: flex;
  flex: 0 0 auto;
  border: 1px solid var(--white-12);
  border-radius: var(--r-md);
  overflow: hidden;
}
.passo-btn {
  padding: 0 14px;
  font-size: var(--fs-sm);
  color: var(--white-75);
  background: var(--widget-bg-solid, rgb(38 54 76 / 90%));
  background-image:
    linear-gradient(rgb(0 0 0 / 22%), rgb(0 0 0 / 22%)),
    var(--meteo-gradient, linear-gradient(180deg, #1565C0 0%, #0D47A1 45%, #0A3A7C 100%));
  /* Come .modello-pro-select: niente `fixed`, offset da syncWidgetBackgrounds(). */
  background-attachment: scroll;
  background-position: 0 var(--meteo-bg-position-y, 0px);
  background-size: 100vw 100vh;
  background-repeat: no-repeat;
  border: none;
  cursor: pointer;
  transition: transform 120ms ease-out;
}
.passo-btn.active {
  background: rgba(100, 181, 246, 0.22);
  color: #fff;
}
.passo-btn:focus-visible {
  outline: 2px solid rgba(100, 181, 246, .55);
  outline-offset: -2px;
}

/* Press feedback (Emil): il pressable reagisce al tocco. Reduced-motion/low-power
   azzerano le transition globalmente (style.css :468 / :475). */
.passo-btn:active,
.chart-unified .chart-pill:active,
.btn-open-hourly:active {
  transform: scale(0.97);
}

/* Confronto multi-modello — toggle + copy (vista Pro).
   Ultimo item della riga pill: niente justify-content/margin-top, l'allineamento
   a destra ora e' la pill-bar che si prende lo spazio libero (flex:1). */
.chart-spread-bar {
  display: flex;
  flex: 0 0 auto;
}
.chart-spread-bar[hidden] { display: none; }

/* Su telefoni stretti il pulsante Modelli non ruba larghezza alla striscia
   orizzontale delle pill: resta visibile su una riga propria. */
@media (max-width: 429px) {
  .chart-unified .chart-pill-row {
    flex-direction: column;
    align-items: stretch;
  }
  .chart-unified .chart-spread-bar {
    align-self: flex-end;
  }
}

/* Copy e avviso stanno FUORI da .chart-panes, quindi non ereditano il suo inset:
   se lo scrivono da soli o vanno a filo del bordo. 10px ai lati = stesso inset di
   .chart-pill-row e .chart-panes; 12px sotto = stesso fondo di .chart-panes. */
.chart-spread-legenda {
  margin: 8px 0 0;
  padding: 0 10px;
  font-size: var(--fs-sm);
  color: rgba(255, 255, 255, .55);
  line-height: 1.35;
}
.chart-spread-avviso {
  margin: 4px 0 0;
  padding: 0 10px 12px;
  font-size: var(--fs-sm);
  color: #ffc107;
}
/* Il fondo lo tiene l'ultimo elemento VISIBILE. L'avviso e' sempre ultimo nel DOM
   ma sparisce con [hidden] (display:none), e :last-child continuerebbe a matcharlo:
   quando e' nascosto il fondo tocca alla legenda. */
.chart-unified-panel:has(.chart-spread-avviso[hidden]) .chart-spread-legenda {
  padding-bottom: 12px;
}

.chart-unified .chart-panes {
  position: relative;
  padding: 8px 10px 12px;
}
.chart-unified .chart-pane {
  display: none;
}
.chart-unified .chart-pane.active {
  display: block;
}
/* Pannello "Ore": full-bleed, scroll orizzontale nativo della strip */
.chart-unified .chart-pane[data-metric="ore"] {
  padding: 0;
  margin: 0 -10px -12px;
}
.chart-unified .chart-pane[data-metric="ore"].active {
  display: block;
}

/* ========== WIDGET SEMAFORI (barra gradiente) ========== */
.widget-semafori {
  /* Eredita padding:12px dalla base .widget */
}
.widget-semafori .sem-row + .sem-row {
  margin-top: 18px;
}
.widget-semafori .sem-row-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 8px;
}
.widget-semafori .sem-title {
  font-size: var(--fs-sm);
  font-weight: var(--fw-regular);
  letter-spacing: 0.6px;
  text-transform: uppercase;
  opacity: 0.7;
  color: #fff;
  cursor: pointer;
}
.widget-semafori .sem-title i {
  opacity: 0.8;
}
.widget-semafori .sem-bar-wrap {
  position: relative;
  width: 100%;
}
.widget-semafori .sem-bar {
  width: 100%;
  height: 5px;
  border-radius: 2.5px;
}
.widget-semafori .sem-bar-tips {
  position: absolute;
  inset: -6px 0;
  display: grid;
  gap: 0;
}
.widget-semafori .sem-tip {
  all: unset;
  position: relative;
  cursor: pointer;
  height: 100%;
}
.widget-semafori .sem-tip:focus-visible {
  outline: 2px solid var(--white-60);
  outline-offset: 2px;
  border-radius: 2px;
}
/* Dot visibile solo per slot con severity > 0 (attenzione/allerta) */
.widget-semafori .sem-tip.has-alert::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--dot-color, #fff);
  border: 1.5px solid var(--dot-border, var(--black-30));
  box-sizing: content-box;
  pointer-events: none;
}

.widget-semafori .sem-labels {
  display: grid;
  gap: 0;
  margin-top: 6px;
  font-size: var(--fs-sm);
  color: var(--white-60);
}
.widget-semafori .sem-labels span {
  text-align: center;
}
.widget-semafori .sem-labels span:first-child {
  text-align: left;
}
.widget-semafori .sem-labels span:last-child {
  text-align: right;
}

.widget-semafori .sem-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px solid var(--white-06);
  font-size: var(--fs-base);
  color: var(--white-75);
}
.widget-semafori .sem-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.widget-semafori .sem-legend-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  display: inline-block;
}

/* Mobile stretto: labels più piccole */
@media (max-width: 374px) {
  .widget-semafori .sem-labels { font-size: var(--fs-xs); }
}

/* Mobile <375: timeline 12 colonne troppo serrata → mostro solo le label pari (cadenza 2h),
   il grid-template-columns:repeat(N,1fr) resta invariato (visibility:hidden mantiene la cella),
   tap target dei .sem-tip restano cliccabili tutti. */
@media (max-width: 374px) {
  .widget-semafori .sem-labels { font-size: var(--fs-sm); }
  .widget-semafori .sem-labels span:nth-child(even) {
    visibility: hidden;
  }
}

/* ========== WIDGET-VALUE HELPER SPANS (unit, trend-delta) ========== */
.widget .widget-footer .data-row .widget-value .unit {
  color: var(--white-85);
  font-weight: var(--fw-regular);
}

/* ========== BTN OPEN HOURLY (apri vista oraria sotto day-bands) ========== */
.btn-open-hourly {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  margin-top: 10px;
  padding: 10px 12px;
  background: var(--white-06);
  color: var(--white-90);
  border: 1px solid var(--white-08);
  border-radius: var(--r-md);
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  cursor: pointer;
  transition: background 0.18s ease, border-color 0.18s ease, transform 120ms ease-out;
}
.btn-open-hourly:hover,
.btn-open-hourly:focus-visible {
  background: var(--white-10);
  border-color: var(--white-16);
  color: #fff;
}
.btn-open-hourly-arrow {
  font-size: var(--fs-lg);
  opacity: 0.7;
  transition: transform 0.22s ease;
}
.btn-open-hourly.active .btn-open-hourly-arrow,
.btn-open-hourly[aria-expanded="true"] .btn-open-hourly-arrow {
  transform: rotate(180deg);
}
.btn-open-hourly.active {
  background: rgba(100, 181, 246, 0.14);
  border-color: rgba(100, 181, 246, 0.4);
  color: #fff;
}
/* ========== DAY BANDS (4 fasce Mattina/Pomeriggio/Sera/Notte) ==========
   Usato dentro ogni card del carousel giorni fra footer e accordion orario. */
.day-bands {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--sp-2);
  padding: 18px 0 4px;
  margin-top: 6px;
  border-top: 1px solid var(--white-08);
}
.day-band {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 6px;
  padding: 12px 6px 14px;
  border-radius: 10px;
  background-color: var(--white-04);
  font-size: var(--fs-sm);
  line-height: 1.3;
}
.day-bands.day-forecast-fasce-bands .day-band {
  border-radius: 6px;
}

/* Variante standalone "Oggi per fasce" (vista Meteo): widget unico contenitore
   con scroll orizzontale su viewport stretti. Bg/border sul wrapper, non sui figli.
   Separatori verticali sottili tra colonne. */
.day-bands.oggi-fasce-orarie-bands {
  display: flex;
  grid-template-columns: none; /* override grid base */
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  /* Affordance scroll-x */
  -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 16px), transparent 100%);
  mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 16px), transparent 100%);
  gap: 0;
  padding: 0;
  margin: 0;
  border-top: none;
  scrollbar-width: none;
}
.day-bands.oggi-fasce-orarie-bands::-webkit-scrollbar {
  display: none;
}
.day-bands.oggi-fasce-orarie-bands .day-band {
  /* 3 item visibili anche su iPhone 5 (320px) — richiesta utente */
  flex: 0 0 33%;
  min-width: 0;
  background-color: transparent;
  border: none;
  border-radius: 0;
  padding: 16px 10px 16px;
  gap: 6px;
}
.day-bands.oggi-fasce-orarie-bands .day-band + .day-band {
  border-left: 1px solid var(--white-08);
}
/* Ritmo verticale uniforme: rimuovo margin ad-hoc, lascio fare al gap */
.day-bands.oggi-fasce-orarie-bands .day-band .weather-svg-icon {
  width: 42px;
  height: 42px;
  margin: 0;
}
.day-bands.oggi-fasce-orarie-bands .day-band-temp {
  margin-top: 0;
}
.day-bands.oggi-fasce-orarie-bands .day-band-wind {
  margin-top: 2px;
}
.day-bands.oggi-fasce-orarie-bands .day-band-wind .windbar-bar {
  margin: 4px 0 4px;
}
.day-bands.oggi-fasce-orarie-bands .day-band-wind-dir {
  margin-top: 4px;
}
.day-bands.oggi-fasce-orarie-bands .day-band-precip {
  margin-top: 2px;
}
/* iPhone X (375px) / Pixel 7 (412px) / iPhone 15 Pro Max (430px): 3 item visibili, 4° in scroll */
@media (min-width: 375px) {
  .day-bands.oggi-fasce-orarie-bands .day-band {
    flex: 0 0 33.3333%;
  }
}
/* iPhone X / SE2 / 12-14 (375-411px): icona meteo leggermente ridotta per stare in 33% */
@media (min-width: 375px) and (max-width: 413px) {
  .day-bands.oggi-fasce-orarie-bands .day-band .weather-svg-icon {
    width: 44px;
    height: 44px;
  }
}
/* Tablet/desktop (≥600px): tutti e 4 visibili, nessuno scroll */
@media (min-width: 768px) {
  .day-bands.oggi-fasce-orarie-bands {
    overflow-x: visible;
  }
  .day-bands.oggi-fasce-orarie-bands .day-band {
    flex: 1 0 25%;
  }
}
.day-band .weather-svg-icon {
  width: 40px;
  height: 40px;
  margin: 2px 0;
}
.day-band-label {
  font-weight: var(--fw-regular);
  font-size: var(--fs-sm);
  opacity: 0.7;
  text-transform: uppercase;
  letter-spacing: 0.6px;
}
.day-band-temp {
  font-size: var(--fs-base);
  font-weight: var(--fw-regular);
  margin-top: 2px;
}
.day-band-cond {
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
  text-transform: capitalize;
  opacity: 0.92;
  margin-top: 1px;
  line-height: 1.15;
  min-height: 2.3em;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.day-band-temp .sep {
  opacity: 0.45;
  margin: 0 3px;
}
.day-band-wind {
  width: 100%;
  gap: 3px;
}
.day-band-wind.windbar-box {
  width: 100%;
}
.day-band-wind .windbar-label {
  font-size: var(--fs-xs);
  white-space: nowrap;
  opacity: 0.9;
}
.day-band-wind .windbar-label .sep {
  opacity: 0.45;
  margin: 0 2px;
}
.day-band-wind .windbar-label .wi-direction-up {
  margin: 0 2px 0 4px;
  font-size: var(--fs-sm);
}
.day-band-wind .windbar-bar {
  height: 4px;
}
.day-band-wind-dir {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 3px;
  font-size: var(--fs-xs);
  white-space: nowrap;
  opacity: 0.9;
  margin-top: 2px;
}
.day-band-wind-dir .wi-direction-up {
  display: inline-block;
  transform-origin: center;
  font-size: var(--fs-sm);
}
.day-band-precip {
  font-size: var(--fs-xs);
  opacity: 0.55;
}
.day-band-precip i {
  margin-right: 2px;
}
.day-band-precip.has-precip {
  opacity: 1;
  color: #64b5f6;
}

/* Mobile stretto: bands più compatte (mantieni respiro interno) */
@media (max-width: 374px) {
  .day-bands {
    gap: 5px;
    padding: 14px 0 4px;
  }
  .day-band {
    gap: 4px;
    padding: 10px 3px 11px;
    font-size: var(--fs-xs);
  }
  .day-band .weather-svg-icon {
    width: 32px;
    height: 32px;
  }
}

/* ========== DAY FORECAST LIST (lista accordion 7gg) ==========
   Restyling 2026-04-25: sostituisce il vecchio carousel + vista oraria.
   Lista verticale: una riga per giorno, click → expand inline (single-open). */
.day-forecast-list {
  padding: 14px 12px 6px;
  margin: 0 0 18px;
}
.day-forecast-list-header {
  font-size: var(--fs-sm);
  font-weight: var(--fw-regular);
  letter-spacing: 0.6px;
  text-transform: uppercase;
  opacity: 0.7;
  padding: 0 0 10px;
}
.day-forecast-row {
  border-top: 1px solid var(--white-10);
}
.day-forecast-row:first-of-type {
  border-top: none;
}
.day-forecast-toggle {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
  padding: 16px 18px;
  background: transparent;
  border: none;
  color: inherit;
  text-align: left;
  font: inherit;
  cursor: pointer;
  transition: background-color 160ms ease, transform 120ms ease-out;
}
.day-forecast-toggle:active { transform: scale(0.99); }
.dfr-main {
  display: grid;
  /* 6 cols: giorno | icona | min° | barra range (1fr) | max° | chevron */
  grid-template-columns: 64px 48px 32px 1fr 40px 20px;
  align-items: center;
  column-gap: 12px;
}
/* Fishing row riempie il proprio grid 5-col — reset eventuali placement */
.fishing-forecast-list .dfr-main > * { grid-column: auto; }
.day-forecast-toggle:hover,
.day-forecast-toggle:focus-visible {
  background-color: var(--white-04);
  outline: none;
}
.day-forecast-toggle:focus-visible {
  box-shadow: inset 0 0 0 2px rgba(100, 181, 246, 0.45);
}
.dfr-day {
  display: flex;
  flex-direction: column;
  line-height: 1.15;
}
.dfr-day-name {
  font-weight: var(--fw-bold);
  font-size: var(--fs-xl);
  letter-spacing: -0.2px;
  color: var(--white-95);
}
.dfr-day-date {
  font-size: var(--fs-base);
  font-weight: var(--fw-regular);
  opacity: 0.55;
  margin-top: 2px;
}
.dfr-icon {
  display: flex;
  align-items: center;
  justify-content: center;
}
.dfr-icon img {
  width: 42px;
  height: 42px;
  display: block;
}
.dfr-weather-label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--white-85);
  opacity: 0.9;
  text-align: left;
  line-height: 1.2;
  white-space: normal;
  overflow-wrap: normal;
  word-break: normal;
  hyphens: none;
}
.dfr-temp {
  font-size: var(--fs-2xl);
  font-weight: var(--fw-regular);
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}
.dfr-tmin,
.dfr-tmax {
  font-weight: var(--fw-regular);
}
.dfr-tmin {
  text-align: left;
  color: var(--white-50);
}
.dfr-tmax {
  text-align: right;
  color: var(--white-95);
}
.dfr-temp-bar {
  position: relative;
  height: 6px;
  border-radius: 999px;
  background-color: var(--white-10);
  overflow: hidden;
}
.dfr-temp-bar-fill {
  position: absolute;
  top: 0;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, #3b82f6, #ef4444);
}
.dfr-chevron {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-lg);
  opacity: 0.5;
  transition: transform 220ms ease, opacity 160ms ease;
}
.day-forecast-toggle[aria-expanded="true"] .dfr-chevron {
  transform: rotate(180deg);
  opacity: 0.85;
}
/* Riga aperta: stessa superficie del widget, leggermente più schermata per
   distinguere l'accordion senza perdere l'allineamento con il cielo. */
.day-forecast-row.is-open {
  background-color: var(--widget-bg-solid, rgb(38 54 76 / 90%));
  background-image:
    linear-gradient(rgb(0 0 0 / 10%), rgb(0 0 0 / 10%)),
    var(--meteo-gradient, linear-gradient(180deg, #1565C0 0%, #0D47A1 45%, #0A3A7C 100%));
  background-attachment: fixed;
  background-position: 0 0;
  background-size: 100vw 100vh;
  background-repeat: no-repeat;
  border-radius: var(--r-lg);
  overflow: hidden;
  padding: 0 10px 6px;   /* respiro laterale: header+band+hairline insettati dal bordo arrotondato */
}
/* Border tra giorni resta visibile anche quando uno è aperto (spec: 1px @10% solo tra giorni). */
.day-forecast-row.is-open .day-forecast-toggle {
  background-color: transparent;
}
.day-forecast-detail {
  padding: 0;
  animation: dfDetailIn 220ms ease both;
}
.day-forecast-detail[hidden] {
  display: none;
}
@keyframes dfDetailIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
/* 4 fasce dentro l'accordion: lista verticale di card.
   Ogni card = grid 4-col x 2-row:
     row 1: label | icon | temp-bar | tmin/tmax
     row 2: vento+nums | dir | wind-bar | precip */
/* Accordion fasce orarie: GRID condiviso fra le 4 sotto-righe.
   Il container è la griglia; ogni .day-band-card è un grid item che usa SUBGRID
   per ereditare le stesse colonne → allineamento verticale perfetto fra le card
   a prescindere dalla larghezza dei contenuti.
   Dimensioni più piccole della riga padre per gerarchia visiva chiara. */
.day-bands.day-forecast-fasce-bands {
  display: flex;
  flex-direction: column;
  gap: 0;                 /* lista continua con hairline, non blocchi separati da gap */
  padding: 4px 0 0;       /* zero horizontal + zero bottom: niente strip scuro sotto ultima band */
  margin: 0;
  border: none;
  background: transparent;
  border-radius: 0;
  font-size: var(--fs-base);
}
/* Card accordion: stesso grid template della riga padre (vars condivise).
   col 12 = chev placeholder vuoto → totale colonne identico a parent →
   allineamento verticale perfetto. */
.day-bands.day-forecast-fasce-bands .day-band-card {
  display: grid;
  grid-template-columns:
    var(--mfl-col-day)
    minmax(0, 1fr)
    var(--mfl-col-precip)
    minmax(0, 0.3fr)              /* slack ridotto: icone più vicine a precip% */
    var(--mfl-col-icons)
    minmax(0, 1fr)
    var(--mfl-col-wind)
    minmax(0, 1fr)
    var(--mfl-col-temp)
    var(--mfl-col-bar)
    var(--mfl-col-temp)
    var(--mfl-col-chev);     /* placeholder vuoto = pari larghezza del chev parent */
  align-items: center;
  column-gap: var(--mfl-gap);
  row-gap: 5px;
  background-color: transparent;
  border: none;
  border-bottom: 1px solid var(--white-08);   /* hairline morbido invece di blocchi squadrati */
  padding: 13px 8px;   /* pad-x match col parent toggle → grid colonne allineate; pad-y piu' arioso */
  margin: 0;
}
.day-bands.day-forecast-fasce-bands .day-band-card:last-child {
  border-bottom: none;
}
/* Zone 1 — label time-range (es. "06–12", "12–18") */
.day-bands.day-forecast-fasce-bands .day-band-label {
  grid-column: 1;
  grid-row: 1;
  justify-self: start;
  font-size: var(--fs-sm);
  font-weight: var(--fw-regular);
  letter-spacing: 0.4px;
  color: var(--white-70);
  margin: 0;
  white-space: nowrap;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}
.day-bands.day-forecast-fasce-bands .day-band-cond {
  grid-column: 1 / 5;
  grid-row: 2;
  justify-self: start;
  min-width: 0;
  min-height: 0;
  max-width: 100%;
  display: block;
  margin: 0;
  color: var(--white-78);
  opacity: 1;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  line-height: 1.15;
  text-align: left;
  text-transform: none;
  white-space: normal;
  overflow-wrap: normal;
  word-break: normal;
  hyphens: none;
}
/* Zone 3 — precip probability chip */
.day-bands.day-forecast-fasce-bands .day-band-precip-prob {
  grid-column: 3;
  grid-row: 1;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  font-size: var(--fs-sm);
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: var(--white-80);
}
.day-bands.day-forecast-fasce-bands .day-band-precip-prob i {
  font-size: var(--fs-md);
  color: #64b5f6;
}
.day-bands.day-forecast-fasce-bands .day-band-precip-prob.is-zero {
  visibility: hidden;
}
/* Zone 5 — sub-grid 2 celle identico al parent.
   .is-day → icona piazzata nella sub-cella 1 (allineata col SOLE parent)
   .is-night → icona piazzata nella sub-cella 2 (allineata con la LUNA parent) */
.day-bands.day-forecast-fasce-bands .day-band-icon-cell {
  grid-column: 5;
  grid-row: 1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  width: 100%;
  align-items: center;
  column-gap: 0;
}
.day-bands.day-forecast-fasce-bands .day-band-icon-cell .weather-svg-icon {
  width: 30px;
  height: 30px;
  margin: 0;
  display: block;
  justify-self: center;
}
.day-bands.day-forecast-fasce-bands .day-band-icon-cell.is-day .weather-svg-icon {
  grid-column: 1;
}
.day-bands.day-forecast-fasce-bands .day-band-icon-cell.is-night .weather-svg-icon {
  grid-column: 2;
}
/* Zone 7 — wind chip (avg · gust km/h + direzione) */
.day-bands.day-forecast-fasce-bands .day-band-wind-chip {
  grid-column: 7;
  grid-row: 1;
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  white-space: nowrap;
  font-size: var(--fs-sm);
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: var(--white-80);
}
.day-bands.day-forecast-fasce-bands .day-band-wind-chip i.wi-strong-wind {
  font-size: var(--fs-md);
  color: var(--white-65);
  align-self: center;
  margin-right: 2px;
}
.day-bands.day-forecast-fasce-bands .day-band-wind-chip .dbw-gust {
  color: var(--white-95);
  font-weight: var(--fw-bold);
}
.day-bands.day-forecast-fasce-bands .day-band-wind-chip .dbw-sep {
  opacity: 0.4;
  margin: 0 1px;
}
.day-bands.day-forecast-fasce-bands .day-band-wind-chip .dbw-unit {
  opacity: 0.55;
  font-size: var(--fs-xs);
  margin-left: 2px;
}
.day-bands.day-forecast-fasce-bands .day-band-wind-chip .dbw-dir {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin-left: 6px;
  font-size: var(--fs-xs);
  color: var(--white-85);
}
.day-bands.day-forecast-fasce-bands .day-band-wind-chip .dbw-dir i {
  font-size: var(--fs-md);
  line-height: 1;
  display: inline-block;
}
.day-bands.day-forecast-fasce-bands .day-band-wind-chip.is-empty {
  opacity: 0.3;
  color: var(--white-50);
}
/* Zone 9-10-11 — temperatura: min · bar · max */
.day-bands.day-forecast-fasce-bands .day-band-tmin {
  grid-column: 9;
  grid-row: 1;
  color: var(--white-50);
  font-size: var(--fs-lg);
  font-weight: var(--fw-regular);
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.day-bands.day-forecast-fasce-bands .day-band-temp-bar {
  grid-column: 10;
  grid-row: 1;
  position: relative;
  height: 5px;
  width: 100%;
  border-radius: 999px;
  background-color: var(--white-10);
  overflow: hidden;
  display: block;
}
.day-bands.day-forecast-fasce-bands .day-band-temp-bar-fill {
  position: absolute;
  top: 0;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, #3b82f6, #ef4444);
}
.day-bands.day-forecast-fasce-bands .day-band-tmax {
  grid-column: 11;
  grid-row: 1;
  color: var(--white-95);
  font-size: var(--fs-lg);
  font-weight: var(--fw-regular);
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Mobile: solo padding verticale + dimensioni font/icone.
   Grid-template-columns NON ridichiarato — eredita dai CSS vars di .meteo-forecast-list. */
@media (max-width: 600px) {
  .day-bands.day-forecast-fasce-bands {
    padding: 6px 0 0;
    gap: 2px;
  }
  .day-bands.day-forecast-fasce-bands .day-band-card {
    padding: 9px 6px 10px;
  }
  .day-bands.day-forecast-fasce-bands .day-band-wind-chip .dbw-unit {
    display: none;
  }
  .day-bands.day-forecast-fasce-bands .day-band-icon-cell .weather-svg-icon {
    width: 26px;
    height: 26px;
  }
  .day-bands.day-forecast-fasce-bands .day-band-label,
  .day-bands.day-forecast-fasce-bands .day-band-cond,
  .day-bands.day-forecast-fasce-bands .day-band-precip-prob,
  .day-bands.day-forecast-fasce-bands .day-band-wind-chip {
    font-size: var(--fs-xs);
  }
  .day-bands.day-forecast-fasce-bands .day-band-tmin,
  .day-bands.day-forecast-fasce-bands .day-band-tmax {
    font-size: var(--fs-md);
  }
}
@media (max-width: 559px) {
  .day-bands.day-forecast-fasce-bands .day-band-card {
    padding: 8px 6px 9px;
  }
  .day-bands.day-forecast-fasce-bands .day-band-wind-chip .dbw-gust,
  .day-bands.day-forecast-fasce-bands .day-band-wind-chip .dbw-sep,
  .day-bands.day-forecast-fasce-bands .day-band-wind-chip .dbw-dir span {
    display: none;
  }
  /* Il chip e' in nowrap dentro una colonna condivisa con la riga padre: qui
     sta a 46px, e icona + media + freccia insieme non ci stanno (60px). Via
     l'icona, che e' decorativa — la freccia dice gia' che si parla di vento,
     e valore e direzione restano entrambi. Senza questa riga la freccia
     tornerebbe sopra la cifra della minima, com'era su iPhone XS. */
  .day-bands.day-forecast-fasce-bands .day-band-wind-chip i.wi-strong-wind {
    display: none;
  }
  .day-bands.day-forecast-fasce-bands .day-band-wind-chip .dbw-dir {
    margin-left: 3px;
  }
  .day-bands.day-forecast-fasce-bands .day-band-icon-cell .weather-svg-icon {
    width: 24px;
    height: 24px;
  }
}
@media (max-width: 374px) {
  .day-bands.day-forecast-fasce-bands {
    padding: 4px 0 0;
  }
  .day-bands.day-forecast-fasce-bands .day-band-card {
    padding: 7px 4px 8px;
  }
  .day-bands.day-forecast-fasce-bands .day-band-cond {
    grid-column: 1 / 6;
  }
}
/* Meta riga sotto l'header (sempre visibile, anche chiuso).
   Allineata alle colonne dell'header: condizione span col 1-2, vento+pioggia a destra. */
.dfr-meta {
  display: grid;
  grid-template-columns: 64px 48px 1fr auto auto;
  align-items: center;
  column-gap: 12px;
  width: 100%;
  margin-top: 0;
  padding: 0;
  border-top: none;
  font-size: var(--fs-base);
}
.dfr-meta .dfm-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  color: var(--white-70);
}
.dfr-meta .dfm-item i {
  font-size: var(--fs-md);
  opacity: 0.7;
}

/* Meteo: layout giornaliero Apple-style — 5 zone bilanciate.
   Layout: [day]  ←slack→  [precip%]  ←slack→  [icone day+night]  ←slack→  [vento·raffica]  ←slack→  [tmin · bar · tmax]  [chev]

   Le colonne sono definite come CSS variables così che la riga padre e le card
   dell'accordion fasce orarie usino il MEDESIMO grid template → tutti gli
   elementi si allineano sulla verticale fra parent e accordion. */
.meteo-forecast-list {
  --mfl-col-day: 56px;
  --mfl-col-precip: 60px;
  --mfl-col-icons: 74px;      /* 2 × 34 + 6 gap (icone parent giorno+notte) */
  --mfl-col-wind: 130px;
  --mfl-col-temp: 42px;
  --mfl-col-bar: clamp(80px, 14vw, 180px);
  --mfl-col-chev: 18px;
  --mfl-pad-x: 12px;
  --mfl-gap: 10px;
}
.meteo-forecast-list .day-forecast-toggle {
  display: grid;
  grid-template-columns:
    var(--mfl-col-day)        /* 1 day */
    minmax(0, 1fr)            /* 2 slack */
    var(--mfl-col-precip)     /* 3 precip% */
    minmax(0, 0.3fr)          /* 4 slack — ridotto: icone vicine a precip% */
    var(--mfl-col-icons)      /* 5 icons (day+night) */
    minmax(0, 1fr)            /* 6 slack */
    var(--mfl-col-wind)       /* 7 wind · gust */
    minmax(0, 1fr)            /* 8 slack */
    var(--mfl-col-temp)       /* 9 tmin */
    var(--mfl-col-bar)        /* 10 bar */
    var(--mfl-col-temp)       /* 11 tmax */
    var(--mfl-col-chev);      /* 12 chev */
  align-items: center;
  column-gap: var(--mfl-gap);
  row-gap: 6px;
  padding: 14px 8px;
}
.meteo-forecast-list .dfr-main {
  display: contents;
}
/* Day + date come blocco unico sulla prima riga. La griglia resta invariata:
   l'eventuale extra-width usa la colonna slack successiva senza comprimere gli altri dati. */
.meteo-forecast-list .dfr-day {
  grid-column: 1;
  grid-row: 1;
  min-width: 0;
  display: flex;
  flex-direction: row;
  align-items: baseline;
  gap: 5px;
  line-height: 1;
  white-space: nowrap;
}
.meteo-forecast-list .dfr-day-name {
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  letter-spacing: -0.2px;
  line-height: 1;
  color: var(--white-95);
}
.meteo-forecast-list .dfr-day-date {
  margin-top: 0;
  font-size: var(--fs-sm);
  font-weight: var(--fw-regular);
  letter-spacing: 0.2px;
  line-height: 1;
  color: var(--white-65);
  opacity: 1;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}
.meteo-forecast-list .dfr-day-sep {
  color: var(--white-50);
  font-size: var(--fs-sm);
  font-weight: var(--fw-regular);
}
.meteo-forecast-list .dfr-weather-label {
  grid-column: 1 / 7;
  grid-row: 2;
  min-width: 0;
  max-width: 100%;
  padding-top: 1px;
}
.meteo-forecast-list .dfr-precip-prob {
  grid-column: 3;
  grid-row: 1;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  font-size: var(--fs-base);
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: var(--white-85);
}
.meteo-forecast-list .dfr-precip-prob i {
  font-size: var(--fs-md);
  color: #64b5f6;
  opacity: 0.95;
}
.meteo-forecast-list .dfr-precip-prob-zero {
  visibility: hidden;
}
/* Col 5: sub-grid 2 celle identiche.
   Sub-cella 1 = icona giorno · Sub-cella 2 = icona notte.
   Mantiene la stessa struttura nel parent (2 icone) e nell'accordion
   (1 icona piazzata in sub-cella 1 o 2 a seconda della fascia giorno/notte). */
.meteo-forecast-list .dfr-icons {
  grid-column: 5;
  grid-row: 1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  width: 100%;
  align-items: center;
  column-gap: 4px;
}
.meteo-forecast-list .dfr-icons .dfr-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  justify-self: center;
}
.meteo-forecast-list .dfr-icons .dfr-icon-day {
  grid-column: 1;
}
.meteo-forecast-list .dfr-icons .dfr-icon-night {
  grid-column: 2;
}
.meteo-forecast-list .dfr-icons .dfr-icon img {
  width: 40px;
  height: 40px;
  display: block;
}
.meteo-forecast-list .dfr-icons .dfr-icon-night {
  opacity: 0.85;
}
.meteo-forecast-list .dfr-wind-gust {
  grid-column: 7;
  grid-row: 1;
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  white-space: nowrap;
  font-size: var(--fs-base);
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: var(--white-85);
}
.meteo-forecast-list .dfr-wind-gust i {
  font-size: var(--fs-md);
  color: var(--white-65);
  align-self: center;
  margin-right: 2px;
}
.meteo-forecast-list .dfr-wind-gust .dfr-wind-avg {
  color: var(--white-85);
}
.meteo-forecast-list .dfr-wind-gust .dfr-gust-max {
  color: var(--white-95);
  font-weight: var(--fw-bold);
}
.meteo-forecast-list .dfr-wind-gust .dfr-wind-sep {
  opacity: 0.4;
  margin: 0 1px;
}
.meteo-forecast-list .dfr-wind-gust .dfr-wind-unit {
  opacity: 0.55;
  font-size: var(--fs-xs);
  margin-left: 2px;
}
.meteo-forecast-list .dfr-tmin {
  grid-column: 9;
  grid-row: 1;
  color: var(--white-50);
}
.meteo-forecast-list .dfr-temp-bar {
  grid-column: 10;
  grid-row: 1;
  height: 5px;
}
.meteo-forecast-list .dfr-tmax {
  grid-column: 11;
  grid-row: 1;
  color: var(--white-95);
}
.meteo-forecast-list .dfr-temp {
  font-size: var(--fs-xl);
}
.meteo-forecast-list .dfr-chevron {
  grid-column: 12;
  grid-row: 1;
}

@media (max-width: 600px) {
  .meteo-forecast-list {
    --mfl-col-day: 46px;
    --mfl-col-precip: 54px;
    --mfl-col-icons: 56px;    /* 2 × 26 + 4 gap */
    --mfl-col-wind: 86px;
    --mfl-col-temp: 36px;
    --mfl-col-bar: clamp(60px, 13vw, 120px);
    --mfl-col-chev: 12px;
    --mfl-pad-x: 12px;
    --mfl-gap: 7px;
  }
  .meteo-forecast-list .day-forecast-toggle {
    padding: 12px 6px 13px;
  }
  .meteo-forecast-list .dfr-wind-gust {
    font-size: var(--fs-xs);
  }
  .meteo-forecast-list .dfr-wind-gust .dfr-wind-unit {
    display: none;
  }
  .meteo-forecast-list .dfr-wind-gust i {
    font-size: var(--fs-sm);
  }
  .meteo-forecast-list .dfr-day {
    gap: 3px;
  }
  .meteo-forecast-list .dfr-day-name,
  .meteo-forecast-list .dfr-temp {
    font-size: var(--fs-md);
  }
  .meteo-forecast-list .dfr-precip-prob {
    font-size: var(--fs-xs);
  }
  .meteo-forecast-list .dfr-day-date {
    font-size: 0.68rem;
  }
  .meteo-forecast-list .dfr-weather-label {
    grid-column: 1 / 8;
    font-size: 0.82rem;
    line-height: 1.15;
  }
  .meteo-forecast-list .dfr-precip-prob {
    gap: 4px;
  }
  .meteo-forecast-list .dfr-icons {
    gap: 4px;
  }
  .meteo-forecast-list .dfr-icons .dfr-icon img {
    width: 30px;
    height: 30px;
  }
  .meteo-forecast-list .dfr-temp-bar {
    height: 4px;
  }
}

@media (max-width: 559px) {
  .meteo-forecast-list {
    --mfl-col-day: 44px;
    --mfl-col-precip: 54px;   /* icona + valore senza contatto con la colonna icone */
    --mfl-col-icons: 56px;    /* 2 × 26 + 4 gap */
    --mfl-col-wind: 46px;     /* riga padre: sola raffica (~30px). La card della
                                 fascia usa la stessa colonna per media +
                                 freccia direzione, che a 3 cifre arrivano a
                                 44px: a 34px il chip sbordava sulla minima e
                                 la freccia finiva sopra la cifra. La colonna e'
                                 condivisa, quindi allargarla tiene allineate
                                 riga e card. */
    --mfl-col-temp: 32px;
    --mfl-col-bar: clamp(40px, 11vw, 80px);
    --mfl-pad-x: 10px;
    --mfl-gap: 2px;
  }
  .meteo-forecast-list .day-forecast-toggle {
    padding: 11px 6px 12px;
  }
  .meteo-forecast-list .dfr-icons .dfr-icon img {
    width: 26px;
    height: 26px;
  }
  .meteo-forecast-list .dfr-precip-prob i {
    font-size: var(--fs-sm);
  }
  /* Mostra solo vento medio */
  .meteo-forecast-list .dfr-wind-gust .dfr-gust-max,
  .meteo-forecast-list .dfr-wind-gust .dfr-wind-sep {
    display: none;
  }
}

@media (max-width: 374px) {
  .meteo-forecast-list {
    --mfl-col-day: 42px;
    --mfl-col-precip: 48px;
    --mfl-col-icons: 48px;    /* 2 × 22 + 4 gap */
    --mfl-col-wind: 40px;
    --mfl-col-temp: 30px;
    --mfl-col-bar: clamp(44px, 12vw, 80px);
    --mfl-col-chev: 10px;
    --mfl-pad-x: 8px;
    --mfl-gap: 5px;
  }
  .meteo-forecast-list .day-forecast-toggle {
    padding: 10px 4px;
  }
  .meteo-forecast-list .dfr-day-date,
  .meteo-forecast-list .dfr-day-sep {
    display: none;
  }
  .meteo-forecast-list .dfr-icons .dfr-icon img {
    width: 22px;
    height: 22px;
  }
}
/* Sotto i 430px le colonne fisse dei due blocchi sopra sommano ~340px, e la
   riga aperta (respiro 10px per lato) ne offre 299 a 375: tmax e chevron
   uscivano dalla card, tagliati da overflow:hidden. Qui la griglia entra:
   unita' «mm» nascosta come gia' km/h del vento, colonna pioggia da cifra
   sola, respiro della riga aperta a 4px. Misurato sull'iPhone XS (375):
   chevron a 18px dal bordo come la data a sinistra. Viene dopo il blocco
   374 di proposito, per vincere sul suo gap. */
@media (max-width: 429px) {
  .meteo-forecast-list {
    --mfl-col-precip: 34px;
    --mfl-col-temp: 30px;
    --mfl-col-bar: clamp(32px, 9vw, 80px);
    --mfl-gap: 2px;
  }
  .meteo-forecast-list .day-forecast-row.is-open {
    padding-left: 4px;
    padding-right: 4px;
  }
  .meteo-forecast-list .dfr-precip-unit,
  .day-bands.day-forecast-fasce-bands .day-band-precip-unit {
    display: none;
  }
  .meteo-forecast-list .dfr-precip-prob,
  .day-bands.day-forecast-fasce-bands .day-band-precip-prob {
    gap: 3px;
  }
}
/* Schermi stretti (<390px, iPhone SE/6/7/8 e iPhone 5): tutto leggermente
   più piccolo del default, mantenendo gerarchia. */
@media (max-width: 389px) {
  .day-forecast-toggle {
    padding: 14px 12px;
    gap: var(--sp-2);
  }
  .dfr-main {
    grid-template-columns: 56px 40px 28px 1fr 34px 16px;
    column-gap: 10px;
  }
  .fishing-forecast-list {
    --pl-chev: 14px;
    --pl-gap: var(--sp-2);
  }
  .dfr-day-date { font-size: var(--fs-sm); }
  .dfr-icon img { width: 36px; height: 36px; }
  .dfr-temp { font-size: var(--fs-xl); }
  .dfr-temp-bar { height: 5px; }
  .dfr-chevron { font-size: var(--fs-base); }
  .dfr-meta {
    grid-template-columns: 56px 40px 1fr auto auto;
    column-gap: 10px;
    font-size: var(--fs-sm);
  }
  .dfr-meta .dfm-item i { font-size: var(--fs-base); }
  /* Fasce orarie accordion: regole specifiche per il nuovo layout 5-zone
     vivono nei breakpoint ≤600/≤429/≤374 con selettore .day-band-card */
}

/* ========== WINDY-STYLE TABLE (variante C) ========== */
/* Tabella 7 righe × N ore: prima colonna sticky con label, resto scroll-x. */

/* ========== DASHBOARD ORARIA (Variante D) ========== */
/* Tabella oraria completa con sparkline temp + sezioni collassabili meteo/pesca */
.dt-widget {
  padding: 0;
  font-feature-settings: "tnum";
}
.dt-widget .dt-body {
  padding: 0 0 8px;
}
.dt-widget .dt-scroll {
  position: relative;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
}
.dt-widget .dt-scroll::-webkit-scrollbar { display: none; }

.dt-widget .dt-table {
  display: grid;
  position: relative;
  min-width: max-content;
  /* position:relative è containing block per dt-sun-overlay:
     overlay bottom:0 segue l'altezza dinamica (shrinks se sezioni collassate). */
}

/* Sparkline row */
.dt-widget .dt-spark-row {
  display: grid;
  grid-template-columns: var(--dt-label-w) 1fr;
}
.dt-widget .dt-spark-label {
  position: sticky;
  left: 0;
  z-index: 4;
  background: rgb(58, 76, 102);
  box-shadow: 4px 0 8px -5px var(--black-45);
  border-right: 1px solid var(--white-08);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 0 4px 6px;
  cursor: pointer;
}
.dt-widget .dt-spark-wrap {
  position: relative;
  padding: 4px 0 0;
}

/* Row (label sticky + cells) */
.dt-widget .dt-row {
  display: grid;
  grid-template-columns: var(--dt-label-w) 1fr;
  align-items: stretch;
}
.dt-widget .dt-row + .dt-row {
  border-top: 0.5px solid var(--white-03);
}
.dt-widget .dt-label {
  position: sticky;
  left: 0;
  z-index: 3;
  background: rgb(58, 76, 102);
  box-shadow: 6px 0 10px -6px var(--black-45);
  border-right: 1px solid var(--white-08);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 4px;
  min-height: 32px;
  font-size: var(--fs-lg);
}

/* Sidebar icon-only (Restyling 2026-04-25): label estesa + unità via tooltip */
.dt-widget .dt-lbl-icon {
  font-size: var(--fs-lg);
  line-height: 1;
  color: var(--white-78);
  cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
  .dt-widget .dt-lbl-icon:hover {
    color: var(--white-100);
  }
}

/* Cells */
.dt-widget .dt-cells {
  display: grid;
  grid-auto-columns: var(--dt-col-w);
  grid-auto-flow: column;
}
.dt-widget .dt-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  color: #fff;
  /* nessun bordo verticale: heatmap colore = separatore visivo.
     Day-boundary mantiene border-left via .dt-cell.day-start. */
  min-height: 34px;
  padding-top: 1px;
  padding-bottom: 1px;
  position: relative;
  line-height: 1;
}
/* Sun-event column: hourly slot dedicato ad alba/tramonto (HH:MM + icona).
   Colori allineati a .forecast-item.alba / .forecast-item.tramonto (vista Meteo
   forecast orario): alba = rosa tenue #ff6f91, tramonto = arancione #ffb347. */
.dt-widget .dt-cell.sun-col {
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  letter-spacing: 0.02em;
  font-feature-settings: "tnum";
}
.dt-widget .dt-cell.sun-alba {
  border-left: 1px dashed rgba(255, 111, 145, 0.7);
  border-right: 1px dashed rgba(255, 111, 145, 0.7);
  color: #ffc0cf;
  background: rgba(255, 111, 145, 0.22);
}
.dt-widget .dt-cell.sun-tramonto {
  border-left: 1px dashed rgba(255, 179, 71, 0.7);
  border-right: 1px dashed rgba(255, 179, 71, 0.7);
  color: #ffd8a0;
  background: rgba(255, 179, 71, 0.22);
}
/* Header sun cell (icon row): mantiene gradient verticale per attenuare ai bordi */
.dt-widget .dt-row-icon .dt-cell.sun-alba,
.dt-widget .dt-row-time .dt-cell.sun-alba {
  background: linear-gradient(to bottom,
    rgba(255, 111, 145, 0.05) 0%,
    rgba(255, 111, 145, 0.18) 50%,
    rgba(255, 111, 145, 0.12) 100%);
}
.dt-widget .dt-row-icon .dt-cell.sun-tramonto,
.dt-widget .dt-row-time .dt-cell.sun-tramonto {
  background: linear-gradient(to bottom,
    rgba(255, 179, 71, 0.05) 0%,
    rgba(255, 179, 71, 0.18) 50%,
    rgba(255, 179, 71, 0.12) 100%);
}
/* Default celle heatmap colorate = testo bianco. Classe .onlight (aggiunta da
   PHP/JS quando bg luminanza >= 0.55) override con testo scuro per bg chiari
   (giallo, beige, grigio chiaro). */
.dt-widget .dt-row-rain .dt-cell:not(.empty):not(.dt-zero):not(.dt-muted),
.dt-widget .dt-row-pprob .dt-cell:not(.empty):not(.dt-zero):not(.dt-muted),
.dt-widget .dt-row-snow .dt-cell:not(.empty):not(.dt-zero):not(.dt-muted),
.dt-widget .dt-row-wind .dt-cell:not(.dt-zero):not(.dt-muted),
.dt-widget .dt-row-gust .dt-cell:not(.dt-zero):not(.dt-muted),
.dt-widget .dt-row-apptemp .dt-cell:not(.empty):not(.dt-zero):not(.dt-muted),
.dt-widget .dt-row-humid .dt-cell:not(.empty):not(.dt-zero):not(.dt-muted),
.dt-widget .dt-row-cloud .dt-cell:not(.empty):not(.dt-zero):not(.dt-muted),
.dt-widget .dt-row-uv .dt-cell:not(.empty):not(.dt-zero):not(.dt-muted),
.dt-widget .dt-row-vis .dt-cell:not(.empty):not(.dt-zero):not(.dt-muted),
.dt-widget .dt-row-pressure .dt-cell:not(.empty):not(.dt-zero):not(.dt-muted),
.dt-widget .dt-row-wave .dt-cell:not(.empty):not(.dt-zero):not(.dt-muted),
.dt-widget .dt-row-wtemp .dt-cell:not(.empty):not(.dt-zero):not(.dt-muted),
.dt-widget .dt-row-fish-score .dt-cell:not(.empty):not(.dt-zero):not(.dt-muted) {
  color: #fff;
  font-weight: var(--fw-bold);
}
.dt-widget .dt-cell.onlight {
  color: #0b1018 !important;
}
/* Legacy .ondark — preservato per retrocompatibilità (alias di default bianco) */
.dt-widget .dt-cell.ondark {
  color: #fff !important;
}
/* Celle "muted" — heatmap stile Windy: nessun background quando il valore è
   trascurabile (sotto/sopra/dentro la soglia significativa). Testo soffuso. */
.dt-widget .dt-cell.dt-muted {
  background: transparent !important;
  color: var(--white-55, rgba(255, 255, 255, 0.55));
  font-weight: var(--fw-regular);
}

/* Row-specific tweaks */
.dt-widget .dt-row-day {
  border-bottom: 1px solid var(--white-06);
  background: var(--white-02);
}
.dt-widget .dt-cells-days {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  min-height: 26px;
}
.dt-widget .dt-day-segment {
  flex: 0 0 auto;
  position: relative;
  border-left: 2px solid rgba(244, 194, 75, 0.25);
  min-height: 26px;
  display: flex;
  align-items: center;
}
.dt-widget .dt-day-segment:first-child {
  border-left: none;
}
/* Day cell sticky: resta pinnato a left:var(--dt-label-w) durante scroll
   orizzontale dentro il suo segment, si rilascia al cambio giorno */
.dt-widget .dt-day-cell {
  position: sticky;
  left: var(--dt-label-w);
  display: inline-flex;
  align-items: center;
  font-size: var(--fs-xs);
  font-weight: var(--fw-regular);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--white-88);
  padding: 0 10px;
  white-space: nowrap;
  line-height: 1;
  min-height: 26px;
  z-index: 2;
}

/* Day separator: riga verticale all'inizio di ogni giorno su tutte le celle */
.dt-widget .dt-cell.day-start {
  border-left: 1px solid rgba(244, 194, 75, 0.35);
}

.dt-widget .dt-row-time .dt-cell {
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  opacity: 0.7;
  background: var(--white-02);
}
.dt-widget .dt-row-time .dt-cell.is-now {
  opacity: 1;
  font-weight: var(--fw-bold);
  color: #ffd670;
  background: rgba(255, 214, 112, 0.1);
}
.dt-widget .dt-row-icon .dt-cell {
  padding: 3px 0;
  cursor: pointer;
  min-height: 40px;
}
.dt-widget .dt-row-icon .dt-cell img,
.dt-widget .dt-row-icon .dt-cell svg {
  width: 32px;
  height: 32px;
  display: block;
  pointer-events: none;
}
.dt-widget .dt-cell.empty {
  color: var(--white-32) !important;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  background-color: rgba(255, 255, 255, 0.025) !important;
  background-image: repeating-linear-gradient(
    -45deg,
    var(--white-04),
    var(--white-04) 4px,
    transparent 4px,
    transparent 8px
  ) !important;
}

/* Cella "zero" — dato presente e pari a 0 (es. nessuna pioggia prevista).
   Trattino bianco leggero, distinguibile da empty (pattern diagonale) */
.dt-widget .dt-cell.dt-zero {
  color: var(--white-35);
  font-size: var(--fs-xs);
  font-weight: var(--fw-regular);
  background: transparent;
}
.dt-widget .dt-cell.dt-zero-rain {
  background: transparent;
  color: var(--white-35);
}
/* Segnale "rovescio possibile, accumulo ~0 mm": puntino azzurro-pioggia tenue,
   visibile anche su touch dove il tooltip non arriva. */
.dt-widget .dt-cell.has-rain-hint .dt-rain-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(95, 179, 227, 0.55);
}
.dt-widget .dt-row-rain .dt-cell:not(.empty) {
  font-size: var(--fs-xs);
}
.dt-widget .dt-row-dir .dt-cell {
  flex-direction: column;
  gap: 1px;
  padding: 2px 0;
  font-size: var(--fs-sm);
  color: var(--white-85);
}
.dt-widget .dt-dir-arrow {
  display: inline-block;
  line-height: 1;
  transform-origin: center;
  font-size: var(--fs-md);
  color: inherit;
  opacity: 1;
}
.dt-widget .dt-dir-label {
  font-size: var(--fs-xs);
  font-weight: var(--fw-regular);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--white-65);
  line-height: 1;
}
.dt-widget .dt-row-vis .dt-cell {
  padding: 4px 3px;
}
.dt-widget .dt-row-tide {
  /* Altezza della striscia: la curva SVG ($tide_curve_h nel partial) si stira su questa. */
  --dt-tide-h: 94px;
  position: relative;
  min-height: var(--dt-tide-h);
}
.dt-widget .dt-row-tide .dt-label {
  min-height: var(--dt-tide-h);
  align-items: flex-end;
  padding-bottom: 6px;
}
.dt-widget .dt-row-tide .dt-cells {
  grid-auto-rows: var(--dt-tide-h);
}
.dt-widget .dt-row-tide .dt-cell {
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  color: #bcd9f2;
  z-index: 2;
  background: transparent;
  min-height: var(--dt-tide-h);
  align-items: flex-start;
  padding-top: 3px;
}
.dt-widget .dt-row-tide .dt-cell.dt-tide-peak {
  font-weight: var(--fw-bold);
  color: #fff;
  text-shadow: 0 1px 2px var(--black-45);
}
.dt-widget .dt-tide-curve {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--dt-label-w);
  right: 0;
  pointer-events: none;
  z-index: 1;
}
.dt-widget .dt-row-fish-rating .dt-cell {
  padding: 3px 2px;
  position: relative;
}
.dt-widget .dt-fish-bar {
  position: absolute;
  left: 2px;
  right: 2px;
  top: 4px;
  bottom: 4px;
  border-radius: 2px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  letter-spacing: 0.04em;
  color: var(--black-78);
}
/* La barra è larga 40px fissi (cella 44 dal PHP), mentre --fs-xs cresce col
   root da 768px: "MAJOR" maiuscolo col tracking misurava 41,9px al telefono e
   usciva dalla cella sul tablet. Il tetto in px tiene la parola dentro la barra
   a ogni root, e lo `zoom` del blocco tablet la scala insieme alla cella. */
.dt-widget .dt-fish-bar.major {
  background: #4ade80;
  font-size: min(var(--fs-xs), 10.5px);
  letter-spacing: 0;
}
.dt-widget .dt-fish-bar.minor {
  background: rgba(74, 222, 128, 0.35);
  color: var(--white-85);
}
.dt-widget .dt-fish-bar.approaching {
  background: rgba(74, 222, 128, 0.14);
  color: var(--white-40);
}
.dt-widget .dt-fish-bar.neutral {
  background: var(--white-04);
  color: var(--white-22);
}
.dt-widget .dt-row-fish-score .dt-cell {
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  padding: 5px 0;
}

/* Sections — toggle accordion: barra full-width colorata per sezione */
.dt-widget .dt-section {
  display: grid;
  grid-template-columns: var(--dt-label-w) 1fr;
  border-top: 0.5px solid var(--white-06);
  cursor: pointer;
  user-select: none;
}
.dt-widget .dt-section-label {
  position: sticky;
  left: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6px 4px;
  background: inherit;
  border-right: 1px solid var(--white-08);
  box-shadow: 4px 0 8px -5px var(--black-45);
}
.dt-widget .dt-section-label .chev {
  font-size: var(--fs-sm);
  opacity: 0.85;
  display: inline-block;
  transition: transform 0.2s ease;
  color: #fff;
}
.dt-widget .dt-section.collapsed .dt-section-label .chev {
  transform: rotate(-90deg);
}
.dt-widget .dt-section-title {
  position: sticky;
  left: var(--dt-label-w);
  z-index: 2;
  display: flex;
  align-items: center;
  width: max-content;
  padding: 6px 12px;
  font-size: var(--fs-sm);
  font-weight: var(--fw-regular);
  letter-spacing: 0.6px;
  text-transform: uppercase;
  opacity: 0.7;
  color: #fff;
}

/* Tinte per sezione (intera barra colorata) */
.dt-widget .dt-section-vento {
  background: linear-gradient(90deg, rgba(125, 211, 192, 0.32) 0%, rgba(125, 211, 192, 0.18) 100%);
  border-top-color: rgba(125, 211, 192, 0.45);
}
.dt-widget .dt-section-vento .dt-section-title {
  color: #c8f0e3;
}
.dt-widget .dt-section-pioggia {
  background: linear-gradient(90deg, rgba(148, 168, 224, 0.32) 0%, rgba(148, 168, 224, 0.18) 100%);
  border-top-color: rgba(148, 168, 224, 0.45);
}
.dt-widget .dt-section-pioggia .dt-section-title {
  color: #d6dffb;
}
.dt-widget .dt-section-atmosfera {
  background: linear-gradient(90deg, rgba(192, 211, 125, 0.32) 0%, rgba(192, 211, 125, 0.18) 100%);
  border-top-color: rgba(192, 211, 125, 0.45);
}
.dt-widget .dt-section-atmosfera .dt-section-title {
  color: #e8f0c0;
}
.dt-widget .dt-section-mare {
  background: linear-gradient(90deg, rgba(106, 169, 224, 0.32) 0%, rgba(106, 169, 224, 0.18) 100%);
  border-top-color: rgba(106, 169, 224, 0.45);
}
.dt-widget .dt-section-mare .dt-section-title {
  color: #cae3f7;
}
.dt-widget .dt-section-pesca {
  background: linear-gradient(90deg, rgba(224, 185, 106, 0.32) 0%, rgba(224, 185, 106, 0.18) 100%);
  border-top-color: rgba(224, 185, 106, 0.45);
}
.dt-widget .dt-section-pesca .dt-section-title {
  color: #f4dfa9;
}

@media (hover: hover) and (pointer: fine) {
  .dt-widget .dt-section:hover {
    filter: brightness(1.15);
  }
}
.dt-widget .dt-section.collapsed {
  filter: saturate(0.6) brightness(0.9);
}

.dt-widget .dt-rows-group {
  grid-column: 1 / -1;
  display: block;
}
/* Restyling 2026-05-21: zebra alternato su gruppi sezioni → lettura più facile */
.dt-widget .dt-rows-group[data-dt-group="pioggia"],
.dt-widget .dt-rows-group[data-dt-group="atmosfera"],
.dt-widget .dt-rows-group[data-dt-group="mare"] {
  background: rgba(255, 255, 255, 0.015);
}
.dt-widget .dt-section.collapsed + .dt-rows-group {
  display: none;
}


/* Etichetta giorno */
.forecast-day-label {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  font-size: var(--fs-base);
  opacity: 0.6;
  padding: 3px 0;
  background-color: rgb(28 51 58 / 86%);
  border-radius: 0;
  border-bottom: solid rgba(28, 51, 58, 0.86) 3px;
  border-bottom: solid rgb(28 51 58 / 86%) 3px;
  box-sizing: border-box;
  flex-shrink: 0;
}
.forecast-day-label .giorno-label,
.forecast-day-label .giorno-num {
  text-transform: uppercase;
  font-size: var(--fs-xs);
  line-height: 1.2;
  color: #ffffff;
}
.forecast-day-label .giorno-num {
  font-size: var(--fs-sm);
}
.forecast-day-label .divider {
  width: 15px;
  height: 1px;
  background-color: #a0b8d4;
  opacity: 0.3;
  margin: 5px 0;
}

/* ========== WIND BOX COLOR GRADIENTS ========== */

.wind-line {
  line-height: 1.2;
  white-space: nowrap;
  margin-bottom: 3px;
}

.wind-line .wi-direction-up {
  display: inline-block;
  transform-origin: center;
  transition: transform 0.3s ease;
  font-size: 15px;
}

.wind-line {
  display: flex;
  align-items: center;
  justify-content: center;
}
/* iOS 12: gap non funziona in flexbox */
.wind-line > * + * { margin-left: 5px; }

.wind-line .wi-direction-up {
  display: inline-block;
  transform-origin: center;
  transition: transform 0.3s ease;
  font-size: var(--fs-lg);
  flex-shrink: 0; /* Non rimpicciolire la freccia */
}

.wind-line .wind-dir-text {
  font-size: var(--fs-xs);
  opacity: 0.9;
}

.wind-bar,
.gust-bar {
  background-color: var(--white-05);
  border-radius: 6px;
  height: 32px;
  padding: 2px 6px;
  font-size: var(--fs-xs);
  color: #e0f0ff;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
.wind-indicator {
  margin-top: 3px;
  height: 3px;
  border-radius: 2px;
  width: 60%;
}

/* Wind gradient levels — palette sincronizzata con --wind-lvl-XX (20 bin) */
.wind-box.lvl-00 {
  background: linear-gradient(0deg, rgba( 98, 113, 183, 0.5) 0%, rgba( 98, 113, 183, 0) 100%);
}
.wind-box.lvl-04 {
  background: linear-gradient(0deg, rgba( 57,  97, 169, 0.5) 0%, rgba( 57,  97, 169, 0) 100%);
}
.wind-box.lvl-11 {
  background: linear-gradient(0deg, rgba( 74, 148, 169, 0.5) 0%, rgba( 74, 148, 169, 0) 100%);
}
.wind-box.lvl-18 {
  background: linear-gradient(0deg, rgba( 77, 141, 123, 0.5) 0%, rgba( 77, 141, 123, 0) 100%);
}
.wind-box.lvl-25 {
  background: linear-gradient(0deg, rgba( 83, 165,  83, 0.5) 0%, rgba( 83, 165,  83, 0) 100%);
}
.wind-box.lvl-32 {
  background: linear-gradient(0deg, rgba( 53, 159,  53, 0.5) 0%, rgba( 53, 159,  53, 0) 100%);
}
.wind-box.lvl-40 {
  background: linear-gradient(0deg, rgba(167, 157,  81, 0.5) 0%, rgba(167, 157,  81, 0) 100%);
}
.wind-box.lvl-47 {
  background: linear-gradient(0deg, rgba(159, 127,  58, 0.5) 0%, rgba(159, 127,  58, 0) 100%);
}
.wind-box.lvl-54 {
  background: linear-gradient(0deg, rgba(161, 108,  92, 0.5) 0%, rgba(161, 108,  92, 0) 100%);
}
.wind-box.lvl-61 {
  background: linear-gradient(0deg, rgba(129,  58,  78, 0.5) 0%, rgba(129,  58,  78, 0) 100%);
}
.wind-box.lvl-68 {
  background: linear-gradient(0deg, rgba(175,  80, 136, 0.5) 0%, rgba(175,  80, 136, 0) 100%);
}
.wind-box.lvl-76 {
  background: linear-gradient(0deg, rgba(117,  74, 147, 0.5) 0%, rgba(117,  74, 147, 0) 100%);
}
.wind-box.lvl-86 {
  background: linear-gradient(0deg, rgba(109,  97, 163, 0.5) 0%, rgba(109,  97, 163, 0) 100%);
}
.wind-box.lvl-97 {
  background: linear-gradient(0deg, rgba( 68, 105, 141, 0.5) 0%, rgba( 68, 105, 141, 0) 100%);
}
.wind-box.lvl-104 {
  background: linear-gradient(0deg, rgba( 92, 144, 152, 0.5) 0%, rgba( 92, 144, 152, 0) 100%);
}
.wind-box.lvl-130 {
  background: linear-gradient(0deg, rgba(125,  68, 165, 0.5) 0%, rgba(125,  68, 165, 0) 100%);
}
.wind-box.lvl-166 {
  background: linear-gradient(0deg, rgba(231, 215, 215, 0.5) 0%, rgba(231, 215, 215, 0) 100%);
}
.wind-box.lvl-184 {
  background: linear-gradient(0deg, rgba(219, 212, 135, 0.5) 0%, rgba(219, 212, 135, 0) 100%);
}
.wind-box.lvl-277 {
  background: linear-gradient(0deg, rgba(205, 202, 112, 0.5) 0%, rgba(205, 202, 112, 0) 100%);
}
.wind-box.lvl-374 {
  background: linear-gradient(0deg, rgba(128, 128, 128, 0.5) 0%, rgba(128, 128, 128, 0) 100%);
}
.wind-box.lvl-00::after  { background-color: rgba( 98, 113, 183, 0.4); }
.wind-box.lvl-04::after  { background-color: rgba( 57,  97, 169, 0.5); }
.wind-box.lvl-11::after  { background-color: rgba( 74, 148, 169, 0.6); }
.wind-box.lvl-18::after  { background-color: rgba( 77, 141, 123, 0.7); }
.wind-box.lvl-25::after  { background-color: rgba( 83, 165,  83, 0.85); }
.wind-box.lvl-32::after  { background-color: rgba( 53, 159,  53, 0.85); }
.wind-box.lvl-40::after  { background-color: rgba(167, 157,  81, 0.9); }
.wind-box.lvl-47::after  { background-color: rgba(159, 127,  58, 0.9); }
.wind-box.lvl-54::after  { background-color: rgba(161, 108,  92, 0.95); }
.wind-box.lvl-61::after  { background-color: rgba(129,  58,  78, 1); }
.wind-box.lvl-68::after  { background-color: rgba(175,  80, 136, 1); }
.wind-box.lvl-76::after  { background-color: rgba(117,  74, 147, 1); }
.wind-box.lvl-86::after  { background-color: rgba(109,  97, 163, 1); }
.wind-box.lvl-97::after  { background-color: rgba( 68, 105, 141, 1); }
.wind-box.lvl-104::after { background-color: rgba( 92, 144, 152, 1); }
.wind-box.lvl-130::after { background-color: rgba(125,  68, 165, 1); }
.wind-box.lvl-166::after { background-color: rgba(231, 215, 215, 1); }
.wind-box.lvl-184::after { background-color: rgba(219, 212, 135, 1); }
.wind-box.lvl-277::after { background-color: rgba(205, 202, 112, 1); }
.wind-box.lvl-374::after { background-color: rgba(128, 128, 128, 1); }

/* ========== METEO ROW GENERIC LAYOUT ========== */
.meteo-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 6px; /* iOS 12: ridotto da 12px - compensato da margin-top sui figli */
}
/* iOS 12: gap non funziona in flexbox con flex-wrap; simula row-gap con margin-top sui figli */
.meteo-row > * { margin-top: 6px; }
.meteo-icon {
  font-size: var(--fs-xl);
  color: #72d9f5;
  margin-right: 8px;
}
.meteo-label {
  color: var(--white-70);
}
.meteo-value {
  color: #ffffff;
}
.divider,
.divider-sm {
  border-top: 1px solid var(--white-15);
}
.highlight {
  color: var(--white-70);
}

/* ========== SEMAFORI (DOTS & ICONS) ========== */
.dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: inline-block;
  margin-right: 3px;
}

.dot-green   { background-color: #4caf50; }
.dot-yellow  { background-color: #ffeb3b; }
.dot-orange  { background-color: #ff9800; }
.dot-red     { background-color: #f44336; }

/* Icone coerenti */
.icon-green   { color: #4caf50; }
.icon-yellow  { color: #ffeb3b; }
.icon-orange  { color: #ff9800; }
.icon-red     { color: #f44336; }

/* Palette Umidità — sincronizzata con HUMIDITY_PALETTE (config.php), getHumidity*() helpers.
   14 bin (%): <30 / <40 / <50 / <60 / <70 / <75 / <80 / <83 / <87 / <90 / <93 / <97 / <100 / =100 */
:root {
  --hum-lvl-0:  #ac5539; /* Secco estremo       (< 30%) */
  --hum-lvl-1:  #ad6e38; /* Molto secco         (< 40%) */
  --hum-lvl-2:  #ad9237; /* Secco               (< 50%) */
  --hum-lvl-3:  #69ac38; /* Confortevole basso  (< 60%) */
  --hum-lvl-4:  #38ad79; /* Confortevole        (< 70%) */
  --hum-lvl-5:  #38afad; /* Leggermente umido   (< 75%) */
  --hum-lvl-6:  #38a0ad; /* Umido               (< 80%) */
  --hum-lvl-7:  #389ead; /* Molto umido         (< 83%) */
  --hum-lvl-8:  #3894ad; /* Afoso               (< 87%) */
  --hum-lvl-9:  #3888ad; /* Afoso intenso       (< 90%) */
  --hum-lvl-10: #3984ac; /* Opprimente          (< 93%) */
  --hum-lvl-11: #387cad; /* Saturo              (< 97%) */
  --hum-lvl-12: #38629e; /* Quasi saturo        (< 100%) */
  --hum-lvl-13: #384772; /* Saturazione         (= 100%) */
}

.icon-hum-lvl-0  { color: var(--hum-lvl-0); }
.icon-hum-lvl-1  { color: var(--hum-lvl-1); }
.icon-hum-lvl-2  { color: var(--hum-lvl-2); }
.icon-hum-lvl-3  { color: var(--hum-lvl-3); }
.icon-hum-lvl-4  { color: var(--hum-lvl-4); }
.icon-hum-lvl-5  { color: var(--hum-lvl-5); }
.icon-hum-lvl-6  { color: var(--hum-lvl-6); }
.icon-hum-lvl-7  { color: var(--hum-lvl-7); }
.icon-hum-lvl-8  { color: var(--hum-lvl-8); }
.icon-hum-lvl-9  { color: var(--hum-lvl-9); }
.icon-hum-lvl-10 { color: var(--hum-lvl-10); }
.icon-hum-lvl-11 { color: var(--hum-lvl-11); }
.icon-hum-lvl-12 { color: var(--hum-lvl-12); }
.icon-hum-lvl-13 { color: var(--hum-lvl-13); }

/* Palette Visibilità — sincronizzata con VISIBILITY_PALETTE (config.php), getVisibility*() helpers.
   9 bin (km): <1.6 / <2.2 / <5 / <6 / <8 / <9 / <15 / <20 / ≥20 */
:root {
  --vis-lvl-0: #a65da6; /* Nebbia densa       (< 1.6 km) */
  --vis-lvl-1: #a261a1; /* Nebbia             (< 2.2 km) */
  --vis-lvl-2: #a75b5b; /* Foschia densa      (< 5 km)   */
  --vis-lvl-3: #a75b5b; /* Foschia            (< 6 km)   */
  --vis-lvl-4: #627aa0; /* Vis. ridotta       (< 8 km)   */
  --vis-lvl-5: #627aa0; /* Vis. moderata      (< 9 km)   */
  --vis-lvl-6: #5aa95a; /* Vis. buona         (< 15 km)  */
  --vis-lvl-7: #5ca764; /* Vis. ottima        (< 20 km)  */
  --vis-lvl-8: #778d78; /* Vis. eccellente    (≥ 20 km)  */
}

/* Granular 9-bin (uso libero) */
.icon-visi-lvl-0 { color: var(--vis-lvl-0); }
.icon-visi-lvl-1 { color: var(--vis-lvl-1); }
.icon-visi-lvl-2 { color: var(--vis-lvl-2); }
.icon-visi-lvl-3 { color: var(--vis-lvl-3); }
.icon-visi-lvl-4 { color: var(--vis-lvl-4); }
.icon-visi-lvl-5 { color: var(--vis-lvl-5); }
.icon-visi-lvl-6 { color: var(--vis-lvl-6); }
.icon-visi-lvl-7 { color: var(--vis-lvl-7); }
.icon-visi-lvl-8 { color: var(--vis-lvl-8); }

/* Coarse 4-livello UI (icone ic-counter-0 … ic-counter-3: pessima/scarsa/moderata/ottima) */
.icon-visi-0 { color: var(--vis-lvl-0); } /* pessima  → purple (bin 0-1) */
.icon-visi-1 { color: var(--vis-lvl-2); } /* scarsa   → red    (bin 2-3) */
.icon-visi-2 { color: var(--vis-lvl-4); } /* moderata → blue   (bin 4-5) */
.icon-visi-3 { color: var(--vis-lvl-6); } /* ottima   → green  (bin 6-8) */

/* Indice UV colorato */
.uv-0 {
  color: #4caf50;
}
.uv-1 {
  color: #ffeb3b;
}
.uv-2 {
  color: #ff9800;
}
.uv-3 {
  color: #f44336;
}
.uv-4 {
  color: #b71c1c;
  font-weight: var(--fw-bold);
}

/* ========== SEMAFORI WIDGET SCROLL ========== */
/* Legacy .widget-semafori layout rules rimossi (struttura dot orizzontale)
   — sostituiti dal blocco .widget-semafori .sem-row (barra gradiente). */
.uv-label {
  font-size: var(--fs-sm);
  margin-left: 4px;
}

/* ========== CHART WIDGETS ========== */

canvas {
  touch-action: none !important;
  user-select: none;
  -webkit-user-select: none;
}

.chart-actions {
  display: flex;
  align-items: flex-start;
  margin-top: 12px;
  margin-bottom: -28px;
  pointer-events: all;
  position: relative;
  z-index: 10;
}

.chart-actions .chart-btn-group {
}

.chart-actions .chart-btn {
  padding: 3px 6px;
  color: #fff;
  background-color: #0c416b;
  border-radius: 4px;
  border: none;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
}

.chart-container {
  width: 100%;
  max-width: 100%;
  height: 240px;
  min-height: 240px;
  position: relative;
  overflow: hidden;
  /*transition: opacity .15s ease-out;*/
  transition: none;
}

.chartjs-tooltip {
  z-index: 9999 !important;
  pointer-events: none;
}

/* === CHART READOUT ===
   Le letture del grafico stanno QUI, sotto il canvas, non in una bolla sopra
   di esso: con intersect:false su touch la bolla non si chiudeva mai, e con
   8 modelli copriva il grafico. Altezza riservata dal placeholder, cosi' il
   primo tocco non sposta il grafico da sotto il dito. */
.chart-readout {
  margin: 6px 0 2px;
  padding: 8px 10px;
  border-radius: 10px;
  background: rgba(0, 0, 0, .22);
  border: 1px solid rgba(255, 255, 255, .10);
  font-size: 11px;
  line-height: 1.25;
  color: #e0f7ff;
  transition: opacity .15s ease-out;
}

.chart-readout--vuoto {
  opacity: .45;
}

.chart-readout__time {
  font-weight: 700;
  font-size: 11px;
  color: #fff;
  margin-bottom: 5px;
}

.chart-readout__items {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2px 10px;
}

.chart-readout__item {
  display: flex;
  align-items: center;
  gap: 5px;
  min-width: 0;
}

.chart-readout__dot {
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  border-radius: 50%;
}

.chart-readout__nome {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: rgba(255, 255, 255, .72);
}

.chart-readout__valore {
  flex: 0 0 auto;
  font-weight: 700;
  color: #fff;
  font-variant-numeric: tabular-nums;
}

.chart-readout__footer {
  margin-top: 5px;
  padding-top: 5px;
  border-top: 1px solid rgba(255, 255, 255, .10);
  font-weight: 700;
  color: #fff;
}

@media (min-width: 430px) {
  .chart-readout__items { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 768px) {
  .chart-readout__items { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .chart-readout { font-size: 12px; }
}

.widget.widget-riga .chart-container {
  margin-top: 10px;
}

/* Grafici della Pro un filo piu' alti degli altri (+12%, 22/10/2026). */
@media (max-width: 743px) {
  .chart-unified .chart-container {
    height: 270px;
    min-height: 270px;
  }
}

/* Fix chart-unified iPad/desktop: widget-cont base è flex (justify-content:space-between
   align-items:center) pensato per coppie value/delta. Nel chart partial widget-cont
   contiene solo .chart-container — flex con align-items:center centra vertically ma
   crea width inconsistenze con Chart.js resize observer su viewport ampi.
   Soluzione: ripristina block flow dentro chart-pane. */
.chart-pane .widget-cont {
  display: block;
  text-align: left;
}

/* Marea e Solunari: chart più alto per leggere bene le 2 zone (split).
   380px: con stackWeight 19:14 (solunar-chart.js) il pannello marea rende
   ~190px = stessa altezza di disegno del chart marea laguna (227px − assi),
   così l'andamento marea ha la stessa ampiezza visiva nelle due viste.
   227 e non 240: senza la legenda nativa (tolta il 20/09/2026) l'area di
   disegno della laguna era salita a 203px. */
.widget[aria-label="Widget Tabelle Solunari"] .chart-container {
  height: 380px;
  min-height: 380px;
}

.widget[aria-label="Widget marea"] .chart-container {
  height: 227px;
  min-height: 227px;
}

/* durante l'animazione dell'accordion il canvas rimane invisibile */
.collapse.show .chart-container {
  opacity: 1;
}

/* ========== NAVBAR BOTTOM ========== */
/* FIX TASK NT-20: Navbar bottom con safe-area completo (bottom + laterale per landscape) */
.navbar-bottom-nav {
  position: fixed;
  /* Allineata alla larghezza utile dei widget nel container-custom. */
  bottom: calc(4px + var(--ui-bottom-pad));
  left: 50%;
  transform: translateX(-50%);
  width: calc(100% - 2 * var(--nav-inset));
  max-width: var(--nav-max-width);
  z-index: 999;
  /* display:flex spostato su .navbar-bottom-content (i link vivono lì ora) */
  border-radius: var(--r-pill);
  overflow: hidden;
  /* 4px di cornice intorno alla pillola della voce attiva; safe-area laterale
     per il landscape. */
  padding: 4px calc(4px + var(--safe-right)) 4px calc(4px + var(--safe-left));
}

/* iPhone PWA: abbassa la pill nella safe-area (home indicator).
   Floor 9px = valore base (no-notch/Android PWA invariato). iPhone (~34px)
   → 9px (era ~14px fino al 23/10/2026, ~38px prima). iOS<13.4 (no max()): declaration ignorata → fallback base. */
@media (display-mode: standalone) {
  .navbar-bottom-nav {
    bottom: max(9px, calc(var(--safe-bottom) - 26px));
  }
}

.nav-link-nav {
  flex: 1;
  text-align: center;
  text-decoration: none;
  color: var(--white-70);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  position: relative;
  transition: color 0.3s ease, background-color 0.3s ease;
  /* Sole icone (22/10/2026): l'etichetta e' .visually-hidden, la voce resta
     un bersaglio da 48px per il pollice. */
  min-height: 48px;
  border-radius: var(--r-pill);
}
/* Icone di sistema: contorno a riposo, piena sulla voce attiva (come Instagram). */
.nav-link-nav .ic {
  font-size: var(--nav-ico, 21px);
}
.nav-link-nav.active .ic {
  font-variation-settings: 'FILL' 1;
}
.nav-link-nav.active {
  color: #ffffff;
  /* Pillola chiara sotto la voce attiva, come Instagram: un velo bianco sopra
     la tinta della barra, nessun colore nuovo. */
  background-color: var(--white-15);
  border-radius: var(--r-pill);
}
/* Indicator trattino rimosso: la voce attiva e' bianca su pillola chiara. */
.nav-link-nav::after {
  display: none;
}

/* Attesa della vista (inizioAttesaVista in core/spa-router.js): la vista di
   destinazione arriva dal server e a schermo resta quella di prima. Non
   blocca la navbar: cambiare idea resta possibile. Contratto:
   _dev/tests/vista-attesa.test.js */
html.vista-in-attesa #main-content {
  /* !important: il fade-in del router lascia `style.opacity = "1"` inline */
  opacity: 0.5 !important;
  pointer-events: none;
  transition: opacity 0.2s ease;
}
.nav-link-nav.in-attesa .ic {
  animation: nav-attesa 0.9s ease-in-out infinite alternate;
}
@keyframes nav-attesa {
  from { opacity: 1; }
  to { opacity: 0.35; }
}
#vista-attesa-barra {
  display: none;
  position: fixed;
  /* 4px sopra le icone della location bar, che partono da --safe-top, cioe' 2px
     dentro la sfumatura di iOS 27: tarata a occhio sul 15 Pro Max (18/09/2026),
     barra 82-85, icone da 89. Il max() la tiene a schermo dove la safe area e'
     zero. */
  top: max(0px, calc(var(--safe-top, 0px) - 7px));
  left: 0;
  right: 0;
  height: 3px;
  z-index: 1300; /* sopra la chrome della mappa (nastro 1200), sotto i banner */
  pointer-events: none;
  background: linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, 0.9) 50%, transparent 100%);
  background-size: 40% 100%;
  background-repeat: no-repeat;
  animation: vista-attesa-barra 1.1s ease-in-out infinite;
}
html.vista-in-attesa #vista-attesa-barra,
html.app-busy #vista-attesa-barra { /* window.Loader, stesso segnale */
  display: block;
}
@keyframes vista-attesa-barra {
  from { background-position: -40% 0; }
  to { background-position: 140% 0; }
}
@media (prefers-reduced-motion: reduce) {
  /* attesa vista */
  .nav-link-nav.in-attesa .ic,
  #vista-attesa-barra {
    animation: none;
  }
  .nav-link-nav.in-attesa .ic { opacity: 0.6; }
  #vista-attesa-barra { background: rgba(255, 255, 255, 0.6); }
}

/* Navbar bottom iPad+ (≥768): voci un po' piu' alte, la barra si legge a
   distanza tablet. */
@media (min-width: 768px) {
  .nav-link-nav {
    min-height: 52px;
  }
}


/* Visibilità */
.badge .ic-visibility {
  vertical-align: -2px;
}

/* Lista sensori / righe widget */
.day-forecast-accordion-list .sensor-value-display {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  margin: -8px 0 0 -8px; /* iOS 12: flex-wrap gap simulation */
}
.day-forecast-accordion-list .sensor-value-display > * {
  margin: 8px 0 0 8px; /* iOS 12: flex-wrap gap simulation */
}

.day-forecast-accordion-list .station-info {
  display: flex;
  flex-wrap: wrap;
  margin: -4px 0 0 -4px; /* iOS 12: flex-wrap gap simulation */
}
.day-forecast-accordion-list .station-info > * {
  margin: 4px 0 0 4px; /* iOS 12: flex-wrap gap simulation */
}

.day-forecast-accordion-list .sensor-icon {
  display: inline-block;
  width: 24px;
  text-align: center;
}

.day-forecast-accordion-list .sensor-value-display .badge {
  font-size: 0.85em;
}

.day-forecast-accordion-list .windbar-label {
  font-size: 0.9em;
}

.day-forecast-accordion-list .windbar-bar {
  --w: 0%;
  display: block;
  height: 6px;
  border-radius: 4px;
  background: linear-gradient(
    90deg,
    var(--wind-lvl-04) 0%,
    var(--wind-lvl-25) 40%,
    var(--wind-lvl-54) 75%,
    var(--wind-lvl-97) 100%
  );
  position: relative;
  overflow: hidden;
}

.day-forecast-accordion-list .windbar-bar::after {
  content: "";
  position: absolute;
  top: 0; 
  left: 0; 
  bottom: 0;
  width: var(--w);
  background: inherit;
  border-radius: 4px;
}

/* ============================================================
   MAPPA STAZIONI
============================================================ */
/* FULL HEIGHT MAP IN VIEW STAZIONI */
body.view-mappa > .container-custom,
body.view-mappa > .container-fluid,
body.view-mappa > main,
body.view-mappa > section,
body.view-mappa > header {
  z-index: 0 !important;
}

/* Il contenitore della mappa deve crescere a 100% */
body.view-mappa #stazioni-map .mappa-map-widget,
body.view-mappa #map-container {
  height: 100% !important;
  min-height: 0 !important;
  width: 100%;
  border-radius: 0;
  overflow: hidden;
  block-size: 100vh;
}

/* Variante "widget-map" */
body.view-mappa #map-container.widget-map {
  height: 100% !important;
}

/* Evita scroll fantasma */
body.view-mappa .container-custom {
  padding: 0;
}

/* FULLSCREEN MAP – ancorata tra top e navbar */
body.view-mappa #stazioni-map {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  height: 100vh !important;
  margin: 0 !important;
  padding: 0 !important;
  border: 0;
  z-index: 200;
  display: flex;
  flex-direction: column;
}

/* Il contenitore interno della mappa riempie lo spazio */
body.view-mappa #stazioni-map .mappa-map-widget,
body.view-mappa #map-container {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  height: auto !important;
  min-height: 0 !important;
  width: 100%;
  border-radius: 0;
  overflow: hidden;
}

/* I controlli della mappa rispettano le safe areas */
body.view-mappa #stazioni-map .mappa-top { 
  top: var(--safe-top) !important; 
}
body.view-mappa #stazioni-map .mappa-bottom { 
  bottom: var(--ui-bottom-pad) !important; 
}

/* Mappa fullscreen: niente padding-top "vuoto" */
body.view-mappa .location-bar { 
  padding-top: 0 !important; 
}


#stazioni-map {
  /* Griglia condivisa dei pannelli informativi inferiori. Le stesse misure
     governano bordi, colonne e righe per evitare offset indipendenti. */
  --map-panel-edge: 15px;
  --map-panel-gap: 8px;
  /* Altezza REALE della riga player, non un valore nominale: le altre due righe
     si impilano sopra sommandola, quindi se il player rende piu' alto del token
     lo scarto si mangia il gap sopra di lui. Era 58 mentre la variante demo
     rendeva 63: il vuoto fra GPS e player misurava 3px invece di 8. */
  --map-panel-player-height: 64px;
  --map-panel-nav-gap: 8px;
}

#stazioni-map .mappa-left,
#stazioni-map .mappa-right {
  background-color: transparent;
  margin-top: 15px;
}

/* Solo l'angolo BASSO sinistro si allinea alla navbar: li' vivono i pannelli
   informativi, che con la navbar formano una pila unica. I controlli in alto
   (zoom, crocino) restano a --map-panel-edge, appesi al bordo della mappa: su
   desktop seguire il cap di 1100px li spingerebbe 90px dentro lo schermo. */
#stazioni-map .mappa-bottom.mappa-left {
  left: var(--chrome-edge);
}

#stazioni-map .mappa-left {
  left: var(--map-panel-edge);
  /* Flexbox per allineamento controlli zoom */
  display: flex !important;
  flex-direction: column;
  align-items: flex-start;
  gap: 0; /* Zoom +/- sono dentro .mappa-bar, non serve gap */
}

/* Ordine della colonna destra: layer, ricerca, bussola, GPS. La bussola sta
   dove stava il righello, che e' passato a sinistra sotto lo zoom. `order` non
   tocca l'ordine nel DOM, quindi la regola `> * + *` continua a spaziare tutti
   tranne il primo, che resta anche il primo a schermo. */
#stazioni-map .mappa-right > .mappa-control-layers { order: 0; }
#stazioni-map .mappa-right > .map-search-control     { order: 1; }
#stazioni-map .mappa-right > .btn-north              { order: 2; }
#stazioni-map .mappa-right > .btn-gps                { order: 3; }

#stazioni-map .mappa-right {
  right: var(--map-panel-edge);
  /* Flexbox per allineamento controlli (layer + GPS) */
  display: flex !important;
  flex-direction: column;
  align-items: flex-end;
}
/* iOS 12: gap non funziona in flexbox */
#stazioni-map .mappa-right > * + * { margin-top: 8px !important; }
/* Passo di 8px (era 10, avvicinati su richiesta il 16/09/2026). Le aree di
   tocco dei pulsanti in alto sono alte 40px e non 44: 4px sopra e 4 sotto, il
   vuoto si divide a meta' invece di cedere 2px al pulsante di sotto. */
#stazioni-map .mappa-top { --tocco-y: 40px; }
/* Stessa spaziatura nella colonna sinistra, dove sotto lo zoom sta il righello. */
#stazioni-map .mappa-top.mappa-left > * + * { margin-top: 8px !important; }

.mappa-top .mappa-control {
  margin: 0 !important;
  border: none;
  background-color: transparent;
  float: none !important;
}

.mappa-left .mappa-control {
  margin-left: 0 !important;
}

.mappa-touch .mappa-control-layers, .mappa-touch .mappa-bar {
  border: none !important;
}

/* Barra zoom (+/-) - layout verticale */
#stazioni-map .mappa-bar:not(.btn-gps) {
  display: flex !important;
  flex-direction: column;
  background: transparent !important;
  box-shadow: none !important;
}
/* iOS 12: gap non funziona in flexbox */
#stazioni-map .mappa-bar:not(.btn-gps) > * + * { margin-top: 8px !important; }

.mappa-control-zoom-in,
.mappa-control-zoom-out,
.mappa-control.btn-gps {
	margin-bottom: 0 !important; /* Spaziatura gestita da margin-top su > * + * */
	display: block;
	width: 32px !important;
	height: 32px !important;
	transition: background-color 0.15s ease;
	background-color: #ffffff;
	cursor: pointer;
	border-radius: 8px !important;
	background-size: 18px !important;
	color: #222222 !important;
	box-shadow: 0px 0px 8px -4px var(--black-60);
	margin-top: 0 !important;
	margin-right: 0 !important;
}

/* Media query rimossa - drawer layers ora funziona solo con click */

.mappa-control-zoom-in,
.mappa-control-zoom-out {
	line-height: 27px !important;
}

.mappa-control-zoom-out {
	margin-bottom: 0;
}

.mappa-control.btn-gps {
	margin-bottom: 0;
}

.mappa-control-zoom-in span,
.mappa-control-zoom-out span {
	color: #222222 !important;
	font-size: var(--fs-3xl) !important;
}


/* Base: pulsante GPS/Bussola */
.mappa-control.btn-gps {
  display: flex !important;
  align-items: center;
  justify-content: center;
  z-index: 10;
  /* Forza sfondo bianco (eredita da regola comune ma può essere sovrascritto) */
  background-color: #ffffff !important;
  box-shadow: 0px 0px 8px -4px var(--black-60) !important;
}

.mappa-control.btn-gps svg { 
  width: 18px; 
  height: 18px; 
  display: block; 
}

/* Il glifo cambia a ogni stato (freccia vuota / piena / ago): il colore
   accompagna il cambio, non lo sostituisce. */
.mappa-control.btn-gps svg {
  transition: color 180ms ease, transform 280ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* Stato 1: solo GPS (none) */
.mappa-control.btn-gps.state-none {
  color: #999999 !important;
}

/* Stato 1 con la bussola ripristinata al rientro: la mappa non segue ma il cono
   gira. Freccia vuota (non segue) in colore attivo, o il pulsante grigio col
   cono vivo sembra un guasto (riscontro su iPhone XS, 17/09/2026). */
.mappa-control.btn-gps.state-none.bussola-accesa {
  color: #0b84ff !important;
}

/* Stato 2: follow (bussola accesa, mappa a nord) */
.mappa-control.btn-gps.state-follow svg {
  color: #0b84ff;
}

/* Stato 3: rotate (mappa che ruota con chi guarda).
   Il vecchio `transform: rotate(316deg)` girava la stessa freccia degli altri
   due stati di un angolo fisso: sembrava un puntatore storto, non una bussola.
   Ora il glifo e' un ago, e non ha bisogno di essere ruotato. */
.mappa-control.btn-gps.state-rotate svg {
  color: #0b84ff;
}

/* ── Scala metrica ───────────────────────────────────────────────────────────
   In basso a sinistra, sopra la banda informativa: e' la riga piu' alta della
   pila dei pannelli inferiori. Quota in flusso
   (`margin-bottom`) e non `bottom`, perche' l'angolo della mappa e' un box
   dimensione-contenuto e un'ancora assoluta ci si collasserebbe dentro.
   Una linea, non un riquadro: la scala e' un riferimento sovrapposto alla
   mappa, e un fondo pieno le da' il peso di un pannello che non ha. */
#stazioni-map .mappa-bottom.mappa-left .mappa-control-scale {
  /* Ancorata come il player e la banda, NON in flusso: nell'angolo basso gli
     altri pannelli restano `position: relative` con un offset `bottom`, quindi
     occupano ancora la loro altezza nel flusso e una quota a `margin` dipende
     dall'ordine in cui i control vengono aggiunti (il player nasce dopo).
     `left: 0` perche' il bordo lo mette gia' l'angolo (`--chrome-edge`).
     Si impila sulla RIGA CHIP, non sulla banda intera: la velocita' e' alta il
     triplo ma sta a destra, e sommarla lascerebbe la scala sospesa sopra il
     vuoto a sinistra, staccata da tutto. L'altezza vera la pubblica map-hud.js
     in `--map-hud-chips-height` (0px quando i chip non ci sono). */
  position: absolute;
  left: 0;
  margin: 0 !important;
  bottom: calc(
    var(--nav-top, 90px) +
    var(--map-panel-nav-gap) +
    var(--map-hud-chips-height, 0px) +
    var(--map-panel-gap) -
    var(--ui-bottom-pad)
  );
  pointer-events: none;        /* e' un riferimento, non un comando */
}


/* Col player a schermo sale di una riga, come la banda informativa. */
#stazioni-map[data-player="on"] .mappa-bottom.mappa-left .mappa-control-scale {
  bottom: calc(
    var(--nav-top, 90px) +
    var(--map-panel-nav-gap) +
    var(--map-panel-player-height) +
    var(--map-panel-gap) +
    var(--map-hud-chips-height, 0px) +
    var(--map-panel-gap) -
    var(--ui-bottom-pad)
  );
}

#stazioni-map .mappa-control-scale-line {
  /* Solo le tre stanghette del righello: niente fondo, niente riquadro. */
  border: 2px solid #fff;
  border-top: none;
  border-radius: 0;
  background: none;
  color: #fff;
  font-size: var(--fs-xs);
  line-height: 1.15;
  padding: 0 4px 2px;
  /* Il contrasto lo fa l'ombra, non un fondo: la scala resta leggibile sia sul
     basemap chiaro sia su quello scuro senza coprire la mappa. */
  text-shadow: 0 1px 2px rgb(0 0 0 / 70%), 0 0 3px rgb(0 0 0 / 50%);
  filter: drop-shadow(0 1px 2px rgb(0 0 0 / 55%));
  box-shadow: none;
}

/* ── Righello ────────────────────────────────────────────────────────────────
   Stesso pulsante degli altri control, con uno stato acceso: mentre misura, il
   tocco sulla mappa non fa piu' quello che faceva prima, e questo va detto. */
.mappa-control.btn-ruler {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background-color: #ffffff !important;
  box-shadow: 0px 0px 8px -4px var(--black-60) !important;
  color: #222222;
  cursor: pointer;
  z-index: 10;
  transition: background-color 150ms ease, color 150ms ease;
}

/* Legenda del layer Marea in laguna (acqua disponibile): in colonna sotto il
   righello, stesso bianco dei bottoni, gradini dall'asciutto al profondo. */
.mappa-control.mappa-legenda-acqua {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 6px 5px;
  border-radius: 8px;
  background-color: #ffffff !important;
  box-shadow: 0px 0px 8px -4px var(--black-60) !important;
  color: #222222;
  pointer-events: none;   /* solo da leggere: il tocco passa alla mappa */
}
.mappa-legenda-acqua__titolo {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  text-align: center;
  line-height: 1.1;
}
.mappa-legenda-acqua__voce {
  display: flex;
  align-items: center;
  gap: 4px;
}
.mappa-legenda-acqua__colore {
  flex: 0 0 auto;
  width: 8px;
  height: 14px;
  border-radius: 2px;
}
.mappa-legenda-acqua__testo {
  font-size: var(--fs-xs);
  line-height: 1;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.mappa-control.btn-ruler svg {
  width: 18px;
  height: 18px;
  display: block;
}

.mappa-control.btn-ruler.is-on {
  background-color: #0b84ff !important;
  color: #ffffff;
}

.mappa-control.btn-ruler:active {
  transform: translateY(1px);
}

/* Il cursore dice che la mappa e' in un'altra modalita' (solo dove esiste). */
#stazioni-map .mappa-container.is-misurando {
  cursor: crosshair;
}

/* Etichetta della misura: sta sull'ultimo vertice, dove guarda l'occhio. */
#stazioni-map .mappa-tooltip.map-righello__eti {
  background: var(--map-chrome-bg, rgb(26 38 52 / 92%));
  border: 1px solid var(--white-15);
  color: #fff;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
  padding: 3px 8px;
  border-radius: 999px;
  box-shadow: var(--map-chrome-shadow, 0 10px 30px rgb(0 0 0 / 30%));
  white-space: nowrap;
}
#stazioni-map .mappa-tooltip.map-righello__eti::before {
  border-top-color: var(--map-chrome-bg, rgb(26 38 52 / 92%));
}

/* ── Info del punto (tap lungo) ──────────────────────────────────────────────
   Vive dentro il popup bianco delle stazioni: stessa cornice, stesso colore di
   testo, cosi' la mappa non impara un secondo linguaggio per una scheda. */
.map-punto {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 208px;
}

.map-punto__coord {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  /* La × del popup sta nell'angolo, 24px: senza questo spazio il titolo le
     arriva a 1px (misurato) e con una stringa piu' lunga ci finisce sotto. */
  padding-right: 18px;
}

.map-punto__da-te,
.map-punto__dato,
.map-punto__fondale {
  font-size: var(--fs-sm);
  opacity: 0.75;
  font-variant-numeric: tabular-nums;
}

.map-punto__titolo {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  padding-right: 18px;
  overflow-wrap: anywhere;
}

.miei-poi-popup__nota {
  white-space: pre-line;
  overflow-wrap: anywhere;
}

/* Una nota lunga non allarga il popup oltre lo schermo (come la richiesta d'aiuto). */
.miei-poi-popup {
  max-width: min(280px, calc(100vw - 64px));
}

/* Modulo «I miei punti»: campi a tutta larghezza; 16px evita lo zoom di iOS sul focus. */
.miei-poi-modulo {
  gap: 6px;
  width: min(260px, calc(100vw - 64px));
}

.miei-poi-modulo__campo {
  width: 100%;
  font-size: 16px;
  padding: 6px 8px;
  border: 1px solid rgb(0 0 0 / 20%);
  border-radius: 8px;
  background: #fff;
  color: inherit;
}

.map-punto__bloccato {
  cursor: pointer;
  text-decoration: underline dotted;
}

/* Le tre azioni sono una riga SOLA, e si stringono invece di andare a capo.
   A larghezza intrinseca stavano dentro per l'11% (192px su 215 misurati) e la
   larghezza gliela detta il titolo `nowrap`: col font di iOS quel margine
   sparisce e «Apri» finisce su una seconda riga spaiata. In colonne 1fr la
   riga e' stabile per costruzione, e regge sia due bottoni sia tre (Condividi
   esiste solo dove c'e' `navigator.share`). */
.map-punto__azioni {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 6px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid rgb(0 0 0 / 8%);
}

.map-punto__azione {
  appearance: none;
  border: 0;
  background: rgb(0 0 0 / 6%);
  color: inherit;
  border-radius: 10px;
  /* Sola icona: il target sta tutto nel bottone, quindi 38px di altezza sono il
     pavimento — il popup si apre di proposito e il dito sa dove va, ma 28px
     erano meta' di un target comodo. */
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 38px;
  padding: 0 6px;
  min-width: 0;
  cursor: pointer;
}

.map-punto__azione .ic {
  font-size: 18px;
  line-height: 1;
}

.map-punto__azione:active {
  background: rgb(0 0 0 / 12%);
}

/* ── Bussola del nord: sempre a schermo, l'ago segue la mappa ─────────────── */
.mappa-control.btn-north {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  /* La spaziatura fra i control della colonna destra la mette gia'
     `#stazioni-map .mappa-right > * + *`: qui non si tocca il margine. */
  border-radius: 8px;
  background-color: #ffffff !important;
  box-shadow: 0px 0px 8px -4px var(--black-60) !important;
  color: #222222;
  cursor: pointer;
  z-index: 10;
  transition: background-color 150ms ease;
}

/* A mappa ruotata il pulsante non e' piu' solo un'indicazione: e' il comando
   che riporta a nord, e lo dice cambiando fondo. */
.mappa-control.btn-north.is-on {
  background-color: #f2f7ff !important;
}

.mappa-control.btn-north .btn-north__ago {
  display: block;
  width: 20px;
  height: 20px;
  /* L'angolo lo scrive il JS a ogni evento `rotate`: nessuna transizione, o
     insegue in ritardo la mappa mentre gira. */
  transform-origin: 50% 50%;
}

.mappa-control.btn-north svg {
  width: 20px;
  height: 20px;
  display: block;
}

.mappa-control.btn-north:active {
  transform: scale(0.94);
}

/* Hover/active - solo GPS (non layer toggle per evitare glitch) */
@media (hover: hover) and (pointer: fine) {
  .mappa-control.btn-gps:hover {
    background: #f7fbff;
  }
}

.mappa-control.btn-gps:active {
  transform: translateY(1px);
}

.mappa-control-zoom-in:active,
.mappa-control-zoom-out:active {
  transform: translateY(1px);
}


/* Drawer layers - contenitore */
.mappa-control-layers {
  pointer-events: auto;
  z-index: 1000;
  position: relative;
  width: 32px !important;
  height: 32px !important;
  min-width: 32px !important;
  max-width: 32px !important;
  min-height: 32px !important;
  max-height: 32px !important;
  margin-bottom: 0 !important;
  overflow: visible !important;
}

/* Mantieni dimensione fissa anche quando aperto: un padding sul contenitore
   sposterebbe il toggle DENTRO di lui e il pannello ancorato a `right: 42px`
   (misurato: +6px a ogni apertura). */
.mappa-control-layers.mc-layers-open {
  width: 32px !important;
  height: 32px !important;
  min-width: 32px !important;
  max-width: 32px !important;
  min-height: 32px !important;
  max-height: 32px !important;
  padding: 0 !important;
}

/* Drawer layers - lista (nascosta di default) */
.mappa-control-layers-list {
  display: none;
  position: absolute !important;
  top: 0;
  right: 42px; /* A sinistra del toggle button */
  z-index: 100;
  width: 220px;
  max-height: 70vh;
  overflow-y: auto;
  padding: 12px 14px;
  background: #ffffff;
  border-radius: 12px;
  box-shadow: 0 4px 20px var(--black-15), 0 0 0 1px var(--black-05);
  pointer-events: auto;
  /* Animazione apertura */
  opacity: 0;
  transform: translateX(10px) scale(0.95);
  transform-origin: right top;
  transition: opacity 0.2s ease, transform 0.2s ease;
}

/* Drawer aperto - mostra lista con animazione */
.mappa-control-layers.mc-layers-open .mappa-control-layers-list {
  display: block;
  opacity: 1;
  transform: translateX(0) scale(1);
}

/* Toggle button - stile stabile */
.mappa-control-layers-toggle {
  display: block !important;
  position: relative !important;
  width: 32px !important;
  height: 32px !important;
  margin: 0 !important;
  background-color: #ffffff !important;
  background-position: center !important;
  background-size: 18px !important;
  border: none !important;
  border-radius: 8px !important;
  box-shadow: 0px 0px 8px -4px var(--black-60) !important;
  cursor: pointer;
  /* Previeni spostamenti e animazioni indesiderate */
  transform: none !important;
  transition: background-color 0.15s ease !important;
}

/* Toggle button - hover */
@media (hover: hover) and (pointer: fine) {
  .mappa-control-layers-toggle:hover {
    background-color: #f5f5f5 !important;
  }
}

/* Toggle button - quando drawer aperto */
.mappa-control-layers.mc-layers-open .mappa-control-layers-toggle {
  background-color: #e8f4ff !important;
}

/* Niente tooltip del browser sul toggle dei livelli */
.mappa-control-layers-toggle[title] {
  font-size: 0 !important;
}

/* RIMUOVI hover per aprire drawer - solo click/tap */
/* (nessuna regola :hover per display) */

/* Drawer layers - stile labels */
.mappa-control-layers label {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  column-gap: 10px;
  font-size: var(--fs-md);
  color: #333;
  padding: 5px 0px;
  margin: 0;
  width: 100%;
  box-sizing: border-box;
  border-radius: 6px;
  cursor: pointer;
  transition: background-color 0.15s ease;
}

@media (hover: hover) and (pointer: fine) {
  .mappa-control-layers label:hover {
    background-color: #f5f5f5;
  }
}

/* Interruttori e radio del pannello layer.
   Agganciati anche alla LISTA (overlay = checkbox, basemap = radio), non solo alle
   classi .lc-toggle-row/.lc-radio-row che mette il JS (layer-control-decorator.js):
   se quel JS non gira o gira tardi, con le sole regole per classe si vedevano
   checkbox e radio NATIVI. Le classi restano: dal JS dipendono ancora header di
   gruppo e ordinamento, non piu' l'aspetto dei controlli. */
.mappa-control-layers-overlays label,
.mappa-control-layers label.lc-toggle-row {
  grid-template-columns: 36px 1fr;
}

/* Riga inibita: in modalita' bussola gli overlay canvas non ruotano, quindi
   non devono poter essere riaccesi. Resta leggibile (non si nasconde: sparire
   e ricomparire e' peggio che essere spenta) ma non risponde al tocco; il
   perche' sta nel title, messo dal decorator. La rete di sicurezza vera e' a
   livello di layer in stazioni-map-core: questa e' la parte che si vede.
   REGOLA A SE': va tenuta fuori da qualunque elenco di selettori. Infilata in
   testa a quello sopra, si e' portata dietro `.mappa-control-layers-overlays
   label` e ha spento TUTTE le righe, sempre. */
.mappa-control-layers label.lc-inibito {
  opacity: .42;
  pointer-events: none;
  cursor: default;
}

.mappa-control-layers-overlays label input[type="checkbox"],
.mappa-control-layers label.lc-toggle-row input[type="checkbox"] {
  -webkit-appearance: none;
  appearance: none;
  width: 36px;
  height: 22px;
  margin: 0;
  border-radius: 999px;
  border: 1px solid #c7ced8;
  background: #dde3ea;
  position: relative;
  cursor: pointer;
  transition: background-color 0.2s ease, border-color 0.2s ease;
}

.mappa-control-layers-overlays label input[type="checkbox"]::after,
.mappa-control-layers label.lc-toggle-row input[type="checkbox"]::after {
  content: "";
  position: absolute;
  top: 1px;
  left: 1px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px var(--black-25);
  transition: transform 0.2s ease;
}

.mappa-control-layers-overlays label input[type="checkbox"]:checked,
.mappa-control-layers label.lc-toggle-row input[type="checkbox"]:checked {
  background: #0b84ff;
  border-color: #0b84ff;
}

.mappa-control-layers-overlays label input[type="checkbox"]:checked::after,
.mappa-control-layers label.lc-toggle-row input[type="checkbox"]:checked::after {
  transform: translateX(14px);
}

.mappa-control-layers-overlays label input[type="checkbox"]:focus-visible,
.mappa-control-layers label.lc-toggle-row input[type="checkbox"]:focus-visible {
  outline: 2px solid rgba(11, 132, 255, 0.35);
  outline-offset: 2px;
}

/* Livello che il piano non apre: in elenco, spento, col lucchetto (pannello-livelli.js). */
.mappa-control-layers label.mc-livello-chiuso { opacity: 0.55; cursor: pointer; }
.mappa-control-layers label.mc-livello-chiuso input { pointer-events: none; }
/* Bussola e Linea di prua: figlie di Navigazione, grigie finche' e' spenta */
.mappa-control-layers label.mc-livello-figlio { padding-left: 22px; }
.mappa-control-layers label.mc-livello-inattivo { opacity: 0.45; }
.mappa-control-layers label.mc-livello-inattivo input { pointer-events: none; }
.mc-livello-lucchetto { margin-left: 6px; font-size: 0.8em; }

.mappa-control-layers-base label,
.mappa-control-layers label.lc-radio-row {
  grid-template-columns: 18px 1fr;
}

.mappa-control-layers-base label input[type="radio"],
.mappa-control-layers label.lc-radio-row input[type="radio"] {
  -webkit-appearance: none;
  appearance: none;
  width: 18px;
  height: 18px;
  margin: 0;
  border: 1.5px solid #9aa6b2;
  border-radius: 50%;
  background: #fff;
  position: relative;
  cursor: pointer;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.mappa-control-layers-base label input[type="radio"]::after,
.mappa-control-layers label.lc-radio-row input[type="radio"]::after {
  content: "";
  position: absolute;
  top: 4px;
  left: 4px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #0b84ff;
  transform: scale(0);
  transition: transform 0.18s ease;
}

.mappa-control-layers-base label input[type="radio"]:checked,
.mappa-control-layers label.lc-radio-row input[type="radio"]:checked {
  border-color: #0b84ff;
  box-shadow: 0 0 0 2px rgba(11, 132, 255, 0.2);
}

.mappa-control-layers-base label input[type="radio"]:checked::after,
.mappa-control-layers label.lc-radio-row input[type="radio"]:checked::after {
  transform: scale(1);
}

.mappa-control-layers-base label input[type="radio"]:focus-visible,
.mappa-control-layers label.lc-radio-row input[type="radio"]:focus-visible {
  outline: 2px solid rgba(11, 132, 255, 0.35);
  outline-offset: 2px;
}

/* Rimossa la regola generica di ripiego per i radio nativi (16px + accent-color):
   stessa specificita' del blocco .mappa-control-layers-base label sopra ma piu'
   in basso nel foglio, quindi vinceva lei e i radio restavano a 16px invece dei 18
   del pallino disegnato. Ora tutti i radio del control passano da quel blocco. */

/* Drawer layers - gruppi/sezioni */
.mappa-control-layers .lc-group {
  margin-top: 12px !important;
  padding-top: 10px;
  border-top: 1px solid #eee;
  color: #666 !important;
  font-size: var(--fs-xs) !important;
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-bottom: 4px !important;
}

.mappa-control-layers .lc-group:first-child {
  margin-top: 0 !important;
  padding-top: 0;
  border-top: none;
}

/* Drawer layers - sezione base maps e overlays */
.mappa-control-layers-base,
.mappa-control-layers-overlays {
  padding: 0;
  margin: 0;
}

.mappa-control-layers-separator {
  height: 1px;
  background: #eee;
  margin: 10px 0;
  border: none;
}


/* Popup stazioni coerente con i widget */
.station-popup {
  max-width: 300px;
}

.station-popup .station-name {
  font-weight: var(--fw-bold);
  border-bottom: 1px solid #dee2e6;
  padding-bottom: 0.4rem;
  margin-bottom: 5px;
  font-size: var(--fs-md);
}

.station-popup .station-name .badge {
  font-size: var(--fs-xs);
  text-transform: uppercase;
}

.sensor-popup-item {
  padding: 4px 0px;
  border-bottom: 1px solid var(--black-06);
  font-size: var(--fs-sm);
  line-height: 110%;
}

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

.sensor-popup-item .sensor-name {
  font-weight: var(--fw-bold);
  color: #495057;
}

#stazioni-map .maplibregl-popup-content {
  background: #fff;
  color: #2b2f36;
  border-radius: 10px;
  box-shadow: var(--shadow-elevated); /* FIX TASK NT-34 */
}

/* Marker e popup sono fratelli DOM senza z-index, quindi un pin creato dopo
   (cluster che si scioglie a un pan) coprirebbe un popup aperto. */
#stazioni-map .maplibregl-popup {
  z-index: 3;
}

/* Mappa GL: la X del popup (24x24, angolo in alto a
   destra: `.map-punto__coord` le lascia 18px), focus visibile da tastiera e
   area di tocco allargata con lo pseudo-elemento, come le altre del 15/09. */
#stazioni-map .maplibregl-popup-close-button {
  top: 0;
  right: 0;
  width: 24px;
  height: 24px;
  font-size: 18px;
  line-height: 24px;
  color: #757575;
}
#stazioni-map .maplibregl-popup-close-button::after {
  content: "";
  position: absolute;
  inset: -10px -10px -6px -6px;
}
#stazioni-map .maplibregl-popup-close-button:focus-visible {
  outline: 2px solid #0a84ff;
  outline-offset: -2px;
}

/* MarkerCluster */
#stazioni-map .marker-cluster-small {
background-color: rgb(255 193 7 / 35%);
}
#stazioni-map .marker-cluster-small div {
  background: #FF9800;
}

#stazioni-map .marker-cluster-medium {
  background: rgb(255 87 34 / 35%);
}
#stazioni-map .marker-cluster-medium div {
  background: #FF5722;
}

#stazioni-map .marker-cluster-large {
  background: rgb(255 87 34 / 35%);
}
#stazioni-map .marker-cluster-large div {
  background: #FF5722;
}

#stazioni-map .marker-cluster div {
  color: #fff;
  font-size: var(--fs-sm);
}



.mappa-bottom .mappa-control.radar-ctl {
 /* --map-panel-left-width e --map-panel-row-height sono spariti con i due
    pannelli che li usavano: il player si dimensiona da se' poche righe sotto. */
 height: auto;
 min-height: 44px;
 margin: 0 !important;
 left: 0;
 /* Ancorato al TOP della navbar: --nav-top = mapRect.bottom - navTop, misurato da
    custom.js sullo stesso offsetParent (#stazioni-map). Sottrae --ui-bottom-pad
    perche' .mappa-bottom lo aggiunge gia' (evita doppio conteggio safe-area:
    in PWA li alzava ~34px di troppo). Resta sopra la navbar in browser e PWA.
    Fallback 90px per pre-init JS. Il player occupa la riga bassa completa;
    GPS e dati vento hanno righe proprie sopra di lui. */
 bottom: calc(var(--nav-top, 90px) + var(--map-panel-nav-gap) - var(--ui-bottom-pad));
 position: absolute;
 font-size: var(--fs-lg) !important;
 line-height: 135% !important;
 border-radius: 6px !important;
 color: #ffffff !important;
 /* Stessa ardesia della navbar, stessa densita' guidata dal basemap. */
 background-color: var(--map-chrome-bg, rgb(26 38 52 / 92%)) !important;
 border: 1px solid var(--white-15) !important;
 box-shadow: var(--map-chrome-shadow, 0 10px 30px rgb(0 0 0 / 30%));
 /* NIENTE backdrop-filter qui, a differenza della navbar: questi pannelli stanno
    sopra una mappa che si trascina, e un blur va ri-rasterizzato a ogni frame di
    pan. Il contratto e' bloccato in widget-solid-background.test.js. Sulle
    basemap chiare la copertura e' 0.92, quindi la sfocatura non servirebbe. */
 padding: 6px 8px !important;
 box-sizing: border-box;
}

/* Override .pwa-mode rimossi: --nav-top è misurato (include safe-area), copre
   browser e PWA senza distinzione. */

.mappa-bottom .mappa-control.radar-ctl {
	/* Riga touch autonoma: margini identici alla mappa e nessuna colonna GPS che
	   sottragga spazio allo scrubber. */
	left: 0 !important; /* l'angolo basso applica già --chrome-edge */
	width: calc(
	  100vw -
	  var(--chrome-edge) -
	  var(--chrome-edge)
	) !important;
	min-width: 0 !important;
	height: var(--map-panel-player-height) !important;
	min-height: var(--map-panel-player-height) !important;
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 6px 10px 6px 8px !important;
	box-sizing: border-box;
}

/* La variante @media (prefers-color-scheme: dark) e' stata rimossa il 22/08/2026:
   questi pannelli galleggiano sulle tile, non sulla pagina: a decidere quanto
   devono coprire e' il basemap attivo (--map-chrome-bg), non il tema di sistema.
   Con lo schema scuro e la basemap Light la vecchia regola li scuriva proprio
   dove servivano piu' stacco, non meno. */

/*
 * NOTE: @media (display-mode: standalone) removed
 *
 * No longer needed - safe-area CSS variables automatically handle
 * the difference between Safari browser and PWA full-screen mode:
 * - Safari browser: --safe-bottom = 0px (navbar present)
 * - PWA mode: --safe-bottom = ~34px (home indicator area)
 *
 * calc() formulas above will automatically adjust positioning
 */


/* ── Banda informativa della mappa (MapHud) ──────────────────────────────────
   Sostituisce i due pannelli gps-ctl e wind-ctl, che insieme coprivano 116px di
   mappa per cinque righe in cui meta' della larghezza erano le etichette. Qui
   l'etichetta la porta l'icona, e la velocita' esce dal pannello.
   E' l'unico elemento sopra il player: la sua altezza puo' restare libera,
   perche' nessuno si impila sopra di lei. */
.mappa-bottom .mappa-control.map-hud {
  left: 0;                     /* l'angolo basso applica gia' --chrome-edge */
  /* Quota SENZA player: la banda sta subito sopra la navbar. E' il default di
     proposito — l'attributo data-player lo scrive TemporalTimeline._show(), e
     se non l'ha ancora scritto il player non c'e': partire dall'altra ipotesi
     lascerebbe un vuoto di 66px fra i dati e la navbar. */
  bottom: calc(
    var(--nav-top, 90px) +
    var(--map-panel-nav-gap) -
    var(--ui-bottom-pad)
  );
  width: calc(100vw - var(--chrome-edge) - var(--chrome-edge)) !important;
  min-width: 0 !important;
  max-width: calc(100vw - var(--chrome-edge) - var(--chrome-edge)) !important;
  margin: 0 !important;
  padding: 0 !important;
  background: none !important;
  border: 0 !important;
  box-shadow: none !important;
  display: flex;
  align-items: flex-end;
  gap: 12px;
  box-sizing: border-box;
  color: #fff;
  pointer-events: none;        /* la banda non ruba il pan alla mappa */
}

/* Col player a schermo la banda sale di una riga. */
#stazioni-map[data-player="on"] .mappa-bottom .mappa-control.map-hud {
  bottom: calc(
    var(--nav-top, 90px) +
    var(--map-panel-nav-gap) +
    var(--map-panel-player-height) +
    var(--map-panel-gap) -
    var(--ui-bottom-pad)
  );
}

/* ── Velocita': il dato dominante, fuori da qualsiasi pannello ───────────── */
.mappa-bottom .mappa-control.map-hud .hud-velocita {
  display: flex;
  align-items: baseline;
  gap: 4px;
  flex: 0 0 auto;
  /* A destra, lontano dai numeri dei chip: due grandezze diverse accostate si
     leggono come una sola. Il posto lo tiene .hud-destra. */
  /* Senza fondo la leggibilita' se la deve portare il testo. Il solo alone
     morbido NON bastava: misurato sui quattro basemap, su Light dava 2,9:1 e su
     OSM 3,6:1 — sotto o al limite della soglia, proprio dove il fondo e' chiaro.
     Serve un contorno vero, che crea contrasto locale a prescindere dal fondo.
     paint-order mette lo stroke DIETRO il riempimento: senza, il contorno
     mangerebbe il bianco dall'interno e il numero risulterebbe piu' magro. */
  -webkit-text-stroke: 3px rgb(0 0 0 / 82%);
  paint-order: stroke fill;
  text-shadow: 0 0 16px rgb(0 0 0 / 45%);
  /* La base delle cifre sul fondo dei chip. Il `padding-bottom: 10px` del
     20/09 teneva la scatola intorno a tutto il glifo, compresa la discesa che
     le cifre non usano, e alzava il numero di 14px sopra le pillole (iPhone
     XS, 22/09/2026: base 687, chip fino a 701). Con -4px la base cade a 701 e
     le cifre restano 12px sopra la navbar (713). */
  margin-bottom: -4px;
}

.mappa-bottom .mappa-control.map-hud .hud-velocita__num {
  /* rem, non px: segue il Dynamic Type invece di ignorarlo.
     Scala 1,5x rispetto ai 2,5-3,5rem iniziali: in barca o in bici il numero si
     legge di sfuggita, a braccio teso e in movimento — era dimensionato per una
     lettura da fermi. I tre termini del clamp sono scalati insieme, o il vw
     cambierebbe il breakpoint a cui il numero smette di crescere. */
  font-size: clamp(3.75rem, 18vw, 5.25rem);
  font-weight: var(--fw-semibold);
  line-height: 0.95;           /* leading stretto: e' testo display, non copy */
  letter-spacing: -0.02em;     /* sopra i 40px le cifre si allontanano otticamente */
  /* Cifre a larghezza fissa: senza, a velocita' alta il numero balla
     lateralmente a ogni aggiornamento ed e' illeggibile in movimento. */
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

.mappa-bottom .mappa-control.map-hud .hud-velocita__unita {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  letter-spacing: 0.01em;      /* tracking positivo: e' testo piccolo */
  opacity: 0.85;
}

/* ── Chip: icona + valore, niente parola ─────────────────────────────────── */
/* Fila da sinistra: prima precisione e altitudine del GPS, poi i dati dei
   layer nell'ordine di ORDINE (map-hud.js). Un chip spento non lascia buchi;
   oltre la larghezza si va a capo. Mai striscia scorrevole: mangerebbe il
   tocco. */
.mappa-bottom .mappa-control.map-hud .hud-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  align-content: flex-end;     /* con una sola riga i chip stanno in basso, sulla base della velocita' */
  justify-content: flex-start;
  gap: 6px;
  order: 1;
  flex: 1 1 0;
  min-width: 0;                /* o il contenuto sfonda il flex row */
}

.mappa-bottom .mappa-control.map-hud .hud-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 8px;
  border-radius: 999px;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  line-height: 1.2;
  white-space: nowrap;
  /* Stessa ardesia della navbar e dei control: un colore solo su tutta la
     mappa, densita' guidata dal basemap attivo. */
  background-color: var(--map-chrome-bg, rgb(26 38 52 / 92%));
  border: 1px solid var(--white-15);
  box-shadow: var(--map-chrome-shadow, 0 10px 30px rgb(0 0 0 / 30%));
}

/* Destra: la (i) delle fonti, discreta, e la velocita'. A destra anche senza
   chip: margin-left:auto, non space-between. */
.mappa-bottom .mappa-control.map-hud .hud-destra {
  order: 2;
  margin-left: auto;
  display: flex;
  align-items: flex-end;
  gap: 8px;
  flex: 0 0 auto;
}

/* I chip li accende e spegne map-hud scrivendo `display`. Senza transizione
   comparivano e sparivano di scatto sotto il numero, a ogni cambio di layer o
   di copertura dei dati: `allow-discrete` + `@starting-style` fanno la
   dissolvenza in entrambi i versi mantenendo il `display: none` (che serve: il
   chip assente non deve occupare spazio nella riga). */
.mappa-bottom .mappa-control.map-hud .hud-chip {
  transition: opacity 180ms ease, transform 180ms cubic-bezier(0.22, 0.61, 0.36, 1),
              display 180ms allow-discrete;
  opacity: 1;
  transform: translateY(0);
}

@starting-style {
  .mappa-bottom .mappa-control.map-hud .hud-chip {
    opacity: 0;
    transform: translateY(4px);
  }
}

.mappa-bottom .mappa-control.map-hud .hud-chip[style*="display: none"] {
  opacity: 0;
  transform: translateY(4px);
}

.mappa-bottom .mappa-control.map-hud .hud-chip i {
  font-size: 0.95em;
  line-height: 1;
  opacity: 0.85;
}

.mappa-bottom .mappa-control.map-hud .hud-chip__val {
  font-variant-numeric: tabular-nums;
}

/* Fonti e licenze: link ai credits montato da map-hud come ultimo chip. Le
   classi .hud-chip gli danno fondo, bordo e raggio; qui solo quel che un <a>
   porta di suo. In basso a destra, dove stava l'attribuzione di MapLibre,
   copriva il numero della velocita'. */
.mappa-bottom .mappa-control.map-hud .hud-chip--attribuzione {
  /* Un rimando, non un dato: niente pillola, solo l'icona. Il contorno scuro
     la tiene leggibile su ogni basemap come il numero accanto. */
  background: none !important;
  border-color: transparent !important;
  box-shadow: none !important;
  padding: 3px 2px;
  filter: drop-shadow(0 0 2px rgb(0 0 0 / 70%));
  /* Grigio, non il bianco dei dati: e' un rimando, non un valore. Piu' scuro
     sparirebbe sul fondo del chip (contrasto 4,4:1 cosi', misurato). */
  color: #8e98a3;
  text-decoration: none;
  /* La banda e' trasparente ai tocchi (non ruba il pan): il link no. */
  pointer-events: auto;
  position: relative;
}
/* Area di tocco allargata senza cambiare la grafica (criterio 15/09/2026): 44px
   in larghezza, 36 in altezza — sotto c'e' il player, e oltre si ruberebbero
   il tocco. */
.mappa-bottom .mappa-control.map-hud .hud-chip--attribuzione::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: max(100%, var(--tocco-x, 44px));
  height: 36px;
  transform: translate(-50%, -50%);
}
/* Senza testo il chip perderebbe l'interlinea del valore (1.2em): l'icona la
   riprende, o la (i) e' 2,6px piu' bassa dei chip accanto. */
.mappa-bottom .mappa-control.map-hud .hud-chip--attribuzione i {
  line-height: calc(1.2em / 0.95);
  opacity: 1;
}

/* Schermi stretti: il numero cede qualcosa prima che cedano i chip. */
@media (max-width: 360px) {
  .mappa-bottom .mappa-control.map-hud {
    gap: 8px;
  }
  .mappa-bottom .mappa-control.map-hud .hud-velocita__num {
    font-size: 3.375rem;   /* 2.25rem x 1,5, come il caso generale */
  }
}




.mappa-bottom .mappa-control.radar-ctl .rv-header {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
}

.mappa-bottom .mappa-control.radar-ctl .rv-btn {
	border-radius: 4px;
}

.mappa-bottom .mappa-control.radar-ctl .rv-timeline {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: center;
  gap: 2px;
  margin: 0;
  flex: 1 1 auto;
  min-width: 0;
}

.mappa-bottom .mappa-control.radar-ctl .rv-timeline input {
  width: 100%;
  min-width: 0;
  margin: 0;
  display: block;
  min-height: 26px;
  touch-action: pan-x;
}

.mappa-bottom .mappa-control.radar-ctl .rv-info {
  display: flex;
  justify-content: flex-end;
  line-height: 1;
}


.mappa-bottom .mappa-control.radar-ctl .rv-ts {
  font-size: 12px;
  color: #ffffff;
  font-weight: var(--fw-regular);
}

/* Player temporale condiviso: stessa card scura per radar e vento, senza
   cambiare i controlli disponibili agli altri adapter. */
.mappa-bottom .mappa-control.radar-ctl {
  background: var(--map-chrome-bg, rgb(26 38 52 / 92%)) !important;
  border: 1px solid var(--white-15) !important;
  border-radius: 12px !important;
  box-shadow: var(--map-chrome-shadow, 0 10px 28px rgb(0 0 0 / 24%));
}

/* Demo Rainbow: scrubber dominante, metadati dell'asse e play a destra.
   Il markup ridotto viene applicato da TemporalTimeline solo al radar. */
.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo {
  border-radius: 6px !important;
  /* NIENTE height:auto qui: la regola base fissa l'altezza a
     --map-panel-player-height, ed e' quella somma che posiziona le righe sopra.
     Un'altezza libera rendeva il token una stima e sbilanciava la pila. */
  padding: 9px 10px 8px 12px !important;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
}

.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-header {
  order: 2;
  align-self: center;
}

.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-timeline {
  order: 1;
  gap: 5px;
}

.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-timeline {
  position: relative;
  /* Centro del pallino alla frazione p: la stessa corsa del range nativo
     (meta' pallino dai bordi). Tacca, riempimento ed etichette la usano tutti,
     o non starebbero sotto il cursore. --rv-thumb arriva dal JS (RV_THUMB_PX). */
  --rv-x-now: calc(var(--rv-thumb, 20px) / 2 + var(--rv-now, .5) * (100% - var(--rv-thumb, 20px)));
  --rv-x-cur: calc(var(--rv-thumb, 20px) / 2 + var(--rv-current, .5) * (100% - var(--rv-thumb, 20px)));
}

/* Barra: il passato e' pieno, la previsione tratteggiata, cosi' "adesso" si
   legge come il confine fra le due anche senza guardare la tacca. Il tratto
   azzurro e' il pezzo gia' percorso dal cursore. */
.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-timeline input {
  -webkit-appearance: none;
  appearance: none;
  min-height: 28px;
  background: transparent;
  position: relative;
  z-index: 1;
  cursor: pointer;
}
.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-timeline input::-webkit-slider-runnable-track {
  height: 6px;
  border-radius: 3px;
  /* Dall'alto: percorso nel passato (pieno), percorso in previsione
     (tratteggio azzurro, largo fino al cursore), passato, previsione. */
  background:
    linear-gradient(to right, #60d6ff 0 min(var(--rv-x-now), var(--rv-x-cur)), transparent 0),
    repeating-linear-gradient(90deg, #60d6ff 0 4px, transparent 4px 7px),
    linear-gradient(to right, rgb(255 255 255 / 34%) 0 var(--rv-x-now), transparent 0),
    repeating-linear-gradient(90deg, rgb(255 255 255 / 26%) 0 4px, transparent 4px 7px);
  background-size: 100% 100%, var(--rv-x-cur) 100%, 100% 100%, 100% 100%;
  background-repeat: no-repeat;
}
.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-timeline input::-moz-range-track {
  height: 6px;
  border-radius: 3px;
  /* Dall'alto: percorso nel passato (pieno), percorso in previsione
     (tratteggio azzurro, largo fino al cursore), passato, previsione. */
  background:
    linear-gradient(to right, #60d6ff 0 min(var(--rv-x-now), var(--rv-x-cur)), transparent 0),
    repeating-linear-gradient(90deg, #60d6ff 0 4px, transparent 4px 7px),
    linear-gradient(to right, rgb(255 255 255 / 34%) 0 var(--rv-x-now), transparent 0),
    repeating-linear-gradient(90deg, rgb(255 255 255 / 26%) 0 4px, transparent 4px 7px);
  background-size: 100% 100%, var(--rv-x-cur) 100%, 100% 100%, 100% 100%;
  background-repeat: no-repeat;
}
.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-timeline input::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: var(--rv-thumb, 20px);
  height: var(--rv-thumb, 20px);
  margin-top: calc((6px - var(--rv-thumb, 20px)) / 2);
  border-radius: 50%;
  background: #fff;
  border: 3px solid #60d6ff;
  box-shadow: 0 1px 4px rgb(0 0 0 / 35%);
}
.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-timeline input::-moz-range-thumb {
  box-sizing: border-box;
  width: var(--rv-thumb, 20px);
  height: var(--rv-thumb, 20px);
  border-radius: 50%;
  background: #fff;
  border: 3px solid #60d6ff;
  box-shadow: 0 1px 4px rgb(0 0 0 / 35%);
}
/* Agganciato ad adesso: il pallino prende il giallo della tacca. */
.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-timeline.rv-at-now input::-webkit-slider-thumb { border-color: #ffc107; }
.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-timeline.rv-at-now input::-moz-range-thumb { border-color: #ffc107; }

/* Tacca di adesso: resta sulla barra quando il cursore va altrove. Sta sotto
   il pallino (z-index) e sporge sopra e sotto la barra. */
.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-now-tick {
  position: absolute;
  top: 6px;
  left: var(--rv-x-now);
  width: 3px;
  height: 16px;
  margin-left: -1.5px;
  border-radius: 2px;
  background: #ffc107;
  pointer-events: none;
  z-index: 0;
}
.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-timeline.rv-aggancio .rv-now-tick {
  animation: rv-aggancio 260ms cubic-bezier(.23, 1, .32, 1);
}
@keyframes rv-aggancio {
  0% { transform: scaleY(1); }
  40% { transform: scaleY(1.45); }
  100% { transform: scaleY(1); }
}
@media (prefers-reduced-motion: reduce) {
  .mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-timeline.rv-aggancio .rv-now-tick { animation: none; }
}

.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-radar-meta {
  position: relative;
  display: block;
  height: 13px;
  color: rgb(232 242 250 / 80%);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .01em;
  line-height: 1;
}

.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-radar-current {
  position: absolute;
  /* px calcolati da centroOra(): l'etichetta resta dentro il blocco anche
     agli estremi. Fallback alla percentuale se il JS non ha ancora misurato. */
  left: var(--rv-current-x, var(--rv-x-cur));
  top: 2px;
  transform: translateX(-50%);
  color: rgb(255 255 255 / 96%);
  font-weight: 750;
  white-space: nowrap;
  z-index: 3;
  pointer-events: none;
}

.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-radar-current.rv-current-now {
  color: #ffc107;
}

.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-radar-now {
  position: absolute;
  top: 2px;
  left: var(--rv-x-now);
  transform: translateX(-50%);
  /* Bottone "torna ad adesso": testo giallo come la tacca, area di tocco
     allargata con lo pseudo-elemento senza spostare il testo. */
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;
  line-height: 1;
  color: #ffc107;
  font-weight: 750;
  cursor: pointer;
  white-space: nowrap;
  z-index: 2;
  transition: opacity 120ms ease-out;
}
.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-radar-now::before {
  content: "";
  position: absolute;
  inset: -10px -10px -8px;
}
.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-radar-now.rv-estremo-nascosto {
  pointer-events: none;
}

.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-radar-end {
  position: absolute;
  right: 0;
  text-align: right;
}

.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-radar-start {
  position: absolute;
  left: 0;
}

/* Etichetta di un estremo coperta dall'ora corrente: agli estremi dell'asse
   l'ora e' centrata sul bordo e le due si sovrappongono ("+4h" dentro "14:45").
   Vince l'ora, che e' il dato; l'estremo e' contesto e si spegne. Chi decide e'
   estremiVisibili() in temporal-timeline.js, sulle larghezze misurate.
   Opacita' e non display: l'etichetta resta nell'albero di accessibilita' e la
   transizione evita il lampeggio durante lo scrub. */
.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-radar-start,
.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-radar-end {
  transition: opacity 120ms ease-out;
}
.mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-estremo-nascosto {
  opacity: 0;
}

.radar-ctl.rv-radar-demo .rv-timeline.rv-has-forecast::before { display: none; }

.radar-ctl.rv-radar-demo .rv-play-btn {
  width: 36px;
  min-width: 36px;
  height: 36px;
  border-radius: 50%;
  border-color: rgb(96 214 255 / 45%);
  background: rgb(96 214 255 / 16%);
}

@media (max-width: 480px) {
  .mappa-bottom .mappa-control.radar-ctl.rv-radar-demo {
    padding: 8px 9px 7px 10px !important;
    gap: 9px;
  }

  .mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-radar-meta {
    font-size: 10px;
    height: 13px;
  }

  .mappa-bottom .mappa-control.radar-ctl.rv-radar-demo .rv-radar-current {
    top: 1px;
  }

  .radar-ctl.rv-radar-demo .rv-play-btn {
    width: 34px;
    min-width: 34px;
    height: 34px;
  }
}


/* === RADAR TIMELINE UNICA: marker "adesso" + badge previsione === */
.radar-ctl .rv-timeline.rv-has-forecast {
  position: relative;
}
/* Linea verticale sul punto "adesso" (--rv-now = frazione 0..1) */
.radar-ctl .rv-timeline.rv-has-forecast::before {
  content: "";
  position: absolute;
  top: -2px;
  left: calc(var(--rv-now, 0.5) * 100%);
  width: 2px;
  height: 14px;
  background: #ffc107;
  transform: translateX(-1px);
  pointer-events: none;
  z-index: 2;
  border-radius: 1px;
}
/* Etichetta orario quando il frame è una previsione */
.radar-ctl .rv-ts.rv-forecast {
  color: #66d9ff;
  font-style: italic;
}


/* === RADAR PLAYER - Icone SVG unificate === */
/* Il futuro dello slider chiuso dal livello (temporal-timeline.js). */
.radar-ctl .rv-futuro-chiuso { gap: 4px; padding: 4px 8px; font-size: 12px; white-space: nowrap; flex: none; }
.radar-ctl .rv-futuro-chiuso[hidden] { display: none; }

.radar-ctl .rv-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 25px;
  height: 25px;
  border: 1px solid var(--white-25);
  background: var(--white-08);
  color: #fff;
  padding: 4px;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

@media (hover: hover) and (pointer: fine) {
  .radar-ctl .rv-btn:hover {
    background: var(--white-15);
    border-color: var(--white-35);
  }
}

.radar-ctl .rv-btn:active {
  transform: scale(0.95);
  background: var(--white-20);
}

/* Icone SVG dentro i pulsanti */
.radar-ctl .rv-btn svg {
  display: block;
  pointer-events: none;
  width: 15px;
  height: 15px;
}

/* Pulsante play/pause leggermente più grande */
.radar-ctl .rv-play-btn {
  min-width: 32px;
}

.radar-ctl .rv-play-btn svg {
  width: 15px;
  height: 15px;
}

/* Stati aria-pressed per accessibilità */
.radar-ctl .rv-btn[aria-pressed="true"] {
  background: rgba(0, 188, 212, 0.25);
  border-color: rgba(0, 188, 212, 0.4);
}







.wind-crosshair {
	position: relative;
	width: 19px;
	height: 19px;
	pointer-events: none;
}

.wind-crosshair .v,
.wind-crosshair .h {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    background: #ffffff;
	box-shadow: var(--shadow-inset); /* FIX TASK NT-34 */
}

.wind-crosshair .v {
	width: 2px;
	height: 19px;
}

.wind-crosshair .h {
	width: 19px;
	height: 2px;
}



/* ============================================================
   FINE SEZIONE LEAFLET
   ============================================================ */


/* MEDIA QUERY */
@media (min-width: 375px) {

  .forecast-item .hour {
    font-size: var(--fs-base);
  }
  .forecast-item .temp {
    font-size: var(--fs-base);
  }

  ul.day-hourly-list li.day-hourly-row .badge {
    width: 60px;
    font-size: var(--fs-xs);
  }

  ul.day-hourly-list li.day-hourly-row .hour-desc {
    font-size: var(--fs-sm);
  }

  .widget .widget-cont .widget-data-preview {
    font-size: var(--fs-base);
  }

  .widget-bollettino .bollettino-testo {
    font-size: var(--fs-md);
  }

  ul.day-hourly-list li.day-hourly-row .weather-svg-icon-xs {
    width: 30px;
  }

  .widget .widget-footer .data-row {
    font-size: var(--fs-base);
  }

  ul.day-hourly-list li.day-hourly-row .hour-desc strong {
    font-size: var(--fs-sm);
  }

.windbar-box {
    width: 75px;
  }
}

@media (min-width: 390px) {
  
  .widget .widget-cont .widget-value strong,
  .widget .widget-cont .widget-delta strong {
    font-size: var(--fs-3xl);
  }

.windbar-box {
    width: 99px;
  }
}

@media (min-width: 430px) {
.windbar-box {
    width: 115px;
  }

}

/* ========== CHART LOADING STATE ========== */
.chart-loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(27, 66, 92, 0.85);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 10;
  border-radius: var(--r-md);
  transition: opacity 0.3s ease-out;
}

.chart-loading-overlay.hidden {
  opacity: 0;
  pointer-events: none;
}

.chart-loading-spinner {
  width: 40px;
  height: 40px;
  border: 3px solid var(--white-10);
  border-top-color: var(--white-60);
  border-radius: 50%;
  animation: chart-spin 0.8s linear infinite;
}

@keyframes chart-spin {
  to { transform: rotate(360deg); }
}

.chart-loading-text {
  margin-top: 12px;
  font-size: var(--fs-sm);
  color: var(--white-70);
  font-weight: var(--fw-bold);
  letter-spacing: 0.3px;
}

/* Skeleton pulse animation (optional alternative) */
.chart-skeleton {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(
    90deg,
    var(--white-03) 25%,
    var(--white-08) 50%,
    var(--white-03) 75%
  );
  background-size: 200% 100%;
  animation: chart-skeleton-pulse 1.5s ease-in-out infinite;
}

@keyframes chart-skeleton-pulse {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* ========== PWA INSTALL BANNER ========== */
/* FIX TASK NT-20: PWA banner con safe-area completo (top + laterale per landscape) */
.pwa-install-banner {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 9999;
  background: rgba(40, 44, 52, 0.98);
  box-shadow:
    0 4px 12px var(--black-15),
    0 0 0 1px var(--white-10);
  transform: translateY(-100%);
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  /* Safe-area: top per notch, laterale per landscape mode */
  padding: var(--ui-top-pad) var(--safe-right) 0 var(--safe-left);
}

.pwa-install-banner.pwa-banner-visible {
  transform: translateY(0);
}

.pwa-banner-content {
  display: flex;
  align-items: center;
  /* A destra il posto della X, che sta in assoluto: senza, copriva il bottone. */
  padding: 12px 48px 12px 16px;
  position: relative;
}
/* iOS 12: gap non funziona in flexbox */
.pwa-banner-content > * + * { margin-left: 12px; }

.pwa-banner-close {
  position: absolute;
  top: 50%;
  right: 12px;
  transform: translateY(-50%);
  background: var(--white-20);
  border: none;
  border-radius: 50%;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: var(--fs-lg);
  cursor: pointer;
  transition: background 0.2s;
  z-index: 2;
}

.pwa-banner-close:hover,
.pwa-banner-close:active {
  background: var(--white-30);
}

.pwa-banner-icon {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  background: var(--white-20);
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-3xl);
  color: #fff;
}

.pwa-banner-text {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding-right: 30px; /* Spazio per close button */
}
/* iOS 12: gap non funziona in flexbox */
.pwa-banner-text > * + * { margin-top: 2px; }

.pwa-banner-title {
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  color: #fff;
  line-height: 1.3;
}

.pwa-banner-subtitle {
  font-size: var(--fs-base);
  color: var(--white-85);
  line-height: 1.3;
}

.pwa-banner-install-btn {
  flex-shrink: 0;
  background: var(--white-20);
  color: white;
  border: none;
  border-radius: 6px;
  padding: 7px 14px;
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
  display: flex;
  align-items: center;
  cursor: pointer;
  transition: background 0.2s ease;
}
/* iOS 12: gap non funziona in flexbox */
.pwa-banner-install-btn > * + * { margin-left: 6px; }

.pwa-banner-install-btn:hover {
  background: var(--white-30);
}

.pwa-banner-install-btn:active {
  background: var(--white-15);
}

.pwa-banner-install-btn i {
  font-size: var(--fs-xl);
}

/* iOS Instructions Panel */
.pwa-ios-instructions {
  background: var(--white-10);
  border-top: 1px solid var(--white-20);
  padding: 16px;
  margin-top: 8px;
  animation: pwa-ios-slide-down 0.3s ease-out;
}

@keyframes pwa-ios-slide-down {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.pwa-ios-steps {
  max-width: 400px;
  margin: 0 auto;
}

.pwa-ios-intro {
  font-size: var(--fs-md);
  color: #fff;
  margin: 0 0 12px 0;
  font-weight: var(--fw-bold);
}

.pwa-ios-list {
  margin: 0 0 16px 0;
  padding-left: 20px;
  color: var(--white-90);
  font-size: var(--fs-md);
  line-height: 1.6;
}

.pwa-ios-list li {
  margin-bottom: 8px;
}

.pwa-ios-list strong {
  color: #fff;
  font-weight: var(--fw-bold);
}

.pwa-ios-got-it {
  width: 100%;
  background: var(--white-20);
  color: white;
  border: none;
  border-radius: 6px;
  padding: 10px 20px;
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  cursor: pointer;
  transition: background 0.2s ease;
}

.pwa-ios-got-it:hover {
  background: var(--white-30);
}

.pwa-ios-got-it:active {
  background: var(--white-15);
}

/* Responsive adjustments */
@media (max-width: 374px) {
  .pwa-banner-content {
    padding: 10px 44px 10px 12px;
  }
  /* iOS 12: gap non funziona in flexbox */
  .pwa-banner-content > * + * { margin-left: 8px; }

  .pwa-banner-icon {
    width: 36px;
    height: 36px;
    font-size: var(--fs-2xl);
  }

  .pwa-banner-title {
    font-size: var(--fs-md);
  }

  .pwa-banner-subtitle {
    font-size: var(--fs-sm);
  }

  .pwa-banner-install-btn {
    padding: 6px 12px;
    font-size: var(--fs-base);
  }
}

/* Low power mode: disabilita animazioni */
html[data-power="low"] .pwa-install-banner,
html[data-power="low"] .pwa-ios-instructions {
  transition: none !important;
  animation: none !important;
}

/* ========================================================
   RESPONSIVE LAYOUT - TABLET & DESKTOP
   Ispirato a Apple Weather su iPad
   ======================================================== */

/* --- TABLET PORTRAIT (768px+) --- */
@media (min-width: 768px) {

  /* Container più ampio e padding laterale aumentato */
  .container-custom {
    padding: 0 20px;
    max-width: 1200px;
    /* iPad: navbar ~69px (12 pt + 52 min-h + 5 ui-bottom-pad) → 80px lascia
       respiro al contenuto. Override di sicurezza nei media nested sotto. */
    padding-bottom: calc(80px + var(--safe-bottom));
  }

  /* Current weather: layout orizzontale */
  .current-weather.today {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    padding: 24px 28px;
    margin-top: 8px;
    margin-bottom: 24px;
  }

  /* Widget griglia 2 colonne */
  .row.gx-3 {
    gap: 16px;
  }

  .row.gx-3 > .col-6 {
    flex: 0 0 calc(50% - 8px);
    max-width: calc(50% - 8px);
  }

  .row.gx-3 > .col-12:not(.station-card) {
    flex: 0 0 100%;
    max-width: 100%;
  }
  /* Stazioni-dati: card grid 2-col su tablet, 3-col su iPad landscape (gap 16px da .row.gx-3) */
  .row.gx-3 > .station-card.col-md-6 {
    flex: 0 0 calc(50% - 8px);
    max-width: calc(50% - 8px);
  }

  /* Widget più spaziosi su iPad */
  .widget {
    padding: 20px 22px;
  }

  .widget-header {
    margin-bottom: 14px;
  }

  /* Forecast scroll: più card visibili */
  .day-forecast-scroll {
    padding: 0 2px;
  }
  .day-forecast-scroll > * + * { margin-left: 12px; }

  .day-forecast-scroll .widget.day-forecast,
  .day-forecast-scroll .widget {
    min-width: 180px;
    max-width: 200px;
  }

  /* Hourly forecast: ottimizza larghezza */
  ul.day-hourly-list li.day-hourly-row {
    min-width: 90px;
  }

  /* Widget-riga-grid: 1 colonna, grafici a piena larghezza su iPad */
  .widget-riga-grid {
    display: flex;
    flex-direction: column;
  }
  .widget-riga-grid > * + * { margin-top: 16px; }

  .widget-riga-grid > .widget-riga {
    margin-bottom: 0;
  }

  /* --- iPad Typography Scale-up --- */

  .widget .widget-cont .widget-value strong,
  .widget .widget-cont .widget-delta strong {
    font-size: var(--fs-5xl);
  }

  .widget .widget-footer .data-row {
    font-size: var(--fs-md);
  }

  .widget .widget-cont .widget-data-preview {
    font-size: var(--fs-md);
  }

  .widget .widget-header .widget-action {
    font-size: var(--fs-md);
  }

  .widget .btn-accordion .widget-cont {
    font-size: var(--fs-md);
  }

  /* --- iPad Bollettino Meteo e avviso marea --- */
  .avviso-marea__icona {
    font-size: var(--fs-2xl);
  }

  .widget-bollettino .bollettino-testo {
    font-size: var(--fs-lg);
    line-height: 160%;
  }

  /* --- iPad Hourly Forecast --- */
  ul.day-hourly-list {
    max-height: 280px;
  }

  ul.day-hourly-list li.day-hourly-row {
    padding-top: 10px;
    padding-bottom: 10px;
  }

  ul.day-hourly-list li.day-hourly-row .weather-svg-icon-xs {
    width: 32px;
  }

  ul.day-hourly-list li.day-hourly-row .hour-desc {
    font-size: var(--fs-base);
  }

  ul.day-hourly-list li.day-hourly-row .hour-desc strong {
    font-size: var(--fs-base);
  }

  ul.day-hourly-list li.day-hourly-row .badge {
    width: 62px;
    font-size: var(--fs-xs);
    padding: 4px;
  }

  /* --- iPad Air Quality --- */
  .widget-air-quality .aqi-bar {
    height: 7px;
    border-radius: 3.5px;
  }

  .widget-air-quality .aqi-indicator {
    width: 12px;
    height: 12px;
  }

  .widget-air-quality .aqi-desc {
    font-size: var(--fs-lg);
  }

  /* --- iPad Chart Heights (piena larghezza → più alti) --- */
  .chart-container {
    min-height: 300px;
  }

  .widget-riga .chart-container {
    min-height: 320px;
  }

  /* Marea e Solunari: mantiene il pannello marea ≈ chart laguna anche a
     tablet (laguna 300px → disegno ~250px; 480px × 19/33 ≈ 248px) */
  .widget[aria-label="Widget Tabelle Solunari"] .chart-container {
    height: 480px;
    min-height: 480px;
  }

  /* --- iPad Day Forecast Carousel: 2 items per slide --- */
  #dayForecastCarousel .carousel-pair {
    gap: 16px;
    flex-wrap: nowrap;
  }

  /* Specificity 0,1,2 to override base #dayForecastCarousel .widget-riga (0,1,1) */
  #dayForecastCarousel .carousel-pair .carousel-pair-item {
    flex: 0 0 calc(50% - 8px);
    max-width: calc(50% - 8px);
    min-width: 0;
    width: calc(50% - 8px);
  }

  #dayForecastCarousel .widget-header .weather-svg-icon {
    width: 64px;
    height: 64px;
  }

  #dayForecastCarousel .widget .widget-footer .data-row {
    font-size: var(--fs-lg);
    margin-bottom: 12px;
  }

  #dayForecastCarousel .widget .widget-footer .data-row .widget-value {
    font-size: var(--fs-lg);
  }

  /* --- iPad Horizontal Hourly Forecast Bar --- */
  .forecast-item {
    min-width: 100px;
  }

  .forecast-item .hour {
    font-size: var(--fs-lg);
    top: 12px;
  }

  .forecast-item .weather-svg-icon {
    width: 44px;
    height: 44px;
    top: 38px;
  }

  .forecast-item .temp {
    font-size: var(--fs-lg);
    top: 84px;
  }

  .forecast-item .rain-bar-container {
    height: 28px;
  }

  .forecast-item .rain-value-text {
    font-size: var(--fs-xs);
  }

  .forecast-item .wind-box {
    font-size: var(--fs-base);
    min-width: 100px;
    min-height: 130px;
  }

  .forecast-item .wind-box .wind-wrapper {
    min-width: 100px;
    bottom: 28px;
  }

  .forecast-day-label {
    min-width: 40px;
    font-size: var(--fs-md);
  }

  .forecast-day-label .giorno-label,
  .forecast-day-label .giorno-num {
    font-size: var(--fs-base);
  }

  /* --- iPad Luna & Marea: Moon phases grid (auto-fit: 3 or 4 columns) --- */
  .day-forecast-scroll.moon-phases {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 12px;
    overflow-x: visible;
  }

  .day-forecast-scroll.moon-phases .widget.day-forecast {
    min-width: 0;
    max-width: none;
    flex: none;
  }

  /* --- iPad Luna & Marea: widget-grid-2 col-12 full width --- */
  .row.gx-3.widget-grid-2 > .col-12 {
    flex: 0 0 100%;
    max-width: 100%;
    width: 100%;
  }

  /* --- iPad Luna & Marea: tide chart taller --- */
  .widget-grid-2 .widget.day-forecast .chart-container {
    min-height: 350px;
  }

  /* --- iPad Stazioni Dati: typography + compact --- */

  /* Data preview (distance, count) */
  .station-header-row .widget-data-preview {
    font-size: var(--fs-md);
  }

  /* Favorite button */
  .station-header-row .station-fav-btn {
    flex: 0 0 48px;
    font-size: var(--fs-2xl);
  }

  /* Data rows: bigger text, less vertical padding */
  .station-data .data-row {
    font-size: var(--fs-md);
    padding-top: 6px;
    padding-bottom: 6px;
  }

  /* Icons in data rows */
  .station-data .data-row .widget-text .wi,
  .station-data .data-row .widget-text .ic {
    font-size: 15px;
  }

  /* Wind bar label */
  .station-data .windbar-label {
    font-size: var(--fs-base);
  }

  .station-data .windbar-label .wind-dir-text {
    font-size: var(--fs-base);
  }

  /* Freshness dot slightly bigger */
  .station-freshness {
    width: 9px;
    height: 9px;
  }

  /* Sort note / legend */
  .station-sort-note {
    font-size: var(--fs-base);
  }

  /* Section headers (Preferiti / Stazioni) */
  .station-section-header {
    font-size: var(--fs-sm);
  }

  /* Less margin between cards */
  .station-card .widget.widget-riga {
    margin-bottom: 10px;
  }

  /* --- iPad Pesca: 3 cards visible + horizontal scroll --- */
  .day-forecast-scroll.pesca {
    scroll-snap-type: x mandatory;
  }

  .day-forecast-scroll.pesca .widget.day-forecast {
    min-width: calc(33.333% - 8px);
    max-width: calc(33.333% - 8px);
    flex: 0 0 calc(33.333% - 8px);
    scroll-snap-align: start;
  }

  /* --- iPad Pesca: solunar chart same height as tide chart --- */
  .widget[aria-label="Widget Tabelle Solunari"] .chart-container {
    min-height: 350px;
  }

}

/* --- TABLET LANDSCAPE / iPad Pro (1024px+) --- */
@media (min-width: 1024px) {

  .container-custom {
    /* solo orizzontale: la shorthand wipava padding-bottom (navbar overlap). */
    padding-left: 32px;
    padding-right: 32px;
  }

  /* Stazioni-dati: card grid 3-col su iPad landscape (gap 16px) */
  .row.gx-3 > .station-card.col-lg-4 {
    flex: 0 0 calc(33.333% - 11px);
    max-width: calc(33.333% - 11px);
  }

  /* Current weather: ancora più spazioso */
  .current-weather.today {
    padding: 28px 36px;
  }

  /* Hourly forecast: ancora più ampio su landscape */
  .forecast-item {
    min-width: 110px;
  }

  .forecast-item .hour {
    font-size: var(--fs-lg);
    top: 14px;
  }

  .forecast-item .weather-svg-icon {
    width: 48px;
    height: 48px;
    top: 40px;
  }

  .forecast-item .temp {
    font-size: 15px;
    top: 90px;
  }

  .forecast-item .wind-box {
    font-size: var(--fs-base);
    min-width: 110px;
    min-height: 140px;
  }

  .forecast-item .wind-box .wind-wrapper {
    min-width: 110px;
  }

  /* .forecast-day-label: min-height rimosso, ora segue altezza item */

  /* Layout 2 colonne per widget piccoli */
  .row.gx-3.widget-grid-2 > .col-6 {
    flex: 0 0 calc(50% - 8px);
    max-width: calc(50% - 8px);
  }

  /* Forecast scroll: card più grandi */
  .day-forecast-scroll .widget.day-forecast,
  .day-forecast-scroll .widget {
    min-width: 200px;
    max-width: 220px;
  }

  /* Charts: dimensioni ottimizzate per piena larghezza */
  .chart-container {
    min-height: 340px;
  }

  /* Widget-riga accordion più leggibile */
  .widget-riga .widget-header {
    padding: 16px 20px;
  }

  /* ========== WIDGET-RIGA: 1 colonna con grafici grandi ========== */

  /* Widget-riga-grid: spacing aumentato */
  .widget-riga-grid > * + * { margin-top: 20px; }

  /* Widget-riga: layout flessibile interno */
  .widget-riga-grid > .widget-riga {
    display: flex;
    flex-direction: column;
  }

  .widget-riga-grid > .widget-riga .widget-header {
    flex: 0 0 auto;
  }

  .widget-riga-grid > .widget-riga .collapse,
  .widget-riga-grid > .widget-riga .collapsing {
    flex: 1 1 auto;
  }

  /* Widget-riga espanso: chart altezza generosa */
  .widget-riga-grid > .widget-riga .collapse.show .chart-container,
  .widget-riga-grid > .widget-riga .collapsing .chart-container {
    min-height: 340px;
  }

  /* Container principale con gap aumentato */
  .view-content > .row.gx-3,
  #main-content > .row.gx-3,
  /* I wrapper `.vista-colonna` sono `display:contents`, ma i SELETTORI leggono
     il DOM, non il box tree: senza questa riga la riga pressione/visibilita'
     perde il margine fuori dall'iPad verticale (landscape e desktop). */
  #main-content > .vista-colonna > .row.gx-3 {
    margin-bottom: 16px;
  }

  /* Widget grid 2 colonne - gap consistente */
  .row.gx-3.widget-grid-2 {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 16px;
  }

  .row.gx-3.widget-grid-2 > .col-6 {
	width: 100%;
    max-width: 100%;
    flex: none;
  }

  .row.gx-3.widget-grid-2 > .col-12 {
    grid-column: 1 / -1;
    width: 100%;
    max-width: 100%;
  }

  /* --- Landscape Stazioni Dati: bigger typography --- */

  .station-header-row .widget-data-preview {
    font-size: var(--fs-lg);
  }

  .station-header-row .station-fav-btn {
    flex: 0 0 42px;
    font-size: 17px;
  }

  .station-data .data-row {
    font-size: var(--fs-lg);
    padding-top: 7px;
    padding-bottom: 7px;
  }

  .station-data .data-row .widget-text .wi,
  .station-data .data-row .widget-text .ic {
    font-size: var(--fs-xl);
  }

  .station-data .windbar-label {
    font-size: var(--fs-md);
  }

  .station-data .windbar-label .wind-dir-text {
    font-size: var(--fs-md);
  }

  .station-sort-note {
    font-size: var(--fs-md);
  }

  .station-section-header {
    font-size: var(--fs-base);
  }

  /* Stazioni view: nessun padding, la mappa e' a tutto schermo.
     Il padding laterale/superiore che stava qui rientrava sopra il
     `padding: 0` della regola base e su iPad lasciava 32px di cornice a sx/dx
     e 24px in alto. Non si notava perche' il `position: fixed` della regola
     fullscreen non arriva mai a valere: Leaflet scrive `position: relative`
     inline sul container all'init, quindi la mappa resta nel flusso e il
     padding del container la rimpicciolisce. */

  /* --- Landscape Pesca: 4 visible cards --- */
  .day-forecast-scroll.pesca .widget.day-forecast {
    min-width: calc(25% - 9px);
    max-width: calc(25% - 9px);
    flex: 0 0 calc(25% - 9px);
  }

  /* --- Landscape Solunar + Tide charts: taller --- */
  .widget[aria-label="Widget Tabelle Solunari"] .chart-container,
  .widget-grid-2 .widget.day-forecast .chart-container {
    min-height: 380px;
  }

  /* --- Landscape widget values: bigger text for wider columns --- */
  .widget .widget-cont .widget-value strong,
  .widget .widget-cont .widget-delta strong {
    font-size: var(--fs-6xl);
  }

  .widget .widget-footer .data-row {
    font-size: var(--fs-lg);
  }

  .widget-air-quality .aqi-desc {
    font-size: 15px;
  }

}

/* --- iPad Pro Landscape (1024px - 1400px) --- */
@media (min-width: 1024px) and (max-width: 1365px) {

  /* Widget-riga-grid: gap più ampio.
     NIENTE margin laterale auto: nella vista Pro il genitore .home-dashboard e'
     un flex column, e i margini laterali auto su un flex item disattivano lo
     stretch -> il widget grafici si stringeva al contenuto (516px dentro 1020px
     disponibili) e restava centrato. Il cap a 1100px lo da' gia' .container-custom. */
  .widget-riga-grid {
    gap: 20px;
  }

  /* Current weather centrato con max-width */
  .current-weather.today {
    max-width: 850px;
    margin-left: auto;
    margin-right: auto;
    border-radius: 16px;
  }

  /* Forecast scroll centrato */
  .day-forecast-scroll,
  .day-hourly-scroll {
    max-width: 1100px;
    margin-left: auto;
    margin-right: auto;
  }

  /* Widget grid-2: occupa tutta la larghezza disponibile su tablet */
  .row.gx-3.widget-grid-2 {
    max-width: 100%;
  }

}

/* --- DESKTOP (1280px+) --- */
@media (min-width: 1366px) {

  .container-custom {
    padding-left: 40px;
    padding-right: 40px;
  }

  /* Current weather: massima espansione */
  .current-weather.today {
    padding: 32px 40px;
  }

  /* Forecast scroll: ancora più card visibili */
  .day-forecast-scroll > * + * { margin-left: 16px; }

  .day-forecast-scroll .widget.day-forecast,
  .day-forecast-scroll .widget {
    min-width: 220px;
    max-width: 240px;
  }

  /* Font size leggermente più grandi */
  body {
    font-size: var(--fs-md);
  }

  .widget-value strong {
    font-size: var(--fs-4xl);
  }

}

/* --- LARGE DESKTOP (1536px+) --- */
@media (min-width: 1366px) {

  /* Layout 4 colonne per widget molto piccoli */
  .row.gx-3.widget-grid-4 > .col-6,
  .row.gx-3.widget-grid-4 > .col-3 {
    flex: 0 0 calc(25% - 12px);
    max-width: calc(25% - 12px);
  }

  /* Current weather: layout side-by-side ottimale */
  .current-weather.today {
    max-width: 1365px;
    margin: 0 auto;
  }

}

/* ========================================================
   OTTIMIZZAZIONI AGGIUNTIVE PER LAYOUT RESPONSIVE
   ======================================================== */

/* Tablet e Desktop: Layout intelligente widget griglia */
@media (min-width: 768px) {

  /* Row con gap responsive */
  .row.gx-3 {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin: 0 0 12px 0;
  }

  /* Reset margin per colonne dentro row con gap */
  .row.gx-3 > [class*="col-"] {
    margin: 0;
    padding: 0;
  }

}

@media (min-width: 1024px) {

  /* Gap più ampio su schermi grandi */
  .row.gx-3 {
    gap: 16px;
    margin: 0 0 16px 0;
  }

  /* Widget riga: mostra più info inline */
  .widget-riga .widget-data-preview {
    font-size: 15px;
  }

  .widget-riga .widget-data-preview strong {
    font-size: var(--fs-2xl);
  }

}

/* Desktop Large: ottimizza ulteriormente spacing */
@media (min-width: 1366px) {

  .row.gx-3 {
    gap: 20px;
    margin: 0 0 20px 0;
  }

  /* Location bar più compatta in alto */
  .location-bar {
    padding: 12px 20px;
  }

  /* Navbar bottom: considera se nascondere su desktop molto grandi */
  /* Per ora lasciamo visibile ma più compatta */
  .navbar-bottom-nav {
    gap: 8px;
  }

}

/* Ottimizzazioni per scroll orizzontali su tablet/desktop */
@media (min-width: 768px) {

  /* Day forecast scroll: migliora UX touch/mouse */
  .day-forecast-scroll {
    scrollbar-width: thin;
    scrollbar-color: var(--white-30) transparent;
  }

  .day-forecast-scroll::-webkit-scrollbar {
    height: 8px;
  }

  .day-forecast-scroll::-webkit-scrollbar-track {
    background: transparent;
  }

  .day-forecast-scroll::-webkit-scrollbar-thumb {
    background: var(--white-30);
    border-radius: 4px;
  }

  .day-forecast-scroll::-webkit-scrollbar-thumb:hover {
    background: var(--white-50);
  }

  /* Hourly list: stessa cosa */
  ul.day-hourly-list {
    scrollbar-width: thin;
    scrollbar-color: var(--white-30) transparent;
  }

  ul.day-hourly-list::-webkit-scrollbar {
    height: 8px;
  }

  ul.day-hourly-list::-webkit-scrollbar-track {
    background: transparent;
  }

  ul.day-hourly-list::-webkit-scrollbar-thumb {
    background: var(--white-30);
    border-radius: 4px;
  }

  ul.day-hourly-list::-webkit-scrollbar-thumb:hover {
    background: var(--white-50);
  }

}

/* Fix per iOS Safari su iPad: previeni bounce eccessivo */
@supports (-webkit-touch-callout: none) {
  @media (min-width: 768px) {
    .day-forecast-scroll,
    ul.day-hourly-list {
      -webkit-overflow-scrolling: touch;
    }
  }
}

/* ========================================================
   OTTIMIZZAZIONI SPECIFICHE PER iPAD
   ======================================================== */

/* iPad Portrait (768-834px) */
@media (min-width: 768px) and (max-width: 819px) {

  .container-custom {
    max-width: 100%;
    padding-left: 24px;
    padding-right: 24px;
  }

  /* Current weather: dimensioni ottimali per iPad portrait */
  .current-weather.today {
    padding: 24px 20px;
  }

  .current-weather .weather-svg-icon {
    width: 120px;
    height: 120px;
  }

}

/* iPad mini Portrait (768-833px): fasi lunari in scroll invece di griglia */
/* A 768px i 4 widget da minmax(180px) non entrano in griglia (728px utili) → capo riga */
/* iPad Pro 11" (834px) non è coinvolto: lì i 4 widget ci stanno */
@media (min-width: 768px) and (max-width: 819px) {

  .day-forecast-scroll.moon-phases {
    display: flex;
    overflow-x: auto;
    grid-template-columns: unset;
    gap: 15px;
    scroll-snap-type: x proximity;
  }

  .day-forecast-scroll.moon-phases .widget.day-forecast {
    min-width: 40%;
    flex: 0 0 40%;
    max-width: none;
    scroll-snap-align: start;
  }

  /* --- Pesca: stessa logica scroll 2.5 card visibili --- */
  .day-forecast-scroll.pesca .widget.day-forecast {
    min-width: 40%;
    max-width: 40%;
    flex: 0 0 40%;
    scroll-snap-align: start;
  }

}

/* iPad Landscape & Tablet Landscape (1024-1194px) */
@media (min-width: 1024px) and (max-width: 1365px) and (orientation: landscape) {

  body {
    font-size: var(--fs-lg);
  }

  .container-custom {
    padding-left: 40px;
    padding-right: 40px;
  }

  /* Layout ottimizzato per landscape: 2 colonne per widget piccoli */
  .row.gx-3.widget-grid-2 > .col-6 {
    flex: 0 0 calc(50% - 8px);
    max-width: calc(50% - 8px);
  }

  /* col-12 always full width */
  .row.gx-3.widget-grid-2 > .col-12 {
    flex: 0 0 100%;
    max-width: 100%;
  }

  /* Current weather: layout orizzontale compatto */
  .current-weather.today {
    padding: 20px 28px;
    max-width: 900px;
    margin: 0 auto 20px;
  }

  .current-weather .weather-svg-icon {
    width: 130px;
    height: 130px;
  }

  /* Widget riga: usa tutto lo spazio disponibile */
  .widget-riga {
    margin-bottom: 16px;
  }

}

/* iPad Pro 11" & 12.9" */
@media (min-width: 1024px) and (max-width: 1365px) {

  /* Card forecast: dimensioni ottimali */
  .day-forecast-scroll .widget.day-forecast,
  .day-forecast-scroll .widget {
    min-width: 190px;
    max-width: 210px;
  }

}

/* ========================================================
   MIGLIORAMENTI WIDGET SU SCHERMI GRANDI
   ======================================================== */

@media (min-width: 1024px) {

  /* Widget: padding più ampio su desktop */
  .widget {
    padding: 22px 24px;
  }

  /* Widget footer: spacing migliorato */
  .widget-footer {
    margin-top: 14px;
    padding-top: 14px;
  }

  .widget-footer .data-row {
    margin-bottom: 10px;
  }

  /* Day forecast widget: dimensioni card ottimali */
  .widget.day-forecast {
    padding: 22px;
    min-height: 240px;
  }

  .widget.day-forecast .weather-svg-icon {
    width: 80px;
    height: 80px;
    margin: 16px 0;
  }

}

@media (min-width: 1366px) {

  /* Widget ancora più spaziosi */
  .widget {
    padding: 24px 28px;
  }

  .widget.day-forecast {
    padding: 24px;
    min-height: 260px;
  }

  .widget.day-forecast .weather-svg-icon {
    width: 90px;
    height: 90px;
    margin: 18px 0;
  }

}

/* ========================================================
   FIX PER CHARTS SU SCHERMI GRANDI
   ======================================================== */

@media (min-width: 1024px) {

  /* Chart container: altezza generosa per grafici a piena larghezza */
  .chart-container {
    min-height: 340px;
  }

  .chart-container canvas {
    max-height: 500px;
  }

}

@media (min-width: 1366px) {

  .chart-container {
    min-height: 360px;
  }

  .chart-container canvas {
    max-height: 500px;
  }

}

/* ========================================================
   OTTIMIZZAZIONI LOCATION BAR SU TABLET/DESKTOP
   ======================================================== */

@media (min-width: 768px) {

  .location-bar {
    padding: 14px 24px;
    padding-top: 24px !important; /* fallback legacy */
    padding-top: max(24px, var(--safe-top)) !important;
    gap: 14px;
  }

  .location-bar .loc-labels {
    max-width: 350px;
  }

  .location-bar .loc-labels .loc-name {
    font-size: var(--fs-lg);
  }

  .location-bar .loc-labels .loc-elev {
    font-size: var(--fs-lg);
  }

  .location-bar .loc-labels .loc-update-time,
  .location-bar .loc-labels .loc-modello,
  .location-bar .loc-labels .update-time {
    font-size: var(--fs-base);
  }

  .location-bar .loc-actions {
    gap: var(--sp-2);
  }

  .location-bar .loc-actions a,
  .location-bar .loc-actions button {
    width: 37px;
    height: 38px;
    padding: 10px;
    font-size: var(--fs-xl);
    border-radius: var(--r-md);
  }

}

@media (min-width: 1024px) {

  .location-bar {
    padding: 16px 32px;
    border-radius: 0 0 12px 12px;
  }

  .location-bar .loc-labels .loc-name {
    font-size: 15px;
  }

  .location-bar .loc-labels .loc-update-time,
  .location-bar .loc-labels .loc-modello,
  .location-bar .loc-labels .update-time {
    font-size: var(--fs-md);
  }

  .location-bar .loc-actions a,
  .location-bar .loc-actions button {
    width: 39px;
    height: 40px;
    padding: 11px;
    font-size: 17px;
  }

}

/* ========================================================
   TRANSIZIONI SMOOTH PER RESIZE
   ======================================================== */

@media (prefers-reduced-motion: no-preference) {

  .current-weather .weather-svg-icon {
    transition: width 0.3s ease, height 0.3s ease, font-size 0.3s ease;
  }

}

/* ========================================================
   FISHING FORECAST LIST (variante accordion · 2026-04-26)
   Riusa stili .day-forecast-list di previsioni meteo.
   ======================================================== */
.fishing-forecast-list .day-forecast-list-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
}
/* Menu della specie: riga sua sotto titolo e info, invece di stringere il
   titolo. Aspetto del selettore modello Pro; 44px di altezza per il tocco. */
.fishing-forecast-list .day-forecast-list-header { flex-wrap: wrap; }
.fishing-tecnica-select {
  order: 3;
  flex: 1 0 100%;
  min-width: 0;
  min-height: 44px;
}
/* Solo la specie (la tecnica sta nel dettaglio del periodo). */
.fishing-forecast-list .dfr-meta .dfm-tecnica {
  color: var(--white-80);
}
.fishing-forecast-list .ffl-info {
  font-size: var(--fs-sm);
  opacity: 0.7;
  cursor: pointer;
  color: var(--white-80);
  transition: opacity 0.15s ease, transform 120ms ease-out;
}
@media (hover: hover) and (pointer: fine) {
  .fishing-forecast-list .ffl-info:hover { opacity: 1; }
}
.fishing-forecast-list .ffl-info:active { transform: scale(0.9); }
.fishing-forecast-list .dfr-fishing-score {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  margin-right: 4px;
}
.fishing-forecast-list .dfr-fishing-score .fishing-score-box {
  font-size: var(--fs-md);
  padding: 5px 9px;
  min-width: 36px;
  text-align: center;
  border-radius: 6px;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.14),
    inset 0 -1px 0 rgba(0, 0, 0, 0.18),
    0 1px 3px rgba(0, 0, 0, 0.22);
  background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.06), rgba(0, 0, 0, 0.10));
  letter-spacing: 0.2px;
}
/* Orario migliore a destra nella colonna elastica, fino alla freccia
   (23/10/2026): prima a destra del punteggio restava un vuoto. Il voto apre la
   riga dei dettagli: «Discreto · leccia amia · 1 periodo». */
.fishing-forecast-list .dfr-migliore {
  justify-self: end;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  color: var(--white-90);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.fishing-forecast-list .dfr-migliore .ic {
  color: #ffc857;
  font-size: var(--fs-lg);
}
.fishing-forecast-list .dfr-meta .dfr-voto {
  color: var(--white-90);
  font-weight: var(--fw-medium);
}
/* Lista sotto i 300px di contenuto (riquadro Premium chiuso sull'iPad in
   verticale): l'orario non sta accanto al punteggio e scende su una riga sua. */
.fishing-forecast-list {
  container: pesca-lista / inline-size;
}
@container pesca-lista (max-width: 299px) {
  .fishing-forecast-list .dfr-migliore {
    grid-column: 1 / -1;
    grid-row: 2;
    justify-self: start;
  }
}
.fishing-forecast-list .dfr-icon img {
  width: 34px;
  height: 34px;
}
/* Fishing row ha 5 figli (day, icon, score, orario migliore, chevron). Override
   grid 6-col base per allineare chevron a destra. */
.fishing-forecast-list {
  --pl-chev: 18px;
  --pl-gap: 12px;
}
.fishing-forecast-list .dfr-main {
  grid-template-columns: minmax(58px, auto) auto auto minmax(0, 1fr) var(--pl-chev);
  column-gap: var(--pl-gap);
}
.fishing-forecast-list .dfr-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 14px;
  row-gap: 6px;
  min-width: 0;
}
/* Fishing usa scala tipografica più compatta (no big day-name come previsioni meteo) */
.fishing-forecast-list .dfr-day-name {
  font-size: var(--fs-lg);
  letter-spacing: 0;
}
.fishing-forecast-list .dfr-day-date {
  font-size: var(--fs-xs);
  opacity: 0.72;
  letter-spacing: 0.3px;
}
/* Meta: specie e conteggio (secondari), Meteo avverso (pill) */
.fishing-forecast-list .dfr-meta .dfm-item .ic-format-list-numbered {
  opacity: 0.5;
}
.fishing-forecast-list .dfm-adaptive {
  color: #5fd4ee;
  background: rgba(13, 202, 240, 0.12);
  border: 1px solid rgba(13, 202, 240, 0.32);
  border-radius: 999px;
  padding: 2px 9px 2px 8px;
  font-size: var(--fs-xs);
  letter-spacing: 0.2px;
}
.fishing-forecast-list .dfm-adaptive i {
  opacity: 0.95;
}
.fishing-detail {
  padding: 4px 14px 14px;
}
.fishing-detail .fishing-reliability-bar {
  margin: 0 0 12px;
}
.fishing-racconto {
  margin: 0 0 12px;
}
/* Stessa voce del bollettino della vista Oggi; la scheda della specie un gradino sotto. */
.fishing-racconto-frase {
  margin: 0 0 var(--sp-1);
  font-size: var(--fs-base);
  line-height: 150%;
  color: var(--white-85);
}
.fishing-racconto-scheda {
  margin: 0;
  font-size: var(--fs-xs);
  line-height: 150%;
  color: var(--white-60);
}
.fishing-period-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.fishing-period-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 0;
  border-bottom: 1px dashed var(--white-12);
}
.fishing-period-item:last-child { border-bottom: 0; }
.fishing-period-item .fishing-score-box {
  flex: 0 0 auto;
  min-width: 32px;
  text-align: center;
}
.fishing-period-item .fishing-period-info {
  flex: 1 1 auto;
  min-width: 0;
}
/* Nella lista delle fasce l'orario e' il primo dato utile; la spiegazione
   (specie, fase, luce) sta sotto, piu' discreta. */
.fishing-period-item .fishing-period-time {
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  color: var(--white-95);
  font-variant-numeric: tabular-nums;
}
.fishing-period-item .fishing-period-type {
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  color: var(--white-70);
  text-transform: none;
  letter-spacing: 0;
  margin-top: 2px;
}

/* ========================================================
   FISHING PERIODS - COMPACT ACCORDION DESIGN
   ======================================================== */

.fishing-period {
  background: rgba(223, 223, 223, 0.12);
  border-left: 3px solid var(--period-color);
  padding: 0;
  margin-bottom: 8px;
  border-radius: var(--r-lg);
  transition: transform 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
  overflow: hidden;
}

.fishing-period:hover {
  background: rgba(223, 223, 223, 0.15);
}

/* Periodo attualmente in corso - evidenziato */
.fishing-period.in-progress {
  background: rgba(223, 223, 223, 0.18);
  box-shadow: 0 0 0 1px var(--period-color),
              0 2px 8px var(--black-15);
}

.fishing-period.in-progress .fishing-period-type::before {
  content: '';
  display: inline-block;
  width: 6px;
  height: 6px;
  background: var(--period-color);
  border-radius: 50%;
  margin-right: 6px;
  animation: pulse-dot 2s infinite;
}

@keyframes pulse-dot {
  0%, 100% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.6;
    transform: scale(1.3);
  }
}

.fishing-period-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 12px;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  min-height: 44px;
  transition: background 0.2s ease;
  position: relative;
  width: 100%;
  border: none;
  background: transparent;
  text-align: left;
  color: inherit;
  font-family: inherit;
}

.fishing-period-header:hover {
  background: var(--white-05);
}

.fishing-period-header:active {
  background: var(--white-08);
}

.fishing-period-header:focus {
  outline: none;
}

.fishing-period-header:focus-visible {
  outline: 2px solid var(--white-50);
  outline-offset: -2px;
}

/* Feedback visivo al tap su mobile */
@media (hover: none) and (pointer: coarse) {
  .fishing-period-header::before {
    content: '';
    position: absolute;
    top: 0;
  right: 0;
  bottom: 0;
  left: 0;
    background: var(--white-10);
    opacity: 0;
    transition: opacity 0.15s ease;
    pointer-events: none;
  }

  .fishing-period-header:active::before {
    opacity: 1;
  }
}

.fishing-period-info {
  display: flex;
  flex: 1;
  min-width: 0;
}

.fishing-period-info > div {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1;
}
/* iOS 12: gap non funziona in flexbox */
.fishing-period-info > div > * + * { margin-top: 2px; }

.fishing-period-type {
  font-weight: var(--fw-bold);
  font-size: var(--fs-xs);
  color: var(--white-95);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  line-height: 1.2;
}

.fishing-period-time {
  font-weight: var(--fw-bold);
  font-size: var(--fs-xs);
  color: var(--white-65);
  line-height: 1.2;
}

.fishing-period-picco {
  font-size: var(--fs-xs);
  opacity: 0.8;
}

.fishing-period-weather {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  margin-right: 4px;
}
/* iOS 12: gap non funziona in flexbox */
.fishing-period-weather > * + * { margin-left: 6px; }

.fishing-period-weather img {
  width: 24px;
  height: 24px;
  filter: drop-shadow(0 1px 2px var(--black-15));
  flex-shrink: 0;
}

.fishing-period-weather-label {
  font-size: var(--fs-xs);
  opacity: 0.7;
  white-space: nowrap;
  font-weight: var(--fw-bold);
  color: var(--white-75);
  max-width: 60px;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fishing-period-badge {
  background: var(--period-color);
  color: white;
  padding: 4px 10px;
  border-radius: var(--r-md);
  font-weight: var(--fw-bold);
  font-size: var(--fs-lg);
  min-width: 40px;
  text-align: center;
  box-shadow: var(--shadow-sm); /* FIX TASK NT-34 */
  flex-shrink: 0;
}

/* Arrow accordion icon (Bootstrap collapse) */
.fishing-period-header .arrow-accordion {
  font-size: var(--fs-base);
  transition: transform 0.2s ease;
  margin-left: 8px;
  flex-shrink: 0;
  color: var(--white-75);
}

.fishing-period-header[aria-expanded="true"] .arrow-accordion {
  transform: rotate(180deg);
}

.fishing-factors {
  display: flex;
  flex-direction: column;
  font-size: var(--fs-xs);
  padding: 10px 12px;
  border-top: 1px solid var(--white-15);
  margin-top: 0;
}
/* iOS 12: gap non funziona in flexbox */
.fishing-factors > * + * { margin-top: 6px; }

.fishing-factor-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 2px 0;
  color: var(--white-85);
}

.fishing-factor-row i {
  opacity: 0.7;
  margin-right: 6px;
}

.fishing-factor-value {
  font-weight: var(--fw-bold);
  font-size: var(--fs-sm);
  color: var(--white-100);
}

.fishing-factor-value.positive {
  color: #4ade80;
}

.fishing-factor-value.negative {
  color: #f87171;
}

.fishing-factor-detail {
  opacity: 0.65;
  font-size: var(--fs-xs);
  margin-left: 4px;
  color: var(--white-65);
}

.fishing-factor-day-penalty {
  border-top: 1px solid var(--white-10);
  padding-top: 6px;
  margin-top: 4px;
}

.fishing-factor-day-penalty span:first-child {
  font-size: var(--fs-xs);
  opacity: 0.75;
}

.fishing-factor-day-penalty .fishing-factor-value {
  font-size: var(--fs-sm);
}

.fishing-score-container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 0;
}
/* iOS 12: gap non funziona in flexbox */
.fishing-score-container > * + * { margin-left: 12px; }

.fishing-score-badge-wrapper {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 65px;
}
/* iOS 12: gap non funziona in flexbox */
.fishing-score-badge-wrapper > * + * { margin-top: 6px; }

.fishing-score-badge {
  color: white;
  padding: 8px 12px;
  border-radius: 12px;
  font-weight: var(--fw-bold);
  font-size: var(--fs-4xl);
  box-shadow: var(--shadow-md); /* FIX TASK NT-34 */
  line-height: 1;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.fishing-score-badge:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-lg); /* FIX TASK NT-34 */
}

.fishing-score-label {
  font-weight: var(--fw-bold);
  font-size: var(--fs-xs);
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--white-85);
}

.fishing-weather-icon-wrapper {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex: 1;
  padding: 4px;
}
/* iOS 12: gap non funziona in flexbox */
.fishing-weather-icon-wrapper > * + * { margin-top: 4px; }

.fishing-weather-icon {
  width: 36px;
  height: 36px;
  filter: drop-shadow(0 1px 3px var(--black-20));
}

.fishing-weather-desc {
  font-size: var(--fs-xs);
  text-align: center;
  color: var(--white-70);
  font-weight: var(--fw-bold);
}

.fishing-periods-container {
  border-top: 1px solid var(--white-15);
  padding-top: 8px;
  margin-top: 8px;
}

.fishing-periods-title {
  font-weight: var(--fw-bold);
  font-size: var(--fs-xs);
  margin-bottom: 8px;
  color: var(--white-75);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  display: flex;
  align-items: center;
}
/* iOS 12: gap non funziona in flexbox */
.fishing-periods-title > * + * { margin-left: 6px; }

.fishing-periods-title::before {
  content: '';
  width: 3px;
  height: 12px;
  background: linear-gradient(180deg, var(--white-50) 0%, var(--white-20) 100%);
  border-radius: 2px;
}

/* Solunar Widget Styles - REDESIGNED */
.solunar-badge {
  font-size: var(--fs-xs);
  color: white;
  font-weight: var(--fw-bold);
  padding: 3px 8px;
  border-radius: 4px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

/* ===== SISTEMA UNIFORME BADGE SCORE ===== */
/* Scala 1-10 gradazioni per widget solunar, previsioni e altri score */
/* Gradazione fluida: verde (ottimo) → verde-acqua → ciano → azzurro → blu (pessimo) */

/* Eccellente (9-10) - Verde smeraldo */
.badge-score-10 {
  background: linear-gradient(135deg, #059669 0%, #047857 100%);
  color: white;
}
.text-score-10 { color: #059669; }

.badge-score-9 {
  background: linear-gradient(135deg, #10B981 0%, #059669 100%);
  color: white;
}
.text-score-9 { color: #10B981; }

/* Ottimo (7-8) - Verde */
.badge-score-8 {
  background: linear-gradient(135deg, #22c55e 0%, #16a34a 100%);
  color: white;
}
.text-score-8 { color: #22c55e; }

.badge-score-7 {
  background: linear-gradient(135deg, #34d399 0%, #10b981 100%);
  color: white;
}
.text-score-7 { color: #10b981; }

/* Buono (5-6) - Verde-acqua / Turchese */
.badge-score-6 {
  background: linear-gradient(135deg, #2dd4bf 0%, #14b8a6 100%);
  color: white;
}
.text-score-6 { color: #14b8a6; }

.badge-score-5 {
  background: linear-gradient(135deg, #14b8a6 0%, #0d9488 100%);
  color: white;
}
.text-score-5 { color: #0d9488; }

/* Discreto (3-4) - Ciano / Azzurro chiaro */
.badge-score-4 {
  background: linear-gradient(135deg, #22d3ee 0%, #06b6d4 100%);
  color: white;
}
.text-score-4 { color: #06b6d4; }

.badge-score-3 {
  background: linear-gradient(135deg, #38bdf8 0%, #0ea5e9 100%);
  color: white;
}
.text-score-3 { color: #0284c7; }

/* Scarso (1-2) - Azzurro / Blu */
.badge-score-2 {
  background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
  color: white;
}
.text-score-2 { color: #2563eb; }

.badge-score-1 {
  background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);
  color: white;
}
.text-score-1 { color: #1d4ed8; }

/* Fallback per score 0 o non valido */
.badge-score-0 {
  background: linear-gradient(135deg, #9ca3af 0%, #6b7280 100%);
  color: white;
}
.text-score-0 { color: #6b7280; }

/* Legacy classes (deprecated, manteniamo per retrocompatibilità) */
.solunar-badge-major {
  background: linear-gradient(135deg, #10B981 0%, #059669 100%);
}

.solunar-badge-minor {
  background: linear-gradient(135deg, #65A30D 0%, #4d7c0f 100%);
}

/* .solunar-stars rimosso - non più utilizzato */

.solunar-status-in-progress {
  position: relative;
}

/* FIX TASK NT-35: Increased specificity, removed !important */
.data-row.solunar-status-in-progress {
  padding-left: 10px;
}

.solunar-status-in-progress::before {
  content: '';
  position: absolute;
  left: 0px;
  top: 50%;
  transform: translateY(-50%);
  width: 6px;
  height: 6px;
  background: #10B981;
  border-radius: 50%;
  animation: pulse 2s infinite;
}

.solunar-status-upcoming {
  opacity: 0.9;
}

@keyframes pulse {
  0%, 100% {
    opacity: 1;
    transform: translateY(-50%) scale(1);
  }
  50% {
    opacity: 0.5;
    transform: translateY(-50%) scale(1.2);
  }
}

/* Fishing View Layout Improvements */
.fishing-view-container {
  padding-bottom: 1rem;
}

/* Improve data rows in solunar widget - REDESIGNED */
.widget[aria-label="Widget Tabelle Solunari"] .data-row {
  padding: 8px 0;
  margin: 0;
  border-bottom: 1px solid var(--white-10);
  transition: background-color 0.15s ease;
}

.widget[aria-label="Widget Tabelle Solunari"] .data-row:last-child {
  border-bottom: none;
}

.widget[aria-label="Widget Tabelle Solunari"] .data-row:hover {
  background-color: var(--white-05);
}

/* Solunar widget chart container - REDESIGNED */
.widget[aria-label="Widget Tabelle Solunari"] .chart-container {
  margin: 10px 0;
  padding: 0;
  background: transparent;
  border-radius: 0;
}

/* Responsive adjustments for fishing periods */
@media (max-width: 374px) {
  .fishing-period-weather {
    /* no gap: ridefinito con margin */
  }
  /* iOS 12: gap non funziona in flexbox */
  .fishing-period-weather > * + * { margin-left: 4px; }

  .fishing-period-weather img {
    width: 20px;
    height: 20px;
  }

  .fishing-period-weather-label {
    display: none;
  }

  .fishing-period-badge {
    min-width: 36px;
    font-size: var(--fs-md);
    padding: 3px 8px;
  }

  .fishing-period-type {
    font-size: var(--fs-xs);
  }
}

/* Low power mode: disable accordion animations */
html[data-power="low"] .fishing-factors,
html[data-power="low"] .fishing-period-header .arrow-accordion {
  transition: none !important;
}

/* Tablet/Desktop: migliora spaziatura e leggibilità */
@media (min-width: 768px) {
  .fishing-period {
    margin-bottom: 10px;
  }

  .fishing-period-header {
    padding: 12px 16px;
  }

  .fishing-period-type {
    font-size: var(--fs-base);
  }

  .fishing-period-time {
    font-size: var(--fs-sm);
  }

  .fishing-period-weather img {
    width: 28px;
    height: 28px;
  }

  .fishing-period-weather-label {
    font-size: var(--fs-xs);
    max-width: 80px;
  }

  .fishing-period-badge {
    font-size: 15px;
    padding: 5px 12px;
    min-width: 44px;
  }

  .fishing-factors {
    padding: 12px 16px;
  }
  /* iOS 12: gap non funziona in flexbox */
  .fishing-factors > * + * { margin-top: 8px; }

  .fishing-factor-row {
    font-size: var(--fs-sm);
  }

  .fishing-factor-value {
    font-size: var(--fs-base);
  }
}

@media (min-width: 1024px) {
  .fishing-period-header {
    padding: 14px 20px;
  }

  .fishing-factors {
    padding: 14px 20px;
  }
}

/* ============================================================================
   FIX TASK NT-6: Animazioni Non Ottimizzate Low-Power
   ============================================================================

   Disabilita animazioni non essenziali quando in battery-saver mode per
   ridurre consumo batteria su dispositivi mobili.

   Power-manager.js (Task NT-21) imposta automaticamente:
   - body.battery-saver class quando POWER.isLow() === true
   - html[data-power="low"] attribute

   Animazioni DISABILITATE in low-power:
   - clouds-move-* (tutte le varianti 1-80): movimento nuvole decorativo
   - starPop: animazione stelle decorativa
   - pulse, pulse-dot: pulsazioni decorative

   Animazioni MANTENUTE: gli spinner veri, esclusi dalla regola che spegne
   animazioni e transition in low (in testa al file, LOW POWER OVERRIDES).
   ============================================================================ */

/* Disabilita animazioni nuvole (clouds-move-*) */
body.battery-saver .weather-overlay,
html[data-power="low"] .weather-overlay,
body.battery-saver .weather-overlay-cloud,
html[data-power="low"] .weather-overlay-cloud,
body.battery-saver [class*="weather-overlay-cloud-"],
html[data-power="low"] [class*="weather-overlay-cloud-"] {
  animation: none !important;
  /* Fallback: mantieni posizione statica */
  transform: translateX(0) translateY(0) !important;
}

/* Disabilita animazione stelle */
body.battery-saver .star,
html[data-power="low"] .star {
  animation: none !important;
  opacity: 0.8 !important; /* opacità statica invece di animata */
}

/* Disabilita pulsazioni decorative */
body.battery-saver [class*="pulse"],
html[data-power="low"] [class*="pulse"] {
  animation: none !important;
}

/* Disabilita ombre complesse (GPU-intensive) in low-power */
body.battery-saver *:not(canvas):not(svg):not(video),
html[data-power="low"] *:not(canvas):not(svg):not(video) {
  box-shadow: none !important;
  text-shadow: none !important;
}

/* Eccezioni: mantieni ombre minimali per UI critica (leggibilità) */
body.battery-saver .btn,
body.battery-saver .card,
body.battery-saver .modal,
html[data-power="low"] .btn,
html[data-power="low"] .card,
html[data-power="low"] .modal {
  box-shadow: var(--shadow-subtle) !important; /* FIX TASK NT-34 */
}

/* Riduce blur effects (GPU-intensive) */
body.battery-saver *:not(canvas):not(svg):not(video),
html[data-power="low"] *:not(canvas):not(svg):not(video) {
  filter: none !important;
  -webkit-filter: none !important;
}

/* ============================================================================
   END FIX TASK NT-6
   ============================================================================ */

/* ============================================================================
   PROGRESSIVE PERFORMANCE TIERS (data-perf-tier)
   Tier "ultra" (0-24): device moderni, nessuna limitazione
   Tier "mid"   (25-39): device 2019-2021, degradazione leggera
   Tier "low"   (40+):   device <2019, max riduzione (già gestito da data-power)
   ============================================================================ */

/* Particle density per tier — letta da JS per scalare il count delle particelle */
html[data-perf-tier="ultra"] { --particle-density: 1.0; }
html[data-perf-tier="mid"]   { --particle-density: 0.6; }
html[data-perf-tier="low"]   { --particle-density: 0.2; }

/* MID tier: transizioni piu' brevi */
html[data-perf-tier="mid"] {
  --apple-duration-slow: 0.3s;
  --apple-duration-normal: 0.15s;
}

/* Disabilita animazioni nuvole CSS in mid (GPU-intensive su device 2019-2021) */
html[data-perf-tier="mid"] .weather-overlay,
html[data-perf-tier="mid"] .weather-overlay-cloud,
html[data-perf-tier="mid"] [class*="weather-overlay-cloud-"] {
  animation: none !important;
  transform: translateX(0) translateY(0) !important;
}

/* ============================================================================
   END PROGRESSIVE PERFORMANCE TIERS
   ============================================================================ */

/* ============================================================================
   NOTIFICATION BANNER - Sistema Unificato
   ============================================================================ */

/**
 * Notification Banner
 *
 * Sistema centralizzato per tutte le notifiche:
 * - Pull-to-refresh
 * - Service worker updates
 * - Messaggi di stato
 *
 * Posizionato sopra location bar con z-index 9999
 * Colore neutro (grigio) per non distrarre
 */

.notification-banner,
.pull-to-refresh-indicator {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  width: 100%;
  background: rgba(60, 60, 67, 0.95);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  opacity: 0;
  transform: translateY(-100%);
  transition: opacity 0.3s ease-out, transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  pointer-events: none;
  box-shadow: 0 2px 12px var(--black-20);
  /* Safe-area per notch - padding simmetrico per centrare */
  padding: calc(12px + var(--safe-top)) env(safe-area-inset-right) 12px env(safe-area-inset-left);
  min-height: calc(50px + var(--safe-top));
}

/* Visible state */
.notification-banner.notification-visible,
.pull-to-refresh-indicator.ptr-visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

/* Consenso alle statistiche (consenso-statistiche.js): stessa superficie del
   banner avvisi, ma sopra la barra in basso e della sua larghezza — in cima
   starebbe sotto la location bar e sotto gli avvisi. «Accetta» e «Rifiuta»
   identici: rifiutare non deve costare piu' fatica. */
.consenso-statistiche {
  position: fixed;
  left: 50%;
  bottom: calc(var(--nav-h, 80px) + 4px + var(--ui-bottom-pad) + 10px);
  width: calc(100% - 20px);
  max-width: var(--chrome-max-width);
  z-index: 9998;
  padding: 14px 16px;
  border-radius: var(--r-md);
  background: rgba(60, 60, 67, 0.95);
  box-shadow: 0 2px 12px var(--black-20);
  color: #fff;
  opacity: 0;
  transform: translate(-50%, 12px);
  transition: opacity 0.3s ease-out, transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.consenso-statistiche.consenso-visibile {
  opacity: 1;
  transform: translate(-50%, 0);
}
.consenso-testo {
  margin: 0 0 12px;
  font-size: var(--fs-md);
  line-height: 1.4;
}
.consenso-testo a { color: #fff; text-decoration: underline; }
.consenso-azioni { display: flex; gap: 10px; }
.consenso-btn {
  flex: 1 1 0;
  min-height: 44px;
  border: 1px solid var(--white-45);
  border-radius: var(--r-sm, 8px);
  background: var(--white-10);
  color: #fff;
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
}
/* Con un pannello aperto il banner si fa da parte: col telefono girato copriva
   il bottone del pannello Account. Torna alla chiusura, la scelta resta da fare. */
body:has(.offcanvas.show, .offcanvas.showing) .consenso-statistiche {
  visibility: hidden;
  opacity: 0;
}
@media (prefers-reduced-motion: reduce) {
  .consenso-statistiche { transition: none; }
}

/* Content layout */
.notification-banner-content {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  max-width: 100%;
  /* Nessun padding aggiuntivo - gestito dal container */
}
/* iOS 12: gap non funziona in flexbox */
.notification-banner-content > * + * { margin-left: 12px; }

/* Spinner Container */
.notification-spinner,
.ptr-spinner {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  position: relative;
  /* Allineamento verticale perfetto */
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Circular SVG Spinner */
.notification-circular,
.ptr-circular {
  width: 100%;
  height: 100%;
  transform-origin: center;
}

.notification-path,
.ptr-path {
  stroke: white;
  stroke-linecap: round;
  stroke-dasharray: 90, 150;
  stroke-dashoffset: 0;
  transform-origin: center;
}

/* Soglia raggiunta: lo spinner si chiude in cerchio pieno e ruota di mezzo
   giro. E' il segnale che al rilascio l'aggiornamento parte davvero — senza,
   l'unico indizio e' il cambio di testo, che a meta' gesto non si legge. */
.pull-to-refresh-indicator .ptr-path {
  transition: stroke-dasharray 180ms ease-out, transform 180ms ease-out;
}
.pull-to-refresh-indicator.ptr-ready:not(.ptr-refreshing) .ptr-path {
  stroke-dasharray: 126, 150;
  transform: rotate(180deg);
}
@media (prefers-reduced-motion: reduce) {
  .pull-to-refresh-indicator .ptr-path {
    transition: none;
  }
}

/* Spinner animation when active/refreshing */
.notification-spinner-active .notification-circular,
.ptr-refreshing .ptr-circular {
  animation: notification-rotate 2s linear infinite;
}

.notification-spinner-active .notification-path,
.ptr-refreshing .ptr-path {
  animation: notification-dash 1.5s ease-in-out infinite;
  stroke-dasharray: 90, 150;
}

@keyframes notification-rotate {
  100% {
    transform: rotate(360deg);
  }
}

@keyframes notification-dash {
  0% {
    stroke-dasharray: 1, 150;
    stroke-dashoffset: 0;
  }
  50% {
    stroke-dasharray: 90, 150;
    stroke-dashoffset: -35;
  }
  100% {
    stroke-dasharray: 90, 150;
    stroke-dashoffset: -124;
  }
}

/* Backward compatibility alias */
@keyframes ptr-rotate {
  100% {
    transform: rotate(360deg);
  }
}

@keyframes ptr-dash {
  0% {
    stroke-dasharray: 1, 150;
    stroke-dashoffset: 0;
  }
  50% {
    stroke-dasharray: 90, 150;
    stroke-dashoffset: -35;
  }
  100% {
    stroke-dasharray: 90, 150;
    stroke-dashoffset: -124;
  }
}

/* Text */
.notification-text,
.ptr-text {
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  line-height: 1.4;
  color: white;
  letter-spacing: -0.01em;
  text-align: left;
  user-select: none;
  flex: 1 1 auto;
  /* Allineamento verticale perfetto */
  align-items: center;
  justify-content: flex-start;
  margin: 0;
  padding: 0 8px;
  word-wrap: break-word;
  max-width: 100%;
}

/* Action Button */
.notification-action {
  padding: 7px 14px;
  border: none;
  border-radius: 6px;
  background: var(--white-20);
  color: white;
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
  line-height: 1.2;
  cursor: pointer;
  transition: background 0.2s ease;
  flex-shrink: 0;
  margin-right: 12px;
  /* Allineamento verticale */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
}

.notification-action:hover {
  background: var(--white-30);
}

.notification-action:active {
  background: var(--white-15);
}

/* ============================================================================
   NOTIFICATION VARIANTS
   ============================================================================ */

/* Success (green) */
.notification-banner.notification-success {
  background: rgba(52, 199, 89, 0.95);
}

/* Warning (orange) */
.notification-banner.notification-warning {
  background: rgba(255, 149, 0, 0.95);
}

/* Error (red) */
.notification-banner.notification-error {
  background: rgba(255, 59, 48, 0.95);
}

/* Error view uses notification banner styling */
.error-view-container {

}

.error-view-banner {
  position: static;
  transform: none;
  opacity: 1;
  pointer-events: auto;
  border-radius: 12px;
  min-height: auto;
  padding: 12px 16px;
  box-shadow: 0 8px 24px var(--black-18);
}

.error-view-banner .notification-banner-content {
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-start;
}
/* iOS 12: gap non funziona in flexbox - override margin-left con column-direction */
.error-view-banner .notification-banner-content > * + * { margin-left: 0; margin-top: 10px; }

.error-view-banner .notification-text {
  width: 100%;
  padding: 0;
  user-select: text;
}

.error-view-actions {
  display: flex;
  flex-wrap: wrap;
  margin: -8px 0 0 -8px; /* iOS 12: flex-wrap gap simulation */
}
.error-view-actions > * {
  margin: 8px 0 0 8px; /* iOS 12: flex-wrap gap simulation */
}

/* Pagina trascinata dal pull-to-refresh.
   Durante il drag NESSUNA transizione: la pagina deve stare incollata al dito,
   e i 100ms di ease-out che c'erano prima la facevano arrivare in ritardo su
   ogni cambio di direzione. La transizione serve solo al rientro, quando il
   dito ha gia' lasciato. */
html.ptr-pulling,
html.ptr-pulling body {
  transition: none;
  will-change: transform;
}
html.ptr-releasing,
html.ptr-releasing body {
  transition: transform 280ms cubic-bezier(0.22, 1, 0.36, 1);
}
@media (prefers-reduced-motion: reduce) {
  html.ptr-releasing,
  html.ptr-releasing body {
    transition: none;
  }
}

/* Dark mode: stessa tonalità neutra, leggermente più scura */
@media (prefers-color-scheme: dark) {
  .notification-banner,
  .pull-to-refresh-indicator {
    background: rgba(44, 44, 46, 0.95);
  }

  .notification-banner.notification-success {
    background: rgba(48, 209, 88, 0.95);
  }

  .notification-banner.notification-warning {
    background: rgba(255, 159, 10, 0.95);
  }

  .notification-banner.notification-error {
    background: rgba(255, 69, 58, 0.95);
  }
}

/* Responsive: Ottimizzazione per schermi piccoli (iPhone) */
@media (max-width: 374px) {
  .notification-banner-content {
    flex-direction: column;
    padding: 8px;
  }
  /* iOS 12: gap non funziona in flexbox - override per column direction */
  .notification-banner-content > * + * { margin-left: 0; margin-top: 10px; }

  .notification-text,
  .ptr-text {
    font-size: var(--fs-md);
    padding: 0 4px;
  }

  .notification-action {
    padding: 6px 12px;
    font-size: var(--fs-base);
    width: 100%;
  }
}

/* Responsive: Schermi 375-429px (chiude gap 375-389 vs intent commento) */
@media (min-width: 375px) and (max-width: 429px) {
  .notification-text,
  .ptr-text {
    font-size: var(--fs-md);
  }

  .notification-action {
    padding: 6px 12px;
    font-size: var(--fs-base);
  }
}

/* ============================================================================
   HIDE REFRESH BUTTON ON TOUCH DEVICES
   ============================================================================ */

/**
 * Hide physical refresh button when pull-to-refresh is available
 * - Only hides on touch-capable devices
 * - Keeps button visible for mouse-only devices (desktop)
 * - Uses :has-pull-to-refresh class added by JS
 */

/* Hide refresh button on devices with pull-to-refresh */
html.has-pull-to-refresh #loc-refresh-btn {
  display: none !important;
}

/* Optional: Add small hint icon showing pull gesture is available */
html.has-pull-to-refresh .location-bar::before {
  content: '';
  position: absolute;
  top: -4px;
  left: 50%;
  transform: translateX(-50%);
  width: 40px;
  height: 4px;
  background: linear-gradient(to right, transparent, rgba(66, 165, 245, 0.3), transparent);
  border-radius: 2px;
  opacity: 0.5;
  pointer-events: none;
}

/* Subtle pulse animation for the hint */
@keyframes ptr-hint-pulse {
  0%, 100% { opacity: 0.3; }
  50% { opacity: 0.6; }
}

html.has-pull-to-refresh .location-bar::before {
  animation: ptr-hint-pulse 3s ease-in-out infinite;
}

/* Hide hint when user interacts */
html.has-pull-to-refresh .location-bar:active::before,
html.has-pull-to-refresh .location-bar:focus-within::before {
  opacity: 0;
}

/* Responsive: Ensure proper spacing without refresh button */
/* iOS 12: gap non funziona in flexbox - override margin-left della regola base (5px) */
html.has-pull-to-refresh .location-bar .loc-actions > * + * { margin-left: 8px; }

/* ============================================================================
   ACCESSIBILITY & REDUCED MOTION
   ============================================================================ */

/* ============================================================================
   END PULL TO REFRESH
   ============================================================================ */

/* ============================================================================
   Z-INDEX HIERARCHY - Clear layering for all overlays
   ============================================================================ */

/* Critical system overlays (highest priority) */
.pull-to-refresh-indicator {
  z-index: 99999 !important; /* Highest priority - must be above all */
}

/* Chart tooltips - must be visible above everything except pull-to-refresh */
.chartjs-tooltip {
  z-index: 99995 !important;
  pointer-events: none;
}

/* Alert/Notification bars - high priority system messages */
.pwa-install-banner {
  z-index: 99990 !important;
}

.notification-banner {
  z-index: 99985 !important;
}

/* Map overlays and busy states */
.stazioni-map-overlay,
#stazioni-map .map-progress {
  z-index: 99980 !important;
}

/* Standard UI elements - modals, dropdowns, tooltips */
.modal,
.dropdown,
.tooltip,
.popover {
  z-index: 99970 !important;
}

/* Background content layers */
.main-content,
.map-container {
  z-index: 1;
}

/* ============================================================================
   END Z-INDEX HIERARCHY
   ============================================================================ */

/* ============================================================================
   TOUCH & OVERSCROLL PROTECTION - Prevent gesture conflicts
   ============================================================================ */

/* Map area protection - prevent pull-to-refresh and scroll conflicts */
#stazioni-map {
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: auto;
  touch-action: pan-x pan-y; /* Allow pan gestures on map */
}

/* Ensure all map children inherit protection */
#stazioni-map * {
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: auto;
}

/* Canvas elements in charts - allow gestures but prevent conflicts */
canvas[data-chart] {
  touch-action: pan-x pan-y pinch-zoom; /* Allow all chart gestures */
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: auto;
}

/* Map and chart containers - prevent interference with page scroll */
.map-container,
.chart-container {
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: auto;
}

/* Hardware acceleration for smooth rendering */
#stazioni-map,
canvas[data-chart] {
  will-change: transform;
  transform: translateZ(0);
  -webkit-transform: translateZ(0);
}

/* ============================================================================
   END TOUCH & OVERSCROLL PROTECTION
   ============================================================================ */

/* ============================================================================
   CSS TOUCH PROTECTION - Mobile UX Optimization
   ============================================================================ */

/* Global tap highlight removal for clean visual feedback */
html,
body {
  -webkit-tap-highlight-color: transparent;
}

/* Eliminate 300ms click delay on interactive elements */
button,
.btn,
[role="button"],
a {
  touch-action: manipulation;
}

/* Restore normal touch behavior for form elements */
input,
textarea,
select {
  touch-action: auto;
}

/* Intelligent user selection control */
/* Allow text selection on content elements */
p,
span:not([class*="btn"]),
div:not([role]):not([class*="btn"]),
li {
  -webkit-user-select: text !important;
  user-select: text !important;
}

/* Ensure form inputs allow text selection and editing */
input,
textarea,
select,
[contenteditable="true"] {
  -webkit-user-select: text !important;
  user-select: text !important;
}

/* Prevent selection on interactive elements */
button,
.btn,
[role="button"] {
  -webkit-user-select: none !important;
  user-select: none !important;
}

/* ============================================================================
   END CSS TOUCH PROTECTION
   ============================================================================ */

/* ============================================================================
   PWA DETECTION & DISPLAY MODE - Environment-specific styles
   ============================================================================ */

/* PWA Standalone Mode - Optimizations for installed app */
@media (display-mode: standalone) {
  html,
  body {
    /* Use dynamic viewport height in PWA for better screen usage */
    height: 100vh;
    height: 100dvh;
  }

  /* Ensure safe area insets are properly applied in PWA */
  .pwa-mode {
    /* PWA-specific adjustments can go here if needed */
  }
}

/* PWA Fullscreen Mode - Maximum screen usage */
@media (display-mode: fullscreen) {
  .pwa-fullscreen-mode {
    /* Fullscreen-specific styles */
  }
}

/* Utility Classes for PWA vs Browser Mode */

/* Hide elements only in PWA mode */
.web-only {
  display: block;
}

.pwa-mode .web-only {
  display: none;
}

/* Hide elements only in browser mode */
.pwa-only {
  display: none;
}

.pwa-mode .pwa-only {
  display: block;
}

/* Inline elements variants */
span.web-only,
span.pwa-only {
  display: inline;
}

.pwa-mode span.web-only {
  display: none;
}

.pwa-mode span.pwa-only {
  display: inline;
}

/* ============================================================================
   END PWA DETECTION & DISPLAY MODE
   ============================================================================ */

/* ============================================================================
   DAY FORECAST CAROUSEL - Bootstrap Carousel Integration
   ============================================================================ */

/* Carousel principale */
#dayForecastCarousel {
  position: relative;
  margin-bottom: 0.5rem;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  touch-action: pan-y pinch-zoom;
}

#dayForecastCarousel:active {
  cursor: grabbing;
}

/* Carousel inner */
#dayForecastCarousel .carousel-inner {
  overflow: hidden;
  position: relative;
}

/* Carousel items - Bootstrap gestisce display/visibility */
#dayForecastCarousel .carousel-item {
  position: relative;
  display: none;
  float: left;
  width: 100%;
  margin-right: -100%;
  padding: 0;
  opacity: 1 !important;
  will-change: transform; /* Hardware acceleration */
  backface-visibility: hidden; /* Riduce flickering */
  -webkit-backface-visibility: hidden;
  transition: transform 0.45s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

#dayForecastCarousel .carousel-item.active,
#dayForecastCarousel .carousel-item-next,
#dayForecastCarousel .carousel-item-prev {
  display: block;
}

#dayForecastCarousel .carousel-item-next {
  transform: translateX(100%);
}

#dayForecastCarousel .carousel-item-prev {
  transform: translateX(-100%);
}

#dayForecastCarousel .carousel-item-next.carousel-item-start,
#dayForecastCarousel .carousel-item-prev.carousel-item-end,
#dayForecastCarousel .carousel-item.active.carousel-item-start,
#dayForecastCarousel .carousel-item.active.carousel-item-end {
  transform: translateX(0);
}

#dayForecastCarousel .carousel-item.active.carousel-item-start {
  transform: translateX(-100%);
}

#dayForecastCarousel .carousel-item.active.carousel-item-end {
  transform: translateX(100%);
}

#dayForecastCarousel .carousel-item .widget {
  margin-bottom: 5px;
}

#dayForecastCarousel .carousel-item .widget .btn-accordion .widget-cont {
  width: 100%;
}

/* Durante animazione slide - transizione più veloce e fluida */
#dayForecastCarousel .carousel-item-next,
#dayForecastCarousel .carousel-item-prev,
#dayForecastCarousel .carousel-item.active {
  opacity: 1 !important;
  transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); /* Easing più naturale */
}

/* Contenitore dentro carousel-item */
#dayForecastCarousel .carousel-item > .d-flex {
  width: 100%;
}
/* iOS 12: gap non funziona in flexbox */
#dayForecastCarousel .carousel-item > .d-flex > * + * { margin-left: 15px; }

/* Widget dentro il carousel */
#dayForecastCarousel .widget-riga {
  min-width: 100%;
  flex: 0 0 100%;
}

/* Indicatori di paginazione sotto il carousel */
#dayForecastCarousel .carousel-indicators {
  position: static !important;
  display: flex !important;
  margin: 12px 0 20px 0;
  padding: 0;
  justify-content: center;
  list-style: none;
  z-index: 2;
}

#dayForecastCarousel .carousel-indicators button {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin: 0 5px;
  padding: 0;
  background-color: var(--white-40) !important;
  border: none !important;
  opacity: 1 !important;
  transition: background-color 0.25s ease, transform 0.25s ease;
  cursor: pointer;
  flex-shrink: 0;
}

#dayForecastCarousel .carousel-indicators button:hover {
  background-color: var(--white-60) !important;
  transform: scale(1.15);
}

#dayForecastCarousel .carousel-indicators button.active {
  background-color: var(--white-95) !important;
  transform: scale(1.3);
}

/* Responsive adjustments */
@media (max-width: 767px) {
  #dayForecastCarousel .carousel-indicators button {
    width: 5px;
    height: 5px;
    margin: 0 3px;
  }
}

/* ============================================================================
   END DAY FORECAST CAROUSEL
   ============================================================================ */

/* ========== WEATHER GRADIENT ENGINE - PARAMETRIC OVERLAYS ========== */
/* New overlay styles for the parametric weather gradient system */

/* Water & Rain Overlays */
.weather-overlay.overlay-water_pattern {
  background-image: radial-gradient(circle at 30% 40%, rgba(200, 220, 240, 0.4) 0%, transparent 50%);
  mix-blend-mode: multiply;
}

.weather-overlay.overlay-light_drops {
  background-image: radial-gradient(circle, rgba(150, 180, 220, 0.3) 0%, transparent 60%);
  animation: rain-drift 4s ease-in-out infinite;
}

.weather-overlay.overlay-medium_drops {
  background: linear-gradient(180deg, rgba(100, 150, 200, 0.4) 0%, transparent 70%);
  animation: rain-medium 3s ease-in-out infinite;
}

.weather-overlay.overlay-heavy_sheets {
  background: linear-gradient(180deg, rgba(80, 120, 180, 0.6) 0%, rgba(60, 100, 160, 0.4) 50%, transparent 100%);
  mix-blend-mode: screen;
}

/* Snow Overlays – particles handled by canvas (snow-particles.js) */

/* Fog Overlays */
.weather-overlay.overlay-light_haze {
  background: radial-gradient(ellipse at 50% 0%, var(--white-20) 0%, transparent 80%);
}

.weather-overlay.overlay-thick_haze {
  background: radial-gradient(ellipse at 50% 50%, rgba(200, 200, 200, 0.3) 0%, transparent 70%);
  mix-blend-mode: soft-light;
}

.weather-overlay.overlay-dense_fog {
  background: linear-gradient(180deg, rgba(180, 180, 180, 0.5) 0%, rgba(150, 150, 150, 0.3) 50%, transparent 100%);
  mix-blend-mode: overlay;
}

.weather-overlay.overlay-fog_effect {
  background: radial-gradient(ellipse at 50% 40%, rgba(200, 200, 200, 0.25) 0%, transparent 100%);
}

/* Lightning Overlay */
.weather-overlay.overlay-lightning {
  background: transparent;
  mix-blend-mode: screen;
}

/* Animations */
@keyframes rain-drift {
  0%, 100% {
    opacity: 0.2;
    transform: translateX(-5px);
  }
  50% {
    opacity: 0.4;
    transform: translateX(5px);
  }
}

@keyframes rain-medium {
  0%, 100% {
    opacity: 0.35;
  }
  50% {
    opacity: 0.5;
  }
}

/* @keyframes snow-fall removed – was rotating the entire .weather-overlay container
   as a grey box. Snow particles are rendered on <canvas> by snow-particles.js */

@keyframes lightning-flash {
  0% {
    opacity: 0;
    background: var(--white-80);
  }
  50% {
    opacity: 0.3;
  }
  100% {
    opacity: 0;
    background: transparent;
  }
}

/* Responsive overlay sizes */
@media (max-width: 767px) {
  .weather-overlay {
    opacity: var(--precip-opacity, 0.5);
  }
}

/* ============================================================================
   DYNAMIC WEATHER EFFECTS - Nuovi effetti per il sistema semplificato
   ============================================================================ */

/* Rain overlay effect - applicato su weather-gradient o weather-overlay */
body.rain-overlay .weather-overlay {
  background-image: radial-gradient(2px 2px at 20% 30%, rgba(100, 150, 200, 0.15), rgba(100, 150, 200, 0.05));
  animation: rain-drift 8s linear infinite;
}

body.rain-overlay .weather-gradient {
  filter: brightness(0.92) contrast(1.05) saturate(0.95);
}

/* Rain sound effect - può essere accompagnato da audio */
body.rain-sound {
  /* Gli audio sono gestiti via JavaScript */
}

/* Snow overlay effect – particle snowflakes are rendered on <canvas> by snow-particles.js.
   No CSS animation here: the old snow-fall keyframe rotated the entire full-screen
   .weather-overlay container (cloud images included), producing a visible grey spinning box. */
body.snow-overlay .weather-overlay {
  /* atmospheric white wash only – no animation */
}

body.snow-overlay .weather-gradient {
  filter: brightness(1.05) saturate(0.85);
}

/* Snow animation */
body.snow-animation {
  /* Animazione neve applicata */
}

/* Fog overlay effect */
body.fog-overlay {
  --fog-opacity: 0.4;
}

/* body.fog-overlay .weather-overlay {
  background: linear-gradient(180deg, rgba(200, 200, 200, 0.2), rgba(200, 200, 200, 0.15));
  backdrop-filter: blur(2px);
} */

body.fog-overlay .weather-gradient {
  filter: brightness(0.88) contrast(0.85) saturate(0.8);
}

/* Lightning flash effect - lampo istantaneo */
body.lightning-flash {
  animation: lightning-strike 0.2s ease-out 1;
}

@keyframes lightning-strike {
  0% {
    filter: brightness(1);
  }
  50% {
    filter: brightness(1.8) contrast(1.3) hue-rotate(180deg);
  }
  100% {
    filter: brightness(1);
  }
}

/* ============================================================================
   Fine sezione DYNAMIC WEATHER EFFECTS
   ============================================================================ */

/* ============================================================================
   NOTA (2026-02-22): Il blocco @supports not (gap: 1px) è stato rimosso.
   Motivo: iOS 12 / Safari 12 supporta gap in CSS Grid ma NON in Flexbox,
   quindi @supports restituisce 'false' su iOS 12 e il fallback non si applica.
   Soluzione: gap rimosso da tutti i flex container e sostituito con regole
   > * + * permanenti (margin) nei rispettivi selettori più sopra nel file.
   ============================================================================ */

/* ============================================================================
   RESPONSIVE DEVICE TUNING (2026-04-29)
   Target: iPhone 5, XS, 12 Pro, 15 Pro Max, iPad mini, iPad Pro 11".
   Solo dimensioni, larghezze e scala tipografica: layout e componenti invariati.
   ============================================================================ */

html,
body {
  max-width: 100%;
  overflow-x: hidden;
}

.nav-link-nav {
  min-width: 0;
}

@media (max-width: 429px) {
  .container-custom {
    padding-left: 10px;
    padding-right: 10px;
  }

  .location-bar {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    justify-content: normal;
    padding-bottom: 16px;
    overflow: hidden;
  }

  .location-bar > * + * {
    margin-left: 6px;
  }

  .location-bar .loc-labels {
    justify-self: end;
    width: auto;
    min-width: 0;
    /* Tetto come sotto i 375px: riga dei bottoni (166px con la campanella) piu'
       distanze e bordo. Senza, un nome lungo spingeva la stella dei preferiti
       fuori schermo (misurato 12/10/2026 a 375px: 6px dal bordo con
       «Marghera Malcontenta, Venezia»). Un bottone in piu' va sommato qui. */
    max-width: calc(100vw - 192px);
  }

  .location-bar .loc-labels .loc-name {
    font-size: var(--fs-xs);
    line-height: 1.15;
  }

  .location-bar .loc-labels .loc-elev,
  .location-bar .loc-labels .loc-update-time,
  .location-bar .loc-labels .loc-modello,
  .location-bar .loc-labels .update-time {
    font-size: var(--fs-xs);
    line-height: 1.15;
  }

  .location-bar .loc-actions {
    justify-self: end;
    flex: 0 0 auto;
  }

  .location-bar .loc-actions > * + * {
    margin-left: 4px;
  }

  .location-bar .loc-actions a,
  .location-bar .loc-actions button {
    width: 30px;
    height: 30px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: var(--fs-md);
    border-radius: 7px;
  }

  .home-favorites {
    padding: 10px;
  }

  .home-favorites .home-favorites-list .list-group-item {
    white-space: normal;
    font-size: var(--fs-sm);
    line-height: 1.35;
  }

  .home-favorites .home-favorites-list .list-group-item strong {
    font-size: var(--fs-md);
  }

  .home-favorites .home-favorites-list .list-group-item .text-muted {
    font-size: var(--fs-sm);
  }

  .day-forecast-toggle {
    padding-left: 14px;
    padding-right: 14px;
  }

  .dfr-main {
    grid-template-columns: 56px 38px 28px minmax(54px, 1fr) 34px 16px;
    column-gap: var(--sp-2);
  }

  .dfr-meta {
    grid-template-columns: 56px 38px minmax(0, 1fr) auto auto;
    column-gap: var(--sp-2);
  }

  .dfr-day-name,
  .dfr-temp {
    font-size: var(--fs-lg);
  }

  .dfr-day-date,
  .dfr-meta,
  .dfr-meta .dfm-item {
    font-size: var(--fs-sm);
  }

  .dfr-icon img {
    width: 36px;
    height: 36px;
  }

  .fishing-forecast-list {
    --pl-chev: 14px;
    --pl-gap: 7px;
  }
  .fishing-forecast-list .dfr-main {
    grid-template-columns: minmax(48px, auto) auto auto minmax(0, 1fr) var(--pl-chev);
  }

  .fishing-forecast-list .dfr-meta {
    grid-template-columns: minmax(0, 1fr) auto auto;
    column-gap: 7px;
  }

  .fishing-forecast-list .dfr-meta .dfm-item {
    gap: 4px;
  }
}

@media (max-width: 374px) {
  .container-custom {
    padding-left: 8px;
    padding-right: 8px;
  }

  .location-bar {
    padding-bottom: 14px;
  }

  .location-bar > * + * {
    margin-left: 5px;
  }

  .location-bar .loc-labels {
    /* Il numero e' la larghezza della riga dei bottoni piu' il respiro a
       sinistra: sotto i 375px niente altro limita le etichette, quindi un
       bottone aggiunto in .loc-actions va sommato QUI o la stella dei
       preferiti finisce fuori schermo (misurato a 360px: -19px con cinque
       bottoni e il vecchio 126). Cinque bottoni = 132px + 5 di distanza. */
    flex-basis: calc(100vw - 161px);
    max-width: calc(100vw - 161px);
  }

  .location-bar .loc-labels .loc-name {
    font-size: var(--fs-xs);
  }

  .location-bar .loc-labels .loc-elev,
  .location-bar .loc-labels .loc-update-time,
  .location-bar .loc-labels .loc-modello,
  .location-bar .loc-labels .update-time {
    font-size: var(--fs-xs);
  }

  .location-bar .loc-actions > * + * {
    margin-left: 3px;
  }

  .location-bar .loc-actions a,
  .location-bar .loc-actions button {
    width: 27px;
    height: 27px;
    font-size: var(--fs-base);
    border-radius: 6px;
  }

  .nav-link-nav {
    --nav-ico: 19px;
  }

  .day-forecast-toggle {
    padding-left: 10px;
    padding-right: 10px;
  }

  .dfr-main {
    grid-template-columns: 50px 34px 26px minmax(42px, 1fr) 30px 14px;
    column-gap: 6px;
  }

  .dfr-meta {
    grid-template-columns: 50px 34px minmax(0, 1fr) auto auto;
    column-gap: 6px;
  }

  .dfr-day-name,
  .dfr-temp {
    font-size: 15px;
  }

  .dfr-icon img {
    width: 32px;
    height: 32px;
  }

  .day-bands.day-forecast-fasce-bands .day-band {
    grid-template-columns: 72px 24px minmax(42px, 1fr) auto;
    column-gap: var(--sp-2);
  }

  .day-bands.day-forecast-fasce-bands .day-band-temp {
    font-size: var(--fs-lg);
  }
}

@media (min-width: 375px) and (max-width: 413px) {
  .current-weather.today {
    gap: 12px;
  }

}

@media (min-width: 414px) and (max-width: 429px) {
  .location-bar .loc-labels {
    max-width: 230px;
  }
}

@media (min-width: 768px) and (max-width: 819px) {
  .location-bar .loc-actions a,
  .location-bar .loc-actions button {
    width: 38px;
    height: 38px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  .current-weather.today {
    min-height: 190px;
  }
}

/* ========== DESKTOP CAP (oltre tablet) ==========
 * Sopra 1194px (iPad Pro landscape) limita larghezza al feeling tablet.
 * Sovrascrive regole esistenti 1024+/1536+ che alzano fino a 1400/1800px,
 * percepite come dispersive su desktop wide.
 *
 * Cap 1100px: tablet portrait+ ergonomico, leggibilità mantenuta.
 * Override esplicito su .container-custom, .location-bar, .navbar-bottom-nav.
 */
@media (min-width: 1024px) {
  .container-custom {
    max-width: 1100px !important;
    margin-left: auto;
    margin-right: auto;
  }

  /* Location-bar è figlia di .container-custom → eredita cap.
     Override solo se necessario su display flex justify-content: flex-end.
     Niente max-width esplicito, già limitato dal padre. */

  /* Navbar desktop: cap coerente con il container-custom.
     Centratura/transform già sulla regola base. */

  /* Vista stazioni container ancora full-viewport per mappa */
  body.view-mappa .container-custom {
    max-width: 100% !important;
  }

  /* Override view-mappa rimosso: pill flottante anche su mappa per coerenza UI */
}

/* ============================================================
   CORREZIONI MIRATE 2026-05-01 (richieste utente)
   ============================================================ */
@media (max-width: 389px) {
  .day-forecast-toggle {
    padding: 16px 12px;
    gap: var(--sp-2);
  }
}

/* ============================================================
   IPHONE 5 (≤360px) — override finale per battere source-order
   ============================================================ */
@media (max-width: 374px) {
  .dfr-day-name,
  .dfr-temp {
    font-size: var(--fs-md);
  }
  .dfr-icon img {
    width: 36px;
    height: 36px;
  }
}

/* Forza regular su testi marea/solunar (richiesta utente: no bold) */
.marea-salute-text,
.solunar-tide-text {
  font-weight: var(--fw-regular);
}

/* Solunar — blocco dark con righe label/valore (stile stazioni laguna) */
.solunar-press-block {
  background: rgb(24 36 54);
  background: color-mix(in srgb, var(--meteo-color, #5393C8) 55%, #000);
  border-radius: var(--r-md);
  padding: 8px 10px;
  margin: 12px -2px 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  background-image:
    linear-gradient(rgb(0 0 0 / 18%), rgb(0 0 0 / 18%)),
    var(--meteo-gradient, linear-gradient(180deg, #1565C0 0%, #0D47A1 45%, #0A3A7C 100%));
  background-attachment: fixed;
  background-position: 0 0;
  background-size: 100vw 100vh;
  background-repeat: no-repeat;
}
.solunar-press-block .data-row .widget-text {
  opacity: 0.85;
}

/* Marea trend icon — riusa wi-direction-up della direzione vento */
.marea-trend-icon {
  display: inline-block;
  line-height: 1;
  font-size: 1.3em;
  position: relative;
  top: 0.18em;
}
.marea-trend-down {
  transform: rotate(180deg);
  top: 0.05em;
}

/* ===========================================================================
   WIDGET PREVISIONI ORARIE (.forecast.forecast-with-rain) — Apple Weather style
   Restyling 2026-05-20: flex-column verticale (niente position:absolute), token
   colore allineati al widget previsioni giornaliere, ordine via CSS `order`.

   Stack per item (Apple): [ora] · [icona] · [precip mm] · [temperatura]
   Nascosti vento/raffica/freccia direzione (presenti nel daily widget sotto).
   =========================================================================== */
.forecast {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  gap: 0;
  padding: 0;
}
.forecast.forecast-with-rain {
  position: relative;
}
.forecast::-webkit-scrollbar {
  display: none;
}

/* Ogni tile oraria: flex column, content centrato. `order` controlla la
   sequenza verticale a prescindere dall'ordine di output PHP. */
.forecast-item {
  flex: 0 0 auto;
  min-width: 64px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  text-align: center;
  padding: 12px 10px 12px;
  color: var(--white-70);
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  position: relative;
}
/* Solo la larghezza scala col viewport: il padding resta quello base, cosi'
   l'item riempie la riga senza margini sopra/sotto (il contenitore e' a 0). */
@media (min-width: 414px) {
  .forecast-item {
    min-width: 76px;
  }
}
@media (max-width: 374px) {
  .forecast-item {
    min-width: 56px;
  }
}

/* Ora — top muted */
.forecast-item .hour {
  order: 1;
  position: static;
  font-size: var(--fs-xs);
  font-weight: var(--fw-regular);
  color: var(--white-65);
  letter-spacing: 0.4px;
  line-height: 1;
  margin: 0 0 6px;
  opacity: 1;
}
@media (min-width: 414px) {
  .forecast-item .hour {
    font-size: var(--fs-sm);
    margin-bottom: 8px;
  }
}

/* Icona meteo — centrale, niente shadow */
.forecast-item .weather-svg-icon {
  order: 2;
  position: static;
  transform: none;
  width: 32px;
  height: 32px;
  margin: 0 0 4px;
  filter: none;
  display: block;
}
@media (min-width: 414px) {
  .forecast-item .weather-svg-icon {
    width: 38px;
    height: 38px;
    margin-bottom: 5px;
  }
}
@media (max-width: 374px) {
  .forecast-item .weather-svg-icon {
    width: 28px;
    height: 28px;
  }
}

/* Slot precipitazioni — slot riservato (vuoto preserva allineamento temp
   tra colonne con/senza pioggia). Altezza compatta: quando il dato è
   presente comprime leggermente, prezzo accettato per layout coerente. */
.forecast-item .rain-value-text {
  order: 3;
  position: static;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 3px;
  height: 12px;
  margin: 0 0 4px;
  font-size: 0.66rem;
  font-weight: var(--fw-regular);
  color: #64b5f6;
  white-space: nowrap;
  text-shadow: none;
  line-height: 1;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}
.forecast-item .rain-value-text.is-empty {
  visibility: hidden;
}
.forecast-item .rain-value-text.rain-hint {
  visibility: visible;
}
.forecast-item .forecast-rain-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(95, 179, 227, 0.55);
}
.forecast-item .rain-value-text i {
  font-size: 0.85em;
  margin: 0;
  opacity: 0.95;
}
@media (min-width: 414px) {
  .forecast-item .rain-value-text {
    font-size: var(--fs-xs);
    height: 14px;
    margin-bottom: 5px;
  }
}

/* Temperatura — Apple-style: peso regular, no bold */
.forecast-item .temp {
  order: 4;
  position: static;
  margin: 0;
  font-size: var(--fs-md);
  font-weight: var(--fw-regular);
  color: var(--white-95);
  letter-spacing: -0.3px;
  line-height: 1;
}
@media (min-width: 414px) {
  .forecast-item .temp {
    font-size: var(--fs-lg);
  }
}
@media (max-width: 374px) {
  .forecast-item .temp {
    font-size: var(--fs-sm);
  }
}

/* NASCOSTI: vento (eccesso di dati nella striscia oraria) + wind-box legacy
   + rain-bar fill. Markup PHP preservato per riattivazione futura. */
.forecast-item .wind-mini,
.forecast-item .wind-box,
.forecast-item .rain-bar-container {
  display: none;
}

/* === Alba / Tramonto: item speciali con gradient atmosferico === */
.forecast-item.tramonto,
.forecast-item.alba {
  min-width: 52px;
}
.forecast-item.tramonto {
  background: linear-gradient(
    to bottom,
    rgba(255, 179, 71, 0.20),
    rgba(255, 179, 71, 0)
  );
}
.forecast-item.alba {
  background: linear-gradient(
    to top,
    rgba(255, 111, 145, 0.20),
    rgba(255, 111, 145, 0)
  );
}
.forecast-item.tramonto .hour,
.forecast-item.tramonto .temp {
  color: #ffd8a0;
}
.forecast-item.alba .hour,
.forecast-item.alba .temp {
  color: #ffc0cf;
}
.forecast-item .alba-icon { color: #ff6f91; }
.forecast-item .tramonto-icon { color: #ffb347; }

/* === Slot 15min: accento sottile in cima === */
.forecast-item.forecast-15min::before {
  content: "";
  position: absolute;
  top: 0;
  left: 8px;
  right: 8px;
  height: 1px;
  background: linear-gradient(
    to right,
    transparent,
    rgba(255, 141, 36, 0.4),
    transparent
  );
}

/* === Day label separator (cambio giorno) === */
.forecast-day-label {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  min-width: 38px;
  padding: 12px 4px;
  background-color: var(--white-04);
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}
.forecast-day-label .giorno-label {
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: var(--white-85);
  line-height: 1;
}
.forecast-day-label .giorno-num {
  font-size: var(--fs-sm);
  font-weight: var(--fw-regular);
  color: var(--white-95);
  line-height: 1;
  margin-top: 3px;
}
.forecast-day-label .divider {
  display: none;
}
@media (min-width: 414px) {
  .forecast-day-label {
    min-width: 44px;
    padding: 14px 6px;
  }
  .forecast-day-label .giorno-label {
    font-size: var(--fs-sm);
  }
  .forecast-day-label .giorno-num {
    font-size: var(--fs-md);
  }
}

/* ============================================================================
   Widget VENTO — Apple-style: 3 righe dati + rosa dei venti compass.
   Riusa .widget / .widget-header / .widget-title della base widget system.
   ============================================================================ */
.widget-wind .widget-wind__body {
  display: grid;
  grid-template-columns: 1fr 128px;
  align-items: center;
  gap: 32px;
  margin-top: 4px;
}
@media (max-width: 374px) {
  .widget-wind .widget-wind__body {
    grid-template-columns: 1fr 108px;
    gap: 18px;
  }
}

.widget-wind .widget-wind__data {
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.widget-wind .widget-wind__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--white-08);
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}
.widget-wind .widget-wind__row:first-child {
  padding-top: 4px;
}
.widget-wind .widget-wind__row:last-child {
  border-bottom: 0;
  padding-bottom: 4px;
}
.widget-wind .widget-wind__row dt {
  margin: 0;
  font-size: var(--fs-md);
  font-weight: var(--fw-regular);
  color: var(--white-95);
  letter-spacing: 0.1px;
}
.widget-wind .widget-wind__row dd {
  margin: 0;
  font-size: var(--fs-md);
  font-weight: 500;
  color: var(--white-85, rgba(255,255,255,0.85));
  letter-spacing: 0.2px;
  text-align: right;
}

/* Compass: SVG fluida nel suo contenitore quadrato */
.widget-wind .widget-wind__compass {
  width: 128px;
  height: 128px;
  position: relative;
  justify-self: end;
  align-self: center;
}
@media (max-width: 374px) {
  .widget-wind .widget-wind__compass {
    width: 108px;
    height: 108px;
  }
}
/* Tablet+: la bussola cresce con il widget.
   Era 128px fissi su ogni larghezza sopra i 374px, mentre le tre righe dati
   accanto salgono a --fs-md / --fs-lg: la bussola passava dal 34% della riga
   sul telefono al 16% a 820 e al 12,5% a 1180, rimpicciolendosi di fatto.
   L'SVG ha viewBox 0 0 200 200, quindi anche le etichette N/E/S/O e i numeri
   al centro (in unita' utente) scalano con il box: non serve toccarli. */
@media (min-width: 768px) {
  .widget-wind .widget-wind__compass {
    width: 144px;
    height: 144px;
  }
}
@media (min-width: 1024px) {
  .widget-wind .widget-wind__compass {
    width: 160px;
    height: 160px;
  }
}
.widget-wind .widget-wind__compass-svg {
  width: 100%;
  height: 100%;
  display: block;
}
/* Needle: rotazione gestita dall'attributo SVG transform="rotate(angle cx cy)"
   (più affidabile cross-browser su <g> rispetto a CSS transform-box: view-box) */

/* ========== Widget Mappa Laguna · 2026-05-21 ==========
   Mini-mappa read-only nella vista Laguna. Tap → vista Mappa
   con base Dark + overlay Vento preimpostati via LocalStore. */
.mappa-laguna-widget {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  overflow: hidden;
}
.mappa-laguna-widget:focus-visible {
  outline: 2px solid var(--white-55, rgba(255, 255, 255, 0.55));
  outline-offset: 2px;
}
.mappa-laguna-widget .mlw-badge {
  font-size: var(--fs-xs);
  color: var(--white-70, rgba(255, 255, 255, 0.7));
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}
.mappa-laguna-widget .mlw-canvas {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 2;
  border-radius: var(--r-md);
  overflow: hidden;
  background: #0e1726;
  margin-top: 6px;
}
/* Fallback senza aspect-ratio (iOS 12 supporta solo da Safari 15) */
@supports not (aspect-ratio: 3 / 2) {
  .mappa-laguna-widget .mlw-canvas {
    height: 0;
    padding-bottom: 66.67%;
  }
}
.mappa-laguna-widget .mlw-mappa {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  /* Widget e' preview puramente decorativa: nessuna interazione sulla mappa
     (zoom/pan/pinch). Click/touch passano al wrapper .mappa-laguna-widget
     che ha l'handler navigateToMap(). */
  pointer-events: none;
}
.mappa-laguna-widget .mlw-mappa * {
  pointer-events: none;
}
.mappa-laguna-widget .mlw-cta {
  position: absolute;
  right: 8px;
  bottom: 8px;
  z-index: 3;
  pointer-events: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 9px;
  border-radius: 999px;
  background: rgba(11, 16, 24, 0.65);
  color: #fff;
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold, 600);
}
.mappa-laguna-widget .mlw-cta i {
  font-size: 0.85em;
  line-height: 1;
}
/* Anteprima: fondo scuro finche' lo stile non arriva, tocco al wrapper */
.mappa-laguna-widget .maplibregl-map {
  background: #0e1726;
  cursor: pointer;
}

/* ============================================================
   SOLID METEO CHROME — bottom nav
   Superficie coerente con i widget, con blur leggero di fusione.
   ============================================================ */
.navbar-bottom-nav {
  /* Stessa superficie adattiva dei widget, con velo piu' fitto (42% contro 22%):
     la chrome deve leggersi come piano piu' arretrato rispetto alle card, non
     come un grigio-blu fisso scollegato dal cielo. L'offset lo sincronizza
     WeatherGradientManager come per .widget (la barra e' fixed, quindi il suo
     top nel viewport e' costante e l'offset non oscilla durante lo scroll). */
  background-color: var(--widget-bg-solid, rgb(38 54 76 / 90%));
  background-image:
    linear-gradient(rgb(0 0 0 / 42%), rgb(0 0 0 / 42%)),
    var(--meteo-gradient, linear-gradient(180deg, #1565C0 0%, #0D47A1 45%, #0A3A7C 100%));
  background-attachment: scroll;
  background-position: 0 var(--meteo-bg-position-y, 0px);
  background-size: 100vw 100vh;
  background-repeat: no-repeat;
  border: 1px solid var(--white-12);
  box-shadow: 0 8px 26px rgba(0, 0, 0, 0.16);
}

.navbar-bottom-nav .navbar-bottom-content {
  position: relative;
  display: flex;
  width: 100%;
  height: 100%;
}

html[data-power="low"] .navbar-bottom-nav,
body.battery-saver .navbar-bottom-nav {
  /* In low-power resta la tinta piena. */
  background-color: var(--widget-bg-solid, #20364a);
  background-image: none;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
}

/* ── Chrome della vista mappa: una tinta sola, densita' guidata dal basemap ───
   Qui #weatherBg e' display:none (style.css ~755): il gradiente meteo citerebbe
   un cielo che non e' a schermo, quindi navbar e control flottanti tornano a una
   ardesia neutra. A cambiare col basemap attivo e' solo la COPERTURA: sopra le
   tile chiare (Light, OSM) serve piu' opacita' e un'ombra piu' marcata per
   staccare, sopra quelle scure (Dark, Satellite) la superficie si alleggerisce.
   Glifi ed etichette restano bianchi in ogni caso: nessuna inversione, quindi
   nessun rischio di contrasto sul beige movimentato di OSM.

   I due token sono la sorgente unica: navbar, pannello vento, pannello GPS e
   player radar li consumano tutti, cosi' un basemap nuovo si tara in un punto
   solo. L'attributo lo scrive stazioni-map-core.js al mount e su
   baselayerchange; senza attributo vale il default, cioe' il caso piu'
   coprente — un layer aggiunto e dimenticato non resta trasparente. */
body.view-mappa {
  --map-chrome-bg: rgb(26 38 52 / 92%);
  --map-chrome-shadow: 0 10px 30px rgb(0 0 0 / 30%);
}

body.view-mappa[data-basemap="Dark"] {
  --map-chrome-bg: rgb(26 38 52 / 78%);
  --map-chrome-shadow: 0 8px 22px rgb(0 0 0 / 18%);
}

body.view-mappa[data-basemap="Satellite"] {
  --map-chrome-bg: rgb(26 38 52 / 86%);
  --map-chrome-shadow: 0 8px 24px rgb(0 0 0 / 24%);
}

/* Low-power e battery saver: niente blur da compensare, le superfici vanno piene. */
html[data-power="low"] body.view-mappa,
body.battery-saver.view-mappa {
  --map-chrome-bg: rgb(26 38 52);
}

body.view-mappa .navbar-bottom-nav {
  background-color: var(--map-chrome-bg);
  background-image: none;
  border-color: var(--white-15);
  box-shadow: var(--map-chrome-shadow);
}

/* ── Modalita' navigazione: nastro bussola + linea di prua ────────────────── */
/* Il nastro e' un OVERLAY in cima alla mappa, non una barra che accorcia il
   container: `--nav-top` (che regge tutta la pila inferiore) e' misurato come
   `mapRect.bottom - navbarTop`, quindi rimpicciolire la mappa lo sposterebbe e
   con lui player, banda informativa e controlli GPS. Con un overlay l'unica
   cosa che si muove sono i controlli in alto, che e' esattamente cio' che si
   voleva. Colori dai token della chrome mappa (`--map-chrome-bg`): questa vista
   NON segue il cielo, `#weatherBg` e' display:none. Niente backdrop-filter —
   sta sopra una mappa che si trascina e si ri-rasterizzerebbe a ogni frame. */
#stazioni-map {
  --nav-nastro-h: 44px;
  /* Il nastro parte dalla safe area piu' una FRAZIONE dello scrim di iOS 27
     (`--nav-nastro-scrim` x `--ios-scrim-extra`: 0,7 x 30 = 21px sull'iPhone,
     0 altrove; sull'iPad la frazione e' 1, nel blocco tablet).
     Il 20/09 era salito alla safe area nuda (89->59) contando sull'ardesia
     piena, ma la sfumatura taglia comunque le etichette dei gradi, che stanno
     in cima alla striscia: a 59 cadevano a 74-87, dentro lo scrim. Tarato a
     schermo sul 15 Pro Max il 22/09/2026, a passi di 2px: nastro a 80. Chi sta
     sotto il nastro (`.mappa-top`) somma QUESTO token, non `--safe-top`. */
  --nav-nastro-scrim: 0.7;
  --nav-nastro-top: calc(env(safe-area-inset-top, 0px) + var(--ios-scrim-extra, 0px) * var(--nav-nastro-scrim));
}

.nav-nastro {
  position: absolute;
  top: var(--nav-nastro-top);
  left: 0;
  right: 0;
  height: var(--nav-nastro-h);
  z-index: 1200; /* sopra i control della mappa (1000) */
  overflow: hidden;
  background-color: var(--map-chrome-bg);
  box-shadow: var(--map-chrome-shadow);
  pointer-events: none;
  color: #fff;
}

.nav-nastro__strip {
  position: absolute;
  top: 0;
  bottom: 0;
  /* Origine al CENTRO: la traslazione e' -rotata, quindi a rotta 0 il nord
     cade in mezzo allo schermo, che e' dove punta l'indice. */
  left: 50%;
  width: 0;
  will-change: transform;
}

.nav-nastro__tick {
  position: absolute;
  top: 0;
  width: 0;
  border-left: 1px solid rgb(255 255 255 / 45%);
  height: 8px;
}

.nav-nastro__tick.is-major {
  height: 13px;
  border-left-color: rgb(255 255 255 / 80%);
}

.nav-nastro__tick > span {
  position: absolute;
  top: 15px;
  left: 0;
  transform: translateX(-50%);
  font-size: 11px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: rgb(255 255 255 / 78%);
  white-space: nowrap;
}

.nav-nastro__tick.is-cardinale > span {
  font-weight: 700;
  font-size: 13px;
  color: #fff;
}

/* Lettura al centro: una LENTE a tutta altezza (22/09/2026, provata a schermo
   sul 15 Pro Max). Rettangolo netto, niente fumetto ne' freccia; vetro neutro
   sopra l'ardesia, che copre le etichette piccole sotto il numero; cornici e
   indice nel colore dello stato (`--nastro-lente`, una variabile per tre
   stati). Dentro scorre la seconda striscia (`.nav-nastro__lente`) ingrandita
   1,6x con i soli cardinali: la muove posizionaStrip insieme alla prima. */
.nav-nastro {
  --nastro-lente: 10 132 255;
}

.nav-nastro__read {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 88px;
  box-sizing: border-box;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 3px;
  padding: 0 0 3px;
  overflow: hidden;
  background:
    linear-gradient(rgb(255 255 255 / 14%), rgb(255 255 255 / 14%)),
    var(--map-chrome-bg);
  box-shadow:
    inset 1.5px 0 0 rgb(var(--nastro-lente)),
    inset -1.5px 0 0 rgb(var(--nastro-lente));
}

/* Indice: la tacca della rotta, al centro in cima. */
.nav-nastro__read::after {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  width: 2px;
  height: 10px;
  transform: translateX(-50%);
  background: rgb(var(--nastro-lente));
}

.nav-nastro__lente {
  position: absolute;
  inset: 0;
  z-index: 0;
  transform: scale(1.6);
  transform-origin: 50% 0;
  pointer-events: none;
}

.nav-nastro__lente .nav-nastro__tick {
  border-left-color: rgb(255 255 255 / 55%);
}

.nav-nastro__lente .nav-nastro__tick > span {
  display: none;
}

/* I cardinali si tengono anche nella lente, in alto accanto alla tacca: cosi'
   passando non coprono il numero. */
.nav-nastro__lente .nav-nastro__tick.is-cardinale > span {
  display: block;
  top: 0;
  left: 3px;
  transform: none;
  font-size: 12px;
  font-weight: 700;
  color: #fff;
}

.nav-nastro__read b,
.nav-nastro__read i {
  position: relative;
  z-index: 1;
  line-height: 1;
}

.nav-nastro__read b {
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.02em;     /* testo display: tracking negativo */
  font-variant-numeric: tabular-nums;
}

/* Senza rosa (bussola) il numero resta al centro: niente gap per un <i> vuoto. */
.nav-nastro__read i:empty { display: none; }
/* E le CIFRE stanno sulla tacca: il «°» e' dentro il riquadro e le spostava
   a sinistra di mezzo simbolo (3,4 px sull'iPhone). */
.nav-nastro__read b:has(+ i:empty) { padding-left: 0.39em; }

.nav-nastro__read i {
  font-size: 11px;
  font-weight: 600;
  font-style: normal;
  letter-spacing: 0.02em;      /* testo piccolo: tracking positivo */
  opacity: 0.8;
}

/* Senza rotta (fermo, o GPS che non la fornisce) il nastro resta a schermo ma
   dichiara di non sapere: spegnerlo farebbe sparire una barra a ogni sosta. */
.nav-nastro.is-senza-rotta .nav-nastro__strip { opacity: 0.35; }
.nav-nastro.is-senza-rotta { --nastro-lente: 120 130 140; }

/* Ripiego sulla bussola del telefono: il numero e' vero e il nastro ci punta,
   ma NON e' la rotta — lo dice il colore, diverso dal blu della rotta. */
.nav-nastro.is-bussola { --nastro-lente: 94 92 230; }

/* I controlli in alto scendono sotto il nastro. La regola base e' `!important`
   (safe-area), quindi serve `!important` anche qui, e la specificita' la alza
   l'attributo — scritto da NavigazioneMode quando il nastro monta, tolto quando
   smonta: se il layer non e' attivo la mappa torna esattamente com'era. */
body.view-mappa #stazioni-map[data-navigazione="on"] .mappa-top {
  top: calc(var(--nav-nastro-top) + var(--nav-nastro-h)) !important;
}

/* Etichetta dell'ULTIMA tacca. Le altre quattro non ne hanno: il passo e'
   costante, letta questa si sa quanto vale ognuna, e cinque etichette lungo una
   linea sottile sarebbero rumore. */
.nav-tacca-label {
  width: auto !important;
  height: auto !important;
  margin: 0 !important;
  pointer-events: none;
}

.nav-tacca-label > span {
  display: inline-block;
  transform: translate(10px, -50%);
  padding: 2px 6px;
  border-radius: 6px;
  background-color: var(--map-chrome-bg);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  box-shadow: 0 1px 4px rgb(0 0 0 / 35%);
}

/* ── Pin mappa condiviso (POI nautici + stazioni) + ricerca (F1, 2026-06-12) ── */
/* Pin a goccia con glifo centrato dentro. Usato da POI nautici E stazioni (uniforme).
   I cluster usano lo stile markercluster default (#stazioni-map .marker-cluster*). */
.map-pin { position: relative; width: 30px; height: 38px; }
.map-pin__body {
  position: absolute; left: 1px; top: 0;
  width: 28px; height: 28px;
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
  background: #577590; border: 2px solid #fff;
  box-shadow: 0 2px 4px rgba(0,0,0,.4);
}
.map-pin .ic {
  position: absolute; left: 0; top: 2px;
  width: 30px; height: 24px;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 12.5px; line-height: 1; pointer-events: none;
}
/* Colori categoria POI nautici */
.poi-marina    .map-pin__body { background: #0a6ebd; }
.poi-slipway   .map-pin__body { background: #2a9d8f; }
.poi-fuel      .map-pin__body { background: #e76f51; }
.poi-anchorage .map-pin__body { background: #264653; }
.poi-mooring   .map-pin__body { background: #6a4c93; }
.poi-pier      .map-pin__body { background: #577590; }
.poi-beacon    .map-pin__body { background: #c99a16; }
.poi-other     .map-pin__body { background: #888; }
/* Colori provider stazioni (allineati ai badge popup: Comune blu, ISPRA ambra) */
.station-comune  .map-pin__body { background: #0a6ebd; }
.station-ispra   .map-pin__body { background: #e6a817; }
.station-default .map-pin__body { background: #577590; }
/* I miei punti: tinte proprie, lontane dai blu di marina e stazioni; ormeggio
   come `.poi-mooring` (stesso significato, stesso colore). Il `colore` del
   simbolo Garmin, se c'e', lo scrive pin-cluster.js sul pin (`colorePin`). */
.miei-poi-pesca    .map-pin__body { background: #29a3d9; }
.miei-poi-pericolo .map-pin__body { background: #c62828; }
.miei-poi-fondale  .map-pin__body { background: #00838f; }
.miei-poi-ormeggio .map-pin__body { background: #6a4c93; }
.miei-poi-generico .map-pin__body { background: #37474f; }
/* Punti degli amici: stessi colori dei miei, bordo tratteggiato e iniziale dell'autore
   in un tondo in alto a destra (si distinguono anche senza colori). */
.map-pin.punti-amici .map-pin__body { border-style: dashed; }
/* Livello senza senso per l'account (i punti degli amici senza gruppi): fuori dall'elenco.
   !important: il decorator mette display:flex sulle label. */
.mappa-control-layers label.mc-livello-assente { display: none !important; }
.map-pin__etichetta {
  position: absolute; right: -6px; top: -6px;
  min-width: 16px; height: 16px; padding: 0 3px; border-radius: 8px;
  background: #fff; color: #263238; border: 1px solid #263238;
  font: 700 10px/14px system-ui, sans-serif; text-align: center; pointer-events: none;
}
.miei-poi-condividi { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.miei-poi-condividi__gruppo { display: flex; align-items: center; gap: 8px; min-height: 44px; }
/* Segnalazioni degli utenti: rombo rosso segnaletico, distinto dalla goccia dei punti
   (anche per chi non distingue i colori: .miei-poi-pericolo e' un rosso vicino).
   Tratteggiato finche' nessuno conferma. */
.map-pin.segnalazione .map-pin__body { background: #d50000; border-radius: 4px; }
.map-pin.segnalazione--non-confermata .map-pin__body { border-style: dashed; }
/* Bottoni del popup: 44 px di tocco, si usano in barca con le mani bagnate. */
.segnalazione-popup .map-punto__azione { min-height: 44px; }
/* Modulo «Segnala un pericolo»: griglia di sei categorie, 3 colonne (2 sotto 360 px).
   Minimi sommati: 3 x 88 px + 2 gap da 6 = 276 px, dentro i 320 px del modulo
   (a 360 px di schermo il modulo ne ha 296). */
/* max-height lo scrive portaDentro() quando il modulo non ci sta (riga d'errore a
   320x568): il form scorre dentro e «Pubblica» resta raggiungibile. */
.segnalazioni-modulo { gap: 10px; width: min(320px, calc(100vw - 64px)); overflow: auto; overscroll-behavior: contain; }
.segnalazioni-modulo > * { flex-shrink: 0; }
/* Il modulo occupa quasi tutta l'altezza di un telefono piccolo: sopra gli angoli dei
   controlli (z 1000, mappa-chrome.css), che a 320 px coprivano titolo e campo nome. */
#stazioni-map .maplibregl-popup.segnalazioni-modulo-popup { z-index: 1001; }
/* Esito vuoto fuori dal flusso: a 320x568 il modulo ha 485 px fra cima e barra in basso. */
.segnalazioni-modulo [role="status"]:empty { display: none; }
.segnalazioni-modulo__griglia { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
@media (max-width: 359px) { .segnalazioni-modulo__griglia { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Un solo trattamento per le tessere (fondo, niente bordo): la scelta si vede da
   anello rosso, fondo e icona rossi; l'anello e' un box-shadow, nessun salto. */
.segnalazioni-modulo__categoria {
  appearance: none; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
  min-height: 64px; min-width: 0; padding: 8px 4px; border: 0; border-radius: 10px;
  background: rgb(0 0 0 / 5%); color: inherit; cursor: pointer;
}
.segnalazioni-modulo__categoria .ic { font-size: 20px; line-height: 1; opacity: 0.8; }
.segnalazioni-modulo__categoria span { font-size: 12px; line-height: 1.2; text-align: center; text-wrap: balance; overflow-wrap: anywhere; }
.segnalazioni-modulo__categoria:focus-visible { outline: 2px solid #1a2634; outline-offset: 2px; }
.segnalazioni-modulo__categoria[aria-pressed="true"] { background: rgb(213 0 0 / 10%); box-shadow: inset 0 0 0 2px #d50000; }
.segnalazioni-modulo__categoria[aria-pressed="true"] .ic { color: #d50000; opacity: 1; }
.segnalazioni-modulo__nome { display: flex; flex-direction: column; gap: 4px; font-size: var(--fs-sm); }
.segnalazioni-modulo .miei-poi-modulo__campo { resize: none; }
/* Pubblica e' l'azione principale: ardesia della chrome. Spenta resta leggibile
   (testo a 4,5:1 sul grigio), non un fantasma; il divisore sopra le azioni qui
   non serve, lo spazio del gruppo basta. */
.segnalazioni-modulo .map-punto__azioni { margin-top: 0; padding-top: 0; border-top: 0; }
.segnalazioni-modulo .map-punto__azione { min-height: 44px; font-weight: var(--fw-medium); }
.segnalazioni-modulo .map-punto__azione[type="submit"] { background: #1a2634; color: #fff; }
.segnalazioni-modulo .map-punto__azione[type="submit"]:disabled { background: rgb(0 0 0 / 6%); color: rgb(0 0 0 / 60%); cursor: default; }
/* Icone disegnate qui: le icone di sistema non hanno alghe, fascine, pesce,
   ancora, faro e pontile. Maschera sul colore del glifo, come i caratteri di .ic. */
.map-pin .ic[class*="mc-ico-"]::before, .segnalazioni-modulo .ic[class*="mc-ico-"]::before { content: ""; display: inline-block; font-size: 1em; margin: 0; width: 1em; height: 1em; background: currentColor; -webkit-mask: var(--mc-ico) center / contain no-repeat; mask: var(--mc-ico) center / contain no-repeat; }
.mc-ico-alga { --mc-ico: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20stroke%3D%22black%22%20stroke-width%3D%221.6%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20fill%3D%22none%22%20d%3D%22M8%2015C8%2011%206.5%208%207.5%202M4.5%2015C4.5%2012%203%2010%203%206.5M11.5%2015C11.5%2012%2013%209.5%2012.5%205M2%2015H14%22/%3E%3C/svg%3E"); }
.mc-ico-fascine { --mc-ico: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20stroke%3D%22black%22%20stroke-width%3D%221.6%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20fill%3D%22none%22%20d%3D%22M2.5%2013L13%203.5M3%203.5L13.5%2013M2%209H14M1.5%2015H14.5%22/%3E%3C/svg%3E"); }
.mc-ico-pesce { --mc-ico: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20fill%3D%22black%22%20fill-rule%3D%22evenodd%22%20d%3D%22M1.5%208C3.5%204.2%208.5%204.2%2011%208C8.5%2011.8%203.5%2011.8%201.5%208ZM4.6%207.2A.9.9%200%201%200%204.6%209A.9.9%200%201%200%204.6%207.2ZM10.6%208L15%204.8V11.2Z%22/%3E%3C/svg%3E"); }
.mc-ico-ancora { --mc-ico: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cg%20stroke%3D%22black%22%20stroke-width%3D%221.6%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20fill%3D%22none%22%3E%3Ccircle%20cx%3D%228%22%20cy%3D%223%22%20r%3D%221.5%22/%3E%3Cpath%20d%3D%22M8%204.5V14.5M5%207H11M2.5%2010C3%2013%205.8%2014.5%208%2014.5S13%2013%2013.5%2010%22/%3E%3C/g%3E%3C/svg%3E"); }
.mc-ico-faro { --mc-ico: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20fill%3D%22black%22%20d%3D%22M5.8%206H10.2L11.2%2015H4.8ZM5.3%205H10.7V3.6L8%201.4L5.3%203.6Z%22/%3E%3Cpath%20stroke%3D%22black%22%20stroke-width%3D%221.3%22%20stroke-linecap%3D%22round%22%20d%3D%22M1.5%203.5L4%204.2M14.5%203.5L12%204.2%22/%3E%3C/svg%3E"); }
.mc-ico-pontile { --mc-ico: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20fill%3D%22black%22%20d%3D%22M1%204.6H15V7.2H1Z%22/%3E%3Cpath%20stroke%3D%22black%22%20stroke-width%3D%221.6%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20fill%3D%22none%22%20d%3D%22M3.5%207V12M8%207V12M12.5%207V12M1.2%2014C2.6%2012.8%204%2015.2%205.4%2014S8.2%2012.8%209.6%2014S12.4%2015.2%2013.8%2014%22/%3E%3C/svg%3E"); }
.mc-ico-attrattore { --mc-ico: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20fill%3D%22black%22%20d%3D%22M3%204.4C4.6%201.6%208.4%201.6%2010.4%204.4C8.4%207.2%204.6%207.2%203%204.4ZM10.2%204.4L13.6%202V6.8Z%22/%3E%3Cpath%20fill%3D%22black%22%20d%3D%22M2%2012H7.4V15.2H2ZM8.6%2012H14V15.2H8.6ZM5.3%208.4H10.7V11.2H5.3Z%22/%3E%3C/svg%3E"); }
.mc-ico-scogli { --mc-ico: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20stroke%3D%22black%22%20stroke-width%3D%221.4%22%20stroke-linecap%3D%22round%22%20fill%3D%22none%22%20d%3D%22M1%203.2C2.4%202%203.8%204.4%205.2%203.2S8%202%209.4%203.2S12.2%204.4%2013.6%203.2%22/%3E%3Cpath%20fill%3D%22black%22%20d%3D%22M1.5%2015L3.2%209.6L6%208L8.4%2010.2L9.2%2015ZM8%2015L9.6%207.4L12.4%206.2L14.6%209L15%2015Z%22/%3E%3C/svg%3E"); }
.mc-ico-scalino { --mc-ico: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20stroke%3D%22black%22%20stroke-width%3D%221.4%22%20stroke-linecap%3D%22round%22%20fill%3D%22none%22%20d%3D%22M1%203.2C2.4%202%203.8%204.4%205.2%203.2S8%202%209.4%203.2S12.2%204.4%2013.6%203.2%22/%3E%3Cpath%20fill%3D%22black%22%20d%3D%22M1%207H6.5L9.5%2012.5H15V15.4H1Z%22/%3E%3C/svg%3E"); }
.mc-ico-dosso { --mc-ico: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20stroke%3D%22black%22%20stroke-width%3D%221.4%22%20stroke-linecap%3D%22round%22%20fill%3D%22none%22%20d%3D%22M1%203.2C2.4%202%203.8%204.4%205.2%203.2S8%202%209.4%203.2S12.2%204.4%2013.6%203.2%22/%3E%3Cpath%20fill%3D%22black%22%20d%3D%22M1%2013C4.5%2013%205.5%207%208%207S11.5%2013%2015%2013V15.4H1Z%22/%3E%3C/svg%3E"); }
.mc-ico-zona-pericolo { --mc-ico: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Crect%20x%3D%221.3%22%20y%3D%221.3%22%20width%3D%2213.4%22%20height%3D%2213.4%22%20rx%3D%221.5%22%20stroke%3D%22black%22%20stroke-width%3D%221.4%22%20stroke-dasharray%3D%222.6%201.6%22%20fill%3D%22none%22/%3E%3Cpath%20fill%3D%22black%22%20d%3D%22M7%204H9L8.7%209.6H7.3ZM7%2011H9V13H7Z%22/%3E%3C/svg%3E"); }
.mc-ico-amo { --mc-ico: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cg%20stroke%3D%22black%22%20stroke-width%3D%221.6%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20fill%3D%22none%22%3E%3Ccircle%20cx%3D%229%22%20cy%3D%222.4%22%20r%3D%221.3%22/%3E%3Cpath%20d%3D%22M9%203.7V10.8C9%2013.4%207.8%2014.6%206%2014.6S3%2013.4%203%2011.4V9.6L4.8%2011.2%22/%3E%3C/g%3E%3C/svg%3E"); }
.mc-ico-briccola { --mc-ico: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cg%20stroke%3D%22black%22%20stroke-width%3D%221.6%22%20stroke-linecap%3D%22round%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M5%2013L6.6%203M8%2013V2.5M11%2013L9.4%203M5.6%205H10.4M1.5%2013.5C3%2012.5%204.5%2014.5%206%2013.5S9%2012.5%2010%2013.5%2013%2014.5%2014.5%2013.5%22/%3E%3C/g%3E%3C/svg%3E"); }
.mc-ico-relitto { --mc-ico: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20stroke%3D%22black%22%20stroke-width%3D%221.4%22%20stroke-linecap%3D%22round%22%20fill%3D%22none%22%20d%3D%22M1%203.2C2.4%202%203.8%204.4%205.2%203.2S8%202%209.4%203.2S12.2%204.4%2013.6%203.2%22/%3E%3Cpath%20fill%3D%22black%22%20d%3D%22M1%2011.4L14.6%207.8L13.6%2012L3.4%2014.8Z%22/%3E%3Cpath%20fill%3D%22black%22%20d%3D%22M5.2%2010.6L5%208.4L8.6%207.4L9.2%209.6Z%22/%3E%3C/svg%3E"); }
.poi-popup .poi-pop-type { font-size: .8em; color: #666; margin-bottom: .25rem; }

/* Panel livelli aperto sopra l'input di ricerca (entrambi sono control z 800;
   senza questo l'ordine DOM mette la ricerca sopra il panel — bug 2026-06-12). */
.mappa-control-layers.mc-layers-open { z-index: 1001; }

.map-search-control { position: relative; display: none !important; }
.map-search-input {
  width: 220px; max-width: 60vw; padding: 6px 10px;
  border: 1px solid #ccc; border-radius: 6px; font-size: 14px;
  background: #fff; box-shadow: 0 1px 4px rgba(0,0,0,.2);
}
.map-search-results {
  position: absolute; top: 100%; left: 0; right: 0; margin: 2px 0 0;
  padding: 0; list-style: none; background: #fff; border-radius: 6px;
  box-shadow: 0 2px 8px rgba(0,0,0,.25); max-height: 260px; overflow-y: auto; z-index: 1000;
}
.map-search-item { padding: 7px 10px; cursor: pointer; font-size: 13px; color: #333; border-bottom: 1px solid #f0f0f0; transition: background 0.15s ease; }
@media (hover: hover) and (pointer: fine) {
  .map-search-item:hover { background: #eef5fb; }
}
.map-search-item:active { background: #e0ecf8; }
.map-search-pin {
  border-radius: 50% 50% 50% 0; transform: rotate(-45deg);
  background: #e63946; border: 2px solid #fff; box-shadow: 0 1px 3px rgba(0,0,0,.4);
}


/* ── Nowcast pioggia (vista oggi) — layout Apple Weather ─────── */
.nowcast-widget { padding: 1.15rem 1.1rem 1.2rem; --nowcast-plot-height: 72px; }
.nowcast-body { display: flex; flex-direction: column; gap: .42rem; }

/* Riga 1: titolo categoria; tipografia ereditata dal sistema .widget-title. */
.nowcast-title {
  display: flex; align-items: center; gap: .5rem;
  min-width: 0;
}
.nowcast-title .ic { color: var(--white-95); flex: 0 0 auto; }
/* Riga 2: sottotitolo (countdown) dim */
.nowcast-sub { font-size: var(--fs-md); color: var(--white-65); line-height: 1.2; }

/* Grafico largo full-width con gridline tratteggiate stile Apple */
.nowcast-chart { margin-top: .7rem; }
/* Riga grafico: mini asse-Y valori (scala sintetica) + colonna barre/orari */
.nowcast-plot { display: flex; align-items: stretch; gap: .5rem; }
.nowcast-graph { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: .35rem; }
.nowcast-yaxis {
  flex: 0 0 auto;
  display: flex; flex-direction: column; justify-content: space-between; align-items: flex-end;
  height: var(--nowcast-plot-height); padding-right: .3rem;
  border-right: 1px solid var(--white-08);
  font-size: var(--fs-xs); line-height: 1; color: var(--white-45); white-space: nowrap;
}
.nowcast-yval:first-child { color: var(--white-70); font-weight: var(--fw-semibold); }
.nowcast-strip {
  position: relative;
  display: flex; align-items: flex-end; gap: 2px;
  height: var(--nowcast-plot-height); width: 100%;
  border-bottom: 1px solid var(--white-20);
}
.nowcast-strip::before, .nowcast-strip::after {
  content: ''; position: absolute; left: 0; right: 0;
  border-top: 1px dashed var(--white-12); z-index: 0;
}
.nowcast-strip::before { top: 33%; }
.nowcast-strip::after  { top: 66%; }
/* Barra: cella flex 1/N (allineata alla scala) ma larghezza visibile ridotta e
   centrata → barre strette e ordinate senza rompere l'allineamento coi tick. */
.nowcast-bar {
  position: relative; z-index: 1;
  flex: 1 1 0; max-width: 22px; margin: 0 auto;
  min-height: 3px;
  background: var(--white-10); border-radius: 2px 2px 0 0;
}
/* Barra "accesa" — colore per categoria (accent sulla strip) */
.nowcast-bar.is-on { background: var(--nowcast-alert-bar, rgba(80,170,230,.9)); } /* rain (default) */
.nowcast-strip.acc-wind .nowcast-bar.is-on { background: var(--nowcast-wind-bar, rgba(79,195,168,.9)); }
.nowcast-strip.acc-heat .nowcast-bar.is-on,
.nowcast-strip.acc-cold .nowcast-bar.is-on,
/* nebbia: tinta assoluta dalla VISIBILITY_PALETTE, la stessa del widget
   Visibilita' piu' in basso nella vista */
.nowcast-strip.acc-fog .nowcast-bar.is-on { background: var(--nowcast-alert-bar); }
.nowcast-scale { display: flex; gap: 2px; }
.nowcast-tick {
  flex: 1 1 0; text-align: center; font-size: var(--fs-xs);
  line-height: 1; color: var(--white-55); white-space: nowrap; overflow: visible;
}
.nowcast-tick:first-child { text-align: left; font-weight: var(--fw-semibold); color: var(--white-75); }
@media (max-width: 360px) { .nowcast-tick { font-size: .6rem; } }

/* CTA informative condivise: stessa superficie adattiva dei widget, con un velo
   piu' leggero (16% contro 22%) perche' la CTA deve staccare di poco dalla card
   che la precede senza diventare un colore proprio. Il fondo azzurro fisso di
   prima stonava su ogni cielo che non fosse blu. Il velo resta 16% e non meno:
   misurato su un cielo da tramonto, a 10% la superficie sbianca e la riga di
   descrizione (opacity .7) perde leggibilita' — lo stacco lo porta il bordo.
   Come per .widget l'ancoraggio e' scroll + --meteo-bg-position-y:
   WeatherGradientManager sincronizza anche queste superfici (background-
   attachment: fixed e' incoerente su iOS durante lo scroll). */
.nowcast-radar-cta,
.stazioni-laguna-live + .station-cta-banner {
  padding: 8px 12px;
  border: 1px solid var(--white-25);
  border-radius: var(--r-sm);
  background-color: var(--widget-bg-solid, rgb(38 54 76 / 90%));
  background-image:
    linear-gradient(rgb(0 0 0 / 16%), rgb(0 0 0 / 16%)),
    var(--meteo-gradient, linear-gradient(180deg, #1565C0 0%, #0D47A1 45%, #0A3A7C 100%));
  background-attachment: scroll;
  background-position: 0 var(--meteo-bg-position-y, 0px);
  background-size: 100vw 100vh;
  background-repeat: no-repeat;
  color: var(--white-95);
}

.nowcast-radar-cta {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: -11px 0 15px;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  text-decoration: none;
}
.stazioni-laguna-live + .station-cta-banner {
  margin-top: 4px;
}

.nowcast-radar-cta .ic:first-child { color: var(--white-95); }
.nowcast-radar-cta .ic:last-child { margin-left: auto; color: var(--white-70); }

.nowcast-radar-cta:hover,
.nowcast-radar-cta:focus-visible,
.stazioni-laguna-live + .station-cta-banner:hover,
.stazioni-laguna-live + .station-cta-banner:focus-visible {
  color: #fff;
  border-color: rgb(255 255 255 / 38%);
  background-image:
    linear-gradient(rgb(0 0 0 / 8%), rgb(0 0 0 / 8%)),
    var(--meteo-gradient, linear-gradient(180deg, #1565C0 0%, #0D47A1 45%, #0A3A7C 100%));
}
/* Alert barca (partials/marea/barca-alert.php): stesso banner del radar, con
   due righe (rischio, azione). La severita' la dice il testo. */
.barca-cta {
  gap: 10px;
  padding: 10px 12px;
}
.barca-cta-testo {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.barca-cta-dato,
.barca-cta-azione {
  font-weight: var(--fw-normal, 400);
  color: var(--white-70);
}
.station-cta-banner .cta-icon { color: var(--white-95); }
.station-cta-banner .cta-arrow { color: var(--white-70); opacity: 1; }
/* L'icona del titolo resta bianca in tutte le severita (regola .nowcast-title .ic). */

/* LOW-POWER BLUR OVERRIDE: l'unico blur rimasto e' il velo dei grafici. */
html[data-power="low"] .chart-loading-overlay,
body.battery-saver .chart-loading-overlay {
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}

/* ===========================================================================
   PANNELLO AVVISI (#loc-avvisi)
   ---------------------------------------------------------------------------
   Il pannello riusa il vestito di .search-panel (stessa famiglia: offcanvas
   dalla location bar). Qui stanno solo i controlli suoi.
   =========================================================================== */

.avvisi-panel .av-nota {
  font-size: var(--fs-md);
  line-height: 1.45;
  margin-bottom: 12px;
}

.avvisi-panel .av-nota--fioca {
  color: var(--white-70, rgb(255 255 255 / 70%));
  font-size: var(--fs-sm);
}

.avvisi-panel .av-link {
  color: #fff;
  text-decoration: underline;
}

.avvisi-panel .av-passi,
.avvisi-panel .av-elenco {
  margin: 0 0 16px;
  padding-left: 1.2em;
  font-size: var(--fs-md);
  line-height: 1.7;
}

.avvisi-panel .av-elenco {
  list-style: none;
  padding-left: 0;
}

.avvisi-panel .av-elenco i {
  width: 1.4em;
  text-align: center;
  opacity: .85;
}

/* Riga interruttore: etichetta a sinistra, controllo a destra.
   min-width:0 sull'etichetta perche' un testo lungo non spinga fuori
   l'interruttore (stesso vincolo dei flex item con contenuto intrinseco). */
.avvisi-panel .av-riga {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--white-10, rgb(255 255 255 / 10%));
}

.avvisi-panel .av-etichetta {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--fs-md);
  margin: 0;
}

.avvisi-panel .av-switch {
  flex-shrink: 0;
  width: 46px;
  height: 28px;
  margin: 0;
  appearance: none;
  -webkit-appearance: none;
  border-radius: 999px;
  background: var(--white-25, rgb(255 255 255 / 25%));
  position: relative;
  cursor: pointer;
  transition: background .2s ease;
}

.avvisi-panel .av-switch::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #fff;
  transition: transform .2s ease;
}

.avvisi-panel .av-switch:checked {
  background: #46c37b;
}

.avvisi-panel .av-switch:checked::after {
  transform: translateX(18px);
}

.avvisi-panel .av-sotto {
  padding: 4px 0 14px;
  font-size: var(--fs-sm);
  color: var(--white-85, rgb(255 255 255 / 85%));
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

.avvisi-panel .av-sotto label {
  margin: 0;
}

/* Il numero della soglia sta DENTRO una frase, quindi deve stare sulla riga
   del testo. Era un <output>, che Bootstrap Reboot rende `inline-block`: su
   iOS finiva alzato di mezza riga, come un esponente, mentre in Chrome era
   allineato. La baseline di un inline-block la calcolano diversamente, e la
   frase non ha bisogno di quell'elemento: e' testo. */
.avvisi-panel .av-valore {
  display: inline;
  vertical-align: baseline;
  font: inherit;
  font-variant-numeric: tabular-nums;
}

.avvisi-panel .av-range {
  width: 100%;
  accent-color: #46c37b;
}

.avvisi-panel .av-ora {
  background: var(--white-10, rgb(255 255 255 / 10%));
  color: #fff;
  border: none;
  border-radius: var(--r-sm, 6px);
  padding: 6px 8px;
  font: inherit;
}

/* ---------------------------------------------------------------------------
   Pallino di stato sulla campanella
   ---------------------------------------------------------------------------
   Quattro stati e tre aspetti: pieno verde (attivi), pieno rosso (guasti: li
   credi accesi e non arrivano), solo bordo (permesso mai concesso: non e' un
   guasto, e' una cosa non decisa), nessun pallino (spenti apposta — una scelta
   rispettata non si segnala).
   Il bottone e' `position: relative` solo qui: nella barra e' statico. */
#loc-avvisi-btn {
  position: relative;
}

#loc-avvisi-btn.av-pallino--attivo::after,
#loc-avvisi-btn.av-pallino--guasto::after,
#loc-avvisi-btn.av-pallino--assente::after {
  content: "";
  position: absolute;
  top: 5px;
  right: 5px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  box-sizing: border-box;
}

#loc-avvisi-btn.av-pallino--attivo::after {
  background: #46c37b;
}

#loc-avvisi-btn.av-pallino--guasto::after {
  background: #ff6b6b;
}

/* Vuoto: dice che c'e' qualcosa da decidere, senza dare un allarme. */
#loc-avvisi-btn.av-pallino--assente::after {
  background: transparent;
  border: 1.5px solid var(--white-55, rgb(255 255 255 / 55%));
}

/* Invito: tre volte e poi mai piu', e solo a chi non ha ancora deciso.
   Ampiezza piccola apposta — la campanella sta anche sopra la mappa, dove
   qualunque movimento ripetuto si nota il doppio. */
@keyframes av-invito {
  0%, 100% { transform: rotate(0); }
  15% { transform: rotate(-9deg); }
  30% { transform: rotate(7deg); }
  45% { transform: rotate(-5deg); }
  60% { transform: rotate(3deg); }
  75% { transform: rotate(-1deg); }
}

#loc-avvisi-btn.av-invito i {
  display: inline-block;
  transform-origin: 50% 15%;
  animation: av-invito 900ms ease-in-out;
}

@media (prefers-reduced-motion: reduce) {
  #loc-avvisi-btn.av-invito i { animation: none; }
}

html[data-power="low"] #loc-avvisi-btn.av-invito i {
  animation: none;
}

/* Blocco del luogo: sta in testa al pannello, sopra gli interruttori. */
.avvisi-panel .av-luogo {
  padding: 4px 0 14px;
  border-bottom: 1px solid var(--white-10, rgb(255 255 255 / 10%));
}

.avvisi-panel .av-luogo .av-etichetta {
  display: block;
  margin-bottom: 8px;
}

/* min-width:0 perche' l'opzione piu' lunga del select non sfondi il pannello:
   e' lo stesso vincolo del selettore modello nella tabella Pro. */
.avvisi-panel .av-select {
  width: 100%;
  min-width: 0;
  padding: 12px;
  border: none;
  border-radius: var(--r-sm, 8px);
  background: var(--white-10, rgb(255 255 255 / 10%));
  color: #fff;
  font: inherit;
  font-size: var(--fs-md);
}

.avvisi-panel .av-luogo .av-nota,
.avvisi-panel .av-sotto__nota {
  margin: 8px 0 0;
  width: 100%;
}

.avvisi-panel .av-nota--marea {
  margin: 12px 0 4px;
}

.avvisi-panel .av-nota--marea i {
  opacity: .85;
  margin-right: 4px;
}

/* Voce che il livello non apre: a vista, spenta, il tocco va al pannello Account (avvisi-panel.js). */
.avvisi-panel .av-riga.av-chiuso { opacity: 0.55; cursor: pointer; }
.avvisi-panel .av-riga.av-chiuso input { pointer-events: none; }
.avvisi-panel .av-lucchetto { margin-left: 6px; font-size: 0.8em; }
.avvisi-panel.av-soglie-fisse .av-range,
.avvisi-panel.av-soglie-fisse .av-ora { opacity: 0.55; }
.avvisi-panel .av-livello-nota { cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }

/* La riga del tetto giornaliero non ha interruttore: e' solo un'etichetta con
   il numero dentro, quindi non deve avere il bordo delle righe con controllo. */
.avvisi-panel .av-riga--tetto {
  border-bottom: none;
  padding-bottom: 0;
}

.avvisi-panel .av-separatore {
  border-color: var(--white-25, rgb(255 255 255 / 25%));
  margin: 18px 0 4px;
}

/* La riga che precede il separatore ha gia' il proprio bordo sotto: le due
   linee si vedevano entrambe, con un vuoto in mezzo. */
.avvisi-panel .av-riga:has(+ .av-separatore) {
  border-bottom: none;
}

.avvisi-panel .av-esito {
  min-height: 1.4em;
  margin: 10px 0 0;
  font-size: var(--fs-sm);
  color: var(--white-70, rgb(255 255 255 / 70%));
}

.avvisi-panel .av-btn-primario,
.avvisi-panel .av-btn-secondario {
  display: block;
  width: 100%;
  margin-top: 14px;
  padding: 14px;
  border: none;
  border-radius: var(--r-sm, 8px);
  font-size: var(--fs-lg);
  font-weight: 600;
}

.avvisi-panel .av-btn-primario {
  background: #46c37b;
  color: #06331c;
}

.avvisi-panel .av-btn-secondario {
  background: var(--white-10, rgb(255 255 255 / 10%));
  color: var(--white-85, rgb(255 255 255 / 85%));
}

/* Campo email del pannello Account: stesso fondo e raggio di .av-select, piu' un
   bordo (il fondo al 10% da solo non arriva a 3:1 contro il pannello). */
.avvisi-panel.account-panel .av-input {
  display: block;
  width: 100%;
  min-width: 0;
  min-height: 44px;
  margin: 4px 0 12px;
  padding: 10px 12px;
  border: 1px solid rgb(255 255 255 / 55%);
  border-radius: var(--r-sm, 8px);
  background: var(--white-10, rgb(255 255 255 / 10%));
  color: #fff;
  font: inherit;
  /* Sotto i 16px Safari iOS zooma la pagina al tocco del campo. */
  font-size: max(16px, var(--fs-md));
}
.avvisi-panel.account-panel .av-stato .av-link {
  display: inline-block;
  padding: 14px 0;
}
/* Il codice si legge in maiuscolo; il valore inviato resta quello digitato (il server normalizza). */
.avvisi-panel.account-panel #account-codice {
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.avvisi-panel.account-panel #account-piano {
  margin: 0 0 12px;
}
.avvisi-panel.account-panel #account-test {
  margin-top: 12px;
}
/* Divisore «oppure» fra il bottone passkey e il campo email. */
.avvisi-panel.account-panel .av-oppure {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 14px 0 4px;
  color: var(--white-70, rgb(255 255 255 / 70%));
  font-size: var(--fs-sm);
}
.avvisi-panel.account-panel .av-oppure::before,
.avvisi-panel.account-panel .av-oppure::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: var(--white-25, rgb(255 255 255 / 25%));
}
.avvisi-panel.account-panel .av-invito {
  margin-bottom: 12px;
}
.avvisi-panel.account-panel .av-sezione {
  margin-top: 16px;
}
.avvisi-panel.account-panel .av-elenco {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
}
.avvisi-panel.account-panel .av-elenco li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 44px;
  font-size: var(--fs-md);
}
.avvisi-panel.account-panel .av-elenco li span {
  min-width: 0;
  overflow-wrap: anywhere;
}
.avvisi-panel.account-panel .av-elenco .av-link {
  flex-shrink: 0;
  min-height: 44px;
  padding: 0 4px;
  border: none;
  background: none;
  font: inherit;
}

/* Stato connesso: profilo in testa, poi gruppi a elenco (Profilo, Abbonamento, Accesso,
   I miei punti, Dati e privacy). Le azioni sono RIGHE, non bottoni pieni: il pannello
   ne ha una decina e a tutta larghezza pesavano tutte uguali. Il verde resta alle
   sole azioni principali (Attiva, Conferma). */
.avvisi-panel.account-panel .av-profilo {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 4px 0 20px;
}
.avvisi-panel.account-panel .av-avatar {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: linear-gradient(160deg, #00a3ff, #0023d6);
  color: #fff;
  font-size: 1.4rem;
  font-weight: 700;
}
.avvisi-panel.account-panel .av-profilo-testo {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.3;
}
/* Il nome e' l'identita': viene subito dopo il titolo del pannello, e non sotto
   il nome del piano nella card Abbonamento. */
.avvisi-panel.account-panel .av-profilo-testo b {
  font-size: var(--fs-xl);
  overflow-wrap: anywhere;
}
.avvisi-panel.account-panel #account-connesso-sotto {
  color: var(--white-70, rgb(255 255 255 / 70%));
  font-size: var(--fs-sm);
  overflow-wrap: anywhere;
}
.avvisi-panel.account-panel #account-piano {
  align-self: flex-start;
  margin: 6px 0 0;
  padding: 2px 10px;
  border-radius: 999px;
  background: var(--white-10, rgb(255 255 255 / 10%));
  color: var(--white-85, rgb(255 255 255 / 85%));
  font-size: var(--fs-sm);
  font-weight: 600;
}
/* Stesso peso e spaziatura di .widget .widget-title: le intestazioni del pannello
   parlano come quelle dei widget. */
.avvisi-panel.account-panel .av-gruppo-titolo {
  margin: 22px 4px 8px;
  color: var(--white-70, rgb(255 255 255 / 70%));
  font-size: var(--fs-sm);
  font-weight: var(--fw-regular);
  letter-spacing: 0.6px;
  text-transform: uppercase;
}
.avvisi-panel.account-panel .av-gruppo-titolo #account-poi-quanti {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
}
.avvisi-panel.account-panel .av-gruppo {
  margin: 0;
  border: 1px solid var(--white-10, rgb(255 255 255 / 10%));
  border-radius: var(--r-md);
  background: rgb(255 255 255 / 6%);
  overflow: hidden;
}
.avvisi-panel.account-panel .av-gruppo--campo {
  padding: 12px 14px 14px;
}
.avvisi-panel.account-panel .av-gruppo--campo .av-etichetta {
  display: block;
  margin-bottom: 6px;
  color: var(--white-85, rgb(255 255 255 / 85%));
  font-size: var(--fs-sm);
}
.avvisi-panel.account-panel .av-gruppo--campo .av-input {
  margin: 0;
}
.avvisi-panel.account-panel .av-gruppo--campo .av-nota {
  margin: 8px 0 0;
}
.avvisi-panel.account-panel .av-campo-riga {
  display: flex;
  gap: 8px;
}
.avvisi-panel.account-panel .av-campo-riga .av-input {
  flex: 1 1 auto;
}
.avvisi-panel.account-panel .av-btn-piccolo {
  flex-shrink: 0;
  min-height: 44px;
  padding: 0 16px;
  border: none;
  border-radius: var(--r-sm, 8px);
  background: rgb(255 255 255 / 16%);
  color: #fff;
  font-size: var(--fs-md);
  font-weight: 600;
}
.avvisi-panel.account-panel .av-azione {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 48px;
  margin: 0;
  padding: 12px 14px;
  border: none;
  border-top: 1px solid var(--white-10, rgb(255 255 255 / 10%));
  background: none;
  color: #fff;
  font: inherit;
  font-size: var(--fs-md);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.avvisi-panel.account-panel .av-gruppo > .av-azione:first-child,
.avvisi-panel.account-panel .av-gruppo > [hidden] + .av-azione:not([hidden]) {
  border-top: none;
}
.avvisi-panel.account-panel .av-azione i {
  width: 1.25em;
  text-align: center;
  opacity: .85;
}
.avvisi-panel.account-panel .av-azione small {
  margin-left: auto;
  color: var(--white-70, rgb(255 255 255 / 70%));
  font-size: var(--fs-sm);
}
.avvisi-panel.account-panel .av-azione:active {
  background: rgb(255 255 255 / 8%);
}
.avvisi-panel.account-panel .av-azione:focus-visible {
  outline: 2px solid #fff;
  outline-offset: -2px;
}
/* Rosso chiaro: sul fondo del pannello il rosso pieno non arriva a 4,5:1. */
.avvisi-panel.account-panel .av-azione--pericolo,
.avvisi-panel.account-panel .av-link--pericolo {
  color: #ff9a8f;
}
.avvisi-panel.account-panel .av-azione--chiusa {
  color: var(--white-85, rgb(255 255 255 / 85%));
}
.avvisi-panel.account-panel .av-gruppo .av-elenco {
  margin: 0;
}
.avvisi-panel.account-panel .av-gruppo .av-elenco li {
  padding: 4px 14px;
  border-bottom: 1px solid var(--white-10, rgb(255 255 255 / 10%));
}
.avvisi-panel.account-panel .av-gruppo .av-elenco:empty {
  display: none;
}
.avvisi-panel.account-panel .av-gruppo .av-elenco:not(:empty) + .av-azione {
  border-top: none;
}
.avvisi-panel.account-panel .av-gruppo-titolo #account-gruppi-tetto {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
}
.avvisi-panel.account-panel .av-gruppo .av-gruppi-elenco li {
  padding: 0;
  border-bottom: none;
}
.avvisi-panel.account-panel .av-gruppi-elenco li:first-child .av-azione {
  border-top: none;
}
.avvisi-panel.account-panel .av-gruppi-elenco .av-azione span {
  min-width: 0;
  overflow-wrap: anywhere;
}
.avvisi-panel.account-panel .av-gruppi-elenco .av-azione small {
  flex-shrink: 0;
}
.avvisi-panel.account-panel .av-gruppi-form {
  padding: 12px 14px 14px;
  border-top: 1px solid var(--white-10, rgb(255 255 255 / 10%));
}
.avvisi-panel.account-panel .av-gruppi-elenco:empty + [hidden] + .av-gruppi-form {
  border-top: none;
}
.avvisi-panel.account-panel .av-gruppi-form .av-etichetta {
  display: block;
  margin-bottom: 6px;
  color: var(--white-85, rgb(255 255 255 / 85%));
  font-size: var(--fs-sm);
}
.avvisi-panel.account-panel .av-gruppi-form .av-input {
  margin: 0;
  min-width: 0;
}
.avvisi-panel.account-panel .av-gruppi-dettaglio {
  margin-top: 8px;
}
.avvisi-panel.account-panel .av-gruppi-testa {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 4px 4px 4px 14px;
}
.avvisi-panel.account-panel .av-gruppi-testa b {
  min-width: 0;
  overflow-wrap: anywhere;
}
.avvisi-panel.account-panel .av-gruppi-nota {
  margin: 0;
  padding: 0 14px 10px;
  color: #ffd27a;
  font-size: var(--fs-sm);
}
.avvisi-panel.account-panel .av-gruppi-dettaglio .av-elenco {
  border-top: 1px solid var(--white-10, rgb(255 255 255 / 10%));
}
.avvisi-panel.account-panel .av-gruppi-dettaglio .av-link {
  min-width: 44px;
}
.avvisi-panel.account-panel .av-gruppi-dettaglio .av-elenco li:last-child {
  border-bottom: none;
}
.avvisi-panel.account-panel .av-gruppi-scelta {
  margin: 0 0 12px;
}
.avvisi-panel.account-panel .av-gruppi-scelta label {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  font-size: var(--fs-md);
}
.avvisi-panel.account-panel .av-invito {
  display: flex;
  gap: 12px;
  margin: 0 0 8px;
  padding: 14px;
  border-radius: 12px;
  background: rgb(70 195 123 / 16%);
  border: 1px solid rgb(70 195 123 / 40%);
}
.avvisi-panel.account-panel .av-invito > i {
  font-size: 1.5rem;
  line-height: 1;
}
.avvisi-panel.account-panel .av-invito p,
.avvisi-panel.account-panel .av-riepilogo p {
  margin: 0;
  font-size: var(--fs-md);
  line-height: 1.4;
}
.avvisi-panel.account-panel .av-riepilogo {
  padding: 12px 14px;
  border-top: 1px solid var(--white-10, rgb(255 255 255 / 10%));
}
.avvisi-panel.account-panel .av-coppia {
  display: flex;
  gap: 8px;
  margin-top: 12px;
}
.avvisi-panel.account-panel .av-coppia .av-btn-primario {
  width: auto;
  flex: 1 1 auto;
  margin: 0;
  padding: 10px 16px;
  min-height: 44px;
  font-size: var(--fs-md);
}
.avvisi-panel.account-panel .av-btn-testo {
  flex: 0 0 auto;
  min-height: 44px;
  padding: 0 14px;
  border: none;
  background: none;
  color: var(--white-85, rgb(255 255 255 / 85%));
  font-size: var(--fs-md);
  font-weight: 600;
}
.avvisi-panel.account-panel .av-esci {
  margin-top: 24px;
}
.avvisi-panel.account-panel .av-piano {
  margin-bottom: 8px;
  padding: 14px;
}
.avvisi-panel.account-panel .av-piano[data-piano="premium"],
.avvisi-panel.account-panel .av-piano[data-piano="prova"] {
  border-color: rgb(255 214 102 / 45%);
  background: linear-gradient(160deg, rgb(255 214 102 / 14%), rgb(255 255 255 / 4%));
}
.avvisi-panel.account-panel .av-piano-testa {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 12px;
}
/* Stessa taglia del nome dell'utente: a 1,35rem superava il titolo del pannello.
   Il risalto del piano lo da' la superficie dorata, non la taglia. */
.avvisi-panel.account-panel .av-piano-nome {
  font-size: var(--fs-xl);
  font-weight: 700;
  line-height: 1.2;
}
.avvisi-panel.account-panel .av-piano-scade {
  color: var(--white-70, rgb(255 255 255 / 70%));
  font-size: var(--fs-sm);
}
.avvisi-panel.account-panel .av-vantaggi-titolo {
  margin: 14px 0 6px;
  font-size: var(--fs-md);
  font-weight: 600;
}
.avvisi-panel.account-panel .av-vantaggi {
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--fs-md);
  line-height: 1.35;
}
.avvisi-panel.account-panel .av-vantaggi li {
  display: flex;
  gap: 10px;
  padding: 5px 0;
}
.avvisi-panel.account-panel .av-vantaggi i {
  width: 1.25em;
  text-align: center;
  color: #ffd666;
}
.avvisi-panel.account-panel .av-piano-come {
  margin: 12px 0 0;
  color: var(--white-70, rgb(255 255 255 / 70%));
  font-size: var(--fs-sm);
}
#account-poi > .av-nota {
  margin: 8px 4px 0;
}

@media (prefers-reduced-motion: reduce) {
  .avvisi-panel .av-switch,
  .avvisi-panel .av-switch::after {
    transition: none;
  }
}

/* ============================================================================
   TABLET — layout a due colonne (iPad, verticale e orizzontale)
   ============================================================================
   Perche' un blocco a parte e perche' in coda: i blocchi `min-width: 768px`
   sparsi nel foglio scalano la tipografia ma lasciano una colonna sola, e la
   cascata dell'hero (`.meteo-hero .main-data .now-temp`, specificita' 0,5,0)
   batte le regole 0,3,0 del vecchio blocco "iPad Portrait (768-819)", che per
   l'hero Meteo e' di fatto morto. Misurato: da 393 a 834px la larghezza
   raddoppia (+112%) e la temperatura cresce da 30 a 34px (+13%), l'hero
   riempie il 45% della riga e la pagina diventa PIU' alta (1606 -> 1980px).
   Qui si cambia il layout, non la scala.

   Il gate e' `min-width: 744px` e `min-height: 744px`, non la larghezza da
   sola: 744 e' l'iPad mini (sotto resterebbe il layout del telefono stirato) e
   l'altezza minima tiene fuori l'iPhone in orizzontale, largo 932. Le colonne
   valgono in entrambi gli orientamenti; le DIMENSIONI stanno nel blocco TABLET
   qui sotto, con lo stesso gate.
   ========================================================================= */

/* Fuori dal media query: i wrapper non esistono per il layout. Sul telefono i
   widget restano figli diretti di #main-content, nell'ordine del PHP. */
.vista-colonna {
  display: contents;
}

@media (min-width: 744px) and (min-height: 744px) {

  /* Pannello Account: il fondo resta a tutto schermo, il contenuto in una
     colonna da 640, misura da form. A piena larghezza il campo email era
     lungo 1300px e il form stava in un angolo. */
  .avvisi-panel.account-panel .offcanvas-header,
  .avvisi-panel.account-panel .offcanvas-body {
    width: 100%;
    max-width: 640px;
    margin-inline: auto;
  }

  /* Nella griglia lo stacco lo da' il gap: il margine del guscio chiuso,
     pensato per la pila del telefono, spostava di 12px la colonna in cui sta
     dentro una .row (/pesca da ospite: colonne a 465 e 477). */
  #main-content .row.gx-3 > [class*="col-"] > .widget-spento {
    margin-top: 0;
  }

  /* --- Griglia della vista ------------------------------------------------
     Tutto span 2 per default (hero, allerta nowcast, striscia oraria restano
     a piena larghezza); solo i due wrapper prendono una colonna ciascuno. */
  #main-content {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 18px;
    align-items: start;
  }

  #main-content > * {
    grid-column: 1 / -1;
    margin-bottom: 0;
  }

  #main-content > .vista-colonna {
    grid-column: auto;
    display: flex;
    flex-direction: column;
    gap: 18px;
    min-width: 0;
    /* Le due colonne finiscono alla stessa altezza: la piu' corta allunga il
       suo ultimo widget. Senza, i fondi sfalsati di 30-50px facevano sembrare
       la griglia casuale (misurato su iPad Pro 11 il 17/09/2026). */
    align-self: stretch;
  }

  /* L'altezza in piu' si divide fra tutte le card della colonna: allungare solo
     l'ultima lasciava un buco vuoto di 80px dentro la qualita' dell'aria. Il
     link a tutte le stazioni non e' una card e resta della sua altezza. */
  #main-content > .vista-colonna > :is(.widget, .row) {
    flex-grow: 1;
  }

  /* Una riga con le colonne vuote (l'avviso marea quando non c'e' niente da
     dire) occupava comunque una cella della griglia: 18px di gap in piu' sotto
     l'hero. Si guarda che le colonne non abbiano figli, non che manchi un
     `.widget`: la tabella di `/stazioni` non e' un widget e spariva. */
  #main-content > .row.gx-3:not(:has(> [class*="col-"] > *)) {
    display: none;
  }

  /* --- /laguna: moduli a righe, in entrambi gli orientamenti --------------
     Le colonne si sciolgono e ogni modulo sceglie solo la COLONNA: le righe le
     assegna la griglia (`dense`), quindi un modulo che manca non lascia buchi.
     Il guscio Premium chiuso (`.widget-spento`) prende il posto del widget che
     contiene: agganciando solo le classi dei widget, da ospite e free i gusci
     finivano piazzati a caso (misurato il 23/10/2026: marea alta 1246 con 700
     vuoti, sicurezza in mezza colonna). L'ordine e' quello del DOM:
     sicurezza e avviso barca a riga intera, marea | stazioni, mappa e link a
     tutte le stazioni a riga intera in fondo (a destra sotto le stazioni il
     link lasciava un vuoto quando la marea e' piu' alta). */
  body.view-laguna #main-content > .vista-colonna {
    display: contents;
  }

  body.view-laguna #main-content > .vista-colonna > :is(
    .widget-semafori, .barca-cta, .mappa-laguna-widget, .station-cta-banner,
    .widget-spento:has(.widget-semafori)) {
    grid-column: 1 / -1;
  }

  body.view-laguna #main-content > .vista-colonna > .row.gx-3 {
    grid-column: 1;
    align-self: stretch;
  }

  body.view-laguna #main-content > .vista-colonna > :is(
    .stazioni-laguna-live, .widget-spento:has(.stazioni-laguna-live)) {
    grid-column: 2;
  }

  body.view-laguna #main-content > .vista-colonna > :is(
    .stazioni-laguna-live, .widget-spento:has(.stazioni-laguna-live)) {
    align-self: stretch;
  }

  /* Un guscio chiuso affiancato a una card vera ne prende l'altezza, e
     l'anteprima riempie quello che resta: con i 560px fissi il guscio delle
     stazioni era alto 791 accanto a una marea di 579, e in /pesca la lista dei
     giorni chiusa restava 236px piu' corta della marea. */
  body.view-laguna .widget-spento:has(.stazioni-laguna-live),
  body.view-pesca .widget-spento:has(.fishing-forecast-list),
  body.view-oggi .widget-spento:has(.day-forecast-list) {
    display: flex;
    flex-direction: column;
  }

  body.view-laguna .widget-spento:has(.stazioni-laguna-live) > .ws-anteprima,
  body.view-pesca .widget-spento:has(.fishing-forecast-list) > .ws-anteprima,
  body.view-oggi .widget-spento:has(.day-forecast-list) > .ws-anteprima {
    flex: 1 1 0;
    min-height: 240px;
    max-height: none;
  }


  /* A riga intera la mappa e' una striscia: a 3:1 faceva scorrere la vista. */
  body.view-laguna .mappa-laguna-widget .mlw-canvas {
    flex: none;
    aspect-ratio: 4 / 1;
    min-height: 0;
  }

  /* I giorni a sinistra (colonna lunga, come la lista 10 giorni di Apple), i
     dati puntuali a destra — senza toccare l'ordine del DOM, che e' quello del
     telefono. NON si usa `order`: su una griglia riordina TUTTI gli item, hero
     compreso, e la pila finisce sotto la lista (misurato: hero a y=1036).
     Con la colonna fissata a mano e `dense`, il wrapper dei giorni rientra
     nella cella 1 della riga gia' aperta invece di aprirne una nuova. */
  #main-content { grid-auto-flow: row dense; }

  /* --- Un bordo solo per tutto ---------------------------------------------
     Erano tre: barra in basso sul bordo del contenitore (21px su iPad Pro 11),
     card a 53 (+32 di padding), bottoni della barra localita' a 84 (+32 suoi).
     Tre linee verticali per lo stesso bordo si leggono come disordine. Il
     contenitore resta al cap di 1100px (`DESKTOP CAP`, con !important) e
     barra in basso, card e barra localita' ne prendono lo stesso bordo. */
  .container-custom {
    padding-left: 0;
    padding-right: 0;
  }

  .location-bar {
    padding-left: 0;
    padding-right: 0;
  }
  #main-content > .vista-colonna--giorni { grid-column: 1; }
  #main-content > .vista-colonna--dati   { grid-column: 2; }

  /* I widget dentro le colonne spaziano col `gap`, non col proprio margine:
     due meccanismi insieme darebbero distanze diverse fra le due colonne. */
  #main-content > .vista-colonna > *,
  #main-content > .vista-colonna > .widget,
  #main-content > .vista-colonna > .row {
    margin-top: 0;
    margin-bottom: 0;
  }

  /* La riga Bootstrap dentro la colonna: le gutter negative di `.row` la
     fanno sporgere di 8px per lato dalla colonna (misurato a 744px: 369px di
     riga dentro 353 di colonna). Il blocco >=768 lo sistema gia' con gap +
     basi calcolate; qui si estende alla fascia 744-767. */
  #main-content > .vista-colonna > .row.gx-3 {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
    margin-left: 0;
    margin-right: 0;
    /* Il blocco >=1024 da' 16px sotto ogni riga: dentro la colonna lo spazio
       e' il `gap`, e i due insieme davano 34px invece di 18. */
    margin-bottom: 0;
  }

  /* Il `widget-grid-2` generale ha piu' specificita' e rimette il margine. */
  #main-content > .vista-colonna > .row.gx-3.widget-grid-2 {
    margin-bottom: 0;
  }

  #main-content > .vista-colonna > .row.gx-3 > [class*="col-"] {
    width: 100%;
    max-width: 100%;
    flex: none;
    padding-left: 0;
    padding-right: 0;
    /* la card riempie la cella: le due card affiancate hanno la stessa altezza */
    display: flex;
  }

  #main-content > .vista-colonna > .row.gx-3 > [class*="col-"] > .widget {
    flex: 1 1 auto;
    margin-bottom: 0;
  }

  /* Una riga a colonna intera (marea in `/laguna`, solunari in `/pesca`) non
     deve finire nella prima delle due celle. */
  #main-content > .vista-colonna > .row.gx-3 > .col-12 {
    grid-column: 1 / -1;
  }

  /* --- Hero: lo schema comune, a scala da tablet (22/10/2026) -------------
     Una regola per le tre hero (SPEC-hero-uniformi). A misura del contenuto e
     centrata: a tutta larghezza il numero finiva a mille pixel dallo stato.
     Stessa aria di prima (64 sopra, 40 sotto); la scala sale per ruolo,
     numero e icona piu' del testo. Il margine sotto lo azzera
     `#main-content > *`, che ha l'id nel selettore: serve il padding. */
  .current-weather.today.hero-uniforme {
    /* Stessa larghezza per tutte, non fit-content: passando da una vista
       all'altra le hero restano allineate. */
    width: var(--hero-larghezza);
    max-width: none;
    margin-inline: auto;
    column-gap: 20px;
    margin-top: 64px;
    padding-bottom: 40px;
  }

  .hero-uniforme .hu-icona {
    width: 150px;
    height: 150px;
    flex-basis: 150px;
  }

  .hero-uniforme .hu-stato {
    font-size: 28px;
  }

  .hero-uniforme .hu-sotto {
    font-size: var(--fs-xl);
  }

  .hero-uniforme .hu-k {
    font-size: var(--fs-md);
  }

  .hero-uniforme .hu-nota {
    font-size: var(--fs-lg);
  }

  .hero-uniforme .hu-num {
    font-size: 64px;
  }

  .hero-uniforme .hu-unita {
    font-size: 22px;
  }

  .hero-uniforme .hu-v {
    font-size: 18px;
  }

  .hero-uniforme .hu-sep {
    margin: 18px 0 16px;
  }

  .hero-uniforme .hu-griglia {
    gap: 12px 24px;
  }

  /* --- Striscia oraria: piena larghezza, passo piu' generoso --------------
     A 84px con icone da 38 e ore a 13,5 era la striscia del telefono. Le celle
     crescono a 96px e si dividono lo spazio; icona 48, ora e temperatura un
     gradino sopra. */
  .forecast-item {
    min-width: 0;
    flex: 1 0 96px;
  }

  .forecast-item .hour {
    font-size: var(--fs-lg);
  }

  .forecast-item .weather-svg-icon {
    width: 48px;
    height: 48px;
  }

  .forecast-item .temp {
    font-size: var(--fs-2xl);
  }


  /* --- Widget in colonna: il respiro viene dalla colonna, non dal padding -- */
  #main-content > .vista-colonna .widget {
    padding: 18px 18px;
  }

  /* La rosa dei venti non deve mangiarsi meta' della colonna. */
  #main-content > .vista-colonna .widget-wind__compass {
    width: 112px;
    height: 112px;
    flex: 0 0 112px;
  }

  /* --- Dentro una colonna vale la scala del TELEFONO, non quella del tablet --
     Le colonne sono larghe ~390px: le maggiorazioni dei blocchi `min-width:768`
     sono tarate sulla riga piena (794px) e qui mandano a capo. Misurato in
     colonna: "1018 hPa" su due righe e la delta "-1.5" staccata dalla freccia.
     Si riportano alla misura che il telefono usa alla stessa larghezza. */
  #main-content > .vista-colonna .widget .widget-cont .widget-value strong,
  #main-content > .vista-colonna .widget .widget-cont .widget-delta strong {
    font-size: var(--fs-3xl);
  }

  /* Stessa ragione, forma diversa: la lista dei giorni non ha font fissi ma
     una griglia a variabili (`--mfl-col-*`), tarata sul viewport. In colonna i
     minimi sommano 588px contro 388 disponibili e la coppia min/max finisce
     tagliata fuori (misurato: tmin/bar/tmax presenti nel DOM, invisibili a
     schermo). Si adottano i valori che il foglio usa gia' sotto i 559px. */
  #main-content > .vista-colonna .meteo-forecast-list {
    --mfl-col-day: 40px;
    --mfl-col-precip: 46px;
    --mfl-col-icons: 48px;    /* 2 x 22 + 4 gap */
    --mfl-col-wind: 36px;
    --mfl-col-temp: 30px;
    --mfl-col-bar: minmax(36px, 1fr);
    --mfl-col-chev: 10px;
    --mfl-pad-x: 8px;
    --mfl-gap: 4px;
  }

  /* Le icone seguono la colonna, o sfondano la cella. */
  #main-content > .vista-colonna .meteo-forecast-list .dfr-icons .dfr-icon img {
    width: 22px;
    height: 22px;
  }

  /* Il numero del giorno esce come sotto i 374px: il nome basta a leggere la
     riga, e sono i 15px che mancano alla colonna piu' stretta (iPad mini). */
  #main-content > .vista-colonna .meteo-forecast-list .dfr-day-date,
  #main-content > .vista-colonna .meteo-forecast-list .dfr-day-sep {
    display: none;
  }

  #main-content > .vista-colonna .meteo-forecast-list .day-forecast-toggle {
    padding: 12px 4px;
  }

  /* Raffica e separatore: il foglio li nasconde gia' sotto i 559px, per lo
     stesso motivo per cui qui non ci stanno (la colonna e' larga come un
     telefono). La media resta, la raffica sta nella fascia dell'accordion. */
  #main-content > .vista-colonna .meteo-forecast-list .dfr-wind-gust .dfr-gust-max,
  #main-content > .vista-colonna .meteo-forecast-list .dfr-wind-gust .dfr-wind-sep,
  #main-content > .vista-colonna .meteo-forecast-list .dfr-wind-gust .dfr-wind-unit {
    display: none;
  }

  #main-content > .vista-colonna .meteo-forecast-list .dfr-day-name,
  #main-content > .vista-colonna .meteo-forecast-list .dfr-temp {
    font-size: var(--fs-lg);
  }

  #main-content > .vista-colonna--giorni .widget {
    padding-left: 12px;
    padding-right: 12px;
  }

  /* --- /oggi riempie l'altezza dell'iPad -----------------------------------
     Con la scala del telefono dentro le colonne la vista finiva a 1261px e la
     barra in basso stava a 1526: 265px vuoti su iPad Pro 11 in verticale, e
     widget piccoli in card larghe 509. Qui prende respiro chi puo' reggerlo:
     righe dei giorni piu' alte con testo un gradino sopra, valori piu' grandi
     nelle card di destra, striscia oraria piu' alta con elementi un filo piu'
     piccoli (a 48px di icona in 140 di altezza sembrava compressa). Il fondo
     arriva a una trentina di px dalla barra in basso. */
  body.view-oggi .forecast-item {
    padding: 18px 10px 16px;
  }

  body.view-oggi .forecast-item .weather-svg-icon {
    width: 44px;
    height: 44px;
    margin: 10px 0;
  }

  body.view-oggi .forecast-item .temp {
    font-size: var(--fs-xl);
  }

  #main-content > .vista-colonna--giorni .meteo-forecast-list {
    --mfl-col-day: 52px;
    --mfl-col-icons: 64px;    /* 2 x 28 + 8 gap */
    --mfl-col-wind: 44px;
    --mfl-col-temp: 40px;
    --mfl-gap: 8px;
  }

  #main-content > .vista-colonna--giorni .meteo-forecast-list .day-forecast-toggle {
    padding: 16px 8px;
  }

  #main-content > .vista-colonna--giorni .meteo-forecast-list .dfr-day-name,
  #main-content > .vista-colonna--giorni .meteo-forecast-list .dfr-temp {
    font-size: var(--fs-2xl);
  }

  #main-content > .vista-colonna--giorni .meteo-forecast-list .dfr-icons .dfr-icon img {
    width: 28px;
    height: 28px;
  }

  #main-content > .vista-colonna--dati .widget .widget-title {
    font-size: var(--fs-lg);
  }

  #main-content > .vista-colonna--dati .widget .widget-cont .widget-value strong,
  #main-content > .vista-colonna--dati .widget .widget-cont .widget-delta strong {
    font-size: var(--fs-6xl);
  }

  /* Una scala sola per le card di destra: titolo 15,75, valore 31,5, righe 18.
     Prima le righe di pressione e visibilita' erano a 20 e quelle del vento a
     14: tre corpi per lo stesso ruolo. */
  #main-content > .vista-colonna--dati .widget .widget-text,
  #main-content > .vista-colonna--dati .widget .data-row,
  #main-content > .vista-colonna--dati .widget-wind .widget-wind__row dt,
  #main-content > .vista-colonna--dati .widget-wind .widget-wind__row dd {
    font-size: var(--fs-xl);
  }

  /* L'altezza in piu' della card va fra il valore e i dettagli, non sotto tutto:
     i dettagli scendono in fondo, e nel vento righe e rosa stanno al centro. */
  #main-content > .vista-colonna--dati .widget {
    display: flex;
    flex-direction: column;
  }

  #main-content > .vista-colonna--dati .widget .widget-footer {
    margin-top: auto;
  }

  #main-content > .vista-colonna--dati .widget-wind__body {
    flex: 1 1 auto;
    align-items: center;
  }

  /* --- /laguna e /pesca: la stessa scala di /oggi ---------------------------
     Dentro le colonne i testi erano quelli del telefono, fra 12,5 e 14,75px,
     in card larghe 509. Stessi ruoli, stessi corpi di /oggi: righe dati 18,
     testi secondari e titoli 15,75, nomi dei giorni 20. Fuori da queste classi
     (grafici, badge, letture sotto i grafici) non si tocca niente. */
  #main-content > .vista-colonna .widget .widget-title {
    font-size: var(--fs-lg);
  }

  #main-content > .vista-colonna .stazioni-laguna-live .data-row,
  #main-content > .vista-colonna .day-forecast .widget-text,
  #main-content > .vista-colonna .day-forecast .widget-value,
  #main-content > .vista-colonna .sole-luna-widget .sl-phase-name,
  #main-content > .vista-colonna .fishing-forecast-list .fishing-score-box {
    font-size: var(--fs-xl);
  }

  #main-content > .vista-colonna .stazioni-laguna-live .sl-metric-label,
  #main-content > .vista-colonna .marea-salute-text,
  #main-content > .vista-colonna .solunar-tide-text,
  #main-content > .vista-colonna .sole-luna-widget .sl-time-label,
  #main-content > .vista-colonna .sole-luna-widget .sl-phase-day,
  #main-content > .vista-colonna .sole-luna-widget .sl-next-name,
  #main-content > .vista-colonna .fishing-forecast-list .dfr-migliore,
  #main-content > .vista-colonna .fishing-forecast-list .dfr-day-date {
    font-size: var(--fs-lg);
  }

  #main-content > .vista-colonna .fishing-forecast-list .dfr-day-name {
    font-size: var(--fs-2xl);
  }

  /* --- /laguna e /pesca stanno nello schermo, come /oggi ----------------------
     Con la scala nuova sforavano di 90-120px, e uno scroll di pochi pixel non ha
     senso (misurato su iPad Pro 11: barra in basso a 1526). Si toglie prima cio'
     che si ripete, poi si compatta:
     - nelle card di marea e solunari il blocco «Livello attuale · Calante»
       ripete l'hero (laguna) o la riga Marea della stessa card (pesca);
     - grafici un filo piu' bassi, restando lontani dal 2,3:1 in colonna;
     - righe di stazioni, sicurezza, giorni di pesca e fasi lunari piu' strette.
     Fondi: /oggi 1485, /laguna 1484, /pesca 1487. */
  #main-content > .vista-colonna .day-forecast > .widget-cont:has(> .weather-svg-icon) {
    display: none;
  }

  body.view-laguna #main-content > .vista-colonna .day-forecast .chart-container {
    height: 300px;
    min-height: 300px;
  }

  body.view-pesca #main-content > .vista-colonna .day-forecast .chart-container {
    height: 350px;
    min-height: 350px;
  }

  #main-content > .vista-colonna .stazioni-laguna-live .data-row {
    padding-top: 1px;
    padding-bottom: 1px;
  }

  #main-content > .vista-colonna .stazioni-laguna-live .sl-metric + .sl-metric {
    margin-top: 10px;
    padding-top: 10px;
  }

  #main-content > .vista-colonna .stazioni-laguna-live .sl-metric-label {
    margin-bottom: 4px;
  }

  #main-content > .vista-colonna .widget-semafori {
    padding-top: 12px;
    padding-bottom: 12px;
    margin-bottom: 8px;
  }

  #main-content > .vista-colonna .fishing-forecast-list .day-forecast-toggle {
    padding-top: 4px;
    padding-bottom: 4px;
  }

  #main-content > .vista-colonna .sole-luna-widget .sl-next-cell {
    padding-top: 5px;
    padding-bottom: 5px;
  }

  #main-content > .vista-colonna .sole-luna-widget .sl-divider {
    margin-top: 8px;
    margin-bottom: 8px;
  }

  /* Testi secondari della lista giorni un gradino sotto nome e temperature. */
  #main-content > .vista-colonna--giorni .meteo-forecast-list .dfr-weather-label,
  #main-content > .vista-colonna--giorni .meteo-forecast-list .dfr-wind-avg {
    font-size: var(--fs-lg);
  }

  #main-content > .vista-colonna--dati .widget-wind__compass {
    width: 124px;
    height: 124px;
    flex: 0 0 124px;
  }

  /* --- Il gradino piu' piccolo e gli inviti (23/10/2026) ---------------------
     Quello che la scala qui sopra lasciava fuori cresceva solo con la radice
     (x1,125) o restava in px: date delle lune, punteggi, pioggia oraria e
     letture dei grafici a 11-12,4px accanto a righe da 18, e gli inviti
     Premium a 13/15 come sul telefono. Il gradino minimo del tablet e' --fs-md
     (14,6px), i titoli dei widget sono --fs-lg in ogni vista, Pro compresa.
     Gli inviti con `.widget` davanti: le regole base stanno piu' in basso. */
  #main-content .widget-title {
    font-size: var(--fs-lg);
  }

  #main-content .sole-luna-widget :is(.sl-next-date, .sl-next-fam, .sl-next-illum),
  #main-content .sole-luna-widget .fishing-score-box,
  .forecast-item .rain-value-text,
  .chart-readout__time,
  .chart-readout__nome,
  .chart-readout__valore,
  #main-content :is(.sem-title, .sem-legend-item, .station-zone, .cta-desc,
    .avviso-marea__agg, .dfm-item, .dfm-specie, .badge, .dfr-precip-prob-value,
    .dfr-precip-unit, .giorno-label, .modello-pro-label, .dt-section-title) {
    font-size: var(--fs-md);
  }

  .widget.widget-spento .ws-invito {
    margin: 6px 14px 16px;
    padding: 20px 22px;
    border-radius: 16px;
  }

  .widget.widget-spento .ws-motivo {
    font-size: var(--fs-xl);
  }

  .widget.widget-spento .ws-desc {
    margin-top: 6px;
    font-size: var(--fs-lg);
  }

  .widget.widget-spento .ws-azione {
    min-height: 52px;
    margin-top: 18px;
    border-radius: 26px;
    font-size: var(--fs-xl);
  }

}

/* ============================================================================
   TABLET — controlli, grafici e tabella a misura di schermo (verticale e orizzontale)
   ============================================================================
   Il blocco sopra cambia le COLONNE e vale solo in verticale. Questo cambia le
   DIMENSIONI, che dipendono dal device e non dall'orientamento. Il gate
   `min-height: 744px` tiene fuori l'iPhone in orizzontale, largo 932.

   Regole, misurate su iPad Pro 11 il 17/09/2026:
   - un controllo toccabile e' alto almeno 44px, col testo a 15,75 (select
     modello 38 e 13,5, tasti 1h/3h 41x36, pill dei grafici 34);
   - un grafico a tutta larghezza non va oltre 2,3:1 (Pro 1032x320 = 3,2:1,
     storico stazioni 1016x240 = 4,2:1: si leggevano schiacciati);
   - una tabella che scorre non deve starci tutta: celle piu' grandi e meno
     colonne a schermo, e il resto si scorre. */
@media (min-width: 744px) and (min-height: 744px) {

  /* La sfumatura di iOS 27 e' piu' alta sull'iPad: 30px, tarati sull'iPhone,
     lasciavano la barra localita' ancora velata. */
  html.ios-scrim-alto {
    --ios-scrim-extra: 40px;
  }

  /* Nastro bussola: sull'iPad lo scrim si prende tutto. A 0,7 (nastro a 60)
     le etichette dei gradi, a 75-88, restavano velate; tarato a schermo
     sull'iPad Pro 11 il 23/09/2026: nastro a 72, safe area 32 + 40. */
  #stazioni-map {
    --nav-nastro-scrim: 1;
  }

  /* --- Spazio in fondo: dall'altezza VERA della barra ------------------------
     `.container-custom` riserva `95px + safe-bottom`, stimati sulla barra
     dell'iPhone. Su iPad la barra e' alta 80 e sta a 29px dal fondo: servono
     109, quindi il fondo della vista finiva sotto il menu (misurato: ultima
     card a 1529, barra a 1526). Qui il valore si deriva da `--nav-h`, che
     `custom.js` scrive dal rect della barra, piu' lo stacco e un respiro. */
  .container-custom {
    padding-bottom: calc(var(--nav-h, 80px) + 4px + var(--ui-bottom-pad) + 20px);
  }

  /* --- Bottoni della barra localita': 39 -> 44 -------------------------------
     Il passo fra i bottoni e' 55px: a 44 restano 11px fra uno e l'altro. */
  .location-bar .loc-actions a,
  .location-bar .loc-actions button {
    width: 44px;
    height: 44px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  /* --- Controlli della vista Pro ------------------------------------------ */
  .modello-pro-select {
    min-height: 44px;
    padding: 10px 40px 10px 14px;
    font-size: var(--fs-lg);
  }

  .passo-toggle {
    min-height: 44px;
  }

  .passo-btn {
    min-width: 56px;
    padding: 0 16px;
    font-size: var(--fs-lg);
  }

  .chart-unified .chart-pill,
  .st-history-panel .chart-pill {
    min-height: 44px;
    padding: 10px 16px;
    font-size: var(--fs-lg);
  }

  /* la riga delle grandezze si riserva prima che le pill arrivino col catalogo */
  .st-history-metric-pills .chart-pill-bar {
    min-height: 44px;
  }

  /* --- Grafici a tutta larghezza piu' alti ---------------------------------- */
  .widget-riga .chart-container {
    min-height: 460px;
  }

  .chart-unified .chart-container {
    min-height: 515px;
  }

  .st-history-panel .chart-container,
  .st-history-chart .chart-container {
    height: 460px;
    min-height: 460px;
  }

  /* Istogramma dell'allerta nowcast: 72px tarati sul telefono, su tutta la
     larghezza dell'iPad era una striscia. Le barre sono in % della strip. */
  .nowcast-widget {
    --nowcast-plot-height: 100px;
  }

  /* L'attesa riserva la stessa altezza: grafico + riga delle letture. */
  .st-history-status[data-state="loading"] ~ .st-history-panes .st-history-chart {
    min-height: calc(519px + 1.5rem);
  }

  /* --- Tabella Pro: la stessa tabella, piu' grande ---------------------------
     Celle 44x34 e testo a 12,4px, identici al telefono. Larghezze, sparkline e
     confini dei giorni sono calcolati in px dal PHP, quindi non si ricalcola
     niente: `zoom` scala tutto insieme, colonna fissa e giorno sticky compresi
     (misurato: etichette ferme a sinistra, tocco sulla cella giusta). A 1,4 le
     celle sono 62x48 e a schermo ne stanno 16 invece di 22. */
  .dt-widget .dt-table {
    zoom: 1.4;
  }

}

/* ============================================================================
   TABLET ORIZZONTALE — piu' larghezza, meno altezza
   ============================================================================
   In orizzontale l'iPad Pro 11 e' 1634x1141: il cap di 1100px del `DESKTOP CAP`
   lasciava 267px vuoti per lato e schiacciava tutto in colonne da 541, mentre
   l'altezza utile scende da 1634 a 1141 e l'hero da 225px pesa il doppio. Qui
   si sposta il baricentro: piu' larghezza (colonne da ~770) e hero piu' basso.
   Le colonne, la scala per ruolo e i controlli restano quelli dei due blocchi
   sopra. Misurato in Chromium a 1634x1141; sul device non ancora, l'iPad non
   ruotava. ========================================================================= */
@media (min-width: 744px) and (min-height: 744px) and (orientation: landscape) {

  /* Il bordo lo decide un numero solo: contenitore e barra in basso lo leggono
     dalla stessa variabile, o la barra resta larga 1100 dentro un contenuto da
     1500 (misurato: barra 267-1367, card 67-1567). */
  :root {
    --chrome-max-width: min(1500px, calc(100vw - 2 * var(--tablet-bordo)));
  }

  .container-custom {
    /* !important: il cap di 1100 ce l'ha, e qui va scavalcato */
    max-width: var(--chrome-max-width) !important;
  }

  /* Hero: meno aria sopra e sotto, l'altezza e' la risorsa scarsa. */
  .current-weather.today.meteo-hero,
  .current-weather.today.marea-hero,
  .current-weather.today.luna-corrente-hero,
  .current-weather.today.pro-hero {
    margin-top: 32px;
    padding-bottom: 26px;
  }

  .current-weather.today.marea-hero,
  .current-weather.today.luna-corrente-hero {
    min-height: 0;
  }

}

/* ==========================================================================
   TABLET VERTICALE — griglia a moduli
   ============================================================================
   Rivisto il 16/10/2026 sul modello di Meteo di Apple su iPad: nella stessa
   riga le card sono alte uguali, e l'altezza in piu' va a righe uguali o a un
   elemento elastico (un grafico), non spalmata su tutte le card. Il
   `flex-grow` del blocco "TABLET layout" conservava le differenze: in /oggi
   le tre card dei dati restavano 264/256/300, in /pesca la card della marea
   veniva stirata ai 1508px della colonna accanto con 547px vuoti in fondo.
   I moduli a sviluppo orizzontale (striscia sicurezza/comfort, mappa, Sole e
   Luna) passano a riga intera. Solo in verticale: l'orizzontale resta quello
   del 17/09, non ancora misurato sul device.

   Le colonne si sciolgono con `display: contents` e i moduli si piazzano con
   `grid-column`/`grid-row` espliciti: NON con `order`, che su una griglia
   riordina anche l'hero. L'ordine del DOM e' quello del telefono e non cambia.
   ========================================================================= */
@media (min-width: 744px) and (min-height: 744px) and (orientation: portrait) {

  /* Il blocco tablet toglie il padding al contenitore e si affida al cap di
     1100px, che in verticale (744-1024) non scatta: le card toccavano i lati
     dello schermo (misurato a 840x900: card 0-840, hero 100-740). Stesso
     bordo dell'orizzontale. !important: il cap di 1100 ce l'ha. La mappa
     resta a tutto schermo. */
  body:not(.view-mappa) .container-custom {
    max-width: calc(100vw - 2 * var(--tablet-bordo)) !important;
  }

  /* --- Un passo e un raggio per tutti i moduli ------------------------------ */
  #main-content .widget,
  #main-content .station-cta-banner {
    border-radius: 12px;
  }

  #main-content > .vista-colonna > .row.gx-3 {
    gap: 18px;
  }

  /* --- /oggi -------------------------------------------------------------
     A destra tre righe uguali (vento, pressione e visibilita', aria): i fondi
     coincidono con la lista dei giorni per costruzione. */
  body.view-oggi #main-content > .vista-colonna--dati {
    display: grid;
    grid-template-rows: repeat(3, minmax(0, 1fr));
    gap: 18px;
  }

  /* Il bollettino e' una riga di testo: da solo era una quarta taglia di
     modulo fra l'hero e la previsione oraria. Diventa la testata dell'orario. */
  body.view-oggi #main-content > .widget-bollettino {
    border-radius: 12px 12px 0 0;
    border-bottom: 1px solid rgb(255 255 255 / 10%);
  }

  body.view-oggi #main-content > .widget-bollettino + .widget {
    margin-top: -18px;
    border-radius: 0 0 12px 12px;
  }

  /* --- /pesca ------------------------------------------------------------
     Giorni a sinistra (come la lista dei giorni in /oggi), marea e solunari a
     destra: alte quasi uguali di natura (955 e 961). Sole e Luna, che affianca
     due archi, in riga intera sotto. */
  body.view-pesca #main-content > .vista-colonna {
    display: contents;
  }

  body.view-pesca #main-content > .vista-colonna > :is(
    .fishing-forecast-list, .widget-spento:has(.fishing-forecast-list)) {
    grid-column: 1;
    grid-row: 2;
    align-self: stretch;
  }

  body.view-pesca #main-content > .vista-colonna:first-of-type > .row.gx-3 {
    grid-column: 2;
    grid-row: 2;
    align-self: stretch;
  }

  body.view-pesca #main-content > .vista-colonna:last-of-type > .row.gx-3 {
    grid-column: 1 / -1;
    grid-row: 3;
  }

  /* Il grafico e' l'elemento elastico della card: prende l'altezza che la
     riga gli lascia, invece di un fondo vuoto sotto i periodi. */
  body.view-pesca #main-content > .vista-colonna .day-forecast {
    display: flex;
    flex-direction: column;
  }

  body.view-pesca #main-content > .vista-colonna .day-forecast .chart-container {
    flex: 1 1 350px;
    height: auto;
  }

  /* Il blocco «Livello attuale · Calante» ripete l'hero (laguna) o la riga
     Marea della stessa card (pesca). La regola del blocco "TABLET layout" lo
     nascondeva, ma `.d-flex` di Bootstrap (con !important) la batte. */
  #main-content > .vista-colonna .day-forecast > .widget-cont:has(> .weather-svg-icon) {
    display: none !important;
  }
}

/* ==========================================================================
   AREE DI TOCCO
   --------------------------------------------------------------------------
   Il bersaglio VISIBILE non cambia: cresce solo l'area che raccoglie il dito,
   con uno pseudo-elemento in posizione assoluta. Serve perche' i controlli piu'
   piccoli stanno fra 13 e 31 px, contro i 44 di Apple — misurati il 15/09/2026
   su iPhone 15 Pro Max, iPhone XS e iPad Pro 11 M1, e la stella dei preferiti
   e' 17x13 su tutti e tre: non cresce a nessun breakpoint.

   Ingrandire i bersagli non era una strada: a 375px fra le etichette della
   location bar e i bottoni ci sono 6px, e i quattro bottoni a 44 ne vorrebbero
   56 — che le etichette non hanno.

   I numeri per controllo NON sono tutti 44, e il motivo e' che dove i vicini
   sono attaccati un'area piu' larga se la ruberebbero a vicenda, peggiorando la
   precisione invece di migliorarla. Ogni deroga e' annotata sotto e verificata
   da `_dev/tests/aree-tocco.test.js`, che misura l'area colpendola davvero con
   `elementFromPoint` — una regola scritta bene ma ritagliata da un antenato con
   `overflow: hidden` passerebbe un test sul CSS e fallisce li'.
   ========================================================================== */

.location-bar .loc-favorite-btn,
.location-bar .loc-actions a,
.location-bar .loc-actions button,
.widget-semafori .sem-tip,
.dt-section,
.radar-ctl .rv-btn,
#stazioni-map .mappa-control-zoom-in,
#stazioni-map .mappa-control-zoom-out,
#stazioni-map .mappa-control-layers-toggle,
#stazioni-map .mappa-control.btn-gps {
  position: relative;
}

.location-bar .loc-favorite-btn::before,
.location-bar .loc-actions a::before,
.location-bar .loc-actions button::before,
.widget-semafori .sem-tip::before,
.dt-section::before,
.radar-ctl .rv-btn::before,
#stazioni-map .mappa-control-zoom-in::before,
#stazioni-map .mappa-control-zoom-out::before,
#stazioni-map .mappa-control-layers-toggle::before,
#stazioni-map .mappa-control.btn-gps::before,
#stazioni-map .mappa-control.btn-ruler::before,
#stazioni-map .mappa-control.btn-north::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* mai piu' piccola del bersaglio: `max()` protegge dal caso in cui il
     controllo sia gia' abbastanza grande */
  width: max(100%, var(--tocco-x, 44px));
  height: max(100%, var(--tocco-y, 44px));
  /* nessuno sfondo e nessun bordo: si vede niente, si tocca di piu' */
}

/* Bottoni della location bar: il passo fra uno e l'altro e' 34-35px (misurato
   a 375 e 430), quindi 34 e' il massimo che non fa sovrapporre le aree. In
   verticale si arriva a 44 perche' la barra e' alta 58-115px. */
.location-bar .loc-actions a,
.location-bar .loc-actions button {
  --tocco-x: 34px;
}

/* Pallini orari dei semafori: sono CONTIGUI (passo = larghezza), quindi in
   orizzontale l'area e' gia' ottimale e allargarla ruberebbe il tocco al
   vicino. Cresce solo l'altezza, da 17 a 44: il genitore `.sem-bar-tips` e'
   alto 17px ma non ritaglia, e sopra e sotto ci sono solo etichette. */
.widget-semafori .sem-tip {
  --tocco-x: 0px;
}

/* Bande accordion della tabella Pro: larghe 4184px dentro uno scroller, il
   problema e' solo l'altezza (31px). Fra una banda e l'altra ci sono 135px di
   passo, quindi l'area piu' alta non tocca la banda vicina. */
.dt-section {
  --tocco-x: 0px;
}

/* Stella e storico nella colonna nome di `stazioni`: 20x20 attaccati, con
   passo 31px fra i centri, quindi in orizzontale non si va oltre 30 senza
   rubarsi il tocco. In verticale la regola chiede 40, ma la riga sotto viene
   dopo nel DOM e vince: sul device l'area vera e' 30x34 (17/09/2026). */
.st-cell-name .fav-btn,
.st-cell-name .history-btn {
  position: relative;
}
.st-cell-name .fav-btn::before,
.st-cell-name .history-btn::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 30px;
  height: 40px;
}

/* Widget "spento": il posto di una funzione chiusa dal livello (partials/common/
   upsell.php). Stesso guscio dei widget veri, ma senza fondo e col bordo
   tratteggiato: si legge come "qui c'e' qualcosa, non per te ancora". Dentro,
   il widget vero (dati limitati dal server) scurito e sfumato; sotto, l'invito
   a contrasto pieno. */
/* Classe ripetuta: deve battere `.widget:not(.alert-widget):not(.pro-row-alert)
   :not(.widget-semafori) { border: 0 }`, che ha quattro classi di specificita'. */
.widget.widget-spento.widget-spento.widget-spento {
  background: transparent;
  background-image: none;
  border: 1.5px dashed rgb(255 255 255 / 42%);
  box-shadow: none;
  padding: 0;
  margin-top: 12px;
}
/* padding: 0 sul guscio: la testa si rimette lo spazio dei widget veri. */
.widget-spento > .widget-header { padding: 14px 16px 6px; margin: 0; }
.widget-spento .ws-anteprima {
  position: relative;
  padding: 0 10px;
  max-height: 560px;
  overflow: hidden;
  filter: brightness(0.62);
  pointer-events: none;
  user-select: none;
  /* Il widget sfuma verso l'invito: l'assaggio finisce, non viene tagliato. */
  -webkit-mask-image: linear-gradient(to bottom, #000 60%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 60%, transparent 100%);
}
/* Il widget vero dentro il guscio: niente margini suoi, niente scroll. */
.widget-spento .ws-anteprima > .widget,
.widget-spento .ws-anteprima > .row,
.widget-spento .ws-anteprima > section { margin: 0 !important; }
/* La hero da tablet e' larga 640 e centrata con margin auto: azzerato qui sopra,
   la hero della Pro chiusa finiva a sinistra mentre le altre stanno al centro. */
@media (min-width: 768px) {
  .widget-spento .ws-anteprima > .hero-uniforme { margin-inline: auto !important; }
}
/* Due widget nello stesso guscio tengono lo stacco dei widget veri (.widget margin-bottom). */
/* :is() con la classe pesa piu' di "> section" qui sopra, che altrimenti vince. */
.widget-spento .ws-anteprima > * + :is(.widget, section, .row, a, div) { margin-top: 15px !important; }
.widget-spento .ws-anteprima .dt-scroll,
.widget-spento .ws-anteprima .st-scroll { overflow: hidden; }
/* L'invito sta in un box pieno: e' l'unica cosa nitida del widget. Una colonna
   sola, il titolo resta nella testa del widget, il bottone occupa la riga. */
.widget-spento .ws-invito {
  margin: 4px 10px 12px;
  padding: 16px;
  border-radius: 14px;
  background: rgb(0 0 0 / 28%);
  border: 1px solid rgb(255 255 255 / 18%);
}
.widget-spento .ws-motivo {
  margin: 0;
  font-size: var(--fs-md, 15px);
  font-weight: 700;
  line-height: 1.3;
  color: #fff;
}
.widget-spento .ws-desc {
  margin: 4px 0 0;
  font-size: 13px;
  line-height: 1.4;
  color: rgb(255 255 255 / 85%);
}
.widget-spento .ws-azione {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: 44px;
  margin-top: 14px;
  padding: 0 18px;
  border-radius: 22px;
  background: #fff;
  color: #14202e;
  font-weight: 700;
  font-size: 15px;
  text-decoration: none;
}
.widget-spento .ws-azione:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
@media (prefers-reduced-transparency: reduce) {
  .widget-spento .ws-anteprima { filter: saturate(0.35); }
}

/* Telefono debole (WeatherGradientManager._applicaSfondoCard): fondo pieno,
   niente cielo nelle superfici. Il cielo allineato si paga con un repaint di
   ogni card a ogni fotogramma di scroll (sync dell'offset, o attachment fixed),
   e su una GPU tipo Mali-T830 lo scroll si impasta. */
html[data-card-sfondo="pieno"] .widget,
html[data-card-sfondo="pieno"] .st-table,
html[data-card-sfondo="pieno"] .st-thead,
html[data-card-sfondo="pieno"] .info-page,
html[data-card-sfondo="pieno"] .station-cta-banner,
html[data-card-sfondo="pieno"] .nowcast-radar-cta,
html[data-card-sfondo="pieno"] .navbar-bottom-nav,
html[data-card-sfondo="pieno"] .solunar-press-block,
html[data-card-sfondo="pieno"] .passo-btn,
html[data-card-sfondo="pieno"] .day-forecast-row.is-open {
  background-image: none;
}
html[data-card-sfondo="pieno"] .modello-pro-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%23ffffff88' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
  background-attachment: scroll;
  background-position: right 12px center;
  background-size: auto;
}
