| <!doctype html> |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1"> |
| <title>Anime HTML Codes Database</title> |
| <style> |
| :root { |
| --bg: #f6f5f2; |
| --panel: #ffffff; |
| --ink: #171923; |
| --muted: #667085; |
| --line: #ddd6cc; |
| --accent: #d9480f; |
| --accent-dark: #b53808; |
| --blue: #2454a6; |
| --green: #147d64; |
| --shadow: 0 18px 46px rgba(31, 26, 20, 0.12); |
| } |
| |
| * { |
| box-sizing: border-box; |
| } |
| |
| body { |
| margin: 0; |
| min-height: 100vh; |
| background: var(--bg); |
| color: var(--ink); |
| font-family: Arial, Helvetica, sans-serif; |
| } |
| |
| button, |
| input, |
| select, |
| textarea { |
| font: inherit; |
| } |
| |
| main { |
| width: min(1180px, calc(100% - 32px)); |
| margin: 0 auto; |
| padding: 28px 0; |
| } |
| |
| header { |
| display: grid; |
| grid-template-columns: 1fr auto; |
| gap: 20px; |
| align-items: end; |
| margin-bottom: 18px; |
| } |
| |
| h1 { |
| margin: 0 0 8px; |
| font-size: clamp(28px, 5vw, 48px); |
| line-height: 1; |
| } |
| |
| p { |
| margin: 0; |
| color: var(--muted); |
| line-height: 1.5; |
| } |
| |
| .counts { |
| display: flex; |
| gap: 10px; |
| flex-wrap: wrap; |
| justify-content: flex-end; |
| } |
| |
| .count { |
| min-width: 104px; |
| padding: 11px 13px; |
| background: var(--panel); |
| border: 1px solid var(--line); |
| border-radius: 8px; |
| box-shadow: var(--shadow); |
| } |
| |
| .count strong, |
| .count span { |
| display: block; |
| } |
| |
| .count strong { |
| font-size: 22px; |
| line-height: 1; |
| } |
| |
| .count span { |
| margin-top: 5px; |
| color: var(--muted); |
| font-size: 12px; |
| text-transform: uppercase; |
| } |
| |
| .workspace { |
| display: grid; |
| grid-template-columns: minmax(300px, 420px) 1fr; |
| gap: 16px; |
| align-items: start; |
| } |
| |
| .panel { |
| background: var(--panel); |
| border: 1px solid var(--line); |
| border-radius: 8px; |
| box-shadow: var(--shadow); |
| overflow: hidden; |
| } |
| |
| .tools { |
| display: grid; |
| grid-template-columns: 1fr 150px; |
| gap: 10px; |
| padding: 14px; |
| border-bottom: 1px solid var(--line); |
| background: #fffcf7; |
| } |
| |
| input, |
| select { |
| width: 100%; |
| height: 42px; |
| border: 1px solid var(--line); |
| border-radius: 6px; |
| padding: 0 12px; |
| color: var(--ink); |
| background: #fff; |
| } |
| |
| .list { |
| max-height: 660px; |
| overflow: auto; |
| } |
| |
| .item { |
| display: grid; |
| grid-template-columns: 1fr auto; |
| gap: 10px; |
| width: 100%; |
| padding: 14px; |
| border: 0; |
| border-bottom: 1px solid var(--line); |
| background: #fff; |
| color: var(--ink); |
| text-align: left; |
| cursor: pointer; |
| } |
| |
| .item:hover, |
| .item.active { |
| background: #fff4ec; |
| } |
| |
| .item strong { |
| display: block; |
| margin-bottom: 5px; |
| font-size: 15px; |
| } |
| |
| .item small { |
| color: var(--muted); |
| line-height: 1.4; |
| } |
| |
| .tag { |
| align-self: start; |
| min-width: 82px; |
| border-radius: 999px; |
| padding: 5px 8px; |
| color: #fff; |
| background: var(--blue); |
| font-size: 12px; |
| font-weight: 700; |
| text-align: center; |
| text-transform: capitalize; |
| } |
| |
| .detail-head { |
| display: flex; |
| justify-content: space-between; |
| gap: 12px; |
| align-items: start; |
| padding: 18px; |
| border-bottom: 1px solid var(--line); |
| } |
| |
| h2 { |
| margin: 0 0 8px; |
| font-size: 25px; |
| line-height: 1.15; |
| } |
| |
| .actions { |
| display: flex; |
| gap: 8px; |
| flex-wrap: wrap; |
| justify-content: flex-end; |
| } |
| |
| button.action { |
| height: 40px; |
| border: 0; |
| border-radius: 6px; |
| padding: 0 13px; |
| color: #fff; |
| background: var(--accent); |
| cursor: pointer; |
| font-weight: 700; |
| white-space: nowrap; |
| } |
| |
| button.action:hover { |
| background: var(--accent-dark); |
| } |
| |
| button.action.secondary { |
| background: var(--green); |
| } |
| |
| .preview { |
| min-height: 220px; |
| padding: 18px; |
| border-bottom: 1px solid var(--line); |
| background: |
| linear-gradient(90deg, rgba(36, 84, 166, 0.07) 1px, transparent 1px), |
| linear-gradient(rgba(36, 84, 166, 0.07) 1px, transparent 1px), |
| #fbfaf8; |
| background-size: 24px 24px; |
| } |
| |
| iframe { |
| display: block; |
| width: 100%; |
| min-height: 230px; |
| border: 1px solid var(--line); |
| border-radius: 8px; |
| background: #fff; |
| } |
| |
| .code-wrap { |
| padding: 0; |
| } |
| |
| pre { |
| margin: 0; |
| max-height: 420px; |
| overflow: auto; |
| padding: 18px; |
| background: #15171f; |
| color: #f8f8f2; |
| font-size: 13px; |
| line-height: 1.55; |
| white-space: pre-wrap; |
| } |
| |
| .empty { |
| padding: 26px 14px; |
| color: var(--muted); |
| text-align: center; |
| } |
| |
| @media (max-width: 900px) { |
| header, |
| .workspace, |
| .tools { |
| grid-template-columns: 1fr; |
| } |
| |
| .counts, |
| .actions { |
| justify-content: flex-start; |
| } |
| |
| .list { |
| max-height: 360px; |
| } |
| } |
| </style> |
| </head> |
| <body> |
| <main> |
| <header> |
| <div> |
| <h1>Anime HTML Codes Database</h1> |
| <p>Twenty simple anime-style HTML snippets with live preview and copy-ready code.</p> |
| </div> |
| <div class="counts"> |
| <div class="count"> |
| <strong id="totalCount">20</strong> |
| <span>Total</span> |
| </div> |
| <div class="count"> |
| <strong id="shownCount">20</strong> |
| <span>Shown</span> |
| </div> |
| </div> |
| </header> |
|
|
| <section class="workspace"> |
| <aside class="panel"> |
| <div class="tools"> |
| <input id="searchInput" type="search" placeholder="Search anime codes"> |
| <select id="typeFilter" aria-label="Filter by type"> |
| <option value="all">All types</option> |
| <option value="card">Card</option> |
| <option value="button">Button</option> |
| <option value="banner">Banner</option> |
| <option value="loader">Loader</option> |
| <option value="badge">Badge</option> |
| </select> |
| </div> |
| <div class="list" id="codeList"></div> |
| <div class="empty" id="emptyState" hidden>No anime codes found.</div> |
| </aside> |
|
|
| <section class="panel" aria-label="Selected code"> |
| <div class="detail-head"> |
| <div> |
| <h2 id="detailTitle">Select a code</h2> |
| <p id="detailDescription">Pick a snippet from the list.</p> |
| </div> |
| <div class="actions"> |
| <button class="action secondary" id="downloadButton" type="button">Download HTML</button> |
| <button class="action" id="copyButton" type="button">Copy Code</button> |
| </div> |
| </div> |
| <div class="preview"> |
| <iframe id="previewFrame" title="Anime code preview"></iframe> |
| </div> |
| <div class="code-wrap"> |
| <pre><code id="codeOutput"></code></pre> |
| </div> |
| </section> |
| </section> |
| </main> |
|
|
| <script> |
| const snippets = [ |
| { |
| id: 1, |
| type: "card", |
| title: "Hero Character Card", |
| description: "A profile card for an anime hero.", |
| code: `<!doctype html> |
| <html> |
| <head> |
| <style> |
| body{margin:0;min-height:100vh;display:grid;place-items:center;background:#f7f2ea;font-family:Arial} |
| .card{width:280px;border:4px solid #161616;border-radius:18px;background:#fff;box-shadow:10px 10px 0 #161616;overflow:hidden} |
| .top{height:130px;background:linear-gradient(135deg,#ff7a45,#ffd166);display:grid;place-items:center} |
| .face{width:88px;height:88px;border-radius:50%;background:#ffe8c7;border:4px solid #161616;position:relative} |
| .face:before,.face:after{content:"";position:absolute;top:34px;width:10px;height:10px;background:#161616;border-radius:50%} |
| .face:before{left:24px}.face:after{right:24px} |
| .body{padding:18px}.name{font-size:24px;font-weight:900}.role{color:#d9480f;font-weight:700;margin-top:6px} |
| </style> |
| </head> |
| <body><div class="card"><div class="top"><div class="face"></div></div><div class="body"><div class="name">Aki Storm</div><div class="role">Fire Squad Captain</div></div></div></body> |
| </html>` |
| }, |
| { |
| id: 2, |
| type: "button", |
| title: "Power Up Button", |
| description: "A bold call-to-action button with anime energy.", |
| code: `<!doctype html> |
| <html> |
| <head> |
| <style> |
| body{margin:0;min-height:100vh;display:grid;place-items:center;background:#10131c;font-family:Arial} |
| button{font-size:22px;font-weight:900;letter-spacing:0;border:3px solid #fff;border-radius:10px;padding:18px 34px;color:#10131c;background:#ffd166;box-shadow:0 0 0 5px #ef476f,0 0 30px #ffd166;cursor:pointer;transform:skew(-8deg)} |
| button:hover{background:#06d6a0;box-shadow:0 0 0 5px #118ab2,0 0 38px #06d6a0} |
| </style> |
| </head> |
| <body><button>POWER UP</button></body> |
| </html>` |
| }, |
| { |
| id: 3, |
| type: "banner", |
| title: "Opening Title Banner", |
| description: "A simple anime opening title block.", |
| code: `<!doctype html> |
| <html> |
| <head> |
| <style> |
| body{margin:0;min-height:100vh;display:grid;place-items:center;background:#eaf2ff;font-family:Arial} |
| .banner{width:min(760px,90vw);padding:38px 28px;border:4px solid #111;background:#fff;box-shadow:12px 12px 0 #2454a6;text-align:center} |
| .eyebrow{color:#d9480f;font-weight:900;text-transform:uppercase} |
| h1{font-size:54px;line-height:1;margin:10px 0}.line{height:8px;background:#111;margin:18px auto;width:80%} |
| p{margin:0;color:#475467;font-weight:700} |
| </style> |
| </head> |
| <body><section class="banner"><div class="eyebrow">Episode 01</div><h1>Skyline Academy</h1><div class="line"></div><p>The first bell rings at sunrise.</p></section></body> |
| </html>` |
| }, |
| { |
| id: 4, |
| type: "loader", |
| title: "Spinning Star Loader", |
| description: "A small loading animation for anime pages.", |
| code: `<!doctype html> |
| <html> |
| <head> |
| <style> |
| body{margin:0;min-height:100vh;display:grid;place-items:center;background:#fff8e6} |
| .star{width:90px;height:90px;background:#ffbe0b;clip-path:polygon(50% 0,61% 35%,98% 35%,68% 57%,79% 91%,50% 70%,21% 91%,32% 57%,2% 35%,39% 35%);animation:spin 1s linear infinite;filter:drop-shadow(0 0 18px #fb5607)} |
| @keyframes spin{to{transform:rotate(360deg)}} |
| </style> |
| </head> |
| <body><div class="star"></div></body> |
| </html>` |
| }, |
| { |
| id: 5, |
| type: "badge", |
| title: "Senpai Badge", |
| description: "A small rank badge for profile cards.", |
| code: `<!doctype html> |
| <html> |
| <head> |
| <style> |
| body{margin:0;min-height:100vh;display:grid;place-items:center;background:#f1f5f9;font-family:Arial} |
| .badge{display:inline-grid;place-items:center;width:170px;height:62px;border:3px solid #111;border-radius:999px;background:#ffcad4;color:#111;box-shadow:7px 7px 0 #111;font-size:22px;font-weight:900} |
| </style> |
| </head> |
| <body><div class="badge">SENPAI</div></body> |
| </html>` |
| }, |
| { |
| id: 6, |
| type: "card", |
| title: "Manga Panel Card", |
| description: "A black and white manga-style panel.", |
| code: `<!doctype html> |
| <html> |
| <head> |
| <style> |
| body{margin:0;min-height:100vh;display:grid;place-items:center;background:#ddd;font-family:Arial} |
| .panel{width:310px;padding:22px;border:5px solid #111;background:repeating-linear-gradient(-35deg,#fff 0 8px,#f2f2f2 8px 16px);box-shadow:12px 12px 0 #111} |
| .bubble{padding:18px;border:3px solid #111;border-radius:50%;background:#fff;text-align:center;font-size:24px;font-weight:900} |
| .caption{margin-top:18px;background:#111;color:#fff;padding:10px;font-weight:700} |
| </style> |
| </head> |
| <body><div class="panel"><div class="bubble">I will win!</div><div class="caption">Chapter 12: Final Round</div></div></body> |
| </html>` |
| }, |
| { |
| id: 7, |
| type: "button", |
| title: "Episode Play Button", |
| description: "A compact anime episode play button.", |
| code: `<!doctype html> |
| <html> |
| <head> |
| <style> |
| body{margin:0;min-height:100vh;display:grid;place-items:center;background:#eff6ff;font-family:Arial} |
| .play{display:flex;align-items:center;gap:12px;border:3px solid #1d2939;border-radius:8px;background:#fff;padding:14px 18px;box-shadow:7px 7px 0 #2454a6;font-weight:900} |
| .icon{width:0;height:0;border-top:12px solid transparent;border-bottom:12px solid transparent;border-left:18px solid #d9480f} |
| </style> |
| </head> |
| <body><button class="play"><span class="icon"></span><span>Watch Episode</span></button></body> |
| </html>` |
| }, |
| { |
| id: 8, |
| type: "banner", |
| title: "School Club Banner", |
| description: "A clean banner for an anime school club.", |
| code: `<!doctype html> |
| <html> |
| <head> |
| <style> |
| body{margin:0;min-height:100vh;display:grid;place-items:center;background:#fff7ed;font-family:Arial} |
| .club{width:min(700px,90vw);border:3px solid #111;border-radius:8px;overflow:hidden;background:#fff} |
| .top{background:#2454a6;color:#fff;padding:14px 20px;font-weight:900} |
| .main{padding:28px 20px}.main h1{margin:0;font-size:42px}.main p{color:#667085;font-weight:700} |
| </style> |
| </head> |
| <body><section class="club"><div class="top">After School Club</div><div class="main"><h1>Art Room Heroes</h1><p>Meet every Friday before sunset.</p></div></section></body> |
| </html>` |
| }, |
| { |
| id: 9, |
| type: "loader", |
| title: "Energy Ring Loader", |
| description: "A glowing ring animation.", |
| code: `<!doctype html> |
| <html> |
| <head> |
| <style> |
| body{margin:0;min-height:100vh;display:grid;place-items:center;background:#111827} |
| .ring{width:95px;height:95px;border-radius:50%;border:8px solid #334155;border-top-color:#06d6a0;border-right-color:#ffd166;animation:turn .8s linear infinite;box-shadow:0 0 26px #06d6a0} |
| @keyframes turn{to{transform:rotate(360deg)}} |
| </style> |
| </head> |
| <body><div class="ring"></div></body> |
| </html>` |
| }, |
| { |
| id: 10, |
| type: "badge", |
| title: "Episode Badge", |
| description: "A label for episode numbers.", |
| code: `<!doctype html> |
| <html> |
| <head> |
| <style> |
| body{margin:0;min-height:100vh;display:grid;place-items:center;background:#f8fafc;font-family:Arial} |
| .episode{border:3px solid #111;background:#fff;padding:12px 18px;box-shadow:6px 6px 0 #ef476f;font-size:20px;font-weight:900} |
| .episode span{color:#ef476f} |
| </style> |
| </head> |
| <body><div class="episode">EP <span>07</span> FINAL MATCH</div></body> |
| </html>` |
| }, |
| { |
| id: 11, |
| type: "card", |
| title: "Villain Notice Card", |
| description: "A sharp warning card for a villain profile.", |
| code: `<!doctype html> |
| <html> |
| <head> |
| <style> |
| body{margin:0;min-height:100vh;display:grid;place-items:center;background:#1f2937;font-family:Arial} |
| .card{width:310px;border:3px solid #f8fafc;background:#111827;color:#fff;padding:24px;box-shadow:10px 10px 0 #ef4444} |
| .label{color:#fca5a5;font-weight:900;text-transform:uppercase}.name{font-size:34px;font-weight:900;margin:12px 0}.note{color:#cbd5e1} |
| </style> |
| </head> |
| <body><div class="card"><div class="label">Wanted</div><div class="name">Noctis Rei</div><div class="note">Shadow technique specialist.</div></div></body> |
| </html>` |
| }, |
| { |
| id: 12, |
| type: "button", |
| title: "Manga Next Button", |
| description: "A next chapter button with hard edges.", |
| code: `<!doctype html> |
| <html> |
| <head> |
| <style> |
| body{margin:0;min-height:100vh;display:grid;place-items:center;background:#fff;font-family:Arial} |
| .next{border:4px solid #000;background:#000;color:#fff;padding:16px 28px;font-size:22px;font-weight:900;box-shadow:8px 8px 0 #ffd166;cursor:pointer} |
| .next:hover{box-shadow:8px 8px 0 #06d6a0} |
| </style> |
| </head> |
| <body><button class="next">NEXT CHAPTER</button></body> |
| </html>` |
| }, |
| { |
| id: 13, |
| type: "banner", |
| title: "Tournament Banner", |
| description: "A tournament matchup headline.", |
| code: `<!doctype html> |
| <html> |
| <head> |
| <style> |
| body{margin:0;min-height:100vh;display:grid;place-items:center;background:#f0fdf4;font-family:Arial} |
| .match{width:min(720px,92vw);border:4px solid #111;background:#fff;padding:28px;text-align:center;box-shadow:12px 12px 0 #16a34a} |
| .small{font-weight:900;color:#16a34a}.names{font-size:38px;font-weight:900;margin:12px 0}.vs{color:#d9480f} |
| </style> |
| </head> |
| <body><section class="match"><div class="small">Grand Tournament</div><div class="names">KAI <span class="vs">VS</span> RIN</div><p>Final arena opens tonight.</p></section></body> |
| </html>` |
| }, |
| { |
| id: 14, |
| type: "loader", |
| title: "Dot Dash Loader", |
| description: "Three quick dots for loading scenes.", |
| code: `<!doctype html> |
| <html> |
| <head> |
| <style> |
| body{margin:0;min-height:100vh;display:grid;place-items:center;background:#fff1f2} |
| .dots{display:flex;gap:12px}.dots span{width:22px;height:22px;border-radius:50%;background:#e11d48;animation:bounce .6s infinite alternate}.dots span:nth-child(2){animation-delay:.15s}.dots span:nth-child(3){animation-delay:.3s} |
| @keyframes bounce{to{transform:translateY(-22px);background:#f59e0b}} |
| </style> |
| </head> |
| <body><div class="dots"><span></span><span></span><span></span></div></body> |
| </html>` |
| }, |
| { |
| id: 15, |
| type: "badge", |
| title: "Clan Badge", |
| description: "A circular clan mark.", |
| code: `<!doctype html> |
| <html> |
| <head> |
| <style> |
| body{margin:0;min-height:100vh;display:grid;place-items:center;background:#ecfeff;font-family:Arial} |
| .clan{width:140px;height:140px;border:5px solid #111;border-radius:50%;background:radial-gradient(circle,#fff 0 34%,#22d3ee 35% 58%,#111 59% 62%,#fff 63%);display:grid;place-items:center;font-weight:900;box-shadow:8px 8px 0 #111} |
| </style> |
| </head> |
| <body><div class="clan">CLAN</div></body> |
| </html>` |
| }, |
| { |
| id: 16, |
| type: "card", |
| title: "Quest Card", |
| description: "A mission card for an anime adventure.", |
| code: `<!doctype html> |
| <html> |
| <head> |
| <style> |
| body{margin:0;min-height:100vh;display:grid;place-items:center;background:#fafaf9;font-family:Arial} |
| .quest{width:320px;border:3px solid #292524;border-radius:8px;background:#fff7ed;padding:20px;box-shadow:9px 9px 0 #292524} |
| .rank{display:inline-block;background:#d9480f;color:#fff;padding:6px 10px;border-radius:4px;font-weight:900}.title{font-size:28px;font-weight:900;margin:14px 0}.reward{color:#147d64;font-weight:900} |
| </style> |
| </head> |
| <body><div class="quest"><span class="rank">S RANK</span><div class="title">Find the Sky Stone</div><div class="reward">Reward: 5000 coins</div></div></body> |
| </html>` |
| }, |
| { |
| id: 17, |
| type: "button", |
| title: "Transform Button", |
| description: "A transformation button with glow.", |
| code: `<!doctype html> |
| <html> |
| <head> |
| <style> |
| body{margin:0;min-height:100vh;display:grid;place-items:center;background:#140f1f;font-family:Arial} |
| button{border:2px solid #f5d0fe;border-radius:999px;padding:16px 30px;background:#7e22ce;color:#fff;font-size:21px;font-weight:900;box-shadow:0 0 22px #c084fc;cursor:pointer} |
| button:hover{background:#a21caf;box-shadow:0 0 34px #f0abfc} |
| </style> |
| </head> |
| <body><button>TRANSFORM</button></body> |
| </html>` |
| }, |
| { |
| id: 18, |
| type: "banner", |
| title: "Subtitle Strip", |
| description: "A simple subtitle strip for anime scenes.", |
| code: `<!doctype html> |
| <html> |
| <head> |
| <style> |
| body{margin:0;min-height:100vh;display:grid;place-items:end center;background:#1e293b;font-family:Arial;padding:30px} |
| .subtitle{max-width:760px;background:rgba(0,0,0,.82);color:#fff;border:2px solid #fff;border-radius:6px;padding:14px 20px;font-size:24px;font-weight:800;text-align:center} |
| </style> |
| </head> |
| <body><div class="subtitle">I promised we would see the sunrise together.</div></body> |
| </html>` |
| }, |
| { |
| id: 19, |
| type: "loader", |
| title: "Slash Loader", |
| description: "Animated sword-slash bars.", |
| code: `<!doctype html> |
| <html> |
| <head> |
| <style> |
| body{margin:0;min-height:100vh;display:grid;place-items:center;background:#f8fafc} |
| .slash{display:flex;gap:8px;transform:skew(-20deg)}.slash span{width:14px;height:80px;background:#111;animation:flash .8s infinite alternate}.slash span:nth-child(2){animation-delay:.15s}.slash span:nth-child(3){animation-delay:.3s} |
| @keyframes flash{to{height:35px;background:#ef4444}} |
| </style> |
| </head> |
| <body><div class="slash"><span></span><span></span><span></span></div></body> |
| </html>` |
| }, |
| { |
| id: 20, |
| type: "badge", |
| title: "New Season Badge", |
| description: "A pill badge for a new season announcement.", |
| code: `<!doctype html> |
| <html> |
| <head> |
| <style> |
| body{margin:0;min-height:100vh;display:grid;place-items:center;background:#eef2ff;font-family:Arial} |
| .season{border:3px solid #312e81;border-radius:999px;background:#fff;color:#312e81;padding:14px 22px;font-weight:900;font-size:22px;box-shadow:0 0 0 8px #c7d2fe} |
| </style> |
| </head> |
| <body><div class="season">NEW SEASON</div></body> |
| </html>` |
| } |
| ]; |
| |
| const list = document.getElementById("codeList"); |
| const emptyState = document.getElementById("emptyState"); |
| const searchInput = document.getElementById("searchInput"); |
| const typeFilter = document.getElementById("typeFilter"); |
| const shownCount = document.getElementById("shownCount"); |
| const detailTitle = document.getElementById("detailTitle"); |
| const detailDescription = document.getElementById("detailDescription"); |
| const codeOutput = document.getElementById("codeOutput"); |
| const previewFrame = document.getElementById("previewFrame"); |
| const copyButton = document.getElementById("copyButton"); |
| const downloadButton = document.getElementById("downloadButton"); |
| |
| let selected = snippets[0]; |
| |
| function filterSnippets() { |
| const query = searchInput.value.trim().toLowerCase(); |
| const type = typeFilter.value; |
| return snippets.filter((snippet) => { |
| const text = `${snippet.title} ${snippet.description} ${snippet.type}`.toLowerCase(); |
| return (type === "all" || snippet.type === type) && text.includes(query); |
| }); |
| } |
| |
| function renderList() { |
| const visible = filterSnippets(); |
| list.innerHTML = ""; |
| shownCount.textContent = String(visible.length); |
| emptyState.hidden = visible.length > 0; |
| |
| for (const snippet of visible) { |
| const button = document.createElement("button"); |
| button.className = `item${snippet.id === selected.id ? " active" : ""}`; |
| button.type = "button"; |
| button.innerHTML = ` |
| <span> |
| <strong>${escapeHtml(snippet.id + ". " + snippet.title)}</strong> |
| <small>${escapeHtml(snippet.description)}</small> |
| </span> |
| <span class="tag">${escapeHtml(snippet.type)}</span> |
| `; |
| button.addEventListener("click", () => { |
| selected = snippet; |
| renderDetail(); |
| renderList(); |
| }); |
| list.appendChild(button); |
| } |
| } |
| |
| function renderDetail() { |
| detailTitle.textContent = selected.title; |
| detailDescription.textContent = `${selected.type.toUpperCase()} #${selected.id}: ${selected.description}`; |
| codeOutput.textContent = selected.code; |
| previewFrame.srcdoc = selected.code; |
| } |
| |
| function escapeHtml(value) { |
| return String(value) |
| .replaceAll("&", "&") |
| .replaceAll("<", "<") |
| .replaceAll(">", ">") |
| .replaceAll('"', """) |
| .replaceAll("'", "'"); |
| } |
| |
| copyButton.addEventListener("click", async () => { |
| await navigator.clipboard.writeText(selected.code); |
| copyButton.textContent = "Copied"; |
| setTimeout(() => { |
| copyButton.textContent = "Copy Code"; |
| }, 1200); |
| }); |
| |
| downloadButton.addEventListener("click", () => { |
| const blob = new Blob([selected.code], { type: "text/html" }); |
| const link = document.createElement("a"); |
| link.href = URL.createObjectURL(blob); |
| link.download = `${selected.title.toLowerCase().replaceAll(" ", "-")}.html`; |
| link.click(); |
| URL.revokeObjectURL(link.href); |
| }); |
| |
| searchInput.addEventListener("input", renderList); |
| typeFilter.addEventListener("change", renderList); |
| renderDetail(); |
| renderList(); |
| </script> |
| </body> |
| </html> |
|
|