GPT-6.1 Sol
by OpenAIreasoning defaultClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 1 min 50 s
- Cost
- $0.095
- Output tokens
- 9,357
- Spent thinking
- 417 tokens
- Speed
- 92.7 tok/s
- Console errors
- 0
- First token after
- 8.7 s
- First visible text after
- 21.0 s
- Prompt tokens
- 493
- Code size
- 29.0 KB
- Finish reason
- stop
- Served by
- OpenAI
- Model id
openai/gpt-6.1-sol- Reasoning sent
model default- Max output
- 128,000 tokens
- Generated
- Nov 12, 2026
What it was asked
The prompt
Build an interactive Kanban board in vanilla HTML, CSS and JavaScript (no framework, no library). Requirements: - Three columns: "To do", "In progress", "Done", each showing its card count. - Pre-populate the board with 6 realistic cards spread across the columns so the first screenshot looks alive. - Each card has a title and a priority (low / medium / high) shown as a colored badge. - Add a card through a small modal form (title required), and delete a card with a button on it. - Drag and drop cards between columns with the mouse, with a clear visual drop indicator. - A search field that filters cards live by title. - A light / dark theme toggle. - State lives in memory only (no storage APIs).
System prompt, sent with every prompt
You are generating a self-contained web demo. It will be rendered automatically in a sandboxed iframe and compared side by side with the output of other AI models given the exact same task. Output rules: - Reply with exactly ONE fenced code block containing the complete file: ```html (or ```svg when the task asks for an SVG). No text before or after the code block. - Everything must be inline: CSS in <style>, JavaScript in <script>. No external files, images, fonts or network requests, except the CDN URLs explicitly allowed by the task. - Do not use localStorage, sessionStorage, cookies, IndexedDB, alert(), confirm(), prompt() or window.open(): they are blocked in the sandbox and will throw. - The page must look right in a 1280×800 viewport and adapt gracefully down to 375px wide. No horizontal scrollbar. - Something meaningful must be visible on first paint: a screenshot is taken automatically about 3 seconds after load, without any interaction. - Everything that makes the demo interesting must be visible within the first seconds: nothing hidden behind a high score, a later level or a long play session. - Games must start in a self-playing demo mode (a simple AI plays) behind a "Click or press a key to start" message, so the game can be judged in action without playing. - The iframe only receives keyboard events after the user clicks it: if the demo uses the keyboard, display a clear "Click or press a key to start" message. - The code must run with zero errors in the console of the latest Chrome.
Code run-1.html · 152 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Forma — Product launch</title>
<style>
:root{--bg:#f7f8fa;--surface:#fff;--column:#eff1f5;--text:#252735;--muted:#8b8e9e;--line:#e8eaf0;--purple:#7060df;--purple-soft:#eeebfc;--shadow:0 2px 4px #24243b04,0 5px 15px #24243b03;--input:#fff}
*{box-sizing:border-box}body{margin:0;font-family:Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;background:var(--bg);color:var(--text);font-size:14px;-webkit-font-smoothing:antialiased}button,input,select,textarea{font:inherit}button{cursor:pointer}button:focus-visible,a:focus-visible{outline:3px solid #ad9ff8;outline-offset:3px}button{color:inherit}svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0}.app{display:flex;min-height:100vh}.sidebar{width:228px;flex-shrink:0;background:var(--surface);border-right:1px solid var(--line);padding:32px 21px 20px;display:flex;flex-direction:column;position:fixed;height:100vh}.brand{display:flex;align-items:center;gap:10px;font-size:25px;font-weight:750;letter-spacing:-1px;padding:0 10px}.brand-mark{display:grid;grid-template-columns:repeat(2,9px);gap:3px;transform:rotate(-6deg)}.brand-mark i{width:9px;height:9px;background:var(--purple);border-radius:2px}.brand-mark i:last-child{opacity:.45}.workspace{margin:35px 0 30px;padding:12px 10px;border:1px solid var(--line);border-radius:9px;display:flex;align-items:center;gap:10px;font-size:12px;font-weight:600}.workspace-icon{width:29px;height:29px;border-radius:7px;display:grid;place-items:center;background:#f0eafa;color:#8364ad;font-size:12px}.workspace small{display:block;color:var(--muted);font-size:10px;font-weight:400;margin-top:3px}.workspace svg{margin-left:auto;width:14px;color:var(--muted)}.nav-label{font-size:10px;letter-spacing:1.4px;font-weight:700;color:var(--muted);margin:0 12px 14px}.nav-item{display:flex;align-items:center;gap:12px;padding:12px;margin:4px 0;border-radius:7px;font-size:13px;color:var(--muted)}.nav-item.active{background:var(--purple-soft);color:var(--purple);font-weight:600}.nav-item .pill{margin-left:auto;font-size:10px;padding:2px 6px;background:#e0dafa;border-radius:4px}.sidebar-project{margin-top:34px}.project-link{display:flex;gap:11px;align-items:center;padding:12px;font-size:12px;color:var(--muted)}.project-dot{width:7px;height:7px;border-radius:50%;background:#b6a5e3}.sidebar-bottom{margin-top:auto}.tip{background:var(--bg);border:1px solid var(--line);border-radius:10px;padding:14px;margin-bottom:18px}.tip .small-title{font-size:12px;font-weight:600;display:flex;gap:7px;align-items:center}.tip p{font-size:11px;line-height:1.7;color:var(--muted);margin:7px 0 0}.theme-toggle{width:100%;background:none;border:0;display:flex;align-items:center;gap:10px;color:var(--muted);padding:12px;font-size:12px}.switch{margin-left:auto;width:30px;height:17px;border-radius:20px;background:#e6e7ec;padding:3px}.switch:after{content:"";display:block;height:11px;width:11px;border-radius:50%;background:#fff;box-shadow:0 1px 3px #0002;transition:transform .2s}.profile{display:flex;align-items:center;gap:9px;border-top:1px solid var(--line);padding:18px 7px 0;margin-top:12px}.avatar{display:grid;place-items:center;width:27px;height:27px;border-radius:50%;font-size:9px;font-weight:700;border:2px solid var(--surface);background:#e9def1;color:#866895}.profile .avatar{width:32px;height:32px;font-size:10px;background:#ece4da;color:#95735c}.profile strong{font-size:11px;font-weight:600}.profile small{display:block;color:var(--muted);font-size:10px;margin-top:3px}.profile svg{margin-left:auto;width:15px;color:var(--muted)}main{margin-left:228px;flex:1;min-width:0}.topbar{height:78px;padding:0 40px;border-bottom:1px solid var(--line);background:var(--surface);display:flex;align-items:center;justify-content:space-between}.breadcrumbs{display:flex;gap:12px;align-items:center;font-size:12px;color:var(--muted)}.breadcrumbs strong{font-weight:500;color:var(--text)}.breadcrumbs svg{width:13px}.top-right{display:flex;align-items:center;gap:20px}.session{font-size:11px;color:var(--muted);display:flex;align-items:center;gap:6px}.session i{height:6px;width:6px;border-radius:50%;background:#64b394}.icon-button{border:0;background:none;padding:6px;display:grid;place-items:center;color:var(--muted);border-radius:6px}.icon-button:hover{background:var(--column);color:var(--text)}.content{max-width:1500px;margin:auto;padding:40px 40px 24px}.project-heading{display:flex;align-items:center;justify-content:space-between;gap:15px}.eyebrow{font-size:10px;text-transform:uppercase;letter-spacing:1.5px;font-weight:600;color:var(--purple);display:flex;gap:7px;align-items:center;margin-bottom:10px}.eyebrow span{height:6px;width:6px;background:var(--purple);border-radius:50%}h1{font-size:29px;letter-spacing:-1px;line-height:1.2;margin:0;font-weight:650}.subtitle{color:var(--muted);font-size:12px;margin:11px 0 0}.primary{border:0;background:var(--purple);color:white;border-radius:7px;padding:11px 15px;display:flex;align-items:center;justify-content:center;gap:8px;font-size:12px;font-weight:550;box-shadow:0 3px 5px #7060df15;white-space:nowrap}.primary:hover{background:#6150ce}.primary svg{width:15px;height:15px}.tabs{display:flex;gap:26px;margin-top:30px;border-bottom:1px solid var(--line);height:39px}.tab{display:flex;gap:7px;align-items:flex-start;font-size:12px;color:var(--purple);border-bottom:2px solid var(--purple);padding:0 1px 14px;font-weight:600}.tab svg{width:15px;height:15px}.tab-info{font-size:11px;color:var(--muted);margin-left:auto;padding-top:2px}.toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:24px 0 22px}.search{position:relative;width:260px}.search svg{position:absolute;left:11px;top:10px;width:16px;height:16px;color:var(--muted)}.search input{width:100%;height:37px;background:var(--input);border:1px solid var(--line);border-radius:7px;padding:0 40px 0 35px;outline:none;color:var(--text);font-size:11px}.search input:focus{border-color:var(--purple)}.search input::placeholder{color:var(--muted)}.key{position:absolute;right:10px;top:10px;font-size:10px;color:var(--muted);border:1px solid var(--line);padding:0 3px;border-radius:3px}.toolbar-right{display:flex;align-items:center;gap:18px}.team{display:flex;padding-left:5px}.team .avatar{margin-left:-5px}.avatar.green{background:#e0ece5;color:#638773}.avatar.orange{background:#f6e4d7;color:#b18561}.avatar.blue{background:#dfe8f5;color:#647da5}.team .more{background:var(--surface);color:var(--muted);border:1px solid var(--line);margin-left:4px}.filter{display:flex;align-items:center;gap:5px;color:var(--muted)}.filter svg{width:15px}.filter select{border:0;outline:none;background:transparent;color:var(--muted);font-size:11px;cursor:pointer;max-width:110px}.board{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:19px;align-items:start}.column{background:var(--column);border:1px solid transparent;border-radius:10px;min-height:438px;padding:15px 12px 12px;transition:background .15s,border-color .15s}.column.drag-over{background:var(--purple-soft);border-color:#b0a3ef}.column-header{display:flex;align-items:center;gap:8px;margin:1px 3px 16px}.status-dot{height:7px;width:7px;border-radius:50%;background:#a6adbf}.column[data-status="progress"] .status-dot{background:#b09ae6}.column[data-status="done"] .status-dot{background:#74b5a0}.column-header h2{font-size:12px;margin:0;font-weight:600}.count{font-size:10px;color:var(--muted);background:var(--surface);border:1px solid var(--line);border-radius:5px;padding:1px 5px;margin-left:1px}.column-header .icon-button{margin-left:auto;padding:0}.column-header .icon-button svg{width:16px;height:16px}.cards{min-height:15px}.card{background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow);border-radius:8px;padding:15px 14px 12px;margin-bottom:11px;cursor:grab;transition:box-shadow .15s,transform .15s}.card:hover{box-shadow:0 4px 12px #23203b0b;border-color:#d6d1e8;transform:translateY(-1px)}.card:active{cursor:grabbing}.card.dragging{opacity:.35;transform:rotate(-1deg)}.card-top{display:flex;justify-content:space-between;align-items:center;gap:5px}.category{font-size:9px;font-weight:550;border-radius:4px;padding:4px 6px;background:#f0ecfa;color:#9581bc;letter-spacing:.1px}.category.design{background:#f9ece4;color:#bd916e}.category.engineering{background:#eaf0fa;color:#7994bc}.category.marketing{background:#e8f1ec;color:#77a28b}.delete{color:#b4b5c1;padding:0;background:none;border:0;display:grid;place-items:center;width:21px;height:22px;border-radius:4px}.delete svg{width:13px;height:13px}.delete:hover{background:#fcebec;color:#d16c78}.card-title{display:block;border:0;background:none;color:var(--text);font-size:12px;font-weight:600;line-height:1.55;text-align:left;padding:0;margin:11px 0 5px;cursor:pointer}.card-description{font-size:10px;line-height:1.65;color:var(--muted);margin:0 0 13px}.priority{display:inline-flex;align-items:center;gap:4px;font-size:9px;font-weight:550;border-radius:4px;padding:3px 6px}.priority i{width:4px;height:4px;border-radius:50%;background:currentColor}.priority.high{background:#fceceb;color:#d67c79}.priority.medium{background:#fcf3df;color:#bc9a4e}.priority.low{background:#eaf3ed;color:#74a186}.card-footer{border-top:1px solid var(--line);margin-top:13px;padding-top:10px;display:flex;align-items:center;gap:10px;color:var(--muted);font-size:9px}.card-footer .meta{display:flex;align-items:center;gap:4px}.card-footer svg{width:12px;height:12px}.card-footer .avatar{margin-left:auto;width:23px;height:23px;font-size:8px;border:0}.card-id{font-size:9px;color:#afb1bd;margin-right:0}.add-card{width:100%;display:flex;align-items:center;justify-content:center;gap:6px;background:none;color:var(--muted);border:1px dashed transparent;padding:10px;border-radius:6px;font-size:11px}.add-card:hover{color:var(--purple);border-color:#c9c0ee;background:var(--surface)}.add-card svg{width:14px;height:14px}.drop-placeholder{height:74px;border:2px dashed #9f8fe4;background:#e4def9;border-radius:8px;margin-bottom:11px;display:grid;place-items:center;color:#8976c6;font-size:11px}.empty{font-size:11px;color:var(--muted);text-align:center;padding:30px 4px}.board-footer{display:flex;justify-content:space-between;color:var(--muted);font-size:10px;margin:20px 2px}.board-footer span{display:flex;gap:5px;align-items:center}.board-footer svg{width:12px;height:12px}.modal-backdrop{position:fixed;inset:0;background:#20203865;backdrop-filter:blur(4px);z-index:10;display:flex;align-items:center;justify-content:center;padding:20px}.modal-backdrop[hidden]{display:none}.modal{width:430px;background:var(--surface);border:1px solid var(--line);border-radius:15px;box-shadow:0 20px 80px #12102033;padding:26px}.modal-header{display:flex;justify-content:space-between;align-items:center}.modal h2{font-size:20px;letter-spacing:-.5px;margin:0}.modal-subtitle{font-size:12px;color:var(--muted);margin:8px 0 24px}.field{display:flex;flex-direction:column;gap:8px;margin-bottom:18px}.field label{font-size:11px;font-weight:600}.field input,.field select,.field textarea{width:100%;border:1px solid var(--line);border-radius:6px;background:var(--input);color:var(--text);padding:10px;outline:none;font-size:12px}.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--purple);box-shadow:0 0 0 3px var(--purple-soft)}.field textarea{resize:vertical;min-height:75px}.form-row{display:flex;gap:14px}.form-row .field{flex:1;min-width:0}.modal-actions{display:flex;justify-content:flex-end;gap:9px;margin-top:8px}.secondary{background:var(--surface);border:1px solid var(--line);border-radius:7px;padding:10px 15px;font-size:12px}.toast{position:fixed;bottom:25px;left:calc(50% + 80px);transform:translateX(-50%);background:var(--text);color:var(--surface);border-radius:8px;padding:12px 17px;font-size:12px;box-shadow:0 5px 30px #0002;z-index:20;display:flex;align-items:center;gap:20px}.toast[hidden]{display:none}.toast button{background:none;border:0;color:#bfb2ff;font-size:12px;font-weight:600}
body.dark{--bg:#17191f;--surface:#20232c;--column:#1c1f27;--text:#e5e5ef;--muted:#9295a8;--line:#30333f;--purple:#a28cf3;--purple-soft:#302b46;--input:#232630;--shadow:0 3px 8px #0001}body.dark .primary{background:#8067da}body.dark .switch{background:#8067da}body.dark .switch:after{transform:translateX(13px)}body.dark .category,body.dark .priority{filter:saturate(.7) brightness(.85)}body.dark .drop-placeholder{background:#342e4e}body.dark .nav-item .pill{background:#43365f}
@media(min-width:1450px){.content{padding-top:48px}.card{padding:18px}.card-title{font-size:14px}.card-description{font-size:12px}}
@media(max-width:1100px){.sidebar{width:195px;padding-left:14px;padding-right:14px}main{margin-left:195px}.content{padding:30px 25px}.topbar{padding:0 25px}.board{gap:12px}.column{padding:13px 9px}.card{padding:12px 10px}.card-footer{gap:7px}.card-id{display:none}}
@media(max-width:900px){.sidebar{width:75px;padding:30px 14px}.brand{padding:0 10px}.brand-name,.workspace,.nav-label,.nav-item span,.sidebar-project,.tip,.profile strong,.profile small,.profile svg,.theme-toggle span{display:none}.nav-item{margin-top:35px;justify-content:center;padding:12px}.theme-toggle{justify-content:center;padding:12px}.profile{justify-content:center;padding:18px 0 0}.profile .avatar{flex-shrink:0}main{margin-left:75px}.content{padding:28px 24px}.topbar{height:65px}.session{display:none}.toast{left:50%}}
@media(max-width:680px){.sidebar{display:none}main{margin-left:0}.topbar{height:56px;padding:0 20px}.content{padding:26px 18px}.top-right{gap:5px}.project-heading{align-items:center}h1{font-size:25px}.subtitle{font-size:11px;max-width:210px;line-height:1.6}.primary{padding:10px 12px;font-size:11px}.board{grid-template-columns:1fr;gap:18px}.column{min-height:150px;padding:16px 13px 9px}.card{padding:16px}.card-title{font-size:13px}.card-description{font-size:11px}.card-id{display:block}.team{display:none}.toolbar{gap:10px}.search{width:100%}.filter{flex-shrink:0}.filter select{max-width:95px}.tab-info{font-size:10px}.board-footer{font-size:9px;gap:15px;line-height:1.6}.column-header h2{font-size:13px}.card-footer{font-size:10px}.mobile-theme{display:grid!important}.modal{padding:22px}}
.mobile-theme{display:none}
</style>
</head>
<body>
<svg style="display:none" aria-hidden="true"><defs>
<symbol id="i-plus" viewBox="0 0 24 24"><path d="M12 5v14M5 12h14"/></symbol>
<symbol id="i-grid" viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></symbol>
<symbol id="i-search" viewBox="0 0 24 24"><circle cx="10.5" cy="10.5" r="6.5"/><path d="m16 16 4 4"/></symbol>
<symbol id="i-chevron" viewBox="0 0 24 24"><path d="m9 5 7 7-7 7"/></symbol>
<symbol id="i-down" viewBox="0 0 24 24"><path d="m8 10 4 4 4-4"/></symbol>
<symbol id="i-moon" viewBox="0 0 24 24"><path d="M20 14.2A8.5 8.5 0 0 1 9.8 4 8.5 8.5 0 1 0 20 14.2Z"/></symbol>
<symbol id="i-trash" viewBox="0 0 24 24"><path d="M4 6h16M9 6V3h6v3M6 6l1 15h10l1-15M10 10v7M14 10v7"/></symbol>
<symbol id="i-calendar" viewBox="0 0 24 24"><rect x="4" y="5" width="16" height="16" rx="2"/><path d="M8 3v4M16 3v4M4 11h16"/></symbol>
<symbol id="i-comment" viewBox="0 0 24 24"><path d="M20 15a3 3 0 0 1-3 3H9l-5 3V6a3 3 0 0 1 3-3h10a3 3 0 0 1 3 3Z"/></symbol>
<symbol id="i-filter" viewBox="0 0 24 24"><path d="M4 7h16M7 12h10M10 17h4"/></symbol>
<symbol id="i-close" viewBox="0 0 24 24"><path d="m6 6 12 12M18 6 6 18"/></symbol>
<symbol id="i-check" viewBox="0 0 24 24"><path d="m5 12 4 4L19 6"/></symbol>
<symbol id="i-drag" viewBox="0 0 24 24"><path d="M8 5h.01M16 5h.01M8 12h.01M16 12h.01M8 19h.01M16 19h.01" stroke-width="3"/></symbol>
<symbol id="i-spark" viewBox="0 0 24 24"><path d="m12 3 2.5 6.5L21 12l-6.5 2.5L12 21l-2.5-6.5L3 12l6.5-2.5Z"/></symbol>
</defs></svg>
<div class="app">
<aside class="sidebar">
<div class="brand"><div class="brand-mark"><i></i><i></i><i></i><i></i></div><span class="brand-name">forma<span style="color:var(--purple)">.</span></span></div>
<div class="workspace"><div class="workspace-icon">S</div><div>Studio workspace<small>Personal workspace</small></div><svg><use href="#i-down"/></svg></div>
<div class="nav-label">WORKSPACE</div>
<div class="nav-item active"><svg><use href="#i-grid"/></svg><span>My boards</span><span class="pill">1</span></div>
<div class="sidebar-project"><div class="nav-label">YOUR PROJECTS</div><div class="project-link" style="color:var(--text)"><span class="project-dot"></span>Product launch</div><div class="project-link"><span class="project-dot" style="background:#8fb7a6"></span>Website refresh</div><div class="project-link"><span class="project-dot" style="background:#dab996"></span>Brand exploration</div></div>
<div class="sidebar-bottom">
<div class="tip"><div class="small-title"><svg style="width:14px;color:var(--purple)"><use href="#i-spark"/></svg>A little less busy.</div><p>Make room for your best work.<br>One card at a time.</p></div>
<button class="theme-toggle" id="themeToggle" aria-label="Switch to dark theme"><svg><use href="#i-moon"/></svg><span id="themeLabel">Dark mode</span><span class="switch"></span></button>
<div class="profile"><span class="avatar">JD</span><div><strong>Jamie Davis</strong><small>Personal account</small></div><svg><use href="#i-down"/></svg></div>
</div>
</aside>
<main>
<header class="topbar"><div class="breadcrumbs"><svg><use href="#i-grid"/></svg><span>My boards</span><svg><use href="#i-chevron"/></svg><strong>Product launch</strong></div><div class="top-right"><span class="session"><i></i>Session up to date</span><button class="icon-button mobile-theme" id="mobileTheme" aria-label="Toggle light or dark theme"><svg><use href="#i-moon"/></svg></button><span class="avatar" style="background:#ece4da;color:#95735c">JD</span></div></header>
<div class="content">
<div class="project-heading"><div><div class="eyebrow"><span></span>Let's make it happen</div><h1>Product launch</h1><p class="subtitle">Big ideas, small steps. Keep the good work moving.</p></div><button class="primary" id="newCard"><svg><use href="#i-plus"/></svg>New card</button></div>
<div class="tabs"><div class="tab"><svg><use href="#i-grid"/></svg>Board</div><span class="tab-info">Sprint 08 <span style="margin:0 7px;color:#c8cad3">/</span> May 12 – 23</span></div>
<div class="toolbar"><div class="search"><svg><use href="#i-search"/></svg><input id="search" type="search" placeholder="Search cards..." aria-label="Search cards by title"><span class="key">/</span></div><div class="toolbar-right"><div class="team" aria-label="Project team"><span class="avatar orange">JD</span><span class="avatar">AL</span><span class="avatar green">MK</span><span class="avatar more">+1</span></div><div class="filter"><svg><use href="#i-filter"/></svg><select id="priorityFilter" aria-label="Filter by priority"><option value="all">All priorities</option><option value="high">High priority</option><option value="medium">Medium priority</option><option value="low">Low priority</option></select></div></div></div>
<div class="board" id="board"></div>
<div class="board-footer"><span><svg><use href="#i-drag"/></svg>Drag cards to move your work forward</span><span>Made for focus. Stored for this session only.</span></div>
</div>
</main>
</div>
<div class="modal-backdrop" id="modal" hidden>
<form class="modal" id="cardForm" aria-labelledby="modalTitle" role="dialog" aria-modal="true">
<div class="modal-header"><h2 id="modalTitle">A fresh idea.</h2><button type="button" class="icon-button" id="closeModal" aria-label="Close dialog"><svg><use href="#i-close"/></svg></button></div>
<p class="modal-subtitle">Every great project starts with a small step.</p>
<div class="field"><label for="cardTitle">Card title <span style="color:var(--purple)">*</span></label><input id="cardTitle" required maxlength="120" placeholder="What needs to get done?" autocomplete="off"></div>
<div class="field"><label for="cardDescription">Description <span style="color:var(--muted);font-weight:400">(optional)</span></label><textarea id="cardDescription" maxlength="300" placeholder="Add a little context..."></textarea></div>
<div class="form-row"><div class="field"><label for="cardStatus">Column</label><select id="cardStatus"><option value="todo">To do</option><option value="progress">In progress</option><option value="done">Done</option></select></div><div class="field"><label for="cardPriority">Priority</label><select id="cardPriority"><option value="low">Low</option><option value="medium" selected>Medium</option><option value="high">High</option></select></div></div>
<div class="modal-actions"><button type="button" class="secondary" id="cancelModal">Cancel</button><button type="submit" class="primary" id="saveCard"><svg><use href="#i-plus"/></svg>Create card</button></div>
</form>
</div>
<div class="toast" id="toast" role="status" hidden><span id="toastText"></span><button id="undoDelete" hidden>Undo</button></div>
<script>
const icon=name=>`<svg aria-hidden="true"><use href="#i-${name}"/></svg>`;
const columns=[{id:'todo',name:'To do'},{id:'progress',name:'In progress'},{id:'done',name:'Done'}];
let cards=[
{id:101,title:'Map out the onboarding flow',description:'Make the first five minutes feel effortless.',priority:'high',status:'todo',category:'Design',person:'AL',color:'',date:'May 16',comments:3},
{id:102,title:'Write the launch announcement',description:'A little story about what we’ve been building.',priority:'medium',status:'todo',category:'Marketing',person:'MK',color:'green',date:'May 19',comments:2},
{id:103,title:'Review mobile breakpoints',description:'Give every screen size a little love.',priority:'low',status:'todo',category:'Engineering',person:'JD',color:'orange',date:'May 20',comments:0},
{id:104,title:'Build the component library',description:'Reusable pieces. A more consistent experience.',priority:'high',status:'progress',category:'Engineering',person:'JD',color:'orange',date:'May 15',comments:5},
{id:105,title:'Design the landing page',description:'Turn a first impression into a lasting one.',priority:'medium',status:'progress',category:'Design',person:'AL',color:'',date:'May 16',comments:4},
{id:106,title:'Define the launch checklist',description:'The plan is in place. Let’s bring it to life.',priority:'low',status:'done',category:'Planning',person:'SR',color:'blue',date:'May 12',comments:2}
];
let nextId=107,editing=null,dragId=null,deleted=null,toastTimer,lastFocus;
const $=id=>document.getElementById(id);
const escapeHTML=s=>String(s).replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
function render(){
const query=$('search').value.toLowerCase().trim(),priority=$('priorityFilter').value;
$('board').innerHTML=columns.map(col=>{
const visible=cards.filter(c=>c.status===col.id&&c.title.toLowerCase().includes(query)&&(priority==='all'||c.priority===priority));
return `<section class="column" data-status="${col.id}" aria-label="${col.name}"><div class="column-header"><span class="status-dot"></span><h2>${col.name}</h2><span class="count">${visible.length}</span><button class="icon-button" data-add="${col.id}" aria-label="Add card to ${col.name}">${icon('plus')}</button></div><div class="cards">${visible.map(cardHTML).join('')}${!visible.length&&(query||priority!=='all')?'<div class="empty">No matching cards</div>':''}</div><button class="add-card" data-add="${col.id}">${icon('plus')}Add card</button></section>`;
}).join('');
}
function cardHTML(c){
return `<article class="card" draggable="true" data-id="${c.id}" aria-label="${escapeHTML(c.title)}, ${c.priority} priority"><div class="card-top"><span class="category ${c.category.toLowerCase()}">${escapeHTML(c.category)}</span><button class="delete" data-delete="${c.id}" aria-label="Delete ${escapeHTML(c.title)}" title="Delete card">${icon('trash')}</button></div><button class="card-title" data-edit="${c.id}" title="Edit card">${escapeHTML(c.title)}</button>${c.description?`<p class="card-description">${escapeHTML(c.description)}</p>`:''}<span class="priority ${c.priority}"><i></i>${c.priority[0].toUpperCase()+c.priority.slice(1)}</span><div class="card-footer"><span class="meta">${icon(c.status==='done'?'check':'calendar')}${c.date||'No due date'}</span>${c.comments?`<span class="meta">${icon('comment')}${c.comments}</span>`:''}<span class="avatar ${c.color}">${c.person}</span><span class="card-id">PRJ-${c.id-77}</span></div></article>`;
}
function openModal(status='todo',card=null){
lastFocus=document.activeElement;editing=card?card.id:null;
$('cardForm').reset();$('cardTitle').setCustomValidity('');
$('cardTitle').value=card?card.title:'';$('cardDescription').value=card?card.description:'';
$('cardStatus').value=card?card.status:status;$('cardPriority').value=card?card.priority:'medium';
$('modalTitle').textContent=card?'Make it your own.':'A fresh idea.';
$('saveCard').innerHTML=icon(card?'check':'plus')+(card?'Save changes':'Create card');
$('modal').hidden=false;setTimeout(()=>$('cardTitle').focus(),30);
}
function closeModal(){$('modal').hidden=true;if(lastFocus&&document.contains(lastFocus))lastFocus.focus();}
function toast(text,undo=false){clearTimeout(toastTimer);$('toastText').textContent=text;$('undoDelete').hidden=!undo;$('toast').hidden=false;toastTimer=setTimeout(()=>$('toast').hidden=true,5000);}
$('newCard').onclick=()=>openModal();
$('closeModal').onclick=closeModal;$('cancelModal').onclick=closeModal;
$('modal').onclick=e=>{if(e.target===$('modal'))closeModal();};
$('cardTitle').oninput=()=>$('cardTitle').setCustomValidity('');
$('cardForm').onsubmit=e=>{
e.preventDefault();const title=$('cardTitle').value.trim();
if(!title){$('cardTitle').setCustomValidity('Please give your card a title.');$('cardTitle').reportValidity();return;}
const data={title,description:$('cardDescription').value.trim(),status:$('cardStatus').value,priority:$('cardPriority').value};
if(editing){Object.assign(cards.find(c=>c.id===editing),data);}else{cards.push({id:nextId++,...data,category:'Planning',person:'JD',color:'orange',date:'',comments:0});}
render();closeModal();toast(editing?'Card updated. Looking good.':'Your next step is on the board.');
};
$('board').onclick=e=>{
const add=e.target.closest('[data-add]'),del=e.target.closest('[data-delete]'),edit=e.target.closest('[data-edit]');
if(add)openModal(add.dataset.add);
if(edit)openModal('todo',cards.find(c=>c.id===+edit.dataset.edit));
if(del){const index=cards.findIndex(c=>c.id===+del.dataset.delete);deleted={card:cards[index],index};cards.splice(index,1);render();toast('Card removed.',true);}
};
$('undoDelete').onclick=()=>{if(deleted){cards.splice(deleted.index,0,deleted.card);deleted=null;render();$('toast').hidden=true;}};
$('search').oninput=render;$('priorityFilter').onchange=render;
function toggleTheme(){const dark=document.body.classList.toggle('dark');$('themeLabel').textContent=dark?'Light mode':'Dark mode';$('themeToggle').setAttribute('aria-label',dark?'Switch to light theme':'Switch to dark theme');}
$('themeToggle').onclick=toggleTheme;$('mobileTheme').onclick=toggleTheme;
document.addEventListener('keydown',e=>{
if(e.key==='Escape')closeModal();
if(e.key==='/'&&$('modal').hidden&&!['INPUT','TEXTAREA','SELECT'].includes(document.activeElement.tagName)){e.preventDefault();$('search').focus();}
if(e.key==='Tab'&&!$('modal').hidden){const focusable=[...$('cardForm').querySelectorAll('button,input,textarea,select')];let first=focusable[0],last=focusable[focusable.length-1];if(e.shiftKey&&document.activeElement===first){e.preventDefault();last.focus();}else if(!e.shiftKey&&document.activeElement===last){e.preventDefault();first.focus();}}
});
const placeholder=document.createElement('div');placeholder.className='drop-placeholder';placeholder.textContent='Drop card here';
function cleanDrag(){placeholder.remove();document.querySelectorAll('.drag-over,.dragging').forEach(el=>el.classList.remove('drag-over','dragging'));dragId=null;}
$('board').addEventListener('dragstart',e=>{const card=e.target.closest('.card');if(!card)return;dragId=+card.dataset.id;e.dataTransfer.effectAllowed='move';e.dataTransfer.setData('text/plain',String(dragId));requestAnimationFrame(()=>card.classList.add('dragging'));});
$('board').addEventListener('dragover',e=>{
if(dragId===null)return;const column=e.target.closest('.column');if(!column)return;e.preventDefault();e.dataTransfer.dropEffect='move';
document.querySelectorAll('.column').forEach(c=>c.classList.toggle('drag-over',c===column));
const list=column.querySelector('.cards');const before=[...list.querySelectorAll('.card:not(.dragging)')].find(card=>e.clientY<card.getBoundingClientRect().top+card.offsetHeight/2);
list.insertBefore(placeholder,before||null);
});
$('board').addEventListener('drop',e=>{
const column=e.target.closest('.column');if(!column||dragId===null)return;e.preventDefault();
const card=cards.find(c=>c.id===dragId);if(!card){cleanDrag();return;}
let sibling=placeholder.nextElementSibling;while(sibling&&!sibling.matches('.card'))sibling=sibling.nextElementSibling;
cards=cards.filter(c=>c.id!==dragId);card.status=column.dataset.status;
if(sibling){const index=cards.findIndex(c=>c.id===+sibling.dataset.id);cards.splice(index<0?cards.length:index,0,card);}else cards.push(card);
cleanDrag();render();
});
$('board').addEventListener('dragend',cleanDrag);
render();
</script>
</body>
</html>Reasoning trace (417 tokens)
**Planning board layout** I need to deliver a polished board without external input. I'm thinking of an off-white and lavender modern "Forma/workspace" design, with a sidebar that could be either on top or the left side, maintaining thoughtful visual quality. The header will feature a purple grid logo, and the main section will have a breadcrumb with a title and description for "Product launch." There will be draggable cards for tasks, along with options for filtering and managing task priorities. I'll ensure everything is functional and user-friendly!**Designing a responsive board** I’m outlining a theme for a button sidebar that will be responsive, hiding under 900 pixels. The board should avoid scrollbars, stacking at 680 pixels. I’ll ensure a tall main board that displays six cards, arranged for variety. We'll label it "Sprint 08" and include a footer that syncs memory with a note on saved changes. Each column will feature an "add" button, and I’ll ensure sorting options are clear without unnecessary clutter. The sidebar will also include a light/dark icon and support robust modals for actions.**Managing drag events** I need to avoid rendering issues during drag events while ensuring a placeholder appears. When cards are dropped, I should splice and reorder them globally based on their list positions. I’ll maintain an initial cards array that’s grouped for better organization and keep track of counts as necessary. If there are search results, I’ll ensure the modal style is user-friendly. Overall, I’m aiming for an output that is both manageable and visually appealing!