<!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>