Qwen3.8-27B-Instruct

M4 Max 128 GB · llama.cpp llama-swap (version not exposed) · every run of this model · uwu · 2026-11-05

Race this run

Race it: run Qwen3.8-27B-Instruct on your computer and see the two side by side.

Score
2,184 Silver
Tasks passed
41/44
Points
57/64Harder tasks count 3
Tokens
76,72220,736 read, 55,986 written, as the runner counted them
Speed
24.5 tok/sAs the runner measured it; the site cannot check this.
Writing speed
24.5 tok/sPrompt reading left out. As the runner measured it; the site cannot check this.

tok/s is tokens a second: how fast the model writes. A token is about three quarters of a word. How the score works.

This setup, checked

No other runs of Qwen3.8-27B-Instruct on M4 Max 128 GB yet; the next one will be compared with this one.

Qwen3.8-27B-Instruct on M4 Max 128 GB: 41 of 44 tasks in 77k tokens at 24.5 tok/s, a Silver score of 2,184, in the resyn benchmark. https://resyn.cloud/suite/a3d56980857b36cb37dde1600d48a891Compare another runComment

Not on the leaderboard: it was posted under an earlier version of the task suite. Leaderboard

Run details
Model file
Not a listed file
Where it ran
Other
How
Run through the model's API, by OpenCode (resyn-bench 2)
Model the API reported
Qwen3.8-27B-UD-Q8_K_XL
Time
39 min 10 s
Settings
seed=42, temperature=0, top_p=1
Suite
resyn-tasks@5
Flag this run

Hides the run from public pages until an admin checks it.

Failed 3

  • A bar chart in SVGThe bars are not labelled Mon to Fri

    4,309 tokens: 142 read, 4,167 written · 2 min 51 s · 24.5 tok/s

    Passes when Five <rect class="bar"> in an <svg>, written in the markup, with heights proportional to 12, 30, 18, 24 and 6 in that order, labelled Mon to Fri in <text>, and a <title> or aria-label. Nothing loaded from another site and no network requests.

    Draw an inline SVG bar chart of coffee sold: Mon 12, Tue 30, Wed 18, Thu 24, Fri 6. Each bar is a <rect class="bar"> whose height attribute is proportional to its value, each bar is labelled with its day in a <text>, and the <svg> has a <title> or an aria-label. Write the bars and labels directly in the SVG markup, not with JavaScript. Output one complete HTML document and nothing else. Put all CSS and JavaScript inline. Do not load anything from another site: no external scripts, stylesheets, fonts or images.

    Open the page on its own. It runs in a sandbox: no network, no access to this site.

    Page source
    Here's a self-contained page that opens on the chart itself, with each `<rect class="bar">` written directly in the markup at a height proportional to its value (scale 10 px per cup), day labels beneath, and an accessible title plus `role="img"`/`aria-label`.
    
    ```html
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Coffee Counter · Week in Cups</title>
    <style>
      :root{
        --bg:#160f0a;
        --ink:#f5e7d3;
        --muted:#b49878;
        --line:rgba(245,231,211,.12);
        --gold:#ffc861;
      }
    
      *{ box-sizing:border-box; margin:0; padding:0; }
    
      html,body{ height:100%; }
    
      body{
        min-height:100vh;
        font-family:"Avenir Next","Segoe UI",system-ui,-apple-system,sans-serif;
        color:var(--ink);
        background:
          radial-gradient(120% 90% at 50% -12%, rgba(255,184,92,.16), transparent 55%),
          radial-gradient(90% 70% at 88% 112%, rgba(150,90,50,.22), transparent 60%),
          linear-gradient(180deg,#1c130d 0%, #140d08 60%, #0f0a06 100%);
        display:flex;
        flex-direction:column;
        align-items:center;
        padding:clamp(24px,5vh,56px) 20px;
        position:relative;
        overflow-x:hidden;
      }
    
      /* faint paper grain */
      body::before{
        content:"";
        position:fixed; inset:0; pointer-events:none; z-index:0;
        background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
        mix-blend-mode:overlay;
      }
    
      .wrap{ position:relative; z-index:1; width:min(780px,100%); display:flex; flex-direction:column; gap:clamp(20px,3.5vh,34px); }
    
      /* ---------- masthead ---------- */
      .masthead{
        display:flex; justify-content:space-between; align-items:flex-end; gap:24px;
        border-bottom:1px solid var(--line); padding-bottom:clamp(16px,3vh,26px);
      }
      .kicker{
        font-size:.72rem; letter-spacing:.34em; text-transform:uppercase; color:var(--muted);
        display:flex; align-items:center; gap:.7em; margin-bottom:.9rem;
      }
      .kicker::before{ content:""; width:26px; height:1px; background:var(--gold); opacity:.7; }
      h1{
        font-family:Georgia,"Iowan Old Style","Palatino Linotype",serif;
        font-weight:600; line-height:.94; letter-spacing:-.01em;
        font-size:clamp(2.3rem,7vw,4.1rem);
      }
      h1 em{ font-style:italic; color:var(--gold); }
    
      .stats{ display:flex; gap:clamp(16px,3vw,30px); text-align:right; flex-shrink:0; }
      .stat b{
        display:block; font-family:Georgia,serif; font-weight:600;
        font-size:clamp(1.5rem,4vw,2.1rem); line-height:1; letter-spacing:-.02em;
      }
      .stat span{
        display:block; margin-top:.35rem; font-size:.66rem; letter-spacing:.2em;
        text-transform:uppercase; color:var(--muted);
      }
    
      /* ---------- board ---------- */
      .board{
        position:relative;
        border:1px solid var(--line); border-radius:4px;
        padding:clamp(16px,3vw,28px) clamp(14px,3vw,26px) clamp(10px,2vw,18px);
        background:linear-gradient(180deg, rgba(58,38,24,.34), rgba(28,19,13,.5));
        box-shadow:inset 0 1px 0 rgba(255,255,255,.04), 0 30px 60px -30px rgba(0,0,0,.7);
      }
    
      svg.chart{ display:block; width:100%; height:auto; overflow:visible; }
    
      /* grid + axes */
      .grid-line{ stroke:var(--line); stroke-width:1; stroke-dasharray:2 5; }
      .baseline{ stroke:rgba(245,231,211,.4); stroke-width:1.5; }
      .axis-num{ fill:var(--muted); font-size:10px; letter-spacing:.04em; opacity:.85; }
    
      /* bars */
      .bar{
        fill:url(#coffeeGrad);
        transform-box:fill-box; transform-origin:bottom center;
        transition:filter .25s ease, opacity .3s ease;
      }
      .bar:hover, .bar:focus-visible{ filter:brightness(1.2) saturate(1.08); outline:none; }
      svg.chart.has-hover .bar:not(:hover):not(:focus-visible){ opacity:.42; }
    
      /* day labels */
      .day-label{ fill:var(--muted); font-size:13px; letter-spacing:.16em; transition:fill .25s ease, opacity .3s ease; }
      svg.chart.has-hover .day-label:not(:hover):not(.active){ opacity:.4; }
      .day-label:hover{ fill:var(--ink); }
    
      /* value labels */
      .value-label{
        font-family:Georgia,serif; font-weight:600; font-size:18px; fill:var(--ink);
        paint-order:stroke; stroke:#140d08; stroke-width:3.5px; stroke-linejoin:round;
        transition:fill .2s ease;
      }
      .value-label.active{ fill:var(--gold); }
    
      /* reveal animation (JS adds .ready) */
      svg.chart:not(.ready) .bar{ transform:scaleY(0); }
      svg.chart.ready .bar{ animation:grow .95s cubic-bezier(.2,.85,.25,1) both; }
      svg.chart:not(.ready) .value-label{ opacity:0; }
      svg.chart.ready .value-label{ animation:fadeUp .5s ease both; }
      @keyframes grow{ from{ transform:scaleY(0); } to{ transform:scaleY(1); } }
      @keyframes fadeUp{ from{ opacity:0; transform:translateY(6px);} to{ opacity:1; transform:translateY(0);} }
    
      /* steam wisps */
      .steam{ fill:none; stroke:rgba(255,240,220,.5); stroke-width:3; stroke-linecap:round; opacity:.45; }
      svg.chart.ready .steam{ animation:drift 3.6s ease-in-out infinite; }
      @keyframes drift{
        0%   { transform:translateY(0);     opacity:0; }
        25%  { opacity:.5; }
        70%  { opacity:.18; }
        100% { transform:translateY(-30px); opacity:0; }
      }
    
      /* ---------- footer ---------- */
      .foot{
        display:flex; justify-content:space-between; align-items:center; gap:16px; flex-wrap:wrap;
        color:var(--muted); font-size:.78rem; letter-spacing:.02em;
      }
      .foot .peak b{ color:var(--ink); font-weight:600; }
      .foot .scale{ display:flex; align-items:center; gap:.5em; }
      .foot .swatch{ width:14px; height:14px; border-radius:3px; background:linear-gradient(180deg,#f2a94b,#6b3d1e); }
    
      @media (max-width:560px){
        .masthead{ flex-direction:column; align-items:flex-start; gap:18px; }
        .stats{ text-align:left; }
      }
    
      @media (prefers-reduced-motion: reduce){
        *{ animation:none !important; transition:none !important; }
        svg.chart:not(.ready) .bar{ transform:none; }
        svg.chart:not(.ready) .value-label{ opacity:1; }
      }
    </style>
    </head>
    <body>
      <div class="wrap">
    
        <header class="masthead">
          <div>
            <p class="kicker">The Coffee Counter</p>
            <h1>Week in <em>Cups</em></h1>
          </div>
          <div class="stats" aria-hidden="true">
            <div class="stat"><b id="totalStat">0</b><span>Total cups</span></div>
            <div class="stat"><b id="peakStat">—</b><span>Peak day</span></div>
          </div>
        </header>
    
        <section class="board" aria-label="Bar chart of coffee sold by weekday">
          <!-- Bars written directly in markup; height ∝ value (10px per cup) -->
          <svg class="chart" viewBox="0 0 720 400" role="img"
               aria-label="Bar chart: coffee sold each day — Monday 12, Tuesday 30, Wednesday 18, Thursday 24, Friday 6 cups.">
            <title>Coffee sold this week</title>
    
            <defs>
              <linearGradient id="coffeeGrad" x1="0" y1="0" x2="0" y2="1">
                <stop offset="0%"  stop-color="#f2a94b"/>
                <stop offset="55%" stop-color="#c87d34"/>
                <stop offset="100%" stop-color="#6b3d1e"/>
              </linearGradient>
            </defs>
    
            <!-- gridlines + axis numbers -->
            <line class="grid-line" x1="52" y1="340" x2="708" y2="340"/>
            <line class="grid-line" x1="52" y1="240" x2="708" y2="240"/>
            <line class="grid-line" x1="52" y1="140" x2="708" y2="140"/>
            <line class="baseline"  x1="52" y1="340" x2="708" y2="340"/>
    
            <text class="axis-num" x="44" y="344" text-anchor="end">0</text>
            <text class="axis-num" x="44" y="244" text-anchor="end">10</text>
            <text class="axis-num" x="44" y="144" text-anchor="end">20</text>
            <text class="axis-num" x="44" y="44"  text-anchor="end">30</text>
    
            <!-- bars -->
            <rect class="bar" x="76.8"  y="220" width="54.4" height="120" rx="4"/>
            <rect class="bar" x="206.4" y="40"  width="54.4" height="300" rx="4"/>
            <rect class="bar" x="336"   y="160" width="54.4" height="180" rx="4"/>
            <rect class="bar" x="465.6" y="100" width="54.4" height="240" rx="4"/>
            <rect class="bar" x="595.2" y="280" width="54.4" height="60"  rx="4"/>
    
            <!-- value labels -->
            <text class="value-label" data-value="12" x="104"   y="204" text-anchor="middle">12</text>
            <text class="value-label" data-value="30" x="233.6" y="24"  text-anchor="middle">30</text>
            <text class="value-label" data-value="18" x="363.2" y="144" text-anchor="middle">18</text>
            <text class="value-label" data-value="24" x="492.8" y="84"  text-anchor="middle">24</text>
            <text class="value-label" data-value="6"  x="622.4" y="264" text-anchor="middle">6</text>
    
            <!-- day labels -->
            <text class="day-label" data-index="0" x="104"   y="368" text-anchor="middle">MON</text>
            <text class="day-label" data-index="1" x="233.6" y="368" text-anchor="middle">TUE</text>
            <text class="day-label" data-index="2" x="363.2" y="368" text-anchor="middle">WED</text>
            <text class="day-label" data-index="3" x="492.8" y="368" text-anchor="middle">THU</text>
            <text class="day-label" data-index="4" x="622.4" y="368" text-anchor="middle">FRI</text>
    
            <!-- steam over the peak (Tuesday) -->
            <path class="steam" d="M225 30 q-7 -9 0 -18 q7 -9 0 -18"/>
            <path class="steam" style="animation-delay:.6s" d="M242 30 q7 -9 0 -18 q-7 -9 0 -18"/>
          </svg>
        </section>
    
        <footer class="foot">
          <span class="peak">Peak day: <b>Tuesday · 30 cups</b></span>
          <span class="scale"><span class="swatch"></span> one bar = cups poured that day</span>
        </footer>
    
      </div>
    
    <script>
    (function(){
      var chart   = document.querySelector('svg.chart');
      var bars    = Array.prototype.slice.call(chart.querySelectorAll('.bar'));
      var labels  = Array.prototype.slice.call(chart.querySelectorAll('.day-label'));
      var values  = Array.prototype.slice.call(chart.querySelectorAll('.value-label'));
      var totalEl = document.getElementById('totalStat');
    
      // stagger the bar reveal
      bars.forEach(function(b, i){ b.style.animationDelay = (i * 0.1) + 's'; });
      values.forEach(function(v, i){ v.style.animationDelay = (0.35 + i * 0.1) + 's'; });
    
      // highlight a bar on hover / focus, syncing its day + value label
      function activate(i){
        chart.classList.add('has-hover');
        labels[i].classList.add('active');
        values[i].classList.add('active');
      }
      function clear(){
        chart.classList.remove('has-hover');
        labels.forEach(function(l){ l.classList.remove('active'); });
        values.forEach(function(v){ v.classList.remove('active'); });
      }
      bars.concat(labels).forEach(function(el, i){
        el.addEventListener('mouseenter', function(){ activate(i); });
        el.addEventListener('mouseleave', clear);
        el.addEventListener('focus',      function(){ activate(i); });
        el.addEventListener('blur',       clear);
      });
    
      // count the total up once on load
      var target = values.reduce(function(s, v){ return s + (+v.dataset.value); }, 0);
      if (totalEl){
        var dur = 1200, t0 = null;
        function step(t){
          if (t0 === null) t0 = t;
          var p = Math.min((t - t0) / dur, 1);
          totalEl.textContent = Math.round(target * (1 - Math.pow(1 - p, 3)));
          if (p < 1) requestAnimationFrame(step); else totalEl.textContent = target;
        }
        requestAnimationFrame(step);
      }
    
      // trigger the entrance animation on the next frame
      requestAnimationFrame(function(){ requestAnimationFrame(function(){ chart.classList.add('ready'); }); });
    })();
    </script>
    </body>
    </html>
    ```
  • Build 2048Failed

    8,740 tokens: 462 read, 8,278 written · 5 min 44 s · 24.2 tok/s

    Build the game 2048 as one web page, playable with the arrow keys, with the board drawn on the page.
    
    In <script id="game">, define createGame() returning an object with move(dir) and state(). dir is "up", "down", "left" or "right". state() returns {board, score, over}: board is 4 rows of 4 numbers, top row first (0 is an empty cell), score is a number, over is a boolean.
    
    The rules, exactly:
    1. The board starts as this one, then a 2 is put in each of the first two empty cells in reading order (row by row from the top, left to right). The score starts at 0.
    [0, 0, 16, 0]
    [2, 0, 0, 4]
    [4, 16, 0, 0]
    [0, 0, 32, 0]
    2. A move slides every tile as far as it goes toward dir. Two tiles of the same value that meet merge into one tile of their sum, nearest the side they move toward first: moving left, [2,2,2,2] becomes [4,4,0,0] and [2,2,2,0] becomes [4,2,0,0]. A tile made by a merge does not merge again in the same move.
    3. Each merge adds the new tile's value to the score.
    4. If a move changed the board, a 2 is put in the first empty cell in reading order. A move that changes nothing does nothing.
    5. over is true when no move would change the board; then moves do nothing.
    
    Output one complete HTML document and nothing else, with all CSS and JavaScript inline and nothing loaded from another site. Put the game logic, and only it, in <script id="game">: it must not touch document, window or timers, because the site runs that script on its own and plays the game through createGame(). Wire the page in another <script>.

    Open the page on its own. It runs in a sandbox: no network, no access to this site.

    Page source
    ```html
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>2048 — Slide &amp; Merge</title>
    <style>
      :root{
        --bg:#0e1b2a; --ink:#f3ede2; --muted:#7f95ab;
        --panel:#16273c; --line:rgba(255,255,255,.08);
        --gold:#f2c14e; --danger:#ef6b5a;
      }
      *{box-sizing:border-box;}
      html,body{margin:0;padding:0;}
      body{
        min-height:100vh; color:var(--ink);
        font-family:"Trebuchet MS","Segoe UI",system-ui,sans-serif;
        background:
          radial-gradient(1200px 700px at 8% -10%, rgba(63,141,195,.20), transparent 60%),
          radial-gradient(1000px 800px at 108% 112%, rgba(242,193,78,.13), transparent 55%),
          linear-gradient(160deg,#0e1b2a,#0a1420 55%,#0c1a29);
        -webkit-font-smoothing:antialiased;
      }
    
      /* ---------- ambient background ---------- */
      .bg{position:fixed;inset:0;z-index:-1;overflow:hidden;}
      .glow{position:absolute;border-radius:50%;filter:blur(70px);opacity:.5;}
      .g1{width:52vw;height:52vw;left:-12vw;top:-16vw;background:radial-gradient(circle,rgba(63,141,195,.55),transparent 70%);animation:drift1 26s ease-in-out infinite;}
      .g2{width:48vw;height:48vw;right:-14vw;bottom:-18vw;background:radial-gradient(circle,rgba(242,193,78,.42),transparent 70%);animation:drift2 32s ease-in-out infinite;}
      .g3{width:30vw;height:30vw;left:52%;top:42%;background:radial-gradient(circle,rgba(196,110,181,.30),transparent 70%);animation:drift1 40s ease-in-out infinite reverse;}
      @keyframes drift1{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(6vw,4vh) scale(1.12)}}
      @keyframes drift2{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(-5vw,-3vh) scale(1.1)}}
      .grid{position:absolute;inset:-2px;opacity:.4;
        background-image:linear-gradient(rgba(255,255,255,.03) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.03) 1px,transparent 1px);
        background-size:46px 46px;
        -webkit-mask-image:radial-gradient(circle at 50% 42%,#000 0%,transparent 78%);
        mask-image:radial-gradient(circle at 50% 42%,#000 0%,transparent 78%);}
      .tile-float{position:absolute;width:56px;height:56px;border-radius:14px;display:flex;align-items:center;justify-content:center;font-weight:800;color:#fff;opacity:.06;box-shadow:inset 0 -3px 0 rgba(0,0,0,.2);animation:floaty 18s ease-in-out infinite;}
      @keyframes floaty{0%,100%{transform:translateY(0) rotate(-8deg)}50%{transform:translateY(-34px) rotate(8deg)}}
    
      /* ---------- layout ---------- */
      .wrap{max-width:1080px;margin:0 auto;padding:clamp(20px,4vw,48px);display:grid;grid-template-columns:minmax(0,1fr) minmax(300px,360px);gap:clamp(24px,4vw,56px);align-items:center;}
      @media(max-width:900px){.wrap{grid-template-columns:1fr;justify-items:center;text-align:left;}}
    
      /* ---------- hero ---------- */
      .eyebrow{display:inline-flex;align-items:center;gap:8px;font-size:.72rem;letter-spacing:.34em;text-transform:uppercase;color:var(--gold);font-weight:700;margin-bottom:18px;}
      .dot{width:8px;height:8px;border-radius:50%;background:var(--gold);box-shadow:0 0 12px var(--gold);animation:pulse 2s ease-in-out infinite;}
      @keyframes pulse{0%,100%{opacity:.4;transform:scale(.8)}50%{opacity:1;transform:scale(1.2)}}
      h1.title{margin:0;font-size:clamp(3rem,10vw,6.4rem);line-height:.9;font-weight:800;letter-spacing:-.03em;display:flex;align-items:baseline;gap:.15em;}
      h1.title .t20{color:#fff;text-shadow:0 8px 30px rgba(0,0,0,.4);}
      h1.title .t48{color:var(--gold);text-shadow:0 8px 34px rgba(242,193,78,.5);}
      .tagline{margin:20px 0 26px;max-width:44ch;font-size:clamp(1rem,1.6vw,1.18rem);line-height:1.55;color:#c9d6e4;}
      .howto{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:28px;}
      .chip{display:inline-flex;align-items:center;gap:8px;padding:9px 14px;border-radius:12px;background:rgba(255,255,255,.04);border:1px solid var(--line);font-size:.9rem;color:#dfe7f0;}
      .chip b{color:var(--gold);}
      .keys{display:inline-flex;gap:4px;}
      kbd{display:inline-grid;place-items:center;min-width:26px;height:26px;padding:0 7px;border-radius:8px;background:#1c2f45;border:1px solid rgba(255,255,255,.1);border-bottom-width:3px;font-family:inherit;font-size:.8rem;color:#eaf0f6;}
      .actions{display:flex;flex-wrap:wrap;gap:12px;margin-bottom:30px;}
      .btn{font:inherit;font-weight:700;font-size:.95rem;padding:13px 22px;border-radius:13px;border:1px solid transparent;cursor:pointer;display:inline-flex;align-items:center;gap:8px;transition:transform .16s,box-shadow .2s,background .2s,border-color .2s;}
      .btn:active{transform:translateY(1px);}
      .btn.primary{background:linear-gradient(135deg,#f7cf6a,#e89b2c);color:#3a2405;box-shadow:0 10px 26px rgba(232,155,44,.34);}
      .btn.primary:hover{transform:translateY(-2px);box-shadow:0 16px 34px rgba(232,155,44,.48);}
      .btn.ghost{background:rgba(255,255,255,.04);color:var(--ink);border-color:var(--line);}
      .btn.ghost:hover{background:rgba(255,255,255,.09);transform:translateY(-2px);}
    
      /* ---------- board card ---------- */
      .board-card{position:relative;width:min(94vw,460px);aspect-ratio:1;padding:18px;border-radius:26px;background:linear-gradient(160deg,#1a2d45,#132238);border:1px solid rgba(255,255,255,.09);box-shadow:0 30px 70px rgba(0,0,0,.5),inset 0 1px 0 rgba(255,255,255,.06);}
      .board-card::before{content:"";position:absolute;inset:-2px;border-radius:28px;background:linear-gradient(135deg,rgba(242,193,78,.5),transparent 40%,transparent 60%,rgba(63,141,195,.4));z-index:-1;filter:blur(22px);opacity:.5;}
      .board{position:relative;width:100%;height:100%;display:grid;grid-template-columns:repeat(4,1fr);grid-template-rows:repeat(4,1fr);gap:clamp(8px,2.4vw,13px);}
      .cell{border-radius:16px;background:rgba(9,17,28,.55);box-shadow:inset 0 2px 8px rgba(0,0,0,.45),inset 0 -1px 0 rgba(255,255,255,.03);}
    
      /* ---------- tiles ---------- */
      .tile{position:absolute;top:0;left:0;will-change:transform;display:flex;align-items:center;justify-content:center;border-radius:16px;font-weight:800;line-height:1;color:#fff;background:#9f9f9f;box-shadow:inset 0 -4px 0 rgba(0,0,0,.2),inset 0 2px 0 rgba(255,255,255,.16),0 6px 14px rgba(0,0,0,.3);z-index:2;transition:transform .17s cubic-bezier(.2,.75,.3,1.18),opacity .18s ease;}
      .tile.moving{transition:transform .17s cubic-bezier(.2,.75,.3,1.18);}
      .tile.pop{animation:pop .2s ease;z-index:4;}
      @keyframes pop{0%{scale:.5;opacity:.4}60%{scale:1.14}100%{scale:1;opacity:1}}
      .t-2{background:#93a7c0;color:#0d1a2b;}
      .t-4{background:#b08ad0;color:#fff;}
      .t-8{background:#ef9f57;}
      .t-16{background:#ec7d4e;}
      .t-32{background:#e8623c;}
      .t-64{background:#e34a30;box-shadow:inset 0 -4px 0 rgba(0,0,0,.2),inset 0 2px 0 rgba(255,255,255,.16),0 8px 22px rgba(227,74,48,.4);}
      .t-128{background:#f2c14e;color:#3a2405;}
      .t-256{background:#f0b429;color:#3a2405;box-shadow:inset 0 -4px 0 rgba(0,0,0,.18),inset 0 2px 0 rgba(255,255,255,.2),0 0 26px rgba(240,180,41,.4);}
      .t-512{background:#f39c12;color:#fff;box-shadow:inset 0 -4px 0 rgba(0,0,0,.2),inset 0 2px 0 rgba(255,255,255,.18),0 0 30px rgba(243,156,18,.5);}
      .t-1024{background:#f57f17;color:#fff;box-shadow:inset 0 -4px 0 rgba(0,0,0,.2),inset 0 2px 0 rgba(255,255,255,.18),0 0 34px rgba(245,127,23,.6);}
      .t-2048{background:#ffd54f;color:#3a2405;box-shadow:inset 0 -4px 0 rgba(0,0,0,.16),inset 0 2px 0 rgba(255,255,255,.28),0 0 44px rgba(255,213,79,.7);}
      .t-super{background:#7c5cff;color:#fff;box-shadow:inset 0 -4px 0 rgba(0,0,0,.22),inset 0 2px 0 rgba(255,255,255,.22),0 0 40px rgba(124,92,255,.6);}
    
      /* ---------- stats ---------- */
      .stats{display:flex;gap:14px;margin-bottom:20px;}
      .stat{flex:1;padding:16px 18px;border-radius:18px;background:linear-gradient(160deg,#1a2d45,#132238);border:1px solid rgba(255,255,255,.07);box-shadow:0 14px 34px rgba(0,0,0,.35);}
      .stat .label{display:block;font-size:.68rem;letter-spacing:.2em;text-transform:uppercase;color:var(--muted);margin-bottom:9px;}
      .stat .value{font-size:clamp(1.7rem,4.4vw,2.4rem);font-weight:800;line-height:1;font-variant-numeric:tabular-nums;letter-spacing:-.01em;}
      .stat.score .value{color:var(--gold);}
      .gain{position:absolute;top:6px;right:14px;font-weight:800;color:var(--gold);font-size:1rem;animation:floatUp .7s ease forwards;pointer-events:none;text-shadow:0 2px 8px rgba(0,0,0,.5);}
      @keyframes floatUp{0%{opacity:0;transform:translateY(6px)}20%{opacity:1}100%{opacity:0;transform:translateY(-24px)}}
    
      .panel-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:22px;}
      .hint{font-size:.85rem;color:var(--muted);}
      .best-badge{font-size:.72rem;letter-spacing:.06em;text-transform:uppercase;padding:6px 12px;border-radius:999px;background:rgba(242,193,78,.14);color:var(--gold);border:1px solid rgba(242,193,78,.3);}
    
      /* ---------- overlays ---------- */
      .overlay{position:absolute;inset:0;border-radius:26px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;background:rgba(10,18,30,.84);backdrop-filter:blur(4px);opacity:0;visibility:hidden;transition:opacity .35s;z-index:20;text-align:center;padding:20px;}
      .overlay.show{opacity:1;visibility:visible;}
      .overlay h2{margin:0;font-size:clamp(1.8rem,6vw,2.6rem);font-weight:800;letter-spacing:-.01em;}
      .overlay p{margin:0;color:#c9d6e4;font-size:.95rem;}
    
      /* ---------- toast ---------- */
      .toast{position:fixed;left:50%;bottom:26px;transform:translateX(-50%) translateY(20px);background:#1c2f45;border:1px solid var(--line);color:var(--ink);padding:12px 20px;border-radius:12px;font-size:.9rem;opacity:0;transition:.3s;z-index:60;box-shadow:0 12px 30px rgba(0,0,0,.4);}
      .toast.show{opacity:1;transform:translateX(-50%) translateY(0);}
    
      /* ---------- reveal ---------- */
      .reveal{opacity:0;animation:rise .7s cubic-bezier(.2,.7,.3,1) forwards;}
      @keyframes rise{from{opacity:0;transform:translateY(24px)}to{opacity:1;transform:none}}
    
      @media(prefers-reduced-motion:reduce){*{animation-duration:.001ms!important;transition-duration:.001ms!important;}}
    </style>
    </head>
    <body>
      <div class="bg" aria-hidden="true">
        <div class="glow g1"></div>
        <div class="glow g2"></div>
        <div class="glow g3"></div>
        <div class="grid"></div>
        <div class="tile-float t-2048" style="left:6%;top:16%;font-size:.9rem;animation-duration:22s;">2048</div>
        <div class="tile-float t-512"  style="right:8%;top:24%;font-size:1.3rem;animation-duration:17s;animation-delay:-4s;">512</div>
        <div class="tile-float t-16"   style="left:14%;bottom:12%;font-size:1.4rem;animation-duration:20s;animation-delay:-8s;">16</div>
        <div class="tile-float t-128"  style="right:12%;bottom:16%;font-size:1rem;animation-duration:24s;animation-delay:-2s;">128</div>
        <div class="tile-float t-8"    style="left:44%;top:70%;font-size:1.5rem;animation-duration:19s;animation-delay:-6s;">8</div>
      </div>
    
      <main class="wrap">
        <!-- HERO -->
        <section class="hero reveal" style="animation-delay:.05s">
          <span class="eyebrow"><span class="dot"></span> Slide · Merge · Climb</span>
          <h1 class="title"><span class="t20">20</span><span class="t48">48</span></h1>
          <p class="tagline">Nudge the tiles, fold matching pairs into bigger powers of two, and chase the golden 2048. One merge at a time — every square counts.</p>
    
          <div class="howto">
            <span class="chip"><span class="keys"><kbd>←</kbd><kbd>→</kbd><kbd>↑</kbd><kbd>↓</kbd></span> slide the board</span>
            <span class="chip"><b>Match</b> two equal tiles to merge</span>
            <span class="chip">Each merge <b>adds its value</b> to your score</span>
          </div>
    
          <div class="actions">
            <button class="btn primary" id="newGame">New Game</button>
            <button class="btn ghost" id="undo">Undo</button>
          </div>
    
          <div class="board-card reveal" style="animation-delay:.18s">
            <div class="board" id="board"></div>
            <div class="overlay" id="overlay">
              <h2 id="ovTitle">Game over</h2>
              <p id="ovText">No moves left.</p>
              <button class="btn primary" id="again">Play again</button>
            </div>
          </div>
        </section>
    
        <!-- PANEL -->
        <aside class="panel reveal" style="animation-delay:.28s">
          <div class="stats">
            <div class="stat score"><span class="label">Score</span><span class="value" id="score">0</span></div>
            <div class="stat best"><span class="label">Best</span><span class="value" id="best">0</span></div>
          </div>
    
          <button class="btn ghost" id="undo2" style="width:100%;justify-content:center;">↶ Undo last move</button>
    
          <div class="panel-foot">
            <span class="hint">Tip: open a corner, keep your biggest tile tucked in.</span>
            <span class="best-badge" id="badge">in play</span>
          </div>
        </aside>
      </main>
    
      <div class="toast" id="toast"></div>
    
      <!-- ============ GAME LOGIC (pure, no DOM / window / timers) ============ -->
      <script id="game">
      function createGame(){
        var start = [
          [0, 0, 16, 0],
          [2, 0,  0, 4],
          [4, 16,  0, 0],
          [0, 0, 32, 0]
        ];
    
        function cloneBoard(b){ return b.map(function(r){ return r.slice(); }); }
    
        function spawnTwo(board){
          var empties = [];
          for (var r=0; r<4; r++) for (var c=0; c<4; c++) if (board[r][c]===0) empties.push([r,c]);
          for (var i=0; i<2 && i<empties.length; i++){
            board[empties[i][0]][empties[i][1]] = 2;
          }
        }
    
        var board = cloneBoard(start);
        spawnTwo(board);
        var score = 0;
    
        function computeOver(b){
          for (var r=0; r<4; r++) for (var c=0; c<4; c++){
            if (b[r][c]===0) return false;
            if (c<3 && b[r][c]===b[r][c+1]) return false;
            if (r<3 && b[r][c]===b[r+1][c]) return false;
          }
          return true;
        }
    
        function move(dir){
          var horizontal = (dir==='left' || dir==='right');
          var forward = (dir==='left' || dir==='up');
    
          var nb = cloneBoard(board);
          var changed = false;
          var gained = 0;
    
          for (var i=0; i<4; i++){
            var line = [];
            for (var j=0; j<4; j++){
              if (horizontal) line.push(board[j][i]);
              else            line.push(board[i][j]);
            }
            if (!forward) line.reverse();
    
            var out = [], k = 0, m = line.length;
            while (k < m){
              if (line[k] === 0){ k++; continue; }
              if (k+1 < m && line[k+1] === line[k]){
                var sum = line[k]*2;
                out.push(sum);
                gained += sum;
                changed = true;
                k += 2;
              } else {
                out.push(line[k]);
                k++;
              }
            }
            while (out.length < 4) out.push(0);
    
            if (!forward) out.reverse();
    
            for (var j=0; j<4; j++){
              var target = horizontal ? nb[j][i] : nb[i][j];
              if (target !== out[j]) changed = true;
              if (horizontal) nb[j][i] = out[j];
              else            nb[i][j] = out[j];
            }
          }
    
          if (!changed) return false;
          board = nb;
          score += gained;
          spawnTwo(board);
          return true;
        }
    
        function state(){
          return { board: cloneBoard(board), score: score, over: computeOver(board) };
        }
    
        return { move: move, state: state };
      }
      </script>
    
      <!-- ============ PAGE WIRING (the only script that touches the DOM) ============ -->
      <script>
      (function(){
        "use strict";
    
        var game = createGame();
        var boardEl = document.getElementById('board');
        var scoreEl = document.getElementById('score');
        var bestEl  = document.getElementById('best');
        var overlay = document.getElementById('overlay');
        var ovTitle = document.getElementById('ovTitle');
        var ovText  = document.getElementById('ovText');
        var badge   = document.getElementById('badge');
        var toastEl = document.getElementById('toast');
    
        // --- background cells (fixed) ---
        for (var i=0; i<16; i++){
          var cell = document.createElement('div');
          cell.className = 'cell';
          boardEl.appendChild(cell);
        }
    
        // --- geometry helpers ---
        function geom(){
          var bRect = boardEl.getBoundingClientRect();
          var cells = boardEl.querySelectorAll('.cell');
          var c0 = cells[0].getBoundingClientRect();
          return { size: c0.width, gap: (bRect.width - 4*c0.width)/3 };
        }
        function transformFor(r,c,g){ return 'translate(' + (c*(g.size+g.gap)) + 'px,' + (r*(g.size+g.gap)) + 'px)'; }
        function fontSize(v, size){
          var len = String(v).length;
          if (len <= 2) return size*0.5;
          if (len === 3) return size*0.4;
          if (len === 4) return size*0.31;
          return size*0.24;
        }
        function tileClass(v){ return v > 2048 ? 't-super' : 't-' + v; }
    
        // --- score animation ---
        var shownScore = 0, scoreAnimId = null;
        function animateScore(target){
          if (scoreAnimId) cancelAnimationFrame(scoreAnimId);
          var from = shownScore, start = performance.now(), dur = 450;
          function step(now){
            var p = Math.min(1, (now-start)/dur);
            var e = 1 - Math.pow(1-p, 3);
            shownScore = Math.round(from + (target-from)*e);
            scoreEl.textContent = shownScore.toLocaleString();
            if (p < 1) scoreAnimId = requestAnimationFrame(step);
          }
          scoreAnimId = requestAnimationFrame(step);
        }
    
        // --- render from state (with optional pop values) ---
        function render(s, popVals){
          var g = geom();
          boardEl.querySelectorAll('.tile').forEach(function(el){ el.remove(); });
          for (var r=0; r<4; r++){
            for (var c=0; c<4; c++){
              var v = s.board[r][c];
              if (!v) continue;
              var el = document.createElement('div');
              el.className = 'tile ' + tileClass(v);
              el.textContent = v;
              el.style.width = g.size + 'px';
              el.style.height = g.size + 'px';
              el.style.fontSize = fontSize(v, g.size) + 'px';
              el.style.transform = transformFor(r,c,g);
              if (popVals && popVals.indexOf(v) !== -1){
                el.classList.add('pop');
                (function(node){ setTimeout(function(){ node.classList.remove('pop'); }, 240); })(el);
              }
              boardEl.appendChild(el);
            }
          }
        }
    
        // --- animated move using the game's own state() ---
        function doMove(dir){
          if (game.state().over) return;
          var before = game.state();
          var moved = game.move(dir);
          if (!moved) return;
          var after = game.state();
    
          // detect new spawns for pop highlight
          var pops = [];
          var seen = 0, spawnCount = 0;
          for (var r=0; r<4; r++) for (var c=0; c<4; c++){
            if (before.board[r][c] === after.board[r][c]) seen++;
          }
          // count cells that changed from 0 to 2 in reading order = spawned tiles
          var spawnVals = [];
          var idx = 0;
          for (var rr=0; rr<4; rr++) for (var cc=0; cc<4; cc++){
            if (before.board[rr][cc] === 0 && after.board[rr][cc] !== 0) spawnVals.push(after.board[rr][cc]);
          }
    
          var g = geom();
          // place "after" tiles at their BEFORE positions, then transition to final
          boardEl.querySelectorAll('.tile').forEach(function(el){ el.remove(); });
          var tiles = [];
          for (var r2=0; r2<4; r2++){
            for (var c2=0; c2<4; c2++){
              var v = after.board[r2][c2];
              if (!v) continue;
              // find a source: same value in before that wasn't consumed — approximate by scanning before for matching value at a different or same cell
              var src = null;
              for (var sr=0; sr<4 && !src; sr++) for (var sc=0; sc<4 && !src; sc++){
                if (before.board[sr][sc] === v){ src = [sr,sc]; }
              }
              var el = document.createElement('div');
              el.className = 'tile moving ' + tileClass(v);
              el.textContent = v;
              el.style.width = g.size + 'px';
              el.style.height = g.size + 'px';
              el.style.fontSize = fontSize(v, g.size) + 'px';
              if (src){ el.style.transform = transformFor(src[0], src[1], g); }
              else { el.style.transform = transformFor(r2,c2,g); }
              boardEl.appendChild(el);
              tiles.push({ el: el, r: r2, c: c2 });
            }
          }
          requestAnimationFrame(function(){
            requestAnimationFrame(function(){
              tiles.forEach(function(t){ t.el.style.transform = transformFor(t.r, t.c, g); });
            });
          });
    
          // score + best
          animateScore(after.score);
          if (after.score > shownBest) { shownBest = after.score; saveBest(); }
          bestEl.textContent = shownBest.toLocaleString();
    
          // gain floater
          var gained = after.score - before.score;
          if (gained > 0){
            var gain = document.createElement('div');
            gain.className = 'gain';
            gain.textContent = '+' + gained;
            boardEl.appendChild(gain);
            setTimeout(function(){ gain.remove(); }, 720);
          }
    
          // settle -> final render (pop the spawns)
          setTimeout(function(){
            render(after, spawnVals.length ? [spawnVals[0]] : null);
            updateOver();
          }, 190);
        }
    
        function updateOver(){
          var s = game.state();
          if (s.over){
            ovTitle.textContent = 'Game over';
            ovText.textContent = 'You reached ' + s.score.toLocaleString() + '. No moves left.';
            badge.textContent = 'game over';
            overlay.classList.add('show');
          } else {
            overlay.classList.remove('show');
            badge.textContent = 'in play';
          }
        }
    
        // --- best score (session-safe) ---
        var shownBest = 0;
        function loadBest(){ try { return parseInt(localStorage.getItem('best2048') || '0', 10) || 0; } catch(e){ return 0; } }
        function saveBest(){ try { localStorage.setItem('best2048', String(shownBest)); } catch(e){} }
        shownBest = loadBest();
    
        // --- toast ---
        var toastTimer = null;
        function toast(msg){
          toastEl.textContent = msg;
          toastEl.classList.add('show');
          if (toastTimer) clearTimeout(toastTimer);
          toastTimer = setTimeout(function(){ toastEl.classList.remove('show'); }, 1600);
        }
    
        // --- reset ---
        function newGame(){
          game = createGame();
          shownScore = 0;
          scoreEl.textContent = '0';
          overlay.classList.remove('show');
          render(game.state(), null);
          toast('Fresh board — good luck!');
        }
    
        // --- wire controls ---
        var keys = { ArrowLeft:'left', ArrowRight:'right', ArrowUp:'up', ArrowDown:'down' };
        window.addEventListener('keydown', function(e){
          if (e.key in keys){ e.preventDefault(); doMove(keys[e.key]); }
        });
    
        document.getElementById('newGame').addEventListener('click', newGame);
        document.getElementById('again').addEventListener('click', newGame);
    
        // simple single-step undo via a lightweight history of states (rebuild not possible, so we just re-render last)
        var history = [];
        function pushHistory(){ history.push(game.state()); if (history.length > 40) history.shift(); }
        // capture state before each successful move by wrapping doMove
        var _doMove = doMove;
        doMove = function(dir){
          if (game.state().over) return;
          pushHistory();
          _doMove(dir);
        };
        function undo(){
          if (!history.length){ toast('Nothing to undo'); return; }
          // We cannot replay a single move backwards through createGame, so we just re-render the previous state for feedback and note it.
          var prev = history.pop();
          render(prev, null);
          animateScore(prev.score);
          overlay.classList.remove('show');
          badge.textContent = 'in play';
          toast('Reverted view (logic keeps advancing on next move)');
        }
        document.getElementById('undo').addEventListener('click', undo);
        document.getElementById('undo2').addEventListener('click', undo);
    
        // --- init ---
        bestEl.textContent = shownBest.toLocaleString();
        render(game.state(), null);
        updateOver();
      })();
      </script>
    </body>
    </html>
    ```
  • Build SnakeFailed

    7,432 tokens: 457 read, 6,975 written · 4 min 48 s · 24.4 tok/s

    Build Snake as one web page on a 10 by 10 grid, playable with the arrow keys (one key press, one step), with the grid drawn on the page.
    
    In <script id="game">, define createGame() returning an object with step(dir) and state(). dir is "up", "down", "left" or "right". state() returns {snake, food, score, over}: snake is a list of [x, y] cells, head first; food is [x, y]; score is a number; over is a boolean. x is the column (0 to 9, left to right), y the row (0 to 9, top to bottom); up is y - 1.
    
    The rules, exactly:
    1. The game starts with snake [[6, 5], [7, 5], [8, 5]], moving left, food at [4, 8], score 0.
    2. step(dir): if dir is the opposite of the current direction it is ignored and the snake keeps going; otherwise dir becomes the current direction. The head moves one cell that way.
    3. If the new head cell holds the food, the snake grows: its tail stays. Otherwise the tail cell is freed first.
    4. If the new head is off the grid or on a cell of the snake (after rule 3), the game is over: over becomes true and nothing else changes. Once over, step does nothing.
    5. Eating adds 1 to the score, and the next food goes to the first empty cell in reading order (row by row from the top, left to right) after the new head's cell, wrapping from [9, 9] to [0, 0].
    
    Output one complete HTML document and nothing else, with all CSS and JavaScript inline and nothing loaded from another site. Put the game logic, and only it, in <script id="game">: it must not touch document, window or timers, because the site runs that script on its own and plays the game through createGame(). Wire the page in another <script>.

    Open the page on its own. It runs in a sandbox: no network, no access to this site.

    Page source
    Here's a complete, self-contained Snake page. The engine lives entirely inside `<script id="game">` (pure logic, no DOM/timers), and a second script wires up the grid, input, sound, and motion.
    
    ```html
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>SNAKE · 10×10</title>
    <style>
    :root{
      --bg:#0a241f;
      --ink:#eafff6;
      --muted:#7fb8ab;
      --line:rgba(120,225,196,.14);
      --cell:rgba(255,255,255,.018);
      --accent:#39d98a;
      --accent-soft:#7ff0b8;
      --danger:#ff5f6d;
      --gold:#ffd166;
      --font-mono: ui-monospace,"SF Mono","JetBrains Mono","Cascadia Code","Fira Code",Menlo,Consolas,monospace;
      --font-body: system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
    }
    *{box-sizing:border-box;}
    html,body{height:100%;}
    body{
      margin:0; min-height:100vh; overflow-x:hidden;
      font-family:var(--font-body); color:var(--ink); background:var(--bg);
      display:flex; align-items:center; justify-content:center; padding:24px;
      -webkit-font-smoothing:antialiased;
    }
    
    /* ambient layers */
    body::before{
      content:""; position:fixed; inset:-10%; z-index:0; pointer-events:none;
      background:
        radial-gradient(58% 52% at 16% 8%, rgba(57,217,138,.20), transparent 60%),
        radial-gradient(52% 52% at 92% 94%, rgba(255,95,109,.12), transparent 60%),
        radial-gradient(42% 42% at 82% 12%, rgba(255,209,102,.07), transparent 60%);
      animation:drift 24s ease-in-out infinite alternate;
    }
    body::after{
      content:""; position:fixed; inset:0; z-index:0; pointer-events:none; opacity:.5;
      background-image:linear-gradient(var(--line) 1px,transparent 1px),linear-gradient(90deg,var(--line) 1px,transparent 1px);
      background-size:46px 46px;
      -webkit-mask:radial-gradient(circle at 50% 42%, #000, transparent 78%);
              mask:radial-gradient(circle at 50% 42%, #000, transparent 78%);
    }
    @keyframes drift{ to{ transform:translate3d(1.6%,-1.4%,0) scale(1.05);} }
    
    /* board */
    .board{ position:relative; z-index:1; width:min(92vw,560px); animation:rise .7s cubic-bezier(.2,.8,.2,1) both; }
    @keyframes rise{ from{opacity:0; transform:translateY(16px);} to{opacity:1; transform:none;} }
    
    .topbar{ display:flex; align-items:center; justify-content:space-between; margin-bottom:14px; }
    .brand{ display:flex; align-items:center; gap:12px; }
    .mark{ width:30px; height:30px; border-radius:8px; position:relative; background:rgba(57,217,138,.1); border:1px solid rgba(57,217,138,.4); box-shadow:inset 0 0 12px rgba(57,217,138,.25); }
    .mark::before{ content:""; position:absolute; inset:6px; border-radius:5px; background:var(--accent); box-shadow:0 0 14px var(--accent); animation:blink 1.9s ease-in-out infinite; }
    .mark::after{ content:""; position:absolute; left:8px; top:8px; width:4px; height:4px; border-radius:50%; background:#06231c; }
    @keyframes blink{ 0%,100%{opacity:.75;} 50%{opacity:1;} }
    .brand h1{ margin:0; font-family:var(--font-mono); font-size:clamp(22px,5.4vw,30px); font-weight:800; letter-spacing:-.02em; line-height:.9; }
    .brand .sub{ display:block; font-size:11px; letter-spacing:.24em; text-transform:uppercase; color:var(--muted); margin-top:5px; }
    
    .stats{ display:flex; align-items:center; gap:8px; }
    .stat{ background:rgba(255,255,255,.03); border:1px solid var(--line); border-radius:12px; padding:7px 12px; min-width:64px; text-align:right; transition:border-color .2s; }
    .stat b{ display:block; font-family:var(--font-mono); font-size:20px; font-weight:700; line-height:1.1; font-variant-numeric:tabular-nums; }
    .stat span{ display:block; font-size:9px; letter-spacing:.18em; text-transform:uppercase; color:var(--muted); margin-top:2px; }
    .icon-btn{ width:40px; height:40px; border-radius:12px; border:1px solid var(--line); background:rgba(255,255,255,.03); color:var(--ink); font-size:16px; cursor:pointer; display:grid; place-items:center; transition:.18s; }
    .icon-btn:hover{ border-color:var(--accent); color:var(--accent-soft); transform:translateY(-1px); }
    
    /* stage + frame */
    .stage{ position:relative; padding:16px; border-radius:24px; background:linear-gradient(180deg,rgba(255,255,255,.03),rgba(0,0,0,.14)); border:1px solid var(--line); box-shadow:0 40px 90px -30px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,255,255,.05); }
    .stage::before{ content:""; position:absolute; inset:6px; border-radius:18px; pointer-events:none; background:repeating-linear-gradient(0deg,rgba(0,0,0,.16) 0 2px,transparent 2px 4px); opacity:.5; mix-blend-mode:multiply; }
    .corner{ position:absolute; width:16px; height:16px; border:2px solid var(--accent); opacity:.55; z-index:3; pointer-events:none; }
    .c-tl{ top:-2px; left:-2px; border-right:0; border-bottom:0; border-top-left-radius:8px;}
    .c-tr{ top:-2px; right:-2px; border-left:0; border-bottom:0; border-top-right-radius:8px;}
    .c-bl{ bottom:-2px; left:-2px; border-right:0; border-top:0; border-bottom-left-radius:8px;}
    .c-br{ bottom:-2px; right:-2px; border-left:0; border-top:0; border-bottom-right-radius:8px;}
    
    .frame{ position:relative; padding:14px; border-radius:16px; background:radial-gradient(circle at 50% 40%, rgba(57,217,138,.05), transparent 70%), #071b17; border:1px solid rgba(120,225,196,.1); box-shadow:inset 0 0 40px rgba(0,0,0,.55); }
    .grid{ position:relative; display:grid; grid-template-columns:repeat(10,1fr); grid-template-rows:repeat(10,1fr); gap:3px; width:100%; aspect-ratio:1/1; border-radius:8px; overflow:hidden; }
    .cell{ background:var(--cell); border-radius:3px; box-shadow:inset 0 0 0 1px rgba(255,255,255,.02); transition:background .1s; }
    
    /* snake */
    .snake{ position:absolute; top:0; left:0; z-index:2; pointer-events:none; will-change:transform; }
    .seg{ position:absolute; top:0; left:0; border-radius:26%; background:#2fbf74; box-shadow:inset 0 1px 2px rgba(255,255,255,.35), inset 0 -3px 5px rgba(0,0,0,.35), 0 0 12px rgba(57,217,138,.3); transition:width .14s ease, height .14s ease, background .14s ease, box-shadow .14s ease; }
    .seg.head{ z-index:3; border-radius:30%; background:radial-gradient(circle at 35% 30%, #d6ffe9, var(--accent) 62%); box-shadow:0 0 18px rgba(57,217,138,.7), inset 0 0 6px rgba(255,255,255,.6); }
    .eye{ position:absolute; width:24%; height:24%; border-radius:50%; background:#06231c; box-shadow:inset 0 0 2px #000; }
    
    /* food */
    .food{ position:absolute; top:0; left:0; z-index:1; pointer-events:none; display:grid; place-items:center; will-change:transform; transition:transform .18s cubic-bezier(.2,.9,.3,1.3); }
    .apple{ width:56%; height:56%; border-radius:47% 47% 46% 46%/52% 52% 44% 44%; background:radial-gradient(circle at 34% 28%, #ff9a9e, var(--danger) 60%, #c11f2d); box-shadow:inset -2px -3px 6px rgba(0,0,0,.35), 0 0 14px rgba(255,95,109,.5); position:relative; animation:bob 1.8s ease-in-out infinite; }
    .apple::before{ content:""; position:absolute; top:-16%; left:50%; width:3px; height:26%; background:#7a4a2b; transform-origin:bottom center; transform:translateX(-50%) rotate(9deg); border-radius:2px; }
    .apple::after{ content:""; position:absolute; top:-18%; left:52%; width:16px; height:9px; background:#4fd37a; border-radius:0 100% 0 100%; transform:rotate(-22deg); box-shadow:0 0 6px rgba(79,211,122,.5); }
    @keyframes bob{ 0%,100%{transform:translateY(0) scale(1);} 50%{transform:translateY(-3%) scale(1.05);} }
    
    /* overlays */
    .overlay{ position:absolute; inset:0; z-index:5; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:12px; text-align:center; background:radial-gradient(circle at 50% 40%, rgba(7,27,23,.86), rgba(7,27,23,.95)); backdrop-filter:blur(3px); -webkit-backdrop-filter:blur(3px); opacity:0; visibility:hidden; transition:opacity .3s ease, visibility .3s; padding:16px; }
    .overlay.show{ opacity:1; visibility:visible; }
    .ov-kicker{ font-size:11px; letter-spacing:.28em; text-transform:uppercase; color:var(--accent-soft); }
    .ov-title{ margin:0; font-family:var(--font-mono); font-weight:800; letter-spacing:-.02em; font-size:clamp(30px,9vw,54px); line-height:.95; text-shadow:0 6px 30px rgba(57,217,138,.35); }
    .ov-title .accent{ color:var(--accent-soft); }
    .ov-sub{ margin:0; max-width:34ch; color:var(--muted); font-size:14px; line-height:1.55; }
    .ov-score{ font-family:var(--font-mono); font-size:15px; letter-spacing:.06em; color:var(--ink); }
    .ov-score b{ font-size:34px; color:var(--gold); margin-left:8px; text-shadow:0 0 20px rgba(255,209,102,.4); }
    .btn{ margin-top:6px; font-family:var(--font-mono); font-weight:700; letter-spacing:.02em; font-size:15px; color:#06231c; background:linear-gradient(180deg,var(--accent-soft),var(--accent)); border:none; border-radius:999px; padding:12px 26px; cursor:pointer; box-shadow:0 10px 24px -8px rgba(57,217,138,.7); transition:transform .15s, box-shadow .15s; }
    .btn:hover{ transform:translateY(-2px); box-shadow:0 16px 30px -8px rgba(57,217,138,.8); }
    .btn:active{ transform:translateY(0); }
    
    /* footer */
    .foot{ margin-top:16px; display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; }
    .hint{ font-size:12px; color:var(--muted); letter-spacing:.02em; }
    kbd{ font-family:var(--font-mono); font-size:11px; background:rgba(255,255,255,.06); border:1px solid var(--line); border-bottom-width:2px; border-radius:6px; padding:3px 7px; color:var(--ink); margin:0 1px; }
    .dpad{ display:grid; grid-template-columns:repeat(3,42px); grid-template-rows:repeat(3,42px); gap:6px; touch-action:none; user-select:none; -webkit-user-select:none; }
    .dk{ border-radius:12px; border:1px solid var(--line); background:rgba(255,255,255,.04); color:var(--ink); font-size:18px; cursor:pointer; display:grid; place-items:center; transition:.1s; }
    .dk:hover{ border-color:var(--accent); color:var(--accent-soft); }
    .dk:active{ background:rgba(57,217,138,.2); transform:scale(.94); }
    .dk.up{ grid-column:2; grid-row:1; } .dk.left{ grid-column:1; grid-row:2; } .dk.right{ grid-column:3; grid-row:2; } .dk.down{ grid-column:2; grid-row:3; }
    
    @media (max-width:560px){
      body{ padding:14px; align-items:flex-start; }
      .dpad{ display:none; }
    }
    @media (prefers-reduced-motion:reduce){
      *{ animation-duration:.001ms !important; animation-iteration-count:1 !important; transition-duration:.001ms !important; }
    }
    </style>
    </head>
    <body>
      <main class="board">
        <header class="topbar">
          <div class="brand">
            <span class="mark" aria-hidden="true"></span>
            <h1>SNAKE<span class="sub">10 × 10 grid</span></h1>
          </div>
          <div class="stats">
            <div class="stat"><b id="score">0</b><span>Score</span></div>
            <button class="icon-btn" id="soundBtn" aria-label="Toggle sound">🔊</button>
          </div>
        </header>
    
        <section class="stage">
          <span class="corner c-tl"></span><span class="corner c-tr"></span>
          <span class="corner c-bl"></span><span class="corner c-br"></span>
          <div class="frame">
            <div class="grid" id="grid"></div>
    
            <div class="overlay show" id="startOv">
              <p class="ov-kicker">Ready</p>
              <h2 class="ov-title">SNAKE<span class="accent">.</span></h2>
              <p class="ov-sub">Steer with the arrow keys. One key press = one step. Eat to grow — touch a wall or yourself and it's over.</p>
              <button class="btn" id="startBtn">▶ Start</button>
            </div>
    
            <div class="overlay" id="overOv">
              <p class="ov-kicker">Game over</p>
              <h2 class="ov-title">GAME<span class="accent">OVER</span></h2>
              <p class="ov-score">SCORE<b id="finalScore">0</b></p>
              <button class="btn" id="restartBtn">↻ Play again</button>
            </div>
          </div>
        </section>
    
        <footer class="foot">
          <p class="hint"><kbd>↑</kbd><kbd>↓</kbd><kbd>←</kbd><kbd>→</kbd> move &nbsp;·&nbsp; <kbd>R</kbd> restart</p>
          <div class="dpad" id="dpad" aria-hidden="true">
            <button class="dk up" data-dir="up">▲</button>
            <button class="dk left" data-dir="left">◀</button>
            <button class="dk right" data-dir="right">▶</button>
            <button class="dk down" data-dir="down">▼</button>
          </div>
        </footer>
      </main>
    
    <script id="game">
    function createGame(){
      var N = 10;
      var snake, food, score, over, dir;
    
      function reset(){
        snake = [[6,5],[7,5],[8,5]];
        food  = [4,8];
        score = 0;
        over  = false;
        dir   = "left";
      }
      reset();
    
      function opposite(a,b){
        return (a==="up"&&b==="down")||(a==="down"&&b==="up")||
               (a==="left"&&b==="right")||(a==="right"&&b==="left");
      }
      function delta(d){
        if(d==="up")    return [0,-1];
        if(d==="down")  return [0, 1];
        if(d==="left")  return [-1,0];
        if(d==="right") return [ 1,0];
        return [0,0];
      }
    
      function placeFood(){
        var hx = snake[0][0], hy = snake[0][1];
        var x = (hx + 1) % N, y = hy;
        for(var i=0;i<N*N;i++){
          if(snake.every(function(c){ return c[0]!==x || c[1]!==y; })){ food=[x,y]; return; }
          x++; if(x>=N){ x=0; y=(y+1)%N; }
        }
      }
    
      function step(d){
        if(over) return;
        if(!(opposite(dir,d))) dir = d;
        var dx = delta(dir)[0], dy = delta(dir)[1];
        var head = [snake[0][0]+dx, snake[0][1]+dy];
    
        var eat = (head[0]===food[0] && head[1]===food[1]);
        if(!eat) snake.pop();
    
        var x=head[0], y=head[1];
        if(x<0||x>=N||y<0||y>=N || snake.some(function(c){ return c[0]===x&&c[1]===y; })){
          over = true;
          return;
        }
    
        snake.unshift(head);
        if(eat){ score++; placeFood(); }
      }
    
      function state(){
        return {
          snake: snake.map(function(c){ return [c[0],c[1]]; }),
          food:  [food[0],food[1]],
          score: score,
          over:  over
        };
      }
    
      return { step: step, state: state, reset: reset };
    }
    </script>
    
    <script>
    (function(){
      "use strict";
      var N=10;
      var game = createGame();
    
      var gridEl   = document.getElementById('grid');
      var scoreEl  = document.getElementById('score');
      var startOv  = document.getElementById('startOv');
      var overOv   = document.getElementById('overOv');
      var finalEl  = document.getElementById('finalScore');
      var board    = document.querySelector('.board');
      var soundBtn = document.getElementById('soundBtn');
    
      // ---- build the grid cells ----
      var cellEls=[];
      for(var i=0;i<N*N;i++){
        var c=document.createElement('div');
        c.className='cell';
        gridEl.appendChild(c);
        cellEls.push(c);
      }
    
      // ---- snake + food DOM (positioned over the grid) ----
      var segEls=[];
      for(var s=0;s<N*N;s++){
        var seg=document.createElement('div');
        seg.className='seg';
        gridEl.appendChild(seg);
        segEls.push(seg);
      }
      var headEls=[document.createElement('div'),document.createElement('div')];
      headEls.forEach(function(e){ e.className='eye'; segEls[0].appendChild(e); });
    
      var foodEl=document.createElement('div');
      foodEl.className='food';
      var apple=document.createElement('div');
      apple.className='apple';
      foodEl.appendChild(apple);
      gridEl.appendChild(foodEl);
    
      // ---- sound ----
      var audioCtx=null, muted=false;
      function ac(){ if(!audioCtx){ try{ audioCtx=new (window.AudioContext||window.webkitAudioContext)(); }catch(e){} } return audioCtx; }
      function beep(freq,dur,type,vol){
        if(muted) return;
        var ctx=ac(); if(!ctx) return;
        var o=ctx.createOscillator(), g=ctx.createGain();
        o.type=type||'sine'; o.frequency.value=freq;
        o.connect(g); g.connect(ctx.destination);
        var t=ctx.currentTime;
        g.gain.setValueAtTime(0.0001,t);
        g.gain.exponentialRampToValueAtTime(vol||0.06,t+0.01);
        g.gain.exponentialRampToValueAtTime(0.0001,t+dur);
        o.start(t); o.stop(t+dur+0.02);
      }
      soundBtn.addEventListener('click',function(){
        muted=!muted;
        soundBtn.textContent=muted?'🔇':'🔊';
        if(!muted){ ac(); beep(660,0.08,'triangle',0.05); }
      });
    
      // ---- helpers ----
      function pct(v){ return (v*100)+'%'; }
      function cellSize(){ var r=gridEl.getBoundingClientRect(); return r.width/N; }
      function segSize(i,len){ var f=Math.max(0,1-(i/(len+2))*0.5); return Math.round(f*84)+16; }
    
      // ---- render ----
      function render(prevScore, prevFood){
        var st=game.state();
        var len=st.snake.length, cs=cellSize();
    
        for(var i=0;i<segEls.length;i++){
          if(i<len){
            segEls[i].style.display='block';
            var x=st.snake[i][0], y=st.snake[i][1];
            var sz=segSize(i,len);
            segEls[i].style.width=sz+'px';
            segEls[i].style.height=sz+'px';
            segEls[i].style.transform='translate('+(x*cs+((cs-sz)/2))+'px,'+(y*cs+((cs-sz)/2))+'px)';
          } else {
            segEls[i].style.display='none';
          }
        }
    
        var h=st.snake[0];
        var hx=h[0]*cs, hy=h[1]*cs;
        var ox=(hx+cs*0.5)/cs*100, oy=(hy+cs*0.5)/cs*100;
        var dx=0,dy=0;
        if(st.snake.length>1){ dx=st.snake[0][0]-st.snake[1][0]; dy=st.snake[0][1]-st.snake[1][1]; }
        var px=-dy*38, py=dx*38, ex=dx*30, ey=dy*30;
        headEls[0].style.left='calc('+ox+'% + '+(px+ex)+'%)';
        headEls[0].style.top ='calc('+oy+'% + '+(py+ey)+'%)';
        headEls[1].style.left='calc('+ox+'% + '+(-px+ex)+'%)';
        headEles_placeholder:;
        headEls[1].style.top ='calc('+oy+'% + '+(-py+ey)+'%)';
    
        foodEl.style.width=cs+'px';
        foodEl.style.height=cs+'px';
        foodEl.style.transform='translate('+(st.food[0]*cs)+'px,'+(st.food[1]*cs)+'px)';
    
        if(st.score!==prevScore){
          scoreEl.textContent=st.score;
          scoreEl.animate([{transform:'scale(1.45)',color:'#7ff0b8'},{transform:'scale(1)',color:''}],{duration:320,easing:'ease-out'});
        }
      }
    
      function flashCell(x,y){
        var el=cellEls[y*N+x];
        if(el) el.animate([{background:'rgba(57,217,138,.4)'},{background:'var(--cell)'}],{duration:360,easing:'ease-out'});
      }
    
      function shake(){
        board.animate([
          {transform:'translate(0,0)'},
          {transform:'translate(-6px,2px)'},{transform:'translate(5px,-3px)'},
          {transform:'translate(-4px,1px)'},{transform:'translate(3px,-2px)'},
          {transform:'translate(0,0)'}
        ],{duration:400,easing:'ease-out'});
      }
    
      // ---- input ----
      function move(d){ if(!game.state().over) game.step(d); afterStep(); }
      var KEY={ArrowUp:'up',ArrowDown:'down',ArrowLeft:'left',ArrowRight:'right'};
      window.addEventListener('keydown',function(e){
        if(KEY[e.key]){ e.preventDefault(); ac(); move(KEY[e.key]); return; }
        if(e.key==='r'||e.key==='R'){ resetGame(); }
      });
    
      document.querySelectorAll('.dk').forEach(function(b){
        b.addEventListener('pointerdown',function(e){ e.preventDefault(); ac(); move(b.dataset.dir); });
      });
    
      function afterStep(){
        var st=game.state();
        render(prevScore, prevFood);
        if(st.over){ gameOver(st.score); }
      }
    
      // ---- lifecycle ----
      var prevScore=0, prevFood=[4,8];
      function resetGame(){
        game.reset();
        prevScore=0; prevFood=[4,8];
        scoreEl.textContent='0';
        startOv.classList.remove('show');
        overOv.classList.remove('show');
        render(0,[4,8]);
      }
      function gameOver(score){
        finalEl.textContent=score;
        overOv.classList.add('show');
        shake();
        beep(150,0.28,'sawtooth',0.07);
        setTimeout(function(){ beep(90,0.34,'sawtooth',0.06); },110);
      }
    
      document.getElementById('startBtn').addEventListener('click',function(){ ac(); resetGame(); });
      document.getElementById('restartBtn').addEventListener('click',function(){ ac(); resetGame(); });
    
      // ---- init + resize ----
      render(0,[4,8]);
      window.addEventListener('resize',function(){ render(prevScore, prevFood); });
    })();
    </script>
    </body>
    </html>
    ```

What it built

Pages and games, as the model wrote them, each in a sandbox. On a computer, click a game and use the arrow keys.

Scored tasks

Summarizing 5 of 5
  • One-sentence summaryPassed

    134 tokens: 102 read, 32 written · 18 s · 22.3 tok/s

    Passes when One sentence of 5 to 30 words saying the library opens earlier (8 a.m.) on weekdays.

    Summarize this in one sentence of at most 30 words.
    
    Starting March 3, the Millbrook Public Library will open at 8 a.m. instead of 10 a.m. on weekdays. The change follows a survey in which 62% of respondents asked for earlier hours. Weekend hours stay the same. The library will hire two part-time staff to cover the extra time, paid for by a state grant.
    Driven by resident demand and funded by a state grant, Millbrook Public Library is extending weekday opening hours to 8 a.m. starting March 3.
  • Meeting notes in three bulletsPassed

    251 tokens: 196 read, 55 written · 3 s · 25.1 tok/s

    Passes when Exactly three bullet points and nothing else, each at most 20 words, covering the launch moving to June 12, the approved marketing budget and Priya owning testing, and leaving out the webhook fix and the coffee machine.

    Summarize these meeting notes as exactly three bullet points, each at most 20 words. Keep only the decisions and ownership changes that matter. Output only the bullet points.
    
    Weekly sync, product team. Present: Priya, Omar, Jules, Sam.
    - Omar reported that the payment provider fixed the webhook bug; no action needed.
    - The launch date moves from June 5 to June 12 because the app store review is slow.
    - Jules showed the new onboarding screens. Everyone liked them. Small copy changes only.
    - The marketing budget of $40,000 was approved by finance on Monday.
    - Priya will own end-to-end testing from now on; Sam hands over the test plan by Friday.
    - Next sync is moved to Thursday at 10:00.
    - Coffee machine on floor 3 is broken again.
    *   Launch date moves to June 12 due to app store review delays.
    *   Priya now owns end-to-end testing; Sam hands over the test plan by Friday.
    *   Finance approved the $40,000 marketing budget.
  • Review sentiment and complaintPassed

    136 tokens: 122 read, 14 written · 1 s · 23.9 tok/s

    Passes when Both lines. Sentiment is mixed: the reviewer loves the battery and sound but is annoyed. The complaint names the charger or support in at most 12 words.

    Read this product review and answer in exactly this format:
    Sentiment: <positive, negative or mixed>
    Complaint: <the main complaint in a few words>
    
    I've used this speaker every day for a month. The battery is honestly amazing, easily two full days, and it sounds far better than its size suggests. But the charger that came in the box stopped working after a week, and support took nine days to reply. I bought a replacement cable myself. Would I buy it again? Probably, but I'm annoyed.
    Sentiment: mixed
    Complaint: defective charger and slow support
  • Faithful summary of a studyPassed

    208 tokens: 137 read, 71 written · 4 s · 24.5 tok/s

    Passes when At most 50 words with the 240 participants, the 12-week length and the 3.1-day result, and nothing the text does not say (no approval, cure, children or recommendation).

    Summarize this in at most 50 words. Keep the key numbers. Do not add anything the text does not say.
    
    In a randomized trial, 240 adults with chronic migraine took either the new drug or a placebo for 12 weeks. Those on the drug had 3.1 fewer headache days per month on average, compared with 1.9 fewer days for placebo. Nausea was the most common side effect, reported by 9% of the drug group. The authors note the trial lasted only 12 weeks and call for longer studies before any recommendation is made.
    In a 12-week randomized trial, 240 adults with chronic migraine took a new drug or placebo. The drug group averaged 3.1 fewer headache days monthly versus 1.9 for placebo. Nausea affected 9% of the drug group. Authors note the short duration and call for longer studies before making recommendations.
  • Action items from an email threadPassed

    265 tokens: 216 read, 49 written · 3 s · 24.9 tok/s

    Passes when Exactly four lines of the form "- owner: action": Dana sends the contract, Luis books the venue, Mei updates the budget sheet, Dana emails the caterer. Tom's declined offer, the logo and the invitations are left out.

    List every action item in this email thread that someone has committed to do, as lines of the form "- <owner>: <action>". Leave out offers that were declined and things that turned out not to be needed. Output only the list.
    
    From: Dana
    Hi all, quick recap of what's still open for the June offsite. I'll send the revised contract to the hotel by Wednesday.
    
    From: Tom
    I can book the venue for the dinner if that helps?
    
    From: Luis
    Thanks Tom, but I'll book the venue myself since I already spoke to them. Also, no need to change the logo on the badges, it's fine as is.
    
    From: Mei
    I'll update the budget sheet with the new hotel price tonight.
    
    From: Dana
    Great. Oh, and I'll email the caterer about the vegetarian options. Tom, could you just double-check the date on the invitations? Actually never mind, I checked them this morning, they're correct.
    
    - Dana: send the revised contract to the hotel by Wednesday
    - Luis: book the venue for the dinner
    - Mei: update the budget sheet with the new hotel price tonight
    - Dana: email the caterer about the vegetarian options
Extracting 5 of 5
  • Fields from an email as JSONPassed

    170 tokens: 120 read, 50 written · 3 s · 25.4 tok/s

    Passes when Only a JSON object with exactly name "Laura Chen", company "Northwind Traders", meeting_date "2025-05-14" and attendees the number 4.

    Extract these fields from the email as a JSON object with exactly these keys: "name" (the sender's full name), "company", "meeting_date" (YYYY-MM-DD) and "attendees" (a number). Output only the JSON.
    
    Hello! This is Laura Chen from Northwind Traders. We'd love to visit your workshop. Could we meet on the 14th of May 2025, any time after lunch? We'll be four people in total, including me. Best, Laura
    {
      "name": "Laura Chen",
      "company": "Northwind Traders",
      "meeting_date": "2025-05-14",
      "attendees": 4
    }
  • Every email address, oncePassed

    170 tokens: 141 read, 29 written · 2 s · 25.9 tok/s

    Passes when Exactly four addresses, one per line, in order: info@harbor-events.org, speakers@harbor-events.org, mia.k@studio-nine.io, accounts@harbor-events.org. "jo at harbor dot org" is not written out in full, and its inbox is closed.

    List every email address written out in full in this text (like name@example.com), one per line, in the order they first appear, without duplicates. Leave out any inbox the text says is closed. Output only the addresses.
    
    Contacts for the conference: write to info@harbor-events.org for general questions, or to speakers@harbor-events.org if you are presenting. Our designer (mia.k@studio-nine.io) made the poster. Billing questions: accounts@harbor-events.org. Again, presenters use speakers@harbor-events.org. Please don't write to jo at harbor dot org, that inbox is closed.
    info@harbor-events.org
    speakers@harbor-events.org
    mia.k@studio-nine.io
    accounts@harbor-events.org
  • A list as CSVPassed

    154 tokens: 100 read, 54 written · 3 s · 25.5 tok/s

    Passes when The header item,qty,price, then the four items with whole-number quantities and prices as plain numbers (no $).

    Convert this shopping list to CSV with the header row item,qty,price. Write prices as plain numbers without a currency sign. Output only the CSV.
    
    Apples - 12 @ $0.50
    Bread loaf - 2 @ $3.25
    Olive oil (1 l) - 1 @ $8.90
    Eggs - 18 @ $0.30
    item,qty,price
    Apples,12,0.50
    Bread loaf,2,3.25
    Olive oil (1 l),1,8.90
    Eggs,18,0.30
  • The real deadlinePassed

    112 tokens: 101 read, 11 written · 1 s · 25.7 tok/s

    Passes when Only 2025-02-07, the extended deadline.

    What is the final submission deadline? Answer with the date only, in YYYY-MM-DD format.
    
    The call for papers opened on 2 January 2025. Drafts were originally due January 20, but the committee extended the final submission deadline to 7 February 2025. Reviews are due by 28 February, and results will be announced on March 10, 2025.
    2025-02-07
  • Warnings and errors from a logPassed

    407 tokens: 278 read, 129 written · 6 s · 26 tok/s

    Passes when Only a JSON array of the WARN line and the two ERROR lines, in order, with time, level and message copied exactly.

    From this log, return a JSON array with one object per WARN or ERROR line, in order, each with the keys "time" (HH:MM:SS), "level" and "message". Output only the JSON.
    
    2025-03-04 09:12:01 INFO  server started on port 8080
    2025-03-04 09:12:07 WARN  config key "timeout" is deprecated
    2025-03-04 09:13:44 INFO  user alice logged in
    2025-03-04 09:15:02 ERROR database connection lost
    2025-03-04 09:15:03 INFO  retrying in 5s
    2025-03-04 09:15:08 INFO  database reconnected
    2025-03-04 09:20:30 DEBUG cache hit ratio 0.93
    2025-03-04 09:31:12 ERROR payment webhook returned 502
    [
      {
        "time": "09:12:07",
        "level": "WARN",
        "message": "config key \"timeout\" is deprecated"
      },
      {
        "time": "09:15:02",
        "level": "ERROR",
        "message": "database connection lost"
      },
      {
        "time": "09:31:12",
        "level": "ERROR",
        "message": "payment webhook returned 502"
      }
    ]
Following instructions 5 of 5
  • Exactly one wordPassed

    24 tokens: 22 read, 2 written · 0 s · 12.4 tok/s

    Passes when Exactly OK, with nothing else, not even a full stop.

    Reply with exactly the word OK and nothing else.
    OK
  • Three lowercase linesPassed

    66 tokens: 44 read, 22 written · 2 s · 19.5 tok/s

    Passes when Exactly three lines about the sea, all lowercase, the third ending with a question mark.

    Write exactly three lines about the sea. Every line must be entirely lowercase, and the third line must end with a question mark. Output only the three lines.
    the waves crash against the shore
    salt air fills the heavy wind
    why does it never stop moving?
  • Exact JSON shapePassed

    73 tokens: 48 read, 25 written · 1 s · 25.8 tok/s

    Passes when Only JSON with exactly two keys: colors (three lowercase color names) and count (the number 3).

    Return a JSON object with exactly two keys: "colors", a list of exactly three color names in lowercase, and "count", the number 3. Output only the JSON.
    {
      "colors": ["red", "green", "blue"],
      "count": 3
    }
  • Sort a listPassed

    52 tokens: 41 read, 11 written · 1 s · 25.7 tok/s

    Passes when One line: apple, apricot, banana, cherry, pear (any capitalization).

    Sort these words alphabetically, ignoring case, and output them on one line separated by commas: pear, Apple, banana, cherry, apricot
    apple, apricot, banana, cherry, pear
  • A name with three rulesPassed

    51 tokens: 48 read, 3 written · 1 s · 12.7 tok/s

    Passes when Two words, both capitalized, with no letter e anywhere.

    Suggest a product name for a solar-powered lamp. Rules: exactly two words, both capitalized, and the letter "e" must not appear anywhere. Output only the name.
    Solar Lamp
Reasoning 5 of 5
  • Unit pricePassed

    203 tokens: 53 read, 150 written · 6 s · 25.5 tok/s

    A shop sells pencils at 4 for $1.60. How much do 9 pencils cost, in dollars? Work it out, then end with a line "ANSWER: <number>".
    To find the cost of 9 pencils, we first need to determine the price of a single pencil.
    
    1.  **Calculate the cost per pencil:**
        The shop sells 4 pencils for $\$1.60$.
        $$ \text{Cost per pencil} = \frac{\$1.60}{4} = \$0.40 $$
    
    2.  **Calculate the cost of 9 pencils:**
        Multiply the cost per pencil by the number of pencils needed.
        $$ \text{Total Cost} = 9 \times \$0.40 $$
        $$ \text{Total Cost} = \$3.60 $$
    
    ANSWER: 3.60
  • Days of the weekPassed

    386 tokens: 48 read, 338 written · 14 s · 24.1 tok/s

    Today is Monday. What day of the week will it be 329 days from today? Work it out, then end with a line "ANSWER: <day>".
    To determine the day of the week 329 days from today (Monday), we can use modular arithmetic because the days of the week repeat in a cycle of 7.
    
    **Step 1: Determine the remainder when dividing the number of days by 7.**
    We need to find $329 \pmod{7}$.
    
    $$329 \div 7 = 46 \text{ with a remainder of } 7?$$
    Let's check:
    $40 \times 7 = 280$
    $329 - 280 = 49$
    $49 \div 7 = 7$
    
    So, $46 + 7 = 53$.
    $53 \times 7 = 371$? No, let's re-calculate directly.
    
    $$329 / 7 = 47$$
    Let's verify:
    $$47 \times 7 = (40 \times 7) + (7 \times 7) = 280 + 49 = 329$$
    
    Since $329$ is perfectly divisible by $7$, the remainder is $0$.
    
    **Step 2: Interpret the result.**
    A remainder of $0$ means that 329 days is exactly an integer number of weeks ($47$ weeks). Therefore, the day of the week will be the same as it is today.
    
    Today is Monday.
    Therefore, 329 days from today will also be a Monday.
    
    ANSWER: Monday
  • Who owns the catPassed

    378 tokens: 68 read, 310 written · 13 s · 24.6 tok/s

    Ben, Gus and Hal each own exactly one pet: a cat, a dog or a fish, all different. Hal does not own the dog. Gus owns the fish. Who owns the cat? Work it out, then end with a line "ANSWER: <name>".
    Here is the step-by-step logical deduction to determine who owns the cat:
    
    1.  **Identify the people and pets:**
        *   People: Ben, Gus, Hal
        *   Pets: Cat, Dog, Fish
        *   Constraint: Each person owns exactly one pet, and all pets are different.
    
    2.  **Analyze the given facts:**
        *   Fact 1: Gus owns the fish.
        *   Fact 2: Hal does not own the dog.
    
    3.  **Deduction:**
        *   Since Gus owns the fish, neither Ben nor Hal can own the fish.
        *   The remaining pets to be assigned are the Cat and the Dog.
        *   The remaining people to assign pets to are Ben and Hal.
        *   We know Hal does not own the dog (Fact 2). Therefore, Hal must own the other remaining pet, which is the **cat**.
        *   This leaves Ben with the last remaining pet, which is the **dog**.
    
    4.  **Verification:**
        *   Gus: Fish (Given)
        *   Hal: Cat (Derived from "not dog" and "fish taken")
        *   Ben: Dog (Remaining option)
        *   All pets are unique? Yes (Fish, Cat, Dog).
        *   Does Hal own the dog? No.
    
    Therefore, Hal owns the cat.
    
    ANSWER: Hal
  • Arrival timePassed

    299 tokens: 66 read, 233 written · 10 s · 25 tok/s

    A train leaves at 07:05 and the trip takes 5 hours 40 minutes. At what time does it arrive? Work it out, then end with a line "ANSWER: <HH:MM>" in 24-hour time.
    To determine the arrival time, we need to add the duration of the trip to the departure time.
    
    **1. Identify the given values:**
    *   Departure Time: 07:05
    *   Duration: 5 hours 40 minutes
    
    **2. Add the hours and minutes separately:**
    
    *   **Minutes:** $5 \text{ minutes} + 40 \text{ minutes} = 45 \text{ minutes}$
    *   **Hours:** $7 \text{ hours} + 5 \text{ hours} = 12 \text{ hours}$
    
    **3. Combine the results:**
    Since the total minutes (45) are less than 60, no additional hour needs to be carried over.
    
    *   Arrival Time: 12:45
    
    **Verification:**
    *   Start at 07:05.
    *   Add 5 hours $\rightarrow$ 12:05.
    *   Add 40 minutes $\rightarrow$ 12:45.
    
    ANSWER: 12:45
  • Filling a tankPassed

    762 tokens: 91 read, 671 written · 27 s · 25.2 tok/s

    A tank holds 120 liters. Pipe A alone fills it in 3 hours, pipe B alone fills it in 10 hours, and a drain alone empties a full tank in 10 hours. With all three open and the tank starting empty, how many hours until it is full? Work it out, then end with a line "ANSWER: <number>".
    To determine how long it takes to fill the tank, we need to calculate the net rate at which the tank is being filled when all three pipes (Pipe A, Pipe B, and the drain) are open simultaneously.
    
    **Step 1: Determine the individual rates of each pipe.**
    
    *   **Pipe A:** Fills the tank in 3 hours.
        Rate of A = $\frac{1 \text{ tank}}{3 \text{ hours}} = \frac{1}{3}$ tanks per hour.
    
    *   **Pipe B:** Fills the tank in 10 hours.
        Rate of B = $\frac{1 \text{ tank}}{10 \text{ hours}} = \frac{1}{10}$ tanks per hour.
    
    *   **Drain:** Empties the tank in 10 hours. Since it removes water, its rate is negative relative to filling.
        Rate of Drain = $-\frac{1 \text{ tank}}{10 \text{ hours}} = -\frac{1}{10}$ tanks per hour.
    
    *Note: The total volume of the tank (120 liters) is not strictly necessary for calculating the time, as we are working with fractions of the total capacity, but it confirms the context.*
    
    **Step 2: Calculate the combined net rate.**
    
    When all three are open, the net rate ($R_{net}$) is the sum of the individual rates:
    
    $$ R_{net} = \text{Rate}_A + \text{Rate}_B + \text{Rate}_{\text{Drain}} $$
    $$ R_{net} = \frac{1}{3} + \frac{1}{10} - \frac{1}{10} $$
    
    Notice that the rate of Pipe B and the rate of the Drain cancel each other out because they have equal magnitudes but opposite effects (one fills at 1/10, the other empties at 1/10).
    
    $$ R_{net} = \frac{1}{3} + 0 $$
    $$ R_{net} = \frac{1}{3} \text{ tanks per hour} $$
    
    **Step 3: Calculate the time required to fill the tank.**
    
    The time ($T$) required to fill one full tank is the reciprocal of the net rate:
    
    $$ T = \frac{1}{R_{net}} $$
    $$ T = \frac{1}{1/3} $$
    $$ T = 3 \text{ hours} $$
    
    **Verification:**
    In 3 hours:
    *   Pipe A fills: $3 \times \frac{120}{3} = 120$ liters.
    *   Pipe B fills: $3 \times \frac{120}{10} = 36$ liters.
    *   Drain empties: $3 \times \frac{120}{10} = 36$ liters.
    *   Net change: $120 + 36 - 36 = 120$ liters.
    The tank is full.
    
    ANSWER: 3
Reading code 4 of 4
  • What does it printPassed

    473 tokens: 78 read, 395 written · 16 s · 25.2 tok/s

    What does this Python program print? Work it out, then end with a line "ANSWER: <output>".
    
    def f(xs):
        return sorted(xs)[::-1][:3]
    
    print(f([20, 29, 37, 18, 11, 31]))
    Let's trace through the execution of this Python program step by step.
    
    1. **Function Definition**:
       The function `f(xs)` takes a list `xs` as input.
       - `sorted(xs)`: This creates a new list with the elements of `xs` sorted in ascending order.
       - `[::-1]`: This slices the sorted list to reverse it, resulting in a list sorted in descending order.
       - `[:3]`: This takes the first three elements of the reversed (descending) list.
       - The function returns this sublist of the top 3 largest elements.
    
    2. **Function Call**:
       `print(f([20, 29, 37, 18, 11, 31]))` is called with the list `[20, 29, 37, 18, 11, 31]`.
    
    3. **Step-by-Step Execution inside `f`**:
       - Input `xs = [20, 29, 37, 18, 11, 31]`
       - `sorted(xs)`: Sorting the list in ascending order gives `[11, 18, 20, 29, 31, 37]`.
       - `[::-1]`: Reversing this list gives `[37, 31, 29, 20, 18, 11]`.
       - `[:3]`: Taking the first three elements gives `[37, 31, 29]`.
    
    4. **Output**:
       The function returns `[37, 31, 29]`, and `print` outputs this list.
    
    ANSWER: [37, 31, 29]
  • Trace a loopPassed

    1,223 tokens: 95 read, 1,128 written · 46 s · 25.1 tok/s

    What does this Python program print? Work it out, then end with a line "ANSWER: <output>".
    
    def g(n):
        total = 0
        for i in range(1, n + 1):
            if i % 2 == 0 or i % 7 == 0:
                total += i
        return total
    
    print(g(22))
    To determine what the program prints, we need to analyze the function `g(n)` and calculate its result for `n = 22`.
    
    **1. Analysis of the Function `g(n)`**
    
    The function `g(n)` iterates through integers from `1` to `n` (inclusive). For each integer `i`, it checks if:
    - `i` is even (`i % 2 == 0`), OR
    - `i` is a multiple of 7 (`i % 7 == 0`).
    
    If either condition is true, the value of `i` is added to `total`. Finally, it returns `total`.
    
    So, we need to find the sum of all integers between 1 and 22 that are either even or divisible by 7.
    
    **2. Identifying the Numbers**
    
    Let's list the numbers from 1 to 22 that satisfy the condition:
    
    *   **Even numbers (divisible by 2):**
        2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22
    
    *   **Multiples of 7:**
        7, 14, 21
    
    Now, we combine these lists and remove duplicates. Note that `14` appears in both lists (it is even and a multiple of 7). We must only add it once.
    
    The unique set of numbers to sum is:
    {2, 4, 6, 7, 8, 10, 12, 14, 16, 18, 20, 21, 22}
    
    **3. Calculating the Sum**
    
    Let's sum these numbers step-by-step or in groups:
    
    *   Even numbers: $2 + 4 + 6 + 8 + 10 + 12 + 14 + 16 + 18 + 20 + 22$
        This is an arithmetic progression.
        Sum = $\frac{11}{2} \times (2 + 22) = 5.5 \times 24 = 132$.
    
    *   Multiples of 7 not already included in the even sum:
        The multiples of 7 are 7, 14, 21.
        14 is already included in the even sum.
        So we add 7 and 21.
        Additional sum = $7 + 21 = 28$.
    
    *   Total Sum = (Sum of evens) + (Additional multiples of 7)
        Total Sum = $132 + 28$
    
    Let's double-check by summing the individual list:
    $2 + 4 = 6$
    $6 + 6 = 12$
    $12 + 7 = 19$
    $19 + 8 = 27$
    $27 + 10 = 37$
    $37 + 12 = 49$
    $49 + 14 = 63$
    $63 + 16 = 79$
    $79 + 18 = 97$
    $97 + 20 = 117$
    $117 + 21 = 138$
    $138 + 22 = 160$
    
    Wait, let me re-calculate the sum of evens.
    Evens: 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22.
    Count = 11 numbers.
    Sum = $\frac{11}{2}(2+22) = \frac{11}{2}(24) = 11 \times 12 = 132$. Correct.
    
    Multiples of 7: 7, 14, 21.
    14 is already in the evens.
    So we add 7 and 21.
    $7 + 21 = 28$.
    
    Total = $132 + 28 = 160$.
    
    Let's re-verify the manual addition:
    2, 4, 6, 7, 8, 10, 12, 14, 16, 18, 20, 21, 22
    
    Group by tens:
    $2+4+6+7+8+10 = 37$
    $12+14+16+18+20 = 80$
    $21+22 = 43$
    
    $37 + 80 + 43$
    $37 + 43 = 80$
    $80 + 80 = 160$
    
    The calculation is consistent.
    
    **Conclusion**
    
    The function `g(22)` returns 160. The program prints this value.
    
    ANSWER: 160
  • Find the bugPassed

    480 tokens: 108 read, 372 written · 16 s · 24.4 tok/s

    Passes when A final line ANSWER: 6 (it divides by one less than the count).

    This function should return the mean of a non-empty list. Which line has the bug? Work it out, then end with a line "ANSWER: <line number>".
    
    1  def average(numbers):
    2      """Return the mean of a non-empty list of numbers."""
    3      total = 0
    4      for n in numbers:
    5          total += n
    6      count = len(numbers) - 1
    7      return total / count
    To determine which line contains the bug, let's analyze the function step by step.
    
    The goal of the function `average` is to calculate the mean (arithmetic average) of a non-empty list of numbers. The formula for the mean is:
    $$ \text{Mean} = \frac{\text{Sum of elements}}{\text{Number of elements}} $$
    
    Let's look at the code execution:
    
    1.  **Line 1**: `def average(numbers):` - Defines the function. Correct.
    2.  **Line 2**: Docstring. Correct.
    3.  **Line 3**: `total = 0` - Initializes a variable to store the sum. Correct.
    4.  **Line 4**: `for n in numbers:` - Iterates through each element in the list. Correct.
    5.  **Line 5**: `total += n` - Adds each element to the total sum. Correct. After this loop, `total` holds the sum of all elements.
    6.  **Line 6**: `count = len(numbers) - 1` - Calculates the count of elements. However, it subtracts 1 from the length. The number of elements in a list is simply `len(numbers)`. Subtracting 1 results in an incorrect denominator (off-by-one error). For example, if the list has 5 numbers, `count` becomes 4 instead of 5.
    7.  **Line 7**: `return total / count` - Divides the sum by the count. Since `count` is incorrect due to Line 6, the result will be wrong.
    
    Therefore, the bug is on Line 6, where it should be `count = len(numbers)`.
    
    ANSWER: 6
  • Run a query in your headPassed

    157 tokens: 145 read, 12 written · 2 s · 23.5 tok/s

    What rows does this SQL query return? Output only the rows, one per line, as customer,total in the query's order.
    
    Table orders:
    id | customer | amount
    1  | cal      | 55
    2  | cal      | 90
    3  | ana      | 45
    4  | ben      | 115
    5  | ana      | 25
    6  | ben      | 60
    
    Query:
    SELECT customer, SUM(amount) AS total
    FROM orders
    GROUP BY customer
    HAVING SUM(amount) > 100
    ORDER BY total DESC;
    ben,175
    cal,145
Using tools 5 of 5
  • Call one toolPassed

    768 tokens: 711 read, 57 written · 4 s · 25.4 tok/s

    Passes when One get_weather call for Lisbon in celsius, then an answer giving the 21 °C the tool returned.

    What's the weather in Lisbon right now, in celsius?
    1. user
      What's the weather in Lisbon right now, in celsius?
    2. assistant
      get_weather({"city":"Lisbon","unit":"celsius"})
    3. tool
      {"city": "Lisbon", "conditions": "sunny", "temperature": 21, "unit": "celsius"}
    4. assistant
      It's currently sunny in Lisbon with a temperature of 21°C.
  • Don't call a tool when none is neededPassed

    432 tokens: 419 read, 13 written · 3 s · 22.1 tok/s

    Passes when No tool call, and the answer is 144.

    What is 12 times 12?
    1. user
      What is 12 times 12?
    2. assistant
      12 × 12 = **144**
  • Two calls for two answersPassed

    992 tokens: 834 read, 158 written · 8 s · 26 tok/s

    Passes when Converts 250 EUR to USD and to JPY in at most three calls, then gives both amounts: 270.50 USD and 40,125 JPY.

    Convert 250 EUR to USD and to JPY.
    1. user
      Convert 250 EUR to USD and to JPY.
    2. assistant
      convert_currency({"amount":250,"from":"EUR","to":"USD"})
      convert_currency({"amount":250,"from":"EUR","to":"JPY"})
    3. tool
      {"amount": 270.5, "currency": "USD"}
    4. tool
      {"amount": 40125, "currency": "JPY"}
    5. assistant
      Here are the conversions for 250 EUR at today's rates:
      
      - **250 EUR ≈ 270.50 USD**
      - **250 EUR ≈ 40,125 JPY**
  • Chain two toolsPassed

    1,368 tokens: 1,266 read, 102 written · 6 s · 25.1 tok/s

    Passes when Looks up the customer first, asks for C-1042's orders, then reports A-77 shipped and A-80 processing.

    What is the status of each order for the customer with the email kim@example.com?
    1. user
      What is the status of each order for the customer with the email kim@example.com?
    2. assistant
      find_customer({"email":"kim@example.com"})
    3. tool
      {"customer_id": "C-1042", "name": "Kim Park"}
    4. assistant
      get_orders({"customer_id":"C-1042"})
    5. tool
      {"orders": [{"carrier": "DHL", "order_id": "A-77", "status": "shipped"}, {"order_id": "A-80", "status": "processing"}]}
    6. assistant
      Kim Park (C-1042) has two orders:
      
      - **Order A-77** — Shipped (carrier: DHL)
      - **Order A-80** — Processing
  • Handle a failed call honestlyPassed

    870 tokens: 749 read, 121 written · 7 s · 25.3 tok/s

    Passes when Tries 19:00 for 2 people, never books another time without asking, does not claim the booking succeeded, and offers 18:30 or 20:30.

    Book a table for 2 people at Luigi's tonight at 19:00.
    1. user
      Book a table for 2 people at Luigi's tonight at 19:00.
    2. assistant
      book_table({"restaurant":"Luigi's","people":2,"time":"19:00"})
    3. tool
      {"available_times": ["18:30", "20:30"], "error": "fully booked at that time"}
    4. assistant
      I couldn't book a table for 2 at Luigi's tonight at 19:00 — that time is fully booked.
      
      The nearest available times are:
      - **18:30**
      - **20:30**
      
      Would you like me to book one of those instead?
Building pages 4 of 5
  • A small websitePassed

    8,105 tokens: 123 read, 7,982 written · 5 min 30 s · 24.2 tok/s

    Passes when A <header> with an <h1> naming the bakery, a <nav> with exactly 3 links, a <main> with <section id="menu"> holding at least 4 list items, and a <footer> with opening hours. Nothing loaded from another site and no network requests.

    Build a one-page website for a bakery called "Crumb & Co". It must have a <header> containing an <h1> with the bakery's name; a <nav> with exactly 3 links; a <main> with a <section id="menu"> listing at least 4 items in a list; and a <footer> with the opening hours. Output one complete HTML document and nothing else. Put all CSS and JavaScript inline. Do not load anything from another site: no external scripts, stylesheets, fonts or images.

    Open the page on its own. It runs in a sandbox: no network, no access to this site.

    Page source
    ```html
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Crumb &amp; Co — Baked Daily</title>
    <style>
      :root{
        --paper:#f4e7d2;
        --paper-2:#efe0c6;
        --card:#fbf3e3;
        --ink:#2a1d15;
        --ink-soft:#5a4636;
        --crust:#b5651d;
        --berry:#7c2f3d;
        --honey:#c98a2b;
        --line:rgba(42,29,21,.16);
        --shadow:0 22px 45px -22px rgba(42,29,21,.55);
      }
    
      *{box-sizing:border-box}
      html{scroll-behavior:smooth}
      body{
        margin:0;
        font-family:"Iowan Old Style","Palatino Linotype",Palatino,"Book Antiqua",Georgia,serif;
        color:var(--ink);
        background-color:var(--paper);
        line-height:1.6;
        -webkit-font-smoothing:antialiased;
        overflow-x:hidden;
      }
    
      /* ---------- ambient background ---------- */
      .bg{position:fixed;inset:0;z-index:-2;background:radial-gradient(125% 95% at 50% -8%,#f7ecd6,#ead6b4)}
      .grain{
        position:fixed;inset:0;z-index:-1;pointer-events:none;opacity:.05;mix-blend-mode:multiply;
        background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
      }
    
      .wrap{max-width:1180px;margin:0 auto;padding:0 clamp(1.1rem,4vw,2.6rem)}
    
      /* ---------- header ---------- */
      .site-head{position:relative}
      .topbar{
        display:flex;justify-content:space-between;align-items:center;gap:1rem;flex-wrap:wrap;
        padding:.75rem clamp(1.1rem,4vw,2.6rem);border-bottom:1px solid var(--line);font-size:.8rem;letter-spacing:.04em;color:var(--ink-soft)
      }
      .topbar b{color:var(--berry);font-weight:700}
      .ticker{overflow:hidden;border-bottom:1px solid var(--line);background:var(--paper-2)}
      .ticker-track{display:inline-flex;white-space:nowrap;padding:.5rem 0;animation:slide 34s linear infinite;font-size:.78rem;letter-spacing:.2em;text-transform:uppercase;color:var(--crust)}
      .ticker-track span{padding:0 1.6rem}
      @keyframes slide{from{transform:translateX(0)}to{transform:translateX(-50%)}}
    
      nav{position:sticky;top:0;z-index:40;background:var(--paper);border-bottom:1px solid var(--line);backdrop-filter:saturate(1.2) blur(3px)}
      .nav-inner{display:flex;align-items:center;justify-content:space-between;padding:.7rem clamp(1.1rem,4vw,2.6rem)}
      .brand{font-weight:800;font-size:1.15rem;letter-spacing:.01em}
      .brand small{color:var(--berry);font-weight:700}
      .nav-links{display:flex;gap:clamp(1rem,3vw,2.2rem)}
      .nav-links a{position:relative;text-decoration:none;color:var(--ink);font-size:.95rem;padding:.3rem 0;letter-spacing:.02em}
      .nav-links a::after{content:"";position:absolute;left:0;bottom:-2px;height:2px;width:100%;background:var(--berry);transform:scaleX(0);transform-origin:right;transition:transform .4s cubic-bezier(.2,.7,.2,1)}
      .nav-links a:hover::after{transform:scaleX(1);transform-origin:left}
    
      /* ---------- hero (masthead) ---------- */
      .hero{position:relative;padding:clamp(3rem,8vw,6rem) 0 clamp(2.5rem,6vw,4rem)}
      .hero-grid{display:grid;grid-template-columns:1.1fr .9fr;gap:clamp(1.5rem,4vw,3rem);align-items:center}
      .kicker{font-size:.78rem;letter-spacing:.32em;text-transform:uppercase;color:var(--crust);margin:0 0 1rem}
      h1{
        font-size:clamp(3.6rem,15vw,9.5rem);line-height:.86;margin:0;font-weight:800;letter-spacing:-.02em;
        animation:rise .9s cubic-bezier(.2,.7,.2,1) both
      }
      h1 .amp{display:inline-block;color:var(--berry);font-style:italic;font-weight:600}
      .lede{max-width:34ch;margin:1.4rem 0 0;font-size:clamp(1.05rem,2vw,1.3rem);color:var(--ink-soft)}
      .stamp{
        display:inline-flex;align-items:center;gap:.5rem;margin-top:1.6rem;padding:.5rem .9rem;border:1px solid var(--line);
        border-radius:999px;font-size:.82rem;letter-spacing:.03em;background:var(--card)
      }
      .stamp .dot{width:.6rem;height:.6rem;border-radius:50%;background:var(--honey);box-shadow:0 0 0 4px rgba(201,138,43,.2)}
    
      .hero-art{position:relative;display:flex;justify-content:center}
      .loaf{width:min(360px,80%);height:auto;filter:drop-shadow(0 24px 26px rgba(42,29,21,.28));animation:bob 5s ease-in-out infinite}
      @keyframes bob{0%,100%{transform:translateY(0) rotate(-1deg)}50%{transform:translateY(-12px) rotate(1deg)}}
      .crumb-bit{position:absolute;width:9px;height:9px;border-radius:50%;background:var(--honey);opacity:.7;animation:float 6s ease-in-out infinite}
      .cb1{top:14%;left:8%;animation-delay:.2s}
      .cb2{top:30%;right:6%;width:6px;height:6px;background:var(--berry);animation-delay:1.1s}
      .cb3{bottom:18%;left:14%;width:7px;height:7px;animation-delay:2s}
      @keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-16px)}}
    
      /* ---------- section headings ---------- */
      .sec-head{display:flex;align-items:baseline;gap:1rem;margin-bottom:2.2rem}
      .sec-head h2{font-size:clamp(2rem,5vw,3.4rem);margin:0;line-height:1;font-weight:800;letter-spacing:-.01em}
      .rule{flex:1;height:1px;background:var(--line);transform:translateY(-.35em)}
      .sec-tag{font-size:.78rem;letter-spacing:.24em;text-transform:uppercase;color:var(--crust);white-space:nowrap}
    
      section{padding:clamp(3rem,7vw,5.5rem) 0}
    
      /* ---------- menu ---------- */
      #menu .lead{max-width:52ch;margin:-1rem 0 2.4rem;color:var(--ink-soft);font-size:1.08rem}
      .menu-list{list-style:none;margin:0;padding:0;display:grid;gap:1px;background:var(--line);border:1px solid var(--line)}
      .item{
        background:var(--card);padding:1.5rem clamp(1.2rem,3vw,2rem);display:grid;
        grid-template-columns:auto 1fr auto;gap:1.4rem;align-items:center;position:relative;overflow:hidden;
        transition:transform .4s cubic-bezier(.2,.7,.2,1),box-shadow .4s;
      }
      .item::before{content:"";position:absolute;left:0;top:0;bottom:0;width:4px;background:var(--berry);transform:scaleY(0);transform-origin:top;transition:transform .45s cubic-bezier(.2,.7,.2,1)}
      .item:hover{transform:translateX(8px);box-shadow:var(--shadow)}
      .item:hover::before{transform:scaleY(1)}
      .item-num{font-size:.9rem;color:var(--crust);letter-spacing:.1em;font-variant-numeric:tabular-nums}
      .item-body h3{margin:0 0 .25rem;font-size:clamp(1.25rem,2.4vw,1.7rem);font-weight:700;display:flex;align-items:center;gap:.6rem;flex-wrap:wrap}
      .tag{font-size:.68rem;letter-spacing:.14em;text-transform:uppercase;color:var(--berry);border:1px solid var(--berry);border-radius:999px;padding:.15rem .55rem;font-weight:700}
      .item-body p{margin:0;color:var(--ink-soft);max-width:46ch}
      .price{font-size:clamp(1.3rem,2.6vw,1.8rem);font-weight:800;white-space:nowrap;font-variant-numeric:tabular-nums}
    
      /* ---------- today (sticky two-column) ---------- */
      #today .two-col{display:grid;grid-template-columns:.9fr 1.1fr;gap:clamp(1.5rem,4vw,3rem);align-items:start}
      .sticky-col{position:sticky;top:6rem}
      .big-num{font-size:clamp(3rem,8vw,5rem);font-weight:800;line-height:.9;color:var(--berry)}
      .sticky-col p{color:var(--ink-soft);max-width:32ch;margin-top:1rem}
      .recipe{display:grid;gap:1px;background:var(--line);border:1px solid var(--line)}
      .recipe-card{background:var(--card);padding:1.6rem clamp(1.2rem,3vw,2rem)}
      .recipe-card h3{margin:0 0 .35rem;font-size:1.4rem}
      .recipe-card .time{font-size:.78rem;letter-spacing:.16em;text-transform:uppercase;color:var(--crust)}
      .recipe-card p{margin:.6rem 0 0;color:var(--ink-soft)}
    
      /* ---------- story (scattered postcards) ---------- */
      #story .board{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:1.4rem;margin-top:1rem}
      .postcard{
        background:var(--card);border:1px solid var(--line);padding:1.6rem 1.5rem;box-shadow:var(--shadow);
        transition:transform .4s cubic-bezier(.2,.7,.2,1),box-shadow .4s;position:relative;
      }
      .postcard:nth-child(odd){transform:rotate(-1.6deg)}
      .postcard:nth-child(even){transform:rotate(1.8deg)}
      .postcard:hover{transform:rotate(0) translateY(-6px);box-shadow:0 30px 50px -24px rgba(42,29,21,.6);z-index:2}
      .postcard .yr{font-size:.8rem;letter-spacing:.2em;color:var(--crust)}
      .postcard h3{margin:.5rem 0 .5rem;font-size:1.35rem}
      .postcard p{margin:0;color:var(--ink-soft);font-size:.98rem}
    
      /* ---------- quote band ---------- */
      .quote-band{background:var(--berry);color:#f6e7d4;padding:clamp(3rem,7vw,5rem) 0}
      .quote-band blockquote{margin:0;max-width:22ch;font-size:clamp(1.8rem,5vw,3.2rem);line-height:1.15;font-style:italic;font-weight:600}
      .quote-band cite{display:block;margin-top:1.4rem;font-style:normal;font-size:.9rem;letter-spacing:.14em;text-transform:uppercase;opacity:.8}
    
      /* ---------- footer / hours ---------- */
      footer{background:#241a13;color:#e9d8c0;padding:clamp(3rem,6vw,4.5rem) 0 2rem}
      .foot-grid{display:grid;grid-template-columns:1.2fr 1fr;gap:2.5rem;align-items:start}
      footer h2{font-size:clamp(2rem,5vw,3rem);margin:0 0 .4rem;color:#f6e7d4;font-weight:800}
      .foot-sub{color:#c9b193;margin:0 0 1.6rem;max-width:34ch}
      .hours{list-style:none;margin:0;padding:0;border-top:1px solid rgba(255,255,255,.12)}
      .hours li{display:flex;justify-content:space-between;gap:1rem;padding:.7rem 0;border-bottom:1px solid rgba(255,255,255,.12);font-variant-numeric:tabular-nums}
      .hours li span:last-child{text-align:right;color:#f6e7d4;font-weight:600}
      .foot-note{margin-top:1.4rem;font-size:.9rem;color:#c9b193}
      .colophon{display:flex;justify-content:space-between;flex-wrap:wrap;gap:.8rem;margin-top:2.5rem;padding-top:1.2rem;border-top:1px solid rgba(255,255,255,.12);font-size:.8rem;color:#b49a7d}
    
      /* ---------- reveal ---------- */
      .reveal{opacity:0;transform:translateY(26px);transition:opacity .7s ease,transform .7s cubic-bezier(.2,.7,.2,1)}
      .reveal.in{opacity:1;transform:none}
      @keyframes rise{from{opacity:0;transform:translateY(34px)}to{opacity:1;transform:none}}
    
      /* ---------- responsive ---------- */
      @media (max-width:860px){
        .hero-grid{grid-template-columns:1fr;text-align:left}
        .hero-art{order:-1;margin-bottom:.5rem}
        #today .two-col{grid-template-columns:1fr}
        .sticky-col{position:static}
        .foot-grid{grid-template-columns:1fr}
      }
      @media (max-width:520px){
        .item{grid-template-columns:auto 1fr;gap:.8rem 1rem}
        .price{grid-column:2;justify-self:start;font-size:1.3rem;margin-top:.2rem}
        .nav-links{gap:1.1rem}
      }
    
      @media (prefers-reduced-motion:reduce){
        *{animation:none!important;transition:none!important}
        .reveal{opacity:1;transform:none}
        html{scroll-behavior:auto}
      }
    </style>
    </head>
    <body>
    <div class="bg"></div>
    <div class="grain"></div>
    
    <header class="site-head">
      <div class="topbar">
        <span>Bakery &amp; Patisserie · Est. 1987</span>
        <span><b id="status">Baking now</b> · Open until 6:00 pm</span>
      </div>
    
      <nav aria-label="Primary">
        <div class="nav-inner">
          <span class="brand">Crumb &amp; Co<small>.</small></span>
          <div class="nav-links">
            <a href="#menu">Menu</a>
            <a href="#today">Today’s Bake</a>
            <a href="#story">Our Story</a>
          </div>
        </div>
      </nav>
    
      <div class="ticker" aria-hidden="true">
        <div class="ticker-track">
          <span>Sourdough · Croissants · Baguettes · Rye · Focaccia · Cinnamon Rolls</span>
          <span>Sourdough · Croissants · Baguettes · Rye · Focaccia · Cinnamon Rolls</span>
        </div>
      </div>
    
      <div class="hero">
        <div class="wrap hero-grid">
          <div>
            <p class="kicker">Baked before the sun is up</p>
            <h1>Crumb <span class="amp">&amp;</span> Co.</h1>
            <p class="lede">A neighbourhood bakery where every loaf begins with a starter we’ve kept alive for thirty-seven years — slow-fermented, hand-shaped, and pulled from the oven while it still crackles.</p>
            <span class="stamp"><span class="dot"></span> Stone-milled flour · No shortcuts</span>
          </div>
          <div class="hero-art">
            <span class="crumb-bit cb1"></span>
            <span class="crumb-bit cb2"></span>
            <span class="crumb-bit cb3"></span>
            <svg class="loaf" viewBox="0 0 340 260" role="img" aria-label="A golden sourdough loaf with score marks">
              <defs>
                <linearGradient id="crust" x1="0" y1="0" x2="0" y2="1">
                  <stop offset="0" stop-color="#e3a95f"/>
                  <stop offset=".55" stop-color="#c87f34"/>
                  <stop offset="1" stop-color="#9d5a1e"/>
                </linearGradient>
                <radialGradient id="shine" cx=".35" cy=".25" r=".6">
                  <stop offset="0" stop-color="#fff2d8" stop-opacity=".85"/>
                  <stop offset="1" stop-color="#fff2d8" stop-opacity="0"/>
                </radialGradient>
              </defs>
              <ellipse cx="170" cy="236" rx="140" ry="18" fill="#2a1d15" opacity=".14"/>
              <path d="M30 210 C20 120 90 70 170 70 C250 70 320 120 310 210 C308 224 292 232 276 232 L64 232 C48 232 32 224 30 210 Z" fill="url(#crust)"/>
              <path d="M30 210 C20 120 90 70 170 70 C250 70 320 120 310 210 C308 224 292 232 276 232 L64 232 C48 232 32 224 30 210 Z" fill="url(#shine)"/>
              <g stroke="#5e3611" stroke-width="7" stroke-linecap="round" opacity=".85">
                <path d="M96 118 C120 104 150 100 178 108"/>
                <path d="M150 138 C180 124 214 122 244 134"/>
                <path d="M104 168 C134 154 172 152 206 162"/>
              </g>
              <g fill="#f7e9cf" opacity=".8">
                <circle cx="120" cy="96" r="3"/><circle cx="210" cy="92" r="2.4"/><circle cx="256" cy="120" r="3"/>
                <circle cx="86" cy="150" r="2.4"/><circle cx="176" cy="188" r="2.6"/><circle cx="232" cy="196" r="2.2"/>
              </g>
            </svg>
          </div>
        </div>
      </div>
    </header>
    
    <main>
      <!-- MENU -->
      <section id="menu">
        <div class="wrap">
          <div class="sec-head reveal">
            <h2>The Daily Bake</h2>
            <span class="rule"></span>
            <span class="sec-tag">From the oven, all day</span>
          </div>
          <p class="lead reveal">Whatever the season, the counter is never empty. These are the staples our regulars line up for — ask about today’s special and we’ll point you to it.</p>
    
          <ol class="menu-list">
            <li class="item reveal">
              <span class="item-num">01</span>
              <div class="item-body">
                <h3>Sourdough Country Loaf <span class="tag">House staple</span></h3>
                <p>48-hour cold ferment, blistered crust, an open crumb that tastes of honey and a whisper of tang.</p>
              </div>
              <span class="price">$7.50</span>
            </li>
            <li class="item reveal">
              <span class="item-num">02</span>
              <div class="item-body">
                <h3>Butter Croissant <span class="tag">Laminated by hand</span></h3>
                <p>Twenty-seven layers of cultured butter, folded over three days for a shattering, honeycomb interior.</p>
              </div>
              <span class="price">$4.25</span>
            </li>
            <li class="item reveal">
              <span class="item-num">03</span>
              <div class="item-body">
                <h3>Brown-Butter Chocolate Babka</h3>
                <p>A soft brioche swirled with dark chocolate and brown butter, finished with a scattering of flaky salt.</p>
              </div>
              <span class="price">$6.75</span>
            </li>
            <li class="item reveal">
              <span class="item-num">04</span>
              <div class="item-body">
                <h3>Rye &amp; Caraway Loaf</h3>
                <p>Dense, moist and deeply savoury — our favourite partner for sharp cheese and a little cold butter.</p>
              </div>
              <span class="price">$8.00</span>
            </li>
            <li class="item reveal">
              <span class="item-num">05</span>
              <div class="item-body">
                <h3>Honey-Cardamom Cinnamon Roll</h3>
                <p>Served warm, glazed with cardamom honey and a soft crumb that barely holds its shape.</p>
              </div>
              <span class="price">$5.50</span>
            </li>
          </ol>
        </div>
      </section>
    
      <!-- TODAY'S BAKE (sticky) -->
      <section id="today">
        <div class="wrap two-col">
          <div class="sticky-col reveal">
            <p class="kicker">Out of the oven</p>
            <div class="big-num">06:30</div>
            <h2 style="font-size:clamp(1.8rem,4vw,2.8rem);margin:.4rem 0 0;font-weight:800;line-height:1.05">First batch, every morning.</h2>
            <p>We turn the ovens on at four so the first loaves are cooling on the counter as the doors open. If you want one of these warm, come early — they rarely last past nine.</p>
          </div>
    
          <div class="recipe">
            <article class="recipe-card reveal">
              <span class="time">Morning · 6:30 am</span>
              <h3>Whole-Milk Baguette</h3>
              <p>Crisp, thin and crackling — baked in a single short batch so each one comes out with that fresh-from-the-oven snap.</p>
            </article>
            <article class="recipe-card reveal">
              <span class="time">Midday · 12:00 pm</span>
              <h3>Olive &amp; Rosemary Focaccia</h3>
              <p>Dimpled by hand, drenched in rosemary oil and studded with green olives. Cut into squares and gone by two.</p>
            </article>
            <article class="recipe-card reveal">
              <span class="time">Afternoon · 3:00 pm</span>
              <h3>Pistachio &amp; Rosewater Madeleines</h3>
              <p>A delicate afternoon treat, baked in the classic shell mould and dusted with a whisper of icing sugar.</p>
            </article>
          </div>
        </div>
      </section>
    
      <!-- STORY (scattered postcards) -->
      <section id="story">
        <div class="wrap">
          <div class="sec-head reveal">
            <h2>Our Story</h2>
            <span class="rule"></span>
            <span class="sec-tag">Thirty-seven years of flour on the floor</span>
          </div>
    
          <div class="board">
            <article class="postcard reveal">
              <span class="yr">1987</span>
              <h3>A single oven</h3>
              <p>Mara and Theo opened with one second-hand deck oven, a hand-cranked mixer, and a sourdough starter named Grandpa’s. The line wrapped around the corner by noon.</p>
            </article>
            <article class="postcard reveal">
              <span class="yr">1999</span>
              <h3>The starter travels</h3>
              <p>When the shop moved down the street, we carried the starter in a jar strapped to our chest. It has never missed a single feed since.</p>
            </article>
            <article class="postcard reveal">
              <span class="yr">2011</span>
              <h3>Stone-milled flour</h3>
              <p>We switched to locally stone-milled wheat, keeping the bran and germ in for a deeper flavour — and a slower, richer ferment.</p>
            </article>
            <article class="postcard reveal">
              <span class="yr">Today</span>
              <h3>Still by hand</h3>
              <p>Two generations on, every loaf is still shaped, scored and baked the same way: slowly, carefully, and with a little too much butter.</p>
            </article>
          </div>
        </div>
      </section>
    
      <!-- QUOTE -->
      <section class="quote-band">
        <div class="wrap">
          <blockquote data-scramble>“The best bread in the county — and I’ve eaten a lot of bread.”</blockquote>
          <cite>— The Morning Gazette, 2019</cite>
        </div>
      </section>
    </main>
    
    <footer>
      <div class="wrap">
        <div class="foot-grid">
          <div class="reveal">
            <h2>Opening Hours</h2>
            <p class="foot-sub">Find us on Mill Lane, just past the old clock tower. We bake through the day and close once the last loaf is sold.</p>
            <ul class="hours">
              <li><span>Monday – Friday</span><span>7:00 am – 6:00 pm</span></li>
              <li><span>Saturday</span><span>8:00 am – 4:00 pm</span></li>
              <li><span>Sunday</span><span>9:00 am – 2:00 pm</span></li>
            </ul>
            <p class="foot-note">Closed on public holidays. Wholesale &amp; catering by arrangement.</p>
          </div>
    
          <div class="reveal">
            <h2 style="font-size:1.6rem">Visit the bakery</h2>
            <p class="foot-sub" style="margin-top:.4rem">
              14 Mill Lane<br>
              Old Town, OR 97035<br><br>
              (503) 555-0182<br>
              hello@crumbandco.bakery
            </p>
          </div>
        </div>
    
        <div class="colophon">
          <span>© <span id="year"></span> Crumb &amp; Co. Baked with care.</span>
          <span>No preservatives · No shortcuts · Just flour, water, salt &amp; time</span>
        </div>
      </div>
    </footer>
    
    <script>
    (function(){
      "use strict";
      var reduce = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    
      /* ---- year ---- */
      var y = document.getElementById("year");
      if(y){ y.textContent = new Date().getFullYear(); }
    
      /* ---- open / closed status based on real time (Mon–Fri 7–18, Sat 8–16, Sun 9–14) ---- */
      (function(){
        var el = document.getElementById("status");
        if(!el){ return; }
        var now = new Date();
        var d = now.getDay();          // 0 Sun .. 6 Sat
        var h = now.getHours() + now.getMinutes()/60;
        var open = false;
        if(d >= 1 && d <= 5){ open = (h >= 7 && h < 18); }
        else if(d === 6){ open = (h >= 8 && h < 16); }
        else { open = (h >= 9 && h < 14); }
        el.textContent = open ? "Baking now" : "Closed right now";
        el.style.color = open ? "#3f7a2e" : "#7c2f3d";
      })();
    
      /* ---- scroll reveal ---- */
      var reveals = Array.prototype.slice.call(document.querySelectorAll(".reveal"));
      if(reduce || !("IntersectionObserver" in window)){
        reveals.forEach(function(r){ r.classList.add("in"); });
      } else {
        var io = new IntersectionObserver(function(entries){
          entries.forEach(function(e){
            if(e.isIntersecting){
              e.target.classList.add("in");
              io.unobserve(e.target);
            }
          });
        }, { threshold:0.15, rootMargin:"0px 0px -8% 0px" });
        reveals.forEach(function(r){ io.observe(r); });
      }
    
      /* ---- scramble-decode on the quote ---- */
      var glyphs = "ABCDEFGHIJKLMNOPQRSTUVWXYZ&?!·—/";
      function scramble(el){
        var text = el.getAttribute("data-text") || el.textContent;
        el.setAttribute("data-text", text);
        if(reduce){ el.textContent = text; return; }
        var frame = 0, total = text.length;
        var timer = setInterval(function(){
          var out = "";
          for(var i=0;i<total;i++){
            if(text[i] === " "){ out += " "; continue; }
            if(i < frame/2){ out += text[i]; }
            else { out += glyphs[Math.floor(Math.random()*glyphs.length)]; }
          }
          el.textContent = out;
          frame++;
          if(frame/2 >= total){ clearInterval(timer); el.textContent = text; }
        }, 45);
      }
    
      var quote = document.querySelector("[data-scramble]");
      if(quote){
        if(reduce || !("IntersectionObserver" in window)){
          /* leave as-is */
        } else {
          var qio = new IntersectionObserver(function(entries){
            entries.forEach(function(e){
              if(e.isIntersecting){ scramble(e.target); qio.unobserve(e.target); }
            });
          }, { threshold:0.6 });
          qio.observe(quote);
        }
      }
    })();
    </script>
    </body>
    </html>
    ```
  • A pricing table with a togglePassed

    5,838 tokens: 94 read, 5,744 written · 3 min 53 s · 24.7 tok/s

    Passes when Three elements with class plan, each holding a price, and a <button id="billing-toggle"> handled by script; the page switches between monthly and yearly. Nothing loaded from another site and no network requests.

    Build a pricing page with three plans. Each plan is an element with class "plan" containing an element with class "price". Add a <button id="billing-toggle"> that switches every price between monthly and yearly billing when clicked. Output one complete HTML document and nothing else. Put all CSS and JavaScript inline. Do not load anything from another site: no external scripts, stylesheets, fonts or images.

    Open the page on its own. It runs in a sandbox: no network, no access to this site.

    Page source
    ```html
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tariff — Pricing</title>
    <style>
      :root{
        --ink:#141210;
        --paper:#f4efe6;
        --paper-2:#eae2d3;
        --card:#fbf8f1;
        --muted:#7c7568;
        --line:rgba(20,18,16,.14);
        --accent:#b5391a;
        --accent-soft:#e8dcd0;
        --serif:"Iowan Old Style","Palatino Linotype",Palatino,"Book Antiqua",Georgia,"Times New Roman",serif;
        --sans:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
      }
    
      *{box-sizing:border-box;margin:0;padding:0}
      html{scroll-behavior:smooth}
      body{
        font-family:var(--sans);
        background:var(--paper);
        color:var(--ink);
        line-height:1.5;
        -webkit-font-smoothing:antialiased;
        overflow-x:hidden;
      }
    
      /* ---------- ambient background ---------- */
      .bg{position:fixed;inset:0;z-index:-2;pointer-events:none}
      .bg__grid{
        position:absolute;inset:0;
        background-image:
          linear-gradient(var(--line) 1px,transparent 1px),
          linear-gradient(90deg,var(--line) 1px,transparent 1px);
        background-size:58px 58px;
        opacity:.45;
        -webkit-mask-image:radial-gradient(ellipse at 50% 30%,#000 0%,transparent 78%);
                mask-image:radial-gradient(ellipse at 50% 30%,#000 0%,transparent 78%);
      }
      .bg__glow{
        position:absolute;inset:-10%;
        background:
          radial-gradient(620px 420px at 12% 8%,rgba(181,57,26,.14),transparent 60%),
          radial-gradient(720px 520px at 92% 96%,rgba(20,18,16,.10),transparent 62%);
        animation:drift 26s ease-in-out infinite alternate;
      }
      @keyframes drift{from{transform:translate3d(-2%,-1%,0)}to{transform:translate3d(2%,2%,0)}}
    
      .wrap{max-width:1180px;margin:0 auto;padding:0 clamp(18px,4vw,40px)}
    
      /* ---------- masthead ---------- */
      .masthead{
        display:flex;align-items:center;justify-content:space-between;
        padding:26px 0;border-bottom:1px solid var(--line);
      }
      .brand{display:flex;align-items:center;gap:12px;font-weight:700;letter-spacing:.02em}
      .mark{width:34px;height:34px;display:grid;place-items:center;background:var(--ink);color:var(--paper);border-radius:9px;font-family:var(--serif);font-size:1.3rem;line-height:1}
      .brand small{display:block;font-weight:500;font-size:.62rem;letter-spacing:.28em;text-transform:uppercase;color:var(--muted)}
      .nav{display:flex;gap:26px;font-size:.9rem}
      .nav a{color:var(--ink);text-decoration:none;opacity:.72;transition:opacity .2s,transform .2s;display:inline-block}
      .nav a:hover{opacity:1;transform:translateY(-1px)}
      .nav a.cta{background:var(--accent);color:#fff;padding:9px 16px;border-radius:8px;opacity:1;font-weight:600}
      .nav a.cta:hover{transform:translateY(-2px)}
      @media(max-width:720px){.nav{display:none}}
    
      /* ---------- intro / toggle ---------- */
      .intro{padding:clamp(48px,8vw,96px) 0 clamp(28px,5vw,48px);max-width:760px}
      .eyebrow{
        display:inline-flex;align-items:center;gap:10px;
        font-size:.72rem;font-weight:700;letter-spacing:.3em;text-transform:uppercase;color:var(--accent);
        margin-bottom:22px;
      }
      .eyebrow::before{content:"";width:34px;height:1px;background:var(--accent)}
      h1{
        font-family:var(--serif);font-weight:600;line-height:.98;letter-spacing:-.02em;
        font-size:clamp(2.7rem,7.5vw,5.4rem);margin-bottom:22px;
      }
      h1 em{font-style:italic;color:var(--accent)}
      .lede{font-size:clamp(1rem,1.6vw,1.2rem);color:#4a453c;max-width:52ch}
    
      .toggle-row{display:flex;align-items:center;gap:18px;margin-top:34px;flex-wrap:wrap}
      #billing-toggle{
        position:relative;display:inline-flex;align-items:center;gap:10px;cursor:pointer;
        background:var(--card);border:1.5px solid var(--ink);color:var(--ink);
        padding:12px 18px;border-radius:999px;font-family:var(--sans);font-weight:600;font-size:.95rem;
        transition:transform .2s,box-shadow .2s,background .3s;
      }
      #billing-toggle:hover{transform:translateY(-2px);box-shadow:4px 6px 0 rgba(20,18,16,.12)}
      #billing-toggle:active{transform:translateY(0)}
      #billing-toggle:focus-visible{outline:3px solid var(--accent);outline-offset:3px}
      .seg{position:relative;display:inline-flex;background:var(--paper-2);border-radius:999px;padding:4px}
      .seg span{position:relative;z-index:1;padding:6px 16px;font-size:.85rem;font-weight:700;color:var(--muted);transition:color .3s;white-space:nowrap}
      .seg__pill{position:absolute;top:4px;left:4px;height:calc(100% - 8px);width:calc(50% - 4px);background:var(--ink);border-radius:999px;transition:transform .38s cubic-bezier(.6,.02,.2,1)}
      #billing-toggle[aria-pressed="true"] .seg__pill{transform:translateX(100%)}
      #billing-toggle[aria-pressed="false"] .seg span:nth-child(1),
      #billing-toggle[aria-pressed="true"] .seg span:nth-child(2){color:var(--paper)}
      .save-chip{
        font-size:.74rem;font-weight:800;letter-spacing:.04em;text-transform:uppercase;
        color:var(--accent);background:rgba(181,57,26,.1);border:1px solid rgba(181,57,26,.3);
        padding:6px 12px;border-radius:999px;transition:transform .3s,opacity .3s;
      }
    
      /* ---------- plans ---------- */
      .plans{display:flex;flex-wrap:wrap;gap:26px;align-items:stretch;padding-bottom:clamp(40px,7vw,80px)}
      .plan{
        position:relative;flex:1 1 300px;display:flex;flex-direction:column;
        background:var(--card);border:1.5px solid var(--line);border-radius:16px;padding:34px 30px;
        transition:transform .35s cubic-bezier(.2,.7,.2,1),box-shadow .35s,border-color .35s;
      }
      .plan:hover{transform:translateY(-8px);border-color:var(--ink);box-shadow:0 24px 40px -22px rgba(20,18,16,.4)}
    
      .plan--featured{
        background:var(--ink);color:var(--paper);border-color:var(--ink);
        transform:translateY(-16px);box-shadow:0 30px 50px -26px rgba(20,18,16,.6);
      }
      .plan--featured:hover{transform:translateY(-24px)}
      .plan__badge{
        position:absolute;top:-13px;left:50%;transform:translateX(-50%);
        background:var(--accent);color:#fff;font-size:.7rem;font-weight:800;letter-spacing:.16em;text-transform:uppercase;
        padding:6px 14px;border-radius:999px;white-space:nowrap;box-shadow:0 6px 16px -6px rgba(181,57,26,.7);
      }
    
      .plan__name{font-family:var(--serif);font-size:1.7rem;font-weight:600;line-height:1}
      .plan__tag{margin-top:8px;font-size:.92rem;color:var(--muted);min-height:2.6em}
      .plan--featured .plan__tag{color:#cfc8bb}
    
      .price-row{display:flex;align-items:flex-end;gap:8px;margin:24px 0 6px}
      .price{
        font-family:var(--serif);font-weight:600;line-height:.9;letter-spacing:-.03em;
        font-size:clamp(2.9rem,5vw,3.7rem);display:inline-block;font-variant-numeric:tabular-nums;
      }
      .price-row.is-billed-yearly .price{animation:pop .45s cubic-bezier(.2,.8,.2,1)}
      @keyframes pop{0%{transform:scale(1);opacity:.3}60%{transform:scale(1.07)}100%{transform:scale(1);opacity:1}}
      .per{font-size:1rem;color:var(--muted);padding-bottom:.55em;font-weight:600}
      .plan--featured .per{color:#cfc8bb}
      .billed-note{font-size:.82rem;color:var(--muted);min-height:1.3em;margin-bottom:24px;transition:opacity .3s}
      .plan--featured .billed-note{color:#b7afa1}
    
      .divider{height:1px;background:var(--line);margin:6px 0 22px}
      .plan--featured .divider{background:rgba(244,239,230,.18)}
    
      .features{list-style:none;display:flex;flex-direction:column;gap:13px;margin-bottom:30px;flex:1}
      .features li{display:flex;gap:11px;font-size:.94rem;align-items:flex-start}
      .tick{flex:none;width:20px;height:20px;border-radius:6px;display:grid;place-items:center;background:rgba(181,57,26,.12);color:var(--accent);font-weight:800;font-size:.8rem;margin-top:1px}
      .plan--featured .tick{background:rgba(244,239,230,.14);color:#f0c9bd}
    
      .plan__cta{
        display:block;width:100%;text-align:center;text-decoration:none;cursor:pointer;
        font-family:var(--sans);font-weight:700;font-size:.98rem;padding:15px;border-radius:11px;
        border:1.5px solid var(--ink);background:transparent;color:var(--ink);
        transition:transform .2s,background .25s,color .25s,box-shadow .25s;
      }
      .plan__cta:hover{transform:translateY(-2px);box-shadow:0 10px 20px -12px rgba(20,18,16,.5)}
      .plan__cta--solid{background:var(--ink);color:var(--paper)}
      .plan__cta--solid:hover{background:#000}
      .plan--featured .plan__cta{border-color:var(--accent);background:var(--accent);color:#fff}
      .plan--featured .plan__cta:hover{background:#9c2f14}
    
      /* ---------- trust strip ---------- */
      .trust{
        display:flex;flex-wrap:wrap;align-items:center;gap:16px 30px;
        border-top:1px solid var(--line);border-bottom:1px solid var(--line);
        padding:22px 0;margin-bottom:clamp(50px,8vw,90px);
      }
      .trust span{font-size:.86rem;color:var(--muted)}
      .trust b{color:var(--ink);font-weight:700}
    
      /* ---------- FAQ ---------- */
      .faq{max-width:760px;padding-bottom:clamp(50px,8vw,90px)}
      .faq h2{font-family:var(--serif);font-size:clamp(1.8rem,4vw,2.6rem);font-weight:600;margin-bottom:26px}
      details{border-top:1px solid var(--line)}
      details:last-child{border-bottom:1px solid var(--line)}
      summary{list-style:none;cursor:pointer;padding:20px 4px;display:flex;justify-content:space-between;align-items:center;font-weight:600;font-size:1.05rem}
      summary::-webkit-details-marker{display:none}
      summary .plus{font-family:var(--serif);font-size:1.6rem;color:var(--accent);transition:transform .3s;line-height:1}
      details[open] summary .plus{transform:rotate(45deg)}
      details p{padding:0 4px 22px;color:#4a453c;max-width:60ch}
    
      /* ---------- footer ---------- */
      footer{border-top:1px solid var(--line);padding:34px 0;display:flex;justify-content:space-between;flex-wrap:wrap;gap:14px;font-size:.82rem;color:var(--muted)}
      footer a{color:var(--ink);text-decoration:none}
    
      /* ---------- reveal ---------- */
      .reveal{opacity:0;transform:translateY(26px);transition:opacity .7s ease,transform .7s cubic-bezier(.2,.7,.2,1)}
      .reveal.in{opacity:1;transform:none}
    
      @media (prefers-reduced-motion: reduce){
        *{animation:none!important;transition:none!important}
        .reveal{opacity:1;transform:none}
        html{scroll-behavior:auto}
      }
    </style>
    </head>
    <body>
    
    <div class="bg" aria-hidden="true">
      <div class="bg__glow"></div>
      <div class="bg__grid"></div>
    </div>
    
    <header class="wrap masthead">
      <div class="brand">
        <span class="mark">T</span>
        <span>Tariff<small>Pricing&nbsp;·&nbsp;2025</small></span>
      </div>
      <nav class="nav">
        <a href="#plans">Plans</a>
        <a href="#faq">FAQ</a>
        <a href="#" class="cta">Sign in</a>
      </nav>
    </header>
    
    <main class="wrap">
    
      <!-- intro + toggle -->
      <section class="intro reveal">
        <span class="eyebrow">Pricing</span>
        <h1>Pick the plan that<br><em>grows with you.</em></h1>
        <p class="lede">Three tiers, one honest bill. Start free, upgrade when the work gets real — and switch to yearly billing whenever you're ready to save.</p>
    
        <div class="toggle-row">
          <button id="billing-toggle" aria-pressed="false" aria-label="Switch between monthly and yearly billing">
            <span class="seg" aria-hidden="true">
              <span>Monthly</span>
              <span>Yearly</span>
              <span class="seg__pill"></span>
            </span>
          </button>
          <span class="save-chip">Save up to 20%</span>
        </div>
      </section>
    
      <!-- plans -->
      <section class="plans" id="plans">
    
        <article class="plan reveal">
          <h3 class="plan__name">Starter</h3>
          <p class="plan__tag">For a single project finding its footing.</p>
          <div class="price-row">
            <span class="price" data-monthly="12" data-yearly="9">$12</span>
            <span class="per">/mo</span>
          </div>
          <p class="billed-note">Billed monthly</p>
          <div class="divider"></div>
          <ul class="features">
            <li><span class="tick">✓</span>1 project, 3 seats</li>
            <li><span class="tick">✓</span>5 GB secure storage</li>
            <li><span class="tick">✓</span>Core analytics</li>
            <li><span class="tick">✓</span>Email support</li>
          </ul>
          <a href="#" class="plan__cta">Start free</a>
        </article>
    
        <article class="plan plan--featured reveal" style="transition-delay:.08s">
          <span class="plan__badge">Most popular</span>
          <h3 class="plan__name">Studio</h3>
          <p class="plan__tag">For teams shipping real work, every week.</p>
          <div class="price-row">
            <span class="price" data-monthly="29" data-yearly="23">$29</span>
            <span class="per">/mo</span>
          </div>
          <p class="billed-note">Billed monthly</p>
          <div class="divider"></div>
          <ul class="features">
            <li><span class="tick">✓</span>Unlimited projects, 15 seats</li>
            <li><span class="tick">✓</span>200 GB storage + versioning</li>
            <li><span class="tick">✓</span>Advanced analytics &amp; exports</li>
            <li><span class="tick">✓</span>Priority support, 4h SLA</li>
            <li><span class="tick">✓</span>API access &amp; webhooks</li>
          </ul>
          <a href="#" class="plan__cta plan__cta--solid">Choose Studio</a>
        </article>
    
        <article class="plan reveal" style="transition-delay:.16s">
          <h3 class="plan__name">Scale</h3>
          <p class="plan__tag">For orgs that need control and compliance.</p>
          <div class="price-row">
            <span class="price" data-monthly="79" data-yearly="63">$79</span>
            <span class="per">/mo</span>
          </div>
          <p class="billed-note">Billed monthly</p>
          <div class="divider"></div>
          <ul class="features">
            <li><span class="tick">✓</span>Everything in Studio</li>
            <li><span class="tick">✓</span>Unlimited seats &amp; storage</li>
            <li><span class="tick">✓</span>SSO, SAML &amp; audit logs</li>
            <li><span class="tick">✓</span>Dedicated success manager</li>
            <li><span class="tick">✓</span>99.9% uptime SLA</li>
          </ul>
          <a href="#" class="plan__cta">Talk to sales</a>
        </article>
    
      </section>
    
      <!-- trust strip -->
      <div class="trust reveal">
        <span><b>14-day free trial</b> on every plan</span>
        <span>No credit card to start</span>
        <span>Cancel anytime, keep your data</span>
        <span>SOC&nbsp;2 Type&nbsp;II certified</span>
      </div>
    
      <!-- FAQ -->
      <section class="faq reveal" id="faq">
        <h2>Questions, answered.</h2>
        <details>
          <summary>Can I switch between monthly and yearly later?<span class="plus">+</span></summary>
          <p>Absolutely. Flip the toggle above to preview either rate — and change your billing period at any time from your account settings. Upgrades apply instantly; downgrades take effect at the end of your current cycle.</p>
        </details>
        <details>
          <summary>What happens when my trial ends?<span class="plus">+</span></summary>
          <p>Your workspace stays intact and read-only until you pick a plan. Nothing is deleted, and we never charge you without an explicit confirmation.</p>
        </details>
        <details>
          <summary>Do you offer discounts for non-profits or students?<span class="plus">+</span></summary>
          <p>Yes — eligible organizations get 40% off any plan. Reach out to our team with proof of status and we'll apply it to your account within a day.</p>
        </details>
        <details>
          <summary>How does the yearly discount work?<span class="plus">+</span></summary>
          <p>You pay for twelve months up front at a reduced monthly rate — roughly two months free compared to paying month-to-month. The per-seat price shown is what you'd effectively pay each month.</p>
        </details>
      </section>
    
    </main>
    
    <footer class="wrap">
      <span>© 2025 Tariff Inc. — Prices in USD, before applicable tax.</span>
      <a href="#plans">Back to pricing ↑</a>
    </footer>
    
    <script>
    (function(){
      var btn = document.getElementById('billing-toggle');
      var prices = Array.prototype.slice.call(document.querySelectorAll('.price'));
      var notes  = Array.prototype.slice.call(document.querySelectorAll('.billed-note'));
      var rows   = Array.prototype.slice.call(document.querySelectorAll('.price-row'));
      var yearly = false;
    
      function render(){
        prices.forEach(function(p){
          p.textContent = '$' + (yearly ? p.dataset.yearly : p.dataset.monthly);
        });
        notes.forEach(function(n, i){
          n.textContent = yearly
            ? 'Billed $' + (prices[i].dataset.yearly * 12) + ' / year'
            : 'Billed monthly';
        });
        rows.forEach(function(r){
          r.classList.remove('is-billed-yearly');
          if(yearly){ void r.offsetWidth; r.classList.add('is-billed-yearly'); }
        });
        btn.setAttribute('aria-pressed', String(yearly));
      }
    
      btn.addEventListener('click', function(){
        yearly = !yearly;
        render();
      });
    
      // scroll reveal
      var reveals = Array.prototype.slice.call(document.querySelectorAll('.reveal'));
      if('IntersectionObserver' in window){
        var io = new IntersectionObserver(function(entries){
          entries.forEach(function(e){
            if(e.isIntersecting){ e.target.classList.add('in'); io.unobserve(e.target); }
          });
        }, {threshold:.12});
        reveals.forEach(function(el){ io.observe(el); });
      } else {
        reveals.forEach(function(el){ el.classList.add('in'); });
      }
    })();
    </script>
    
    </body>
    </html>
    ```
  • An accessible sign-up formPassed

    6,476 tokens: 129 read, 6,347 written · 4 min 20 s · 24.5 tok/s

    Passes when <form id="signup"> with name, email (type email) and password (type password, minlength 8 or more) inputs, each with a <label for>; a submit button; an element id="status" with role="status"; and script that stops the submit and writes to the status. Nothing loaded from another site and no network requests.

    Build a sign-up form: <form id="signup"> with inputs id="name", id="email" (type email) and id="password" (type password, minlength at least 8), each with a <label for>, and a submit button. When the form is submitted and valid, prevent the real submission and show a confirmation in an element with id="status" and role="status". Output one complete HTML document and nothing else. Put all CSS and JavaScript inline. Do not load anything from another site: no external scripts, stylesheets, fonts or images.

    Open the page on its own. It runs in a sandbox: no network, no access to this site.

    Page source
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Join the Ledger — Create your account</title>
    <style>
      :root{
        --bg:#e7e9df;
        --panel:#f4f6ee;
        --ink:#152820;
        --ink-soft:#4c5a52;
        --line:rgba(21,40,32,.16);
        --accent:#0e7d5b;
        --accent-2:#0a5f45;
        --gold:#cf922b;
        --err:#c0432c;
      }
    
      *{box-sizing:border-box;}
    
      html,body{margin:0;padding:0;}
    
      body{
        font-family:"Iowan Old Style","Palatino Linotype",Palatino,"Book Antiqua",Georgia,serif;
        color:var(--ink);
        background-color:var(--bg);
        min-height:100vh;
        display:flex;
        align-items:center;
        justify-content:center;
        padding:clamp(16px,4vw,52px);
        position:relative;
        overflow-x:hidden;
      }
    
      /* ---------- ambient background ---------- */
      .bg{position:fixed;inset:0;z-index:-1;overflow:hidden;}
      .glow{position:absolute;border-radius:50%;filter:blur(70px);opacity:.42;animation:breathe 13s ease-in-out infinite;}
      .glow.a{width:52vmax;height:52vmax;left:-16vmax;top:-18vmax;background:radial-gradient(circle at 35% 35%,#9fd6bf,transparent 70%);}
      .glow.b{width:46vmax;height:46vmax;right:-16vmax;bottom:-20vmax;background:radial-gradient(circle at 60% 60%,#ecd9a8,transparent 70%);animation-delay:-5s;}
      .glow.c{width:30vmax;height:30vmax;left:44%;top:38%;background:radial-gradient(circle,#cfe6db,transparent 70%);opacity:.3;animation-delay:-9s;}
      @keyframes breathe{0%,100%{transform:scale(1) translate(0,0);}50%{transform:scale(1.14) translate(2%,-2%);}}
    
      .grain{position:absolute;inset:0;opacity:.05;mix-blend-mode:multiply;
        background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");}
    
      .ring{position:absolute;border:1px solid rgba(21,40,32,.09);border-radius:50%;animation:drift 26s linear infinite;}
      .ring.r1{width:38vmax;height:38vmax;left:-10vmax;top:20%;}
      .ring.r2{width:24vmax;height:24vmax;right:-6vmax;bottom:6%;border-style:dashed;animation-duration:38s;}
      @keyframes drift{to{transform:rotate(360deg);}}
    
      /* ---------- layout ---------- */
      .sheet{
        display:grid;
        grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
        width:100%;max-width:1080px;
        background:var(--panel);
        border-radius:20px;overflow:hidden;
        box-shadow:0 44px 90px -34px rgba(20,40,32,.5),0 2px 0 rgba(255,255,255,.6) inset;
        animation:sheetIn .8s cubic-bezier(.2,.7,.2,1) both;
      }
      @keyframes sheetIn{from{opacity:0;transform:translateY(24px);}to{opacity:1;transform:none;}}
    
      /* ---------- brand panel ---------- */
      .brand{
        position:relative;overflow:hidden;color:#eaf3ec;
        background:radial-gradient(125% 120% at 18% 6%,#1c463a,#0d2b23 72%);
        padding:clamp(30px,4.2vw,54px);
        display:flex;flex-direction:column;justify-content:space-between;gap:26px;min-height:520px;
      }
      .brand::before{content:"";position:absolute;inset:0;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");opacity:.06;mix-blend-mode:overlay;}
      .brand::after{content:"";position:absolute;width:60vmax;height:60vmax;right:-24vmax;top:-24vmax;border-radius:50%;background:radial-gradient(circle,rgba(159,214,191,.28),transparent 60%);animation:breathe 12s ease-in-out infinite;}
    
      .mark{display:flex;align-items:center;gap:13px;position:relative;z-index:1;}
      .monogram{width:46px;height:46px;display:grid;place-items:center;border-radius:12px;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.16);font-weight:700;font-size:1.3rem;color:#f4d9a0;letter-spacing:.02em;}
      .wordmark{display:flex;flex-direction:column;line-height:1.05;}
      .wordmark b{font-size:1.15rem;letter-spacing:.01em;}
      .wordmark small{font-family:"Trebuchet MS",Verdana,system-ui,sans-serif;font-size:.62rem;text-transform:uppercase;letter-spacing:.32em;color:#9fc4b2;margin-top:4px;}
    
      .brand-copy{position:relative;z-index:1;}
      .eyebrow{font-family:"Trebuchet MS",Verdana,system-ui,sans-serif;font-size:.7rem;text-transform:uppercase;letter-spacing:.3em;color:#f0c877;margin:0 0 16px;}
      .headline{margin:0;font-weight:400;font-size:clamp(2.1rem,4.6vw,3.35rem);line-height:1.03;letter-spacing:-.01em;}
      .hl{color:#f4d9a0;font-style:italic;position:relative;white-space:nowrap;}
      .hl::after{content:"";position:absolute;left:0;right:0;bottom:.06em;height:.08em;background:var(--gold);transform:scaleX(0);transform-origin:left;transition:transform 1s ease .55s;}
      body.loaded .hl::after{transform:scaleX(1);}
      .lede{margin:20px 0 0;max-width:34ch;color:#c7dccf;font-size:1.02rem;line-height:1.62;}
    
      .steps{list-style:none;margin:30px 0 0;padding:0;display:flex;flex-direction:column;gap:15px;position:relative;z-index:1;}
      .steps li{display:flex;align-items:center;gap:14px;font-size:.96rem;color:#dbe8df;}
      .dot{width:27px;height:27px;flex:none;display:grid;place-items:center;border-radius:50%;border:1px solid rgba(255,255,255,.3);font-family:"Trebuchet MS",Verdana,sans-serif;font-size:.7rem;color:#f4d9a0;}
    
      .foot{position:relative;z-index:1;display:flex;align-items:center;gap:18px;flex-wrap:wrap;padding-top:20px;border-top:1px solid rgba(255,255,255,.13);}
      .avatars{display:flex;}
      .av{width:34px;height:34px;border-radius:50%;border:2px solid #123b30;margin-left:-9px;display:grid;place-items:center;font-family:"Trebuchet MS",Verdana,sans-serif;font-size:.68rem;color:#0d2b23;}
      .av:first-child{margin-left:0;}
      .av.a1{background:#f4d9a0;} .av.a2{background:#a7dcc4;} .av.a3{background:#e9b98a;}
      .trust{font-size:.86rem;color:#c7dccf;}
    
      /* ---------- form panel ---------- */
      .form-wrap{padding:clamp(28px,4vw,50px);display:flex;flex-direction:column;justify-content:center;background:var(--panel);}
      .eyebrow-l{font-family:"Trebuchet MS",Verdana,system-ui,sans-serif;font-size:.68rem;text-transform:uppercase;letter-spacing:.28em;color:var(--accent);margin:0 0 14px;}
      h2{margin:0 0 8px;font-weight:700;font-size:clamp(1.7rem,3vw,2.25rem);letter-spacing:-.01em;}
      .sub{margin:0 0 26px;color:var(--ink-soft);font-size:.98rem;line-height:1.55;max-width:40ch;}
    
      #signup{display:flex;flex-direction:column;gap:19px;margin:0;}
      .field{position:relative;}
      label{display:block;font-family:"Trebuchet MS",Verdana,system-ui,sans-serif;font-size:.72rem;text-transform:uppercase;letter-spacing:.16em;color:var(--ink-soft);margin-bottom:8px;transition:color .2s;}
      .field:focus-within label{color:var(--accent);}
    
      input[type=email],input[type=password],input:not([type]){
        width:100%;font-family:inherit;font-size:1rem;color:var(--ink);
        background:#fbfcf8;border:1px solid var(--line);border-radius:12px;
        padding:14px 16px;transition:border-color .2s,box-shadow .2s,background .2s;
      }
      input::placeholder{color:#9aa79e;}
      input:focus{outline:none;border-color:var(--accent);background:#fff;box-shadow:0 0 0 4px rgba(14,125,91,.16);}
    
      .pw-wrap{position:relative;}
      .eye{position:absolute;right:8px;top:50%;transform:translateY(-50%);width:38px;height:38px;display:grid;place-items:center;border:none;background:transparent;color:var(--ink-soft);cursor:pointer;border-radius:9px;transition:background .2s,color .2s;}
      .eye:hover{background:rgba(14,125,91,.08);color:var(--accent);}
      .eye svg{width:20px;height:20px;}
    
      .meter{display:flex;align-items:center;gap:10px;margin-top:11px;opacity:.55;transition:opacity .2s;}
      .field.filled .meter{opacity:1;}
      .bar{flex:1;height:6px;border-radius:99px;background:rgba(21,40,32,.1);overflow:hidden;}
      .bar i{display:block;height:100%;width:0;border-radius:inherit;transition:width .35s ease,background .35s ease;}
      .strength{font-family:"Trebuchet MS",Verdana,sans-serif;font-size:.68rem;text-transform:uppercase;letter-spacing:.14em;color:var(--ink-soft);min-width:72px;text-align:right;}
    
      .hint{margin:9px 0 0;font-family:"Trebuchet MS",Verdana,system-ui,sans-serif;font-size:.76rem;line-height:1.45;color:var(--err);}
      .field.invalid .hint{display:block;animation:shake .4s;}
      @keyframes shake{0%,100%{transform:translateX(0);}20%{transform:translateX(-5px);}40%{transform:translateX(5px);}60%{transform:translateX(-3px);}80%{transform:translateX(3px);}}
      .field.invalid input{border-color:var(--err);box-shadow:0 0 0 4px rgba(192,67,44,.15);}
    
      .btn{
        position:relative;overflow:hidden;cursor:pointer;border:none;
        font-family:"Trebuchet MS",Verdana,system-ui,sans-serif;font-weight:700;font-size:.98rem;letter-spacing:.03em;
        color:#f4f9f5;background:linear-gradient(180deg,#128a63,#0c6b4c);
        padding:15px 20px;border-radius:12px;margin-top:4px;
        box-shadow:0 14px 26px -12px rgba(12,107,76,.7);
        transition:transform .2s,box-shadow .2s,filter .2s;
      }
      .btn:hover{transform:translateY(-2px);box-shadow:0 20px 34px -14px rgba(12,107,76,.85);filter:saturate(1.08);}
      .btn:active{transform:translateY(0);}
      .btn::after{content:"";position:absolute;top:0;left:-130%;width:55%;height:100%;background:linear-gradient(90deg,transparent,rgba(255,255,255,.4),transparent);transform:skewX(-20deg);}
      .btn:hover::after{animation:sheen .8s ease;}
      @keyframes sheen{to{left:160%;}}
    
      #status{min-height:1.2em;margin-top:16px;padding:0;font-family:"Trebuchet MS",Verdana,system-ui,sans-serif;font-size:.9rem;line-height:1.5;color:var(--ink-soft);border-radius:10px;transition:background .3s,color .3s;}
      #status.ok{background:rgba(14,125,91,.12);color:#0a5f45;padding:13px 16px;border-left:3px solid var(--accent);}
      #status.err{background:rgba(192,67,44,.1);color:#8f2f1e;padding:13px 16px;border-left:3px solid var(--err);}
    
      .fineprint{margin-top:22px;font-size:.78rem;color:var(--ink-soft);line-height:1.5;}
      .fineprint a{color:var(--accent);text-decoration:none;border-bottom:1px solid rgba(14,125,91,.35);}
      .fineprint a:hover{border-color:var(--accent);}
    
      /* ---------- responsive ---------- */
      @media (max-width:860px){
        .sheet{grid-template-columns:1fr;}
        .brand{min-height:auto;padding:clamp(26px,6vw,40px);}
        .steps{margin-top:24px;gap:12px;}
      }
    
      @media (prefers-reduced-motion:reduce){
        *{animation:none!important;transition:none!important;}
      }
    </style>
    </head>
    <body>
      <div class="bg" aria-hidden="true">
        <span class="glow a"></span>
        <span class="glow b"></span>
        <span class="glow c"></span>
        <span class="ring r1"></span>
        <span class="ring r2"></span>
        <span class="grain"></span>
      </div>
    
      <main class="sheet">
        <!-- Brand / context -->
        <section class="brand" aria-label="About Ledgerline">
          <div class="mark">
            <span class="monogram">L</span>
            <span class="wordmark"><b>Ledgerline</b><small>Est. 2014</small></span>
          </div>
    
          <div class="brand-copy">
            <p class="eyebrow">Create your account</p>
            <h1 class="headline">Keep every number in its proper place.</h1>
            <p class="lede">A calm, considered home for your finances — built for the people who read the fine print and still sleep well at night.</p>
    
            <ol class="steps">
              <li><span class="dot">1</span> Tell us a little about you</li>
              <li><span class="dot">2</span> Choose a strong password</li>
              <li><span class="dot">3</span> Start your first ledger</li>
            </ol>
          </div>
    
          <div class="foot">
            <div class="avatars" aria-hidden="true">
              <span class="av a1">M</span>
              <span class="av a2">R</span>
              <span class="av a3">K</span>
            </div>
            <p class="trust">Trusted by 48,000+ careful bookkeepers.</p>
          </div>
        </section>
    
        <!-- Form -->
        <section class="form-wrap" aria-label="Sign up form">
          <p class="eyebrow-l">Get started</p>
          <h2>Join the ledger</h2>
          <p class="sub">It takes about a minute. No credit card, no pressure — just a place to begin.</p>
    
          <form id="signup" novalidate>
            <div class="field">
              <label for="name">Full name</label>
              <input id="name" name="name" type="text" autocomplete="name" placeholder="Ada Lovelace" required>
              <p class="hint" aria-hidden="true"></p>
            </div>
    
            <div class="field">
              <label for="email">Email address</label>
              <input id="email" name="email" type="email" autocomplete="email" placeholder="you@example.com" required>
              <p class="hint" aria-hidden="true"></p>
            </div>
    
            <div class="field">
              <label for="password">Password</label>
              <div class="pw-wrap">
                <input id="password" name="password" type="password" autocomplete="new-password" minlength="8" placeholder="At least 8 characters" required aria-describedby="status">
                <button type="button" class="eye" id="togglePw" aria-label="Show password" aria-pressed="false">
                  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                    <path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12z"></path>
                    <circle cx="12" cy="12" r="3"></circle>
                  </svg>
                </button>
              </div>
              <div class="meter">
                <span class="bar"><i></i></span>
                <span class="strength">Strength</span>
              </div>
              <p class="hint" aria-hidden="true"></p>
            </div>
    
            <button type="submit" class="btn">Create my account</button>
    
            <p id="status" role="status" aria-live="polite"></p>
          </form>
    
          <p class="fineprint">By creating an account you agree to our <a href="#">Terms</a> and acknowledge the <a href="#">Privacy Policy</a>.</p>
        </section>
      </main>
    
    <script>
    (function(){
      var form = document.getElementById('signup');
      var nameEl = document.getElementById('name');
      var emailEl = document.getElementById('email');
      var pwEl = document.getElementById('password');
      var statusEl = document.getElementById('status');
      var toggle = document.getElementById('togglePw');
    
      var eyeOpen = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12z"></path><circle cx="12" cy="12" r="3"></circle></svg>';
      var eyeClosed = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9.9 5.2A9.6 9.6 0 0 1 12 5c6.5 0 10 7 10 7a13.4 13.4 0 0 1-1.7 2.5M6.3 6.3A13.4 13.4 0 0 0 2 12s3.5 7 10 7a9.6 9.6 0 0 0 4-.85"></path><path d="M9.9 9.9a3 3 0 0 0 4.2 4.2"></path><line x1="3" y1="3" x2="21" y2="21"></line></svg>';
    
      /* ---- password visibility toggle ---- */
      toggle.addEventListener('click', function(){
        var show = pwEl.type === 'password';
        pwEl.type = show ? 'text' : 'password';
        toggle.innerHTML = show ? eyeClosed : eyeOpen;
        toggle.setAttribute('aria-pressed', String(show));
        toggle.setAttribute('aria-label', show ? 'Hide password' : 'Show password');
        pwEl.focus();
      });
    
      /* ---- live strength meter ---- */
      var bar = form.querySelector('.bar i');
      var label = form.querySelector('.strength');
      function score(v){
        if(!v) return null;
        var s = 0;
        if(v.length >= 8) s++;
        if(/[a-z]/.test(v) && /[A-Z]/.test(v)) s++;
        if(/\d/.test(v)) s++;
        if(/[^A-Za-z0-9]/.test(v)) s++;
        return Math.max(1, Math.min(s, 4));
      }
      function paintStrength(){
        var v = pwEl.value;
        var f = pwEl.closest('.field');
        f.classList.toggle('filled', v.length > 0);
        var sc = score(v);
        if(sc === null){ bar.style.width = '0'; label.textContent = 'Strength'; return; }
        var map = {1:['28%','#c0432c','Weak'],2:['52%','#cf922b','Fair'],3:['76%','#0e7d5b','Good'],4:['100%','#0a5f45','Strong']};
        bar.style.width = map[sc][0];
        bar.style.background = map[sc][1];
        label.textContent = map[sc][2];
      }
      pwEl.addEventListener('input', paintStrength);
    
      /* ---- validation helpers ---- */
      function setError(el, msg){
        var f = el.closest('.field');
        f.classList.add('invalid');
        f.querySelector('.hint').textContent = msg;
        el.setAttribute('aria-invalid','true');
      }
      function clearError(el){
        var f = el.closest('.field');
        f.classList.remove('invalid');
        f.querySelector('.hint').textContent = '';
        el.removeAttribute('aria-invalid');
      }
      function validate(){
        var ok = true;
        if(!nameEl.value.trim()){ setError(nameEl,'Please tell us your name.'); ok = false; } else clearError(nameEl);
    
        if(!emailEl.checkValidity() || !emailEl.value.trim()){ setError(emailEl,'Enter a valid email address.'); ok = false; } else clearError(emailEl);
    
        if(pwEl.value.length < 8){ setError(pwEl,'Password must be at least 8 characters.'); ok = false; } else clearError(pwEl);
        return ok;
      }
    
      [nameEl, emailEl, pwEl].forEach(function(el){
        el.addEventListener('input', function(){ if(el.closest('.field').classList.contains('invalid')) clearError(el); });
      });
    
      /* ---- submit ---- */
      form.addEventListener('submit', function(e){
        e.preventDefault();
        if(!validate()){
          statusEl.className = 'err';
          statusEl.textContent = 'Almost there — please fix the highlighted fields above.';
          var firstBad = form.querySelector('.field.invalid input');
          if(firstBad) firstBad.focus();
          return;
        }
        var first = nameEl.value.trim().split(/\s+/)[0];
        statusEl.className = 'ok';
        statusEl.textContent = 'Welcome, ' + first + '! Your account is ready — check your inbox to confirm.';
        form.reset();
        paintStrength();
      });
    
      /* ---- reveal underline on load ---- */
      requestAnimationFrame(function(){ document.body.classList.add('loaded'); });
    })();
    </script>
    </body>
    </html>
  • A to-do app that remembersPassed

    5,489 tokens: 117 read, 5,372 written · 3 min 39 s · 24.6 tok/s

    Passes when The input, add button and list with the given ids, and script that saves to localStorage under "todos" and adds list items with a remove control. Nothing loaded from another site and no network requests.

    Build a to-do list app with an <input id="new-task">, a <button id="add"> and a <ul id="tasks">. Clicking add appends the text as an <li> with its own remove button. Save the list in localStorage under the key "todos" and load it again when the page opens. Output one complete HTML document and nothing else. Put all CSS and JavaScript inline. Do not load anything from another site: no external scripts, stylesheets, fonts or images.

    Open the page on its own. It runs in a sandbox: no network, no access to this site.

    Page source
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>The Day Sheet</title>
    <style>
      :root{
        --ink:#231d16;
        --ink-soft:#6f6459;
        --paper:#f4efe5;
        --card:#fffdf8;
        --line:rgba(35,29,22,.12);
        --accent:#e0472b;
        --accent-deep:#c23a22;
        --teal:#1f6f66;
        --gold:#e0a428;
        --shadow:0 1px 2px rgba(35,29,22,.05), 0 24px 48px -28px rgba(35,29,22,.4);
        --font-display:"Iowan Old Style","Palatino Linotype",Palatino,"Book Antiqua",Georgia,serif;
        --font-body:ui-sans-serif,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
        --font-mono:ui-monospace,"SF Mono","Cascadia Code","Roboto Mono",Menlo,Consolas,monospace;
      }
    
      *{box-sizing:border-box;}
      html,body{margin:0;padding:0;}
      body{
        min-height:100vh;
        font-family:var(--font-body);
        color:var(--ink);
        background-color:var(--paper);
        background-image:
          radial-gradient(120% 85% at 50% -15%, rgba(255,255,255,.75), transparent 60%),
          radial-gradient(circle at center, rgba(35,29,22,.045) 1px, transparent 1.6px);
        background-size:auto, 22px 22px;
        background-attachment:fixed,fixed;
        -webkit-font-smoothing:antialiased;
        overflow-x:hidden;
      }
    
      /* ambient layers */
      .grain{
        position:fixed; inset:0; z-index:1; pointer-events:none; opacity:.5; mix-blend-mode:multiply;
        background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
      }
      .watermark{
        position:fixed; z-index:0; pointer-events:none; user-select:none;
        font-family:var(--font-mono); letter-spacing:.4em; text-transform:uppercase;
        color:rgba(35,29,22,.05); white-space:nowrap;
      }
      .wm-top{ top:6vh; right:-1vw; font-size:clamp(80px,17vw,240px); animation:drift 46s ease-in-out infinite alternate; }
      .wm-bottom{ bottom:3vh; left:-1vw; font-size:clamp(50px,10vw,140px); animation:drift 60s ease-in-out infinite alternate-reverse; }
      @keyframes drift{ from{transform:translateX(-2%)} to{transform:translateX(3%)} }
    
      .page{ position:relative; z-index:2; max-width:940px; margin:0 auto; padding:clamp(28px,6vw,72px) clamp(18px,5vw,40px) 60px; }
    
      /* masthead */
      .masthead{ display:flex; justify-content:space-between; align-items:flex-end; gap:24px; flex-wrap:wrap; }
      .kicker{ margin:0; font-family:var(--font-mono); font-size:.72rem; letter-spacing:.34em; text-transform:uppercase; color:var(--ink-soft); }
      h1.title{ margin:.18em 0 0; font-family:var(--font-display); font-weight:600; font-size:clamp(3rem,11vw,6.2rem); line-height:.92; letter-spacing:-.02em; color:var(--ink); }
      .title .dot{ color:var(--accent); }
      .subhead{ margin:.55em 0 0; max-width:34ch; font-size:1rem; line-height:1.5; color:var(--ink-soft); }
    
      .clock{ text-align:right; display:flex; flex-direction:column; align-items:flex-end; gap:6px; }
      .time{ margin:0; font-family:var(--font-mono); font-size:clamp(2rem,5vw,3rem); font-weight:600; letter-spacing:.02em; color:var(--ink); font-variant-numeric:tabular-nums; }
      .date{ margin:0; font-family:var(--font-mono); font-size:.74rem; letter-spacing:.22em; text-transform:uppercase; color:var(--ink-soft); }
    
      /* rule */
      .rule{ position:relative; height:1px; background:var(--line); margin:clamp(20px,4vw,34px) 0 clamp(22px,4vw,32px); }
      .rule::before,.rule::after{ content:""; position:absolute; top:-3px; width:7px; height:7px; background:var(--accent); border-radius:1px; transform:rotate(45deg); }
      .rule::before{ left:0; } .rule::after{ right:0; }
    
      /* composer */
      .composer{ display:flex; gap:12px; align-items:stretch; background:var(--card); border:1.5px solid var(--ink); border-radius:3px; padding:8px 8px 8px 20px; box-shadow:4px 4px 0 rgba(35,29,22,.12); transition:box-shadow .2s ease, transform .2s ease; }
      .composer:focus-within{ box-shadow:6px 6px 0 rgba(224,71,43,.28); transform:translate(-1px,-1px); }
      #new-task{ flex:1; min-width:0; border:none; background:transparent; font-family:var(--font-body); font-size:1.1rem; color:var(--ink); padding:12px 4px; outline:none; }
      #new-task::placeholder{ color:rgba(35,29,22,.38); }
      .add-btn{ display:inline-flex; align-items:center; gap:9px; border:none; cursor:pointer; background:var(--ink); color:#fbf6ec; font-family:var(--font-mono); font-size:.74rem; letter-spacing:.16em; text-transform:uppercase; padding:0 20px; border-radius:2px; transition:background .18s ease, transform .12s ease; }
      .add-btn:hover{ background:var(--accent); }
      .add-btn:active{ transform:scale(.96); }
      .plus{ font-size:1.05rem; line-height:1; transition:transform .3s ease; }
      .add-btn:hover .plus{ transform:rotate(90deg); }
    
      /* board */
      .board-head{ display:flex; align-items:center; gap:14px; margin:clamp(26px,5vw,40px) 0 16px; }
      .count{ font-family:var(--font-mono); font-size:.78rem; letter-spacing:.18em; text-transform:uppercase; color:var(--ink-soft); }
      .count b{ color:var(--ink); font-weight:700; }
      .progress{ flex:1; height:6px; background:rgba(35,29,22,.1); border-radius:999px; overflow:hidden; }
      .progress i{ display:block; height:100%; width:0; background:linear-gradient(90deg,var(--teal),var(--accent)); transition:width .55s cubic-bezier(.4,0,.2,1); }
    
      #tasks{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:10px; }
      .task{ position:relative; display:flex; align-items:center; gap:14px; background:var(--card); border:1px solid var(--line); border-radius:3px; padding:15px 16px 15px 18px; box-shadow:var(--shadow); transition:transform .2s ease, border-color .2s ease, box-shadow .2s ease; }
      .task::before{ content:""; position:absolute; left:0; top:0; bottom:0; width:3px; background:var(--teal); opacity:.85; transition:background .3s ease, opacity .3s ease; }
      .task:hover{ transform:translateX(4px); border-color:rgba(35,29,22,.28); box-shadow:0 1px 2px rgba(35,29,22,.06), 0 26px 44px -26px rgba(35,29,22,.42); }
      .task.done{ background:transparent; border-color:transparent; box-shadow:none; }
      .task.done::before{ opacity:0; }
    
      .check{ flex:none; width:24px; height:24px; padding:0; cursor:pointer; background:var(--card); border:1.6px solid var(--ink); border-radius:50%; display:grid; place-items:center; color:#fff; transition:background .2s ease, border-color .2s ease, transform .12s ease; }
      .check:hover{ transform:scale(1.1); }
      .check svg{ width:13px; height:13px; opacity:0; transform:scale(.4); transition:opacity .2s ease, transform .25s cubic-bezier(.34,1.56,.64,1); }
      .task.done .check{ background:var(--teal); border-color:var(--teal); }
      .task.done .check svg{ opacity:1; transform:scale(1); }
    
      .text{ flex:1; min-width:0; font-size:1.06rem; line-height:1.4; color:var(--ink); overflow-wrap:anywhere; transition:color .3s ease; }
      .task.done .text{ color:var(--ink-soft); }
      .task.done .text::after{ content:""; display:block; height:1px; background:currentColor; width:0; margin-top:4px; transition:width .45s ease; }
      .task.done .text::after{ width:100%; }
    
      .remove{ flex:none; width:30px; height:30px; padding:0; cursor:pointer; background:transparent; border:1px solid transparent; border-radius:50%; color:var(--ink-soft); font-size:1.2rem; line-height:1; display:grid; place-items:center; opacity:.4; transition:opacity .18s ease, background .18s ease, color .18s ease, transform .3s ease, border-color .18s ease; }
      .task:hover .remove{ opacity:1; }
      .remove:hover{ background:rgba(224,71,43,.12); color:var(--accent); border-color:rgba(224,71,43,.3); transform:rotate(90deg); }
    
      /* empty state */
      .empty{ text-align:center; padding:56px 20px; }
      .empty-mark{ font-size:2.6rem; color:var(--accent); animation:bob 3s ease-in-out infinite; }
      @keyframes bob{ 0%,100%{transform:translateY(0)} 50%{transform:translateY(-8px)} }
      .empty h2{ margin:.4em 0 .2em; font-family:var(--font-display); font-weight:600; font-size:1.7rem; letter-spacing:-.01em; }
      .empty p{ margin:0; color:var(--ink-soft); font-size:.98rem; }
    
      /* footer */
      .foot{ display:flex; justify-content:space-between; align-items:center; gap:16px; flex-wrap:wrap; margin-top:clamp(34px,6vw,52px); padding-top:20px; border-top:1px solid var(--line); font-family:var(--font-mono); font-size:.7rem; letter-spacing:.14em; text-transform:uppercase; color:var(--ink-soft); }
      .foot .right{ display:flex; align-items:center; gap:8px; }
      .pulse{ width:7px; height:7px; border-radius:50%; background:var(--teal); animation:pulse 2.4s ease-out infinite; }
      @keyframes pulse{ 0%{box-shadow:0 0 0 0 rgba(31,111,102,.5)} 70%{box-shadow:0 0 0 8px rgba(31,111,102,0)} 100%{box-shadow:0 0 0 0 rgba(31,111,102,0)} }
    
      /* reveal */
      @keyframes rise{ from{opacity:0; transform:translateY(16px)} to{opacity:1; transform:none} }
      .reveal{ animation:rise .7s cubic-bezier(.2,.7,.2,1) both; }
      .d1{animation-delay:.05s} .d2{animation-delay:.13s} .d3{animation-delay:.21s} .d4{animation-delay:.3s} .d5{animation-delay:.4s}
    
      @keyframes popIn{ from{opacity:0; transform:translateY(-8px) scale(.98)} to{opacity:1; transform:none} }
      @keyframes slideOut{ to{opacity:0; transform:translateX(26px); max-height:0; margin-bottom:-10px; padding-top:0; padding-bottom:0; border-width:0;} }
    
      /* focus */
      :focus-visible{ outline:2px solid var(--accent); outline-offset:3px; border-radius:2px; }
    
      @media (max-width:560px){
        .clock{ align-items:flex-start; text-align:left; }
        .masthead{ align-items:flex-start; }
      }
      @media (prefers-reduced-motion:reduce){
        *{ animation-duration:.001ms !important; animation-iteration-count:1 !important; transition-duration:.001ms !important; }
      }
    </style>
    </head>
    <body>
      <div class="grain" aria-hidden="true"></div>
      <div class="watermark wm-top" aria-hidden="true">TO-DO</div>
      <div class="watermark wm-bottom" aria-hidden="true">LIST</div>
    
      <main class="page">
        <header class="masthead">
          <div>
            <p class="kicker reveal d1">The Day Sheet · No. 001</p>
            <h1 class="title reveal d2">To-Do<span class="dot">.</span></h1>
            <p class="subhead reveal d3">Write it down before it writes itself off your mind. Everything you add stays on this page — even after the tab closes.</p>
          </div>
          <div class="clock reveal d4">
            <p class="time" id="time">--:--</p>
            <p class="date" id="date">—</p>
          </div>
        </header>
    
        <div class="rule reveal d3"></div>
    
        <form class="composer reveal d4" id="composer" autocomplete="off">
          <input id="new-task" type="text" placeholder="What needs doing?" aria-label="New task" maxlength="200">
          <button id="add" class="add-btn" type="submit"><span class="plus">+</span>Add</button>
        </form>
    
        <section class="board reveal d5">
          <div class="board-head">
            <span class="count" id="count"></span>
            <div class="progress"><i id="bar"></i></div>
          </div>
          <ul id="tasks"></ul>
        </section>
    
        <footer class="foot reveal d5">
          <span>Local only · nothing leaves this browser</span>
          <span class="right"><span class="pulse" aria-hidden="true"></span>Saved to this device</span>
        </footer>
      </main>
    
    <script>
    (function(){
      "use strict";
      var KEY = "todos";
      var tasksEl   = document.getElementById("tasks");
      var form      = document.getElementById("composer");
      var input     = document.getElementById("new-task");
      var addBtn    = document.getElementById("add");
      var countEl   = document.getElementById("count");
      var bar       = document.getElementById("bar");
      var timeEl    = document.getElementById("time");
      var dateEl    = document.getElementById("date");
    
      var CHECK_SVG = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3.2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12.5l5 5L20 6"/></svg>';
    
      var state = load();
      if (!Array.isArray(state)) state = [];
    
      function load(){
        try { return JSON.parse(localStorage.getItem(KEY)); }
        catch(e){ return null; }
      }
      function save(){
        try { localStorage.setItem(KEY, JSON.stringify(state)); }
        catch(e){ /* storage unavailable — keep working in memory */ }
      }
    
      function makeTask(t){
        var li = document.createElement("li");
        li.className = "task" + (t.done ? " done" : "");
    
        var check = document.createElement("button");
        check.type = "button";
        check.className = "check";
        check.setAttribute("aria-label", t.done ? "Mark as not done" : "Mark as done");
        check.innerHTML = CHECK_SVG;
    
        var span = document.createElement("span");
        span.className = "text";
        span.textContent = t.text;
    
        var remove = document.createElement("button");
        remove.type = "button";
        remove.className = "remove";
        remove.setAttribute("aria-label", "Remove task");
        remove.innerHTML = "&times;";
    
        check.addEventListener("click", function(){
          t.done = !t.done;
          li.classList.toggle("done", t.done);
          check.setAttribute("aria-label", t.done ? "Mark as not done" : "Mark as done");
          save(); updateMeta();
        });
    
        remove.addEventListener("click", function(){
          li.style.overflow = "hidden";
          li.style.maxHeight = li.offsetHeight + "px";
          requestAnimationFrame(function(){
            li.style.transition = "all .32s ease";
            li.style.animation  = "slideOut .32s ease forwards";
          });
          li.addEventListener("animationend", function(){
            var i = state.indexOf(t);
            if (i > -1) state.splice(i, 1);
            save();
            li.remove();
            updateMeta();
          }, { once:true });
        });
    
        li.appendChild(check);
        li.appendChild(span);
        li.appendChild(remove);
        return li;
      }
    
      function render(){
        tasksEl.innerHTML = "";
        state.forEach(function(t, i){
          var li = makeTask(t);
          li.style.animation = "popIn .5s cubic-bezier(.2,.7,.2,1) both";
          li.style.animationDelay = (i * 45) + "ms";
          tasksEl.appendChild(li);
        });
        updateMeta();
      }
    
      function showEmpty(){
        var d = document.createElement("div");
        d.className = "empty";
        d.innerHTML = '<div class="empty-mark">✎</div><h2>A clean slate.</h2><p>Add your first task above and it will appear right here.</p>';
        tasksEl.appendChild(d);
      }
    
      function updateMeta(){
        var total = state.length;
        var done  = state.filter(function(t){ return t.done; }).length;
        var open  = total - done;
        countEl.innerHTML = '<b>' + open + '</b> open &nbsp;/&nbsp; ' + total + ' total';
        bar.style.width = (total ? Math.round(done / total * 100) : 0) + "%";
    
        var empty = tasksEl.querySelector(".empty");
        if (total === 0){ if (!empty) showEmpty(); }
        else if (empty){ empty.remove(); }
      }
    
      function addTask(text){
        text = text.trim();
        if (!text) return;
        state.push({ text: text, done: false });
        save();
        var li = makeTask(state[state.length - 1]);
        li.style.animation = "popIn .45s cubic-bezier(.2,.7,.2,1) both";
        tasksEl.appendChild(li);
        updateMeta();
        input.value = "";
        input.focus();
      }
    
      form.addEventListener("submit", function(e){
        e.preventDefault();
        addTask(input.value);
      });
    
      // live clock + date
      var DAYS = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
      var MONTHS = ["January","February","March","April","May","June","July","August","September","October","November","December"];
      function tick(){
        var n = new Date();
        var h = n.getHours(), m = n.getMinutes();
        timeEl.textContent = (h < 10 ? "0" + h : h) + ":" + (m < 10 ? "0" + m : m);
        dateEl.textContent = DAYS[n.getDay()] + ", " + MONTHS[n.getMonth()] + " " + n.getDate();
      }
      tick();
      setInterval(tick, 15000);
    
      render();
    })();
    </script>
    </body>
    </html>
  • A bar chart in SVGFailed

    4,309 tokens: 142 read, 4,167 written · 2 min 51 s · 24.5 tok/s

    Passes when Five <rect class="bar"> in an <svg>, written in the markup, with heights proportional to 12, 30, 18, 24 and 6 in that order, labelled Mon to Fri in <text>, and a <title> or aria-label. Nothing loaded from another site and no network requests.

    Draw an inline SVG bar chart of coffee sold: Mon 12, Tue 30, Wed 18, Thu 24, Fri 6. Each bar is a <rect class="bar"> whose height attribute is proportional to its value, each bar is labelled with its day in a <text>, and the <svg> has a <title> or an aria-label. Write the bars and labels directly in the SVG markup, not with JavaScript. Output one complete HTML document and nothing else. Put all CSS and JavaScript inline. Do not load anything from another site: no external scripts, stylesheets, fonts or images.

    Open the page on its own. It runs in a sandbox: no network, no access to this site.

    Page source
    Here's a self-contained page that opens on the chart itself, with each `<rect class="bar">` written directly in the markup at a height proportional to its value (scale 10 px per cup), day labels beneath, and an accessible title plus `role="img"`/`aria-label`.
    
    ```html
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Coffee Counter · Week in Cups</title>
    <style>
      :root{
        --bg:#160f0a;
        --ink:#f5e7d3;
        --muted:#b49878;
        --line:rgba(245,231,211,.12);
        --gold:#ffc861;
      }
    
      *{ box-sizing:border-box; margin:0; padding:0; }
    
      html,body{ height:100%; }
    
      body{
        min-height:100vh;
        font-family:"Avenir Next","Segoe UI",system-ui,-apple-system,sans-serif;
        color:var(--ink);
        background:
          radial-gradient(120% 90% at 50% -12%, rgba(255,184,92,.16), transparent 55%),
          radial-gradient(90% 70% at 88% 112%, rgba(150,90,50,.22), transparent 60%),
          linear-gradient(180deg,#1c130d 0%, #140d08 60%, #0f0a06 100%);
        display:flex;
        flex-direction:column;
        align-items:center;
        padding:clamp(24px,5vh,56px) 20px;
        position:relative;
        overflow-x:hidden;
      }
    
      /* faint paper grain */
      body::before{
        content:"";
        position:fixed; inset:0; pointer-events:none; z-index:0;
        background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
        mix-blend-mode:overlay;
      }
    
      .wrap{ position:relative; z-index:1; width:min(780px,100%); display:flex; flex-direction:column; gap:clamp(20px,3.5vh,34px); }
    
      /* ---------- masthead ---------- */
      .masthead{
        display:flex; justify-content:space-between; align-items:flex-end; gap:24px;
        border-bottom:1px solid var(--line); padding-bottom:clamp(16px,3vh,26px);
      }
      .kicker{
        font-size:.72rem; letter-spacing:.34em; text-transform:uppercase; color:var(--muted);
        display:flex; align-items:center; gap:.7em; margin-bottom:.9rem;
      }
      .kicker::before{ content:""; width:26px; height:1px; background:var(--gold); opacity:.7; }
      h1{
        font-family:Georgia,"Iowan Old Style","Palatino Linotype",serif;
        font-weight:600; line-height:.94; letter-spacing:-.01em;
        font-size:clamp(2.3rem,7vw,4.1rem);
      }
      h1 em{ font-style:italic; color:var(--gold); }
    
      .stats{ display:flex; gap:clamp(16px,3vw,30px); text-align:right; flex-shrink:0; }
      .stat b{
        display:block; font-family:Georgia,serif; font-weight:600;
        font-size:clamp(1.5rem,4vw,2.1rem); line-height:1; letter-spacing:-.02em;
      }
      .stat span{
        display:block; margin-top:.35rem; font-size:.66rem; letter-spacing:.2em;
        text-transform:uppercase; color:var(--muted);
      }
    
      /* ---------- board ---------- */
      .board{
        position:relative;
        border:1px solid var(--line); border-radius:4px;
        padding:clamp(16px,3vw,28px) clamp(14px,3vw,26px) clamp(10px,2vw,18px);
        background:linear-gradient(180deg, rgba(58,38,24,.34), rgba(28,19,13,.5));
        box-shadow:inset 0 1px 0 rgba(255,255,255,.04), 0 30px 60px -30px rgba(0,0,0,.7);
      }
    
      svg.chart{ display:block; width:100%; height:auto; overflow:visible; }
    
      /* grid + axes */
      .grid-line{ stroke:var(--line); stroke-width:1; stroke-dasharray:2 5; }
      .baseline{ stroke:rgba(245,231,211,.4); stroke-width:1.5; }
      .axis-num{ fill:var(--muted); font-size:10px; letter-spacing:.04em; opacity:.85; }
    
      /* bars */
      .bar{
        fill:url(#coffeeGrad);
        transform-box:fill-box; transform-origin:bottom center;
        transition:filter .25s ease, opacity .3s ease;
      }
      .bar:hover, .bar:focus-visible{ filter:brightness(1.2) saturate(1.08); outline:none; }
      svg.chart.has-hover .bar:not(:hover):not(:focus-visible){ opacity:.42; }
    
      /* day labels */
      .day-label{ fill:var(--muted); font-size:13px; letter-spacing:.16em; transition:fill .25s ease, opacity .3s ease; }
      svg.chart.has-hover .day-label:not(:hover):not(.active){ opacity:.4; }
      .day-label:hover{ fill:var(--ink); }
    
      /* value labels */
      .value-label{
        font-family:Georgia,serif; font-weight:600; font-size:18px; fill:var(--ink);
        paint-order:stroke; stroke:#140d08; stroke-width:3.5px; stroke-linejoin:round;
        transition:fill .2s ease;
      }
      .value-label.active{ fill:var(--gold); }
    
      /* reveal animation (JS adds .ready) */
      svg.chart:not(.ready) .bar{ transform:scaleY(0); }
      svg.chart.ready .bar{ animation:grow .95s cubic-bezier(.2,.85,.25,1) both; }
      svg.chart:not(.ready) .value-label{ opacity:0; }
      svg.chart.ready .value-label{ animation:fadeUp .5s ease both; }
      @keyframes grow{ from{ transform:scaleY(0); } to{ transform:scaleY(1); } }
      @keyframes fadeUp{ from{ opacity:0; transform:translateY(6px);} to{ opacity:1; transform:translateY(0);} }
    
      /* steam wisps */
      .steam{ fill:none; stroke:rgba(255,240,220,.5); stroke-width:3; stroke-linecap:round; opacity:.45; }
      svg.chart.ready .steam{ animation:drift 3.6s ease-in-out infinite; }
      @keyframes drift{
        0%   { transform:translateY(0);     opacity:0; }
        25%  { opacity:.5; }
        70%  { opacity:.18; }
        100% { transform:translateY(-30px); opacity:0; }
      }
    
      /* ---------- footer ---------- */
      .foot{
        display:flex; justify-content:space-between; align-items:center; gap:16px; flex-wrap:wrap;
        color:var(--muted); font-size:.78rem; letter-spacing:.02em;
      }
      .foot .peak b{ color:var(--ink); font-weight:600; }
      .foot .scale{ display:flex; align-items:center; gap:.5em; }
      .foot .swatch{ width:14px; height:14px; border-radius:3px; background:linear-gradient(180deg,#f2a94b,#6b3d1e); }
    
      @media (max-width:560px){
        .masthead{ flex-direction:column; align-items:flex-start; gap:18px; }
        .stats{ text-align:left; }
      }
    
      @media (prefers-reduced-motion: reduce){
        *{ animation:none !important; transition:none !important; }
        svg.chart:not(.ready) .bar{ transform:none; }
        svg.chart:not(.ready) .value-label{ opacity:1; }
      }
    </style>
    </head>
    <body>
      <div class="wrap">
    
        <header class="masthead">
          <div>
            <p class="kicker">The Coffee Counter</p>
            <h1>Week in <em>Cups</em></h1>
          </div>
          <div class="stats" aria-hidden="true">
            <div class="stat"><b id="totalStat">0</b><span>Total cups</span></div>
            <div class="stat"><b id="peakStat">—</b><span>Peak day</span></div>
          </div>
        </header>
    
        <section class="board" aria-label="Bar chart of coffee sold by weekday">
          <!-- Bars written directly in markup; height ∝ value (10px per cup) -->
          <svg class="chart" viewBox="0 0 720 400" role="img"
               aria-label="Bar chart: coffee sold each day — Monday 12, Tuesday 30, Wednesday 18, Thursday 24, Friday 6 cups.">
            <title>Coffee sold this week</title>
    
            <defs>
              <linearGradient id="coffeeGrad" x1="0" y1="0" x2="0" y2="1">
                <stop offset="0%"  stop-color="#f2a94b"/>
                <stop offset="55%" stop-color="#c87d34"/>
                <stop offset="100%" stop-color="#6b3d1e"/>
              </linearGradient>
            </defs>
    
            <!-- gridlines + axis numbers -->
            <line class="grid-line" x1="52" y1="340" x2="708" y2="340"/>
            <line class="grid-line" x1="52" y1="240" x2="708" y2="240"/>
            <line class="grid-line" x1="52" y1="140" x2="708" y2="140"/>
            <line class="baseline"  x1="52" y1="340" x2="708" y2="340"/>
    
            <text class="axis-num" x="44" y="344" text-anchor="end">0</text>
            <text class="axis-num" x="44" y="244" text-anchor="end">10</text>
            <text class="axis-num" x="44" y="144" text-anchor="end">20</text>
            <text class="axis-num" x="44" y="44"  text-anchor="end">30</text>
    
            <!-- bars -->
            <rect class="bar" x="76.8"  y="220" width="54.4" height="120" rx="4"/>
            <rect class="bar" x="206.4" y="40"  width="54.4" height="300" rx="4"/>
            <rect class="bar" x="336"   y="160" width="54.4" height="180" rx="4"/>
            <rect class="bar" x="465.6" y="100" width="54.4" height="240" rx="4"/>
            <rect class="bar" x="595.2" y="280" width="54.4" height="60"  rx="4"/>
    
            <!-- value labels -->
            <text class="value-label" data-value="12" x="104"   y="204" text-anchor="middle">12</text>
            <text class="value-label" data-value="30" x="233.6" y="24"  text-anchor="middle">30</text>
            <text class="value-label" data-value="18" x="363.2" y="144" text-anchor="middle">18</text>
            <text class="value-label" data-value="24" x="492.8" y="84"  text-anchor="middle">24</text>
            <text class="value-label" data-value="6"  x="622.4" y="264" text-anchor="middle">6</text>
    
            <!-- day labels -->
            <text class="day-label" data-index="0" x="104"   y="368" text-anchor="middle">MON</text>
            <text class="day-label" data-index="1" x="233.6" y="368" text-anchor="middle">TUE</text>
            <text class="day-label" data-index="2" x="363.2" y="368" text-anchor="middle">WED</text>
            <text class="day-label" data-index="3" x="492.8" y="368" text-anchor="middle">THU</text>
            <text class="day-label" data-index="4" x="622.4" y="368" text-anchor="middle">FRI</text>
    
            <!-- steam over the peak (Tuesday) -->
            <path class="steam" d="M225 30 q-7 -9 0 -18 q7 -9 0 -18"/>
            <path class="steam" style="animation-delay:.6s" d="M242 30 q7 -9 0 -18 q-7 -9 0 -18"/>
          </svg>
        </section>
    
        <footer class="foot">
          <span class="peak">Peak day: <b>Tuesday · 30 cups</b></span>
          <span class="scale"><span class="swatch"></span> one bar = cups poured that day</span>
        </footer>
    
      </div>
    
    <script>
    (function(){
      var chart   = document.querySelector('svg.chart');
      var bars    = Array.prototype.slice.call(chart.querySelectorAll('.bar'));
      var labels  = Array.prototype.slice.call(chart.querySelectorAll('.day-label'));
      var values  = Array.prototype.slice.call(chart.querySelectorAll('.value-label'));
      var totalEl = document.getElementById('totalStat');
    
      // stagger the bar reveal
      bars.forEach(function(b, i){ b.style.animationDelay = (i * 0.1) + 's'; });
      values.forEach(function(v, i){ v.style.animationDelay = (0.35 + i * 0.1) + 's'; });
    
      // highlight a bar on hover / focus, syncing its day + value label
      function activate(i){
        chart.classList.add('has-hover');
        labels[i].classList.add('active');
        values[i].classList.add('active');
      }
      function clear(){
        chart.classList.remove('has-hover');
        labels.forEach(function(l){ l.classList.remove('active'); });
        values.forEach(function(v){ v.classList.remove('active'); });
      }
      bars.concat(labels).forEach(function(el, i){
        el.addEventListener('mouseenter', function(){ activate(i); });
        el.addEventListener('mouseleave', clear);
        el.addEventListener('focus',      function(){ activate(i); });
        el.addEventListener('blur',       clear);
      });
    
      // count the total up once on load
      var target = values.reduce(function(s, v){ return s + (+v.dataset.value); }, 0);
      if (totalEl){
        var dur = 1200, t0 = null;
        function step(t){
          if (t0 === null) t0 = t;
          var p = Math.min((t - t0) / dur, 1);
          totalEl.textContent = Math.round(target * (1 - Math.pow(1 - p, 3)));
          if (p < 1) requestAnimationFrame(step); else totalEl.textContent = target;
        }
        requestAnimationFrame(step);
      }
    
      // trigger the entrance animation on the next frame
      requestAnimationFrame(function(){ requestAnimationFrame(function(){ chart.classList.add('ready'); }); });
    })();
    </script>
    </body>
    </html>
    ```
Building games 0 of 2
  • Build 2048Failed

    8,740 tokens: 462 read, 8,278 written · 5 min 44 s · 24.2 tok/s

    Build the game 2048 as one web page, playable with the arrow keys, with the board drawn on the page.
    
    In <script id="game">, define createGame() returning an object with move(dir) and state(). dir is "up", "down", "left" or "right". state() returns {board, score, over}: board is 4 rows of 4 numbers, top row first (0 is an empty cell), score is a number, over is a boolean.
    
    The rules, exactly:
    1. The board starts as this one, then a 2 is put in each of the first two empty cells in reading order (row by row from the top, left to right). The score starts at 0.
    [0, 0, 16, 0]
    [2, 0, 0, 4]
    [4, 16, 0, 0]
    [0, 0, 32, 0]
    2. A move slides every tile as far as it goes toward dir. Two tiles of the same value that meet merge into one tile of their sum, nearest the side they move toward first: moving left, [2,2,2,2] becomes [4,4,0,0] and [2,2,2,0] becomes [4,2,0,0]. A tile made by a merge does not merge again in the same move.
    3. Each merge adds the new tile's value to the score.
    4. If a move changed the board, a 2 is put in the first empty cell in reading order. A move that changes nothing does nothing.
    5. over is true when no move would change the board; then moves do nothing.
    
    Output one complete HTML document and nothing else, with all CSS and JavaScript inline and nothing loaded from another site. Put the game logic, and only it, in <script id="game">: it must not touch document, window or timers, because the site runs that script on its own and plays the game through createGame(). Wire the page in another <script>.

    Open the page on its own. It runs in a sandbox: no network, no access to this site.

    Page source
    ```html
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>2048 — Slide &amp; Merge</title>
    <style>
      :root{
        --bg:#0e1b2a; --ink:#f3ede2; --muted:#7f95ab;
        --panel:#16273c; --line:rgba(255,255,255,.08);
        --gold:#f2c14e; --danger:#ef6b5a;
      }
      *{box-sizing:border-box;}
      html,body{margin:0;padding:0;}
      body{
        min-height:100vh; color:var(--ink);
        font-family:"Trebuchet MS","Segoe UI",system-ui,sans-serif;
        background:
          radial-gradient(1200px 700px at 8% -10%, rgba(63,141,195,.20), transparent 60%),
          radial-gradient(1000px 800px at 108% 112%, rgba(242,193,78,.13), transparent 55%),
          linear-gradient(160deg,#0e1b2a,#0a1420 55%,#0c1a29);
        -webkit-font-smoothing:antialiased;
      }
    
      /* ---------- ambient background ---------- */
      .bg{position:fixed;inset:0;z-index:-1;overflow:hidden;}
      .glow{position:absolute;border-radius:50%;filter:blur(70px);opacity:.5;}
      .g1{width:52vw;height:52vw;left:-12vw;top:-16vw;background:radial-gradient(circle,rgba(63,141,195,.55),transparent 70%);animation:drift1 26s ease-in-out infinite;}
      .g2{width:48vw;height:48vw;right:-14vw;bottom:-18vw;background:radial-gradient(circle,rgba(242,193,78,.42),transparent 70%);animation:drift2 32s ease-in-out infinite;}
      .g3{width:30vw;height:30vw;left:52%;top:42%;background:radial-gradient(circle,rgba(196,110,181,.30),transparent 70%);animation:drift1 40s ease-in-out infinite reverse;}
      @keyframes drift1{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(6vw,4vh) scale(1.12)}}
      @keyframes drift2{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(-5vw,-3vh) scale(1.1)}}
      .grid{position:absolute;inset:-2px;opacity:.4;
        background-image:linear-gradient(rgba(255,255,255,.03) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.03) 1px,transparent 1px);
        background-size:46px 46px;
        -webkit-mask-image:radial-gradient(circle at 50% 42%,#000 0%,transparent 78%);
        mask-image:radial-gradient(circle at 50% 42%,#000 0%,transparent 78%);}
      .tile-float{position:absolute;width:56px;height:56px;border-radius:14px;display:flex;align-items:center;justify-content:center;font-weight:800;color:#fff;opacity:.06;box-shadow:inset 0 -3px 0 rgba(0,0,0,.2);animation:floaty 18s ease-in-out infinite;}
      @keyframes floaty{0%,100%{transform:translateY(0) rotate(-8deg)}50%{transform:translateY(-34px) rotate(8deg)}}
    
      /* ---------- layout ---------- */
      .wrap{max-width:1080px;margin:0 auto;padding:clamp(20px,4vw,48px);display:grid;grid-template-columns:minmax(0,1fr) minmax(300px,360px);gap:clamp(24px,4vw,56px);align-items:center;}
      @media(max-width:900px){.wrap{grid-template-columns:1fr;justify-items:center;text-align:left;}}
    
      /* ---------- hero ---------- */
      .eyebrow{display:inline-flex;align-items:center;gap:8px;font-size:.72rem;letter-spacing:.34em;text-transform:uppercase;color:var(--gold);font-weight:700;margin-bottom:18px;}
      .dot{width:8px;height:8px;border-radius:50%;background:var(--gold);box-shadow:0 0 12px var(--gold);animation:pulse 2s ease-in-out infinite;}
      @keyframes pulse{0%,100%{opacity:.4;transform:scale(.8)}50%{opacity:1;transform:scale(1.2)}}
      h1.title{margin:0;font-size:clamp(3rem,10vw,6.4rem);line-height:.9;font-weight:800;letter-spacing:-.03em;display:flex;align-items:baseline;gap:.15em;}
      h1.title .t20{color:#fff;text-shadow:0 8px 30px rgba(0,0,0,.4);}
      h1.title .t48{color:var(--gold);text-shadow:0 8px 34px rgba(242,193,78,.5);}
      .tagline{margin:20px 0 26px;max-width:44ch;font-size:clamp(1rem,1.6vw,1.18rem);line-height:1.55;color:#c9d6e4;}
      .howto{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:28px;}
      .chip{display:inline-flex;align-items:center;gap:8px;padding:9px 14px;border-radius:12px;background:rgba(255,255,255,.04);border:1px solid var(--line);font-size:.9rem;color:#dfe7f0;}
      .chip b{color:var(--gold);}
      .keys{display:inline-flex;gap:4px;}
      kbd{display:inline-grid;place-items:center;min-width:26px;height:26px;padding:0 7px;border-radius:8px;background:#1c2f45;border:1px solid rgba(255,255,255,.1);border-bottom-width:3px;font-family:inherit;font-size:.8rem;color:#eaf0f6;}
      .actions{display:flex;flex-wrap:wrap;gap:12px;margin-bottom:30px;}
      .btn{font:inherit;font-weight:700;font-size:.95rem;padding:13px 22px;border-radius:13px;border:1px solid transparent;cursor:pointer;display:inline-flex;align-items:center;gap:8px;transition:transform .16s,box-shadow .2s,background .2s,border-color .2s;}
      .btn:active{transform:translateY(1px);}
      .btn.primary{background:linear-gradient(135deg,#f7cf6a,#e89b2c);color:#3a2405;box-shadow:0 10px 26px rgba(232,155,44,.34);}
      .btn.primary:hover{transform:translateY(-2px);box-shadow:0 16px 34px rgba(232,155,44,.48);}
      .btn.ghost{background:rgba(255,255,255,.04);color:var(--ink);border-color:var(--line);}
      .btn.ghost:hover{background:rgba(255,255,255,.09);transform:translateY(-2px);}
    
      /* ---------- board card ---------- */
      .board-card{position:relative;width:min(94vw,460px);aspect-ratio:1;padding:18px;border-radius:26px;background:linear-gradient(160deg,#1a2d45,#132238);border:1px solid rgba(255,255,255,.09);box-shadow:0 30px 70px rgba(0,0,0,.5),inset 0 1px 0 rgba(255,255,255,.06);}
      .board-card::before{content:"";position:absolute;inset:-2px;border-radius:28px;background:linear-gradient(135deg,rgba(242,193,78,.5),transparent 40%,transparent 60%,rgba(63,141,195,.4));z-index:-1;filter:blur(22px);opacity:.5;}
      .board{position:relative;width:100%;height:100%;display:grid;grid-template-columns:repeat(4,1fr);grid-template-rows:repeat(4,1fr);gap:clamp(8px,2.4vw,13px);}
      .cell{border-radius:16px;background:rgba(9,17,28,.55);box-shadow:inset 0 2px 8px rgba(0,0,0,.45),inset 0 -1px 0 rgba(255,255,255,.03);}
    
      /* ---------- tiles ---------- */
      .tile{position:absolute;top:0;left:0;will-change:transform;display:flex;align-items:center;justify-content:center;border-radius:16px;font-weight:800;line-height:1;color:#fff;background:#9f9f9f;box-shadow:inset 0 -4px 0 rgba(0,0,0,.2),inset 0 2px 0 rgba(255,255,255,.16),0 6px 14px rgba(0,0,0,.3);z-index:2;transition:transform .17s cubic-bezier(.2,.75,.3,1.18),opacity .18s ease;}
      .tile.moving{transition:transform .17s cubic-bezier(.2,.75,.3,1.18);}
      .tile.pop{animation:pop .2s ease;z-index:4;}
      @keyframes pop{0%{scale:.5;opacity:.4}60%{scale:1.14}100%{scale:1;opacity:1}}
      .t-2{background:#93a7c0;color:#0d1a2b;}
      .t-4{background:#b08ad0;color:#fff;}
      .t-8{background:#ef9f57;}
      .t-16{background:#ec7d4e;}
      .t-32{background:#e8623c;}
      .t-64{background:#e34a30;box-shadow:inset 0 -4px 0 rgba(0,0,0,.2),inset 0 2px 0 rgba(255,255,255,.16),0 8px 22px rgba(227,74,48,.4);}
      .t-128{background:#f2c14e;color:#3a2405;}
      .t-256{background:#f0b429;color:#3a2405;box-shadow:inset 0 -4px 0 rgba(0,0,0,.18),inset 0 2px 0 rgba(255,255,255,.2),0 0 26px rgba(240,180,41,.4);}
      .t-512{background:#f39c12;color:#fff;box-shadow:inset 0 -4px 0 rgba(0,0,0,.2),inset 0 2px 0 rgba(255,255,255,.18),0 0 30px rgba(243,156,18,.5);}
      .t-1024{background:#f57f17;color:#fff;box-shadow:inset 0 -4px 0 rgba(0,0,0,.2),inset 0 2px 0 rgba(255,255,255,.18),0 0 34px rgba(245,127,23,.6);}
      .t-2048{background:#ffd54f;color:#3a2405;box-shadow:inset 0 -4px 0 rgba(0,0,0,.16),inset 0 2px 0 rgba(255,255,255,.28),0 0 44px rgba(255,213,79,.7);}
      .t-super{background:#7c5cff;color:#fff;box-shadow:inset 0 -4px 0 rgba(0,0,0,.22),inset 0 2px 0 rgba(255,255,255,.22),0 0 40px rgba(124,92,255,.6);}
    
      /* ---------- stats ---------- */
      .stats{display:flex;gap:14px;margin-bottom:20px;}
      .stat{flex:1;padding:16px 18px;border-radius:18px;background:linear-gradient(160deg,#1a2d45,#132238);border:1px solid rgba(255,255,255,.07);box-shadow:0 14px 34px rgba(0,0,0,.35);}
      .stat .label{display:block;font-size:.68rem;letter-spacing:.2em;text-transform:uppercase;color:var(--muted);margin-bottom:9px;}
      .stat .value{font-size:clamp(1.7rem,4.4vw,2.4rem);font-weight:800;line-height:1;font-variant-numeric:tabular-nums;letter-spacing:-.01em;}
      .stat.score .value{color:var(--gold);}
      .gain{position:absolute;top:6px;right:14px;font-weight:800;color:var(--gold);font-size:1rem;animation:floatUp .7s ease forwards;pointer-events:none;text-shadow:0 2px 8px rgba(0,0,0,.5);}
      @keyframes floatUp{0%{opacity:0;transform:translateY(6px)}20%{opacity:1}100%{opacity:0;transform:translateY(-24px)}}
    
      .panel-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:22px;}
      .hint{font-size:.85rem;color:var(--muted);}
      .best-badge{font-size:.72rem;letter-spacing:.06em;text-transform:uppercase;padding:6px 12px;border-radius:999px;background:rgba(242,193,78,.14);color:var(--gold);border:1px solid rgba(242,193,78,.3);}
    
      /* ---------- overlays ---------- */
      .overlay{position:absolute;inset:0;border-radius:26px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;background:rgba(10,18,30,.84);backdrop-filter:blur(4px);opacity:0;visibility:hidden;transition:opacity .35s;z-index:20;text-align:center;padding:20px;}
      .overlay.show{opacity:1;visibility:visible;}
      .overlay h2{margin:0;font-size:clamp(1.8rem,6vw,2.6rem);font-weight:800;letter-spacing:-.01em;}
      .overlay p{margin:0;color:#c9d6e4;font-size:.95rem;}
    
      /* ---------- toast ---------- */
      .toast{position:fixed;left:50%;bottom:26px;transform:translateX(-50%) translateY(20px);background:#1c2f45;border:1px solid var(--line);color:var(--ink);padding:12px 20px;border-radius:12px;font-size:.9rem;opacity:0;transition:.3s;z-index:60;box-shadow:0 12px 30px rgba(0,0,0,.4);}
      .toast.show{opacity:1;transform:translateX(-50%) translateY(0);}
    
      /* ---------- reveal ---------- */
      .reveal{opacity:0;animation:rise .7s cubic-bezier(.2,.7,.3,1) forwards;}
      @keyframes rise{from{opacity:0;transform:translateY(24px)}to{opacity:1;transform:none}}
    
      @media(prefers-reduced-motion:reduce){*{animation-duration:.001ms!important;transition-duration:.001ms!important;}}
    </style>
    </head>
    <body>
      <div class="bg" aria-hidden="true">
        <div class="glow g1"></div>
        <div class="glow g2"></div>
        <div class="glow g3"></div>
        <div class="grid"></div>
        <div class="tile-float t-2048" style="left:6%;top:16%;font-size:.9rem;animation-duration:22s;">2048</div>
        <div class="tile-float t-512"  style="right:8%;top:24%;font-size:1.3rem;animation-duration:17s;animation-delay:-4s;">512</div>
        <div class="tile-float t-16"   style="left:14%;bottom:12%;font-size:1.4rem;animation-duration:20s;animation-delay:-8s;">16</div>
        <div class="tile-float t-128"  style="right:12%;bottom:16%;font-size:1rem;animation-duration:24s;animation-delay:-2s;">128</div>
        <div class="tile-float t-8"    style="left:44%;top:70%;font-size:1.5rem;animation-duration:19s;animation-delay:-6s;">8</div>
      </div>
    
      <main class="wrap">
        <!-- HERO -->
        <section class="hero reveal" style="animation-delay:.05s">
          <span class="eyebrow"><span class="dot"></span> Slide · Merge · Climb</span>
          <h1 class="title"><span class="t20">20</span><span class="t48">48</span></h1>
          <p class="tagline">Nudge the tiles, fold matching pairs into bigger powers of two, and chase the golden 2048. One merge at a time — every square counts.</p>
    
          <div class="howto">
            <span class="chip"><span class="keys"><kbd>←</kbd><kbd>→</kbd><kbd>↑</kbd><kbd>↓</kbd></span> slide the board</span>
            <span class="chip"><b>Match</b> two equal tiles to merge</span>
            <span class="chip">Each merge <b>adds its value</b> to your score</span>
          </div>
    
          <div class="actions">
            <button class="btn primary" id="newGame">New Game</button>
            <button class="btn ghost" id="undo">Undo</button>
          </div>
    
          <div class="board-card reveal" style="animation-delay:.18s">
            <div class="board" id="board"></div>
            <div class="overlay" id="overlay">
              <h2 id="ovTitle">Game over</h2>
              <p id="ovText">No moves left.</p>
              <button class="btn primary" id="again">Play again</button>
            </div>
          </div>
        </section>
    
        <!-- PANEL -->
        <aside class="panel reveal" style="animation-delay:.28s">
          <div class="stats">
            <div class="stat score"><span class="label">Score</span><span class="value" id="score">0</span></div>
            <div class="stat best"><span class="label">Best</span><span class="value" id="best">0</span></div>
          </div>
    
          <button class="btn ghost" id="undo2" style="width:100%;justify-content:center;">↶ Undo last move</button>
    
          <div class="panel-foot">
            <span class="hint">Tip: open a corner, keep your biggest tile tucked in.</span>
            <span class="best-badge" id="badge">in play</span>
          </div>
        </aside>
      </main>
    
      <div class="toast" id="toast"></div>
    
      <!-- ============ GAME LOGIC (pure, no DOM / window / timers) ============ -->
      <script id="game">
      function createGame(){
        var start = [
          [0, 0, 16, 0],
          [2, 0,  0, 4],
          [4, 16,  0, 0],
          [0, 0, 32, 0]
        ];
    
        function cloneBoard(b){ return b.map(function(r){ return r.slice(); }); }
    
        function spawnTwo(board){
          var empties = [];
          for (var r=0; r<4; r++) for (var c=0; c<4; c++) if (board[r][c]===0) empties.push([r,c]);
          for (var i=0; i<2 && i<empties.length; i++){
            board[empties[i][0]][empties[i][1]] = 2;
          }
        }
    
        var board = cloneBoard(start);
        spawnTwo(board);
        var score = 0;
    
        function computeOver(b){
          for (var r=0; r<4; r++) for (var c=0; c<4; c++){
            if (b[r][c]===0) return false;
            if (c<3 && b[r][c]===b[r][c+1]) return false;
            if (r<3 && b[r][c]===b[r+1][c]) return false;
          }
          return true;
        }
    
        function move(dir){
          var horizontal = (dir==='left' || dir==='right');
          var forward = (dir==='left' || dir==='up');
    
          var nb = cloneBoard(board);
          var changed = false;
          var gained = 0;
    
          for (var i=0; i<4; i++){
            var line = [];
            for (var j=0; j<4; j++){
              if (horizontal) line.push(board[j][i]);
              else            line.push(board[i][j]);
            }
            if (!forward) line.reverse();
    
            var out = [], k = 0, m = line.length;
            while (k < m){
              if (line[k] === 0){ k++; continue; }
              if (k+1 < m && line[k+1] === line[k]){
                var sum = line[k]*2;
                out.push(sum);
                gained += sum;
                changed = true;
                k += 2;
              } else {
                out.push(line[k]);
                k++;
              }
            }
            while (out.length < 4) out.push(0);
    
            if (!forward) out.reverse();
    
            for (var j=0; j<4; j++){
              var target = horizontal ? nb[j][i] : nb[i][j];
              if (target !== out[j]) changed = true;
              if (horizontal) nb[j][i] = out[j];
              else            nb[i][j] = out[j];
            }
          }
    
          if (!changed) return false;
          board = nb;
          score += gained;
          spawnTwo(board);
          return true;
        }
    
        function state(){
          return { board: cloneBoard(board), score: score, over: computeOver(board) };
        }
    
        return { move: move, state: state };
      }
      </script>
    
      <!-- ============ PAGE WIRING (the only script that touches the DOM) ============ -->
      <script>
      (function(){
        "use strict";
    
        var game = createGame();
        var boardEl = document.getElementById('board');
        var scoreEl = document.getElementById('score');
        var bestEl  = document.getElementById('best');
        var overlay = document.getElementById('overlay');
        var ovTitle = document.getElementById('ovTitle');
        var ovText  = document.getElementById('ovText');
        var badge   = document.getElementById('badge');
        var toastEl = document.getElementById('toast');
    
        // --- background cells (fixed) ---
        for (var i=0; i<16; i++){
          var cell = document.createElement('div');
          cell.className = 'cell';
          boardEl.appendChild(cell);
        }
    
        // --- geometry helpers ---
        function geom(){
          var bRect = boardEl.getBoundingClientRect();
          var cells = boardEl.querySelectorAll('.cell');
          var c0 = cells[0].getBoundingClientRect();
          return { size: c0.width, gap: (bRect.width - 4*c0.width)/3 };
        }
        function transformFor(r,c,g){ return 'translate(' + (c*(g.size+g.gap)) + 'px,' + (r*(g.size+g.gap)) + 'px)'; }
        function fontSize(v, size){
          var len = String(v).length;
          if (len <= 2) return size*0.5;
          if (len === 3) return size*0.4;
          if (len === 4) return size*0.31;
          return size*0.24;
        }
        function tileClass(v){ return v > 2048 ? 't-super' : 't-' + v; }
    
        // --- score animation ---
        var shownScore = 0, scoreAnimId = null;
        function animateScore(target){
          if (scoreAnimId) cancelAnimationFrame(scoreAnimId);
          var from = shownScore, start = performance.now(), dur = 450;
          function step(now){
            var p = Math.min(1, (now-start)/dur);
            var e = 1 - Math.pow(1-p, 3);
            shownScore = Math.round(from + (target-from)*e);
            scoreEl.textContent = shownScore.toLocaleString();
            if (p < 1) scoreAnimId = requestAnimationFrame(step);
          }
          scoreAnimId = requestAnimationFrame(step);
        }
    
        // --- render from state (with optional pop values) ---
        function render(s, popVals){
          var g = geom();
          boardEl.querySelectorAll('.tile').forEach(function(el){ el.remove(); });
          for (var r=0; r<4; r++){
            for (var c=0; c<4; c++){
              var v = s.board[r][c];
              if (!v) continue;
              var el = document.createElement('div');
              el.className = 'tile ' + tileClass(v);
              el.textContent = v;
              el.style.width = g.size + 'px';
              el.style.height = g.size + 'px';
              el.style.fontSize = fontSize(v, g.size) + 'px';
              el.style.transform = transformFor(r,c,g);
              if (popVals && popVals.indexOf(v) !== -1){
                el.classList.add('pop');
                (function(node){ setTimeout(function(){ node.classList.remove('pop'); }, 240); })(el);
              }
              boardEl.appendChild(el);
            }
          }
        }
    
        // --- animated move using the game's own state() ---
        function doMove(dir){
          if (game.state().over) return;
          var before = game.state();
          var moved = game.move(dir);
          if (!moved) return;
          var after = game.state();
    
          // detect new spawns for pop highlight
          var pops = [];
          var seen = 0, spawnCount = 0;
          for (var r=0; r<4; r++) for (var c=0; c<4; c++){
            if (before.board[r][c] === after.board[r][c]) seen++;
          }
          // count cells that changed from 0 to 2 in reading order = spawned tiles
          var spawnVals = [];
          var idx = 0;
          for (var rr=0; rr<4; rr++) for (var cc=0; cc<4; cc++){
            if (before.board[rr][cc] === 0 && after.board[rr][cc] !== 0) spawnVals.push(after.board[rr][cc]);
          }
    
          var g = geom();
          // place "after" tiles at their BEFORE positions, then transition to final
          boardEl.querySelectorAll('.tile').forEach(function(el){ el.remove(); });
          var tiles = [];
          for (var r2=0; r2<4; r2++){
            for (var c2=0; c2<4; c2++){
              var v = after.board[r2][c2];
              if (!v) continue;
              // find a source: same value in before that wasn't consumed — approximate by scanning before for matching value at a different or same cell
              var src = null;
              for (var sr=0; sr<4 && !src; sr++) for (var sc=0; sc<4 && !src; sc++){
                if (before.board[sr][sc] === v){ src = [sr,sc]; }
              }
              var el = document.createElement('div');
              el.className = 'tile moving ' + tileClass(v);
              el.textContent = v;
              el.style.width = g.size + 'px';
              el.style.height = g.size + 'px';
              el.style.fontSize = fontSize(v, g.size) + 'px';
              if (src){ el.style.transform = transformFor(src[0], src[1], g); }
              else { el.style.transform = transformFor(r2,c2,g); }
              boardEl.appendChild(el);
              tiles.push({ el: el, r: r2, c: c2 });
            }
          }
          requestAnimationFrame(function(){
            requestAnimationFrame(function(){
              tiles.forEach(function(t){ t.el.style.transform = transformFor(t.r, t.c, g); });
            });
          });
    
          // score + best
          animateScore(after.score);
          if (after.score > shownBest) { shownBest = after.score; saveBest(); }
          bestEl.textContent = shownBest.toLocaleString();
    
          // gain floater
          var gained = after.score - before.score;
          if (gained > 0){
            var gain = document.createElement('div');
            gain.className = 'gain';
            gain.textContent = '+' + gained;
            boardEl.appendChild(gain);
            setTimeout(function(){ gain.remove(); }, 720);
          }
    
          // settle -> final render (pop the spawns)
          setTimeout(function(){
            render(after, spawnVals.length ? [spawnVals[0]] : null);
            updateOver();
          }, 190);
        }
    
        function updateOver(){
          var s = game.state();
          if (s.over){
            ovTitle.textContent = 'Game over';
            ovText.textContent = 'You reached ' + s.score.toLocaleString() + '. No moves left.';
            badge.textContent = 'game over';
            overlay.classList.add('show');
          } else {
            overlay.classList.remove('show');
            badge.textContent = 'in play';
          }
        }
    
        // --- best score (session-safe) ---
        var shownBest = 0;
        function loadBest(){ try { return parseInt(localStorage.getItem('best2048') || '0', 10) || 0; } catch(e){ return 0; } }
        function saveBest(){ try { localStorage.setItem('best2048', String(shownBest)); } catch(e){} }
        shownBest = loadBest();
    
        // --- toast ---
        var toastTimer = null;
        function toast(msg){
          toastEl.textContent = msg;
          toastEl.classList.add('show');
          if (toastTimer) clearTimeout(toastTimer);
          toastTimer = setTimeout(function(){ toastEl.classList.remove('show'); }, 1600);
        }
    
        // --- reset ---
        function newGame(){
          game = createGame();
          shownScore = 0;
          scoreEl.textContent = '0';
          overlay.classList.remove('show');
          render(game.state(), null);
          toast('Fresh board — good luck!');
        }
    
        // --- wire controls ---
        var keys = { ArrowLeft:'left', ArrowRight:'right', ArrowUp:'up', ArrowDown:'down' };
        window.addEventListener('keydown', function(e){
          if (e.key in keys){ e.preventDefault(); doMove(keys[e.key]); }
        });
    
        document.getElementById('newGame').addEventListener('click', newGame);
        document.getElementById('again').addEventListener('click', newGame);
    
        // simple single-step undo via a lightweight history of states (rebuild not possible, so we just re-render last)
        var history = [];
        function pushHistory(){ history.push(game.state()); if (history.length > 40) history.shift(); }
        // capture state before each successful move by wrapping doMove
        var _doMove = doMove;
        doMove = function(dir){
          if (game.state().over) return;
          pushHistory();
          _doMove(dir);
        };
        function undo(){
          if (!history.length){ toast('Nothing to undo'); return; }
          // We cannot replay a single move backwards through createGame, so we just re-render the previous state for feedback and note it.
          var prev = history.pop();
          render(prev, null);
          animateScore(prev.score);
          overlay.classList.remove('show');
          badge.textContent = 'in play';
          toast('Reverted view (logic keeps advancing on next move)');
        }
        document.getElementById('undo').addEventListener('click', undo);
        document.getElementById('undo2').addEventListener('click', undo);
    
        // --- init ---
        bestEl.textContent = shownBest.toLocaleString();
        render(game.state(), null);
        updateOver();
      })();
      </script>
    </body>
    </html>
    ```
  • Build SnakeFailed

    7,432 tokens: 457 read, 6,975 written · 4 min 48 s · 24.4 tok/s

    Build Snake as one web page on a 10 by 10 grid, playable with the arrow keys (one key press, one step), with the grid drawn on the page.
    
    In <script id="game">, define createGame() returning an object with step(dir) and state(). dir is "up", "down", "left" or "right". state() returns {snake, food, score, over}: snake is a list of [x, y] cells, head first; food is [x, y]; score is a number; over is a boolean. x is the column (0 to 9, left to right), y the row (0 to 9, top to bottom); up is y - 1.
    
    The rules, exactly:
    1. The game starts with snake [[6, 5], [7, 5], [8, 5]], moving left, food at [4, 8], score 0.
    2. step(dir): if dir is the opposite of the current direction it is ignored and the snake keeps going; otherwise dir becomes the current direction. The head moves one cell that way.
    3. If the new head cell holds the food, the snake grows: its tail stays. Otherwise the tail cell is freed first.
    4. If the new head is off the grid or on a cell of the snake (after rule 3), the game is over: over becomes true and nothing else changes. Once over, step does nothing.
    5. Eating adds 1 to the score, and the next food goes to the first empty cell in reading order (row by row from the top, left to right) after the new head's cell, wrapping from [9, 9] to [0, 0].
    
    Output one complete HTML document and nothing else, with all CSS and JavaScript inline and nothing loaded from another site. Put the game logic, and only it, in <script id="game">: it must not touch document, window or timers, because the site runs that script on its own and plays the game through createGame(). Wire the page in another <script>.

    Open the page on its own. It runs in a sandbox: no network, no access to this site.

    Page source
    Here's a complete, self-contained Snake page. The engine lives entirely inside `<script id="game">` (pure logic, no DOM/timers), and a second script wires up the grid, input, sound, and motion.
    
    ```html
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>SNAKE · 10×10</title>
    <style>
    :root{
      --bg:#0a241f;
      --ink:#eafff6;
      --muted:#7fb8ab;
      --line:rgba(120,225,196,.14);
      --cell:rgba(255,255,255,.018);
      --accent:#39d98a;
      --accent-soft:#7ff0b8;
      --danger:#ff5f6d;
      --gold:#ffd166;
      --font-mono: ui-monospace,"SF Mono","JetBrains Mono","Cascadia Code","Fira Code",Menlo,Consolas,monospace;
      --font-body: system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
    }
    *{box-sizing:border-box;}
    html,body{height:100%;}
    body{
      margin:0; min-height:100vh; overflow-x:hidden;
      font-family:var(--font-body); color:var(--ink); background:var(--bg);
      display:flex; align-items:center; justify-content:center; padding:24px;
      -webkit-font-smoothing:antialiased;
    }
    
    /* ambient layers */
    body::before{
      content:""; position:fixed; inset:-10%; z-index:0; pointer-events:none;
      background:
        radial-gradient(58% 52% at 16% 8%, rgba(57,217,138,.20), transparent 60%),
        radial-gradient(52% 52% at 92% 94%, rgba(255,95,109,.12), transparent 60%),
        radial-gradient(42% 42% at 82% 12%, rgba(255,209,102,.07), transparent 60%);
      animation:drift 24s ease-in-out infinite alternate;
    }
    body::after{
      content:""; position:fixed; inset:0; z-index:0; pointer-events:none; opacity:.5;
      background-image:linear-gradient(var(--line) 1px,transparent 1px),linear-gradient(90deg,var(--line) 1px,transparent 1px);
      background-size:46px 46px;
      -webkit-mask:radial-gradient(circle at 50% 42%, #000, transparent 78%);
              mask:radial-gradient(circle at 50% 42%, #000, transparent 78%);
    }
    @keyframes drift{ to{ transform:translate3d(1.6%,-1.4%,0) scale(1.05);} }
    
    /* board */
    .board{ position:relative; z-index:1; width:min(92vw,560px); animation:rise .7s cubic-bezier(.2,.8,.2,1) both; }
    @keyframes rise{ from{opacity:0; transform:translateY(16px);} to{opacity:1; transform:none;} }
    
    .topbar{ display:flex; align-items:center; justify-content:space-between; margin-bottom:14px; }
    .brand{ display:flex; align-items:center; gap:12px; }
    .mark{ width:30px; height:30px; border-radius:8px; position:relative; background:rgba(57,217,138,.1); border:1px solid rgba(57,217,138,.4); box-shadow:inset 0 0 12px rgba(57,217,138,.25); }
    .mark::before{ content:""; position:absolute; inset:6px; border-radius:5px; background:var(--accent); box-shadow:0 0 14px var(--accent); animation:blink 1.9s ease-in-out infinite; }
    .mark::after{ content:""; position:absolute; left:8px; top:8px; width:4px; height:4px; border-radius:50%; background:#06231c; }
    @keyframes blink{ 0%,100%{opacity:.75;} 50%{opacity:1;} }
    .brand h1{ margin:0; font-family:var(--font-mono); font-size:clamp(22px,5.4vw,30px); font-weight:800; letter-spacing:-.02em; line-height:.9; }
    .brand .sub{ display:block; font-size:11px; letter-spacing:.24em; text-transform:uppercase; color:var(--muted); margin-top:5px; }
    
    .stats{ display:flex; align-items:center; gap:8px; }
    .stat{ background:rgba(255,255,255,.03); border:1px solid var(--line); border-radius:12px; padding:7px 12px; min-width:64px; text-align:right; transition:border-color .2s; }
    .stat b{ display:block; font-family:var(--font-mono); font-size:20px; font-weight:700; line-height:1.1; font-variant-numeric:tabular-nums; }
    .stat span{ display:block; font-size:9px; letter-spacing:.18em; text-transform:uppercase; color:var(--muted); margin-top:2px; }
    .icon-btn{ width:40px; height:40px; border-radius:12px; border:1px solid var(--line); background:rgba(255,255,255,.03); color:var(--ink); font-size:16px; cursor:pointer; display:grid; place-items:center; transition:.18s; }
    .icon-btn:hover{ border-color:var(--accent); color:var(--accent-soft); transform:translateY(-1px); }
    
    /* stage + frame */
    .stage{ position:relative; padding:16px; border-radius:24px; background:linear-gradient(180deg,rgba(255,255,255,.03),rgba(0,0,0,.14)); border:1px solid var(--line); box-shadow:0 40px 90px -30px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,255,255,.05); }
    .stage::before{ content:""; position:absolute; inset:6px; border-radius:18px; pointer-events:none; background:repeating-linear-gradient(0deg,rgba(0,0,0,.16) 0 2px,transparent 2px 4px); opacity:.5; mix-blend-mode:multiply; }
    .corner{ position:absolute; width:16px; height:16px; border:2px solid var(--accent); opacity:.55; z-index:3; pointer-events:none; }
    .c-tl{ top:-2px; left:-2px; border-right:0; border-bottom:0; border-top-left-radius:8px;}
    .c-tr{ top:-2px; right:-2px; border-left:0; border-bottom:0; border-top-right-radius:8px;}
    .c-bl{ bottom:-2px; left:-2px; border-right:0; border-top:0; border-bottom-left-radius:8px;}
    .c-br{ bottom:-2px; right:-2px; border-left:0; border-top:0; border-bottom-right-radius:8px;}
    
    .frame{ position:relative; padding:14px; border-radius:16px; background:radial-gradient(circle at 50% 40%, rgba(57,217,138,.05), transparent 70%), #071b17; border:1px solid rgba(120,225,196,.1); box-shadow:inset 0 0 40px rgba(0,0,0,.55); }
    .grid{ position:relative; display:grid; grid-template-columns:repeat(10,1fr); grid-template-rows:repeat(10,1fr); gap:3px; width:100%; aspect-ratio:1/1; border-radius:8px; overflow:hidden; }
    .cell{ background:var(--cell); border-radius:3px; box-shadow:inset 0 0 0 1px rgba(255,255,255,.02); transition:background .1s; }
    
    /* snake */
    .snake{ position:absolute; top:0; left:0; z-index:2; pointer-events:none; will-change:transform; }
    .seg{ position:absolute; top:0; left:0; border-radius:26%; background:#2fbf74; box-shadow:inset 0 1px 2px rgba(255,255,255,.35), inset 0 -3px 5px rgba(0,0,0,.35), 0 0 12px rgba(57,217,138,.3); transition:width .14s ease, height .14s ease, background .14s ease, box-shadow .14s ease; }
    .seg.head{ z-index:3; border-radius:30%; background:radial-gradient(circle at 35% 30%, #d6ffe9, var(--accent) 62%); box-shadow:0 0 18px rgba(57,217,138,.7), inset 0 0 6px rgba(255,255,255,.6); }
    .eye{ position:absolute; width:24%; height:24%; border-radius:50%; background:#06231c; box-shadow:inset 0 0 2px #000; }
    
    /* food */
    .food{ position:absolute; top:0; left:0; z-index:1; pointer-events:none; display:grid; place-items:center; will-change:transform; transition:transform .18s cubic-bezier(.2,.9,.3,1.3); }
    .apple{ width:56%; height:56%; border-radius:47% 47% 46% 46%/52% 52% 44% 44%; background:radial-gradient(circle at 34% 28%, #ff9a9e, var(--danger) 60%, #c11f2d); box-shadow:inset -2px -3px 6px rgba(0,0,0,.35), 0 0 14px rgba(255,95,109,.5); position:relative; animation:bob 1.8s ease-in-out infinite; }
    .apple::before{ content:""; position:absolute; top:-16%; left:50%; width:3px; height:26%; background:#7a4a2b; transform-origin:bottom center; transform:translateX(-50%) rotate(9deg); border-radius:2px; }
    .apple::after{ content:""; position:absolute; top:-18%; left:52%; width:16px; height:9px; background:#4fd37a; border-radius:0 100% 0 100%; transform:rotate(-22deg); box-shadow:0 0 6px rgba(79,211,122,.5); }
    @keyframes bob{ 0%,100%{transform:translateY(0) scale(1);} 50%{transform:translateY(-3%) scale(1.05);} }
    
    /* overlays */
    .overlay{ position:absolute; inset:0; z-index:5; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:12px; text-align:center; background:radial-gradient(circle at 50% 40%, rgba(7,27,23,.86), rgba(7,27,23,.95)); backdrop-filter:blur(3px); -webkit-backdrop-filter:blur(3px); opacity:0; visibility:hidden; transition:opacity .3s ease, visibility .3s; padding:16px; }
    .overlay.show{ opacity:1; visibility:visible; }
    .ov-kicker{ font-size:11px; letter-spacing:.28em; text-transform:uppercase; color:var(--accent-soft); }
    .ov-title{ margin:0; font-family:var(--font-mono); font-weight:800; letter-spacing:-.02em; font-size:clamp(30px,9vw,54px); line-height:.95; text-shadow:0 6px 30px rgba(57,217,138,.35); }
    .ov-title .accent{ color:var(--accent-soft); }
    .ov-sub{ margin:0; max-width:34ch; color:var(--muted); font-size:14px; line-height:1.55; }
    .ov-score{ font-family:var(--font-mono); font-size:15px; letter-spacing:.06em; color:var(--ink); }
    .ov-score b{ font-size:34px; color:var(--gold); margin-left:8px; text-shadow:0 0 20px rgba(255,209,102,.4); }
    .btn{ margin-top:6px; font-family:var(--font-mono); font-weight:700; letter-spacing:.02em; font-size:15px; color:#06231c; background:linear-gradient(180deg,var(--accent-soft),var(--accent)); border:none; border-radius:999px; padding:12px 26px; cursor:pointer; box-shadow:0 10px 24px -8px rgba(57,217,138,.7); transition:transform .15s, box-shadow .15s; }
    .btn:hover{ transform:translateY(-2px); box-shadow:0 16px 30px -8px rgba(57,217,138,.8); }
    .btn:active{ transform:translateY(0); }
    
    /* footer */
    .foot{ margin-top:16px; display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; }
    .hint{ font-size:12px; color:var(--muted); letter-spacing:.02em; }
    kbd{ font-family:var(--font-mono); font-size:11px; background:rgba(255,255,255,.06); border:1px solid var(--line); border-bottom-width:2px; border-radius:6px; padding:3px 7px; color:var(--ink); margin:0 1px; }
    .dpad{ display:grid; grid-template-columns:repeat(3,42px); grid-template-rows:repeat(3,42px); gap:6px; touch-action:none; user-select:none; -webkit-user-select:none; }
    .dk{ border-radius:12px; border:1px solid var(--line); background:rgba(255,255,255,.04); color:var(--ink); font-size:18px; cursor:pointer; display:grid; place-items:center; transition:.1s; }
    .dk:hover{ border-color:var(--accent); color:var(--accent-soft); }
    .dk:active{ background:rgba(57,217,138,.2); transform:scale(.94); }
    .dk.up{ grid-column:2; grid-row:1; } .dk.left{ grid-column:1; grid-row:2; } .dk.right{ grid-column:3; grid-row:2; } .dk.down{ grid-column:2; grid-row:3; }
    
    @media (max-width:560px){
      body{ padding:14px; align-items:flex-start; }
      .dpad{ display:none; }
    }
    @media (prefers-reduced-motion:reduce){
      *{ animation-duration:.001ms !important; animation-iteration-count:1 !important; transition-duration:.001ms !important; }
    }
    </style>
    </head>
    <body>
      <main class="board">
        <header class="topbar">
          <div class="brand">
            <span class="mark" aria-hidden="true"></span>
            <h1>SNAKE<span class="sub">10 × 10 grid</span></h1>
          </div>
          <div class="stats">
            <div class="stat"><b id="score">0</b><span>Score</span></div>
            <button class="icon-btn" id="soundBtn" aria-label="Toggle sound">🔊</button>
          </div>
        </header>
    
        <section class="stage">
          <span class="corner c-tl"></span><span class="corner c-tr"></span>
          <span class="corner c-bl"></span><span class="corner c-br"></span>
          <div class="frame">
            <div class="grid" id="grid"></div>
    
            <div class="overlay show" id="startOv">
              <p class="ov-kicker">Ready</p>
              <h2 class="ov-title">SNAKE<span class="accent">.</span></h2>
              <p class="ov-sub">Steer with the arrow keys. One key press = one step. Eat to grow — touch a wall or yourself and it's over.</p>
              <button class="btn" id="startBtn">▶ Start</button>
            </div>
    
            <div class="overlay" id="overOv">
              <p class="ov-kicker">Game over</p>
              <h2 class="ov-title">GAME<span class="accent">OVER</span></h2>
              <p class="ov-score">SCORE<b id="finalScore">0</b></p>
              <button class="btn" id="restartBtn">↻ Play again</button>
            </div>
          </div>
        </section>
    
        <footer class="foot">
          <p class="hint"><kbd>↑</kbd><kbd>↓</kbd><kbd>←</kbd><kbd>→</kbd> move &nbsp;·&nbsp; <kbd>R</kbd> restart</p>
          <div class="dpad" id="dpad" aria-hidden="true">
            <button class="dk up" data-dir="up">▲</button>
            <button class="dk left" data-dir="left">◀</button>
            <button class="dk right" data-dir="right">▶</button>
            <button class="dk down" data-dir="down">▼</button>
          </div>
        </footer>
      </main>
    
    <script id="game">
    function createGame(){
      var N = 10;
      var snake, food, score, over, dir;
    
      function reset(){
        snake = [[6,5],[7,5],[8,5]];
        food  = [4,8];
        score = 0;
        over  = false;
        dir   = "left";
      }
      reset();
    
      function opposite(a,b){
        return (a==="up"&&b==="down")||(a==="down"&&b==="up")||
               (a==="left"&&b==="right")||(a==="right"&&b==="left");
      }
      function delta(d){
        if(d==="up")    return [0,-1];
        if(d==="down")  return [0, 1];
        if(d==="left")  return [-1,0];
        if(d==="right") return [ 1,0];
        return [0,0];
      }
    
      function placeFood(){
        var hx = snake[0][0], hy = snake[0][1];
        var x = (hx + 1) % N, y = hy;
        for(var i=0;i<N*N;i++){
          if(snake.every(function(c){ return c[0]!==x || c[1]!==y; })){ food=[x,y]; return; }
          x++; if(x>=N){ x=0; y=(y+1)%N; }
        }
      }
    
      function step(d){
        if(over) return;
        if(!(opposite(dir,d))) dir = d;
        var dx = delta(dir)[0], dy = delta(dir)[1];
        var head = [snake[0][0]+dx, snake[0][1]+dy];
    
        var eat = (head[0]===food[0] && head[1]===food[1]);
        if(!eat) snake.pop();
    
        var x=head[0], y=head[1];
        if(x<0||x>=N||y<0||y>=N || snake.some(function(c){ return c[0]===x&&c[1]===y; })){
          over = true;
          return;
        }
    
        snake.unshift(head);
        if(eat){ score++; placeFood(); }
      }
    
      function state(){
        return {
          snake: snake.map(function(c){ return [c[0],c[1]]; }),
          food:  [food[0],food[1]],
          score: score,
          over:  over
        };
      }
    
      return { step: step, state: state, reset: reset };
    }
    </script>
    
    <script>
    (function(){
      "use strict";
      var N=10;
      var game = createGame();
    
      var gridEl   = document.getElementById('grid');
      var scoreEl  = document.getElementById('score');
      var startOv  = document.getElementById('startOv');
      var overOv   = document.getElementById('overOv');
      var finalEl  = document.getElementById('finalScore');
      var board    = document.querySelector('.board');
      var soundBtn = document.getElementById('soundBtn');
    
      // ---- build the grid cells ----
      var cellEls=[];
      for(var i=0;i<N*N;i++){
        var c=document.createElement('div');
        c.className='cell';
        gridEl.appendChild(c);
        cellEls.push(c);
      }
    
      // ---- snake + food DOM (positioned over the grid) ----
      var segEls=[];
      for(var s=0;s<N*N;s++){
        var seg=document.createElement('div');
        seg.className='seg';
        gridEl.appendChild(seg);
        segEls.push(seg);
      }
      var headEls=[document.createElement('div'),document.createElement('div')];
      headEls.forEach(function(e){ e.className='eye'; segEls[0].appendChild(e); });
    
      var foodEl=document.createElement('div');
      foodEl.className='food';
      var apple=document.createElement('div');
      apple.className='apple';
      foodEl.appendChild(apple);
      gridEl.appendChild(foodEl);
    
      // ---- sound ----
      var audioCtx=null, muted=false;
      function ac(){ if(!audioCtx){ try{ audioCtx=new (window.AudioContext||window.webkitAudioContext)(); }catch(e){} } return audioCtx; }
      function beep(freq,dur,type,vol){
        if(muted) return;
        var ctx=ac(); if(!ctx) return;
        var o=ctx.createOscillator(), g=ctx.createGain();
        o.type=type||'sine'; o.frequency.value=freq;
        o.connect(g); g.connect(ctx.destination);
        var t=ctx.currentTime;
        g.gain.setValueAtTime(0.0001,t);
        g.gain.exponentialRampToValueAtTime(vol||0.06,t+0.01);
        g.gain.exponentialRampToValueAtTime(0.0001,t+dur);
        o.start(t); o.stop(t+dur+0.02);
      }
      soundBtn.addEventListener('click',function(){
        muted=!muted;
        soundBtn.textContent=muted?'🔇':'🔊';
        if(!muted){ ac(); beep(660,0.08,'triangle',0.05); }
      });
    
      // ---- helpers ----
      function pct(v){ return (v*100)+'%'; }
      function cellSize(){ var r=gridEl.getBoundingClientRect(); return r.width/N; }
      function segSize(i,len){ var f=Math.max(0,1-(i/(len+2))*0.5); return Math.round(f*84)+16; }
    
      // ---- render ----
      function render(prevScore, prevFood){
        var st=game.state();
        var len=st.snake.length, cs=cellSize();
    
        for(var i=0;i<segEls.length;i++){
          if(i<len){
            segEls[i].style.display='block';
            var x=st.snake[i][0], y=st.snake[i][1];
            var sz=segSize(i,len);
            segEls[i].style.width=sz+'px';
            segEls[i].style.height=sz+'px';
            segEls[i].style.transform='translate('+(x*cs+((cs-sz)/2))+'px,'+(y*cs+((cs-sz)/2))+'px)';
          } else {
            segEls[i].style.display='none';
          }
        }
    
        var h=st.snake[0];
        var hx=h[0]*cs, hy=h[1]*cs;
        var ox=(hx+cs*0.5)/cs*100, oy=(hy+cs*0.5)/cs*100;
        var dx=0,dy=0;
        if(st.snake.length>1){ dx=st.snake[0][0]-st.snake[1][0]; dy=st.snake[0][1]-st.snake[1][1]; }
        var px=-dy*38, py=dx*38, ex=dx*30, ey=dy*30;
        headEls[0].style.left='calc('+ox+'% + '+(px+ex)+'%)';
        headEls[0].style.top ='calc('+oy+'% + '+(py+ey)+'%)';
        headEls[1].style.left='calc('+ox+'% + '+(-px+ex)+'%)';
        headEles_placeholder:;
        headEls[1].style.top ='calc('+oy+'% + '+(-py+ey)+'%)';
    
        foodEl.style.width=cs+'px';
        foodEl.style.height=cs+'px';
        foodEl.style.transform='translate('+(st.food[0]*cs)+'px,'+(st.food[1]*cs)+'px)';
    
        if(st.score!==prevScore){
          scoreEl.textContent=st.score;
          scoreEl.animate([{transform:'scale(1.45)',color:'#7ff0b8'},{transform:'scale(1)',color:''}],{duration:320,easing:'ease-out'});
        }
      }
    
      function flashCell(x,y){
        var el=cellEls[y*N+x];
        if(el) el.animate([{background:'rgba(57,217,138,.4)'},{background:'var(--cell)'}],{duration:360,easing:'ease-out'});
      }
    
      function shake(){
        board.animate([
          {transform:'translate(0,0)'},
          {transform:'translate(-6px,2px)'},{transform:'translate(5px,-3px)'},
          {transform:'translate(-4px,1px)'},{transform:'translate(3px,-2px)'},
          {transform:'translate(0,0)'}
        ],{duration:400,easing:'ease-out'});
      }
    
      // ---- input ----
      function move(d){ if(!game.state().over) game.step(d); afterStep(); }
      var KEY={ArrowUp:'up',ArrowDown:'down',ArrowLeft:'left',ArrowRight:'right'};
      window.addEventListener('keydown',function(e){
        if(KEY[e.key]){ e.preventDefault(); ac(); move(KEY[e.key]); return; }
        if(e.key==='r'||e.key==='R'){ resetGame(); }
      });
    
      document.querySelectorAll('.dk').forEach(function(b){
        b.addEventListener('pointerdown',function(e){ e.preventDefault(); ac(); move(b.dataset.dir); });
      });
    
      function afterStep(){
        var st=game.state();
        render(prevScore, prevFood);
        if(st.over){ gameOver(st.score); }
      }
    
      // ---- lifecycle ----
      var prevScore=0, prevFood=[4,8];
      function resetGame(){
        game.reset();
        prevScore=0; prevFood=[4,8];
        scoreEl.textContent='0';
        startOv.classList.remove('show');
        overOv.classList.remove('show');
        render(0,[4,8]);
      }
      function gameOver(score){
        finalEl.textContent=score;
        overOv.classList.add('show');
        shake();
        beep(150,0.28,'sawtooth',0.07);
        setTimeout(function(){ beep(90,0.34,'sawtooth',0.06); },110);
      }
    
      document.getElementById('startBtn').addEventListener('click',function(){ ac(); resetGame(); });
      document.getElementById('restartBtn').addEventListener('click',function(){ ac(); resetGame(); });
    
      // ---- init + resize ----
      render(0,[4,8]);
      window.addEventListener('resize',function(){ render(prevScore, prevFood); });
    })();
    </script>
    </body>
    </html>
    ```
Writing code 3 of 3
  • Merge intervalsPassed

    454 tokens: 160 read, 294 written · 12 s · 25.5 tok/s

    Write a JavaScript function mergeIntervals(intervals). intervals is an array of [start, end] pairs of integers with start <= end, in any order, possibly empty. Return a new array of the merged intervals sorted by start: intervals that overlap or touch (one ends where the next starts) become one. Do not change the input array or its pairs.
    
    mergeIntervals([[8, 10], [1, 3], [2, 6], [6, 7]]) returns [[1, 7], [8, 10]].
    
    Reply with one ```js code block holding plain JavaScript (no imports, no exports, no DOM, no timers). The site runs it with hidden tests.
    ```js
    function mergeIntervals(intervals) {
      if (!intervals || intervals.length === 0) return [];
    
      // Create a shallow copy of the array and sort by start (then end for stability)
      const sorted = intervals.map(iv => [iv[0], iv[1]]).sort((a, b) => {
        if (a[0] !== b[0]) return a[0] - b[0];
        return a[1] - b[1];
      });
    
      const merged = [];
      let currentStart = sorted[0][0];
      let currentEnd = sorted[0][1];
    
      for (let i = 1; i < sorted.length; i++) {
        const start = sorted[i][0];
        const end = sorted[i][1];
    
        if (start <= currentEnd) {
          // Overlapping or touching: merge
          if (end > currentEnd) {
            currentEnd = end;
          }
        } else {
          // Non-overlapping: push current and start new
          merged.push([currentStart, currentEnd]);
          currentStart = start;
          currentEnd = end;
        }
      }
    
      // Push the last interval
      merged.push([currentStart, currentEnd]);
    
      return merged;
    }
    ```
  • An LRU cachePassed

    392 tokens: 170 read, 222 written · 10 s · 24.9 tok/s

    Write a JavaScript class LRUCache: a least-recently-used cache of integer keys and values.
    
    - new LRUCache(capacity): capacity is an integer of at least 1.
    - get(key) returns the value stored for key, or -1 if there is none. A get that finds the key makes it the most recently used.
    - put(key, value) stores the value (replacing any value already there) and makes key the most recently used. If that leaves more than capacity keys, the least recently used key is removed.
    
    get and put should take constant time on average.
    
    Reply with one ```js code block holding plain JavaScript (no imports, no exports, no DOM, no timers). The site runs it with hidden tests.
    ```js
    class LRUCache {
      constructor(capacity) {
        this.capacity = capacity;
        this.map = new Map();
      }
    
      get(key) {
        if (!this.map.has(key)) {
          return -1;
        }
        const value = this.map.get(key);
        // Remove and re-insert to mark as most recently used
        this.map.delete(key);
        this.map.set(key, value);
        return value;
      }
    
      put(key, value) {
        if (this.map.has(key)) {
          // Update existing key: remove then re-insert to make it MRU
          this.map.delete(key);
        } else if (this.map.size >= this.capacity) {
          // Evict the least recently used key (first key in Map insertion order)
          const lruKey = this.map.keys().next().value;
          this.map.delete(lruKey);
        }
        this.map.set(key, value);
      }
    }
    ```
  • Evaluate arithmeticPassed

    1,022 tokens: 196 read, 826 written · 33 s · 25.4 tok/s

    Write a JavaScript function evaluate(expr) that returns the value of an arithmetic expression given as a string. The expression has non-negative integers, the operators + - * /, parentheses, unary minus (as in -3, - -3, 2 * -3 or -(1 + 2)) and spaces anywhere between tokens. * and / bind tighter than + and -, and operators of the same kind group from the left. / is integer division that truncates toward zero: 7 / 2 is 3 and -7 / 2 is -3. Dividing by zero must throw an Error. Do not use eval or Function.
    
    evaluate("2 + 3 * (4 - 6) / 4") returns 1.
    
    Reply with one ```js code block holding plain JavaScript (no imports, no exports, no DOM, no timers). The site runs it with hidden tests.
    ```js
    function evaluate(expr) {
        // Tokenize
        const tokens = [];
        let i = 0;
        while (i < expr.length) {
            const ch = expr[i];
            if (ch === ' ') {
                i++;
                continue;
            }
            if (ch >= '0' && ch <= '9') {
                let num = '';
                while (i < expr.length && expr[i] >= '0' && expr[i] <= '9') {
                    num += expr[i];
                    i++;
                }
                tokens.push({ type: 'num', value: parseInt(num, 10) });
            } else if (ch === '+' || ch === '-' || ch === '*' || ch === '/' || ch === '(' || ch === ')') {
                tokens.push({ type: ch });
                i++;
            } else {
                throw new Error("Invalid character: " + ch);
            }
        }
    
        // Parser with recursive descent
        let pos = 0;
    
        function peek() {
            return pos < tokens.length ? tokens[pos] : null;
        }
    
        function consume(type) {
            const tok = peek();
            if (!tok || tok.type !== type) {
                throw new Error("Expected " + type);
            }
            pos++;
            return tok;
        }
    
        // parseExpression: handles + and - (left-associative)
        function parseExpression() {
            let left = parseTerm();
            while (peek() && (peek().type === '+' || peek().type === '-')) {
                const op = consume(peek().type).type;
                const right = parseTerm();
                if (op === '+') {
                    left = left + right;
                } else {
                    left = left - right;
                }
            }
            return left;
        }
    
        // parseTerm: handles * and / (left-associative)
        function parseTerm() {
            let left = parseUnary();
            while (peek() && (peek().type === '*' || peek().type === '/')) {
                const op = consume(peek().type).type;
                const right = parseUnary();
                if (op === '*') {
                    left = left * right;
                } else {
                    if (right === 0) {
                        throw new Error("Division by zero");
                    }
                    // Integer division truncating toward zero
                    left = Math.trunc(left / right);
                }
            }
            return left;
        }
    
        // parseUnary: handles unary minus and plus
        function parseUnary() {
            if (peek() && peek().type === '-') {
                consume('-');
                return -parseUnary();
            }
            if (peek() && peek().type === '+') {
                consume('+');
                return parseUnary();
            }
            return parsePrimary();
        }
    
        // parsePrimary: handles numbers and parenthesized expressions
        function parsePrimary() {
            const tok = peek();
            if (!tok) {
                throw new Error("Unexpected end of expression");
            }
            if (tok.type === 'num') {
                consume('num');
                return tok.value;
            }
            if (tok.type === '(') {
                consume('(');
                const val = parseExpression();
                consume(')');
                return val;
            }
            throw new Error("Unexpected token: " + JSON.stringify(tok));
        }
    
        const result = parseExpression();
        if (pos !== tokens.length) {
            throw new Error("Unexpected token after expression");
        }
        return result;
    }
    ```
Fixing code 2 of 2
  • Fix the bookings modulePassed

    1,269 tokens: 668 read, 601 written · 26 s · 25.8 tok/s

    This JavaScript module has one bug. Guests are charged the weekend rate for Sunday nights and the weekday rate for Friday nights.
    
    Find it and fix it without changing anything else.
    
    ```js
    // Bookings for one holiday flat. A booking is { guest, checkIn, checkOut } with dates as "YYYY-MM-DD".
    // A guest sleeps the nights from checkIn up to, but not including, checkOut: checkOut is the day they leave,
    // and another guest may check in that same day.
    
    function dayNumber(date) {
      const [y, m, d] = date.split('-').map(Number);
      return Date.UTC(y, m - 1, d) / 86400000;
    }
    
    function toDate(day) {
      return new Date(day * 86400000).toISOString().slice(0, 10);
    }
    
    function nights(booking) {
      return dayNumber(booking.checkOut) - dayNumber(booking.checkIn);
    }
    
    function overlaps(a, b) {
      return dayNumber(a.checkIn) < dayNumber(b.checkOut) && dayNumber(b.checkIn) < dayNumber(a.checkOut);
    }
    
    function canBook(bookings, request) {
      if (nights(request) < 1) return false;
      for (const booking of bookings) {
        if (overlaps(booking, request)) return false;
      }
      return true;
    }
    
    function isBooked(bookings, day) {
      return bookings.some((b) => dayNumber(b.checkIn) <= day && day < dayNumber(b.checkOut));
    }
    
    // The nights from `from` up to, but not including, `to` that someone has booked.
    function bookedNights(bookings, from, to) {
      let count = 0;
      for (let day = dayNumber(from); day < dayNumber(to); day++) {
        if (isBooked(bookings, day)) count++;
      }
      return count;
    }
    
    // The first night on or after `from` that nobody has booked, as "YYYY-MM-DD".
    function firstFreeNight(bookings, from) {
      let day = dayNumber(from);
      while (isBooked(bookings, day)) day++;
      return toDate(day);
    }
    
    // The price in cents: Friday and Saturday nights at rates.weekend, every other night at rates.weekday.
    function price(booking, rates) {
      let total = 0;
      for (let day = dayNumber(booking.checkIn); day < dayNumber(booking.checkOut); day++) {
        const weekday = new Date(day * 86400000).getUTCDay();
        total += weekday === 6 || weekday === 0 ? rates.weekend : rates.weekday;
      }
      return total;
    }
    ```
    
    Reply with the whole corrected module in one ```js code block, with the same function names.
    ```js
    // Bookings for one holiday flat. A booking is { guest, checkIn, checkOut } with dates as "YYYY-MM-DD".
    // A guest sleeps the nights from checkIn up to, but not including, checkOut: checkOut is the day they leave,
    // and another guest may check in that same day.
    
    function dayNumber(date) {
      const [y, m, d] = date.split('-').map(Number);
      return Date.UTC(y, m - 1, d) / 86400000;
    }
    
    function toDate(day) {
      return new Date(day * 86400000).toISOString().slice(0, 10);
    }
    
    function nights(booking) {
      return dayNumber(booking.checkOut) - dayNumber(booking.checkIn);
    }
    
    function overlaps(a, b) {
      return dayNumber(a.checkIn) < dayNumber(b.checkOut) && dayNumber(b.checkIn) < dayNumber(a.checkOut);
    }
    
    function canBook(bookings, request) {
      if (nights(request) < 1) return false;
      for (const booking of bookings) {
        if (overlaps(booking, request)) return false;
      }
      return true;
    }
    
    function isBooked(bookings, day) {
      return bookings.some((b) => dayNumber(b.checkIn) <= day && day < dayNumber(b.checkOut));
    }
    
    // The nights from `from` up to, but not including, `to` that someone has booked.
    function bookedNights(bookings, from, to) {
      let count = 0;
      for (let day = dayNumber(from); day < dayNumber(to); day++) {
        if (isBooked(bookings, day)) count++;
      }
      return count;
    }
    
    // The first night on or after `from` that nobody has booked, as "YYYY-MM-DD".
    function firstFreeNight(bookings, from) {
      let day = dayNumber(from);
      while (isBooked(bookings, day)) day++;
      return toDate(day);
    }
    
    // The price in cents: Friday and Saturday nights at rates.weekend, every other night at rates.weekday.
    function price(booking, rates) {
      let total = 0;
      for (let day = dayNumber(booking.checkIn); day < dayNumber(booking.checkOut); day++) {
        const weekday = new Date(day * 86400000).getUTCDay();
        total += weekday === 5 || weekday === 6 ? rates.weekend : rates.weekday;
      }
      return total;
    }
    ```
  • Fix the CSV readerPassed

    957 tokens: 516 read, 441 written · 19 s · 25.8 tok/s

    This JavaScript module has one bug. A quoted field with a comma in it, such as "Smith, Jane", is split in two.
    
    Find it and fix it without changing anything else.
    
    ```js
    // Reads CSV the way spreadsheets write it: fields are separated by commas, a field may be wrapped in
    // double quotes so it can hold commas, and "" inside a quoted field stands for one double quote.
    // Fields are not trimmed. Empty lines are skipped.
    
    function parseLine(line) {
      const fields = [];
      let field = '';
      let quoted = false;
      for (let i = 0; i < line.length; i++) {
        const ch = line[i];
        if (quoted && ch !== ',') {
          if (ch === '"') {
            if (line[i + 1] === '"') {
              field += '"';
              i++;
            } else {
              quoted = false;
            }
          } else {
            field += ch;
          }
        } else if (ch === '"') {
          quoted = true;
        } else if (ch === ',') {
          fields.push(field);
          field = '';
        } else {
          field += ch;
        }
      }
      fields.push(field);
      return fields;
    }
    
    function parseCSV(text) {
      return text.split(/\r?\n/).filter((line) => line !== '').map(parseLine);
    }
    
    // Each row after the header as an object keyed by the header's names; a missing field is ''.
    function toObjects(text) {
      const [header, ...rows] = parseCSV(text);
      return rows.map((row) => {
        const record = {};
        header.forEach((name, i) => {
          record[name] = i < row.length ? row[i] : '';
        });
        return record;
      });
    }
    
    // The sum of a column's numbers; fields that are not numbers count as 0.
    function sumColumn(text, name) {
      return toObjects(text).reduce((total, record) => total + (Number(record[name]) || 0), 0);
    }
    ```
    
    Reply with the whole corrected module in one ```js code block, with the same function names.
    ```js
    // Reads CSV the way spreadsheets write it: fields are separated by commas, a field may be wrapped in
    // double quotes so it can hold commas, and "" inside a quoted field stands for one double quote.
    // Fields are not trimmed. Empty lines are skipped.
    
    function parseLine(line) {
      const fields = [];
      let field = '';
      let quoted = false;
      for (let i = 0; i < line.length; i++) {
        const ch = line[i];
        if (quoted) {
          if (ch === '"') {
            if (line[i + 1] === '"') {
              field += '"';
              i++;
            } else {
              quoted = false;
            }
          } else {
            field += ch;
          }
        } else if (ch === '"') {
          quoted = true;
        } else if (ch === ',') {
          fields.push(field);
          field = '';
        } else {
          field += ch;
        }
      }
      fields.push(field);
      return fields;
    }
    
    function parseCSV(text) {
      return text.split(/\r?\n/).filter((line) => line !== '').map(parseLine);
    }
    
    // Each row after the header as an object keyed by the header's names; a missing field is ''.
    function toObjects(text) {
      const [header, ...rows] = parseCSV(text);
      return rows.map((row) => {
        const record = {};
        header.forEach((name, i) => {
          record[name] = i < row.length ? row[i] : '';
        });
        return record;
      });
    }
    
    // The sum of a column's numbers; fields that are not numbers count as 0.
    function sumColumn(text, name) {
      return toObjects(text).reduce((total, record) => total + (Number(record[name]) || 0), 0);
    }
    ```
Planning and data 3 of 3
  • A query over hidden dataPassed

    318 tokens: 234 read, 84 written · 4 s · 25.6 tok/s

    Write one SQLite query that answers the question below. The site runs it on its own copy of these tables, filled with rows you have not seen.
    
    ```sql
    CREATE TABLE customers (id INTEGER PRIMARY KEY, name TEXT NOT NULL, city TEXT NOT NULL);
    CREATE TABLE orders (id INTEGER PRIMARY KEY, customer_id INTEGER NOT NULL REFERENCES customers(id),
                         placed TEXT NOT NULL,  -- 'YYYY-MM-DD'
                         status TEXT NOT NULL); -- 'delivered', 'cancelled' or 'pending'
    CREATE TABLE items (order_id INTEGER NOT NULL REFERENCES orders(id), product TEXT NOT NULL,
                        quantity INTEGER NOT NULL, price_cents INTEGER NOT NULL);  -- price_cents: for one unit
    ```
    
    Question: For each product, how many different customers bought it in a delivered order. Columns: product, customers. Only products with at least 2 such customers. Most customers first, then product name A to Z.
    
    Reply with only the query, in one ```sql code block: one SELECT statement (WITH is fine), nothing that changes the database.
    ```sql
    SELECT i.product AS product, COUNT(DISTINCT c.id) AS customers
    FROM items i
    JOIN orders o ON i.order_id = o.id
    JOIN customers c ON o.customer_id = c.id
    WHERE o.status = 'delivered'
    GROUP BY i.product
    HAVING COUNT(DISTINCT c.id) >= 2
    ORDER BY customers DESC, i.product ASC;
    ```
  • Schedule five meetingsPassed

    3,628 tokens: 276 read, 3,352 written · 2 min 17 s · 24.7 tok/s

    Five people each have one meeting today: Fay, Gus, Ivy, Jon, Noa. The five meetings are at different times, 09:00, 10:00, 11:00, 13:00, 14:00 (in that order: 10:00 is right after 09:00, 13:00 right after 11:00), and in different rooms. The list of rooms, in order: Cedar, Elm, Oak, Pine, Willow.
    
    1. Jon meets after lunch.
    2. Gus's and Noa's rooms are next to each other on the list of rooms.
    3. Whoever is in Pine meets earlier than Noa.
    4. Fay's and Jon's rooms are not next to each other on the list of rooms.
    5. Gus's meeting is in the slot right after Ivy's.
    6. Gus's and Jon's rooms are next to each other on the list of rooms.
    7. Gus meets after lunch.
    
    Exactly one schedule fits every clue. Work it out, then end with exactly five lines, one per person, in this form:
    Ana: 09:00, Oak
    To determine the exact schedule, we will deduce the time slots and rooms for each person step-by-step using the provided clues.
    
    **The Data:**
    *   **People:** Fay (F), Gus (G), Ivy (I), Jon (J), Noa (N)
    *   **Times (in order):** 09:00, 10:00, 11:00, 13:00, 14:00
        *   "Before lunch": 09:00, 10:00, 11:00
        *   "After lunch": 13:00, 14:00
    *   **Rooms (in order):** Cedar (C), Elm (E), Oak (O), Pine (P), Willow (W)
    
    **Step 1: Determine Time Slots based on Clues 1, 5, and 7**
    
    *   From Clue 7: Gus meets after lunch. So, Gus is at **13:00** or **14:00**.
    *   From Clue 1: Jon meets after lunch. So, Jon is at **13:00** or **14:00**.
    *   Since there are only two "after lunch" slots (13:00 and 14:00), both Gus and Jon must occupy these two slots. Consequently, Fay, Ivy, and Noa must occupy the "before lunch" slots: **09:00, 10:00, 11:00**.
    *   From Clue 5: Gus's meeting is in the slot right after Ivy's.
        *   This implies Ivy is immediately before Gus in time.
        *   If Gus were at 13:00, Ivy would have to be at 11:00 (since 11:00 is right before 13:00).
        *   If Gus were at 14:00, Ivy would have to be at 13:00. But we established that Jon is also in the after-lunch slots. Let's analyze this further.
    
    Let's test the two possibilities for Gus and Jon:
    
    **Case A: Gus is at 13:00.**
    *   Then Jon must be at **14:00** (the only other after-lunch slot).
    *   From Clue 5, if Gus is at 13:00, Ivy must be at **11:00** (the slot right before 13:00).
    *   The remaining people are Fay and Noa. The remaining time slots are **09:00** and **10:00**.
    *   So, {Fay, Noa} are at {09:00, 10:00}.
    
    **Case B: Gus is at 14:00.**
    *   Then Jon must be at **13:00**.
    *   From Clue 5, if Gus is at 14:00, Ivy must be at **13:00**.
    *   However, we just assigned Jon to 13:00. Two people cannot have the same meeting time.
    *   Therefore, **Case B is impossible**.
    
    **Conclusion from Step 1:**
    *   **Gus:** 13:00
    *   **Jon:** 14:00
    *   **Ivy:** 11:00
    *   **Fay & Noa:** 09:00 and 10:00 (order unknown yet)
    
    **Step 2: Determine Rooms based on Clues 2, 3, 4, and 6**
    
    Current Time Assignments:
    *   09:00: Fay or Noa
    *   10:00: Noa or Fay
    *   11:00: Ivy
    *   13:00: Gus
    *   14:00: Jon
    
    Let's look at the room constraints for Gus and Jon first.
    *   From Clue 6: Gus's and Jon's rooms are next to each other.
    *   Let $R(G)$ be Gus's room and $R(J)$ be Jon's room. $|Index(R(G)) - Index(R(J))| = 1$.
    
    Let's look at Clue 2: Gus's and Noa's rooms are next to each other.
    *   Let $R(N)$ be Noa's room. $|Index(R(G)) - Index(R(N))| = 1$.
    
    This means Noa's room and Jon's room are both adjacent to Gus's room.
    There are two sub-cases for the position of Gus's room:
    1.  Gus is in a middle room (Elm, Oak, Pine). Then Noa and Jon are on either side of him. This would mean $R(N)$ and $R(J)$ are different rooms (one left, one right).
    2.  Gus is at an end (Cedar or Willow). Then only one adjacent room exists. This would force Noa and Jon to be in the *same* room, which is impossible since all rooms are different.
        *   Therefore, **Gus cannot be in Cedar or Willow**.
        *   Gus must be in **Elm (2), Oak (3), or Pine (4)**.
    
    Let's evaluate each possible room for Gus:
    
    **Scenario 1: Gus is in Elm (Index 2)**
    *   Adjacent rooms are Cedar (1) and Oak (3).
    *   So, {Noa, Jon} occupy {Cedar, Oak}.
    *   Clue 4: Fay's and Jon's rooms are not next to each other.
    *   We need to place Fay, Ivy, and the remaining person from {Noa, Jon} into the remaining rooms: Pine (4), Willow (5), and whichever of Cedar/Oak isn't taken by Noa/Jon? Wait, let's list all rooms.
        *   Rooms: C(1), E(2), O(3), P(4), W(5).
        *   G is at E(2).
        *   N and J are at C(1) and O(3).
        *   Remaining rooms for F and I: P(4) and W(5).
    *   Let's check Clue 3: Whoever is in Pine meets earlier than Noa.
        *   This implies Noa is NOT in Pine (obviously, since N is C or O). It also implies the person in Pine has a time < Time(Noa).
        *   Time(Noa) is either 09:00 or 10:00.
        *   The person in Pine is either Fay or Ivy.
        *   If Noa is at 09:00, no one meets earlier than her. So Noa cannot be at 09:00 if someone is in Pine and must meet earlier? Wait. "Whoever is in Pine meets earlier than Noa." This requires that the person in Pine exists and their time < Time(Noa).
        *   If Noa is at 09:00, there is no time earlier than 09:00. Thus, **Noa cannot be at 09:00**.
        *   Therefore, **Noa must be at 10:00** and **Fay must be at 09:00**.
        *   Let's verify this deduction later. For now, assume Time(N) = 10:00, Time(F) = 09:00.
        *   Back to Scenario 1 (Gus in Elm):
            *   N and J are in C(1) and O(3).
            *   F and I are in P(4) and W(5).
            *   Clue 3: Person in Pine meets earlier than Noa (10:00).
            *   Who is in Pine? Either Fay or Ivy.
            *   If Fay is in Pine (P=4): Time(Fay) = 09:00. Is 09:00 < 10:00? Yes. This works.
            *   If Ivy is in Pine (P=4): Time(Ivy) = 11:00. Is 11:00 < 10:00? No. So Ivy cannot be in Pine.
            *   Therefore, **Fay is in Pine**. Consequently, **Ivy is in Willow**.
            *   Now we have:
                *   G: Elm (2)
                *   F: Pine (4)
                *   I: Willow (5)
                *   Remaining rooms for N and J: Cedar (1) and Oak (3).
            *   Clue 4: Fay's (Pine, index 4) and Jon's rooms are not next to each other.
                *   If Jon is in Oak (3): Index 3 is next to Index 4. This violates Clue 4.
                *   If Jon is in Cedar (1): Index 1 is not next to Index 4. This works.
            *   So, **Jon is in Cedar**. Consequently, **Noa is in Oak**.
            *   Let's check Clue 2: Gus (Elm, 2) and Noa (Oak, 3) are next to each other. Yes.
            *   Let's check all clues for this solution:
                *   1. Jon (14:00) after lunch? Yes.
                *   2. Gus (Elm) and Noa (Oak) adjacent? Yes (2,3).
                *   3. Pine (Fay, 09:00) earlier than Noa (10:00)? Yes.
                *   4. Fay (Pine, 4) and Jon (Cedar, 1) not adjacent? Yes.
                *   5. Gus (13:00) right after Ivy (11:00)? Yes.
                *   6. Gus (Elm, 2) and Jon (Cedar, 1) adjacent? Yes.
                *   7. Gus (13:00) after lunch? Yes.
            *   This looks like a valid solution. Let's double check if other scenarios are possible to ensure uniqueness.
    
    **Scenario 2: Gus is in Oak (Index 3)**
    *   Adjacent rooms: Elm (2) and Pine (4).
    *   So, {Noa, Jon} occupy {Elm, Pine}.
    *   Remaining rooms for Fay and Ivy: Cedar (1) and Willow (5).
    *   Clue 3: Person in Pine meets earlier than Noa.
        *   Who is in Pine? Either Noa or Jon.
        *   If Noa is in Pine: Clue says "Whoever is in Pine...". That would be Noa. So Noa meets earlier than Noa. Impossible.
        *   Therefore, **Jon must be in Pine**. Consequently, **Noa is in Elm**.
        *   So, Time(Jon) = 14:00. Room(Jon) = Pine.
        *   Room(Noa) = Elm.
        *   Clue 3 says: Person in Pine (Jon) meets earlier than Noa.
        *   Time(Jon) < Time(Noa).
        *   We know Time(Jon) = 14:00.
        *   So, 14:00 < Time(Noa). This is impossible as 14:00 is the latest time.
        *   Therefore, **Scenario 2 is impossible**.
    
    **Scenario 3: Gus is in Pine (Index 4)**
    *   Adjacent rooms: Oak (3) and Willow (5).
    *   So, {Noa, Jon} occupy {Oak, Willow}.
    *   Remaining rooms for Fay and Ivy: Cedar (1) and Elm (2).
    *   Clue 3: Person in Pine meets earlier than Noa.
        *   Who is in Pine? Gus.
        *   So, Time(Gus) < Time(Noa).
        *   We know Time(Gus) = 13:00.
        *   So, 13:00 < Time(Noa).
        *   The only time after 13:00 is 14:00.
        *   Therefore, **Noa must be at 14:00**.
        *   But we established in Step 1 that Jon is at 14:00 and Gus is at 13:00. Noa is either 09:00 or 10:00.
        *   Contradiction. **Scenario 3 is impossible**.
    
    **Conclusion:**
    Only Scenario 1 yields a valid schedule.
    
    **Final Schedule Reconstruction:**
    *   **Times:**
        *   Fay: 09:00
        *   Noa: 10:00
        *   Ivy: 11:00
        *   Gus: 13:00
        *   Jon: 14:00
    *   **Rooms:**
        *   Jon: Cedar
        *   Gus: Elm
        *   Noa: Oak
        *   Fay: Pine
        *   Ivy: Willow
    
    Let's do a final verification.
    1.  **Jon meets after lunch.** Jon is at 14:00. (Check)
    2.  **Gus's and Noa's rooms are next to each other.** Gus (Elm, 2), Noa (Oak, 3). Adjacent. (Check)
    3.  **Whoever is in Pine meets earlier than Noa.** Fay is in Pine (09:00). Noa is at 10:00. 09:00 < 10:00. (Check)
    4.  **Fay's and Jon's rooms are not next to each other.** Fay (Pine, 4), Jon (Cedar, 1). Not adjacent. (Check)
    5.  **Gus's meeting is in the slot right after Ivy's.** Gus (13:00), Ivy (11:00). 13:00 is the next slot after 11:00. (Check)
    6.  **Gus's and Jon's rooms are next to each other.** Gus (Elm, 2), Jon (Cedar, 1). Adjacent. (Check)
    7.  **Gus meets after lunch.** Gus is at 13:00. (Check)
    
    The schedule is unique.
    
    Fay: 09:00, Pine
    Gus: 13:00, Elm
    Ivy: 11:00, Willow
    Jon: 14:00, Cedar
    Noa: 10:00, Oak
  • A replacement in ten calls or fewerPassed

    11,229 tokens: 10,545 read, 684 written · 35 s · 24.6 tok/s

    Passes when Looks up the account, opens order R-5530 (the kettle), checks north then south and stops, reserves one steel kettle at south for R-5530, opens a damage claim (a return, if tried, is refused), makes at most 10 calls, and tells the customer claim CL-2207 and that the replacement ships on 3 November, without claiming a return label.

    Hi, it's ana.silva@example.com. My kettle arrived with a cracked lid. Can you sort it out?
    1. system
      You are the support agent of Tidewell Home, working through its tools. When an item arrives damaged: confirm which order it came in, send a replacement from the north warehouse if it has the item, else from south, else from east (check each in that order, and only as far as needed), and take the damaged item back with a return. Then reply to the customer with what you did, giving any reference numbers and the date the replacement ships.
    2. user
      Hi, it's ana.silva@example.com. My kettle arrived with a cracked lid. Can you sort it out?
    3. assistant
      I'm sorry to hear your kettle arrived damaged! Let me look into this for you right away.
      
      
      lookup_account({"email":"ana.silva@example.com"})
    4. tool
      {"account_id": "AC-311", "name": "Ana Silva"}
    5. assistant
      list_orders({"account_id":"AC-311"})
    6. tool
      {"orders": [{"order_id": "R-5521", "placed": "2026-10-02", "status": "delivered"}, {"order_id": "R-5530", "placed": "2026-10-09", "status": "delivered"}, {"order_id": "R-5544", "placed": "2026-10-20", "status": "in transit"}]}
    7. assistant
      Let me check your delivered orders to find the kettle.
      
      
      get_order({"order_id":"R-5521"})
      get_order({"order_id":"R-5530"})
    8. tool
      {"items": [{"name": "Oak table lamp", "quantity": 1, "sku": "lamp-oak"}], "order_id": "R-5521"}
    9. tool
      {"items": [{"name": "Steel kettle", "quantity": 1, "sku": "kettle-steel"}, {"name": "Grey mug", "quantity": 2, "sku": "mug-grey"}], "order_id": "R-5530"}
    10. assistant
      Found it — the Steel kettle (SKU `kettle-steel`) was in order **R-5530**, delivered. Now let me check warehouse stock to send a replacement, starting with the north warehouse.
      
      
      check_stock({"sku":"kettle-steel","warehouse":"north"})
    11. tool
      {"available": 0, "sku": "kettle-steel", "warehouse": "north"}
    12. assistant
      North is out of stock. Checking south next.
      
      
      check_stock({"sku":"kettle-steel","warehouse":"south"})
    13. tool
      {"available": 4, "sku": "kettle-steel", "warehouse": "south"}
    14. assistant
      South has stock. I'll reserve a replacement from the south warehouse and create a return label for the damaged kettle.
      
      
      reserve_item({"sku":"kettle-steel","warehouse":"south","order_id":"R-5530"})
      create_return({"order_id":"R-5530","reason":"Kettle arrived with a cracked lid (damaged in transit)"})
    15. tool
      {"reservation_id": "RS-4410", "ships_on": "2026-11-03"}
    16. tool
      {"error": "damaged items are not returned: open a damage claim with open_claim instead"}
    17. assistant
      The replacement is reserved. For the damaged item, I need to open a damage claim rather than a standard return — let me do that.
      
      
      open_claim({"order_id":"R-5530","reason":"Steel kettle arrived with a cracked lid (damaged in transit)"})
    18. tool
      {"claim_id": "CL-2207", "order_id": "R-5530", "status": "open"}
    19. assistant
      All sorted, Ana! Here's what I did about your cracked kettle:
      
      - **Order confirmed:** Your Steel kettle was in order **R-5530** (delivered).
      - **Replacement sent:** A new kettle is on its way from our south warehouse — reservation reference **RS-4410**, and it ships on **2026-11-03**.
      - **Damaged item:** I opened a damage claim for the cracked-lid kettle, reference **CL-2207** (status: open). You won't need to do anything with that one — no return label required.
      
      You should have your replacement kettle arriving around **3 November 2026**. Is there anything else I can help with?

Comments

Sign in or create an account to comment.