Models 44

GPT-6 Luna

by OpenAIReasoningClean
Open in new window

Running live in a sandboxed frame. Click inside it before using the keyboard.

How it went

Total time
37.4 s
Cost
$0.0030
Output tokens
5,810
Spent thinking
0 tokens
Speed
162.8 tok/s
Console errors
0
First token after
1.7 s
First visible text after
1.7 s
Prompt tokens
493
Code size
18.3 KB
Finish reason
stop
Served by
OpenAI
Model id
openai/gpt-6-luna
Reasoning sent
{"effort":"none"}
Max output
64,000 tokens
Generated
Nov 10, 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 · 395 lines

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kanban — Project workspace</title>
<style>
  :root {
    color-scheme: light;
    --bg: #f5f6f8;
    --surface: #fff;
    --surface-2: #fafbfc;
    --text: #20232b;
    --muted: #818796;
    --line: #e8eaf0;
    --accent: #6758e8;
    --accent-soft: #efedff;
    --shadow: 0 10px 30px rgba(28, 31, 48, .07);
    --high: #e45b63;
    --medium: #d58b21;
    --low: #359875;
  }
  body.dark {
    color-scheme: dark;
    --bg: #171922;
    --surface: #20232e;
    --surface-2: #252936;
    --text: #eef0f7;
    --muted: #9a9fb0;
    --line: #343847;
    --accent: #9c91ff;
    --accent-soft: #35304f;
    --shadow: 0 10px 30px rgba(0, 0, 0, .24);
    --high: #ff858b;
    --medium: #f3ba63;
    --low: #6dd2aa;
  }
  * { box-sizing: border-box; }
  body {
    margin: 0;
    min-height: 100vh;
    background: var(--bg);
    color: var(--text);
    font: 14px/1.45 Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    transition: background .2s, color .2s;
  }
  button, input, select { font: inherit; }
  button { color: inherit; }
  .app { max-width: 1220px; margin: auto; padding: 0 40px 42px; }
  header {
    height: 78px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-bottom: 1px solid var(--line);
  }
  .brand { display: flex; align-items: center; gap: 11px; font-size: 15px; font-weight: 750; letter-spacing: -.3px; }
  .brand-mark {
    width: 31px; height: 31px; border-radius: 10px; display: grid; place-items: center;
    color: white; background: var(--accent); font-weight: 800; font-size: 17px;
    box-shadow: 0 5px 12px color-mix(in srgb, var(--accent), transparent 70%);
  }
  .header-actions { display: flex; align-items: center; gap: 11px; }
  .icon-btn, .secondary-btn, .primary-btn {
    border: 1px solid var(--line); background: var(--surface); cursor: pointer; transition: .16s ease;
  }
  .icon-btn {
    width: 38px; height: 38px; border-radius: 11px; display: grid; place-items: center;
    color: var(--muted);
  }
  .icon-btn:hover, .secondary-btn:hover { border-color: var(--accent); color: var(--accent); }
  .primary-btn {
    border: 0; background: var(--accent); color: white; font-weight: 650;
    height: 39px; padding: 0 15px; border-radius: 10px; box-shadow: 0 5px 12px color-mix(in srgb, var(--accent), transparent 80%);
  }
  .primary-btn:hover { filter: brightness(1.07); transform: translateY(-1px); }
  .plus { font-size: 19px; vertical-align: -1px; margin-right: 5px; }
  main { padding-top: 34px; }
  .topline { display: flex; justify-content: space-between; align-items: flex-end; gap: 20px; }
  h1 { margin: 0; font-size: 27px; letter-spacing: -.8px; line-height: 1.2; }
  .subtitle { margin-top: 7px; color: var(--muted); font-size: 13px; }
  .toolbar { display: flex; align-items: center; gap: 10px; }
  .search { position: relative; }
  .search svg { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--muted); }
  .search input {
    width: 220px; height: 39px; padding: 0 12px 0 37px; border: 1px solid var(--line);
    border-radius: 10px; outline: none; color: var(--text); background: var(--surface);
  }
  .search input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent), transparent 87%); }
  .board { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 19px; margin-top: 29px; align-items: start; }
  .column {
    padding: 14px; background: color-mix(in srgb, var(--surface-2), transparent 12%);
    border: 1px solid var(--line); border-radius: 14px; min-height: 425px;
    transition: border-color .18s, background .18s, box-shadow .18s;
  }
  .column.drop-target {
    border-color: var(--accent); background: color-mix(in srgb, var(--accent-soft), var(--surface) 35%);
    box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--accent), transparent 78%);
  }
  .column-head { height: 34px; display: flex; justify-content: space-between; align-items: center; margin: 0 1px 12px; }
  .column-name { display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: 13px; letter-spacing: .05px; }
  .dot { width: 8px; height: 8px; border-radius: 50%; background: #8d92a1; }
  .todo .dot { background: #a0a5b3; }
  .progress .dot { background: #7063e8; }
  .done .dot { background: #3bb187; }
  .count { min-width: 23px; height: 22px; padding: 0 6px; display: grid; place-items: center; border-radius: 7px; background: var(--surface); color: var(--muted); font-size: 11px; font-weight: 700; border: 1px solid var(--line); }
  .cards { min-height: 350px; }
  .card {
    background: var(--surface); border: 1px solid var(--line); border-radius: 11px; padding: 14px;
    margin-bottom: 10px; box-shadow: 0 2px 5px rgba(22, 27, 45, .025); cursor: grab;
    transition: transform .15s, border-color .15s, box-shadow .15s, opacity .15s;
  }
  .card:hover { transform: translateY(-2px); box-shadow: var(--shadow); border-color: color-mix(in srgb, var(--accent), var(--line) 58%); }
  .card.dragging { opacity: .38; transform: rotate(-1deg); }
  .card-title { margin: 0 0 14px; font-size: 13px; line-height: 1.5; font-weight: 650; letter-spacing: -.12px; padding-right: 5px; }
  .card-bottom { display: flex; justify-content: space-between; align-items: center; }
  .badge { border-radius: 6px; padding: 3px 8px; font-size: 10px; font-weight: 700; letter-spacing: .15px; text-transform: capitalize; }
  .badge.high { color: var(--high); background: color-mix(in srgb, var(--high), transparent 89%); }
  .badge.medium { color: var(--medium); background: color-mix(in srgb, var(--medium), transparent 88%); }
  .badge.low { color: var(--low); background: color-mix(in srgb, var(--low), transparent 88%); }
  .card-actions { display: flex; align-items: center; gap: 8px; }
  .avatar {
    display: grid; place-items: center; width: 23px; height: 23px; border-radius: 50%;
    color: #6458b9; background: #eeecff; font-size: 9px; font-weight: 750;
  }
  body.dark .avatar { background: #393454; color: #c2baff; }
  .delete-btn {
    border: 0; padding: 3px; line-height: 0; color: #a5a9b4; background: transparent;
    cursor: pointer; opacity: 0; transition: .15s;
  }
  .card:hover .delete-btn, .delete-btn:focus { opacity: 1; }
  .delete-btn:hover { color: var(--high); }
  .empty {
    color: var(--muted); font-size: 12px; text-align: center; padding: 28px 8px;
    border: 1px dashed var(--line); border-radius: 9px; margin-top: 4px;
  }
  .board-note { display: flex; align-items: center; gap: 7px; margin-top: 17px; color: var(--muted); font-size: 11px; }
  .board-note svg { color: var(--accent); }
  .modal-backdrop {
    display: none; position: fixed; inset: 0; z-index: 5; background: rgba(14, 17, 28, .44);
    align-items: center; justify-content: center; padding: 18px;
  }
  .modal-backdrop.open { display: flex; }
  .modal {
    width: min(100%, 420px); background: var(--surface); border: 1px solid var(--line);
    border-radius: 16px; padding: 23px; box-shadow: 0 24px 70px rgba(0,0,0,.22);
    animation: rise .18s ease-out;
  }
  @keyframes rise { from { opacity: 0; transform: translateY(8px) scale(.98); } to { opacity: 1; transform: none; } }
  .modal-top { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 20px; }
  .modal h2 { margin: 0; font-size: 19px; letter-spacing: -.4px; }
  .modal-copy { margin-top: 5px; color: var(--muted); font-size: 12px; }
  .close-btn { border: 0; background: transparent; color: var(--muted); padding: 3px; cursor: pointer; font-size: 20px; line-height: 1; }
  label { display: block; margin-bottom: 7px; font-size: 12px; font-weight: 650; }
  .field { margin-bottom: 17px; }
  .field input, .field select {
    width: 100%; height: 41px; border: 1px solid var(--line); border-radius: 9px;
    background: var(--surface-2); color: var(--text); padding: 0 11px; outline: none;
  }
  .field input:focus, .field select:focus { border-color: var(--accent); }
  .modal-footer { display: flex; justify-content: flex-end; gap: 8px; margin-top: 21px; }
  .secondary-btn { height: 38px; border-radius: 9px; padding: 0 13px; font-weight: 600; }
  .modal .primary-btn { height: 38px; }
  @media (max-width: 760px) {
    .app { padding: 0 20px 30px; }
    .board { gap: 12px; }
    .column { padding: 10px; }
    .card { padding: 11px; }
    .search input { width: 190px; }
  }
  @media (max-width: 560px) {
    header { height: 66px; }
    .app { padding: 0 15px 26px; }
    .brand { font-size: 14px; }
    .header-actions { gap: 7px; }
    .primary-btn { padding: 0 11px; }
    main { padding-top: 25px; }
    .topline { align-items: flex-start; flex-direction: column; gap: 16px; }
    h1 { font-size: 24px; }
    .toolbar { width: 100%; }
    .search { flex: 1; }
    .search input { width: 100%; }
    .board { grid-template-columns: 1fr; margin-top: 20px; gap: 12px; }
    .column { min-height: 0; padding: 12px; }
    .cards { min-height: 30px; }
    .card { padding: 13px; }
    .delete-btn { opacity: .7; }
    .board-note { margin-top: 13px; }
  }
  @media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; } }
</style>
</head>
<body>
<div class="app">
  <header>
    <div class="brand"><span class="brand-mark">K</span> Orbit workspace</div>
    <div class="header-actions">
      <button class="icon-btn" id="themeToggle" aria-label="Toggle light or dark theme" title="Toggle theme">
        <svg id="themeIcon" width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2m0 16v2M4.93 4.93l1.42 1.42m11.3 11.3 1.42 1.42M2 12h2m16 0h2M4.93 19.07l1.42-1.42m11.3-11.3 1.42-1.42"/></svg>
      </button>
      <button class="primary-btn" id="openModal"><span class="plus">+</span>Add card</button>
    </div>
  </header>
  <main>
    <div class="topline">
      <div>
        <h1>Project board</h1>
        <div class="subtitle">Plan, track, and move work forward.</div>
      </div>
      <div class="toolbar">
        <div class="search">
          <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="11" cy="11" r="7"/><path d="m20 20-4-4"/></svg>
          <input id="searchInput" type="search" placeholder="Search cards..." aria-label="Search cards">
        </div>
      </div>
    </div>
    <section class="board" aria-label="Kanban board">
      <div class="column todo" data-status="todo">
        <div class="column-head"><div class="column-name"><span class="dot"></span>To do</div><span class="count">0</span></div>
        <div class="cards"></div>
      </div>
      <div class="column progress" data-status="progress">
        <div class="column-head"><div class="column-name"><span class="dot"></span>In progress</div><span class="count">0</span></div>
        <div class="cards"></div>
      </div>
      <div class="column done" data-status="done">
        <div class="column-head"><div class="dot"></span>Done</div><span class="count">0</span></div>
        <div class="cards"></div>
      </div>
    </section>
    <div class="board-note">
      <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v12m0 0 4-4m-4 4-4-4"/><path d="M5 17v3h14v-3"/></svg>
      Drag cards between columns to update their status
    </div>
  </main>
</div>

<div class="modal-backdrop" id="modalBackdrop" role="dialog" aria-modal="true" aria-labelledby="modalTitle">
  <form class="modal" id="cardForm">
    <div class="modal-top">
      <div><h2 id="modalTitle">Add a card</h2><div class="modal-copy">Add a task to your project board.</div></div>
      <button type="button" class="close-btn" id="closeModal" aria-label="Close">×</button>
    </div>
    <div class="field">
      <label for="cardTitle">Title</label>
      <input id="cardTitle" maxlength="100" placeholder="What needs to get done?" required>
    </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 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="modal-footer">
      <button type="button" class="secondary-btn" id="cancelModal">Cancel</button>
      <button type="submit" class="primary-btn">Create card</button>
    </div>
  </form>
</div>

<script>
(() => {
  let cards = [
    { id: 1, title: "Review Q3 product roadmap", priority: "high", status: "todo", initials: "AM" },
    { id: 2, title: "Gather customer feedback for onboarding", priority: "medium", status: "todo", initials: "JL" },
    { id: 3, title: "Prepare launch announcement copy", priority: "low", status: "todo", initials: "SK" },
    { id: 4, title: "Build analytics dashboard wireframes", priority: "high", status: "progress", initials: "AM" },
    { id: 5, title: "Update API documentation", priority: "medium", status: "progress", initials: "JL" },
    { id: 6, title: "Set up team project workspace", priority: "low", status: "done", initials: "SK" }
  ];
  const board = document.querySelector(".board");
  const searchInput = document.getElementById("searchInput");
  const backdrop = document.getElementById("modalBackdrop");
  const form = document.getElementById("cardForm");
  const titleInput = document.getElementById("cardTitle");
  let draggedId = null;
  let nextId = 7;

  function render() {
    const query = searchInput.value.trim().toLowerCase();
    document.querySelectorAll(".column").forEach(column => {
      const status = column.dataset.status;
      const list = column.querySelector(".cards");
      const matching = cards.filter(card => card.status === status && card.title.toLowerCase().includes(query));
      column.querySelector(".count").textContent = cards.filter(card => card.status === status).length;
      list.innerHTML = "";
      if (!matching.length && query) {
        const empty = document.createElement("div");
        empty.className = "empty";
        empty.textContent = "No matching cards";
        list.appendChild(empty);
      }
      matching.forEach(card => {
        const item = document.createElement("article");
        item.className = "card";
        item.draggable = true;
        item.dataset.id = card.id;
        item.innerHTML = `<p class="card-title"></p>
          <div class="card-bottom">
            <span class="badge ${card.priority}">${card.priority}</span>
            <div class="card-actions"><span class="avatar" aria-label="Assignee">${card.initials || "ME"}</span>
            <button class="delete-btn" aria-label="Delete card" title="Delete card">
              <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18M8 6V4h8v2m3 0-.8 14H5.8L5 6m4 4v6m6-6v6"/></svg>
            </button></div>
          </div>`;
        item.querySelector(".card-title").textContent = card.title;
        list.appendChild(item);
      });
    });
  }

  board.addEventListener("click", event => {
    const button = event.target.closest(".delete-btn");
    if (!button) return;
    const card = button.closest(".card");
    cards = cards.filter(item => item.id !== Number(card.dataset.id));
    render();
  });

  board.addEventListener("dragstart", event => {
    const card = event.target.closest(".card");
    if (!card) return;
    draggedId = Number(card.dataset.id);
    card.classList.add("dragging");
    event.dataTransfer.effectAllowed = "move";
    event.dataTransfer.setData("text/plain", String(draggedId));
  });
  board.addEventListener("dragend", event => {
    const card = event.target.closest(".card");
    if (card) card.classList.remove("dragging");
    document.querySelectorAll(".drop-target").forEach(el => el.classList.remove("drop-target"));
    draggedId = null;
  });
  document.querySelectorAll(".column").forEach(column => {
    column.addEventListener("dragover", event => {
      event.preventDefault();
      event.dataTransfer.dropEffect = "move";
      column.classList.add("drop-target");
    });
    column.addEventListener("dragleave", event => {
      if (!column.contains(event.relatedTarget)) column.classList.remove("drop-target");
    });
    column.addEventListener("drop", event => {
      event.preventDefault();
      column.classList.remove("drop-target");
      const id = Number(event.dataTransfer.getData("text/plain")) || draggedId;
      const card = cards.find(item => item.id === id);
      if (card) { card.status = column.dataset.status; render(); }
    });
  });
  searchInput.addEventListener("input", render);

  const openModal = () => {
    backdrop.classList.add("open");
    titleInput.focus();
  };
  const closeModal = () => {
    backdrop.classList.remove("open");
    form.reset();
  };
  document.getElementById("openModal").addEventListener("click", openModal);
  document.getElementById("closeModal").addEventListener("click", closeModal);
  document.getElementById("cancelModal").addEventListener("click", closeModal);
  backdrop.addEventListener("click", event => { if (event.target === backdrop) closeModal(); });
  document.addEventListener("keydown", event => { if (event.key === "Escape") closeModal(); });
  form.addEventListener("submit", event => {
    event.preventDefault();
    const title = titleInput.value.trim();
    if (!title) { titleInput.focus(); return; }
    cards.push({
      id: nextId++,
      title,
      priority: document.getElementById("cardPriority").value,
      status: document.getElementById("cardStatus").value,
      initials: "ME"
    });
    render();
    closeModal();
  });

  const themeToggle = document.getElementById("themeToggle");
  themeToggle.addEventListener("click", () => {
    const dark = document.body.classList.toggle("dark");
    document.getElementById("themeIcon").innerHTML = dark
      ? '<path d="M20.4 15.2A8.5 8.5 0 0 1 8.8 3.6 8.6 8.6 0 1 0 20.4 15.2Z"/>'
      : '<circle cx="12" cy="12" r="4"/><path d="M12 2v2m0 16v2M4.93 4.93l1.42 1.42m11.3 11.3 1.42 1.42M2 12h2m16 0h2M4.93 19.07l1.42-1.42m11.3-11.3 1.42-1.42"/>';
  });

  render();
})();
</script>
</body>
</html>