1<!DOCTYPE html> 2<html lang="it"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1"> 6 <title>Vetrina Prodotti e Servizi â VerbumRadio</title> 7 <meta name="description" content="Prodotti, servizi e piani VerbumRadio per Radio Streaming e Video Streaming: apparati, servizi aggiuntivi e abbonamenti per parrocchie, santuari e comunità ."> 8 <link rel="canonical" href="https://www.verbumradio.com/vetrina-prodotti.html"> 9 <meta name="robots" content="index, follow"> 10 <meta property="og:type" content="website"> 11 <meta property="og:site_name" content="VerbumRadio"> 12 <meta property="og:locale" content="it_IT"> 13 <meta property="og:title" content="Prodotti, Servizi e Piani â Radio e Video streaming | VerbumRadio"> 14 <meta property="og:description" content="Apparati, servizi e piani per trasmettere in diretta streaming la Santa Messa: soluzioni radio e video per parrocchie e santuari."> 15 <meta property="og:url" content="https://www.verbumradio.com/vetrina-prodotti.html"> 16 <meta property="og:image" content="https://www.verbumradio.com/immagini/og-verbumradio.jpg"> 17 <meta name="twitter:card" content="summary_large_image"> 18 <meta name="twitter:title" content="Prodotti, Servizi e Piani â Radio e Video streaming | VerbumRadio"> 19 <meta name="twitter:description" content="Apparati, servizi e piani per trasmettere in diretta streaming la Santa Messa: soluzioni radio e video per parrocchie e santuari."> 20 <meta name="twitter:image" content="https://www.verbumradio.com/immagini/og-verbumradio.jpg"> 21
21<script type="application/ld+json"> 22 { 23 "@context":"https://schema.org", 24 "@type":"Service", 25 "serviceType":"Radio e video streaming per parrocchie e santuari", 26 "name":"Prodotti, servizi e piani VerbumRadio", 27 "provider":{"@type":"Organization","name":"VerbumRadio","alternateName":"A.D.V. Telecommunications","url":"https://www.verbumradio.com/","telephone":"+39 02 9517056","email":"[email protected]","address":{"@type":"PostalAddress","addressLocality":"Gorgonzola","addressRegion":"MI","addressCountry":"IT"}}, 28 "areaServed":"IT", 29 "description":"Apparati, servizi aggiuntivi e piani di abbonamento per trasmettere in diretta streaming le celebrazioni: radio e video streaming.", 30 "url":"https://www.verbumradio.com/vetrina-prodotti.html" 31 } 32 </script>
32 33 <link rel="preconnect" href="https://fonts.googleapis.com"> 34 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin=""> 35 <link href="https://fonts.googleapis.com/css2?family=Lora:wght@400;500;600;700&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet"> 36 <style> 37 :root{ 38 --terra:#8a4020; --terra-dk:#6b3018; --terra-lt:#f5e8df; --terra-xlt:#fdf2ec; --terra-soft:#c98352; 39 --blu:#185FA5; --blu-dk:#124a82; 40 --brown:#2d2416; --brown-md:#5a4a38; --brown-lt:#8a7560; --brown-xlt:#c5b8a8; 41 --cream:#faf8f5; --cream-2:#f3ede4; --line:#e7ddd0; 42 --green:#4a7c59; 43 } 44 *{box-sizing:border-box;margin:0;padding:0} 45 body{font-family:'Inter',system-ui,-apple-system,'Segoe UI',sans-serif;color:var(--brown);background:var(--cream);line-height:1.6;overflow-x:hidden} 46 a{color:inherit} 47 img{max-width:100%;display:block} 48 .wrap{max-width:1120px;margin:0 auto;padding:0 20px} 49 50 /* Barra superiore */ 51 .topbar{position:sticky;top:0;z-index:20;background:rgba(45,36,22,.96);backdrop-filter:blur(6px);color:#fff; 52 border-bottom:1px solid rgba(255,255,255,.08)} 53 .topbar .wrap{display:flex;align-items:center;justify-content:space-between;gap:16px;padding-top:14px;padding-bottom:14px} 54 .brand{font-family:'Lora',Georgia,serif;font-size:22px;font-weight:700;color:#fff;text-decoration:none;white-space:nowrap} 55 .brand span{color:var(--terra-soft)} 56 .top-actions{display:flex;align-items:center;gap:10px;flex-wrap:wrap;justify-content:flex-end} 57 .top-actions a{font-size:13.5px;text-decoration:none;color:#e9dfd4;padding:7px 12px;border-radius:999px;transition:.15s} 58 .top-actions a:hover{background:rgba(255,255,255,.10);color:#fff} 59 .wa{display:inline-flex;align-items:center;gap:7px;background:#25d366;color:#fff !important;font-weight:700; 60 box-shadow:0 8px 20px -10px rgba(37,211,102,.9)} 61 .wa:hover{background:#1eb457 !important} 62 .wa svg{width:17px;height:17px;fill:currentColor;flex-shrink:0} 63 64 /* Intestazione pagina */ 65 .page-hero{background:linear-gradient(180deg,var(--terra-xlt),var(--cream));border-bottom:1px solid var(--line)} 66 .page-hero .wrap{padding-top:46px;padding-bottom:38px} 67 .eyebrow{font-size:12.5px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--terra-dk)} 68 h1{font-family:'Lora',Georgia,serif;font-size:clamp(30px,4.4vw,46px);line-height:1.1;color:var(--terra-dk);margin:8px 0 12px} 69 .page-hero p{max-width:60ch;color:var(--brown-md);font-size:16.5px} 70 /* Due banner affiancati, ciascuno linka alla propria sezione */ 71 .banner-row{display:grid;grid-template-columns:1fr 1fr;gap:22px;margin-top:28px} 72 .banner{display:block;border-radius:16px;overflow:hidden;border:1px solid var(--line);background:#fff; 73 box-shadow:0 18px 44px -30px rgba(45,36,22,.6);transition:transform .16s ease, box-shadow .16s ease} 74 .banner:hover{transform:translateY(-3px);box-shadow:0 26px 54px -28px rgba(45,36,22,.7)} 75 .banner:focus-visible{outline:2px solid var(--terra);outline-offset:3px} 76 .banner img{width:100%;height:auto;display:block} 77 @media(max-width:640px){.banner-row{grid-template-columns:1fr;gap:16px}} 78 79 /* Sezione categoria */ 80 .cat{padding:52px 0;scroll-margin-top:74px} 81 .cat + .cat{border-top:1px solid var(--line)} 82 .cat.video{background:var(--cream-2)} 83 /* Titolo della sezione (la si raggiunge cliccando il banner in cima) */ 84 .cat-title{margin-bottom:6px;text-align:center} 85 .cat-title .eyebrow{color:var(--terra-dk)} 86 .cat.video .cat-title .eyebrow{color:var(--blu-dk)} 87 .cat-title h2{font-family:'Lora',serif;font-size:clamp(26px,3.4vw,36px);color:var(--terra-dk);margin-top:6px;line-height:1.15} 88 .cat.video .cat-title h2{color:var(--blu-dk)} 89 /* Riquadro-spiegazione: cosa significa avviare il servizio */ 90 .cat-intro{background:var(--terra-xlt);border:1px solid var(--terra-lt);border-left:5px solid var(--terra); 91 border-radius:14px;padding:18px 22px;margin:14px 0 30px} 92 .cat.video .cat-intro{background:#eef4fb;border-color:#d6e4f3;border-left-color:var(--blu)} 93 .cat-intro .lead{font-family:'Lora',serif;font-size:clamp(18px,2.2vw,22px);font-weight:600;color:var(--terra-dk);line-height:1.35} 94 .cat.video .cat-intro .lead{color:var(--blu-dk)} 95 .cat-intro p.more{color:var(--brown-md);font-size:15.5px;margin-top:8px} 96 .cat-intro strong{color:var(--terra-dk)} 97 .cat.video .cat-intro strong{color:var(--blu-dk)} 98 .vh{position:absolute !important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0} 99 100 /* Sotto-blocchi Prodotti / Servizi / Piani */ 101 .sub{margin-top:34px} 102 .sub-title{display:flex;align-items:center;justify-content:center;gap:14px;margin-bottom:16px} 103 .sub-title::before{content:"";flex:1;height:1px;background:var(--line)} 104 .sub-title h3{font-family:'Lora',serif;font-size:clamp(22px,2.4vw,26px);color:var(--brown);white-space:nowrap} 105 .sub-title .count{font-size:13px;color:var(--brown-lt);white-space:nowrap} 106 .sub-title .rule{flex:1;height:1px;background:var(--line)} 107 108 /* Card prodotto: immagine + descrizione a fianco */ 109 .items{display:grid;gap:16px} 110 .pcard{display:grid;grid-template-columns:200px 1fr;gap:20px;background:#fff;border:1px solid var(--line); 111 border-radius:16px;padding:16px;box-shadow:0 14px 34px -28px rgba(45,36,22,.55)} 112 .pcard .thumb{border-radius:12px;overflow:hidden;background:var(--cream-2);aspect-ratio:4/3;display:flex;align-items:center;justify-content:center} 113 .pcard .thumb img{width:100%;height:100%;object-fit:cover} 114 .pcard .thumb.ph{color:var(--brown-xlt);font-size:13px;font-style:italic} 115 .pcard .body{align-self:center} 116 .pcard .name{font-family:'Lora',serif;font-size:19px;color:var(--brown);margin-bottom:4px} 117 .pcard .desc{color:var(--brown-md);font-size:14.5px;margin-top:6px} 118 .badge-pop{display:inline-block;background:var(--terra);color:#fff;font-size:11px;font-weight:700;padding:2px 9px;border-radius:999px;margin-left:8px;vertical-align:middle} 119 .price{display:inline-block;font-weight:700;color:var(--terra-dk);font-size:18px} 120 .cat.video .price{color:var(--blu-dk)} 121 .price .u{font-size:12.5px;font-weight:600;color:var(--brown-lt)} 122 .feats{list-style:none;margin:10px 0 0;display:flex;flex-wrap:wrap;gap:6px 14px} 123 .feats li{position:relative;padding-left:16px;font-size:13px;color:var(--brown-md)} 124 .feats li::before{content:"";position:absolute;
124left:0;top:7px;width:7px;height:7px;border-radius:50%;background:var(--green)} 125 /* Link acquisto (solo se il prodotto è attivo nell'e-commerce) */ 126 .buy{margin-top:14px} 127 .buy-btn{display:inline-flex;align-items:center;gap:8px;background:var(--terra);color:#fff;text-decoration:none; 128 font-weight:700;font-size:14px;padding:10px 18px;border-radius:999px;transition:transform .15s ease,background .15s ease; 129 box-shadow:0 10px 22px -12px rgba(138,64,32,.85)} 130 .buy-btn:hover{background:var(--terra-dk);transform:translateY(-1px)} 131 .buy-btn:focus-visible{outline:2px solid var(--terra-dk);outline-offset:2px} 132 .cat.video .buy-btn{background:var(--blu);box-shadow:0 10px 22px -12px rgba(24,95,165,.85)} 133 .cat.video .buy-btn:hover{background:var(--blu-dk)} 134 .soldout{display:inline-block;margin-top:12px;font-size:13px;color:var(--brown-lt);background:var(--cream-2); 135 border:1px solid var(--line);border-radius:999px;padding:5px 13px} 136 /* Link "Come funziona la radio" in fondo ai servizi radio */ 137 .svc-more{margin-top:16px} 138 .how-link{display:inline-flex;align-items:center;gap:8px;font-weight:700;font-size:14.5px;color:var(--terra-dk); 139 text-decoration:none;border:1.5px solid var(--terra-lt);background:var(--terra-xlt);border-radius:999px;padding:9px 18px;transition:.15s} 140 .how-link:hover{border-color:var(--terra);transform:translateY(-1px)} 141 .how-link span{transition:transform .15s} 142 .how-link:hover span{transform:translateX(3px)} 143 144 /* Card servizio (più compatta) */ 145 .scard{display:grid;grid-template-columns:96px 1fr auto;gap:16px;align-items:center;background:#fff;border:1px solid var(--line); 146 border-radius:14px;padding:14px 16px} 147 .scard .thumb{width:96px;height:72px;border-radius:10px;overflow:hidden;background:var(--cream-2);display:flex;align-items:center;justify-content:center} 148 .scard .thumb img{width:100%;height:100%;object-fit:cover} 149 .scard.noimg{grid-template-columns:1fr auto} 150 .scard .name{font-weight:700;font-size:16px;color:var(--brown)} 151 .scard .desc{color:var(--brown-md);font-size:14px;margin-top:2px} 152 .scard .plans-tag{display:inline-block;margin-top:6px;font-size:11.5px;color:var(--brown-lt);background:var(--cream-2);border:1px solid var(--line);border-radius:999px;padding:2px 10px} 153 .scard .sprice{text-align:right;white-space:nowrap} 154 .scard .sprice .p{font-weight:700;color:var(--terra-dk);font-size:16px} 155 .cat.video .scard .sprice .p{color:var(--blu-dk)} 156 .scard .sprice small{display:block;color:var(--brown-lt);font-size:11.5px} 157 158 /* Piani */ 159 .plans{display:grid;grid-template-columns:1fr 1fr;gap:18px} 160 .plan{display:flex;flex-direction:column;background:#fff;border:1px solid var(--line);border-radius:18px;overflow:hidden; 161 box-shadow:0 18px 44px -32px rgba(45,36,22,.6)} 162 .plan .pimg{aspect-ratio:16/9;background:var(--cream-2);overflow:hidden} 163 .plan .pimg img{width:100%;height:100%;object-fit:cover} 164 .plan .pin{padding:18px 20px 20px;display:flex;flex-direction:column;flex:1} 165 .plan .pname{font-family:'Lora',serif;font-size:20px;color:var(--terra-dk)} 166 .cat.video .plan .pname{color:var(--blu-dk)} 167 .plan .pdesc{color:var(--brown-md);font-size:14.5px;margin:8px 0 14px} 168 .plan .pprice{font-size:26px;font-weight:700;color:var(--brown);margin-top:auto} 169 .plan .pprice .u{font-size:14px;font-weight:600;color:var(--brown-lt)} 170 .plan .pcta{margin-top:14px} 171 .plan .pcta a{display:inline-flex;align-items:center;gap:8px;background:#25d366;color:#fff;text-decoration:none;font-weight:700; 172 font-size:14px;padding:10px 16px;border-radius:999px;transition:.15s;box-shadow:0 8px 20px -10px rgba(37,211,102,.9)} 173 .plan .pcta a:hover{background:#1eb457;transform:translateY(-1px)} 174 .plan .pcta a svg{width:17px;height:17px;fill:currentColor} 175 176 .empty-note{background:#fff;border:1px dashed var(--line);border-radius:14px;padding:20px;color:var(--brown-lt);font-size:14.5px;text-align:center} 177 .loading{color:var(--brown-lt);font-size:15px;padding:8px 0} 178 179 footer{background:var(--brown);color:#e9dfd4;margin-top:0;padding:34px 0} 180 footer .wrap{text-align:center;font-size:13.5px;line-height:1.7} 181 footer .brand{font-size:20px} 182 footer a{color:var(--terra-soft);text-decoration:none} 183 184 @media(max-width:820px){ 185 .plans{grid-template-columns:1fr} 186 } 187 @media(max-width:560px){ 188 .pcard{grid-template-columns:1fr} 189 .pcard .thumb{aspect-ratio:16/9} 190 .scard{grid-template-columns:1fr;text-align:left} 191 .scard .thumb{width:100%;height:150px} 192 .scard .sprice{text-align:left} 193 } 194 @media(prefers-reduced-motion:reduce){*{transition:none !important}} 195 196 /* Modalità "embed": quando la pagina è inclusa in un iframe (es. nella landing), 197 nasconde barra, intestazione testuale e footer, lasciando i banner e i contenuti. */ 198 html.is-embed body{background:transparent} 199 html.is-embed .topbar, html.is-embed footer{display:none} 200 html.is-embed .page-hero{background:none;border-bottom:none} 201 html.is-embed .page-hero .eyebrow, html.is-embed .page-hero h1, html.is-embed .page-hero p{display:none} 202 html.is-embed .page-hero .wrap{padding-top:18px;padding-bottom:0} 203 </style> 204 <link rel="stylesheet" href="theme.php?css"> 205
205<script> 206 /* Modalità embed (iframe): attiva la classe e comunica l'altezza al contenitore per l'auto-resize. */ 207 (function(){ 208 try{ 209 var p=new URLSearchParams(location.search); 210 if(p.get('embed')!=='1') return; 211 document.documentElement.classList.add('is-embed'); 212 function postH(){ try{ parent.postMessage({vetrinaHeight: Math.ceil(document.body.getBoundingClientRect().height)}, '*'); }catch(e){} } 213 window.addEventListener('load', postH); 214 window.addEventListener('resize', postH); 215 document.addEventListener('DOMContentLoaded', function(){ 216 postH(); 217 if('ResizeObserver' in window){ try{ new ResizeObserver(postH).observe(document.body); }catch(e){} } 218 var n=0, t=setInterval(function(){ postH(); if(++n>20) clearInterval(t); }, 500); // rete di sicurezza mentre i dati si caricano 219 }); 220 }catch(e){} 221 })(); 222 </script>
222 223</head> 224<body> 225 226 <div class="topbar"> 227 <div class="wrap"> 228 <a class="brand" href="index.html">Verbum<span>Radio</span></a> 229 <div class="top-actions"> 230 <a href="index.html">Home</a> 231 <a href="ecommerce-verbumradio/landing.html">Shop & servizi</a> 232 <a class="wa" href="https://wa.me/393355990528?text=Salve%2C%20vorrei%20informazioni%20su%20prodotti%20e%20servizi%20VerbumRadio." target="_blank" rel="noopener"> 233 <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M17.5 14.4c-.3-.15-1.7-.85-2-.95-.25-.1-.45-.15-.6.15-.2.3-.7.95-.85 1.1-.15.2-.3.2-.6.05-.3-.15-1.25-.45-2.4-1.5-.9-.8-1.5-1.75-1.65-2.05-.15-.3 0-.45.15-.6.15-.15.3-.35.45-.55.15-.15.2-.3.3-.5.1-.2.05-.35-.05-.5-.1-.15-.6-1.5-.85-2.05-.2-.5-.45-.45-.6-.45h-.5c-.2 0-.5.05-.75.35-.25.3-1 .95-1 2.35s1.05 2.75 1.2 2.9c.15.2 2.05 3.15 5 4.4.7.3 1.25.5 1.65.6.7.2 1.3.2 1.8.1.55-.1 1.7-.7 1.95-1.35.25-.65.25-1.2.15-1.35-.1-.15-.3-.2-.6-.35zM12 2a10 10 0 0 0-8.6 15.1L2 22l5-1.3A10 10 0 1 0 12 2z"></path></svg> 234 Chiedi informazioni 235 </a> 236 </div> 237 </div> 238 </div> 239 240 <header class="page-hero"> 241 <div class="wrap"> 242 <div class="eyebrow">Vetrina VerbumRadio</div> 243 <h1>Prodotti e Servizi</h1> 244 <p>Tutto ciò che serve per portare la vita della vostra comunità online: apparati, servizi aggiuntivi e piani di abbonamento, per la <strong>Radio Streaming</strong> e il <strong>Video Streaming</strong>.</p> 245 <div class="banner-row"> 246 <a class="banner" href="#radio" id="radioBanner" aria-label="Vai alla sezione Radio Streaming"></a> 247 <a class="banner" href="#video" id="videoBanner" aria-label="Vai alla sezione Video Streaming"></a> 248 </div> 249 </div> 250 </header> 251 252 <!-- âââââââââââ RADIO âââââââââââ --> 253 <section class="cat radio" id="radio"> 254 <div class="wrap"> 255 <div class="cat-title"> 256 <span class="eyebrow">Prodotti e Servizi</span> 257 <h2>Radio Streaming</h2> 258 </div> 259 260 <div class="cat-intro" id="radioIntro"> 261 <p class="lead" id="radioIntroLead">Avviare la vostra Radio Streaming significa dare voce alla comunità , ogni giorno, 24 ore su 24.</p> 262 <p class="more" id="radioIntroText">Le Sante Messe, il Rosario, gli avvisi e la musica raggiungono i fedeli <strong>ovunque si trovino</strong> â a casa, in auto, al lavoro â dal sito della parrocchia, dallo smartphone, dagli altoparlanti vocali e persino dalla Smart-TV. Una presenza semplice da gestire, che tiene tutti uniti.</p> 263 </div> 264 265 <div class="sub"> 266 <div class="sub-title"><h3>Piani</h3><span class="rule"></span></div> 267 <div class="plans" id="radioPlans"></div> 268 </div> 269 270 <div class="sub"> 271 <div class="sub-title"><h3>Prodotti</h3><span class="count" id="radioProdCount"></span><span class="rule"></span></div> 272 <div class="items" id="radioProducts"><div class="loading">Caricamento prodottiâ¦</div></div> 273 </div> 274 275 <div class="sub"> 276 <div class="sub-title"><h3>Servizi</h3><span class="count" id="radioSvcCount"></span><span class="rule"></span></div> 277 <div class="items" id="radioServices"></div> 278 <div class="svc-more"> 279 <a class="how-link" href="info-radio.html" target="_blank" rel="noopener">Come funziona la radio <span aria-hidden="true">â</span></a> 280 </div> 281 </div> 282 </div> 283 </section> 284 285 <!-- âââââââââââ VIDEO âââââââââââ --> 286 <section class="cat video" id="video"> 287 <div class="wrap"> 288 <div class="cat-title"> 289 <span class="eyebrow">Prodotti e Servizi</span> 290 <h2>Video Streaming</h2> 291 </div> 292 293 <div class="cat-intro" id="videoIntro"> 294 <p class="lead" id="videoIntroLead">Avviare il vostro Video Streaming significa aprire le porte della chiesa a chi non può essere presente.</p> 295 <p class="more" id="videoIntroText">Le celebrazioni vanno <strong>in diretta e in alta definizione</strong> su qualsiasi Smart-TV, sul sito della parrocchia, sui social e su computer, tablet e smartphone. Gli anziani, i malati e i lontani tornano a vivere la liturgia con voi, <strong>come se fossero lì</strong>.</p> 296 </div> 297 298 <div class="sub"> 299 <div class="sub-title"><h3>Piani</h3><span class="rule"></span></div> 300 <div class="plans" id="videoPlans"></div> 301 </div> 302 303 <div class="sub"> 304 <div class="sub-title"><h3>Prodotti</h3><span class="count" id="videoProdCount"></span><span class="rule"></span></div> 305 <div class="items" id="videoProducts"><div class="loading">Caricamento prodottiâ¦</div></div> 306 </div> 307 308 <div class="sub"> 309 <div class="sub-title"><h3>Servizi</h3><span class="count" id="videoSvcCount"></span><span class="rule"></span></div> 310 <div class="items" id="videoServices"></div> 311 </div> 312 </div> 313 </section> 314 315 <footer> 316 <div class="wrap"> 317 <a href="index.html" class="brand">Verbum<span style="color:var(--terra-soft)">Radio</span></a> 318 <p style="margin-top:8px">A.D.V. Telecommunications di Bogino Maurizio â P.IVA 10557300158<br> 319 [email protected] · Tel. 02 9517056 · 335 5990528</p> 320 <p style="margin-top:10px"><a href="ecommerce-verbumradio/landing.html">Vai allo shop e ai servizi â</a></p> 321 </div> 322 </footer> 323
324<script> 325(function(){ 326 "use strict"; 327 // I dati e le immagini stanno nella cartella dell'e-commerce (stessa fonte dello shop). 328 var INV_BASE = 'ecommerce-verbumradio/'; 329 var TEL = '393355990528'; 330 331 function esc(s){ return String(s==null?'':s).replace(/[&<>"]/g,function(c){return c==='&'?'&':c==='<'?'<':c==='>'?'>':'"';}); } 332 333 // Risolve un path immagine: URL assoluto â invariato; relativo â dentro la cartella e-commerce. 334 function img(u){ 335 u=(u||'').trim(); if(!u) return ''; 336 if(/^(https?:)?\/\//i.test(u) || u.indexOf('data:')===0) return u; 337 if(u.charAt(0)==='/') return u; 338 return INV_BASE + u.replace(/^\.\//,''); 339 } 340 // Formatta un prezzo in euro; ritorna '' se vuoto/non valido. 341 function eur(v){ 342 if(v===''||v==null) return ''; 343 var n=Number(v); if(isNaN(n)) return ''; 344 var neg=n<0; n=Math.abs(n); 345 var intPart=Math.floor(n).toString().replace(/\B(?=(\d{3})+(?!\d))/g,'.'); // migliaia col punto 346 var cents=Math.round(n*100)%100, dec = cents ? (','+(cents<10?'0'+cents:cents)) : ''; 347 return 'â¬'+(neg?'-':'')+intPart+dec; 348 } 349 function waHref(msg){ return 'https://wa.me/'+TEL+'?text='+encodeURIComponent(msg); } 350 var WA_SVG='<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M17.5 14.4c-.3-.15-1.7-.85-2-.95-.25-.1-.45-.15-.6.15-.2.3-.7.95-.85 1.1-.15.2-.3.2-.6.05-.3-.15-1.25-.45-2.4-1.5-.9-.8-1.5-1.75-1.65-2.05-.15-.3 0-.45.15-.6.15-.15.3-.35.45-.55.15-.15.2-.3.3-.5.1-.2.05-.35-.05-.5-.1-.15-.6-1.5-.85-2.05-.2-.5-.45-.45-.6-.45h-.5c-.2 0-.5.05-.75.35-.25.3-1 .95-1 2.35s1.05 2.75 1.2 2.9c.15.2 2.05 3.15 5 4.4.7.3 1.25.5 1.65.6.7.2 1.3.2 1.8.1.55-.1 1.7-.7 1.95-1.35.25-.65.25-1.2.15-1.35-.1-.15-.3-.2-.6-.35zM12 2a10 10 0 0 0-8.6 15.1L2 22l5-1.3A10 10 0 1 0 12 2z"></path></svg>'; 351 352 var LABEL={radio:'Radio Streaming', video:'Video Streaming'}; 353 var BANNER_ALT={radio:'Radio Live Streaming', video:'Video Live Streaming'}; 354 // Fallback del banner se l'admin non ha impostato l'immagine "tipo servizio" 355 var BANNER_FALLBACK={radio:INV_BASE+'immagini/svc-radio.jpg', video:INV_BASE+'immagini/svc-video.jpg'}; 356 // Pagina di acquisto (il negozio-wizard dell'e-commerce) 357 var SHOP_URL=INV_BASE+'verbumradio-shop.html'; 358 var MESI=['gennaio','febbraio','marzo','aprile','maggio','giugno','luglio','agosto','settembre','ottobre','novembre','dicembre']; 359 function fmtDate(s){ if(!s) return ''; var d=new Date(s); if(isNaN(d.getTime())) return esc(s); return d.getDate()+' '+MESI[d.getMonth()]+' '+d.getFullYear(); } 360 361 function productCard(p, cat, catActive){ 362 var im=img(p.imageUrl); 363 var feats=(p.feats||'').split('\n').map(function(s){return s.trim();}).filter(Boolean); 364 var price=eur(p.price); 365 var stock=Number(p.stock||0); 366 var active=!!catActive && stock>=1; // attivo nell'e-commerce = categoria abilitata e disponibile 367 var buy; 368 if(active){ 369 buy='<div class="buy"><a class="buy-btn" href="'+esc(SHOP_URL)+'">Acquista <span aria-hidden="true">→</span></a></div>'; 370 } else if(stock<1){ 371 buy='<div class="buy"><span class="soldout">'+(p.availFrom?'Disponibile dal '+esc(fmtDate(p.availFrom)):'Non disponibile online')+'</span></div>'; 372 } else { buy=''; } // categoria non attiva: solo catalogo, nessun link 373 return '<div class="pcard">'+ 374 (im?'<div class="thumb"><img src="'+esc(im)+'" alt="'+esc(p.name||'')+'" loading="lazy" onerror="this.parentNode.classList.add(\'ph\');this.remove();this.parentNode.textContent=\'immagine non disponibile\'"></div>' 375 :'<div class="thumb ph">nessuna foto</div>')+ 376 '<div class="body">'+ 377 '<div class="name">'+esc(p.name||'Prodotto')+(p.popular?'<span class="badge-pop">Consigliato</span>':'')+'</div>'+ 378 (price?'<span class="price">'+price+'</span>':'')+ 379 (p.desc?'<div class="desc">'+esc(p.desc)+'</div>':'')+ 380 (feats.length?'<ul class="feats">'+feats.map(function(f){return '<li>'+esc(f)+'</li>';}).join('')+'</ul>':'')+ 381 buy+ 382 '</div>'+ 383 '</div>'; 384 } 385 386 function serviceCard(s, cat){ 387 var im=img(s.imageUrl); 388 var single=(s.pricingModel==='single'); 389 var p1=Number(s.priceP1||0), p2=Number(s.priceP2||0); 390 var priceHtml=''; 391 if(single){ if(p1) priceHtml='<div class="p">'+eur(p1)+'</div>'; } 392 else{ 393 if(p1||p2){ 394 priceHtml='<div class="p">'+eur(p1||p2)+'</div>'; 395 if(p1&&p2&&p1!==p2) priceHtml='<div class="p">'+eur(p1)+'</div><small>con apparato</small>'+ 396 '<div class="p" style="margin-top:6px">'+eur(p2)+'</div><small>da solo</small>'; 397 } 398 } 399 var plansArr=Array.isArray(s.availableInPlans)?s.availableInPlans:[]; 400 var plansTag = plansArr.length ? '<span class="plans-tag">Disponibile nei piani: '+plansArr.map(function(x){return esc(x.charAt(0).toUpperCase()+x.slice(1));}).join(', ')+'</span>' : ''; 401 var noimg = im ? '' : ' noimg'; 402 return '<div class="scard'+noimg+'">'+ 403 (im?'<div class="thumb"><img src="'+esc(im)+'" alt="'+esc(s.name||'')+'" loading="lazy" onerror="this.closest(\'.scard\').classList.add(\'noimg\');this.closest(\'.thumb\').remove()"></div>':'')+ 404 '<div class="info"><div class="name">'+esc(s.name||'Servizio')+'</div>'+ 405 (s.desc?'<div class="desc">'+esc(s.desc)+'</div>':'')+ 406 (s.note?'<div class="desc" style="font-size:13px;color:var(--brown-lt)">'+esc(s.note)+'</div>':'')+ 407 plansTag+ 408 '</div>'+ 409 '<div class="sprice">'+(priceHtml||'<small>su richiesta</small>')+'</div>'+ 410 '</div>'; 411 } 412 413 function planCard(pl, cat){ 414 var im=img(pl.img); 415 var price=eur(pl.price); 416 var msg='Salve, vorrei informazioni sul piano '+(pl.name||'')+' ('+LABEL[cat]+') di VerbumRadio.'; 417 return '<div class="plan">'+ 418 (im?'<div class="pimg"><img src="'+esc(im)+'" alt="'+esc(pl.name||'')+'" loading="lazy" onerror="this.closest(\'.pimg\').remove()"></div>':'')+ 419 '<div class="pin">'+ 420 '<div class="pname">'+esc(pl.name||'Piano')+'</div>'+ 421 (pl.desc?'<div class="pdesc">'+esc(pl.desc)+'</div>':'<div class="pdesc"></div>')+ 422 '<div class="pprice">'+(price?price+' <span class="u">/ mese</span>':'<span class="u">Prezzo su richiesta</span>')+'</div>'+ 423 '<div class="pcta"><a href="'+esc(waHref(msg))+'" target="_blank" rel="noopener">'+WA_SVG+' Chiedi informazioni</a></div>'+ 424 '</div>'+ 425 '</div>'; 426 } 427 428 function fillCategory(cat, data){ 429 // Banner in cima alla pagina (link alla sezione). Immagine gestita dall'admin 430 // (svcRadioImg/svcVideoImg); se assente, fallback a immagini/svc-<cat>.jpg. 431 var banner=document.getElementById(cat+'Banner'); 432 var bim=img(data.svc.img) || BANNER_FALLBACK[cat]; 433 banner.innerHTML='<img src="'+esc(bim)+'" alt="'+esc(BANNER_ALT[cat])+'" '+ 434 'onerror="if(this.src.indexOf(\''+BANNER_FALLBACK[cat]+'\')<0){this.src=\''+BANNER_FALLBACK[cat]+'\';}else{this.closest(\'.banner\').style.display=\'none\';}">'; 435 436 // Prodotti 437 var pc=document.getElementById(cat+'Products'); 438 if(data.products.length){ pc.innerHTML=data.products.map(function(p){return productCard(p,cat,data.catActive);}).join(''); } 439 else { pc.innerHTML='<div class="empty-note">Nessun prodotto disponibile al momento. Scrivici per una soluzione su misura.<
439/div>'; } 440 document.getElementById(cat+'ProdCount').textContent = data.products.length ? '('+data.products.length+')' : ''; 441 442 // Servizi 443 var sc=document.getElementById(cat+'Services'); 444 if(data.services.length){ sc.innerHTML=data.services.map(function(s){return serviceCard(s,cat);}).join(''); } 445 else { sc.innerHTML='<div class="empty-note">Nessun servizio aggiuntivo per questa categoria al momento.</div>'; } 446 document.getElementById(cat+'SvcCount').textContent = data.services.length ? '('+data.services.length+')' : ''; 447 448 // Piani 449 var plc=document.getElementById(cat+'Plans'); 450 var plans=data.plans.filter(function(pl){ return (pl.name && String(pl.name).trim()) || pl.price!=='' ; }); 451 if(plans.length){ plc.innerHTML=plans.map(function(pl){return planCard(pl,cat);}).join(''); } 452 else { plc.innerHTML='<div class="empty-note">I piani per questa categoria saranno pubblicati a breve.</div>'; } 453 } 454 455 function num(o,k){ return (o&&o[k]!==undefined&&o[k]!=='')?o[k]:''; } 456 457 (async function(){ 458 var IMGS={}, P={}, SET={}, PRODUCTS=[], SERVICES=[]; 459 460 // 1) config-manifest.json (immagini/prezzi di base) 461 try{ 462 var r1=await fetch(INV_BASE+'config-manifest.json?v='+Date.now(),{cache:'no-store'}); 463 if(r1.ok){ var c=await r1.json(); 464 if(c.imgs && typeof c.imgs==='object') IMGS=c.imgs; 465 if(c.prices && typeof c.prices==='object') P=c.prices; 466 } 467 }catch(e){} 468 469 // 2) inventory pubblico (prodotti + servizi + settings piani/servizi) 470 try{ 471 var r2=await fetch(INV_BASE+'inventory.php?action=get_public&v='+Date.now(),{cache:'no-store'}); 472 if(r2.ok){ var inv=await r2.json(); 473 if(inv && inv.ok){ 474 PRODUCTS=Array.isArray(inv.products)?inv.products:[]; 475 SERVICES=Array.isArray(inv.services)?inv.services:[]; 476 SET=inv.settings||{}; 477 Object.keys(SET).forEach(function(k){ if(SET[k]!==undefined && SET[k]!=='') P[k]=SET[k]; }); 478 } 479 } 480 }catch(e){} 481 482 var svc={ 483 radio:{ desc: num(SET,'svcRadioDesc'), img: num(SET,'svcRadioImg') || num(IMGS,'svcRadio') }, 484 video:{ desc: num(SET,'svcVideoDesc'), img: num(SET,'svcVideoImg') || num(IMGS,'svcVideo') } 485 }; 486 var plans={ 487 radio:[ 488 {name:num(P,'planLite')||'Lite', desc:num(P,'planLiteDesc'), img:num(P,'planLiteImg'), price:num(P,'radioLite')}, 489 {name:num(P,'planTop')||'Top', desc:num(P,'planTopDesc'), img:num(P,'planTopImg'), price:num(P,'radioTop')} 490 ], 491 video:[ 492 {name:num(P,'planVideoLite')||'Video Lite', desc:num(P,'planVideoLiteDesc'), img:num(P,'planVideoLiteImg'), price:num(P,'videoLite')}, 493 {name:num(P,'planVideoTop')||'Video Top', desc:num(P,'planVideoTopDesc'), img:num(P,'planVideoTopImg'), price:num(P,'videoTop')} 494 ] 495 }; 496 497 function byCatProducts(cat){ 498 return PRODUCTS.filter(function(p){ return p.category===cat; }) 499 .sort(function(a,b){ return Number(a.price||0)-Number(b.price||0); }); 500 } 501 function byCatServices(cat){ 502 return SERVICES.filter(function(s){ 503 return Array.isArray(s.appliesTo) ? s.appliesTo.indexOf(cat)>=0 : (cat==='radio'); 504 }); 505 } 506 507 // Categoria "attiva" nell'e-commerce, con le stesse regole del negozio: 508 // radio abilitata salvo esplicito false; video abilitata solo se esplicitamente true. 509 var enabled={ radio:(P.radioEnabled!==false), video:(P.videoEnabled===true) }; 510 511 ['radio','video'].forEach(function(cat){ 512 fillCategory(cat,{ 513 svc: svc[cat], 514 products: byCatProducts(cat), 515 services: byCatServices(cat), 516 plans: plans[cat], 517 catActive: enabled[cat] 518 }); 519 }); 520 })(); 521})(); 522</script>
vendor: 1 bytes, line 522
522
523<script> 524/* Testi introduttivi editabili: se salvati in vetrina-intro.json (via vetrina-intro.php), 525 sovrascrivono i testi predefiniti qui sopra. Supporta **grassetto** e a-capo. 526 Se non c'è nulla di salvato (o il file non è raggiungibile), restano i testi predefiniti. */ 527(function(){ 528 function fmt(s){ 529 s=String(s==null?'':s).replace(/[&<>"]/g,function(c){return c==='&'?'&':c==='<'?'<':c==='>'?'>':'"';}); 530 return s.replace(/\*\*([^*]+)\*\*/g,'<strong>$1</strong>').replace(/\r?\n/g,'<br>'); 531 } 532 fetch('vetrina-intro.php?action=get&v='+Date.now(),{cache:'no-store'}) 533 .then(function(r){ return r.ok ? r.json() : null; }) 534 .then(function(d){ 535 if(!d || !d.ok || !d.intro) return; 536 ['radio','video'].forEach(function(cat){ 537 var it=d.intro[cat]; if(!it) return; 538 var l=document.getElementById(cat+'IntroLead'); 539 var t=document.getElementById(cat+'IntroText'); 540 if(l && it.lead && String(it.lead).trim()) l.innerHTML=fmt(it.lead); 541 if(t && it.text && String(it.text).trim()) t.innerHTML=fmt(it.text); 542 }); 543 }) 544 .catch(function(){}); 545})(); 546</script>
546 547</body> 548</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.