<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Paolo Campitelli - Producer · Multi-Instrumentalist · Sound Engineer</title>
<meta name="description" content="Official website of Paolo Campitelli - Music Producer, Multi-Instrumentalist, Sound Engineer. Owner of Warlord Sound Studios, Rome, Italy.">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;0,900;1,400;1,700&family=Inter:wght@300;400;500;600&display=swap" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js"></script>
<link href="https://cdn.quilljs.com/1.3.7/quill.snow.css" rel="stylesheet">
<script src="https://cdn.quilljs.com/1.3.7/quill.min.js"></script>
<style>
/* Quill dark theme */
.ql-toolbar.ql-snow{background:var(--s2);border-color:var(--border);border-radius:4px 4px 0 0}
.ql-container.ql-snow{background:var(--s2);border-color:var(--border);border-radius:0 0 4px 4px;min-height:200px}
.ql-toolbar .ql-stroke{stroke:var(--muted)}.ql-toolbar .ql-fill{fill:var(--muted)}
.ql-toolbar button:hover .ql-stroke{stroke:var(--accent)}.ql-toolbar button:hover .ql-fill{fill:var(--accent)}
.ql-editor{color:var(--text);font-family:'Inter',sans-serif;font-size:.95rem;line-height:1.75}
.ql-editor.ql-blank::before{color:var(--muted)}
/* Gallery card selector */
.gallery-card{
  background:var(--s1);border:1px solid var(--border);border-radius:6px;
  overflow:hidden;cursor:pointer;transition:border-color .25s,transform .25s,box-shadow .25s;
}
.gallery-card:hover{border-color:rgba(200,150,62,.4);transform:translateY(-3px)}
.gallery-card.active{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent),0 8px 32px rgba(200,150,62,.15)}
.gallery-card-thumb{width:100%;aspect-ratio:4/3;object-fit:cover;filter:brightness(.75);transition:filter .3s}
.gallery-card.active .gallery-card-thumb{filter:brightness(.9)}
.gallery-card-body{padding:.85rem 1rem}
.gallery-card-icon{font-size:1.2rem;margin-bottom:.3rem}
.gallery-card-name{font-family:'Playfair Display',serif;font-size:1rem;font-weight:700;color:#fff}
.gallery-card-count{font-size:.65rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--muted);margin-top:.2rem}
.gallery-card.active .gallery-card-name{color:var(--accent)}
.gallery-card.active .gallery-card-count{color:rgba(200,150,62,.7)}
@media(max-width:500px){#gallery-cards{grid-template-columns:1fr !important}}
/* Admin post table */
.admin-post-table{width:100%;border-collapse:collapse;margin-bottom:2rem}
.admin-post-table th{font-size:.65rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted);padding:.6rem .8rem;border-bottom:1px solid var(--border);text-align:left}
.admin-post-table td{padding:.7rem .8rem;border-bottom:1px solid var(--border);font-size:.82rem;color:var(--text)}
.admin-post-table tr:hover td{background:var(--s2)}
.slug-preview{font-size:.65rem;color:var(--muted);margin-top:.2rem;font-family:monospace}
</style>
<style>
:root {
  --bg: #0c0c0c;
  --s1: #141414;
  --s2: #1c1c1c;
  --s3: #242424;
  --border: rgba(255,255,255,0.07);
  --text: #dedad4;
  --muted: #706e69;
  --accent: #c8963e;
  --accent-glow: rgba(200,150,62,0.15);
  --accent-light: #e0ad5c;
  --nav-h: 64px;
}
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;font-size:16px}
body{background:var(--bg);color:var(--text);font-family:'Inter',system-ui,sans-serif;overflow-x:hidden;min-height:100vh}
a{color:inherit;text-decoration:none}
img{display:block;max-width:100%}
button{cursor:pointer;border:none;background:none;font-family:inherit;color:inherit}

/* ── SCROLLBAR ── */
::-webkit-scrollbar{width:4px}
::-webkit-scrollbar-track{background:var(--bg)}
::-webkit-scrollbar-thumb{background:var(--s3);border-radius:2px}
::-webkit-scrollbar-thumb:hover{background:var(--accent)}

/* ── NAV ── */
#nav{
  position:fixed;top:0;left:0;right:0;z-index:1000;
  height:var(--nav-h);
  display:flex;align-items:center;justify-content:space-between;
  padding:0 2.5rem;
  background:rgba(12,12,12,0);
  border-bottom:1px solid transparent;
  transition:background .4s,border-color .4s;
}
#nav.scrolled{background:rgba(12,12,12,.95);border-color:var(--border);backdrop-filter:blur(20px)}
.nav-logo{
  font-family:'Playfair Display',serif;
  font-size:1.1rem;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:#fff;
  cursor:pointer;
}
.nav-logo span{color:var(--accent)}
.nav-links{display:flex;align-items:center;gap:2rem;list-style:none}
.nav-links a{
  font-size:.72rem;font-weight:500;letter-spacing:.18em;text-transform:uppercase;
  color:var(--muted);transition:color .2s;
}
.nav-links a:hover,.nav-links a.active{color:var(--accent)}
.nav-social{display:flex;align-items:center;gap:.9rem;margin-left:1.5rem}
.nav-social a{color:var(--muted);transition:color .2s;display:flex;align-items:center}
.nav-social a:hover{color:var(--accent)}
.nav-social svg{width:16px;height:16px;fill:currentColor}
.nav-hamburger{display:none;flex-direction:column;gap:5px;padding:4px;cursor:pointer}
.nav-hamburger span{width:22px;height:1.5px;background:var(--text);transition:.3s;display:block}
@media(max-width:768px){
  .nav-links{display:none;position:fixed;top:var(--nav-h);left:0;right:0;bottom:0;background:var(--bg);flex-direction:column;justify-content:center;align-items:center;gap:2.5rem}
  .nav-links.open{display:flex}
  .nav-hamburger{display:flex}
  .nav-social{display:none}
}

/* ── PAGES ── */
.page{display:none;min-height:100vh;padding-top:var(--nav-h)}
.page.active{display:block}

/* ── HERO ── */
#hero{position:relative;height:100vh;display:flex;align-items:center;justify-content:center;overflow:hidden;background:#070608}
#hero-canvas{position:absolute;inset:0;width:100%;height:100%}
.hero-fallback{
  position:absolute;inset:0;
  background:radial-gradient(ellipse at 50% 60%,rgba(200,150,62,.12) 0%,transparent 65%),
             linear-gradient(180deg,#0c0c0c 0%,#111 50%,#0c0c0c 100%);
}
.hero-content{
  position:relative;z-index:10;text-align:center;
  padding:0 1.5rem;
}
.hero-eyebrow{
  font-size:.6rem;letter-spacing:.4em;text-transform:uppercase;
  color:rgba(200,150,62,.6);margin-bottom:1.8rem;
}
.hero-name{text-transform:uppercase;
  font-family:'Playfair Display',serif;
  font-size:clamp(3.5rem,10vw,8rem);
  font-weight:900;line-height:1;letter-spacing:-.01em;
  color:#fff;margin-bottom:1.2rem;
  text-shadow:0 0 40px rgba(200,150,62,.6),0 0 100px rgba(200,150,62,.3),0 0 180px rgba(200,150,62,.15),0 2px 40px rgba(0,0,0,.9);
}
.hero-name .surname{color:var(--accent)}
.hero-sub{
  font-size:clamp(.72rem,1.5vw,.9rem);
  letter-spacing:.32em;text-transform:uppercase;
  color:rgba(200,150,62,.75);font-weight:400;margin-bottom:3rem;
}
.hero-cta{
  display:inline-flex;gap:1rem;flex-wrap:wrap;justify-content:center;
}
.btn{
  display:inline-flex;align-items:center;gap:.5rem;
  padding:.75rem 1.8rem;border-radius:3px;
  font-size:.72rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  transition:all .25s;
}
.btn-primary{
  background:var(--accent);color:#0c0c0c;
}
.btn-primary:hover{background:var(--accent-light);transform:translateY(-2px)}
.btn-ghost{
  border:1px solid rgba(255,255,255,.18);color:var(--text);
}
.btn-ghost:hover{border-color:var(--accent);color:var(--accent);transform:translateY(-2px)}
.hero-scroll{
  position:absolute;bottom:2rem;left:50%;transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:.5rem;
  opacity:.5;animation:float 2.5s ease-in-out infinite;
}
.hero-scroll span{font-size:.6rem;letter-spacing:.22em;text-transform:uppercase;color:var(--muted)}
.hero-scroll-line{width:1px;height:40px;background:linear-gradient(to bottom,var(--accent),transparent)}
@keyframes float{0%,100%{transform:translateX(-50%) translateY(0)}50%{transform:translateX(-50%) translateY(6px)}}

/* ── HOME SECTIONS ── */
.home-section{padding:6rem 0;overflow:hidden}
.section-eyebrow{
  font-size:.62rem;letter-spacing:.28em;text-transform:uppercase;
  color:var(--accent);margin-bottom:.8rem;
  display:flex;align-items:center;gap:.8rem;
}
.section-eyebrow::before{content:'';width:30px;height:1px;background:var(--accent);opacity:.6}
.section-title{
  font-family:'Playfair Display',serif;
  font-size:clamp(2rem,5vw,3.5rem);
  font-weight:700;color:#fff;line-height:1.15;margin-bottom:1.5rem;
}
.section-sub{font-size:1rem;color:var(--muted);line-height:1.8;max-width:520px}
.container{max-width:1200px;margin:0 auto;padding:0 2rem}
.container-wide{max-width:1440px;margin:0 auto;padding:0 2rem}

/* ── REVEAL ANIMATIONS ── */
.reveal{opacity:0;transform:translateY(40px);transition:opacity .7s ease,transform .7s ease}
.reveal.visible{opacity:1;transform:none}
.reveal-delay-1{transition-delay:.1s}
.reveal-delay-2{transition-delay:.2s}
.reveal-delay-3{transition-delay:.3s}

/* ── HOME - featured band strip ── */
.band-strip{
  border-top:1px solid var(--border);border-bottom:1px solid var(--border);
  padding:2rem 0;margin-top:4rem;overflow:hidden;
}
.band-strip-inner{
  display:flex;gap:3rem;align-items:center;
  animation:marquee 20s linear infinite;
  width:max-content;
}
.band-name-item{
  font-family:'Playfair Display',serif;font-size:1.1rem;
  font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--muted);white-space:nowrap;transition:color .2s;
}
.band-name-item.active{color:var(--accent)}
.band-sep{color:var(--border);font-size:1.2rem}
@keyframes marquee{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* ── HOME - latest releases preview ── */
.latest-grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));
  gap:1.5rem;margin-top:3rem;
}
.latest-card{
  cursor:pointer;
  background:var(--s1);border:1px solid var(--border);border-radius:4px;
  overflow:hidden;transition:transform .3s,border-color .3s;
}
.latest-card:hover{transform:translateY(-6px);border-color:rgba(200,150,62,.3)}
.latest-card img{width:100%;aspect-ratio:1;object-fit:cover;filter:brightness(.9)}
.latest-card:hover img{filter:brightness(1)}
.latest-card-body{padding:.85rem 1rem}
.latest-card-year{font-size:.65rem;color:var(--accent);letter-spacing:.12em;text-transform:uppercase;margin-bottom:.3rem}
.latest-card-title{font-size:.82rem;font-weight:600;color:#fff;line-height:1.3}
.latest-card-artist{font-size:.72rem;color:var(--muted);margin-top:.2rem}

/* ── DISCOGRAPHY PAGE ── */
.disco-header{padding:4rem 0 2rem;text-align:center}
.disco-filter{
  display:flex;gap:.5rem;justify-content:center;flex-wrap:wrap;
  margin-top:2rem;
}
.filter-btn{
  font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;
  padding:.4rem 1rem;border:1px solid var(--border);border-radius:20px;
  color:var(--muted);transition:all .2s;
}
.filter-btn:hover,.filter-btn.active{border-color:var(--accent);color:var(--accent);background:var(--accent-glow)}
.disco-grid{
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(220px,1fr));
  gap:2px;margin:2rem 0;
}
.disco-card{
  position:relative;cursor:pointer;overflow:hidden;aspect-ratio:1;
  background:var(--s1);
}
.disco-card img{
  width:100%;height:100%;object-fit:cover;
  transition:transform .5s ease,filter .5s ease;
  filter:brightness(.8) saturate(.85);
}
.disco-card:hover img{transform:scale(1.06);filter:brightness(.55) saturate(.7)}
.disco-card-overlay{
  position:absolute;inset:0;padding:1.5rem;
  display:flex;flex-direction:column;justify-content:flex-end;
  background:linear-gradient(to top,rgba(0,0,0,.85) 0%,transparent 50%);
  opacity:0;transition:opacity .35s;
}
.disco-card:hover .disco-card-overlay,.disco-card-overlay.show{opacity:1}
.disco-card-year{font-size:.62rem;color:var(--accent);letter-spacing:.14em;text-transform:uppercase;margin-bottom:.3rem}
.disco-card-title{font-family:'Playfair Display',serif;font-size:1rem;font-weight:700;color:#fff;line-height:1.2}
.disco-card-artist{font-size:.72rem;color:rgba(255,255,255,.6);margin-top:.2rem}
.disco-card-role{
  position:absolute;top:1rem;right:1rem;
  font-size:.58rem;letter-spacing:.1em;text-transform:uppercase;
  background:rgba(200,150,62,.9);color:#000;
  padding:.2rem .5rem;border-radius:2px;font-weight:700;
  opacity:0;transition:opacity .35s;
}
.disco-card:hover .disco-card-role{opacity:1}
.disco-card-yt{
  display:inline-flex;align-items:center;gap:.4rem;margin-top:.6rem;
  font-size:.68rem;color:var(--accent);
}

/* ── ALBUM MODAL ── */
#album-modal{
  display:none;position:fixed;inset:0;z-index:2000;
  background:rgba(0,0,0,.85);backdrop-filter:blur(12px);
  align-items:center;justify-content:center;padding:2rem;
}
#album-modal.open{display:flex}
.album-modal-inner{
  background:var(--s1);border:1px solid var(--border);border-radius:8px;
  max-width:640px;width:100%;display:flex;gap:0;overflow:hidden;
  max-height:90vh;
}
.album-modal-img{width:240px;min-width:240px;object-fit:cover;flex-shrink:0}
.album-modal-body{padding:2rem;overflow-y:auto;flex:1}
.album-modal-artist{font-size:.65rem;color:var(--accent);letter-spacing:.2em;text-transform:uppercase;margin-bottom:.5rem}
.album-modal-title{font-family:'Playfair Display',serif;font-size:1.5rem;font-weight:700;color:#fff;line-height:1.2;margin-bottom:1.2rem}
.album-modal-meta{display:flex;flex-direction:column;gap:.5rem;margin-bottom:1.5rem}
.album-modal-meta-row{display:flex;gap:.5rem;font-size:.78rem}
.album-modal-meta-key{color:var(--muted);min-width:80px}
.album-modal-meta-val{color:var(--text)}
.album-modal-close{
  position:absolute;top:1rem;right:1rem;
  width:36px;height:36px;border-radius:50%;
  background:var(--s2);border:1px solid var(--border);
  display:flex;align-items:center;justify-content:center;
  font-size:1.2rem;color:var(--muted);cursor:pointer;
  transition:background .2s,color .2s;
}
.album-modal-close:hover{background:var(--s3);color:#fff}
@media(max-width:540px){.album-modal-inner{flex-direction:column}.album-modal-img{width:100%;min-width:0;max-height:240px}}

/* ── STUDIO PAGE ── */
.studio-page .page-hero{
  height:60vh;min-height:360px;
  position:relative;display:flex;align-items:flex-end;justify-content:flex-start;
  overflow:hidden;
}
.studio-page .page-hero img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  filter:brightness(.45) saturate(.8);
}
.studio-page .page-hero-text{
  position:relative;z-index:2;padding:3rem 2.5rem;
  background:linear-gradient(to right,rgba(12,12,12,.9),transparent);
}

/* ── ABOUT PAGE ── */
.about-layout{
  display:grid;grid-template-columns:1fr 1.6fr;gap:5rem;
  align-items:start;padding:4rem 0;
}
@media(max-width:768px){.about-layout{grid-template-columns:1fr;gap:3rem}}
.about-img-wrap{position:relative}
.about-img-wrap img{width:100%;border-radius:4px;filter:brightness(.9) contrast(1.05)}
.about-img-caption{
  position:absolute;bottom:0;left:0;right:0;
  padding:1rem 1.2rem;
  background:linear-gradient(to top,rgba(0,0,0,.8),transparent);
  font-size:.65rem;letter-spacing:.18em;text-transform:uppercase;color:var(--muted);
}

/* ── GALLERY PAGE ── */
.gallery-tabs{display:flex;gap:.5rem;margin-bottom:2rem;flex-wrap:wrap}
.gallery-tab{
  font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;
  padding:.5rem 1.2rem;border:1px solid var(--border);border-radius:2px;
  color:var(--muted);transition:all .2s;
}
.gallery-tab.active,.gallery-tab:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-glow)}
.gallery-masonry{
  columns:3 220px;column-gap:6px;
}
@media(max-width:500px){.gallery-masonry{columns:2 140px}}
.gallery-item{
  break-inside:avoid;margin-bottom:6px;cursor:pointer;overflow:hidden;border-radius:2px;
  position:relative;
}
.gallery-item img{
  width:100%;display:block;
  transition:transform .4s,filter .4s;
  filter:brightness(.85) saturate(.9);
}
.gallery-item:hover img{transform:scale(1.04);filter:brightness(1) saturate(1)}

/* ── LIGHTBOX ── */
#lightbox{
  display:none;position:fixed;inset:0;z-index:3000;
  background:rgba(0,0,0,.95);
  align-items:center;justify-content:center;
}
#lightbox.open{display:flex}
#lightbox-img{max-width:90vw;max-height:90vh;object-fit:contain;border-radius:2px}
.lb-close{
  position:absolute;top:1.5rem;right:1.5rem;
  font-size:2rem;color:var(--muted);cursor:pointer;
  transition:color .2s;line-height:1;
}
.lb-close:hover{color:#fff}
.lb-prev,.lb-next{
  position:absolute;top:50%;transform:translateY(-50%);
  font-size:2rem;color:var(--muted);cursor:pointer;
  padding:.5rem 1rem;transition:color .2s;
  background:none;user-select:none;
}
.lb-prev:hover,.lb-next:hover{color:var(--accent)}
.lb-prev{left:1rem}.lb-next{right:1rem}

/* ── BLOG PAGE ── */
.blog-list{padding:4rem 0}
.blog-item{
  border-bottom:1px solid var(--border);
  padding:2rem 0;display:flex;gap:3rem;align-items:baseline;
  transition:background .2s;cursor:pointer;
}
.blog-item:hover .blog-item-title{color:var(--accent)}
.blog-item-date{
  font-size:.68rem;color:var(--muted);letter-spacing:.1em;
  white-space:nowrap;min-width:90px;
}
.blog-item-content{flex:1}
.blog-item-cats{
  display:flex;gap:.4rem;flex-wrap:wrap;margin-bottom:.5rem;
}
.blog-cat{
  font-size:.58rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--accent);border:1px solid rgba(200,150,62,.25);
  padding:.1rem .4rem;border-radius:2px;
}
.blog-item-title{
  font-family:'Playfair Display',serif;
  font-size:1.25rem;font-weight:700;color:#fff;
  transition:color .2s;line-height:1.3;
}
.blog-item-arrow{color:var(--muted);font-size:1.2rem;transition:transform .2s,color .2s}
.blog-item:hover .blog-item-arrow{transform:translateX(4px);color:var(--accent)}

/* ── BLOG SINGLE ── */
.blog-single{padding:4rem 0;max-width:740px;margin:0 auto}
.blog-back{
  font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted);display:inline-flex;align-items:center;gap:.4rem;
  margin-bottom:2rem;cursor:pointer;transition:color .2s;
}
.blog-back:hover{color:var(--accent)}
.blog-single-title{
  font-family:'Playfair Display',serif;
  font-size:clamp(1.8rem,4vw,2.8rem);font-weight:700;color:#fff;
  line-height:1.2;margin-bottom:1rem;
}
.blog-single-meta{
  font-size:.72rem;color:var(--muted);margin-bottom:3rem;
  padding-bottom:1.5rem;border-bottom:1px solid var(--border);
}
.blog-content{font-size:1rem;line-height:1.85;color:var(--text)}
.blog-content h1,.blog-content h2,.blog-content h3{
  font-family:'Playfair Display',serif;color:#fff;margin:2rem 0 .8rem;
}
.blog-content p{margin-bottom:1.2rem}
.blog-content a{color:var(--accent);text-decoration:underline}
.blog-content img{max-width:100%;border-radius:4px;margin:1.5rem 0}
.blog-content ul,.blog-content ol{padding-left:1.5rem;margin-bottom:1.2rem}
.blog-content li{margin-bottom:.4rem}
.blog-content code{background:var(--s2);padding:.1rem .4rem;border-radius:3px;font-size:.88em}
.blog-content pre{background:var(--s2);padding:1.2rem;border-radius:4px;overflow-x:auto;margin-bottom:1.2rem}
.blog-content blockquote{border-left:3px solid var(--accent);padding-left:1.5rem;color:var(--muted);font-style:italic;margin-bottom:1.2rem}
.blog-content iframe{max-width:100%;border-radius:4px;margin:1.5rem 0}

/* ── CONTACT PAGE ── */
.contact-layout{
  display:grid;grid-template-columns:1fr 1.2fr;gap:5rem;
  padding:4rem 0;align-items:start;
}
@media(max-width:768px){.contact-layout{grid-template-columns:1fr;gap:3rem}}
.contact-info-item{display:flex;gap:1rem;margin-bottom:2rem;align-items:flex-start}
.contact-icon{
  width:40px;height:40px;border-radius:4px;
  background:var(--accent-glow);border:1px solid rgba(200,150,62,.25);
  display:flex;align-items:center;justify-content:center;
  font-size:1.1rem;flex-shrink:0;
}
.contact-info-label{font-size:.65rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);margin-bottom:.2rem}
.contact-info-val{font-size:.95rem;color:var(--text)}
.contact-form{background:var(--s1);border:1px solid var(--border);border-radius:6px;padding:2rem}
.form-group{margin-bottom:1.5rem}
.form-label{font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);display:block;margin-bottom:.5rem}
.form-input,.form-textarea{
  width:100%;background:var(--s2);border:1px solid var(--border);
  border-radius:4px;padding:.75rem 1rem;
  color:var(--text);font-family:inherit;font-size:.9rem;
  transition:border-color .2s;resize:none;
}
.form-input:focus,.form-textarea:focus{outline:none;border-color:var(--accent)}
.form-textarea{min-height:140px}
.form-submit{width:100%}

/* ── SHOP PAGE ── */
.shop-coming{
  min-height:60vh;display:flex;flex-direction:column;
  align-items:center;justify-content:center;text-align:center;gap:1.5rem;
}
.shop-coming-icon{font-size:3rem;opacity:.3}
.shop-coming h2{font-family:'Playfair Display',serif;font-size:2rem;color:var(--muted)}
.shop-coming p{color:var(--muted);font-size:.9rem}

/* ── APPS PAGE ── */
.apps-page{padding:3rem 0 4rem}

/* ── ADMIN ── */
#admin-page{padding:calc(var(--nav-h) + 2rem) 2rem 4rem;min-height:100vh;background:var(--bg)}
.admin-login{
  max-width:380px;margin:4rem auto;
  background:var(--s1);border:1px solid var(--border);
  border-radius:8px;padding:2.5rem;
}
.admin-login h2{
  font-family:'Playfair Display',serif;font-size:1.5rem;
  color:#fff;margin-bottom:1.8rem;text-align:center;
}
.admin-panel{display:none}
.admin-panel.active{display:block}
.admin-section-title{
  font-family:'Playfair Display',serif;font-size:1.4rem;color:#fff;
  border-bottom:1px solid var(--border);padding-bottom:1rem;margin:2rem 0 1.5rem;
}
.admin-tabs{display:flex;gap:.5rem;margin-bottom:2rem;flex-wrap:wrap}
.admin-tab{
  font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;
  padding:.5rem 1.2rem;border:1px solid var(--border);border-radius:3px;
  color:var(--muted);transition:all .2s;
}
.admin-tab.active,.admin-tab:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-glow)}
.admin-album-grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:1rem;
  margin-bottom:2rem;
}
.admin-album-card{
  background:var(--s1);border:1px solid var(--border);border-radius:4px;overflow:hidden;
  position:relative;
}
.admin-album-card img{width:100%;aspect-ratio:1;object-fit:cover}
.admin-album-card-body{padding:.7rem .8rem}
.admin-album-card-title{font-size:.78rem;font-weight:600;color:#fff;line-height:1.3}
.admin-album-card-year{font-size:.65rem;color:var(--accent);margin-top:.2rem}
.admin-album-actions{
  display:flex;gap:.4rem;padding:.5rem .8rem;
  border-top:1px solid var(--border);
}
.admin-btn-edit,.admin-btn-delete{
  font-size:.65rem;letter-spacing:.1em;text-transform:uppercase;
  padding:.3rem .7rem;border:1px solid var(--border);border-radius:3px;
  transition:all .2s;
}
.admin-btn-edit{color:var(--accent);border-color:rgba(200,150,62,.3)}
.admin-btn-edit:hover{background:var(--accent-glow)}
.admin-btn-delete{color:#e06060;border-color:rgba(200,80,80,.25)}
.admin-btn-delete:hover{background:rgba(200,80,80,.1)}
.admin-btn-add{
  display:inline-flex;align-items:center;gap:.4rem;
  font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;
  padding:.55rem 1.2rem;background:var(--accent);color:#000;
  border-radius:3px;font-weight:700;transition:background .2s;
  margin-bottom:1.5rem;
}
.admin-btn-add:hover{background:var(--accent-light)}
.admin-logout{
  float:right;font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--muted);border:1px solid var(--border);padding:.4rem .9rem;border-radius:3px;
  transition:all .2s;
}
.admin-logout:hover{color:#fff;border-color:rgba(255,255,255,.3)}

/* ── MODAL FORM ── */
#form-modal{
  display:none;position:fixed;inset:0;z-index:4000;
  background:rgba(0,0,0,.85);align-items:center;justify-content:center;padding:2rem;
}
#form-modal.open{display:flex}
.form-modal-inner{
  background:var(--s1);border:1px solid var(--border);border-radius:8px;
  max-width:520px;width:100%;padding:2rem;max-height:90vh;overflow-y:auto;
  position:relative;
}
.form-modal-title{font-family:'Playfair Display',serif;font-size:1.3rem;color:#fff;margin-bottom:1.5rem}
.form-modal-close{
  position:absolute;top:1rem;right:1rem;
  font-size:1.5rem;color:var(--muted);cursor:pointer;transition:color .2s;
}
.form-modal-close:hover{color:#fff}

/* ── FOOTER ── */
footer{
  border-top:1px solid var(--border);
  padding:3rem 2rem;text-align:center;
}
.footer-logo{
  font-family:'Playfair Display',serif;font-size:1.2rem;
  font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted);margin-bottom:1rem;
}
.footer-logo span{color:var(--accent)}
.footer-tagline{font-size:.7rem;letter-spacing:.18em;text-transform:uppercase;color:var(--muted);margin-bottom:1.5rem}
.footer-links{display:flex;gap:2rem;justify-content:center;flex-wrap:wrap;margin-bottom:1.5rem}
.footer-links a{font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);transition:color .2s}
.footer-links a:hover{color:var(--accent)}
.footer-copy{font-size:.65rem;color:rgba(112,110,105,.5)}

/* ── UTIL ── */
.page-header{padding:4rem 0 2rem}
.page-header .section-eyebrow{margin-bottom:.6rem}
.divider{height:1px;background:var(--border);margin:3rem 0}
.tag{
  display:inline-block;font-size:.65rem;letter-spacing:.1em;text-transform:uppercase;
  background:var(--s2);border:1px solid var(--border);border-radius:3px;
  padding:.2rem .6rem;color:var(--muted);
}
.tag.gold{background:var(--accent-glow);border-color:rgba(200,150,62,.3);color:var(--accent)}

/* ── ALERT ── */
.alert{
  padding:.8rem 1.2rem;border-radius:4px;font-size:.8rem;
  margin-bottom:1rem;display:none;
}
.alert.show{display:block}
.alert-success{background:rgba(60,160,80,.12);border:1px solid rgba(60,160,80,.3);color:#6fca83}
.alert-error{background:rgba(200,60,60,.1);border:1px solid rgba(200,60,60,.25);color:#e08080}

/* ── GALLERY ADMIN ── */
.admin-gallery-grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:8px;
  margin-bottom:2rem;
}
.admin-gallery-item{
  position:relative;aspect-ratio:1;overflow:hidden;border-radius:3px;cursor:pointer;
  background:var(--s2);
}
.admin-gallery-item img{width:100%;height:100%;object-fit:cover;transition:filter .2s}
.admin-gallery-item:hover img{filter:brightness(.6)}
.admin-gallery-del{
  position:absolute;top:4px;right:4px;
  width:22px;height:22px;border-radius:50%;
  background:rgba(200,60,60,.85);color:#fff;
  font-size:.9rem;display:flex;align-items:center;justify-content:center;
  opacity:0;transition:opacity .2s;
}
.admin-gallery-item:hover .admin-gallery-del{opacity:1}
</style>
</head>
<body>
<!-- NAV -->
<nav id="nav">
  <div class="nav-logo" onclick="navigate('/')">Paolo <span>Campitelli</span></div>
  <ul class="nav-links" id="nav-links">
    <li><a href="/#/" href="/#/" onclick="navigate('/');return false">Home</a></li>
    <li><a href="/#/" href="/#/about" onclick="navigate('/about');return false">About</a></li>
    <li><a href="/#/" href="/#/discography" onclick="navigate('/discography');return false">Discography</a></li>
    <li><a href="/#/" href="/#/studio" onclick="navigate('/studio');return false">Studio</a></li>
    <li><a href="/#/" href="/#/gallery" onclick="navigate('/gallery');return false">Gallery</a></li>
    <li><a href="/#/" href="/#/apps" onclick="navigate('/apps');return false">Apps</a></li>
    <li><a href="/#/" href="/#/blog" onclick="navigate('/blog');return false">Blog</a></li>
    <li><a href="/#/" href="/#/contact" onclick="navigate('/contact');return false">Contact</a></li>
  </ul>
  <div class="nav-social">
    <a href="https://www.instagram.com/paolocampitelli/" target="_blank" rel="noopener" title="Instagram">
      <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z"/></svg>
    </a>
    <a href="https://www.facebook.com/PaoloCampitelliOfficial" target="_blank" rel="noopener" title="Facebook">
      <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/></svg>
    </a>
    <a href="https://www.linkedin.com/in/paolocampitelli84" target="_blank" rel="noopener" title="LinkedIn">
      <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>
    </a>
    <a href="https://www.youtube.com/@Paolocampitelli" target="_blank" rel="noopener" title="YouTube">
      <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>
    </a>
  </div>
  <button class="nav-hamburger" id="hamburger" onclick="toggleMenu()">
    <span></span><span></span><span></span>
  </button>
</nav>

<!-- HOME PAGE -->
<div class="page active" id="page-home">
  <!-- HERO -->
  <section id="hero">
    <canvas id="hero-canvas"></canvas>
    <div class="hero-fallback" id="hero-fallback"></div>
    <div class="hero-content">
      <div class="hero-eyebrow">Rome, Italy &nbsp;·&nbsp; Warlord Sound Studios</div>
      <h1 class="hero-name">PAOLO<br><span class="surname">CAMPITELLI</span></h1>
      <p class="hero-sub">Multi-Instrumentalist &nbsp;·&nbsp; Sound Engineer &amp; Producer &nbsp;·&nbsp; Computer Engineer</p>
      <div class="hero-cta">
        <button class="btn btn-primary" onclick="navigate('/discography')">Discography</button>
        <button class="btn btn-ghost" onclick="navigate('/studio')">Warlord Sound Studios</button>
      </div>
    </div>
    <div class="hero-scroll">
      <span>Scroll</span>
      <div class="hero-scroll-line"></div>
    </div>
  </section>

  <!-- BAND STRIP -->
  <div class="band-strip">
    <div class="band-strip-inner" id="band-strip">
      <span class="band-name-item active">Alterium</span>
      <span class="band-sep">·</span>
      <span class="band-name-item active">ScreaMachine</span>
      <span class="band-sep">·</span>
      <span class="band-name-item active">Noveria</span>
      <span class="band-sep">·</span>
      <span class="band-name-item">Kaledon (former)</span>
      <span class="band-sep">·</span>
      <span class="band-name-item">Warlord Sound Studios</span>
      <span class="band-sep">·</span>
      <span class="band-name-item active">Alterium</span>
      <span class="band-sep">·</span>
      <span class="band-name-item active">ScreaMachine</span>
      <span class="band-sep">·</span>
      <span class="band-name-item active">Noveria</span>
      <span class="band-sep">·</span>
      <span class="band-name-item">Kaledon (former)</span>
      <span class="band-sep">·</span>
      <span class="band-name-item">Warlord Sound Studios</span>
      <span class="band-sep">·</span>
    </div>
  </div>

  <!-- HOME CONTENT -->
  <section class="home-section">
    <div class="container">
      <div style="display:grid;grid-template-columns:1fr 1fr;gap:4rem;align-items:center" class="reveal">
        <div>
          <div class="section-eyebrow">Latest Releases</div>
          <h2 class="section-title">22 Albums.<br>One Vision.</h2>
          <p class="section-sub">From power metal to progressive rock - producer, arranger and musician on over two decades of recordings.</p>
          <div style="margin-top:2rem">
            <button class="btn btn-ghost" onclick="navigate('/discography')">View All Releases →</button>
          </div>
        </div>
        <div id="home-latest-grid" class="latest-grid"></div>
      </div>
    </div>
  </section>

  <!-- STUDIO TEASER -->
  <section class="home-section" style="background:var(--s1);border-top:1px solid var(--border);border-bottom:1px solid var(--border)">
    <div class="container">
      <div style="display:grid;grid-template-columns:1.2fr 1fr;gap:4rem;align-items:center">
        <div class="reveal">
          <img src="assets/images/2025/10/05569F9E-B0D2-4C04-BC99-28B7A0C73246-scaled.jpeg"
            alt="Warlord Sound Studios" style="width:100%;border-radius:4px;filter:brightness(.85) contrast(1.05)">
        </div>
        <div class="reveal reveal-delay-1">
          <div class="section-eyebrow">Rome, Italy</div>
          <h2 class="section-title">Warlord<br>Sound Studios</h2>
          <p class="section-sub">A professional recording facility equipped for heavy music - from tracking to mix, mastering and beyond.</p>
          <div style="margin-top:1.5rem;display:flex;gap:.5rem;flex-wrap:wrap">
            <span class="tag gold">Logic Pro</span>
            <span class="tag">UA Apollo</span>
            <span class="tag">Kemper</span>
            <span class="tag">Neve 1073</span>
            <span class="tag">Peavey 6505</span>
            <span class="tag">Mesa Boogie</span>
          </div>
          <div style="margin-top:2rem">
            <button class="btn btn-ghost" onclick="navigate('/studio')">Explore the Studio →</button>
          </div>
        </div>
      </div>
    </div>
  </section>

  <!-- BANDS TEASER -->
  <section class="home-section">
    <div class="container" style="text-align:center">
      <div class="reveal">
        <div class="section-eyebrow" style="justify-content:center">Bands &amp; Projects</div>
        <h2 class="section-title" style="max-width:600px;margin:0 auto 1.5rem">Multi-Instrumentalist.<br>Multiple Bands.</h2>
        <p class="section-sub" style="margin:0 auto 3rem">Guitar, keys, bass, drums - Paolo plays them all. Currently active in Alterium (AFM Records), ScreaMachine (Frontiers Records) and Noveria (Scarlet Records).</p>
      </div>
      <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:1rem;max-width:900px;margin:0 auto">
        <div class="reveal" style="background:var(--s1);border:1px solid var(--border);border-radius:4px;padding:1.5rem;text-align:left">
          <div class="tag gold" style="margin-bottom:.8rem">Active</div>
          <div style="font-family:'Playfair Display',serif;font-size:1.3rem;font-weight:700;color:#fff;margin-bottom:.3rem">Alterium</div>
          <div style="font-size:.75rem;color:var(--muted)">Guitar · Production<br>AFM Records</div>
        </div>
        <div class="reveal reveal-delay-1" style="background:var(--s1);border:1px solid var(--border);border-radius:4px;padding:1.5rem;text-align:left">
          <div class="tag gold" style="margin-bottom:.8rem">Active</div>
          <div style="font-family:'Playfair Display',serif;font-size:1.3rem;font-weight:700;color:#fff;margin-bottom:.3rem">ScreaMachine</div>
          <div style="font-size:.75rem;color:var(--muted)">Guitar · Production<br>Frontiers Records</div>
        </div>
        <div class="reveal reveal-delay-2" style="background:var(--s1);border:1px solid var(--border);border-radius:4px;padding:1.5rem;text-align:left">
          <div class="tag gold" style="margin-bottom:.8rem">Since 2025</div>
          <div style="font-family:'Playfair Display',serif;font-size:1.3rem;font-weight:700;color:#fff;margin-bottom:.3rem">Noveria</div>
          <div style="font-size:.75rem;color:var(--muted)">Keyboard Player<br>Scarlet Records</div>
        </div>
        <div class="reveal reveal-delay-3" style="background:var(--s1);border:1px solid var(--border);border-radius:4px;padding:1.5rem;text-align:left;opacity:.6">
          <div class="tag" style="margin-bottom:.8rem">2013–2023</div>
          <div style="font-family:'Playfair Display',serif;font-size:1.3rem;font-weight:700;color:#fff;margin-bottom:.3rem">Kaledon</div>
          <div style="font-size:.75rem;color:var(--muted)">Keyboard Player · Former</div>
        </div>
      </div>
    </div>
  </section>

  <footer>
    <div class="footer-logo">Paolo <span>Campitelli</span></div>
    <div class="footer-tagline">Producer · Multi-Instrumentalist · Sound Engineer · Rome, Italy</div>
    <div class="footer-links">
      <a href="/#/" href="/#/about" onclick="navigate('/about');return false">About</a>
      <a href="/#/" href="/#/discography" onclick="navigate('/discography');return false">Discography</a>
      <a href="/#/" href="/#/studio" onclick="navigate('/studio');return false">Studio</a>
      <a href="/#/" href="/#/gallery" onclick="navigate('/gallery');return false">Gallery</a>
      <a href="/#/" href="/#/blog" onclick="navigate('/blog');return false">Blog</a>
      <a href="/#/" href="/#/contact" onclick="navigate('/contact');return false">Contact</a>
      <a href="login.php">Admin</a>
    </div>
    <div class="footer-copy">© 2026 Paolo Campitelli. All rights reserved.</div>
  </footer>
</div>

<!-- ABOUT PAGE -->
<div class="page" id="page-about">
<nav id="nav-about" style="display:none"></nav>
<div class="container">
  <div class="page-header reveal">
    <div class="section-eyebrow">About</div>
    <h1 class="section-title">Paolo Campitelli</h1>
    <p class="section-sub">Rome-based musician, producer and sound engineer with over 20 years of experience in heavy music.</p>
  </div>
  <div class="about-layout">
    <div class="about-img-wrap reveal">
      <img src="assets/images/2025/10/05569F9E-B0D2-4C04-BC99-28B7A0C73246-scaled.jpeg"
        alt="Paolo Campitelli" loading="lazy">
      <div class="about-img-caption">Paolo Campitelli · Rome, Italy</div>
    </div>
    <div class="reveal reveal-delay-1">
      <div id="wss-bio">
<style scoped>
#wss-bio *{box-sizing:border-box;margin:0;padding:0}
#wss-bio{--bg:#0c0c0c;--s1:#141414;--s2:#1c1c1c;--s3:#242424;--border:rgba(255,255,255,0.07);--text:#dedad4;--muted:#706e69;--accent:#c8963e;--accent-glow:rgba(200,150,62,0.15);--radius:6px;background:var(--bg);color:var(--text);border-radius:10px;overflow:hidden;font-family:'Inter',system-ui,sans-serif;font-size:15px;line-height:1.6;padding:2rem 0}
.bio-section-label{font-size:.72rem;letter-spacing:.25em;text-transform:uppercase;color:var(--accent);font-weight:600;margin-top:2.5rem;margin-bottom:1rem;display:flex;align-items:center;gap:.8rem}
.bio-section-label::after{content:'';flex:1;height:1px;background:rgba(200,150,62,.25)}
.bio-roles{display:flex;flex-wrap:wrap;gap:.4rem;list-style:none;margin-bottom:3.5rem}
.bio-role{font-size:.78rem;font-weight:600;background:var(--s1);border:1px solid var(--border);border-radius:20px;padding:.3rem .85rem;color:var(--text);transition:background .18s,border-color .18s}
.bio-role:hover{background:var(--s3);border-color:rgba(200,150,62,.3);color:#fff}
.bio-role.highlight{background:var(--accent-glow);border-color:rgba(200,150,62,.35);color:var(--accent)}
.bio-expertise{display:flex;flex-wrap:wrap;gap:.35rem;list-style:none;margin-bottom:3.5rem}
.bio-exp{font-size:.72rem;background:var(--s1);border:1px solid var(--border);border-radius:4px;padding:.25rem .7rem;color:var(--text);transition:background .18s,border-color .18s}
.bio-exp:hover{background:var(--s3);border-color:rgba(200,150,62,.3);color:#fff}
.bio-exp.key{background:var(--accent-glow);border-color:rgba(200,150,62,.3);color:var(--accent)}
.bio-pillars{display:grid;grid-template-columns:1fr 1fr;gap:.75rem;margin-bottom:3.5rem}
@media(max-width:560px){.bio-pillars{grid-template-columns:1fr}}
.bio-pillar{background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);padding:.9rem 1rem;transition:border-color .2s}
.bio-pillar:hover{border-color:rgba(200,150,62,.25)}
.bio-pillar-icon{font-size:1.1rem;margin-bottom:.4rem;display:block}
.bio-pillar-title{font-size:.72rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--accent);margin-bottom:.2rem}
.bio-pillar-sub{font-size:.72rem;color:var(--muted);line-height:1.4}
.bio-pillar-sub em{color:var(--text);font-style:normal}
.bio-bands{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:.75rem}
.bio-band{background:var(--s1);border:1px solid var(--border);border-radius:var(--radius);padding:1rem 1rem .9rem;position:relative;overflow:hidden;transition:border-color .2s,background .2s}
.bio-band:hover{background:var(--s2);border-color:rgba(200,150,62,.3)}
.bio-band-badge{position:absolute;top:.55rem;right:.6rem;font-size:.55rem;letter-spacing:.12em;text-transform:uppercase;border-radius:3px;padding:.1rem .4rem}
.bio-band-badge.new{color:var(--accent);background:var(--accent-glow);border:1px solid rgba(200,150,62,.3)}
.bio-band-badge.former{color:var(--muted);background:rgba(255,255,255,0.04);border:1px solid rgba(255,255,255,0.09)}
.bio-band.is-former{opacity:.7}
.bio-band.is-former:hover{opacity:1}
.bio-band-name{font-size:1rem;font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:#fff;margin-bottom:.3rem}
.bio-band-role{font-size:.68rem;color:var(--muted)}
.bio-band-role strong{color:var(--text);font-weight:500}
</style>
<div class="bio-section-label">Roles</div>
<ul class="bio-roles">
  <li class="bio-role">Multi-Instrumentalist</li>
  <li class="bio-role">Piano &amp; Keyboards</li>
  <li class="bio-role">Guitar &amp; Bass</li>
  <li class="bio-role">Drums</li>
  <li class="bio-role">Composer</li>
  <li class="bio-role">Sound Engineer</li>
  <li class="bio-role">FOH Engineer</li>
  <li class="bio-role">Producer</li>
</ul>
<div class="bio-section-label" style="margin-top:3.5rem">Expertise</div>
<ul class="bio-expertise">
  <li class="bio-exp">Recording</li>
  <li class="bio-exp">Mixing</li>
  <li class="bio-exp">Mastering</li>
  <li class="bio-exp">Orchestral Score Writing</li>
  <li class="bio-exp">Live Sound (FOH)</li>
  <li class="bio-exp">Music Production</li>
  <li class="bio-exp">Arrangement</li>
  <li class="bio-exp">Audio Post-Production</li>
  <li class="bio-exp">And much more...</li>
</ul>
<div class="bio-section-label" style="margin-top:3.5rem">Background</div>
<div class="bio-pillars">
  <div class="bio-pillar"><span class="bio-pillar-icon">🎓</span><div class="bio-pillar-title">Computer Engineer</div><div class="bio-pillar-sub">Since <em>2011</em></div></div>
  <div class="bio-pillar"><span class="bio-pillar-icon">💻</span><div class="bio-pillar-title">Product Manager &amp; Developer</div><div class="bio-pillar-sub">Freelance <em>iOS &amp; macOS</em> developer</div></div>
</div>
<div class="bio-section-label" style="margin-top:3.5rem">Official Bands</div>
<div class="bio-bands">
  <div class="bio-band"><div class="bio-band-name">Alterium</div><div class="bio-band-role"><strong>Guitar Player</strong> &amp; <strong>Producer</strong><br><span style="font-size:.62rem;color:var(--accent)">AFM Records</span></div></div>
  <div class="bio-band"><div class="bio-band-name">ScreaMachine</div><div class="bio-band-role"><strong>Guitar Player</strong> &amp; <strong>Producer</strong><br><span style="font-size:.62rem;color:var(--accent)">Frontiers Records</span></div></div>
  <div class="bio-band"><div class="bio-band-badge former">Since 2025</div><div class="bio-band-name">Noveria</div><div class="bio-band-role"><strong>Keyboard Player</strong><br><span style="font-size:.62rem;color:var(--accent)">Scarlet Records</span></div></div>
  <div class="bio-band is-former"><div class="bio-band-badge former">2013–2023</div><div class="bio-band-name">Kaledon</div><div class="bio-band-role"><strong>Keyboard Player</strong> - Former<br><span style="font-size:.62rem;color:var(--accent)">Scarlet Records &amp; Sleazy Records</span></div></div>
</div>
      </div>
    </div>
  </div>
</div>
<footer>
  <div class="footer-logo">Paolo <span>Campitelli</span></div>
  <div class="footer-tagline">Producer · Multi-Instrumentalist · Sound Engineer · Rome, Italy</div>
  <div class="footer-links">
    <a href="/#/" href="/#/discography" onclick="navigate('/discography');return false">Discography</a>
    <a href="/#/" href="/#/studio" onclick="navigate('/studio');return false">Studio</a>
    <a href="/#/" href="/#/contact" onclick="navigate('/contact');return false">Contact</a>
  </div>
  <div class="footer-copy">© 2026 Paolo Campitelli. All rights reserved.</div>
</footer>
</div>

<!-- DISCOGRAPHY PAGE -->
<div class="page" id="page-discography">
<div class="container">
  <div class="disco-header reveal">
    <div class="section-eyebrow" style="justify-content:center">Portfolio</div>
    <h1 class="section-title">Discography</h1>
    <p class="section-sub" style="margin:0 auto">22 albums - as musician, producer, arranger and sound engineer.</p>
    <div class="disco-filter" id="disco-filter">
      <button class="filter-btn active" data-filter="all">All</button>
      <button class="filter-btn" data-filter="producer">Producer</button>
      <button class="filter-btn" data-filter="screamachine">ScreaMachine</button>
      <button class="filter-btn" data-filter="kaledon">Kaledon</button>
      <button class="filter-btn" data-filter="alterium">Alterium</button>
    </div>
  </div>
</div>
<div id="disco-grid" class="disco-grid"></div>
<!-- Album Modal -->
<div id="album-modal">
  <div style="position:relative">
    <button class="album-modal-close" onclick="closeAlbumModal()">×</button>
    <div class="album-modal-inner">
      <img id="modal-img" class="album-modal-img" src="" alt="">
      <div class="album-modal-body">
        <div id="modal-artist" class="album-modal-artist"></div>
        <div id="modal-title" class="album-modal-title"></div>
        <div class="album-modal-meta" id="modal-meta"></div>
        <div id="modal-yt"></div>
      </div>
    </div>
  </div>
</div>
</div>

<!-- STUDIO PAGE -->
<div class="page studio-page" id="page-studio">
<div class="page-hero">
  <img src="assets/images/2025/10/05569F9E-B0D2-4C04-BC99-28B7A0C73246-scaled.jpeg" alt="Warlord Sound Studios" loading="eager">
  <div class="page-hero-text">
    <div class="section-eyebrow">Rome, Italy</div>
    <h1 class="section-title" style="font-size:clamp(2rem,5vw,3.5rem)">Warlord<br>Sound Studios</h1>
  </div>
</div>
<div class="container" style="padding-top:3rem;padding-bottom:4rem">
  <div id="studio-content"></div>
</div>
<footer>
  <div class="footer-logo">Paolo <span>Campitelli</span></div>
  <div class="footer-tagline">Recording · Mixing · Production · Rome, Italy</div>
  <div class="footer-copy">© 2026 Paolo Campitelli. All rights reserved.</div>
</footer>
</div>

<!-- GALLERY PAGE -->
<div class="page" id="page-gallery">
<div class="container">
  <div class="page-header reveal">
    <div class="section-eyebrow">Photos</div>
    <h1 class="section-title">Gallery</h1>
    <p style="color:var(--muted);font-size:.9rem;margin-bottom:2rem">Select a collection</p>
    <div id="gallery-cards" style="display:grid;grid-template-columns:repeat(3,1fr);gap:1rem;margin-bottom:2.5rem">
      <!-- rendered by JS -->
    </div>
  </div>
  <div id="gallery-grid" class="gallery-masonry"></div>
</div>
<div id="lightbox">
  <span class="lb-close" onclick="closeLightbox()">×</span>
  <button class="lb-prev" onclick="lbNav(-1)">‹</button>
  <img id="lightbox-img" src="" alt="">
  <button class="lb-next" onclick="lbNav(1)">›</button>
</div>
</div>

<!-- SHOP PAGE -->
<div class="page" id="page-shop">
<div class="container">
  <div class="shop-coming reveal">
    <div class="shop-coming-icon">🛒</div>
    <h2>Shop Coming Soon</h2>
    <p>Merchandise, sample packs and more - coming soon.</p>
  </div>
</div>
</div>

<!-- APPS PAGE -->
<div class="page" id="page-apps">
<div class="container">
  <div class="page-header reveal">
    <div class="section-eyebrow">iOS &amp; macOS</div>
    <h1 class="section-title">Apps</h1>
    <p class="section-sub">Apps developed by Paolo Campitelli for iOS and macOS.</p>
  </div>
  <div class="apps-page">
    <div class="reveal">
      <!-- DirectGram -->
      <div style="background:linear-gradient(135deg,#f8f5ff 0%,#ede8ff 100%);border-radius:16px;overflow:hidden;margin-bottom:3rem;border:1px solid rgba(109,40,217,.12)">
        <div style="padding:3rem;background:linear-gradient(135deg,#f0ebff,#e8e0ff);border-bottom:1px solid rgba(109,40,217,.1)">
          <div style="display:inline-flex;align-items:center;gap:6px;background:rgba(109,40,217,.1);border:1px solid rgba(109,40,217,.2);color:#7c3aed;border-radius:100px;padding:5px 14px;font-size:.75rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;margin-bottom:1.2rem">📷 iOS App</div>
          <h2 style="font-family:'Playfair Display',serif;font-size:2.5rem;font-weight:800;color:#1e1b2e;letter-spacing:-.03em;margin-bottom:.5rem">DirectGram</h2>
          <p style="font-size:1rem;color:#4c4575;max-width:520px">The most complete Instagram Direct Messages manager for iOS. Reply, react, manage DMs - everything in one app.</p>
        </div>
        <div style="padding:2.5rem 3rem;background:#fff">
          <div style="display:flex;gap:.5rem;margin-bottom:1.5rem;flex-wrap:wrap">
            <span style="background:rgba(109,40,217,.08);color:#7c3aed;border:1px solid rgba(109,40,217,.2);border-radius:4px;font-size:.72rem;padding:.2rem .6rem">Instagram DM</span>
            <span style="background:rgba(109,40,217,.08);color:#7c3aed;border:1px solid rgba(109,40,217,.2);border-radius:4px;font-size:.72rem;padding:.2rem .6rem">iOS</span>
            <span style="background:rgba(109,40,217,.08);color:#7c3aed;border:1px solid rgba(109,40,217,.2);border-radius:4px;font-size:.72rem;padding:.2rem .6rem">Swift</span>
          </div>
          <p style="color:#4c4575;font-size:.95rem;margin-bottom:1.5rem">Manage all your Instagram Direct Messages from a dedicated, feature-rich app. Supports reactions, media, voice messages and more.</p>
          <a href="https://apps.apple.com/app/directgram/id1449558282" target="_blank" style="display:inline-flex;align-items:center;gap:.5rem;background:#7c3aed;color:#fff;padding:.75rem 1.5rem;border-radius:8px;font-weight:700;font-size:.9rem;text-decoration:none">
            ⬇ Download on App Store
          </a>
          <p style="margin-top:.8rem;font-size:.72rem;color:#9c91c9;font-style:italic">⚠ Requires Instagram account. Not affiliated with Meta.</p>
        </div>
      </div>
      <!-- Battletap -->
      <div style="background:linear-gradient(135deg,#fff8ee,#fff3e0);border-radius:16px;overflow:hidden;margin-bottom:3rem;border:1px solid rgba(200,100,0,.12)">
        <div style="padding:3rem;background:linear-gradient(135deg,#fff3e0,#ffe8c0);border-bottom:1px solid rgba(200,100,0,.1)">
          <div style="display:inline-flex;align-items:center;gap:6px;background:rgba(200,100,0,.1);border:1px solid rgba(200,100,0,.2);color:#c85a00;border-radius:100px;padding:5px 14px;font-size:.75rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;margin-bottom:1.2rem">🎮 iOS App</div>
          <h2 style="font-family:'Playfair Display',serif;font-size:2.5rem;font-weight:800;color:#1e1b2e;letter-spacing:-.03em;margin-bottom:.5rem">Battletap</h2>
          <p style="font-size:1rem;color:#7a5c3a;max-width:520px">The ultimate tap battle game for iOS. Challenge your friends and prove who has the fastest fingers!</p>
        </div>
        <div style="padding:2.5rem 3rem;background:#fff">
          <div style="display:flex;gap:.5rem;margin-bottom:1.5rem;flex-wrap:wrap">
            <span style="background:rgba(200,100,0,.08);color:#c85a00;border:1px solid rgba(200,100,0,.2);border-radius:4px;font-size:.72rem;padding:.2rem .6rem">Game</span>
            <span style="background:rgba(200,100,0,.08);color:#c85a00;border:1px solid rgba(200,100,0,.2);border-radius:4px;font-size:.72rem;padding:.2rem .6rem">iOS</span>
            <span style="background:rgba(200,100,0,.08);color:#c85a00;border:1px solid rgba(200,100,0,.2);border-radius:4px;font-size:.72rem;padding:.2rem .6rem">Multiplayer</span>
          </div>
          <p style="color:#7a5c3a;font-size:.95rem;margin-bottom:1.5rem">Fast-paced tap battle game. Challenge friends locally, see who's the fastest. Simple mechanics, intense competition.</p>
          <a href="https://apps.apple.com/app/battletap/id1449558282" target="_blank" style="display:inline-flex;align-items:center;gap:.5rem;background:#c85a00;color:#fff;padding:.75rem 1.5rem;border-radius:8px;font-weight:700;font-size:.9rem;text-decoration:none">
            ⬇ Download on App Store
          </a>
        </div>
      </div>
      <!-- Absolute Cleaner -->
      <div style="background:linear-gradient(135deg,#eeffee,#e8f5e8);border-radius:16px;overflow:hidden;margin-bottom:3rem;border:1px solid rgba(0,140,70,.12)">
        <div style="padding:3rem;background:linear-gradient(135deg,#e8f5e8,#d4ecd4);border-bottom:1px solid rgba(0,140,70,.1)">
          <div style="display:inline-flex;align-items:center;gap:6px;background:rgba(0,140,70,.08);border:1px solid rgba(0,140,70,.2);color:#006b35;border-radius:100px;padding:5px 14px;font-size:.75rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;margin-bottom:1.2rem">🖥 macOS App</div>
          <h2 style="font-family:'Playfair Display',serif;font-size:2.5rem;font-weight:800;color:#1e1b2e;letter-spacing:-.03em;margin-bottom:.5rem">Absolute Cleaner</h2>
          <p style="font-size:1rem;color:#2a5a3a;max-width:520px">The powerful Mac cleaner that keeps your system fast, clean and optimized.</p>
        </div>
        <div style="padding:2.5rem 3rem;background:#fff">
          <div style="display:flex;gap:.5rem;margin-bottom:1.5rem;flex-wrap:wrap">
            <span style="background:rgba(0,140,70,.08);color:#006b35;border:1px solid rgba(0,140,70,.2);border-radius:4px;font-size:.72rem;padding:.2rem .6rem">macOS</span>
            <span style="background:rgba(0,140,70,.08);color:#006b35;border:1px solid rgba(0,140,70,.2);border-radius:4px;font-size:.72rem;padding:.2rem .6rem">Utility</span>
            <span style="background:rgba(0,140,70,.08);color:#006b35;border:1px solid rgba(0,140,70,.2);border-radius:4px;font-size:.72rem;padding:.2rem .6rem">Swift</span>
          </div>
          <p style="color:#2a5a3a;font-size:.95rem;margin-bottom:1.5rem">Remove junk files, free up space, and keep your Mac running at peak performance. Safe, fast, and effective.</p>
          <a href="https://apps.apple.com/app/absolute-cleaner/id1449558282" target="_blank" style="display:inline-flex;align-items:center;gap:.5rem;background:#006b35;color:#fff;padding:.75rem 1.5rem;border-radius:8px;font-weight:700;font-size:.9rem;text-decoration:none">
            ⬇ Download on Mac App Store
          </a>
        </div>
      </div>
    </div>
  </div>
</div>
</div>

<!-- CONTACT PAGE -->
<div class="page" id="page-contact">
<div class="container">
  <div class="page-header reveal">
    <div class="section-eyebrow">Get in Touch</div>
    <h1 class="section-title">Contact</h1>
  </div>
  <div class="contact-layout">
    <div class="reveal">
      <p style="color:var(--muted);line-height:1.8;margin-bottom:2.5rem">For recording, mixing, mastering, production or collaborations - reach out through any of the following channels.</p>
      <div class="contact-info-item">
        <div class="contact-icon">📍</div>
        <div>
          <div class="contact-info-label">Location</div>
          <div class="contact-info-val">Rome, Italy · Warlord Sound Studios</div>
        </div>
      </div>
      <div class="contact-info-item">
        <div class="contact-icon">🎵</div>
        <div>
          <div class="contact-info-label">Bands</div>
          <div class="contact-info-val">Alterium · ScreaMachine · Noveria</div>
        </div>
      </div>
      <div class="contact-info-item">
        <div class="contact-icon">🎛</div>
        <div>
          <div class="contact-info-label">Services</div>
          <div class="contact-info-val">Reamping - Mixing - Mastering - Production - Orchestral &amp; Modern Keyboard Arrangements</div>
        </div>
      </div>
    </div>
    <div class="reveal reveal-delay-1">
      <form class="contact-form" onsubmit="handleContactForm(event)" id="contact-form">
        <div id="contact-alert" class="alert"></div>
        <div class="form-group">
          <label class="form-label">Name</label>
          <input class="form-input" type="text" name="name" placeholder="Your name" required>
        </div>
        <div class="form-group">
          <label class="form-label">Email</label>
          <input class="form-input" type="email" name="email" placeholder="your@email.com" required>
        </div>
        <div class="form-group">
          <label class="form-label">Subject</label>
          <input class="form-input" type="text" name="subject" placeholder="Recording session, mix inquiry...">
        </div>
        <div class="form-group">
          <label class="form-label">Message</label>
          <textarea class="form-textarea" name="message" placeholder="Tell me about your project..." required></textarea>
        </div>
        <!-- Honeypot: hidden field, only bots fill this -->
        <div style="position:absolute;left:-9999px;top:-9999px;opacity:0;height:0;overflow:hidden" aria-hidden="true">
          <label>Leave this empty</label>
          <input type="text" name="website" tabindex="-1" autocomplete="off">
        </div>
        <button type="submit" class="btn btn-primary form-submit">Send Message</button>
      </form>
    </div>
  </div>
</div>
<footer>
  <div class="footer-logo">Paolo <span>Campitelli</span></div>
  <div class="footer-copy">© 2026 Paolo Campitelli. All rights reserved.</div>
</footer>
</div>

<!-- BLOG PAGE -->
<div class="page" id="page-blog">
<div class="container">
  <div class="page-header reveal">
    <div class="section-eyebrow">News &amp; Articles</div>
    <h1 class="section-title">Blog</h1>
  </div>
  <div id="blog-list" class="blog-list"></div>
</div>
</div>

<!-- BLOG SINGLE PAGE -->
<div class="page" id="page-blog-single">
<div class="container">
  <div class="blog-single" id="blog-single-content"></div>
</div>
</div>

<!-- ADMIN PAGE -->
<div id="admin-page" class="page" style="display:none">
  <!-- Login -->
  <div id="admin-login-wrap" class="admin-login">
    <h2>Admin Panel</h2>
    <div id="login-alert" class="alert"></div>
    <div class="form-group">
      <label class="form-label">Username</label>
      <input class="form-input" type="text" id="login-user" placeholder="Username">
    </div>
    <div class="form-group">
      <label class="form-label">Password</label>
      <input class="form-input" type="password" id="login-pass" placeholder="Password">
    </div>
    <button class="btn btn-primary form-submit" onclick="doLogin()">Login</button>
  </div>
  <!-- Panel -->
  <div id="admin-panel-wrap" class="admin-panel">
    <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:2rem">
      <h1 style="font-family:'Playfair Display',serif;color:#fff">Admin Panel</h1>
      <button class="admin-logout" onclick="doLogout()">Logout</button>
    </div>
    <div id="admin-save-alert" class="alert"></div>
    <div class="admin-tabs">
      <button class="admin-tab active" onclick="adminTab('albums',this)">Albums</button>
      <button class="admin-tab" onclick="adminTab('gallery',this)">Gallery</button>
      <button class="admin-tab" onclick="adminTab('posts',this)">Blog Posts</button>
    </div>
    <!-- Albums tab -->
    <div id="admin-albums-tab">
      <button class="admin-btn-add" onclick="openAlbumForm()">+ Add Album</button>
      <div id="admin-album-grid" class="admin-album-grid"></div>
    </div>
    <!-- Gallery tab -->
    <div id="admin-gallery-tab" style="display:none">
      <button class="admin-btn-add" onclick="openGalleryAdd()">+ Add Photo</button>
      <div id="admin-gallery-grid" class="admin-gallery-grid"></div>
    </div>
    <!-- Posts tab -->
    <div id="admin-posts-tab" style="display:none">
      <button class="admin-btn-add" onclick="openPostEditor()">+ New Post</button>
      <table class="admin-post-table" id="admin-post-table">
        <thead><tr><th>Title</th><th>Date</th><th>Status</th><th>Actions</th></tr></thead>
        <tbody id="admin-post-tbody"></tbody>
      </table>
      <!-- Inline post editor -->
      <div id="post-editor-wrap" style="display:none;background:var(--s1);border:1px solid var(--border);border-radius:6px;padding:2rem;margin-top:1rem">
        <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem">
          <div class="admin-section-title" style="margin:0;border:none;padding:0" id="post-editor-title">New Post</div>
          <button onclick="closePostEditor()" style="color:var(--muted);font-size:1.5rem;background:none;cursor:pointer">×</button>
        </div>
        <div class="form-group"><label class="form-label">Title</label><input class="form-input" id="pe-title" placeholder="Post title" oninput="updateSlugPreview()"></div>
        <div class="form-group">
          <label class="form-label">Slug</label>
          <input class="form-input" id="pe-slug" placeholder="post-slug">
          <div class="slug-preview" id="pe-slug-preview"></div>
        </div>
        <div style="display:grid;grid-template-columns:1fr 1fr;gap:1rem">
          <div class="form-group"><label class="form-label">Date</label><input class="form-input" type="date" id="pe-date"></div>
          <div class="form-group"><label class="form-label">Status</label>
            <select class="form-input" id="pe-status">
              <option value="published">Published</option>
              <option value="draft">Draft</option>
            </select>
          </div>
        </div>
        <div class="form-group"><label class="form-label">Category</label>
          <select class="form-input" id="pe-category">
            <option>News</option><option>Tutorial</option><option>ScreaMachine</option>
            <option>Alterium</option><option>Musica</option><option>Altro</option>
          </select>
        </div>
        <div class="form-group"><label class="form-label">Featured Image URL</label>
          <input class="form-input" id="pe-img" placeholder="https://..." oninput="updateImgPreview()">
          <img id="pe-img-preview" style="max-width:200px;margin-top:.5rem;border-radius:4px;display:none">
        </div>
        <div class="form-group"><label class="form-label">Content</label>
          <div id="pe-editor-container"></div>
        </div>
        <div style="display:flex;gap:.8rem;margin-top:1.5rem">
          <button class="btn btn-primary" onclick="savePost()">Save Post</button>
          <button class="btn btn-ghost" onclick="previewPost()">Preview</button>
        </div>
      </div>
    </div>
  </div>
</div>

<!-- FORM MODAL -->
<div id="form-modal">
  <div class="form-modal-inner">
    <button class="form-modal-close" onclick="closeFormModal()">×</button>
    <div class="form-modal-title" id="form-modal-title">Album</div>
    <div id="form-modal-body"></div>
  </div>
</div>

<script>
// ═══════════════════════════════════════════════════════
//  DATA
// ═══════════════════════════════════════════════════════
const ALBUMS_DEFAULT = [
  {slug:'kaledon-antillius-the-king-of-the-light',title:'KALEDON – "Antillius - The King of the Light"',artist:'KALEDON',year:'2014',label:'Scarlet Records',producer:'Giuseppe Orlando',youtube:'https://youtu.be/ZxqJ3-BV0Sc',cover:'assets/images/2019/07/48374597_2152092771773555_2667093241056198656_o.jpg',credits:'Keyboards.'},
  {slug:'kaledon-chapter-iv-twilight-of-the-gods-remaster',title:'KALEDON – "Chapter IV: Twilight of the Gods"',artist:'KALEDON',year:'2015',label:'Scarlet Records',producer:'Giuseppe Orlando & Paolo Campitelli',youtube:'https://youtu.be/6l6IYCVUJSA',cover:'assets/images/2019/07/48373969_2152120911770741_2110204676195483648_o.jpg',credits:'Keyboards on 2015 - Tracks 12 and 13.'},
  {slug:'aldaria-the-three-kings',title:'Aldaria – "The Three Kings"',artist:'Aldaria',year:'2016',label:'',producer:'',youtube:'https://youtu.be/CUuhwyznov4',cover:'assets/images/2019/07/48417864_2152106751772157_8692926666512531456_o.jpg',credits:'Keyboards.'},
  {slug:'aldaria-land-of-the-light',title:'Aldaria – "Land of the Light"',artist:'Aldaria',year:'2016',label:'',producer:'Roland Grapow',youtube:'https://youtu.be/CWApltduIa8',cover:'assets/images/2019/07/48370297_2152106221772210_62859419062370304_o.jpg',credits:'Keyboards on \"When Reality Ends\".'},
  {slug:'thabu-humanidad',title:'Thabu – "Humanidad"',artist:'Thabu',year:'2014',label:'',producer:'',youtube:'',cover:'assets/images/2019/07/humanidad.jpg'},
  {slug:'vivaldi-metal-project-the-four-seasons',title:'Vivaldi Metal Project – "The Four Seasons"',artist:'Vivaldi Metal Project',year:'2016',label:'',producer:'Maestro Mysteria (Giuseppe Iampieri)',youtube:'',cover:'assets/images/2019/07/48370606_2152122541770578_8787363355149991936_n.jpg',credits:'Keyboards on \"The Final Hour\".'},
  {slug:'kaledon-carnagus-emperor-of-the-darkness',title:'KALEDON – "Carnagus - Emperor of the Darkness"',artist:'KALEDON',year:'2017',label:'',producer:'Simone Mularoni',youtube:'https://youtu.be/J-eu3-gqKmE',cover:'assets/images/2019/07/48373543_2152102761772556_8249308204702367744_n.jpg',credits:'Keyboards.'},
  {slug:'terror-tales-a-tribute-to-death-ss',title:'"Terror Tales" – A Tribute to Death SS',artist:'Various',year:'2018',label:'',producer:'Paolo Campitelli',youtube:'',cover:'assets/images/2019/07/48372653_2152125945103571_3159608127414861824_n.jpg',credits:'Keyboards, Mix and Mastering on \"Let the Sabbath Begin\".'},
  {slug:'kaledon-reunited-kingdom',title:'KALEDON – "Reunited Kingdom"',artist:'KALEDON',year:'2018',label:'',producer:'Paolo Campitelli',youtube:'https://youtu.be/19Y2XTe2a5k',cover:'assets/images/2019/07/48398874_2152119665104199_6431109812271972352_o.png',credits:'Keyboards, Mix and Mastering.'},
  {slug:'althea-the-art-of-trees',title:'Althea – "The Art of Trees"',artist:'Althea',year:'2019',label:'',producer:'',youtube:'https://youtu.be/ftklUGr7RWs',cover:'assets/images/2019/07/48367916_2152118985104267_4415548459885527040_n.jpg',credits:'Synth Solo on \"Away From Me\".'},
  {slug:'even-flow-mother',title:'Even Flow – "Mother"',artist:'Even Flow',year:'2019',label:'',producer:'Joost van den Broek & Paolo Campitelli',youtube:'https://youtu.be/bF36J9lCIDs',cover:'assets/images/2019/07/64223980_2269271476722350_7317522974049828864_o.jpg',credits:'Keyboards - Vocal, and Guitars recording/editing.'},
  {slug:'kalidia-to-the-darkness-i-belong-orchestral-version',title:'KALIDIA – "To the Darkness I Belong"',artist:'KALIDIA',year:'2020',label:'Innerwound Records',producer:'Paolo Campitelli',youtube:'https://youtu.be/ilcalpLxpvk',cover:'assets/images/2020/03/87987720_2901086659938552_6349817987008036864_n.jpg',credits:'Mixing and Mastering.'},
  {slug:'edoardo-taddei-nemesi-2020',title:'Edoardo Taddei – "Nemesi"',artist:'Edoardo Taddei',year:'2020',label:'',producer:'',youtube:'https://www.youtube.com/watch?v=pOZmTTn2qa8',cover:'assets/images/2020/03/83874044_128999328599724_5460930108023898112_o.jpg',credits:'Keyboards.'},
  {slug:'alex-mele-alien-doppelganger',title:'Alex Mele – "Alien Doppelganger"',artist:'Alex Mele',year:'2020',label:'Underground Symphony',producer:'Paolo Campitelli',youtube:'https://youtu.be/tKLiwVZctrE',cover:'assets/images/2020/08/106600484_2985728738320706_3532334770372667478_o.jpg',credits:'Mixed and Mastered by Paolo Campitelli. Keyboards.'},
  {slug:"sick-n-beautiful-startruck-2022",title:"Sick N' Beautiful – \"Starstruck\"",artist:"Sick N' Beautiful",year:'2022',label:'',producer:'',youtube:'',cover:'assets/images/2023/03/SICK-N-BEAUTIFUL-Starstruck.jpeg'},
  {slug:'shores-of-null-beyond-the-shores-2020',title:'Shores of Null – "Beyond the Shores"',artist:'Shores of Null',year:'2020',label:'',producer:'',youtube:'https://youtu.be/PicIlnHwYCw',cover:'assets/images/2023/03/SHORES-OF-NULL-Beyond-The-Shores-On-Death-And-Dying-2020-700x700.png',credits:'Piano on \"Beyond the Shores\".'},
  {slug:'screamachine-screamachine-2021',title:'ScreaMachine – "ScreaMachine"',artist:'ScreaMachine',year:'2021',label:'Frontiers Records srl',producer:'Paolo Campitelli',youtube:'https://youtu.be/OcV3X_t78lE',cover:'assets/images/2021/02/ScreaMachine-Cover-OFFICIAL-low.jpg',credits:'Recorded, Mixed and Mastered by Paolo Campitelli.'},
  {slug:'screamachine-borderline-2022',title:'ScreaMachine – "Borderline"',artist:'ScreaMachine',year:'2022',label:'Frontiers Records srl',producer:'Paolo Campitelli',youtube:'https://youtu.be/bI4N8RgRhQ8',cover:'assets/images/2022/09/Borderline-Official-Cover.jpg',credits:'Recorded, Mixed and Mastered by Paolo Campitelli.'},
  {slug:'kalidia-lies-device-2021-edition',title:"KALIDIA – \"Lies' Device\" (2021 Edition)",artist:'KALIDIA',year:'2021',label:'Innerwound Records',producer:'Paolo Campitelli',youtube:'https://youtu.be/8K_nc3EoZbo',cover:'assets/images/2020/12/lies-device-2021.jpg',credits:'Mixed and Mastered by Paolo Campitelli. Keyboards additions.'},
  {slug:'screamachine-church-of-the-scream-2023',title:'ScreaMachine – "Church of the Scream"',artist:'ScreaMachine',year:'2023',label:'Frontiers Records srl',producer:'Paolo Campitelli',youtube:'https://youtu.be/T2j0hy4AkLk',cover:'assets/images/2023/03/SCREAMACHINE-ARTWORK-2023-official.jpg',credits:'Guitars, Mix, Mastering.'},
  {slug:'alterium-of-war-and-flames-2024',title:'Alterium – "Of War and Flames"',artist:'Alterium',year:'2024',label:'AFM Records',producer:'Lars Rettkowitz',youtube:'https://youtu.be/CnDVSF6tIvQ',cover:'assets/images/2025/03/ALTERIUM-Of-War-And-Flames-2024.jpg',credits:'Guitars.'},
  {slug:'alterium-stormrage-2025',title:'Alterium – "Stormrage"',artist:'Alterium',year:'2025',label:'',producer:'Lars Rettkowitz & Paolo Campitelli',youtube:'https://youtu.be/mILaIBIxudQ',cover:'assets/images/2025/08/506761946_660443850361314_8855488891702602619_n.jpg',credits:'Guitars, Keyboards. Producer, Mix and Mastering. VideoClip on \"Paradise Lost\".'}
];

const GALLERY_DEFAULT = {
  studio:{title:'Studio',images:[
    {url:'assets/images/2025/10/05569F9E-B0D2-4C04-BC99-28B7A0C73246-scaled.jpeg',alt:'Studio'},
    {url:'assets/images/2025/10/9F0721E6-0EBE-4CE1-9B6D-628F29B842D7-scaled.jpeg',alt:'Studio'},
    {url:'assets/images/2025/10/A03ED513-3C85-45DA-91CE-A5CD1568962E-scaled.jpeg',alt:'Studio'},
    {url:'assets/images/2019/07/64379959_2269280586721439_396671278104182784_o.jpg',alt:'Studio'},
    
    {url:'assets/images/2019/07/49238893_2154739648175534_8166560548733845504_o.jpg',alt:'Studio'},
    {url:'assets/images/2019/07/48923789_2154739564842209_4159887516524085248_o.jpg',alt:'Studio'},
    
    
    {url:'assets/images/2019/07/48421193_2154739634842202_8707474137355911168_o.jpg',alt:'Studio'},
    
    {url:'assets/images/2019/07/IMG_2467.jpg',alt:'Studio'},
    
    {url:'assets/images/2019/07/IMG_2464.jpg',alt:'Studio'}
  ]},
  live:{title:'Live',images:[
    {url:'assets/images/2019/07/46276256_2129060580743441_8762883222678798336_o.jpg',alt:'Live'},
    {url:'assets/images/2019/07/21316086_114546725888257_6677264775786929303_o.jpg',alt:'Live'},
    {url:'assets/images/2019/07/21105722_10211630043561586_6346112302317866107_n.jpg',alt:'Live'},
    {url:'assets/images/2019/07/46269165_2129058870743612_8422050054180700160_n.jpg',alt:'Live'},
    {url:'assets/images/2019/07/21122246_872473542921594_916345219097858125_o.jpg',alt:'Live'},
    {url:'assets/images/2019/07/80986979_10217747870303431_8063268668324184064_o.jpg',alt:'Live'},
    {url:'assets/images/2019/07/22788703_10214861932526735_9193549636968159447_n.jpg',alt:'Live'},
    {url:'assets/images/2019/07/65292757_2277795032536661_8189407275077599232_o.jpg',alt:'Live'},
    {url:'assets/images/2019/07/61842383_2259992237650274_6911383255858020352_n.jpg',alt:'Live'},
    {url:'assets/images/2019/07/82933793_10217901737510015_418984135718076416_o.jpg',alt:'Live'},
    {url:'assets/images/2019/07/74838120_10217363557255845_906617813219672064_o.jpg',alt:'Live'},
    {url:'assets/images/2019/07/75456807_2596240957102479_8676956401853005824_o.jpg',alt:'Live'}
  ]},
  foh:{title:'FOH',images:[
    {url:'assets/images/2019/07/66194629_2286357695013728_3770304613790515200_o.jpg',alt:'FOH'},
    {url:'assets/images/2019/07/56997505_2227681727547992_2727504086378217472_o.jpg',alt:'FOH'},
    {url:'assets/images/2019/07/66053487_2286357778347053_8462754399842729984_o.jpg',alt:'FOH'},
    {url:'assets/images/2019/07/66407097_2286357868347044_7135842709218000896_o.jpg',alt:'FOH'},
    {url:'assets/images/2019/07/61172577_2251096761873155_470843696858791936_o.jpg',alt:'FOH'},
    {url:'assets/images/2019/07/65284571_2276224109360420_8749838681151373312_o.jpg',alt:'FOH'}
  ]}
};

const POSTS_DEFAULT = [
  {slug:'welcome-to-paolocampitelli-com-2-0',title:'Welcome to PaoloCampitelli.com 2.0!',date:'2019-07-24',categories:["News"],content:'<h2>Welcome to my new website! </h2>\n\n<p>Hope you will enjoy it!</p>\n\n<p> </p>\n\n<p><em>Paolo</em></p>',content_rendered:'<h2>Welcome to my new website! </h2>\n\n<p>Hope you will enjoy it!</p>\n\n<p> </p>\n\n<p><em>Paolo</em></p>',excerpt:'',thumb_url:'assets/images/2019/07/48923789_2154739564842209_4159887516524085248_o.jpg',source:'wordpress'},
  {slug:'korg-kronos-fan-cooling-message-how-to-fix-high-temperature',title:'Korg Kronos: "Fan Cooling" message? How to fix high temperature!',date:'2020-07-27',categories:["Korg"],content:'<p>Some days ago, I saw a red alert on the screen of my Korg Kronos: "Fan Cooling". I have immediately checked the cpu temperature and it was 89 degrees. Definitely too much! </p>\n\n<p>Since my Kronos is out of warranty (I have the first series) I decided to open the workstation because I was convinced that the problem was the dust. </p>\n\n<p>Honestly, when I opened the Kronos, I was quite disappointed about the heat dissipation: No fan on the cpu (on an Intel Atom dual core CPU, really?), only a very small (and noisy!) fan near the power supply and that\'s it. Now I understand why the temperature is always so high and this is not a good thing. </p>\n\n<p style="text-align:center"><strong>So... ready to start? :D </strong></p>\n\n<p><strong>What you need:</strong></p>\n\n<ul><li>Artic F8 Pro Fan (12 Volt): <a href="https://amzn.to/2P1T05S">Amazon</a> </li><li>Small Fan 5V for the CPU: <a href="https://amzn.to/3f54X5d">Amazon</a></li><li>Passive Heatsink: <a href="https://amzn.to/304Ks4v">Amazon</a></li><li>Four small rubber pads</li><li>Super Attack Glue: <a href="https://amzn.to/2D7pKb0">Amazon</a></li></ul>\n\n<p>1: Put the kronos upside down and remove all the screws. Pay attention to the joystick. </p>\n\n<div><figure class="aligncenter is-resized"><img src="assets/images/2020/07/IMG_3938-e1595883503696-768x1024.jpg" alt="" width="384" height="512"/></figure></div>\n\n<p>2: On the left side, unplug the cable of the fan:</p>\n\n<div><figure class="aligncenter"><img src="assets/images/2020/07/IMG_3939-1024x768.jpg" alt=""/></figure></div>\n\n<p>3: In the center, find the fan and remove the 2 screws: </p>\n\n<div><figure class="aligncenter"><img src="assets/images/2020/07/IMG_3944-1-768x1024.jpg" alt=""/></figure></div>\n\n<p>4: Remove the old fan:</p>\n\n<div><figure class="aligncenter"><img src="assets/images/2020/07/IMG_3945-768x1024.jpg" alt=""/></figure></div>\n\n<div><figure class="aligncenter"><img src="assets/images/2020/07/IMG_3946-768x1024.jpg" alt=""/></figure></div>\n\n<p>5: Put the rubber pads on the 4 corners, add the Artic Fan in the slot and use the glue to attack it to the rubbers. Connect the cable to the power:</p>\n\n<div><figure class="aligncenter"><img src="assets/images/2020/07/IMG_3947-768x1024.jpg" alt=""/></figure></div>\n\n<div><figure class="aligncenter"><img src="assets/images/2020/07/IMG_3949-768x1024.jpg" alt=""/></figure></div>\n\n<div><figure class="aligncenter"><img src="assets/images/2020/07/IMG_3955-768x1024.jpg" alt=""/></figure></div>\n\n<p>6: Time to add a small fan on the cpu: </p>\n\n<div><figure class="aligncenter"><img src="assets/images/2020/07/IMG_3953-768x1024.jpg" alt=""/></figure></div>\n\n<div><figure class="aligncenter"><img src="assets/images/2020/07/IMG_3954-768x1024.jpg" alt=""/></figure></div>\n\n<p>8: Last Step! Let\'s add the passive heatsink on the northbridge:</p>\n\n<div><figure class="aligncenter"><img src="assets/images/2020/07/IMG_3957-1024x768.jpg" alt=""/></figure></div>\n\n<p>Done! Time to close your Kronos :) </p>\n\n<p><strong>Improvements: </strong></p>\n\n<p>Temperature after 30 minutes is 28 (!) degrees cooler. </p>\n\n<p>Noise has been reduced.</p>\n\n<figure><img src="assets/images/2020/07/IMG_3961.jpg" alt=""/></figure>\n\n<blockquote><p>Enjoy! </p></blockquote>',content_rendered:'<p>Some days ago, I saw a red alert on the screen of my Korg Kronos: "Fan Cooling". I have immediately checked the cpu temperature and it was 89 degrees. Definitely too much! </p>\n\n<p>Since my Kronos is out of warranty (I have the first series) I decided to open the workstation because I was convinced that the problem was the dust. </p>\n\n<p>Honestly, when I opened the Kronos, I was quite disappointed about the heat dissipation: No fan on the cpu (on an Intel Atom dual core CPU, really?), only a very small (and noisy!) fan near the power supply and that\'s it. Now I understand why the temperature is always so high and this is not a good thing. </p>\n\n<p style="text-align:center"><strong>So... ready to start? :D </strong></p>\n\n<p><strong>What you need:</strong></p>\n\n<ul><li>Artic F8 Pro Fan (12 Volt): <a href="https://amzn.to/2P1T05S">Amazon</a> </li><li>Small Fan 5V for the CPU: <a href="https://amzn.to/3f54X5d">Amazon</a></li><li>Passive Heatsink: <a href="https://amzn.to/304Ks4v">Amazon</a></li><li>Four small rubber pads</li><li>Super Attack Glue: <a href="https://amzn.to/2D7pKb0">Amazon</a></li></ul>\n\n<p>1: Put the kronos upside down and remove all the screws. Pay attention to the joystick. </p>\n\n<div><figure class="aligncenter is-resized"><img src="assets/images/2020/07/IMG_3938-e1595883503696-768x1024.jpg" alt="" width="384" height="512"/></figure></div>\n\n<p>2: On the left side, unplug the cable of the fan:</p>\n\n<div><figure class="aligncenter"><img src="assets/images/2020/07/IMG_3939-1024x768.jpg" alt=""/></figure></div>\n\n<p>3: In the center, find the fan and remove the 2 screws: </p>\n\n<div><figure class="aligncenter"><img src="assets/images/2020/07/IMG_3944-1-768x1024.jpg" alt=""/></figure></div>\n\n<p>4: Remove the old fan:</p>\n\n<div><figure class="aligncenter"><img src="assets/images/2020/07/IMG_3945-768x1024.jpg" alt=""/></figure></div>\n\n<div><figure class="aligncenter"><img src="assets/images/2020/07/IMG_3946-768x1024.jpg" alt=""/></figure></div>\n\n<p>5: Put the rubber pads on the 4 corners, add the Artic Fan in the slot and use the glue to attack it to the rubbers. Connect the cable to the power:</p>\n\n<div><figure class="aligncenter"><img src="assets/images/2020/07/IMG_3947-768x1024.jpg" alt=""/></figure></div>\n\n<div><figure class="aligncenter"><img src="assets/images/2020/07/IMG_3949-768x1024.jpg" alt=""/></figure></div>\n\n<div><figure class="aligncenter"><img src="assets/images/2020/07/IMG_3955-768x1024.jpg" alt=""/></figure></div>\n\n<p>6: Time to add a small fan on the cpu: </p>\n\n<div><figure class="aligncenter"><img src="assets/images/2020/07/IMG_3953-768x1024.jpg" alt=""/></figure></div>\n\n<div><figure class="aligncenter"><img src="assets/images/2020/07/IMG_3954-768x1024.jpg" alt=""/></figure></div>\n\n<p>8: Last Step! Let\'s add the passive heatsink on the northbridge:</p>\n\n<div><figure class="aligncenter"><img src="assets/images/2020/07/IMG_3957-1024x768.jpg" alt=""/></figure></div>\n\n<p>Done! Time to close your Kronos :) </p>\n\n<p><strong>Improvements: </strong></p>\n\n<p>Temperature after 30 minutes is 28 (!) degrees cooler. </p>\n\n<p>Noise has been reduced.</p>\n\n<figure><img src="assets/images/2020/07/IMG_3961.jpg" alt=""/></figure>\n\n<blockquote><p>Enjoy! </p></blockquote>',excerpt:'',thumb_url:'assets/images/2020/07/IMG_3948.jpg',source:'wordpress'},
  {slug:'ignite-amps-emissary-official-kemper-and-tonehub-pack-out-now',title:'Ignite Amps Emissary: official Kemper and ToneHub pack OUT NOW!',date:'2020-08-07',categories:["Ignite Amps", "Kemper", "STLTones", "ToneHub"],content:'<p>I\'m really proud and excited to announce my partnership with STL Tones and share with you my official Ignite Amps Emissary preset packs for Kemper &amp; ToneHub! Thanks to STL Tones for this opportunity! 😎<br> I have personally produced and engineered 27 presets from 4 different cabinets, numerous mic configurations (SM57, U87, R-121 and MD421), and overdrive options.</p>\n\n<p>Check them out on STLTones website here: </p>\n\n<p><a href="https://www.stltones.com/collections/ignite-amps-amp-series"><em>https://www.stltones.com/collections/ignite-amps-amp-series</em></a><em> </em></p>\n\n<p>And enjoy a demo!</p>\n\n<figure><div>\nhttps://www.youtube.com/watch?v=Q9uV6eh5-aY&amp;t=181s\n</div></figure>\n\n<p></p>',content_rendered:'<p>I\'m really proud and excited to announce my partnership with STL Tones and share with you my official Ignite Amps Emissary preset packs for Kemper &amp; ToneHub! Thanks to STL Tones for this opportunity! 😎<br> I have personally produced and engineered 27 presets from 4 different cabinets, numerous mic configurations (SM57, U87, R-121 and MD421), and overdrive options.</p>\n\n<p>Check them out on STLTones website here: </p>\n\n<p><a href="https://www.stltones.com/collections/ignite-amps-amp-series"><em>https://www.stltones.com/collections/ignite-amps-amp-series</em></a><em> </em></p>\n\n<p>And enjoy a demo!</p>\n\n<figure><div>\nhttps://www.youtube.com/watch?v=Q9uV6eh5-aY&amp;t=181s\n</div></figure>\n\n<p></p>',excerpt:'',thumb_url:'assets/images/2020/08/IMG_2452.jpg',source:'wordpress'},
  {slug:'lexicon-mx200-flashing-random-numbers-here-the-solution',title:'Lexicon MX200 flashing random numbers? Here the solution!',date:'2020-08-13',categories:["Tutorial"],content:'<p>Any Lexicon MX200 owner here? I have this unit since 2011 and, even if it is a cheap unit, does its job. I use it as multi-effect unit in send/return of my Peavey 6505 Amp, preset 13 (chorus and delay) works fine for guitar leads. Of course it isn\'t even comparable with the popular Lexicon PCM series, and least of all with 480/224 series therefore I never use it in a mixing session. :D </p>\n\n<p>This unit has a common issue: flashing random lights. It isn\'t a firmware issue as I read online: the cause is simply dirty pots. The solution is to open the unit and clean it with compressed air for the dust and WD40 contact cleaner.</p>\n\n<p>Enjoy the procedure!</p>\n\n<ul><li class="blocks-gallery-item"><figure><img src="assets/images/2020/08/IMG_0206-1024x769.jpg" alt="" data-id="1690" data-link="https://www.paolocampitelli.com/?attachment_id=1690"/></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2020/08/IMG_0162-768x1024.jpg" alt="" data-id="1688" data-link="https://www.paolocampitelli.com/?attachment_id=1688"/></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2020/08/IMG_5084-768x1024.jpg" alt="" data-id="1687" data-link="https://www.paolocampitelli.com/?attachment_id=1687"/></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2020/08/IMG_8758-1024x768.jpg" alt="" data-id="1686" data-link="https://www.paolocampitelli.com/?attachment_id=1686"/></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2020/08/IMG_4289-1024x768.jpg" alt="" data-id="1685" data-link="https://www.paolocampitelli.com/?attachment_id=1685"/></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2020/08/IMG_4253-768x1024.jpg" alt="" data-id="1684" data-link="https://www.paolocampitelli.com/?attachment_id=1684"/></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2020/08/IMG_3837-1024x768.jpg" alt="" data-id="1683" data-link="https://www.paolocampitelli.com/?attachment_id=1683"/></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2020/08/IMG_2315-1024x768.jpg" alt="" data-id="1680" data-link="https://www.paolocampitelli.com/?attachment_id=1680"/></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2020/08/IMG_3646-1024x768.jpg" alt="" data-id="1681" data-link="https://www.paolocampitelli.com/?attachment_id=1681"/></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2020/08/IMG_6560-1024x768.jpg" alt="" data-id="1682" data-link="https://www.paolocampitelli.com/?attachment_id=1682"/></figure></li></ul>',content_rendered:'<p>Any Lexicon MX200 owner here? I have this unit since 2011 and, even if it is a cheap unit, does its job. I use it as multi-effect unit in send/return of my Peavey 6505 Amp, preset 13 (chorus and delay) works fine for guitar leads. Of course it isn\'t even comparable with the popular Lexicon PCM series, and least of all with 480/224 series therefore I never use it in a mixing session. :D </p>\n\n<p>This unit has a common issue: flashing random lights. It isn\'t a firmware issue as I read online: the cause is simply dirty pots. The solution is to open the unit and clean it with compressed air for the dust and WD40 contact cleaner.</p>\n\n<p>Enjoy the procedure!</p>\n\n<ul><li class="blocks-gallery-item"><figure><img src="assets/images/2020/08/IMG_0206-1024x769.jpg" alt="" data-id="1690" data-link="https://www.paolocampitelli.com/?attachment_id=1690"/></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2020/08/IMG_0162-768x1024.jpg" alt="" data-id="1688" data-link="https://www.paolocampitelli.com/?attachment_id=1688"/></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2020/08/IMG_5084-768x1024.jpg" alt="" data-id="1687" data-link="https://www.paolocampitelli.com/?attachment_id=1687"/></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2020/08/IMG_8758-1024x768.jpg" alt="" data-id="1686" data-link="https://www.paolocampitelli.com/?attachment_id=1686"/></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2020/08/IMG_4289-1024x768.jpg" alt="" data-id="1685" data-link="https://www.paolocampitelli.com/?attachment_id=1685"/></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2020/08/IMG_4253-768x1024.jpg" alt="" data-id="1684" data-link="https://www.paolocampitelli.com/?attachment_id=1684"/></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2020/08/IMG_3837-1024x768.jpg" alt="" data-id="1683" data-link="https://www.paolocampitelli.com/?attachment_id=1683"/></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2020/08/IMG_2315-1024x768.jpg" alt="" data-id="1680" data-link="https://www.paolocampitelli.com/?attachment_id=1680"/></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2020/08/IMG_3646-1024x768.jpg" alt="" data-id="1681" data-link="https://www.paolocampitelli.com/?attachment_id=1681"/></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2020/08/IMG_6560-1024x768.jpg" alt="" data-id="1682" data-link="https://www.paolocampitelli.com/?attachment_id=1682"/></figure></li></ul>',excerpt:'',thumb_url:'assets/images/2020/08/IMG_2412.jpg',source:'wordpress'},
  {slug:'screamachine-my-new-band',title:'SCREAMACHINE: my new band!',date:'2020-12-05',categories:["Senza categoria"],content:'<p><strong>Frontiers Music Srl</strong>&nbsp;is proud to announce the signing of Italy’s ScreaMachine to the label. The band hails from Rome, Italy and are proud heavy metallers. The quintet’s gloriously loud sound is inspired by titans like Judas Priest, early Metallica, early Iced Earth, Savatage and Accept. But even if the guys are in love with the legendary 80’s metal sound, they are not living in the past. Their aim is to deliver an aggressive and traditional heavy metal sound blended with modern production and up-to-date songwriting.</p>\n\n<figure><img src="assets/images/2020/12/119230140_632612420728672_8996527692830816852_o-1024x683.jpg" alt=""/></figure>\n\n<p><br>The musicians involved are no strangers to the metal scene. The members come from respected Italian acts like Stormlord, Kaledon, and Lunarsea, and have been active since the ‘90’s with respectable discographies and hundreds of gigs under their collective belts.<br>Born from an idea of Francesco Bucci (bass player and songwriter of the extreme epic metal act Stormlord), the five metalheads have joined forces to deliver the heaviest of metal they can muster. ScreaMachine is now eager to unleash its rage worldwide and join fans in their celebration of heavy metal.<br>Come join the cult of the Scream!</p>\n\n<blockquote><p><br><em>“you’ll beg for sparing lives whose meaning’s to be taken,the metal monster rides with fire’s brutal law&nbsp;all that you can do is just bow to the sentence of war“</em></p></blockquote>\n\n<p>ScreaMachine are:</p>\n\n<ul><li>Valerio “The Brave” Caricchio – Lead Vocals</li><li>Francesco Bucci – Bass</li><li>Alex Mele &nbsp;– &nbsp;Guitars</li><li>Paolo Campitelli &nbsp;– &nbsp;Guitars</li><li>Alfonso “Fo” Corace – &nbsp;Drums</li></ul>\n\n<ul><li><strong>Official website</strong>: https://www.screamachineband.com  </li><li><strong>Facebook</strong>: <a rel="noreferrer noopener" href="https://www.facebook.com/screamachineofficial/" target="_blank">https://www.facebook.com/screamachineofficial/</a></li><li><strong>Instagram</strong>: <a rel="noreferrer noopener" href="https://www.instagram.com/screamachineofficial/" target="_blank">https://www.instagram.com/screamachineofficial/ </a></li><li><strong>YouTube</strong>: <a rel="noreferrer noopener" href="https://bit.ly/screaMachine" target="_blank">https://bit.ly/screaMachine</a></li></ul>',content_rendered:'<p><strong>Frontiers Music Srl</strong>&nbsp;is proud to announce the signing of Italy’s ScreaMachine to the label. The band hails from Rome, Italy and are proud heavy metallers. The quintet’s gloriously loud sound is inspired by titans like Judas Priest, early Metallica, early Iced Earth, Savatage and Accept. But even if the guys are in love with the legendary 80’s metal sound, they are not living in the past. Their aim is to deliver an aggressive and traditional heavy metal sound blended with modern production and up-to-date songwriting.</p>\n\n<figure><img src="assets/images/2020/12/119230140_632612420728672_8996527692830816852_o-1024x683.jpg" alt=""/></figure>\n\n<p><br>The musicians involved are no strangers to the metal scene. The members come from respected Italian acts like Stormlord, Kaledon, and Lunarsea, and have been active since the ‘90’s with respectable discographies and hundreds of gigs under their collective belts.<br>Born from an idea of Francesco Bucci (bass player and songwriter of the extreme epic metal act Stormlord), the five metalheads have joined forces to deliver the heaviest of metal they can muster. ScreaMachine is now eager to unleash its rage worldwide and join fans in their celebration of heavy metal.<br>Come join the cult of the Scream!</p>\n\n<blockquote><p><br><em>“you’ll beg for sparing lives whose meaning’s to be taken,the metal monster rides with fire’s brutal law&nbsp;all that you can do is just bow to the sentence of war“</em></p></blockquote>\n\n<p>ScreaMachine are:</p>\n\n<ul><li>Valerio “The Brave” Caricchio – Lead Vocals</li><li>Francesco Bucci – Bass</li><li>Alex Mele &nbsp;– &nbsp;Guitars</li><li>Paolo Campitelli &nbsp;– &nbsp;Guitars</li><li>Alfonso “Fo” Corace – &nbsp;Drums</li></ul>\n\n<ul><li><strong>Official website</strong>: https://www.screamachineband.com  </li><li><strong>Facebook</strong>: <a rel="noreferrer noopener" href="https://www.facebook.com/screamachineofficial/" target="_blank">https://www.facebook.com/screamachineofficial/</a></li><li><strong>Instagram</strong>: <a rel="noreferrer noopener" href="https://www.instagram.com/screamachineofficial/" target="_blank">https://www.instagram.com/screamachineofficial/ </a></li><li><strong>YouTube</strong>: <a rel="noreferrer noopener" href="https://bit.ly/screaMachine" target="_blank">https://bit.ly/screaMachine</a></li></ul>',excerpt:'',thumb_url:'assets/images/2020/12/frontiers_music_logo-1.png',source:'wordpress'},
  {slug:'screamachine-leather-rebel-judas-priest-cover-pandemic-live-session-at-trafalgar-studios',title:'SCREAMACHINE – Leather Rebel (Judas Priest Cover) | Pandemic Live Session at Trafalgar Studios',date:'2020-12-05',categories:["Senza categoria"],content:'<figure><div>\nhttps://youtu.be/xPxYA0ydyKk\n</div></figure>',content_rendered:'<figure><div>\nhttps://youtu.be/xPxYA0ydyKk\n</div></figure>',excerpt:'',thumb_url:'assets/images/2020/12/thumbnail-leather.png',source:'wordpress'},
  {slug:'kalidia-lies-device-2021-mix-and-mastering',title:'KALIDIA - Lies\' Device 2021 (Mix and Mastering)',date:'2020-12-05',categories:["Senza categoria"],content:'<p></p>\n\n<p>Mixed and Mastered by yours truly.</p>\n\n<p>The album will be available on CD, limited vinyl and digital on February 5th via <a href="https://www.facebook.com/innerwoundrecordings/?__cft__[0]=AZWwf-jttANFc_cQztyPg1l8nNcJkmuMV561GpNb1byprFfgY4kJZ5GjlbAVE8HHkQsWHwNhw_tOEp7EEqpgRGE3Mu8YEa3-j_VHtchmArpj5aC56Qd-tmT20P3KKcWsFExMLVQqxz47llKGm95noftF&amp;__tn__=kK-R">Inner Wound Recordings</a>.</p>\n\n<figure><div>\nhttps://youtu.be/8K_nc3EoZbo\n</div></figure>\n\n<figure><div>\nhttps://youtu.be/siqdHlB0OW4\n</div></figure>',content_rendered:'<p></p>\n\n<p>Mixed and Mastered by yours truly.</p>\n\n<p>The album will be available on CD, limited vinyl and digital on February 5th via <a href="https://www.facebook.com/innerwoundrecordings/?__cft__[0]=AZWwf-jttANFc_cQztyPg1l8nNcJkmuMV561GpNb1byprFfgY4kJZ5GjlbAVE8HHkQsWHwNhw_tOEp7EEqpgRGE3Mu8YEa3-j_VHtchmArpj5aC56Qd-tmT20P3KKcWsFExMLVQqxz47llKGm95noftF&amp;__tn__=kK-R">Inner Wound Recordings</a>.</p>\n\n<figure><div>\nhttps://youtu.be/8K_nc3EoZbo\n</div></figure>\n\n<figure><div>\nhttps://youtu.be/siqdHlB0OW4\n</div></figure>',excerpt:'',thumb_url:'assets/images/2020/12/lies-device-2021.jpg',source:'wordpress'},
  {slug:'stl-tones-bass-pack-by-paolo-campitelli',title:'STL Tones Bass Pack by Paolo Campitelli!',date:'2021-01-18',categories:["Senza categoria"],content:'<p>STL Tones has just released their official "STL Bass Pack 1"and I\'m very proud to announce that I have personally profiled and engineered in my studio all the 105 bass profiles for the Kemper Profiler and STL ToneHub plugin! ✌<br>\nAll the most popular metal and rock pedals and amps are available in the pack (Did someone say Ampeg, Sansamp, Darkglass etc.? 🤭), I promise you you won\'t be disappointed! 🔥</p>\n\n<p>Check out samples, additional information, profiles and much more on STL website! </p>\n\n<p><a href="https://www.stltones.com/products/stl-bass-pack-1-tonehub-preset-pack"><strong>https://www.stltones.com/products/stl-bass-pack-1-tonehub-preset-pack</strong></a></p>\n\n<blockquote><p>Enjoy! 💀</p></blockquote>',content_rendered:'<p>STL Tones has just released their official "STL Bass Pack 1"and I\'m very proud to announce that I have personally profiled and engineered in my studio all the 105 bass profiles for the Kemper Profiler and STL ToneHub plugin! ✌<br>\nAll the most popular metal and rock pedals and amps are available in the pack (Did someone say Ampeg, Sansamp, Darkglass etc.? 🤭), I promise you you won\'t be disappointed! 🔥</p>\n\n<p>Check out samples, additional information, profiles and much more on STL website! </p>\n\n<p><a href="https://www.stltones.com/products/stl-bass-pack-1-tonehub-preset-pack"><strong>https://www.stltones.com/products/stl-bass-pack-1-tonehub-preset-pack</strong></a></p>\n\n<blockquote><p>Enjoy! 💀</p></blockquote>',excerpt:'',thumb_url:'assets/images/2021/01/130865099_2734845030164990_7999860584437310806_o.jpg',source:'wordpress'},
  {slug:'demondome-video-out-now',title:'"Demondome" video out now!',date:'2021-02-05',categories:["ScreaMachine", "Senza categoria"],content:'<p>Check out my band Screamachine! Recorded, mixed and mastered by yours truly!</p>\n\n<figure><div>\nhttps://youtu.be/OcV3X_t78lE\n</div></figure>',content_rendered:'<p>Check out my band Screamachine! Recorded, mixed and mastered by yours truly!</p>\n\n<figure><div>\nhttps://youtu.be/OcV3X_t78lE\n</div></figure>',excerpt:'',thumb_url:'assets/images/2021/02/Screenshot-2021-03-12-at-15.47.00.png',source:'wordpress'},
  {slug:'the-metal-monster-out-now',title:'"The Metal Monster" out now!',date:'2021-03-12',categories:["ScreaMachine"],content:'<p>Check out the second single of my new band Screamachine! Recorded, mixed and mastered by yours truly!</p>\n\n<figure><div>\nhttps://youtu.be/nbYKQ084slw\n</div></figure>\n\n<p><br></p>',content_rendered:'<p>Check out the second single of my new band Screamachine! Recorded, mixed and mastered by yours truly!</p>\n\n<figure><div>\nhttps://youtu.be/nbYKQ084slw\n</div></figure>\n\n<p><br></p>',excerpt:'',thumb_url:'assets/images/2021/03/Screenshot-2021-03-12-at-15.44.20.png',source:'wordpress'},
  {slug:'tutorial-how-to-convert-an-old-laptop-to-a-rack-mountable-computer',title:'[TUTORIAL] How to convert an old Laptop to a Rack-Mountable Computer',date:'2021-06-03',categories:["Tutorial"],content:'<p>The reason why I have started this DIY project is pretty simple: I have a homestudio/project studio where I usually have fun recording and mixing albums and, even if I have a pretty powerful computer (<em>Mac Pro Intel Xeon 3.5ghz 12 core, 64gb of ram, nvme hard disk and a Radeon RX580 GPU</em>), plugins are becoming increasingly heavy in terms of CPU power (especially Acustica Audio plugins can really take down your CPU!). On the other hand, I had an unused Sony Vaio Laptop from 2010  (Intel i5 with 4gb of ram) that, even if it is not the fastest computer on the globe, for sure it could be useful for something. </p>\n\n<p>Last year, an open-source project called "<a href="https://audiogridder.com/"><strong>AudioGridder</strong></a>" appears on GitHub: it allows to run plugins on another computer without affecting the main one (like VSL or a UAD card).  It is incredibly promising and I have to say that it works really well, especially with AA plugins due to the efficient management of multitasking/multicore! So why "destroy" my Sony Vaio? Well, because if you have a studio, you surely like rack hardware, pretty obvious right? Rack is always so coooool! :D</p>\n\n<p>Of course, a rack computer like this can be used as a low wattage Linux server, a media-center powered by Plex etc. In short, the possibilities are endless. </p>\n\n<ul><li class="blocks-gallery-item"><figure><img src="assets/images/2021/06/IMG_8153-2-1024x767.jpg" alt="" data-id="1738" data-link="https://www.paolocampitelli.com/img_8153-2/"/><figcaption>Before:</figcaption></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2021/06/IMG_8430-2-1024x768.jpg" alt="" data-id="1737" data-link="https://www.paolocampitelli.com/img_8430-2/"/><figcaption>After!</figcaption></figure></li></ul>\n\n<blockquote><p><em>Before getting started, please notice: you gonna open the laptop and remove the screen etc. therefore there is the possibility of broken it irretrievably; please be very careful! Please also read the entire tutorial before you do anything</em>!</p></blockquote>\n\n<h2>Let\'s start! </h2>\n\n<h4>My shopping list:</h4>\n\n<ul><li><strong>Empty rack case: Adam Hall 87407V (</strong><a href="https://www.thomann.de/it/adam_hall_87407_v_19_1he_leergehaeuse.htm"><strong>Thomann)</strong></a> </li><li>Noctua NT-H1 Thermal Paste (<a href="https://amzn.to/2SRUy7F">Amazon</a>)</li><li>Isopropyl Alcool (<a href="https://amzn.to/3vObWst">Amazon</a>)</li><li>Compressed Air Bottle (<a href="https://amzn.to/3fIiPG1">Amazon</a>)</li><li>USB fan 40x40 (<a href="https://amzn.to/34KbMX2">Amazon</a>)</li><li>HDMI Dummy 4k/1080p adapter (<a href="https://amzn.to/34J8vY1">Amazon</a>)</li><li>HDMI Extension Cable (<a href="https://amzn.to/34JF1JO">Amazon</a>)</li><li>Usb 3.0 Extension Cable (<a href="https://amzn.to/3fJOwyP">Amazon</a>)</li><li>Heat Sinks (<a href="https://amzn.to/3uMtRhY">Amazon</a>)</li><li>Hard Disk SSD 120Gb (<a href="https://amzn.to/34Grcvs">Amazon</a>)</li><li>4/8 Gb of Ram (It depends on your laptop)</li><li>Drill (<a href="https://amzn.to/3g5MWWV">Amazon</a>) </li><li>Drill Bits for Iron/metal (<a href="https://amzn.to/3g6DJO3">Amazon</a>)</li><li>Intel Sticker on Ebay</li></ul>\n\n<p>Ok, it may seem a pretty long list but actually what is mandatory is only the empty rack case. Anyway, I strongly suggest buying also the other stuff and I will explain why in a while.</p>\n\n<p>The first step is to remove the motherboard from the case. As I said before, please be very careful, every laptop is different. Take your time and remove all the components from the motherboard: the monitor, speakers, trackpad, battery etc. </p>\n\n<figure><img src="assets/images/2021/06/IMG_8182-1024x768.jpg" alt=""/><figcaption>The motherboard of my Sony Laptop</figcaption></figure>\n\n<p>After more than 10 years, the temperature of the CPU was extremely high (75/80 degrees after only 1 minute!) and the fan was very noisy. Even if it not mandatory, I strongly suggest cleaning up everything (and thanks me later). You have to remove the dust, especially in the CPU fan using the compressed air bottle and most important, replace the thermal pad on the CPU, removing the heatsink:</p>\n\n<figure><img src="assets/images/2021/06/IMG_8181-1024x768.jpg" alt=""/><figcaption>The original thermal paste was completely burned.</figcaption></figure>\n\n<p>Clean up the old paste with the isopropyl alcohol and replace it with the Noctua thermal paste (which is extremely efficient). After this, you can install the additional ram if needed and of course the new SSD hard disk (SSD hard disks are exceptionally fast compared to the old ones!).</p>\n\n<p>Time to put the motherboard inside the rack! Before doing that, I suggest piercing the rack on the side where the CPU heater is placed in order to improve the heat dissipation:</p>\n\n<figure><img src="assets/images/2021/06/IMG_8415-1024x768.jpg" alt=""/><figcaption>Use drill bits only for iron/metal!</figcaption></figure>\n\n<p>Let\'s move everything in the rack:</p>\n\n<ul><li class="blocks-gallery-item"><figure><img src="assets/images/2021/06/D1E263C5-1555-4AC6-8369-D44AD6F09AE6-1024x576.jpg" alt="" data-id="1744" data-link="https://www.paolocampitelli.com/d1e263c5-1555-4ac6-8369-d44ad6f09ae6/"/></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2021/06/IMG_8421-1024x768.jpg" alt="" data-id="1743" data-link="https://www.paolocampitelli.com/img_8421/"/></figure></li></ul>\n\n<figure><img src="assets/images/2021/06/IMG_8419-1024x768.jpg" alt=""/><figcaption>Almost done!</figcaption></figure>\n\n<h4>Some comments:</h4>\n\n<p>Starting from the left, I have connected the HDMI extender cable to the motherboard in order to facilitate the connection on the back to an external monitor or the dummy HDMI adapter if you wanna use vnc/teamviewer for a remote connection. Why an HDMI dummy adapter? The reason is that, on Windows, you cannot select a resolution higher than the original monitor without it. In this way, I\'m able to select also 1080p/4k. </p>\n\n<p>I have added a USB fan in order to improve the air circulation. It is quite effective. </p>\n\n<p>I have 3 USB ports so I use a USB extension cable in order to facilitate access on the back once the rack is closed.</p>\n\n<p>I have used a USB-to-ethernet adapter since it wasn\'t possible to remove the original one from the case. Not a big issue.</p>\n\n<p>I have connected the power button in front of the rack drilling the case (bottom right in the photo).</p>\n\n<p>What I also did for improving the CPU temperature is to add some heatsink on the original one. I know, it is not very fancy but it works! The temperature has improved by 6/8 degrees!</p>\n\n<figure><img src="assets/images/2021/06/IMG_8455-1024x768.jpg" alt=""/><figcaption>Heatsink on the cpu and southbridge.</figcaption></figure>\n\n<h6><strong>Important</strong>: I suggest installing the operating system before doing this, especially if you don\'t have an external monitor to use. </h6>\n\n<h3>Et voilà! </h3>\n\n<ul><li class="blocks-gallery-item"><figure><img src="assets/images/2021/06/IMG_8430-1024x768.jpg" alt="" data-id="1748" data-link="https://www.paolocampitelli.com/?attachment_id=1748"/><figcaption>I have added an Intel sticker on the left because is cool! You can find it on Ebay.</figcaption></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2021/06/IMG_8458-1024x768.jpg" alt="" data-id="1740" data-link="https://www.paolocampitelli.com/img_8458/"/></figure></li></ul>\n\n<h3>If you are interested in configuring an AudioGridder Server click on the second part of the tutorial <strong><a href="https://www.paolocampitelli.com/2021/06/03/tutorial-how-to-create-a-rack-mountable-server-for-audiogridder/">HERE</a></strong>!</h3>\n\n<h1>Enjoy your rack-mounted server! </h1>',content_rendered:'<p>The reason why I have started this DIY project is pretty simple: I have a homestudio/project studio where I usually have fun recording and mixing albums and, even if I have a pretty powerful computer (<em>Mac Pro Intel Xeon 3.5ghz 12 core, 64gb of ram, nvme hard disk and a Radeon RX580 GPU</em>), plugins are becoming increasingly heavy in terms of CPU power (especially Acustica Audio plugins can really take down your CPU!). On the other hand, I had an unused Sony Vaio Laptop from 2010  (Intel i5 with 4gb of ram) that, even if it is not the fastest computer on the globe, for sure it could be useful for something. </p>\n\n<p>Last year, an open-source project called "<a href="https://audiogridder.com/"><strong>AudioGridder</strong></a>" appears on GitHub: it allows to run plugins on another computer without affecting the main one (like VSL or a UAD card).  It is incredibly promising and I have to say that it works really well, especially with AA plugins due to the efficient management of multitasking/multicore! So why "destroy" my Sony Vaio? Well, because if you have a studio, you surely like rack hardware, pretty obvious right? Rack is always so coooool! :D</p>\n\n<p>Of course, a rack computer like this can be used as a low wattage Linux server, a media-center powered by Plex etc. In short, the possibilities are endless. </p>\n\n<ul><li class="blocks-gallery-item"><figure><img src="assets/images/2021/06/IMG_8153-2-1024x767.jpg" alt="" data-id="1738" data-link="https://www.paolocampitelli.com/img_8153-2/"/><figcaption>Before:</figcaption></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2021/06/IMG_8430-2-1024x768.jpg" alt="" data-id="1737" data-link="https://www.paolocampitelli.com/img_8430-2/"/><figcaption>After!</figcaption></figure></li></ul>\n\n<blockquote><p><em>Before getting started, please notice: you gonna open the laptop and remove the screen etc. therefore there is the possibility of broken it irretrievably; please be very careful! Please also read the entire tutorial before you do anything</em>!</p></blockquote>\n\n<h2>Let\'s start! </h2>\n\n<h4>My shopping list:</h4>\n\n<ul><li><strong>Empty rack case: Adam Hall 87407V (</strong><a href="https://www.thomann.de/it/adam_hall_87407_v_19_1he_leergehaeuse.htm"><strong>Thomann)</strong></a> </li><li>Noctua NT-H1 Thermal Paste (<a href="https://amzn.to/2SRUy7F">Amazon</a>)</li><li>Isopropyl Alcool (<a href="https://amzn.to/3vObWst">Amazon</a>)</li><li>Compressed Air Bottle (<a href="https://amzn.to/3fIiPG1">Amazon</a>)</li><li>USB fan 40x40 (<a href="https://amzn.to/34KbMX2">Amazon</a>)</li><li>HDMI Dummy 4k/1080p adapter (<a href="https://amzn.to/34J8vY1">Amazon</a>)</li><li>HDMI Extension Cable (<a href="https://amzn.to/34JF1JO">Amazon</a>)</li><li>Usb 3.0 Extension Cable (<a href="https://amzn.to/3fJOwyP">Amazon</a>)</li><li>Heat Sinks (<a href="https://amzn.to/3uMtRhY">Amazon</a>)</li><li>Hard Disk SSD 120Gb (<a href="https://amzn.to/34Grcvs">Amazon</a>)</li><li>4/8 Gb of Ram (It depends on your laptop)</li><li>Drill (<a href="https://amzn.to/3g5MWWV">Amazon</a>) </li><li>Drill Bits for Iron/metal (<a href="https://amzn.to/3g6DJO3">Amazon</a>)</li><li>Intel Sticker on Ebay</li></ul>\n\n<p>Ok, it may seem a pretty long list but actually what is mandatory is only the empty rack case. Anyway, I strongly suggest buying also the other stuff and I will explain why in a while.</p>\n\n<p>The first step is to remove the motherboard from the case. As I said before, please be very careful, every laptop is different. Take your time and remove all the components from the motherboard: the monitor, speakers, trackpad, battery etc. </p>\n\n<figure><img src="assets/images/2021/06/IMG_8182-1024x768.jpg" alt=""/><figcaption>The motherboard of my Sony Laptop</figcaption></figure>\n\n<p>After more than 10 years, the temperature of the CPU was extremely high (75/80 degrees after only 1 minute!) and the fan was very noisy. Even if it not mandatory, I strongly suggest cleaning up everything (and thanks me later). You have to remove the dust, especially in the CPU fan using the compressed air bottle and most important, replace the thermal pad on the CPU, removing the heatsink:</p>\n\n<figure><img src="assets/images/2021/06/IMG_8181-1024x768.jpg" alt=""/><figcaption>The original thermal paste was completely burned.</figcaption></figure>\n\n<p>Clean up the old paste with the isopropyl alcohol and replace it with the Noctua thermal paste (which is extremely efficient). After this, you can install the additional ram if needed and of course the new SSD hard disk (SSD hard disks are exceptionally fast compared to the old ones!).</p>\n\n<p>Time to put the motherboard inside the rack! Before doing that, I suggest piercing the rack on the side where the CPU heater is placed in order to improve the heat dissipation:</p>\n\n<figure><img src="assets/images/2021/06/IMG_8415-1024x768.jpg" alt=""/><figcaption>Use drill bits only for iron/metal!</figcaption></figure>\n\n<p>Let\'s move everything in the rack:</p>\n\n<ul><li class="blocks-gallery-item"><figure><img src="assets/images/2021/06/D1E263C5-1555-4AC6-8369-D44AD6F09AE6-1024x576.jpg" alt="" data-id="1744" data-link="https://www.paolocampitelli.com/d1e263c5-1555-4ac6-8369-d44ad6f09ae6/"/></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2021/06/IMG_8421-1024x768.jpg" alt="" data-id="1743" data-link="https://www.paolocampitelli.com/img_8421/"/></figure></li></ul>\n\n<figure><img src="assets/images/2021/06/IMG_8419-1024x768.jpg" alt=""/><figcaption>Almost done!</figcaption></figure>\n\n<h4>Some comments:</h4>\n\n<p>Starting from the left, I have connected the HDMI extender cable to the motherboard in order to facilitate the connection on the back to an external monitor or the dummy HDMI adapter if you wanna use vnc/teamviewer for a remote connection. Why an HDMI dummy adapter? The reason is that, on Windows, you cannot select a resolution higher than the original monitor without it. In this way, I\'m able to select also 1080p/4k. </p>\n\n<p>I have added a USB fan in order to improve the air circulation. It is quite effective. </p>\n\n<p>I have 3 USB ports so I use a USB extension cable in order to facilitate access on the back once the rack is closed.</p>\n\n<p>I have used a USB-to-ethernet adapter since it wasn\'t possible to remove the original one from the case. Not a big issue.</p>\n\n<p>I have connected the power button in front of the rack drilling the case (bottom right in the photo).</p>\n\n<p>What I also did for improving the CPU temperature is to add some heatsink on the original one. I know, it is not very fancy but it works! The temperature has improved by 6/8 degrees!</p>\n\n<figure><img src="assets/images/2021/06/IMG_8455-1024x768.jpg" alt=""/><figcaption>Heatsink on the cpu and southbridge.</figcaption></figure>\n\n<h6><strong>Important</strong>: I suggest installing the operating system before doing this, especially if you don\'t have an external monitor to use. </h6>\n\n<h3>Et voilà! </h3>\n\n<ul><li class="blocks-gallery-item"><figure><img src="assets/images/2021/06/IMG_8430-1024x768.jpg" alt="" data-id="1748" data-link="https://www.paolocampitelli.com/?attachment_id=1748"/><figcaption>I have added an Intel sticker on the left because is cool! You can find it on Ebay.</figcaption></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2021/06/IMG_8458-1024x768.jpg" alt="" data-id="1740" data-link="https://www.paolocampitelli.com/img_8458/"/></figure></li></ul>\n\n<h3>If you are interested in configuring an AudioGridder Server click on the second part of the tutorial <strong><a href="https://www.paolocampitelli.com/2021/06/03/tutorial-how-to-create-a-rack-mountable-server-for-audiogridder/">HERE</a></strong>!</h3>\n\n<h1>Enjoy your rack-mounted server! </h1>',excerpt:'',thumb_url:'assets/images/2021/06/IMG_8430.jpg',source:'wordpress'},
  {slug:'tutorial-how-to-create-a-rack-mountable-server-for-audiogridder',title:'[TUTORIAL] How to create a Rack-Mountable Server for AudioGridder',date:'2021-06-03',categories:["Tutorial"],content:'<p>Welcome to the second part of the tutorial! </p>\n\n<h4>In the first part <strong><a rel="noreferrer noopener" aria-label="HERE (apre in una nuova scheda)" href="https://www.paolocampitelli.com/2021/06/03/tutorial-how-to-convert-an-old-laptop-to-a-rack-mountable-computer/" target="_blank">HERE</a></strong>, I explained to you how to convert an old Laptop to a Rack-Mountable Computer:</h4>\n\n<ul><li class="blocks-gallery-item"><figure><img src="assets/images/2021/06/IMG_8153-2-1024x767.jpg" alt="" data-id="1738" data-link="https://www.paolocampitelli.com/img_8153-2/"/><figcaption>Before:</figcaption></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2021/06/IMG_8430-2-1024x768.jpg" alt="" data-id="1737" data-link="https://www.paolocampitelli.com/img_8430-2/"/><figcaption>After!</figcaption></figure></li></ul>\n\n<p>In this following part, I will explain to you how to create an <a href="https://audiogridder.com/">AudioGridder</a> server. Let\'s start!</p>\n\n<h4>First of all, what is AudioGridder? </h4>\n\n<blockquote><p>"AudioGridder is a network bridge for audio and MIDI that allows for offloading the DSP processing of audio plugins to remote computers. This can come in handy when mixing complex projects or running CPU intensive instruments."</p></blockquote>\n\n<p>Audiogridder is very useful especially with Acustica Audio plugins which are extremely CPU intensive. </p>\n\n<p>What you need in terms of hardware is a direct lan connection between the two computers, avoiding the router. This is extremely important if you want to run plugins smoothly. On my Mac Pro, I have two ethernet ports so the main one is connected to the router for the internet connection, the second one is connected to my audiogridder server with a static IP. If your computer doesn\'t have two ethernet ports it is not a problem: simply buy a USB-to-Ethernet adapter (<a href="https://amzn.to/3g4TIMx">Amazon</a>) and you are done.</p>\n\n<h4>Let\'s configure our machines!</h4>\n\n<p>The correct configuration of the ethernet connection is <strong>crucial</strong>. My server is based on Windows 10 but you can also use a Mac.</p>\n\n<p>First step: let\'s configure the network settings on Windows 10 and configure the network settings as below:</p>\n\n<figure><img src="assets/images/2021/06/Schermata-2021-06-03-alle-18.24.03-1024x593.png" alt=""/><figcaption>Of course 6.6.6.6 is an arbitrary IP address.</figcaption></figure>\n\n<p>Let\'s move to the host (in my case Mac OS), open the network settings and assign another arbitrary IP address:</p>\n\n<figure><img src="assets/images/2021/06/Schermata-2021-06-03-alle-18.27.24-1024x802.png" alt=""/></figure>\n\n<p>No router IP address in both cases, simply the IP address and subnet mask. I have also disabled Windows Defender Firewall on Windows 10 for better compatibility since the computer is not connected to the internet.</p>\n\n<p>I also suggest enabling the auto-login on boot avoiding using a password. You can enable the autologin using the netplwiz command (Win+R) and deselect the option related to the password at login. Only in this way you can start using AudioGridder simply by switching on the computer. I also suggest to select "switch off the computer when power button is pressed" under the power setting: in this way you will be able to switch on and off the server without a monitor/vnc:</p>\n\n<figure><img src="assets/images/2021/06/Screenshot-2021-06-08-at-16.23.37-1024x619.png" alt=""/></figure>\n\n<p>Anyway, if you need to manage the computer you can use VNC or Teamviewer:</p>\n\n<figure><img src="assets/images/2021/06/Schermata-2021-06-03-alle-20.11.29-2-1024x576.png" alt=""/><figcaption>TightVNC runs on my Mac OS.</figcaption></figure>\n\n<p><em>(Teamviewer is more user friendly, I tend to prefer TightVNC as server because is lighter but they both work great!)</em></p>\n\n<h4>Time to install AudioGridder!</h4>\n\n<p>Open the official website <a href="https://audiogridder.com/">https://audiogridder.com/</a> and download the stable version. Personally, I do not recommend beta versions if you are focused on stability but of course, it\'s up to you :)</p>\n\n<p>Download the server installer on Windows and the plugin installer in your host (in my case Mac OS). Once finished, AudioGridder server will scan all the plugins installed on your Windows computer. Below my settings:</p>\n\n<div><figure class="aligncenter"><img src="assets/images/2021/06/Schermata-2021-06-03-alle-18.44.02.png" alt=""/><figcaption>I have selected Screen Capturing Quality as High since it is a direct ethernet connection. Of course you have to run audiogridder at startup.</figcaption></figure></div>\n\n<p>Let\'s move to the host (in my case Mac OS with Logic Pro X) and open the audiogridder plugin:</p>\n\n<div><figure class="aligncenter is-resized"><img src="assets/images/2021/06/Schermata-2021-06-03-alle-18.58.30.png" alt="" width="254" height="253"/></figure></div>\n\n<p>Click on "Add" and select the server IP (in our case 6.6.6.6). Done!</p>\n\n<p>Let\'s try a plugin!</p>\n\n<figure><img src="assets/images/2021/06/Schermata-2021-06-03-alle-19.15.55-1024x455.png" alt=""/><figcaption>Coffee plugin by Acustica Audio with Preamp module enabled!</figcaption></figure>\n\n<ul><li class="blocks-gallery-item"><figure><img src="assets/images/2021/06/Schermata-2021-06-03-alle-19.22.21.png" alt="" data-id="1769" data-link="https://www.paolocampitelli.com/?attachment_id=1769"/><figcaption>Logic Pro X Meter: Coffee as Native Plugin on the Mac Pro</figcaption></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2021/06/Schermata-2021-06-03-alle-19.21.20-1.png" alt="" data-id="1770" data-link="https://www.paolocampitelli.com/?attachment_id=1770"/><figcaption>Logic Pro X Meter: Coffee hosted on AudioGridder server!</figcaption></figure></li></ul>\n\n<h4>Benchmark time!</h4>\n\n<p><em>Hardware/Software setup: </em></p>\n\n<p><em><strong>Host</strong>: Mac Pro 5.1 (Intel Xeon 12 Core 3.5ghz, 64Gb of Ram) | Logic Pro X 10.5.1 (44.1, 1024 buffer) on Mac OS 10.14. </em></p>\n\n<p><em><strong>Server</strong>: Audiogridder Rack Server (Intel i5 480m 2 core, 2.67ghz, 8Gb of Ram) | Windows 10.</em></p>\n\n<p><strong>AudioGridder</strong>: <strong>16</strong> instances of Acustica Audio Coffee with Preamp Emulation Enabled:</p>\n\n<figure><img src="assets/images/2021/06/Schermata-2021-06-03-alle-19.44.43-1024x576.png" alt=""/><figcaption>Audiogridder CPU: 99%</figcaption></figure>\n\n<p><strong>Mac Pro</strong>: <strong>47</strong> instances of Acustica Audio Coffee with Preamp Emulation Enabled:</p>\n\n<figure><img src="assets/images/2021/06/Schermata-2021-06-03-alle-19.51.47-1024x576.png" alt=""/><figcaption>Logic Pro X has a good multitasking engine!</figcaption></figure>\n\n<h3>Conclusions:</h3>\n\n<p>Although the Mac Pro is obviously the winner, audiogridder result is absolutely impressive (It runs on an Intel i5 mobile with only 2 cores!) and it can really help our mixing sessions. Remember that AA plugins are really CPU intensive, probably the heaviest plugins on the market so you will be able to run hundreds on standard plugin on this old machine.</p>\n\n<p>Audiogridder also supports Midi and Virtual Instruments, really impressive. If you like this software, please remember to donate something to the developer <a rel="noreferrer noopener" aria-label="HERE (apre in una nuova scheda)" href="https://donorbox.org/audiogridder?default_interval=o" target="_blank">HERE</a>, he deserves it! Awesome job Mr. Andreas Pohl! :D</p>\n\n<h1>Enjoy your AudioGridder Server!</h1>\n\n<p></p>',content_rendered:'<p>Welcome to the second part of the tutorial! </p>\n\n<h4>In the first part <strong><a rel="noreferrer noopener" aria-label="HERE (apre in una nuova scheda)" href="https://www.paolocampitelli.com/2021/06/03/tutorial-how-to-convert-an-old-laptop-to-a-rack-mountable-computer/" target="_blank">HERE</a></strong>, I explained to you how to convert an old Laptop to a Rack-Mountable Computer:</h4>\n\n<ul><li class="blocks-gallery-item"><figure><img src="assets/images/2021/06/IMG_8153-2-1024x767.jpg" alt="" data-id="1738" data-link="https://www.paolocampitelli.com/img_8153-2/"/><figcaption>Before:</figcaption></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2021/06/IMG_8430-2-1024x768.jpg" alt="" data-id="1737" data-link="https://www.paolocampitelli.com/img_8430-2/"/><figcaption>After!</figcaption></figure></li></ul>\n\n<p>In this following part, I will explain to you how to create an <a href="https://audiogridder.com/">AudioGridder</a> server. Let\'s start!</p>\n\n<h4>First of all, what is AudioGridder? </h4>\n\n<blockquote><p>"AudioGridder is a network bridge for audio and MIDI that allows for offloading the DSP processing of audio plugins to remote computers. This can come in handy when mixing complex projects or running CPU intensive instruments."</p></blockquote>\n\n<p>Audiogridder is very useful especially with Acustica Audio plugins which are extremely CPU intensive. </p>\n\n<p>What you need in terms of hardware is a direct lan connection between the two computers, avoiding the router. This is extremely important if you want to run plugins smoothly. On my Mac Pro, I have two ethernet ports so the main one is connected to the router for the internet connection, the second one is connected to my audiogridder server with a static IP. If your computer doesn\'t have two ethernet ports it is not a problem: simply buy a USB-to-Ethernet adapter (<a href="https://amzn.to/3g4TIMx">Amazon</a>) and you are done.</p>\n\n<h4>Let\'s configure our machines!</h4>\n\n<p>The correct configuration of the ethernet connection is <strong>crucial</strong>. My server is based on Windows 10 but you can also use a Mac.</p>\n\n<p>First step: let\'s configure the network settings on Windows 10 and configure the network settings as below:</p>\n\n<figure><img src="assets/images/2021/06/Schermata-2021-06-03-alle-18.24.03-1024x593.png" alt=""/><figcaption>Of course 6.6.6.6 is an arbitrary IP address.</figcaption></figure>\n\n<p>Let\'s move to the host (in my case Mac OS), open the network settings and assign another arbitrary IP address:</p>\n\n<figure><img src="assets/images/2021/06/Schermata-2021-06-03-alle-18.27.24-1024x802.png" alt=""/></figure>\n\n<p>No router IP address in both cases, simply the IP address and subnet mask. I have also disabled Windows Defender Firewall on Windows 10 for better compatibility since the computer is not connected to the internet.</p>\n\n<p>I also suggest enabling the auto-login on boot avoiding using a password. You can enable the autologin using the netplwiz command (Win+R) and deselect the option related to the password at login. Only in this way you can start using AudioGridder simply by switching on the computer. I also suggest to select "switch off the computer when power button is pressed" under the power setting: in this way you will be able to switch on and off the server without a monitor/vnc:</p>\n\n<figure><img src="assets/images/2021/06/Screenshot-2021-06-08-at-16.23.37-1024x619.png" alt=""/></figure>\n\n<p>Anyway, if you need to manage the computer you can use VNC or Teamviewer:</p>\n\n<figure><img src="assets/images/2021/06/Schermata-2021-06-03-alle-20.11.29-2-1024x576.png" alt=""/><figcaption>TightVNC runs on my Mac OS.</figcaption></figure>\n\n<p><em>(Teamviewer is more user friendly, I tend to prefer TightVNC as server because is lighter but they both work great!)</em></p>\n\n<h4>Time to install AudioGridder!</h4>\n\n<p>Open the official website <a href="https://audiogridder.com/">https://audiogridder.com/</a> and download the stable version. Personally, I do not recommend beta versions if you are focused on stability but of course, it\'s up to you :)</p>\n\n<p>Download the server installer on Windows and the plugin installer in your host (in my case Mac OS). Once finished, AudioGridder server will scan all the plugins installed on your Windows computer. Below my settings:</p>\n\n<div><figure class="aligncenter"><img src="assets/images/2021/06/Schermata-2021-06-03-alle-18.44.02.png" alt=""/><figcaption>I have selected Screen Capturing Quality as High since it is a direct ethernet connection. Of course you have to run audiogridder at startup.</figcaption></figure></div>\n\n<p>Let\'s move to the host (in my case Mac OS with Logic Pro X) and open the audiogridder plugin:</p>\n\n<div><figure class="aligncenter is-resized"><img src="assets/images/2021/06/Schermata-2021-06-03-alle-18.58.30.png" alt="" width="254" height="253"/></figure></div>\n\n<p>Click on "Add" and select the server IP (in our case 6.6.6.6). Done!</p>\n\n<p>Let\'s try a plugin!</p>\n\n<figure><img src="assets/images/2021/06/Schermata-2021-06-03-alle-19.15.55-1024x455.png" alt=""/><figcaption>Coffee plugin by Acustica Audio with Preamp module enabled!</figcaption></figure>\n\n<ul><li class="blocks-gallery-item"><figure><img src="assets/images/2021/06/Schermata-2021-06-03-alle-19.22.21.png" alt="" data-id="1769" data-link="https://www.paolocampitelli.com/?attachment_id=1769"/><figcaption>Logic Pro X Meter: Coffee as Native Plugin on the Mac Pro</figcaption></figure></li><li class="blocks-gallery-item"><figure><img src="assets/images/2021/06/Schermata-2021-06-03-alle-19.21.20-1.png" alt="" data-id="1770" data-link="https://www.paolocampitelli.com/?attachment_id=1770"/><figcaption>Logic Pro X Meter: Coffee hosted on AudioGridder server!</figcaption></figure></li></ul>\n\n<h4>Benchmark time!</h4>\n\n<p><em>Hardware/Software setup: </em></p>\n\n<p><em><strong>Host</strong>: Mac Pro 5.1 (Intel Xeon 12 Core 3.5ghz, 64Gb of Ram) | Logic Pro X 10.5.1 (44.1, 1024 buffer) on Mac OS 10.14. </em></p>\n\n<p><em><strong>Server</strong>: Audiogridder Rack Server (Intel i5 480m 2 core, 2.67ghz, 8Gb of Ram) | Windows 10.</em></p>\n\n<p><strong>AudioGridder</strong>: <strong>16</strong> instances of Acustica Audio Coffee with Preamp Emulation Enabled:</p>\n\n<figure><img src="assets/images/2021/06/Schermata-2021-06-03-alle-19.44.43-1024x576.png" alt=""/><figcaption>Audiogridder CPU: 99%</figcaption></figure>\n\n<p><strong>Mac Pro</strong>: <strong>47</strong> instances of Acustica Audio Coffee with Preamp Emulation Enabled:</p>\n\n<figure><img src="assets/images/2021/06/Schermata-2021-06-03-alle-19.51.47-1024x576.png" alt=""/><figcaption>Logic Pro X has a good multitasking engine!</figcaption></figure>\n\n<h3>Conclusions:</h3>\n\n<p>Although the Mac Pro is obviously the winner, audiogridder result is absolutely impressive (It runs on an Intel i5 mobile with only 2 cores!) and it can really help our mixing sessions. Remember that AA plugins are really CPU intensive, probably the heaviest plugins on the market so you will be able to run hundreds on standard plugin on this old machine.</p>\n\n<p>Audiogridder also supports Midi and Virtual Instruments, really impressive. If you like this software, please remember to donate something to the developer <a rel="noreferrer noopener" aria-label="HERE (apre in una nuova scheda)" href="https://donorbox.org/audiogridder?default_interval=o" target="_blank">HERE</a>, he deserves it! Awesome job Mr. Andreas Pohl! :D</p>\n\n<h1>Enjoy your AudioGridder Server!</h1>\n\n<p></p>',excerpt:'',thumb_url:'assets/images/2021/06/IMG_8458.jpg',source:'wordpress'},
  {slug:'drag-me-to-hell-by-alterium-new-single-out-now',title:'"Drag me to Hell" by Alterium: new single out now!',date:'2023-09-01',categories:["Senza categoria"],content:'<p>Happy to share with you the first single of my new band.</p>\n\n<p>Check it out and follow on our social pages!</p>\n\n<figure><div>\nhttps://youtu.be/CnDVSF6tIvQ?si=7MMO56AcMmUqcDOv\n</div></figure>',content_rendered:'<p>Happy to share with you the first single of my new band.</p>\n\n<p>Check it out and follow on our social pages!</p>\n\n<figure><div>\nhttps://youtu.be/CnDVSF6tIvQ?si=7MMO56AcMmUqcDOv\n</div></figure>',excerpt:'',thumb_url:'assets/images/2023/09/Drag-Me-to-Hell-artwork.jpg',source:'wordpress'},
  {slug:'yamaha-spx90-warning-low-battery-message-how-to-fix',title:'Yamaha SPX90 "Warning Low Battery" message - HOW TO FIX',date:'2025-03-03',categories:["Tutorial"],content:'<p><strong>How to Fix the Battery Low Error on the Yamaha SPX90</strong></p>\n\n<p>If you own a Yamaha SPX90, you might eventually run into the "Battery Low" error. Over time, the internal backup battery loses charge, and replacing it becomes necessary. I recently replaced mine, and despite installing a brand-new battery, the error persisted. Here’s how I fixed it.</p>\n\n<h3>Replacing the Battery</h3>\n\n<p>The original SPX90 battery is soldered onto the board, which makes replacement a bit tricky. Instead of just replacing the battery, I opted to install a CR2032 battery holder to make future replacements much easier. If you’re planning to do the same, follow these steps:</p>\n\n<ol><li>Desolder the old battery carefully.</li><li>Solder a <a href="https://amzn.to/41qZ8sS">CR2032 battery holder</a> in its place.</li><li>Insert a fresh CR2032 battery, ensuring correct polarity.</li><li>Reassemble the unit and power it on.</li></ol>\n\n<figure><img src="assets/images/2025/03/11A94473-723E-4580-9851-353ECA962F81-1024x888.jpg" alt=""/></figure>\n\n<h3>Resetting the Error</h3>\n\n<p>Even with a new battery, the SPX90 might still display the "Battery Low" warning. To clear the error, follow these steps:</p>\n\n<ol><li><strong>Ensure the new CR2032 battery is installed correctly.</strong> Double-check the polarity and that the battery holder has good contact.</li><li><strong>Perform a system reset:</strong></li></ol>\n\n<ul><li>Turn off the SPX90.</li><li>Hold down the <strong>[BALANCE]</strong> and <strong>[FOOT TRIGGER]</strong> buttons simultaneously.</li><li>While holding them, turn the unit back on.</li></ul>\n\n<p>This should clear the battery warning, and your SPX90 will be good to go.</p>\n\n<p>Your welcome.</p>',content_rendered:'<p><strong>How to Fix the Battery Low Error on the Yamaha SPX90</strong></p>\n\n<p>If you own a Yamaha SPX90, you might eventually run into the "Battery Low" error. Over time, the internal backup battery loses charge, and replacing it becomes necessary. I recently replaced mine, and despite installing a brand-new battery, the error persisted. Here’s how I fixed it.</p>\n\n<h3>Replacing the Battery</h3>\n\n<p>The original SPX90 battery is soldered onto the board, which makes replacement a bit tricky. Instead of just replacing the battery, I opted to install a CR2032 battery holder to make future replacements much easier. If you’re planning to do the same, follow these steps:</p>\n\n<ol><li>Desolder the old battery carefully.</li><li>Solder a <a href="https://amzn.to/41qZ8sS">CR2032 battery holder</a> in its place.</li><li>Insert a fresh CR2032 battery, ensuring correct polarity.</li><li>Reassemble the unit and power it on.</li></ol>\n\n<figure><img src="assets/images/2025/03/11A94473-723E-4580-9851-353ECA962F81-1024x888.jpg" alt=""/></figure>\n\n<h3>Resetting the Error</h3>\n\n<p>Even with a new battery, the SPX90 might still display the "Battery Low" warning. To clear the error, follow these steps:</p>\n\n<ol><li><strong>Ensure the new CR2032 battery is installed correctly.</strong> Double-check the polarity and that the battery holder has good contact.</li><li><strong>Perform a system reset:</strong></li></ol>\n\n<ul><li>Turn off the SPX90.</li><li>Hold down the <strong>[BALANCE]</strong> and <strong>[FOOT TRIGGER]</strong> buttons simultaneously.</li><li>While holding them, turn the unit back on.</li></ul>\n\n<p>This should clear the battery warning, and your SPX90 will be good to go.</p>\n\n<p>Your welcome.</p>',excerpt:'',thumb_url:'assets/images/2025/03/o0640048013649318751.jpg',source:'wordpress'},
  {slug:'apple-mac-studio-ethernet-disconnections-and-issues-here-the-fix',title:'Apple Mac Studio - Ethernet disconnections and issues? Here the fix!',date:'2025-03-25',categories:["Senza categoria", "Tutorial"],content:'<p>I recently purchased a fantastic Apple Mac Studio with an M3 Ultra processor (w/ 28 core) and 96GB of RAM. It’s truly an outstanding device, and I’m extremely satisfied with it.</p>\n\n<p>After installing all system updates and reinstalling my essential software, I noticed that the Ethernet connection was intermittently disconnecting every 10-15 minutes. This issue wasn’t limited to just internet access but also affected my local network (LAN), which raised some concerns.</p>\n\n<p>At home, I have a 5Gbps FTTH fiber connection, and my Ethernet port is 2.5Gbps (the Mac Studio even supports 10Gbps). To fix this issue, you need to manually adjust the Ethernet hardware settings as shown in the screenshot.</p>\n\n<figure><img src="assets/images/2025/03/Screenshot-2025-03-25-at-14.05.40-1024x913.png" alt=""/><figcaption>(System Settings → Network → Ethernet → Details → Hardware)</figcaption></figure>\n\n<p>Hope this helps someone!</p>\n\n<p>Enjoy your Mac Studio! </p>',content_rendered:'<p>I recently purchased a fantastic Apple Mac Studio with an M3 Ultra processor (w/ 28 core) and 96GB of RAM. It’s truly an outstanding device, and I’m extremely satisfied with it.</p>\n\n<p>After installing all system updates and reinstalling my essential software, I noticed that the Ethernet connection was intermittently disconnecting every 10-15 minutes. This issue wasn’t limited to just internet access but also affected my local network (LAN), which raised some concerns.</p>\n\n<p>At home, I have a 5Gbps FTTH fiber connection, and my Ethernet port is 2.5Gbps (the Mac Studio even supports 10Gbps). To fix this issue, you need to manually adjust the Ethernet hardware settings as shown in the screenshot.</p>\n\n<figure><img src="assets/images/2025/03/Screenshot-2025-03-25-at-14.05.40-1024x913.png" alt=""/><figcaption>(System Settings → Network → Ethernet → Details → Hardware)</figcaption></figure>\n\n<p>Hope this helps someone!</p>\n\n<p>Enjoy your Mac Studio! </p>',excerpt:'',thumb_url:'assets/images/2025/03/IMG_8114.jpeg',source:'wordpress'},
  {slug:'alterium-paradise-lost-out-now',title:'Alterium - "Paradise Lost" OUT NOW!',date:'2025-08-29',categories:["Musica"],content:'<p>I had the pleasure of producing, mixing and mastering this amazing Symphony X cover – hope you’ll enjoy it! I also took care of the video too, because… why not? 🙂</p>\n\n<figure><div>\nhttps://www.youtube.com/watch?v=mILaIBIxudQ\n</div></figure>\n\n<p></p>',content_rendered:'<p>I had the pleasure of producing, mixing and mastering this amazing Symphony X cover – hope you’ll enjoy it! I also took care of the video too, because… why not? 🙂</p>\n\n<figure><div>\nhttps://www.youtube.com/watch?v=mILaIBIxudQ\n</div></figure>\n\n<p></p>',excerpt:'',thumb_url:'assets/images/2025/08/thumbnail-1.jpeg',source:'wordpress'},
];

// ═══════════════════════════════════════════════════════
//  STATE
// ═══════════════════════════════════════════════════════
let siteData = { albums: [...ALBUMS_DEFAULT], gallery: {...GALLERY_DEFAULT}, posts: [...POSTS_DEFAULT] };
let currentRoute = '/';
let lbImages = [], lbIndex = 0;
let adminLoggedIn = false;
let editingAlbumSlug = null;

// ═══════════════════════════════════════════════════════
//  LOAD DATA
// ═══════════════════════════════════════════════════════
async function loadSiteData() {
  try {
    const r = await fetch('data/site-data.json?v=' + Date.now());
    if (r.ok) { const d = await r.json(); if (d.albums) siteData = d; }
  } catch(e) {}
}

// ═══════════════════════════════════════════════════════
//  ROUTER
// ═══════════════════════════════════════════════════════
const PAGES = {
  '/': 'page-home',
  '/about': 'page-about',
  '/discography': 'page-discography',
  '/studio': 'page-studio',
  '/gallery': 'page-gallery',
  '/shop': 'page-shop',
  '/apps': 'page-apps',
  '/contact': 'page-contact',
  '/blog': 'page-blog',
  '/admin': 'admin-page'
};

function navigate(path) {
  history.pushState({}, '', '#' + path);
  renderRoute(path);
}

function renderRoute(path) {
  const blogMatch = path.match(/^\/blog\/(.+)$/);
  const route = blogMatch ? '/blog/:slug' : path;

  document.querySelectorAll('.page, #admin-page').forEach(p => {
    p.classList.remove('active');
    p.style.display = 'none';
  });
  document.querySelectorAll('.nav-links a').forEach(a => a.classList.remove('active'));
  window.scrollTo(0,0);
  currentRoute = path;

  if (blogMatch) {
    const el = document.getElementById('page-blog-single');
    if (el) { el.classList.add('active'); el.style.display = 'block'; }
    renderBlogSingle(blogMatch[1]);
    return;
  }

  const pageId = PAGES[path] || 'page-home';
  const el = document.getElementById(pageId);
  if (el) { el.classList.add('active'); el.style.display = 'block'; }

  const navPath = path === '/' ? '/' : path;
  document.querySelectorAll('.nav-links a').forEach(a => {
    if (a.getAttribute('onclick') && a.getAttribute('onclick').includes("'" + navPath + "'")) {
      a.classList.add('active');
    }
  });

  // Close mobile menu
  document.getElementById('nav-links').classList.remove('open');

  switch(path) {
    case '/': renderHome(); break;
    case '/discography': renderDiscography(); break;
    case '/studio': renderStudio(); break;
    case '/gallery': renderGallery('studio'); break;
    case '/blog': renderBlog(); break;
    case '/admin': window.location.href = 'login.php'; break;
  }

  // Trigger reveal animations
  setTimeout(initReveal, 100);
}

window.addEventListener('popstate', () => {
  const hash = location.hash.replace('#','') || '/';
  renderRoute(hash);
});

// ═══════════════════════════════════════════════════════
//  RENDER HOME
// ═══════════════════════════════════════════════════════
function renderHome() {
  const latest = siteData.albums.slice(-6).reverse();
  const grid = document.getElementById('home-latest-grid');
  if (!grid) return;
  grid.innerHTML = latest.map(a => `
    <div class="latest-card" onclick="navigate('/discography')">
      <img src="${a.cover}" alt="${a.title}" loading="lazy" onerror="this.style.background='var(--s2)'">
      <div class="latest-card-body">
        <div class="latest-card-year">${a.year}</div>
        <div class="latest-card-title">${a.title.replace(/"/g,'&quot;')}</div>
        <div class="latest-card-artist">${a.artist}</div>
      </div>
    </div>`).join('');
}

// ═══════════════════════════════════════════════════════
//  RENDER DISCOGRAPHY
// ═══════════════════════════════════════════════════════
let discoFilter = 'all';
function renderDiscography(filter) {
  if (filter !== undefined) discoFilter = filter;
  const grid = document.getElementById('disco-grid');
  if (!grid) return;

  const albums = [...siteData.albums].reverse();
  const filtered = albums.filter(a => {
    if (discoFilter === 'all') return true;
    if (discoFilter === 'producer') return a.producer && a.producer.toLowerCase().includes('campitelli');
    return a.artist.toLowerCase().includes(discoFilter) || a.title.toLowerCase().includes(discoFilter) || a.slug.includes(discoFilter);
  });

  grid.innerHTML = filtered.map(a => {
    const role = (a.producer && a.producer.toLowerCase().includes('campitelli')) ? 'Producer' :
                 (a.artist.toLowerCase().includes('screamachine') || a.artist.toLowerCase().includes('alterium') || a.artist.toLowerCase().includes('kaledon')) ? 'Musician' : 'Engineer';
    return `
    <div class="disco-card" onclick="openAlbumModal('${a.slug}')">
      <img src="${a.cover}" alt="${a.title}" loading="lazy" onerror="this.style.background='var(--s2)'">
      <div class="disco-card-role">${role}</div>
      <div class="disco-card-overlay">
        <div class="disco-card-year">${a.year}</div>
        <div class="disco-card-title">${a.title}</div>
        <div class="disco-card-artist">${a.artist}</div>
        ${a.credits ? '<div style="font-size:.62rem;color:rgba(200,150,62,.8);margin-top:.3rem;font-style:italic">'+a.credits+'</div>' : ''}
        ${a.youtube ? '<div class="disco-card-yt">▶ Watch on YouTube</div>' : ''}
      </div>
    </div>`;
  }).join('');

  // Filter buttons
  document.querySelectorAll('#disco-filter .filter-btn').forEach(btn => {
    btn.classList.toggle('active', btn.dataset.filter === discoFilter);
    btn.onclick = () => renderDiscography(btn.dataset.filter);
  });
}

function openAlbumModal(slug) {
  const a = siteData.albums.find(x => x.slug === slug);
  if (!a) return;
  document.getElementById('modal-img').src = a.cover;
  document.getElementById('modal-img').alt = a.title;
  document.getElementById('modal-artist').textContent = a.artist;
  document.getElementById('modal-title').textContent = a.title;
  const meta = [];
  if (a.year) meta.push(`<div class="album-modal-meta-row"><span class="album-modal-meta-key">Year</span><span class="album-modal-meta-val">${a.year}</span></div>`);
  if (a.label) meta.push(`<div class="album-modal-meta-row"><span class="album-modal-meta-key">Label</span><span class="album-modal-meta-val">${a.label}</span></div>`);
  if (a.producer) meta.push(`<div class="album-modal-meta-row"><span class="album-modal-meta-key">Producer</span><span class="album-modal-meta-val">${a.producer}</span></div>`);
  if (a.credits) meta.push(`<div class="album-modal-meta-row"><span class="album-modal-meta-key">Credits</span><span class="album-modal-meta-val" style="color:var(--accent);font-style:italic">${a.credits}</span></div>`);
  document.getElementById('modal-meta').innerHTML = meta.join('');
  document.getElementById('modal-yt').innerHTML = a.youtube
    ? `<a href="${a.youtube}" target="_blank" class="btn btn-ghost" style="margin-top:.5rem;font-size:.7rem">▶ Watch on YouTube</a>` : '';
  const modal = document.getElementById('album-modal');
  modal.classList.add('open');
  modal.onclick = e => { if (e.target === modal) closeAlbumModal(); };
}
function closeAlbumModal() { document.getElementById('album-modal').classList.remove('open'); }

// ═══════════════════════════════════════════════════════
//  RENDER STUDIO
// ═══════════════════════════════════════════════════════
function renderStudio() {
  const el = document.getElementById('studio-content');
  if (!el || el.innerHTML) return;
  el.innerHTML = `<div class="wss" id="wss-studio">
<div class="wss-body">
  <div class="wss-divider">Hardware</div>
  <div class="wss-cols">
    <div>
      <div class="wss-cat"><div class="wss-cat-title">Workstation &amp; Monitoring</div>
        <ul class="wss-tags">
          <li class="wss-tag accent">Mac Studio M3 Ultra 24-core / 96GB RAM</li>
          <li class="wss-tag">Yamaha NS10</li><li class="wss-tag">Mission LX2</li>
          <li class="wss-tag">Sonarworks SoundID Reference</li>
          <li class="wss-tag">Audeze LCD-X</li><li class="wss-tag">Sienna Reference Correction</li>
        </ul>
      </div>
      <div class="wss-cat"><div class="wss-cat-title">Interfaces &amp; Preamps</div>
        <ul class="wss-tags">
          <li class="wss-tag">UA Apollo Thunderbolt</li><li class="wss-tag">UAD Satellite 8 DSP</li>
          <li class="wss-tag">BAE 1073</li><li class="wss-tag">Neve 1073 (Stam Edition)</li>
        </ul>
      </div>
      <div class="wss-cat"><div class="wss-cat-title">Effects &amp; Compressors</div>
        <ul class="wss-tags">
          <li class="wss-tag">Lexicon PCM80</li><li class="wss-tag">Yamaha SPX90/900</li>
          <li class="wss-tag">Eventide H3000</li><li class="wss-tag">Klark Teknik Dimension D</li>
          <li class="wss-tag">Empirical Labs Distressor</li>
          <li class="wss-tag">Warm Audio 1176</li><li class="wss-tag">SSL G4000 Buss</li>
        </ul>
      </div>
      <div class="wss-cat"><div class="wss-cat-title">Bass</div>
        <ul class="wss-tags">
          <li class="wss-tag">Ampeg SVP Pro</li><li class="wss-tag">Sansamp PSA-1 &amp; RBI</li>
          <li class="wss-tag">DarkGlass Alpha Omega Ultra</li>
          <li class="wss-tag">DarkGlass B7K</li><li class="wss-tag">Microtubes X Ultra</li>
        </ul>
      </div>
    </div>
    <div>
      <div class="wss-cat"><div class="wss-cat-title">Guitar Amps &amp; Cabinets</div>
        <ul class="wss-tags">
          <li class="wss-tag">Peavey 6505</li>
          <li class="wss-tag">Mesa Boogie Dual Rectifier (1996)</li>
          <li class="wss-tag">Engl Blackmore Signature</li>
          <li class="wss-tag">Marshall JVM410</li><li class="wss-tag">Marshall Valvestate</li>
          <li class="wss-tag">Mesa 4x12 Oversize V30</li><li class="wss-tag">St-rock React:IR</li>
        </ul>
      </div>
      <div class="wss-cat"><div class="wss-cat-title">Digital Systems</div>
        <ul class="wss-tags">
          <li class="wss-tag">Kemper Profiler</li><li class="wss-tag">Line6 Helix</li>
          <li class="wss-tag">IK Multimedia TONEX</li>
        </ul>
      </div>
      <div class="wss-cat"><div class="wss-cat-title">Keys, Synths &amp; Drums</div>
        <ul class="wss-tags">
          <li class="wss-tag">Korg Kronos</li><li class="wss-tag">Korg 01/WF</li>
          <li class="wss-tag">Nord Wave</li><li class="wss-tag">KORG Concert 7000</li>
          <li class="wss-tag">Korg Trinity V3</li><li class="wss-tag">Moog Sub37</li>
          <li class="wss-tag">IK UNO Synth</li><li class="wss-tag">Alesis DM10 Studio E-Drum</li>
        </ul>
      </div>
      <div class="wss-cat"><div class="wss-cat-title">Microphones</div>
        <ul class="wss-tags">
          <li class="wss-tag">Shure</li><li class="wss-tag">Royer</li>
          <li class="wss-tag">Warm Audio</li><li class="wss-tag">Neumann</li>
          <li class="wss-tag">Studio Projects</li><li class="wss-tag">AKG</li>
        </ul>
      </div>
    </div>
  </div>
  <div class="wss-divider" style="margin-top:2rem">Software</div>
  <div class="wss-cols">
    <div>
      <div class="wss-cat"><div class="wss-cat-title">DAW</div>
        <ul class="wss-tags">
          <li class="wss-tag main-daw">Logic Pro</li>
          <li class="wss-tag">UA Luna</li><li class="wss-tag">Cubase</li>
          <li class="wss-tag">Studio One</li><li class="wss-tag">Reaper</li>
          <li class="wss-tag no-thanks">No sorry, I hate Pro Tools :)</li>
        </ul>
      </div>
      <div class="wss-cat"><div class="wss-cat-title">Plugin Bundles</div>
        <ul class="wss-tags">
          <li class="wss-tag">UAD Plugins</li><li class="wss-tag">IK T-Racks</li>
          <li class="wss-tag">Waves</li><li class="wss-tag">Softube</li>
          <li class="wss-tag">Soundtoys</li>
          <li class="wss-tag">Plugin Alliance</li><li class="wss-tag">oeksound</li>
        </ul>
      </div>
      <div class="wss-cat"><div class="wss-cat-title">Drums</div>
        <ul class="wss-tags">
          <li class="wss-tag">Steven Slate Drums</li><li class="wss-tag">Toontrack Bundle</li>
          <li class="wss-tag">Trigger2 + TCI</li>
          <li class="wss-tag">GGD Drums</li><li class="wss-tag">MDL Ultimate Heavy Drums</li>
        </ul>
      </div>
    </div>
    <div>
      <div class="wss-cat"><div class="wss-cat-title">Guitar &amp; Bass</div>
        <ul class="wss-tags">
          <li class="wss-tag">STL Tones</li>
          <li class="wss-tag">Neural DSP</li><li class="wss-tag">Bogren Digital</li>
        </ul>
      </div>
      <div class="wss-cat"><div class="wss-cat-title">Synths &amp; Orchestra</div>
        <ul class="wss-tags">
          <li class="wss-tag">Omnisphere</li><li class="wss-tag">Serum</li>
          <li class="wss-tag">Dune</li><li class="wss-tag">Korg</li>
          <li class="wss-tag">EW QL Pianos</li><li class="wss-tag">EW Platinum Orchestra</li>
          <li class="wss-tag">NI Kontakt + many libraries</li>
        </ul>
      </div>
      <div class="wss-cat"><div class="wss-cat-title">Vocals</div>
        <ul class="wss-tags">
          <li class="wss-tag">Melodyne</li><li class="wss-tag">VocalAlign</li>
        </ul>
      </div>
    </div>
  </div>
  <div class="wss-gallery" style="margin-top:2rem">
    <img src="assets/images/2025/10/A03ED513-3C85-45DA-91CE-A5CD1568962E-scaled.jpeg" alt="Studio" loading="lazy">
    <img src="assets/images/2025/10/9F0721E6-0EBE-4CE1-9B6D-628F29B842D7-scaled.jpeg" alt="Studio" loading="lazy">
  </div>
</div>
<div class="wss-footer">Recording · Mixing · Production · Rome, Italy</div>
</div>`;
  // Inject CSS for wss
  if (!document.getElementById('wss-css')) {
    const s = document.createElement('style'); s.id = 'wss-css';
    s.textContent = `
.wss-body{padding:0 0 2rem}
.wss-cols{display:grid;grid-template-columns:1fr 1fr;gap:2rem}
@media(max-width:660px){.wss-cols{grid-template-columns:1fr}}
.wss-cat{margin-bottom:1.6rem}
.wss-cat-title{font-size:.62rem;font-weight:600;letter-spacing:.18em;text-transform:uppercase;color:var(--accent);margin-bottom:.6rem;padding-bottom:.4rem;border-bottom:1px solid var(--border)}
.wss-tags{display:flex;flex-wrap:wrap;gap:.3rem;list-style:none}
.wss-tag{font-size:.72rem;background:var(--s1);border:1px solid var(--border);border-radius:4px;padding:.25rem .6rem;color:var(--text);white-space:nowrap;transition:background .18s,border-color .18s,color .18s}
.wss-tag:hover{background:var(--s3);border-color:rgba(200,150,62,.35);color:#fff}
.wss-tag.accent{background:var(--accent-glow);border-color:rgba(200,150,62,.3);color:var(--accent)}
.wss-tag.main-daw{background:var(--accent-glow);border-color:rgba(200,150,62,.4);color:var(--accent);font-weight:600}
.wss-tag.main-daw::after{content:'main daw';display:inline-block;margin-left:.45rem;font-size:.6rem;letter-spacing:.12em;text-transform:uppercase;opacity:.65;vertical-align:middle}
.wss-tag.no-thanks{background:rgba(180,50,50,0.08);border-color:rgba(180,50,50,0.2);color:#888;font-style:italic}
.wss-tag.no-thanks:hover{background:rgba(180,50,50,0.12);border-color:rgba(180,50,50,0.3);color:#aaa}
.wss-divider{display:flex;align-items:center;gap:.75rem;font-size:.62rem;letter-spacing:.2em;text-transform:uppercase;color:var(--muted);margin:0 0 1.5rem}
.wss-divider::before,.wss-divider::after{content:'';flex:1;height:1px;background:var(--border)}
.wss-gallery{display:grid;grid-template-columns:1fr 1fr;gap:.5rem;margin-top:2rem}
.wss-gallery img{width:100%;aspect-ratio:3/4;object-fit:cover;border-radius:4px;filter:brightness(.88) contrast(1.08);transition:filter .3s}
.wss-gallery img:hover{filter:brightness(1)}
.wss-footer{text-align:center;padding:1rem 2rem 1.5rem;font-size:.68rem;letter-spacing:.1em;color:var(--muted);border-top:1px solid var(--border);text-transform:uppercase;margin-top:2rem}`;
    document.head.appendChild(s);
  }
}

// ═══════════════════════════════════════════════════════
//  RENDER GALLERY
// ═══════════════════════════════════════════════════════
let currentGalleryAlbum = 'studio';
function renderGallery(album) {
  currentGalleryAlbum = album || currentGalleryAlbum;
  document.querySelectorAll('.gallery-tab').forEach(t => {
    t.classList.toggle('active', t.dataset.album === currentGalleryAlbum);
    t.onclick = () => renderGallery(t.dataset.album);
  });
  const data = siteData.gallery[currentGalleryAlbum];
  if (!data) return;
  lbImages = data.images;
  const grid = document.getElementById('gallery-grid');
  if (!grid) return;
  grid.innerHTML = data.images.map((img, i) => `
    <div class="gallery-item" onclick="openLightbox(${i})">
      <img src="${img.url}" alt="${img.alt}" loading="lazy">
    </div>`).join('');
}

function openLightbox(i) {
  lbIndex = i;
  document.getElementById('lightbox-img').src = lbImages[i].url;
  const lb = document.getElementById('lightbox');
  lb.classList.add('open');
  lb.onclick = e => { if (e.target === lb) closeLightbox(); };
}
function closeLightbox() { document.getElementById('lightbox').classList.remove('open'); }
function lbNav(dir) {
  lbIndex = (lbIndex + dir + lbImages.length) % lbImages.length;
  document.getElementById('lightbox-img').src = lbImages[lbIndex].url;
}
document.addEventListener('keydown', e => {
  if (document.getElementById('lightbox').classList.contains('open')) {
    if (e.key === 'ArrowLeft') lbNav(-1);
    if (e.key === 'ArrowRight') lbNav(1);
    if (e.key === 'Escape') closeLightbox();
  }
  if (document.getElementById('album-modal').classList.contains('open') && e.key === 'Escape') closeAlbumModal();
});

// ═══════════════════════════════════════════════════════
//  RENDER BLOG
// ═══════════════════════════════════════════════════════
function renderBlog() {
  const list = document.getElementById('blog-list');
  if (!list) return;
  list.innerHTML = siteData.posts.map(p => `
    <div class="blog-item" onclick="navigate('/blog/${p.slug}')">
      <div class="blog-item-date">${p.date}</div>
      <div class="blog-item-content">
        <div class="blog-item-cats">${(p.categories||[]).filter(c=>c&&c!=='Senza categoria').slice(0,3).map(c=>`<span class="blog-cat">${c}</span>`).join('')}</div>
        <div class="blog-item-title">${p.title}</div>
      </div>
      <div class="blog-item-arrow">→</div>
    </div>`).join('');
}

function renderBlogSingle(slug) {
  const post = siteData.posts.find(p => p.slug === slug);
  const el = document.getElementById('blog-single-content');
  if (!el) return;
  if (!post) {
    el.innerHTML = '<div style="text-align:center;padding:4rem;color:var(--muted)">Post not found. <button class="blog-back" onclick="navigate(\'/blog\')">← Back to Blog</button></div>';
    return;
  }
  // Render full content - use content.rendered if available, else content string
  const rawContent = post.content_rendered || post.content || '';
  // Make images responsive
  const styledContent = rawContent
    .replace(/<img /g, '<img style="max-width:100%;height:auto;border-radius:4px;margin:1.5rem 0" ')
    .replace(/<iframe /g, '<iframe style="max-width:100%;border-radius:4px;margin:1.5rem 0" ');
  const cats = (post.categories||[]).filter(c=>c&&c!=='Senza categoria');
  el.innerHTML = `
    <div class="blog-back" onclick="navigate('/blog')">- Back to Blog</div>
    <div class="blog-single-meta">${post.date}${cats.length?' · '+cats.join(', '):''}</div>
    <h1 class="blog-single-title">${post.title}</h1>
    <div class="blog-content">${styledContent || '<p>Read the full article on <a href="https://paolocampitelli.com/" target="_blank">paolocampitelli.com</a>.</p>'}</div>`;
}

// ═══════════════════════════════════════════════════════
//  CONTACT FORM
// ═══════════════════════════════════════════════════════
async function handleContactForm(e) {
  e.preventDefault();
  const form = e.target;
  const alertEl = document.getElementById('contact-alert');
  const btn = form.querySelector('button[type=submit]');
  btn.disabled = true;
  btn.textContent = 'Sending...';
  alertEl.className = 'alert';

  const payload = {
    name:    form.querySelector('[name=name]').value.trim(),
    email:   form.querySelector('[name=email]').value.trim(),
    subject: form.querySelector('[name=subject]').value.trim(),
    message: form.querySelector('[name=message]').value.trim(),
    website: form.querySelector('[name=website]').value // honeypot
  };

  try {
    const r = await fetch('contact.php', {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify(payload)
    });
    const d = await r.json();
    if (d.ok) {
      alertEl.className = 'alert alert-success show';
      alertEl.textContent = 'Message sent! Paolo will get back to you soon.';
      form.reset();
    } else {
      throw new Error(d.error || 'Unknown error');
    }
  } catch(err) {
    alertEl.className = 'alert alert-error show';
    alertEl.textContent = err.message.includes('fetch') ? 'Connection error. Please try again.' : err.message;
  } finally {
    btn.disabled = false;
    btn.textContent = 'Send Message';
    setTimeout(() => alertEl.classList.remove('show'), 6000);
  }
}

// ═══════════════════════════════════════════════════════
//  NAV SCROLL
// ═══════════════════════════════════════════════════════
function toggleMenu() {
  document.getElementById('nav-links').classList.toggle('open');
}
window.addEventListener('scroll', () => {
  document.getElementById('nav').classList.toggle('scrolled', window.scrollY > 50);
}, {passive:true});

// ═══════════════════════════════════════════════════════
//  REVEAL ANIMATIONS
// ═══════════════════════════════════════════════════════
function initReveal() {
  const els = document.querySelectorAll('.reveal:not(.visible)');
  const observer = new IntersectionObserver(entries => {
    entries.forEach(e => { if (e.isIntersecting) { e.target.classList.add('visible'); observer.unobserve(e.target); } });
  }, { threshold: 0.1 });
  els.forEach(el => observer.observe(el));
}

// ═══════════════════════════════════════════════════════
//  ADMIN
// ═══════════════════════════════════════════════════════
function renderAdmin() {
  document.getElementById('admin-login-wrap').style.display = adminLoggedIn ? 'none' : 'block';
  document.getElementById('admin-panel-wrap').classList.toggle('active', adminLoggedIn);
  if (adminLoggedIn) renderAdminAlbums();
}

function doLogin() {
  const u = document.getElementById('login-user').value;
  const p = document.getElementById('login-pass').value;
  const alert = document.getElementById('login-alert');
  if (false) { // credentials removed — use login.php
    adminLoggedIn = true;
    document.getElementById('admin-login-wrap').style.display = 'none';
    document.getElementById('admin-panel-wrap').classList.add('active');
    renderAdminAlbums();
  } else {
    alert.className = 'alert alert-error show';
    alert.textContent = 'Invalid credentials.';
  }
}
function doLogout() {
  adminLoggedIn = false;
  document.getElementById('admin-login-wrap').style.display = 'block';
  document.getElementById('admin-panel-wrap').classList.remove('active');
}

function adminTab(tab, btn) {
  document.querySelectorAll('.admin-tab').forEach(b => b.classList.remove('active'));
  btn.classList.add('active');
  document.getElementById('admin-albums-tab').style.display = tab === 'albums' ? 'block' : 'none';
  document.getElementById('admin-gallery-tab').style.display = tab === 'gallery' ? 'block' : 'none';
  if (tab === 'gallery') renderAdminGallery();
}

function renderAdminAlbums() {
  const grid = document.getElementById('admin-album-grid');
  if (!grid) return;
  grid.innerHTML = [...siteData.albums].reverse().map(a => `
    <div class="admin-album-card">
      <img src="${a.cover}" alt="${a.title}" loading="lazy">
      <div class="admin-album-card-body">
        <div class="admin-album-card-title">${a.title}</div>
        <div class="admin-album-card-year">${a.year} · ${a.artist}</div>
      </div>
      <div class="admin-album-actions">
        <button class="admin-btn-edit" onclick="openAlbumForm('${a.slug}')">Edit</button>
        <button class="admin-btn-delete" onclick="deleteAlbum('${a.slug}')">Delete</button>
      </div>
    </div>`).join('');
}

function renderAdminGallery() {
  const grid = document.getElementById('admin-gallery-grid');
  if (!grid) return;
  const images = [];
  Object.values(siteData.gallery).forEach(ga => ga && ga.images && images.push(...ga.images));
  grid.innerHTML = images.map((img, i) => `
    <div class="admin-gallery-item">
      <img src="${img.url}" alt="${img.alt}" loading="lazy">
      <button class="admin-gallery-del" onclick="deleteGalleryImg(${i})" title="Delete">×</button>
    </div>`).join('');
}

function openAlbumForm(slug) {
  editingAlbumSlug = slug || null;
  const a = slug ? siteData.albums.find(x => x.slug === slug) : {};
  document.getElementById('form-modal-title').textContent = slug ? 'Edit Album' : 'Add Album';
  document.getElementById('form-modal-body').innerHTML = `
    <div class="form-group"><label class="form-label">Title</label><input class="form-input" id="fa-title" value="${(a.title||'').replace(/"/g,'&quot;')}" placeholder="Artist – Title"></div>
    <div class="form-group"><label class="form-label">Artist</label><input class="form-input" id="fa-artist" value="${a.artist||''}"></div>
    <div class="form-group"><label class="form-label">Year</label><input class="form-input" id="fa-year" value="${a.year||''}"></div>
    <div class="form-group"><label class="form-label">Label</label><input class="form-input" id="fa-label" value="${a.label||''}"></div>
    <div class="form-group"><label class="form-label">Producer</label><input class="form-input" id="fa-producer" value="${a.producer||''}"></div>
    <div class="form-group"><label class="form-label">YouTube URL</label><input class="form-input" id="fa-yt" value="${a.youtube||''}"></div>
    <div class="form-group"><label class="form-label">Cover Image URL</label><input class="form-input" id="fa-cover" value="${a.cover||''}"></div>
    <button class="btn btn-primary form-submit" onclick="saveAlbumForm()" style="margin-top:.5rem">Save Album</button>`;
  document.getElementById('form-modal').classList.add('open');
}
function openGalleryAdd() {
  document.getElementById('form-modal-title').textContent = 'Add Photo';
  document.getElementById('form-modal-body').innerHTML = `
    <div class="form-group"><label class="form-label">Image URL</label><input class="form-input" id="fg-url" placeholder="https://..."></div>
    <div class="form-group"><label class="form-label">Alt / Caption</label><input class="form-input" id="fg-alt" placeholder="Description"></div>
    <div class="form-group"><label class="form-label">Album</label>
      <select class="form-input" id="fg-album">
        <option value="studio">Studio</option><option value="live">Live</option><option value="foh">FOH</option>
      </select>
    </div>
    <button class="btn btn-primary form-submit" onclick="saveGalleryAdd()" style="margin-top:.5rem">Add Photo</button>`;
  document.getElementById('form-modal').classList.add('open');
}
function closeFormModal() { document.getElementById('form-modal').classList.remove('open'); }

function saveAlbumForm() {
  const title = document.getElementById('fa-title').value.trim();
  if (!title) return;
  const album = {
    slug: editingAlbumSlug || title.toLowerCase().replace(/[^a-z0-9]+/g,'-').replace(/^-|-$/g,''),
    title, artist: document.getElementById('fa-artist').value.trim(),
    year: document.getElementById('fa-year').value.trim(),
    label: document.getElementById('fa-label').value.trim(),
    producer: document.getElementById('fa-producer').value.trim(),
    youtube: document.getElementById('fa-yt').value.trim(),
    cover: document.getElementById('fa-cover').value.trim()
  };
  if (editingAlbumSlug) {
    const i = siteData.albums.findIndex(x => x.slug === editingAlbumSlug);
    if (i >= 0) siteData.albums[i] = album;
  } else { siteData.albums.push(album); }
  closeFormModal();
  saveSiteData();
  renderAdminAlbums();
}
function saveGalleryAdd() {
  const url = document.getElementById('fg-url').value.trim();
  if (!url) return;
  const albumKey = document.getElementById('fg-album').value;
  if (!siteData.gallery[albumKey]) siteData.gallery[albumKey] = {title: albumKey, images:[]};
  siteData.gallery[albumKey].images.unshift({url, alt: document.getElementById('fg-alt').value.trim()});
  closeFormModal();
  saveSiteData();
  renderAdminGallery();
}
function deleteAlbum(slug) {
  if (!confirm('Delete this album?')) return;
  siteData.albums = siteData.albums.filter(a => a.slug !== slug);
  saveSiteData(); renderAdminAlbums();
}
function deleteGalleryImg(globalIdx) {
  if (!confirm('Delete this photo?')) return;
  let count = 0;
  outer: for (const key of Object.keys(siteData.gallery)) {
    const imgs = siteData.gallery[key].images;
    for (let i = 0; i < imgs.length; i++) {
      if (count === globalIdx) { imgs.splice(i, 1); break outer; }
      count++;
    }
  }
  saveSiteData(); renderAdminGallery();
}

async function saveSiteData() {
  const alert = document.getElementById('admin-save-alert');
  try {
    const r = await fetch('save.php', {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(siteData)});
    const d = await r.json();
    if (d.ok) { alert.className='alert alert-success show'; alert.textContent='Saved successfully!'; }
    else throw new Error('Server error');
  } catch(e) {
    alert.className='alert alert-error show'; alert.textContent='Saved locally only (no PHP server running).';
  }
  setTimeout(() => alert.classList.remove('show'), 3500);
}

// ═══════════════════════════════════════════════════════
//  THREE.JS HERO — 40K PARTICLE WAVEFORM UNIVERSE (WOW)
// ═══════════════════════════════════════════════════════
function initHero() {
  const canvas = document.getElementById('hero-canvas');
  if (!canvas || typeof THREE === 'undefined') {
    startFallbackAnimation();
    return;
  }
  document.getElementById('hero-fallback').style.display = 'none';

  let W = canvas.offsetWidth, H = canvas.offsetHeight;
  const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: false });
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
  renderer.setSize(W, H);
  renderer.setClearColor(0x070608, 1);

  const scene = new THREE.Scene();
  scene.fog = new THREE.FogExp2(0x070608, 0.028);

  const camera = new THREE.PerspectiveCamera(60, W / H, 0.01, 300);
  camera.position.set(0, 2, 18);
  camera.lookAt(0, 0, 0);

  // ── PARTICLE COUNTS ───────────────────────────────────
  const N_WAVE  = 18000;   // main waveform ribbon
  const N_HALO  = 12000;   // orbital halo
  const N_DUST  =  8000;   // ambient dust
  const N_TOTAL = N_WAVE + N_HALO + N_DUST;

  // ── BUFFERS ───────────────────────────────────────────
  const positions  = new Float32Array(N_TOTAL * 3);
  const initPos    = new Float32Array(N_TOTAL * 3); // fly-in start
  const targets    = new Float32Array(N_TOTAL * 3); // waveform targets
  const colors     = new Float32Array(N_TOTAL * 3);
  const sizes      = new Float32Array(N_TOTAL);
  const phases     = new Float32Array(N_TOTAL);

  // ── BUILD WAVEFORM TARGETS ────────────────────────────
  // Main wave: multi-layer ribbon in XY, spread in Z
  for (let i = 0; i < N_WAVE; i++) {
    const t  = (i / N_WAVE) * Math.PI * 10 - Math.PI * 5;
    const layer = Math.floor(i / (N_WAVE / 5));       // 5 stacked layers
    const lOff  = (layer - 2) * 0.18;

    const amp1 = 1.8, amp2 = 0.9, amp3 = 0.45, amp4 = 0.22;
    const y = Math.sin(t * 0.9) * amp1
            + Math.sin(t * 1.7) * amp2
            + Math.sin(t * 3.1) * amp3
            + Math.sin(t * 5.3) * amp4
            + lOff;

    targets[i*3]   = t * 1.15;
    targets[i*3+1] = y;
    targets[i*3+2] = (Math.random() - 0.5) * 0.6 + lOff * 0.5;
    phases[i] = Math.random() * Math.PI * 2;

    // Color: deep amber → bright gold based on Y height
    const norm = (y + 3) / 6;
    const bright = 0.4 + norm * 0.6;
    colors[i*3]   = bright * 0.95;
    colors[i*3+1] = bright * 0.62;
    colors[i*3+2] = bright * 0.12;
    sizes[i] = 0.04 + Math.abs(y) * 0.012 + Math.random() * 0.03;
  }

  // Halo: torus-like spiral around the waveform
  for (let i = 0; i < N_HALO; i++) {
    const idx = N_WAVE + i;
    const theta = (i / N_HALO) * Math.PI * 2 * 8;
    const phi   = (i / N_HALO) * Math.PI * 2;
    const R = 6 + Math.sin(phi * 3) * 1.5;
    const r = 0.6 + Math.random() * 0.8;

    targets[idx*3]   = Math.cos(theta) * r + Math.cos(phi) * R * 0.4;
    targets[idx*3+1] = Math.sin(phi) * R * 0.18 + (Math.random()-0.5) * 0.8;
    targets[idx*3+2] = Math.sin(theta) * r;
    phases[idx] = Math.random() * Math.PI * 2;

    const b = 0.08 + Math.random() * 0.18;
    colors[idx*3]   = b * 0.9;
    colors[idx*3+1] = b * 0.55;
    colors[idx*3+2] = b * 0.08;
    sizes[idx] = 0.025 + Math.random() * 0.035;
  }

  // Ambient dust
  for (let i = 0; i < N_DUST; i++) {
    const idx = N_WAVE + N_HALO + i;
    targets[idx*3]   = (Math.random()-0.5) * 60;
    targets[idx*3+1] = (Math.random()-0.5) * 20;
    targets[idx*3+2] = (Math.random()-0.5) * 30 - 5;
    phases[idx] = Math.random() * Math.PI * 2;

    const b = 0.02 + Math.random() * 0.06;
    colors[idx*3]   = b * 0.9;
    colors[idx*3+1] = b * 0.6;
    colors[idx*3+2] = b * 0.1;
    sizes[idx] = 0.015 + Math.random() * 0.04;
  }

  // ── FLY-IN START POSITIONS ───────────────────────────
  // Particles start scattered at huge random distances
  for (let i = 0; i < N_TOTAL; i++) {
    const angle = Math.random() * Math.PI * 2;
    const dist  = 40 + Math.random() * 80;
    initPos[i*3]   = Math.cos(angle) * dist + (Math.random()-0.5) * 20;
    initPos[i*3+1] = (Math.random()-0.5) * 40;
    initPos[i*3+2] = Math.sin(angle) * dist * 0.5 - 10;
    positions[i*3]   = initPos[i*3];
    positions[i*3+1] = initPos[i*3+1];
    positions[i*3+2] = initPos[i*3+2];
  }

  // ── GEOMETRY + MATERIAL ───────────────────────────────
  const geo = new THREE.BufferGeometry();
  geo.setAttribute('position', new THREE.BufferAttribute(positions, 3));
  geo.setAttribute('color',    new THREE.BufferAttribute(colors, 3));

  // Custom shader for glow + size
  const mat = new THREE.PointsMaterial({
    size: 0.09,
    vertexColors: true,
    transparent: true,
    opacity: 0.92,
    blending: THREE.AdditiveBlending,
    depthWrite: false,
    sizeAttenuation: true,
  });

  const particles = new THREE.Points(geo, mat);
  scene.add(particles);

  // ── MOUSE ─────────────────────────────────────────────
  const mouse = { x: 0, y: 0, tx: 0, ty: 0, down: false };
  window.addEventListener('mousemove', e => {
    mouse.tx = (e.clientX / W - 0.5) * 2;
    mouse.ty = (e.clientY / H - 0.5) * 2;
  }, { passive: true });

  // ── ANIMATION STATE ───────────────────────────────────
  let elapsed = 0;
  let flyInDone = false;
  const FLY_IN_DURATION = 2.8; // seconds
  const camOrbit = { angle: 0 };

  // GSAP camera fly-in
  if (typeof gsap !== 'undefined') {
    gsap.from(camera.position, {
      z: 60, y: 20, duration: 3.5, ease: 'power3.out',
      onUpdate: () => camera.lookAt(0, 0, 0)
    });
  }

  // ── CLOCK ─────────────────────────────────────────────
  const clock = new THREE.Clock();

  function animate() {
    requestAnimationFrame(animate);
    const delta = clock.getDelta();
    elapsed += delta;

    // Smooth mouse
    mouse.x += (mouse.tx - mouse.x) * 0.045;
    mouse.y += (mouse.ty - mouse.y) * 0.045;

    const posArr = geo.attributes.position.array;
    const t = elapsed;

    // Fly-in progress (0→1 over FLY_IN_DURATION)
    const flyProgress = Math.min(1, elapsed / FLY_IN_DURATION);
    // Ease: cubic in-out
    const ease = flyProgress < 0.5
      ? 4 * flyProgress ** 3
      : 1 - Math.pow(-2 * flyProgress + 2, 3) / 2;

    // ── UPDATE PARTICLES ──────────────────────────────
    for (let i = 0; i < N_TOTAL; i++) {
      const i3 = i * 3;

      // Waveform oscillation (applied to targets, not initPos)
      let waveY = 0, waveX = 0;
      if (i < N_WAVE) {
        const tx = targets[i3];
        waveY = Math.sin(tx * 0.35 + t * 1.1 + phases[i]) * 0.35
              + Math.sin(tx * 0.7  + t * 0.7 + phases[i]) * 0.18
              + Math.sin(tx * 1.4  + t * 1.6) * 0.09;
        // mouse push
        const dx = posArr[i3] - mouse.x * 6;
        const dy = posArr[i3+1] - mouse.y * 2;
        const distM = Math.sqrt(dx*dx + dy*dy);
        if (distM < 3.5) {
          waveX += (dx / distM) * (3.5 - distM) * 0.08 * (1 - ease);
          waveY += (dy / distM) * (3.5 - distM) * 0.06 * (1 - ease);
        }
      } else if (i < N_WAVE + N_HALO) {
        // Halo slow rotation
        const a = phases[i] + t * 0.12;
        waveX = Math.cos(a) * 0.15;
        waveY = Math.sin(a) * 0.08;
      } else {
        // Dust drift
        waveY = Math.sin(t * 0.2 + phases[i]) * 0.06;
      }

      const tx_final = targets[i3]   + waveX;
      const ty_final = targets[i3+1] + waveY;
      const tz_final = targets[i3+2];

      // Lerp from init to target
      posArr[i3]   = initPos[i3]   + (tx_final - initPos[i3])   * ease;
      posArr[i3+1] = initPos[i3+1] + (ty_final - initPos[i3+1]) * ease;
      posArr[i3+2] = initPos[i3+2] + (tz_final - initPos[i3+2]) * ease;
    }
    geo.attributes.position.needsUpdate = true;

    // ── CAMERA ────────────────────────────────────────
    camOrbit.angle += delta * 0.04;
    const orbitR = 18 - Math.sin(t * 0.06) * 2;
    const camTargetX = Math.sin(camOrbit.angle) * orbitR * 0.12 + mouse.x * 1.2;
    const camTargetY = 2 + mouse.y * -1.5 + Math.sin(t * 0.08) * 0.6;
    const camTargetZ = orbitR - Math.cos(camOrbit.angle) * 0.8;

    if (elapsed > 2.0) {
      camera.position.x += (camTargetX - camera.position.x) * 0.02;
      camera.position.y += (camTargetY - camera.position.y) * 0.02;
      camera.position.z += (camTargetZ - camera.position.z) * 0.015;
    }
    camera.lookAt(0, 0.5, 0);

    // ── PARTICLE SIZE PULSE ───────────────────────────
    mat.size = 0.07 + Math.sin(t * 1.2) * 0.008 + (1 - ease) * 0.06;

    renderer.render(scene, camera);
  }
  animate();

  // GSAP scroll fade
  if (typeof gsap !== 'undefined' && typeof ScrollTrigger !== 'undefined') {
    gsap.to(canvas, {
      opacity: 0,
      scrollTrigger: { trigger: '#hero', start: 'top top', end: '70% top', scrub: true }
    });
  }

  window.addEventListener('resize', () => {
    W = canvas.offsetWidth; H = canvas.offsetHeight;
    camera.aspect = W / H; camera.updateProjectionMatrix();
    renderer.setSize(W, H);
  });
}

function startFallbackAnimation() {
  document.getElementById('hero-fallback').style.cssText =
    'display:block;background:radial-gradient(ellipse at 50% 60%,rgba(200,150,62,.22) 0%,transparent 60%),#070608;animation:fallbackPulse 4s ease-in-out infinite';
  const style = document.createElement('style');
  style.textContent = '@keyframes fallbackPulse{0%,100%{background-size:100%}50%{background-size:130%}}';
  document.head.appendChild(style);
  const name = document.querySelector('.hero-name');
  if (name) { name.style.opacity = '0'; name.style.transition = 'opacity 2s'; setTimeout(() => name.style.opacity = '1', 400); }
}



// ═══════════════════════════════════════════════════════
//  GSAP SCROLL ANIMATIONS
// ═══════════════════════════════════════════════════════
function initGSAP() {
  if (typeof gsap === 'undefined' || typeof ScrollTrigger === 'undefined') return;
  gsap.registerPlugin(ScrollTrigger);

  // Hero — attesa fly-in particelle (1.8s), poi esplosione testo
  const tl = gsap.timeline({ delay: 1.8 });
  tl.from('.hero-eyebrow',  { opacity:0, y:20, letterSpacing:'0.6em', duration:1.2, ease:'power4.out' })
    .from('.hero-name',     { opacity:0, y:80, skewY:3, duration:1.4, ease:'expo.out', stagger:.08 }, '-=0.6')
    .from('.hero-name .surname', { color:'#fff', duration:1.2, ease:'power2.inOut' }, '-=1.0')
    .from('.hero-sub',      { opacity:0, letterSpacing:'0.5em', duration:1.2, ease:'power3.out' }, '-=0.8')
    .from('.hero-cta',      { opacity:0, y:24, duration:.9, ease:'power3.out' }, '-=0.7')
    .from('.hero-scroll',   { opacity:0, duration:.8, ease:'power2.out' }, '-=0.4');

  // Scroll parallax hero content
  gsap.to('.hero-content', {
    y: -80, opacity: 0,
    scrollTrigger: { trigger:'#hero', start:'top top', end:'60% top', scrub: 1.5 }
  });
}

// ═══════════════════════════════════════════════════════
//  INIT
// ═══════════════════════════════════════════════════════
document.addEventListener('DOMContentLoaded', async () => {
  await loadSiteData();
  // Initial route
  const hash = location.hash.replace('#','') || '/';
  renderRoute(hash);
  initHero();
  initGSAP();
  initReveal();
});

// ═══════════════════════════════════════════════
//  FIX 10 - Gallery selector cards
// ═══════════════════════════════════════════════
const GALLERY_META = {
  studio: { icon: '🎙', label: 'Studio' },
  live:   { icon: '🎸', label: 'Live' },
  foh:    { icon: '🎧', label: 'FOH' }
};
function renderGallerySelectorCards() {
  const wrap = document.getElementById('gallery-cards');
  if (!wrap) return;
  wrap.innerHTML = Object.entries(GALLERY_META).map(([key, meta]) => {
    const ga = siteData.gallery[key];
    const count = ga && ga.images ? ga.images.length : 0;
    const thumb = ga && ga.images && ga.images[0] ? ga.images[0].url : '';
    const isActive = key === currentGalleryAlbum;
    return `<div class="gallery-card${isActive?' active':''}" onclick="renderGallery('${key}');renderGallerySelectorCards()">
      ${thumb ? `<img class="gallery-card-thumb" src="${thumb}" alt="${meta.label}" loading="lazy">` : '<div style="aspect-ratio:4/3;background:var(--s2)"></div>'}
      <div class="gallery-card-body">
        <div class="gallery-card-icon">${meta.icon}</div>
        <div class="gallery-card-name">${meta.label}</div>
        <div class="gallery-card-count">${count} photo${count !== 1 ? 's' : ''}</div>
      </div>
    </div>`;
  }).join('');
}

// Override renderGallery to also update cards
const _origRenderGallery = renderGallery;
function renderGallery(album) {
  currentGalleryAlbum = album || currentGalleryAlbum;
  renderGallerySelectorCards();
  document.querySelectorAll('.gallery-tab').forEach(t => {
    t.classList.toggle('active', t.dataset.album === currentGalleryAlbum);
    t.onclick = () => renderGallery(t.dataset.album);
  });
  const data = siteData.gallery[currentGalleryAlbum];
  if (!data) return;
  lbImages = data.images;
  const grid = document.getElementById('gallery-grid');
  if (!grid) return;
  grid.innerHTML = data.images.map((img, i) => `
    <div class="gallery-item" onclick="openLightbox(${i})">
      <img src="${img.url}" alt="${img.alt || ''}" loading="lazy">
    </div>`).join('');
}

// ═══════════════════════════════════════════════
//  FIX 5 - Admin: Blog post editor (Quill)
// ═══════════════════════════════════════════════
let quillEditor = null;
let editingPostSlug = null;

function adminTab(tab, btn) {
  document.querySelectorAll('.admin-tab').forEach(b => b.classList.remove('active'));
  btn.classList.add('active');
  document.getElementById('admin-albums-tab').style.display = tab === 'albums' ? 'block' : 'none';
  document.getElementById('admin-gallery-tab').style.display = tab === 'gallery' ? 'block' : 'none';
  document.getElementById('admin-posts-tab').style.display = tab === 'posts' ? 'block' : 'none';
  if (tab === 'gallery') renderAdminGallery();
  if (tab === 'posts') renderAdminPosts();
}

function renderAdminPosts() {
  const tbody = document.getElementById('admin-post-tbody');
  if (!tbody) return;
  const posts = (siteData.admin_posts || []).sort((a,b) => b.date.localeCompare(a.date));
  tbody.innerHTML = posts.length ? posts.map(p => `
    <tr>
      <td><strong>${p.title}</strong><div class="slug-preview">/${p.slug}</div></td>
      <td>${p.date}</td>
      <td><span class="tag ${p.status==='published'?'gold':''}">${p.status||'draft'}</span></td>
      <td style="display:flex;gap:.4rem">
        <button class="admin-btn-edit" onclick="openPostEditor('${p.slug}')">Edit</button>
        <button class="admin-btn-delete" onclick="deletePost('${p.slug}')">Delete</button>
        <button class="admin-btn-edit" onclick="previewPost('${p.slug}')">View</button>
      </td>
    </tr>`).join('')
    : '<tr><td colspan="4" style="color:var(--muted);text-align:center;padding:2rem">No posts yet. Click "+ New Post" to create one.</td></tr>';
}

function openPostEditor(slug) {
  editingPostSlug = slug || null;
  const post = slug ? (siteData.admin_posts||[]).find(p => p.slug === slug) : null;
  document.getElementById('post-editor-title').textContent = slug ? 'Edit Post' : 'New Post';
  document.getElementById('pe-title').value = post ? post.title : '';
  document.getElementById('pe-slug').value = post ? post.slug : '';
  document.getElementById('pe-date').value = post ? post.date : new Date().toISOString().split('T')[0];
  document.getElementById('pe-status').value = post ? (post.status||'published') : 'published';
  document.getElementById('pe-category').value = post ? (post.categories&&post.categories[0]||'News') : 'News';
  document.getElementById('pe-img').value = post ? (post.thumb_url||'') : '';
  updateImgPreview();
  updateSlugPreview();
  document.getElementById('post-editor-wrap').style.display = 'block';
  // Init Quill
  if (typeof Quill !== 'undefined') {
    const container = document.getElementById('pe-editor-container');
    container.innerHTML = '';
    const editorDiv = document.createElement('div');
    editorDiv.id = 'pe-quill-editor';
    container.appendChild(editorDiv);
    quillEditor = new Quill('#pe-quill-editor', {
      theme: 'snow',
      placeholder: 'Write your post...',
      modules: {
        toolbar: [
          [{'header':[1,2,3,false]}],
          ['bold','italic','underline','strike'],
          ['blockquote','code-block'],
          [{'list':'ordered'},{'list':'bullet'}],
          ['link','image'],
          ['clean']
        ]
      }
    });
    if (post && post.content) {
      quillEditor.clipboard.dangerouslyPasteHTML(post.content);
    }
  }
}

function closePostEditor() {
  document.getElementById('post-editor-wrap').style.display = 'none';
  quillEditor = null;
  editingPostSlug = null;
}

function updateSlugPreview() {
  const title = document.getElementById('pe-title').value;
  if (!editingPostSlug) {
    const slug = title.toLowerCase().replace(/[^a-z0-9]+/g,'-').replace(/^-|-$/g,'');
    document.getElementById('pe-slug').value = slug;
  }
  document.getElementById('pe-slug-preview').textContent = '/' + document.getElementById('pe-slug').value;
}

function updateImgPreview() {
  const url = document.getElementById('pe-img').value.trim();
  const img = document.getElementById('pe-img-preview');
  if (url) { img.src = url; img.style.display = 'block'; }
  else { img.style.display = 'none'; }
}

function savePost() {
  const title = document.getElementById('pe-title').value.trim();
  if (!title) return;
  const content = quillEditor ? quillEditor.root.innerHTML : '';
  const post = {
    slug: document.getElementById('pe-slug').value.trim() || title.toLowerCase().replace(/[^a-z0-9]+/g,'-'),
    title,
    date: document.getElementById('pe-date').value,
    status: document.getElementById('pe-status').value,
    categories: [document.getElementById('pe-category').value],
    content,
    content_rendered: content,
    thumb_url: document.getElementById('pe-img').value.trim(),
    source: 'admin'
  };
  if (!siteData.admin_posts) siteData.admin_posts = [];
  if (editingPostSlug) {
    const i = siteData.admin_posts.findIndex(p => p.slug === editingPostSlug);
    if (i >= 0) siteData.admin_posts[i] = post; else siteData.admin_posts.push(post);
  } else {
    siteData.admin_posts.unshift(post);
  }
  closePostEditor();
  saveSiteData();
  renderAdminPosts();
}

function deletePost(slug) {
  if (!confirm('Delete this post?')) return;
  siteData.admin_posts = (siteData.admin_posts||[]).filter(p => p.slug !== slug);
  saveSiteData(); renderAdminPosts();
}

function previewPost(slug) {
  const s = slug || (quillEditor ? document.getElementById('pe-slug').value : null);
  if (s) navigate('/blog/' + s);
}

// ── Override renderBlog to merge admin_posts ──────────
const _renderBlogOrig = renderBlog;
function renderBlog() {
  const list = document.getElementById('blog-list');
  if (!list) return;
  const adminPosts = (siteData.admin_posts || []).filter(p => p.status !== 'draft');
  const wpPosts = siteData.posts || [];
  // Merge, dedupe by slug, sort by date desc
  const merged = [...adminPosts, ...wpPosts];
  const seen = new Set();
  const posts = merged.filter(p => { if (seen.has(p.slug)) return false; seen.add(p.slug); return true; })
    .sort((a,b) => b.date.localeCompare(a.date));
  list.innerHTML = posts.map(p => `
    <div class="blog-item" onclick="navigate('/blog/${p.slug}')">
      <div class="blog-item-date">${p.date}</div>
      <div class="blog-item-content">
        <div class="blog-item-cats">${(p.categories||[]).filter(c=>c&&c!=='Senza categoria').slice(0,3).map(c=>`<span class="blog-cat">${c}</span>`).join('')}</div>
        <div class="blog-item-title">${p.title}</div>
      </div>
      <div class="blog-item-arrow">-></div>
    </div>`).join('');
}

// ── Override renderBlogSingle to check admin_posts too ──
const _renderBlogSingleOrig = renderBlogSingle;
function renderBlogSingle(slug) {
  const post = (siteData.admin_posts||[]).find(p => p.slug === slug)
            || (siteData.posts||[]).find(p => p.slug === slug);
  const el = document.getElementById('blog-single-content');
  if (!el) return;
  if (!post) {
    el.innerHTML = '<div style="text-align:center;padding:4rem;color:var(--muted)">Post not found.<br><button class="btn btn-ghost" onclick="navigate(\'/blog\')" style="margin-top:1rem">Back to Blog</button></div>';
    return;
  }
  const rawContent = post.content_rendered || post.content || '';
  const styledContent = rawContent
    .replace(/<img /g, '<img style="max-width:100%;height:auto;border-radius:4px;margin:1.5rem 0" ')
    .replace(/<iframe /g, '<iframe style="max-width:100%;border-radius:4px;margin:1.5rem 0" ');
  const cats = (post.categories||[]).filter(c=>c&&c!=='Senza categoria');
  el.innerHTML = `
    <div class="blog-back" onclick="navigate('/blog')">- Back to Blog</div>
    <div class="blog-single-meta">${post.date}${cats.length?' · '+cats.join(', '):''}</div>
    <h1 class="blog-single-title">${post.title}</h1>
    ${post.thumb_url ? `<img src="${post.thumb_url}" alt="${post.title}" style="width:100%;border-radius:6px;margin-bottom:2rem;max-height:400px;object-fit:cover">` : ''}
    <div class="blog-content">${styledContent || '<p>Read the full article on <a href="https://paolocampitelli.com/" target="_blank">paolocampitelli.com</a>.</p>'}</div>`;
}

// ── Patch navigate to also init gallery cards ────────────
const _navOrig = navigate;
function navigate(path) {
  history.pushState({}, '', '#' + path);
  renderRoute(path);
  if (path === '/gallery') setTimeout(renderGallerySelectorCards, 50);
  trackPageView(path);
}

// ── Analytics tracker ─────────────────────────────────
function trackPageView(page) {
  try {
    fetch('tracker.php', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ page: page || '/', referrer: document.referrer || '' })
    });
  } catch(e) {}
}
// Track initial page load
document.addEventListener('DOMContentLoaded', () => {
  const initPage = location.hash.replace('#','') || '/';
  trackPageView(initPage);
});
</script>
</body>
</html>