Source: site.view [edit]
Function name: happyBDJP
Arguments:
Description:
Page type: html
Render function:  
Module: adam

Page source:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>πŸŽ‰ Happy Birthday!</title>
  <meta name="description" content="A birthday message for JP!" />
  <style>
    :root {
      --bg: radial-gradient(1200px 800px at 10% 10%, #fff6e7 0%, #ffe6f6 35%, #e7f3ff 70%, #f5f7ff 100%);
      --ink: #0f172a;         /* slate-900 */
      --muted: #475569;       /* slate-600 */
      --accent: #7c3aed;      /* violet-600 */
      --accent-2: #f97316;    /* orange-500 */
      --card: rgba(255, 255, 255, 0.72);
      --border: rgba(15, 23, 42, 0.08);
      --shadow: 0 10px 30px rgba(2, 6, 23, 0.08), 0 2px 8px rgba(2, 6, 23, 0.06);
    }

    /* Base reset */
    * { box-sizing: border-box; }
    html, body { height: 100%; }
    body {
      margin: 0;
      color: var(--ink);
      background: var(--bg);
      font: 16px/1.5 system-ui, -apple-system, Segoe UI, Roboto, "Helvetica Neue", Arial, "Noto Sans", "Apple Color Emoji", "Segoe UI Emoji";
      overflow-x: hidden;
    }

    .wrap {
      max-width: 1100px;
      margin: 0 auto;
      padding: 24px;
    }

    /* Top banner */
    header.hero {
      position: relative;
      margin: 32px 0 22px;
      border-radius: 28px;
      background: var(--card);
      border: 1px solid var(--border);
      box-shadow: var(--shadow);
      overflow: hidden;
      padding: clamp(20px, 3.5vw, 36px);
      backdrop-filter: blur(6px);
    }

    .hero h1 {
      margin: 0 0 6px;
      font-size: clamp(28px, 5vw, 56px);
      letter-spacing: -0.02em;
    }
    .hero p.lead {
      margin: 6px 0 0;
      font-size: clamp(16px, 2.2vw, 20px);
      color: var(--muted);
    }

    /* Confetti */
    .confetti {
      position: absolute;
      inset: 0;
      pointer-events: none;
      overflow: hidden;
    }
    .confetti span {
      position: absolute;
      top: -10%;
      width: 10px; height: 14px;
      border-radius: 2px;
      animation: drop 6s linear infinite;
      opacity: 0.85;
    }
    /* generate a handful of pieces with different hues */
    .confetti span:nth-child(odd) { background: #f97316; }
    .confetti span:nth-child(3n) { background: #22c55e; }
    .confetti span:nth-child(5n) { background: #3b82f6; }
    .confetti span:nth-child(7n) { background: #eab308; }
    .confetti span:nth-child(11n) { background: #a855f7; }

    @keyframes drop {
      0%   { transform: translateY(-120%) rotate(0deg); opacity: 0; }
      10%  { opacity: 1; }
      100% { transform: translateY(120vh) rotate(720deg); opacity: 1; }
    }

    /* Main card */
    .card {
      display: grid;
      gap: 18px;
      grid-template-columns: 1fr;
    }

    .panel {
      border-radius: 22px;
      background: var(--card);
      border: 1px solid var(--border);
      box-shadow: var(--shadow);
      padding: clamp(16px, 2.6vw, 28px);
    }

    /* Video */
    .video-wrap {
      position: relative;
      border-radius: 18px;
      overflow: hidden;
      border: 1px solid var(--border);
      background: #0b1220;
      aspect-ratio: 16 / 9; /* keeps it large & horizontal */
      display: grid;
      place-items: center;
    }
    .video-wrap iframe,
    .video-wrap video {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
      border: 0;
    }
    .video-placeholder {
      color: #cbd5e1;
      text-align: center;
      padding: 16px;
      font-size: clamp(14px, 1.6vw, 16px);
    }

    /* Message & details */
    .grid {
      display: grid;
      gap: 18px;
    }
    @media (min-width: 960px) {
      .card {
        grid-template-columns: 2fr 1fr;
        align-items: start;
      }
      .grid.two { grid-template-columns: 1fr 1fr; }
    }

    h2 { margin: 0 0 8px; font-size: clamp(20px, 2.6vw, 28px); }
    p { margin: 0 0 10px; }

    .cta-row {
      display: flex;
      flex-wrap: wrap;
      gap: 10px;
      margin-top: 12px;
    }
    .btn {
      appearance: none;
      border: 0; cursor: pointer;
      font-weight: 600;
      border-radius: 999px;
      padding: 12px 18px;
      background: linear-gradient(135deg, var(--accent), var(--accent-2));
      color: white;
      box-shadow: 0 6px 16px rgba(124, 58, 237, 0.35);
      transition: transform .06s ease, box-shadow .2s ease;
      text-decoration: none;
      display: inline-flex;
      align-items: center; gap: 8px;
    }
    .btn:active { transform: translateY(1px); box-shadow: 0 4px 10px rgba(124,58,237,.28); }

    /* Photo strip (optional) */
    .photo-strip {
      display: grid;
      grid-template-columns: repeat(6, 1fr);
      gap: 8px;
    }
    .photo-strip img {
      width: 100%;
      height: 100px;
      object-fit: cover;
      border-radius: 12px;
      border: 1px solid var(--border);
    }
    @media (max-width: 680px) {
      .photo-strip { grid-template-columns: repeat(3, 1fr); }
      .photo-strip img { height: 90px; }
    }

    /* Footer */
    footer {
      text-align: center;
      color: var(--muted);
      padding: 30px 10px 60px;
      font-size: 14px;
    }

    /* Subtle floating balloons (SVG) */
    .balloons {
      position: absolute; inset: 0; pointer-events: none; overflow: hidden;
    }
    .balloons svg { position: absolute; opacity: .25; animation: float 14s ease-in-out infinite; }
    .b1 { left: -40px; top: 20px; animation-delay: 0s; }
    .b2 { right: -30px; top: 120px; animation-delay: 2s; }
    .b3 { left: 10%; bottom: -30px; animation-delay: 4s; }
    @keyframes float {
      0%,100% { transform: translateY(0px); }
      50% { transform: translateY(-16px); }
    }

    /* Print styles */
    @media print {
      .confetti, .balloons, .btn { display: none !important; }
      header.hero, .panel { box-shadow: none; }
      body { background: white; }
    }
  </style>
</head>
<body>
  <div class="wrap">
    <header class="hero">
      <div class="balloons" aria-hidden="true">
        <svg class="b1" width="120" height="220" viewBox="0 0 120 220" fill="none" xmlns="http://www.w3.org/2000/svg">
          <ellipse cx="60" cy="60" rx="56" ry="60" fill="#7c3aed"/>
          <path d="M60 120 C62 150, 70 170, 60 220" stroke="#7c3aed" stroke-width="2"/>
        </svg>
        <svg class="b2" width="100" height="200" viewBox="0 0 100 200" fill="none" xmlns="http://www.w3.org/2000/svg">
          <ellipse cx="50" cy="50" rx="46" ry="50" fill="#f97316"/>
          <path d="M50 100 C52 130, 60 160, 52 200" stroke="#f97316" stroke-width="2"/>
        </svg>
        <svg class="b3" width="140" height="240" viewBox="0 0 140 240" fill="none" xmlns="http://www.w3.org/2000/svg">
          <ellipse cx="70" cy="70" rx="66" ry="70" fill="#22c55e"/>
          <path d="M70 140 C72 170, 80 190, 70 240" stroke="#22c55e" stroke-width="2"/>
        </svg>
      </div>

      <h1>Happy Birthday, <span id="name">JP</span>! πŸŽ‚πŸŽ‰</h1>
      <p class="lead">I'm so proud of the year you've had, and excited about the year to come! πŸ’œ</p>
      <div class="confetti" aria-hidden="true"></div>
    </header>

    <main class="card">
      <!-- LEFT COLUMN: Video + Message -->
      <section class="panel">
        <h2>Your Birthday Present</h2>
        <div class="video-wrap" id="video">
          <div class="video-placeholder" aria-hidden="true">
            <iframe width="560" height="315" src="https://www.youtube.com/embed/DFHTEvjeLrg?si=m5sZJQP41L8KVpMa" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
          
          </div>
        </div>

        <div class="cta-row">
          <a class="btn" href="https://www.dropbox.com/scl/fi/klye0ufvyslzt3euvtglm/Shockwave_dl.m4v?rlkey=owmczhii9ci5n2owuw8h4fx3e&st=guprpepi&dl=0" title="Jump to tutorial">πŸ’Œ Download Tutorial</a>
        </div>
      </section>

      <!-- RIGHT COLUMN: Details -->
      <aside class="panel">
        <h2>About Your Present</h2>
        <p><strong>For:  JP</strong></p>
        <p><strong>Date: October 5, 2025</strong></p>
        <p><strong>From: Adam</strong></p>
        <p>Hey JP, <p>
        <p>   For your present I bought you "Shockwave" by Johannes Mengel: 5 routines that should be up your alley (danger magic), not too hard to learn, require no props other than your body, and just in time to learn for Halloween!  </p>
        <p>Enjoy!!</p>
        <p>I treasure our walks and our friendship.  Looking forward to an exciting year for both of us!</p>
      </aside>
    </main>

    <section id="messages" class="panel" style="margin-top:18px;">
      <h2>Some Inspiration</h2>
      <div class="grid two">
        <div>
          <p><em>β€œWithout continual growth and progress, such words as improvement, achievement, and success have no meaning.” <br> -– Benjamin Franklin</em></p>
        </div>
        <div>
          <p><em>β€œWe are what we repeatedly do. Excellence, then, is not an act, but a habit.” <br> -– Aristotle</em></p>
        </div>
      </div>
    </section>


    <footer>
      Made with ❀️ just for you!  OK, I had a little help from AI... ;-)
    </footer>
  </div>

  <script>
    // Confetti placement: sprinkle spans across the width with random timing
    (function confetti() {
      const c = document.querySelector('.confetti');
      if (!c) return;
      const pieces = 60;
      for (let i = 0; i < pieces; i++) {
        const s = document.createElement('span');
        s.style.left = Math.random() * 100 + '%';
        s.style.animationDelay = (Math.random() * 6) + 's';
        s.style.animationDuration = (4 + Math.random() * 4) + 's';
        s.style.transform = `scale(${0.6 + Math.random()*0.9})`;
        c.appendChild(s);
      }
    })();
  </script>
</body>
</html>