<!-- CCC • 16 Ribbons • PSA Top (Green) • Sponsor Bottom (Gold) -->
<style>
.ccc16-wrap{max-width:1220px;margin:0 auto;padding:8px}
.ccc16-title{font:700 1.25rem/1.2 system-ui,Segoe UI,Roboto,Arial;margin:8px 0 16px}
.ccc16-grid{display:grid;gap:12px}
@media(min-width:900px){.ccc16-grid{grid-template-columns:1fr 1fr}}
.ccc16-card{border:1px solid #ddd;border-radius:12px;overflow:hidden;background:#f8fafc;position:relative}
.ccc16-ribbon{display:flex;align-items:stretch;min-height:160px;background:linear-gradient(90deg,#e9eef7,#f4f8ff)}
.ccc16-img{width:34%;min-height:160px;background:#dfe7f5 center/cover no-repeat;flex:none}
.ccc16-body{flex:1;padding:12px 14px}
.ccc16-name{font:700 1rem/1 system-ui;margin:0 0 2px}
.ccc16-sub{font:600 .85rem/1.2 system-ui;color:#444;margin:0 0 8px}
.ccc16-badge{position:absolute;top:10px;left:10px;font:700 .7rem/1 system-ui;background:#315efb;color:#fff;padding:6px 10px;border-radius:20px}
.ccc16-card.open{background:#fff8eb;border-style:dashed}
.ccc16-card.open .ccc16-badge{background:#ef8f00}
.ccc16-psa{font:600 .8rem/1.2 system-ui;color:#555;margin:6px 0}
.ccc16-slots{display:grid;grid-template-columns:repeat(11,minmax(0,1fr));gap:6px}
.ccc16-slot{font:700 .72rem/1.1 system-ui;background:#fff;border:1px solid #e3e8ef;border-radius:8px;padding:8px 6px;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ccc16-slot.active{outline:3px solid #315efb;box-shadow:0 0 0 2px rgba(49,94,251,.15)}
.ccc16-slot.psa{background:#e3f7e1;border-color:#91c788}
.ccc16-slot.sponsor{background:#fff7d6;border-color:#e3c46f}
.ccc16-meta{font:600 .75rem/1.2 system-ui;color:#666;margin-top:8px}
.ccc16-links{display:flex;gap:10px;flex-wrap:wrap;margin-top:8px}
.ccc16-links a{font:700 .8rem/1 system-ui;text-decoration:none;background:#111;color:#fff;padding:8px 10px;border-radius:6px}
</style>
<div class="ccc16-wrap" id="ccc16-app">
<div class="ccc16-title">Citrus County Classifieds — 16 Ribbons • PSA Top (Green) • Sponsor Bottom (Gold)</div>
<div class="ccc16-grid" id="ccc16-grid"></div>
</div>
<script>
(function(){
// PSA first, Sponsor last
const PLACEHOLDERS = [
"PSA",
"Calendar","Caregivers","Careers","Cars","Charity","Churches","Citizens","Classifieds","Classroom",
"Commerce","Community","Construction","Coolspots","Cosmetologist","Cottage","Coupon","Courier ~ News",
"Crafts","Cruises","Cuisine",
"Sponsor"
];
const RIBBONS = [
{ time:"08:00", name:"Sugarmill Woods", zip:["34461"], psa:"Weather MSS" },
{ time:"08:30", name:"Homosassa", zip:["34446","34448","34487"], psa:"County Commissioner" },
{ time:"09:00", name:"Homosassa Springs", zip:["34447"], psa:"School(s)" },
{ time:"09:30", name:"Crystal River", zip:["34423","34428","34429"], psa:"State Representative" },
{ time:"10:00", name:"Hernando", zip:["34442","34441"], psa:"Federal Representative" },
{ time:"10:30", name:"Citrus Springs", zip:["34433","34434"], psa:"Senator" },
{ time:"11:00", name:"Pine Ridge", zip:["34465"], psa:"Governor" },
{ time:"11:30", name:"Beverly Hills", zip:["34464","34465"], psa:"Special 11:11 Window" },
{ time:"12:00", name:"OPEN SLOT", open:true, note:"Special Programming / Break (12:00–12:30)" },
{ time:"12:30", name:"Citrus Hills", zip:["34461"], psa:"Weather MSS" },
{ time:"13:00", name:"Lecanto", zip:["34460","34461"], psa:"County Commissioner" },
{ time:"13:30", name:"Inverness Highlands South", zip:["34452","34453"], psa:"School(s)" },
{ time:"14:00", name:"Inverness Highlands North", zip:["34452","34453"], psa:"State Representative" },
{ time:"14:30", name:"Inverness", zip:["34450","34451","34452","34453"], psa:"Federal Representative" },
{ time:"15:00", name:"Floral City", zip:["34436"], psa:"Senator" },
{ time:"15:30", name:"Sugarmill Woods", zip:["34461"], psa:"Governor" }
];
const VILLAGE_IMAGES = {}; // optional per placeholder images
const LINKS = {
donate: "https://paypal.me/innerbeautyministry",
payPerPost: "https://paypal.me/paulmgrogan/25",
contact: "mailto:info@PaulMGrogan.com"
};
const grid = document.getElementById('ccc16-grid');
function makeEl(tag, cls, html){ const el=document.createElement(tag); if(cls) el.className=cls; if(html!=null) el.innerHTML=html; return el; }
function buildCard(item){
const card = makeEl('div','ccc16-card'+(item.open?' open':''));
const ribbon = makeEl('div','ccc16-ribbon');
const img = makeEl('div','ccc16-img');
const body = makeEl('div','ccc16-body');
const villageImgs = VILLAGE_IMAGES[item.name] || {};
const name = makeEl('div','ccc16-name', `${item.name}${item.zip?' — '+item.zip.join(', '):''}`);
const sub = makeEl('div','ccc16-sub', `Slot: ${item.time}${item.open?'':' • 22 placeholders (auto-highlight)'}`);
body.appendChild(name);
body.appendChild(sub);
if(item.open){
body.appendChild(makeEl('div','ccc16-psa', item.note || 'Open slot for special programming.'));
} else if(item.psa){
body.appendChild(makeEl('div','ccc16-psa', `PSA at :00 or :30 → <strong>${item.psa}</strong>`));
}
const slots = makeEl('div','ccc16-slots');
PLACEHOLDERS.forEach((ph,i)=>{
let slotClass = 'ccc16-slot';
if(i===0) slotClass += ' psa';
if(i===PLACEHOLDERS.length-1) slotClass += ' sponsor';
const slot = makeEl('div',slotClass, ph);
slot.dataset.ph=ph; slot.dataset.idx=i;
slots.appendChild(slot);
});
body.appendChild(slots);
const meta = makeEl('div','ccc16-meta'); meta.dataset.ts=''; body.appendChild(meta);
const links = makeEl('div','ccc16-links',
`<a href="${LINKS.payPerPost}" target="_blank" rel="noopener">Post $25</a>
<a href="${LINKS.donate}" target="_blank" rel="noopener">Donate</a>
<a href="${LINKS.contact}">Contact</a>`);
body.appendChild(links);
ribbon.appendChild(img); ribbon.appendChild(body);
card.appendChild(ribbon);
const badge = makeEl('div','ccc16-badge', item.open?'OPEN':'SLOT');
card.appendChild(badge);
grid.appendChild(card);
return {card,img,slots,meta,item,villageImgs};
}
const cards = RIBBONS.map(buildCard);
function highlightActiveRibbon(){
const now = new Date();
const hh = now.getHours().toString().padStart(2,'0');
const mm = now.getMinutes();
const half = `${hh}:${mm<30?'00':'30'}`;
cards.forEach(c=>c.card.classList.remove('active'));
const idx = RIBBONS.findIndex(r=>r.time===half);
if(idx>=0) cards[idx].card.classList.add('active');
}
function tick(){
const now = new Date();
const m = now.getMinutes();
const s = now.getSeconds();
const activeIdx = PLACEHOLDERS.length ? (m % PLACEHOLDERS.length) : 0;
const activeName = PLACEHOLDERS[activeIdx] || '';
cards.forEach(ctx=>{
const imgUrl = (ctx.villageImgs && ctx.villageImgs[activeName]) ? ctx.villageImgs[activeName] : '';
ctx.img.style.backgroundImage = imgUrl ? `url('${imgUrl}')` : '';
const slotNodes = ctx.slots.querySelectorAll('.ccc16-slot');
slotNodes.forEach(n=>n.classList.remove('active'));
if(slotNodes[activeIdx]) slotNodes[activeIdx].classList.add('active');
ctx.meta.textContent = `Now: ${now.toLocaleTimeString([], {hour:'2-digit',minute:'2-digit'})} • Minute ${m} → Active: “${activeName}”`;
});
if(s===0) highlightActiveRibbon();
}
highlightActiveRibbon();
tick();
setInterval(tick, 1000);
})();
</script>
Share this: You know you want to!