<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Letrero Neón</title>
<style>
:root{
--neon-color: #00e5ff; /* cambia el color aquí o vía ?color=%23ff00ff */
--bg-brick1: #1b1b1b; /* color ladrillo oscuro */
--bg-brick2: #161616; /* color junta */
--tube-color: #b7ffff; /* color del tubo encendido */
}
/* Pared de ladrillos hecha 100% con CSS */
body{
margin:0;
min-height:100svh;
display:grid;
place-items:center;
background:
/* textura sutil */
radial-gradient(1200px 800px at 20% 10%, #2222 0%, transparent 40%),
radial-gradient(1000px 600px at 80% 90%, #0008 0%, transparent 50%),
/* patrón de ladrillos */
repeating-linear-gradient(
0deg,
var(--bg-brick1) 0 44px,
var(--bg-brick2) 44px 48px
),
repeating-linear-gradient(
90deg,
transparent 0 88px,
#0003 88px 90px
);
color:#fff;
overflow:hidden;
}
.sign{
position:relative;
padding: clamp(16px, 4vw, 36px) clamp(20px, 6vw, 56px);
border-radius: 24px;
/* halo del letrero al muro */
box-shadow:
0 0 12px 0 color-mix(in srgb, var(--neon-color) 60%, transparent),
0 0 80px 10px color-mix(in srgb, var(--neon-color) 40%, transparent),
inset 0 0 40px 5px #0006;
background: linear-gradient(#0009, #0002);
backdrop-filter: blur(2px) brightness(0.8);
-webkit-backdrop-filter: blur(2px) brightness(0.8);
}
.neon{
font-family: system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", Arial, "Noto Sans", "Apple Color Emoji", "Segoe UI Emoji";
font-weight: 700;
font-size: clamp(36px, 11vw, 120px);
letter-spacing: 0.06em;
line-height: 1;
white-space: pre-wrap;
display:block;
color: var(--tube-color);
filter: saturate(120%);
text-shadow:
0 0 1px var(--tube-color),
0 0 2px var(--tube-color),
0 0 6px var(--neon-color),
0 0 14px var(--neon-color),
0 0 26px color-mix(in srgb, var(--neon-color) 80%, #fff),
0 0 48px color-mix(in srgb, var(--neon-color) 70%, #fff);
}
/* Tubo de soporte: simula el vidrio alrededor del texto */
.neon::before{
content: attr(data-text);
position:absolute;
inset:0;
pointer-events:none;
color: #fff1;
text-shadow:
0 0 1px #fff5,
0 0 2px #fff3,
0 0 6px #fff2;
filter: blur(0.6px) opacity(0.6);
mask: linear-gradient(#000 50%, transparent);
}
/* cable colgante decorativo */
.cable{
position:absolute; inset:auto 0 100% 0; height:80px; display:flex; justify-content:center;
}
.cable::before{
content:""; width:min(70%, 520px); height:100%; display:block;
background:
radial-gradient(8px 8px at 10% 8%, #000a 30%, transparent 32%) no-repeat,
linear-gradient(#111, #0a0a0a) padding-box;
border: 2px solid #050505;
border-radius: 800px 800px 0 0 / 120px 120px 0 0;
box-shadow: inset 0 -10px 20px #0008;
margin-top:-12px;
clip-path: ellipse(50% 100% at 50% 100%);
filter: blur(0.2px);
}
/* Animaciones */
@keyframes flicker {
0%, 18%, 22%, 25%, 53%, 57%, 100% { opacity: 1; }
20%, 24%, 55% { opacity: 0.4; }
}
@keyframes broken {
0% { opacity: 0.2; text-shadow: none; }
2% { opacity: 1; }
8% { opacity: 0.1; }
10% { opacity: 1; }
11% { opacity: 0.2; }
12% { opacity: 1; }
20% { opacity: 0.15; }
21% { opacity: 1; }
100% { opacity: 0.7; }
}
.neon span { display:inline-block; }
.flicker { animation: flicker 2.6s infinite; }
.broken { animation: broken 6s infinite; }
/* Botones utilitarios opcionales */
.controls{
position: fixed; right: 12px; bottom: 12px; display:flex; gap:8px; flex-wrap:wrap;
background:#0007; border:1px solid #ffffff22; padding:10px 12px; border-radius:12px;
backdrop-filter: blur(4px);
}
.controls input[type="color"], .controls input[type="text"], .controls button{
font: inherit; padding: 6px 10px; border-radius: 8px; border:1px solid #ffffff22; background:#111; color:#fff;
}
.controls button{ cursor:pointer }
</style>
</head>
<body>
<div class="cable" aria-hidden="true"></div>
<div class="sign">
<!-- Cambia el mensaje aquí dentro o usa ?text=Hola%20Mundo -->
<h1 id="text" class="neon" data-text=“¡¡¡PUTO EL QUE LO LEA!!!></h1>
</div>
<div class="controls" title="Controles en vivo (opcionales)">
<label>
Mensaje:
<input id="msg" type="text" placeholder="Escribe tu mensaje" />
</label>
<label>
Color:
<input id="color" type="color" value="#00e5ff" />
</label>
<label>
Letra defectuosa:
<input id="idx" type="number" min="1" value="3" style="width:5rem" />
</label>
<button id="aplicar">Aplicar</button>
</div>
<script>
// --- utilidades ---
const $ = (sel, el=document) => el.querySelector(sel);
const neon = $('#text');
// Rellena el texto como spans para poder animar letra por letra
function renderText(str, brokenIndex = 3){
neon.innerHTML = '';
neon.dataset.text = str;
[...str].forEach((ch, i) => {
const span = document.createElement('span');
span.textContent = ch;
// espacios siguen ocupando el lugar
if(ch === ' ') span.style.width = '0.35em';
// Asignamos parpadeo a varias letras
if(Math.random() < 0.12) span.classList.add('flicker');
// Una letra "defectuosa" (1‑based index en UI)
if(i === brokenIndex-1 && ch.trim() !== '') span.classList.add('broken');
neon.appendChild(span);
});
}
// Lee parámetros de URL (?text= & color= & broken=)
const params = new URLSearchParams(location.search);
const initialText = params.get('text') || 'NEÓN EN HTML5';
const initialColor = params.get('color') || getComputedStyle(document.documentElement).getPropertyValue('--neon-color').trim();
const broken = parseInt(params.get('broken')||'3',10);
renderText(initialText, broken);
document.documentElement.style.setProperty('--neon-color', initialColor);
// Controles en vivo
$('#msg').value = initialText;
$('#color').value = initialColor.startsWith('#') ? initialColor : '#00e5ff';
$('#idx').value = broken;
$('#aplicar').addEventListener('click', () => {
const txt = $('#msg').value || ' ';
const b = Math.max(1, parseInt($('#idx').value||'1',10));
renderText(txt, b);
document.documentElement.style.setProperty('--neon-color', $('#color').value);
// Opcional: actualizar URL sin recargar
const p = new URLSearchParams(location.search);
p.set('text', txt);
p.set('color', $('#color').value);
p.set('broken', b);
history.replaceState(null, '', `${location.pathname}?${p.toString()}`);
});
</script>
</body>
</html>