[html]<div id="bingo-mount"></div>
<script>
/* ==========================================================
BINGO GENERATOR · legume
========================================================== */
(function(){
const CONFIG = {
background: "https://upforme.ru/uploads/000f/09/5e/16134/215761.jpg",
columns: 4,
rows: 4,
title: "форум бинго",
overlayOpacity: 0.3,
items: [
"пофиксил баг — появилось три новых",
"кто-то снова забыл закрыть тег",
"у меня не работает — без скриншота",
"почему форум тормозит",
"чиню css который не трогал",
"юзер сломал профиль полем html",
"правлю скрипт прямо на проде",
"кэш виноват (как всегда)",
"диз сломался в сафари",
"в теме 300 сообщений флуда",
"опять чистить личку",
"обновляю статистику постов",
"внезапно упал хостинг",
"ищу пропавший </div>",
"а можно ещё одну роль?",
"ночью переписываю js"
]
};
function escapeHtml(s){
return String(s)
.replace(/&/g,"&")
.replace(/</g,"<")
.replace(/>/g,">")
.replace(/"/g,""");
}
function ensureFont(){
if(document.getElementById("roboto-slab-link")) return;
const link = document.createElement("link");
link.id = "roboto-slab-link";
link.rel = "stylesheet";
link.href = "https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@400;600;700&display=swap";
document.head.appendChild(link);
}
function renderBingo(){
ensureFont();
const total = CONFIG.columns * CONFIG.rows;
let cellsHTML = "";
for(let i=0;i<total;i++){
const text = CONFIG.items[i] ? escapeHtml(CONFIG.items[i]) : " ";
cellsHTML += `<div class="nota-bingo-cell">${text}</div>`;
}
const style = `
<style>
.nota-bingo-wrap{
width: 600px;
font-family: serif;
position: relative;
border-radius: 16px;
background: url(${CONFIG.background}) center/cover no-repeat;
padding: 28px;
color: #fff;
overflow: hidden;
}
.nota-bingo-overlay{
position:absolute;
inset:0;
background: rgba(0,0,0,${CONFIG.overlayOpacity});
}
.nota-bingo-inner{
position: relative;
z-index:2;
}
.nota-bingo-title{
text-align:center;
text-transform:uppercase;
font:400 40px "Yeseva One";
margin-bottom:20px;
text-shadow:0 3px 12px rgba(0,0,0,.6);
}
.nota-bingo-grid{
display:grid;
grid-template-columns: repeat(${CONFIG.columns}, 1fr);
gap:12px;
}
.nota-bingo-cell{
background: rgba(0,0,0,.25);
border:1px solid rgba(255,255,255,.12);
border-radius:12px;
min-height:90px;
padding:14px;
display:flex;
align-items:center;
justify-content:center;
text-align:center;
font-weight:600;
font-size:14px;
line-height:1.25;
text-shadow:0 2px 10px rgba(0,0,0,.7);
transition:.2s;
}
.nota-bingo-cell:hover{
background: rgba(0,0,0,.35);
}
@media(max-width:600px){
.nota-bingo-wrap{ padding:18px; }
.nota-bingo-cell{ min-height:70px; font-size:12px; }
}
</style>
`;
const html = `
${style}
<div class="nota-bingo-wrap">
<div class="nota-bingo-overlay"></div>
<div class="nota-bingo-inner">
<div class="nota-bingo-title">${escapeHtml(CONFIG.title)}</div>
<div class="nota-bingo-grid">
${cellsHTML}
</div>
</div>
</div>
`;
document.getElementById("bingo-mount").innerHTML = html;
}
renderBingo();
})();
</script>[/html]

















