← back to Model Arena

data/artifacts/0066d3284995/qwen3-14b.html

352 lines

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>The Ship of State Steered by Committee</title>
  <style>
    :root {
      --bg-light: #f9f9f9;
      --bg-dark: #1e1e1e;
      --text-light: #222;
      --text-dark: #ddd;
      --accent: #4a90e2;
      --error: #d9534f;
      --success: #5cb85c;
    }

    body {
      margin: 0;
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      background-color: var(--bg-light);
      color: var(--text-light);
      display: flex;
      flex-direction: column;
      height: 100vh;
      overflow: hidden;
      transition: background-color 0.3s, color 0.3s;
    }

    body.dark {
      --bg-light: #1e1e1e;
      --bg-dark: #0e0e0e;
      --text-light: #ddd;
      --text-dark: #222;
      background-color: var(--bg-dark);
      color: var(--text-dark);
    }

    .container {
      flex: 1;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      position: relative;
      padding: 20px;
      box-sizing: border-box;
    }

    svg {
      width: 100%;
      height: 100%;
      max-height: 80vh;
      max-width: 100%;
      min-width: 390px;
      min-height: 400px;
      user-select: none;
    }

    .controls {
      display: flex;
      gap: 10px;
      margin-top: 20px;
      flex-wrap: wrap;
      justify-content: center;
    }

    .control {
      background-color: var(--accent);
      padding: 8px 12px;
      border: none;
      color: white;
      border-radius: 6px;
      cursor: pointer;
      font-size: 14px;
      transition: background-color 0.2s;
    }

    .control:active {
      background-color: #3a76c0;
    }

    .toggle {
      position: absolute;
      top: 10px;
      right: 10px;
      background-color: var(--accent);
      color: white;
      border: none;
      border-radius: 50%;
      width: 30px;
      height: 30px;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 14px;
      cursor: pointer;
      user-select: none;
    }

    .caption {
      margin-top: 20px;
      font-size: 18px;
      text-align: center;
      max-width: 80%;
      white-space: pre-wrap;
      transition: color 0.3s;
    }

    .error {
      color: var(--error);
    }

    .success {
      color: var(--success);
    }

    .info {
      color: var(--accent);
    }

    .ship {
      transform: scale(1);
      transition: transform 0.3s;
    }

    .ship.dragging {
      transform: scale(1.1);
    }

    .handle {
      cursor: move;
      fill: var(--accent);
      pointer-events: all;
    }

    .handle.dragging {
      fill: #3a76c0;
    }

    .indicator {
      position: absolute;
      top: 10px;
      left: 10px;
      background-color: var(--accent);
      color: white;
      padding: 5px 10px;
      border-radius: 6px;
      font-size: 12px;
      display: none;
    }

    .indicator.active {
      display: block;
    }

    .empty {
      display: none;
    }

    .empty.active {
      display: block;
    }

    .error-state {
      display: none;
    }

    .error-state.active {
      display: block;
    }

    .success-state {
      display: none;
    }

    .success-state.active {
      display: block;
    }

    @media (prefers-reduced-motion: no-preference) {
      .ship {
        transition: transform 0.3s;
      }
    }

    @media (max-width: 768px) {
      .controls {
        flex-direction: column;
      }
    }
  </style>
</head>
<body>
  <div class="container">
    <svg viewBox="0 0 800 600">
      <!-- Sea -->
      <rect x="0" y="0" width="800" height="600" fill="#99ccff" />
      <!-- Ship -->
      <g id="ship" class="ship" transform="translate(400,300)">
        <!-- Hull -->
        <polygon points="0,-60 100,-20 150,0 140,60 0,60 -60,0" fill="#666" stroke="#333" stroke-width="3" />
        <!-- Masts -->
        <line x1="70" y1="-60" x2="70" y2="-140" stroke="#888" stroke-width="6" />
        <line x1="130" y1="-60" x2="130" y2="-140" stroke="#888" stroke-width="6" />
        <!-- Sails -->
        <polygon points="70,-140 100,-160 130,-140 100,-130" fill="white" stroke="#888" stroke-width="2" />
        <polygon points="70,-140 40,-180 130,-140 100,-160" fill="white" stroke="#888" stroke-width="2" />
        <!-- Steering Wheel -->
        <g class="handle" transform="translate(75,-70)">
          <circle cx="0" cy="0" r="20" fill="#4a90e2" />
          <line x1="0" y1="10" x2="0" y2="30" stroke="#333" stroke-width="3" />
        </g>
        <!-- Committee -->
        <g id="committee">
          <circle cx="100" cy="30" r="15" fill="#c93030" />
          <text x="115" y="40" font-size="14" fill="white" text-anchor="start">Red</text>
          <circle cx="200" cy="30" r="15" fill="#4caf50" />
          <text x="215" y="40" font-size="14" fill="white" text-anchor="start">Green</text>
          <circle cx="300" cy="30" r="15" fill="#ff9800" />
          <text x="315" y="40" font-size="14" fill="white" text-anchor="start">Yellow</text>
          <circle cx="400" cy="30" r="15" fill="#00bcd4" />
          <text x="415" y="40" font-size="14" fill="white" text-anchor="start">Blue</text>
        </g>
      </g>
    </svg>
    <button class="toggle" aria-label="Toggle light/dark mode">
      🌞
    </button>
    <div class="controls">
      <button class="control" id="reset">Reset</button>
      <button class="control" id="drift">Drift</button>
      <button class="control" id="sink">Sink</button>
      <button class="control" id="anchor">Anchor</button>
    </div>
    <div class="indicator" id="indicator">Dragging...</div>
    <div class="empty" id="empty">No committee members present.</div>
    <div class="error" id="error">Ship is sinking. Committee is disoriented.</div>
    <div class="success" id="success">Course corrected! The ship is on track.</div>
    <div class="caption" id="caption">The ship of state steered by a committed and balanced committee.</div>
  </div>

  <script>
    const svg = document.querySelector('svg');
    const shipGroup = document.getElementById('ship');
    const handle = document.querySelector('.handle');
    const committee = document.getElementById('committee');
    const indicator = document.getElementById('indicator');
    const caption = document.getElementById('caption');
    const empty = document.getElementById('empty');
    const error = document.getElementById('error');
    const success = document.getElementById('success');
    const resetBtn = document.getElementById('reset');
    const driftBtn = document.getElementById('drift');
    const sinkBtn = document.getElementById('sink');
    const anchorBtn = document.getElementById('anchor');
    const toggleBtn = document.querySelector('.toggle');

    let isDragging = false;
    let offsetX, offsetY;

    // Toggle light/dark
    toggleBtn.addEventListener('click', () => {
      document.body.classList.toggle('dark');
    });

    // Dragging ship handle
    handle.addEventListener('mousedown', (e) => {
      isDragging = true;
      offsetX = e.clientX - shipGroup.transform.baseVal.getItem(0).matrix.e;
      offsetY = e.clientY - shipGroup.transform.baseVal.getItem(0).matrix.f;
      indicator.classList.add('active');
      handle.classList.add('dragging');
    });

    document.addEventListener('mousemove', (e) => {
      if (isDragging) {
        const x = e.clientX - offsetX;
        const y = e.clientY - offsetY;
        shipGroup.setAttribute('transform', `translate(${x},${y})`);
      }
    });

    document.addEventListener('mouseup', () => {
      if (isDragging) {
        isDragging = false;
        indicator.classList.remove('active');
        handle.classList.remove('dragging');
      }
    });

    // Reset all
    resetBtn.addEventListener('click', () => {
      shipGroup.setAttribute('transform', 'translate(400,300)');
      committee.setAttribute('transform', 'translate(0,0)');
      indicator.classList.remove('active');
      handle.classList.remove('dragging');
      empty.classList.remove('active');
      error.classList.remove('active');
      success.classList.remove('active');
      caption.textContent = "The ship of state steered by a committed and balanced committee.";
    });

    // Drift (move committee)
    driftBtn.addEventListener('click', () => {
      const randomX = Math.random() * 200 - 100;
      const randomY = Math.random() * 200 - 100;
      committee.setAttribute('transform', `translate(${randomX},${randomY})`);
      caption.textContent = "The ship of state is drifting. The committee is divided.";
    });

    // Sink (add error state)
    sinkBtn.addEventListener('click', () => {
      committee.setAttribute('transform', 'translate(0,100)');
      caption.textContent = "The ship of state is sinking. The committee is at odds.";
      error.classList.add('active');
    });

    // Anchor (add success state)
    anchorBtn.addEventListener('click', () => {
      committee.setAttribute('transform', 'translate(0,0)');
      caption.textContent = "The ship of state is anchored. The committee is unified.";
      success.classList.add('active');
    });

    // Keyboard access
    document.addEventListener('keydown', (e) => {
      if (e.key === 'r') resetBtn.click();
      if (e.key === 'd') driftBtn.click();
      if (e.key === 's') sinkBtn.click();
      if (e.key === 'a') anchorBtn.click();
      if (e.key === 't') toggleBtn.click();
    });

    // Focus styles
    document.querySelectorAll('button, [role="button"]').forEach(el => {
      el.setAttribute('tabindex', '0');
      el.addEventListener('focus', () => {
        el.style.outline = '2px solid var(--accent)';
      });
      el.addEventListener('blur', () => {
        el.style.outline = 'none';
      });
    });

    // Empty state (if committee is hidden)
    if (!committee) {
      empty.classList.add('active');
    }
  </script>
</body>
</html>