JustPaste
HomeCategoriesAboutDonateContactTerms of UsePrivacy Policy
JustPaste

Free online notepad — write and share instantly

Navigate

  • Home
  • Timeline
  • Categories

Info

  • About
  • Donate
  • Contact

Legal

  • Terms of Use
  • Privacy Policy

© 2026 JustPaste.app. All rights reserved.

Made with ♥ by JustPaste

Lulita mia | JustPaste.app
2 months ago0 views
💻Technology

Lulita mia

<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
  <title>Buenas noches, Lulita ✨</title>
  <link href="https://fonts.googleapis.com/css2?family=Dancing+Script:wght@400;600;700&family=Quicksand:wght@300;400;500;600;700&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      min-height: 100vh;
      background: radial-gradient(ellipse at center, #0a0f2a 0%, #030617 100%);
      display: flex;
      align-items: center;
      justify-content: center;
      font-family: 'Quicksand', sans-serif;
      padding: 1.5rem;
      position: relative;
      overflow-x: hidden;
      cursor: pointer;
    }

    /* === ESTRELLAS FIJAS (fondo) === */
    .stars {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      pointer-events: none;
      z-index: 0;
    }
    .star {
      position: absolute;
      background-color: #fff;
      border-radius: 50%;
      opacity: 0.7;
      animation: twinkle 2s infinite alternate;
    }
    @keyframes twinkle {
      0% { opacity: 0.2; transform: scale(1);}
      100% { opacity: 1; transform: scale(1.2);}
    }

    /* === ESTRELLAS FUGAZES (canvas) === */
    #shootingStarsCanvas {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      pointer-events: none;
      z-index: 1;
    }

    /* === SOBRE Y CARTA === */
    .container {
      position: relative;
      z-index: 20;
      max-width: 700px;
      width: 100%;
      perspective: 1500px;
    }

    /* Sobre cerrado */
    .envelope {
      background: linear-gradient(145deg, #1e2a3a, #0f1724);
      border-radius: 32px;
      padding: 2rem 1.5rem 2rem;
      text-align: center;
      box-shadow: 0 30px 40px rgba(0,0,0,0.5), 0 0 0 4px #f9e0a0, 0 0 0 8px #b87c4f;
      cursor: pointer;
      transition: transform 0.4s cubic-bezier(0.2, 0.9, 0.4, 1.1), box-shadow 0.3s;
      backdrop-filter: blur(2px);
      border: 1px solid rgba(255,215,150,0.6);
    }
    .envelope:hover {
      transform: scale(1.02);
      box-shadow: 0 35px 50px rgba(0,0,0,0.6), 0 0 0 4px #ffefb0, 0 0 0 8px #d4945a;
    }
    .moon-icon {
      font-size: 4rem;
      color: #f9e0a0;
      filter: drop-shadow(0 0 8px #ffd966);
      margin-bottom: 0.8rem;
    }
    .envelope h2 {
      font-family: 'Dancing Script', cursive;
      font-size: 2.2rem;
      color: #ffefcf;
      text-shadow: 0 2px 5px #2c1a0e;
      margin: 0.5rem 0;
    }
    .envelope p {
      color: #cbd5e6;
      font-weight: 500;
      margin-bottom: 1.5rem;
    }
    .open-btn {
      background: linear-gradient(135deg, #f3b33d, #e07c1f);
      border: none;
      padding: 12px 28px;
      font-size: 1.2rem;
      font-weight: bold;
      border-radius: 50px;
      color: #1e1a0c;
      cursor: pointer;
      box-shadow: 0 5px 15px rgba(0,0,0,0.3);
      transition: 0.2s;
      display: inline-flex;
      align-items: center;
      gap: 12px;
      font-family: 'Quicksand', sans-serif;
    }
    .open-btn:active {
      transform: scale(0.96);
    }
    .star-deco {
      margin-top: 1.8rem;
      font-size: 1.4rem;
      color: #ffda88;
      display: flex;
      justify-content: center;
      gap: 1rem;
    }

    /* CARTA (contenido) - inicialmente oculta */
    .letter-card {
      display: none;
      background: rgba(20, 15, 35, 0.85);
      backdrop-filter: blur(12px);
      border-radius: 48px;
      padding: 2rem 1.8rem;
      box-shadow: 0 25px 45px rgba(0,0,0,0.5), 0 0 0 2px #ffecb3, 0 0 0 5px #b46f3a;
      animation: floatIn 0.7s ease-out forwards;
      border: 1px solid rgba(255,225,140,0.6);
    }
    @keyframes floatIn {
      0% {
        opacity: 0;
        transform: translateY(40px) rotateX(-10deg);
      }
      100% {
        opacity: 1;
        transform: translateY(0) rotateX(0);
      }
    }
    .letter-header {
      text-align: center;
      font-size: 2.5rem;
      color: #ffdfa5;
      margin-bottom: 0.5rem;
    }
    .letter-header i {
      margin: 0 0.5rem;
      filter: drop-shadow(0 0 4px gold);
    }
    .message-content {
      background: rgba(0,0,0,0.4);
      border-radius: 32px;
      padding: 1.8rem;
      margin: 1.2rem 0;
      font-family: 'Quicksand', sans-serif;
      font-size: 1.15rem;
      line-height: 1.6;
      color: #fef7e0;
      text-align: center;
      font-weight: 500;
      border: 1px solid rgba(255,215,120,0.4);
      box-shadow: inset 0 0 12px rgba(0,0,0,0.3), 0 6px 12px rgba(0,0,0,0.2);
    }
    .message-content p {
      margin: 0.6rem 0;
    }
    .signature {
      text-align: right;
      font-family: 'Dancing Script', cursive;
      font-size: 1.5rem;
      margin-top: 1rem;
      color: #ffda88;
      border-top: 1px dashed #ffcf7a;
      padding-top: 1rem;
    }
    .night-flowers {
      display: flex;
      justify-content: center;
      gap: 1rem;
      font-size: 1.5rem;
      color: #b9d0ff;
      margin-top: 1rem;
    }
    /* Responsive */
    @media (max-width: 550px) {
      .envelope h2 { font-size: 1.6rem; }
      .message-content { font-size: 1rem; padding: 1.2rem; }
      .letter-card { padding: 1.5rem; }
    }
    /* ocultar elemento al abrir */
    .hidden-envelope {
      display: none;
    }
  </style>
</head>
<body>

<!-- Estrellas fijas de fondo (estáticas) -->
<div class="stars" id="staticStars"></div>
<!-- Canvas para estrellas fugaces -->
<canvas id="shootingStarsCanvas"></canvas>

<div class="container">
  <!-- SOBRE CERRADO -->
  <div id="envelopeClosed" class="envelope">
    <div class="moon-icon">
      <i class="fas fa-moon"></i> <i class="fas fa-star"></i>
    </div>
    <h2>🌙 Para mi Lulita 🌙</h2>
    <p>Una última carta antes de dormir...</p>
    <button id="openEnvelopeBtn" class="open-btn"><i class="fas fa-envelope-open"></i> Abrir con el corazón</button>
    <div class="star-deco">
      <i class="fas fa-star"></i> <i class="fas fa-star"></i> <i class="fas fa-star"></i>
      <i class="fas fa-cloud-moon"></i> <i class="fas fa-star"></i>
    </div>
    <div style="margin-top: 1rem; font-size: 0.8rem; color:#b9b3e0;">
      <i class="fas fa-crown"></i> Toca para abrir <i class="fas fa-gem"></i>
    </div>
  </div>

  <!-- CARTA ABIERTA (contenido) -->
  <div id="letterOpened" class="letter-card">
    <div class="letter-header">
      <i class="fas fa-star-of-life"></i> ✨ Buenas noches, mi amor ✨ <i class="fas fa-star-of-life"></i>
    </div>
    <div class="message-content">
      <p>🌠 hasta mas enseguida lulita,</p>
      <p>espero que me ames siempre, estar siempre juntos y pasar esta mala etapa adelante, por q yo juro q te amo y quiero estar con vs por siempre.</p>
      <p>que tengas lindos sueños y q amanezcas con todas las pilas y espero algun dia proponerte q seas mi novia de vuelta y de una manera mejor,</p>
      <p>nos vemos mañana te amo. 💖🌙</p>
    </div>
    <div class="signature">
      <i class="fas fa-feather-alt"></i> Con todo mi corazón
    </div>
    <div class="night-flowers">
      <i class="fas fa-moon"></i> <i class="fas fa-star"></i> <i class="fas fa-cloud-moon"></i> <i class="fas fa-star"></i>
    </div>
  </div>
</div>

<script>
  // ========== ESTRELLAS FUGAZES CON CANVAS (animación suave) ==========
  const canvas = document.getElementById('shootingStarsCanvas');
  let ctx = canvas.getContext('2d');
  let width, height;
  let meteors = [];
  const MAX_METEORS = 5;
  let lastTimestamp = 0;

  function resizeCanvas() {
    width = window.innerWidth;
    height = window.innerHeight;
    canvas.width = width;
    canvas.height = height;
  }
  window.addEventListener('resize', () => {
    resizeCanvas();
    initStaticStars(); // regenerar estrellas estáticas también
  });

  // Clase para estrella fugaz
  class ShootingStar {
    constructor() {
      this.reset();
    }
    reset() {
      this.x = Math.random() * width;
      this.y = Math.random() * (height * 0.5); // empieza en mitad superior
      this.length = Math.random() * 80 + 40;
      this.speed = Math.random() * 8 + 6;
      this.angle = Math.random() * (Math.PI / 3) - Math.PI / 6; // entre -30° y 30° (inclinación)
      this.opacity = Math.random() * 0.6 + 0.4;
      this.active = true;
      this.trail = [];
      this.maxTrail = 12;
    }
    update() {
      if (!this.active) return false;
      // mover
      this.x += Math.cos(this.angle) * this.speed;
      this.y += Math.sin(this.angle) * this.speed;
      // guardar rastro
      this.trail.push({ x: this.x, y: this.y });
      if (this.trail.length > this.maxTrail) this.trail.shift();
      // si sale de pantalla o se aleja mucho, reiniciar
      if (this.x > width + 200 || this.x < -200 || this.y > height + 200 || this.y < -200) {
        this.reset();
        this.x = Math.random() * width;
        this.y = Math.random() * (height * 0.4);
        return true;
      }
      return true;
    }
    draw(ctx) {
      if (!this.active) return;
      ctx.save();
      ctx.beginPath();
      // dibujar rastro (estela)
      for (let i = 0; i < this.trail.length; i++) {
        const point = this.trail[i];
        const alpha = (i / this.trail.length) * this.opacity * 0.7;
        ctx.beginPath();
        ctx.arc(point.x, point.y, 2.2 * (i / this.trail.length), 0, Math.PI * 2);
        ctx.fillStyle = `rgba(255, 240, 170, ${alpha * 0.8})`;
        ctx.fill();
      }
      // cabeza brillante
      ctx.shadowBlur = 12;
      ctx.shadowColor = "#ffd966";
      ctx.beginPath();
      ctx.arc(this.x, this.y, 3.5, 0, Math.PI * 2);
      ctx.fillStyle = `rgba(255, 235, 140, ${this.opacity + 0.3})`;
      ctx.fill();
      ctx.beginPath();
      ctx.arc(this.x, this.y, 2, 0, Math.PI * 2);
      ctx.fillStyle = `white`;
      ctx.fill();
      ctx.restore();
    }
  }

  function initMeteors() {
    meteors = [];
    for (let i = 0; i < MAX_METEORS; i++) {
      let star = new ShootingStar();
      star.reset();
      // aleatorizar posiciones iniciales distribuidas
      star.x = Math.random() * width;
      star.y = Math.random() * (height * 0.5);
      star.trail = [];
      meteors.push(star);
    }
  }

  let animationFrame;
  function animateShootingStars() {
    if (!ctx) return;
    ctx.clearRect(0, 0, width, height);
    for (let meteor of meteors) {
      meteor.update();
      meteor.draw(ctx);
    }
    animationFrame = requestAnimationFrame(animateShootingStars);
  }

  // ========== ESTRELLAS ESTÁTICAS (fondo) ==========
  function initStaticStars() {
    const starsContainer = document.getElementById('staticStars');
    starsContainer.innerHTML = '';
    const starCount = 220;
    for (let i = 0; i < starCount; i++) {
      const star = document.createElement('div');
      star.classList.add('star');
      const size = Math.random() * 3 + 1.5;
      star.style.width = size + 'px';
      star.style.height = size + 'px';
      star.style.left = Math.random() * 100 + '%';
      star.style.top = Math.random() * 100 + '%';
      star.style.animationDelay = Math.random() * 3 + 's';
      star.style.animationDuration = Math.random() * 2 + 1.5 + 's';
      starsContainer.appendChild(star);
    }
  }

  // ========== APERTURA DEL SOBRE CON MOVIMIENTO ==========
  const envelopeDiv = document.getElementById('envelopeClosed');
  const letterDiv = document.getElementById('letterOpened');
  const openButton = document.getElementById('openEnvelopeBtn');

  function openEnvelopeWithAnimation() {
    // Animación de movimiento: rotación, desvanecimiento y "vuelo"
    envelopeDiv.style.transition = 'transform 0.5s cubic-bezier(0.34, 1.2, 0.64, 1), opacity 0.4s';
    envelopeDiv.style.transform = 'rotateX(90deg) scale(0.7)';
    envelopeDiv.style.opacity = '0';
    setTimeout(() => {
      envelopeDiv.classList.add('hidden-envelope');
      envelopeDiv.style.display = 'none';
      // Mostrar carta con efecto
      letterDiv.style.display = 'block';
      // Disparar confeti de estrellas (estrellitas brillantes)
      shootStarConfetti();
      // también generar una ráfaga de estrellas fugaces extra
      for(let i=0; i<3; i++) {
        setTimeout(() => {
          createExtraShootingStar();
        }, i * 200);
      }
    }, 500);
  }

  // confeti estilo estrellas y lunas
  function shootStarConfetti() {
    // Pequeña lluvia de confeti con forma de estrella (usamos canvas-confetti)
    if (typeof canvasConfetti !== 'undefined') {
      canvasConfetti({ particleCount: 120, spread: 70, origin: { y: 0.6 }, colors: ['#ffec99', '#ffd966', '#f3c26b', '#ffe0a3'], shapes: ['star'] });
      canvasConfetti({ particleCount: 60, spread: 45, origin: { y: 0.3, x: 0.2 }, startVelocity: 18, colors: ['#ffdfa5'] });
      canvasConfetti({ particleCount: 60, spread: 45, origin: { y: 0.3, x: 0.8 }, startVelocity: 18, colors: ['#f5e3b0'] });
    } else {
      // fallback simple
      console.log("✨ Estrellas mágicas ✨");
    }
  }

  function createExtraShootingStar() {
    // generar una estrella fugaz nueva visible de inmediato
    if (meteors.length > 0) {
      let newMeteor = new ShootingStar();
      newMeteor.x = Math.random() * width;
      newMeteor.y = Math.random() * (height * 0.3);
      newMeteor.active = true;
      newMeteor.speed = Math.random() * 12 + 8;
      meteors.push(newMeteor);
      setTimeout(() => {
        // eliminar después de su vida (opcional)
        const index = meteors.indexOf(newMeteor);
        if (index !== -1) meteors.splice(index, 1);
      }, 4000);
    }
  }

  // Eventos para abrir el sobre (click en el botón o en el sobre)
  openButton.addEventListener('click', (e) => {
    e.stopPropagation();
    openEnvelopeWithAnimation();
  });
  envelopeDiv.addEventListener('click', (e) => {
    if (e.target === openButton || openButton.contains(e.target)) return;
    openEnvelopeWithAnimation();
  });

  // Inicialización completa
  window.addEventListener('load', () => {
    resizeCanvas();
    initStaticStars();
    initMeteors();
    animateShootingStars();
    // Cargar canvas-confetti desde CDN si no existe (asegurar)
    if (typeof canvasConfetti === 'undefined') {
      const script = document.createElement('script');
      script.src = 'https://cdn.jsdelivr.net/npm/canvas-confetti@1';
      script.onload = () => {
        console.log('Confetti listo');
      };
      document.head.appendChild(script);
    }
    // Pequeño detalle: cada 6 segundos aparece una estrella fugaz nueva aleatoria
    setInterval(() => {
      if (meteors.length < MAX_METEORS + 2) {
        let extra = new ShootingStar();
        extra.x = Math.random() * width;
        extra.y = Math.random() * (height * 0.4);
        extra.speed = Math.random() * 10 + 7;
        meteors.push(extra);
        setTimeout(() => {
          const idx = meteors.indexOf(extra);
          if (idx !== -1) meteors.splice(idx, 1);
        }, 5000);
      }
    }, 8000);
  });
</script>
<!-- Aseguramos que el canvas-confetti esté cargado -->
<script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1"></script>
</body>
</html>
← Back to timeline