| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8" /> |
| <title>Mini CodePen – Live Preview</title> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| <style> |
| * { |
| box-sizing: border-box; |
| margin: 0; |
| padding: 0; |
| font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; |
| } |
| |
| body { |
| background: #0f172a; |
| color: #e5e7eb; |
| min-height: 100vh; |
| display: flex; |
| flex-direction: column; |
| } |
| |
| header { |
| padding: 12px 20px; |
| border-bottom: 1px solid #1f2937; |
| display: flex; |
| align-items: center; |
| justify-content: space-between; |
| gap: 12px; |
| } |
| |
| header h1 { |
| font-size: 1.1rem; |
| font-weight: 600; |
| color: #f9fafb; |
| } |
| |
| header span { |
| font-size: 0.8rem; |
| color: #9ca3af; |
| } |
| |
| .actions { |
| display: flex; |
| gap: 8px; |
| } |
| |
| button { |
| border: none; |
| padding: 8px 14px; |
| border-radius: 999px; |
| font-size: 0.85rem; |
| cursor: pointer; |
| background: #22c55e; |
| color: #022c22; |
| font-weight: 600; |
| transition: transform 0.1s ease, box-shadow 0.1s ease, background 0.15s ease; |
| } |
| |
| button:hover { |
| transform: translateY(-1px); |
| box-shadow: 0 8px 20px rgba(34, 197, 94, 0.35); |
| } |
| |
| button.secondary { |
| background: #111827; |
| color: #e5e7eb; |
| border: 1px solid #374151; |
| box-shadow: none; |
| } |
| |
| button.secondary:hover { |
| background: #020617; |
| } |
| |
| main { |
| flex: 1; |
| display: grid; |
| grid-template-columns: 1.1fr 1fr; |
| min-height: 0; |
| } |
| |
| @media (max-width: 900px) { |
| main { |
| grid-template-columns: 1fr; |
| grid-template-rows: minmax(300px, 1fr) minmax(250px, 1fr); |
| } |
| } |
| |
| .panes { |
| display: grid; |
| grid-template-rows: repeat(3, minmax(0, 1fr)); |
| border-right: 1px solid #1f2937; |
| min-height: 0; |
| } |
| |
| .editor { |
| display: flex; |
| flex-direction: column; |
| border-bottom: 1px solid #1f2937; |
| min-height: 0; |
| background: #020617; |
| } |
| |
| .editor-header { |
| display: flex; |
| align-items: center; |
| justify-content: space-between; |
| padding: 6px 10px; |
| font-size: 0.75rem; |
| border-bottom: 1px solid #111827; |
| background: linear-gradient(to right, #020617, #0f172a); |
| } |
| |
| .editor-header span.label { |
| text-transform: uppercase; |
| letter-spacing: 0.08em; |
| font-weight: 600; |
| } |
| |
| .editor-header span.badge { |
| font-size: 0.65rem; |
| padding: 2px 8px; |
| border-radius: 999px; |
| background: #111827; |
| border: 1px solid #1f2937; |
| color: #9ca3af; |
| } |
| |
| textarea { |
| flex: 1; |
| width: 100%; |
| border: none; |
| resize: none; |
| padding: 10px 12px; |
| font-family: "Fira Code", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; |
| font-size: 0.8rem; |
| line-height: 1.4; |
| color: #e5e7eb; |
| background: #020617; |
| outline: none; |
| overflow: auto; |
| } |
| |
| textarea::placeholder { |
| color: #4b5563; |
| } |
| |
| .preview-pane { |
| display: flex; |
| flex-direction: column; |
| min-height: 0; |
| background: #020617; |
| } |
| |
| .preview-header { |
| padding: 6px 10px; |
| font-size: 0.75rem; |
| border-bottom: 1px solid #111827; |
| display: flex; |
| align-items: center; |
| justify-content: space-between; |
| background: linear-gradient(to right, #111827, #1f2937); |
| } |
| |
| .preview-header span { |
| text-transform: uppercase; |
| letter-spacing: 0.08em; |
| font-weight: 600; |
| } |
| |
| iframe { |
| flex: 1; |
| border: none; |
| background: white; |
| } |
| |
| footer { |
| font-size: 0.7rem; |
| padding: 6px 12px; |
| text-align: right; |
| color: #6b7280; |
| border-top: 1px solid #111827; |
| } |
| </style> |
| </head> |
| <body> |
| <header> |
| <div> |
| <h1>Mini Code Preview</h1> |
| <span>Paste HTML, CSS, JS and click “Run” to preview</span> |
| </div> |
| <div class="actions"> |
| <button id="run-btn">Run ▶</button> |
| <button id="reset-btn" class="secondary">Reset</button> |
| </div> |
| </header> |
|
|
| <main> |
| |
| <section class="panes"> |
| <div class="editor"> |
| <div class="editor-header"> |
| <span class="label">HTML</span> |
| <span class="badge">Markup</span> |
| </div> |
| <textarea id="html-input" placeholder="<h1>Hello World</h1>"> |
| <div class="card"> |
| <h1>Hello Mini CodePen 👋</h1> |
| <p>Edit HTML, CSS, and JS, then press <strong>Run</strong>.</p> |
| <button onclick="alert('JS is working!')">Click Me</button> |
| </div> |
| </textarea> |
| </div> |
|
|
| <div class="editor"> |
| <div class="editor-header"> |
| <span class="label">CSS</span> |
| <span class="badge">Styles</span> |
| </div> |
| <textarea id="css-input" placeholder="body { font-family: sans-serif; }"> |
| body { |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| min-height: 100vh; |
| margin: 0; |
| background: linear-gradient(135deg, #22c55e, #0ea5e9); |
| font-family: system-ui, sans-serif; |
| } |
|
|
| .card { |
| background: white; |
| padding: 24px 28px; |
| border-radius: 16px; |
| box-shadow: 0 20px 50px rgba(15, 23, 42, 0.35); |
| max-width: 360px; |
| text-align: center; |
| } |
|
|
| .card h1 { |
| margin-bottom: 10px; |
| color: #111827; |
| } |
|
|
| .card p { |
| margin-bottom: 16px; |
| color: #4b5563; |
| } |
|
|
| .card button { |
| border: none; |
| background: #22c55e; |
| color: #022c22; |
| padding: 8px 18px; |
| border-radius: 999px; |
| font-weight: 600; |
| cursor: pointer; |
| } |
| </textarea> |
| </div> |
|
|
| <div class="editor"> |
| <div class="editor-header"> |
| <span class="label">JavaScript</span> |
| <span class="badge">Logic</span> |
| </div> |
| <textarea id="js-input" placeholder="console.log('Hello');"> |
| console.log("Mini CodePen ready!"); |
|
|
| </textarea> |
| </div> |
| </section> |
|
|
| |
| <section class="preview-pane"> |
| <div class="preview-header"> |
| <span>Preview</span> |
| <small id="status-text">Idle</small> |
| </div> |
| <iframe id="preview-frame" title="Live Preview"></iframe> |
| </section> |
| </main> |
|
|
| <footer> |
| Mini Code Preview • Pure HTML + CSS + JavaScript |
| </footer> |
|
|
| <script> |
| const htmlInput = document.getElementById("html-input"); |
| const cssInput = document.getElementById("css-input"); |
| const jsInput = document.getElementById("js-input"); |
| const previewFrame = document.getElementById("preview-frame"); |
| const runBtn = document.getElementById("run-btn"); |
| const resetBtn = document.getElementById("reset-btn"); |
| const statusText = document.getElementById("status-text"); |
| |
| function runPreview() { |
| const html = htmlInput.value || ""; |
| const css = cssInput.value || ""; |
| const js = jsInput.value || ""; |
| |
| const finalCode = ` |
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <style> |
| ${css} |
| </style> |
| </head> |
| <body> |
| ${html} |
| <script> |
| ${js.replace(/<\/script>/gi, "<\\/script>")} |
| </script> |
| </body> |
| </html>`; |
|
|
| previewFrame.srcdoc = finalCode; |
| statusText.textContent = "Last run: " + new Date().toLocaleTimeString(); |
| } |
|
|
| function resetEditors() { |
| htmlInput.value = "<h1>Hello World</h1>"; |
| cssInput.value = "body { font-family: system-ui, sans-serif; }"; |
| jsInput.value = "console.log('Reset!');"; |
| runPreview(); |
| } |
|
|
| runBtn.addEventListener("click", runPreview); |
| resetBtn.addEventListener("click", resetEditors); |
|
|
| // Optional: auto-run on Ctrl+Enter in any editor |
| [htmlInput, cssInput, jsInput].forEach((area) => { |
| area.addEventListener("keydown", (e) => { |
| if (e.ctrlKey && e.key === "Enter") { |
| e.preventDefault(); |
| runPreview(); |
| } |
| }); |
| }); |
|
|
| // Initial load |
| runPreview(); |
| </script> |
| </body> |
| </html> |