← back to Model Arena

data/artifacts/0ddb58a78233/qwen3-14b.html

408 lines

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>HoloCard Arena</title>
  <style>
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }

    html, body {
      height: 100%;
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      background: #111;
      color: #eee;
      overflow: hidden;
    }

    .container {
      display: flex;
      height: 100%;
      width: 100%;
      flex-direction: column;
    }

    .header {
      background: #222;
      padding: 1rem;
      text-align: center;
      font-size: 1.5rem;
      color: #fff;
      box-shadow: 0 2px 5px rgba(0,0,0,0.5);
    }

    .card-container {
      flex-grow: 1;
      position: relative;
      overflow: hidden;
      display: flex;
      justify-content: center;
      align-items: center;
      perspective: 1000px;
    }

    .card {
      width: 300px;
      height: 450px;
      background: #222;
      border-radius: 16px;
      box-shadow: 0 0 30px rgba(255,255,255,0.2);
      position: relative;
      cursor: pointer;
      transform-style: preserve-3d;
      transition: transform 0.2s ease-out, box-shadow 0.3s ease;
      user-select: none;
    }

    .card:hover {
      transform: rotateX(5deg) rotateY(5deg);
      box-shadow: 0 0 50px rgba(255,255,255,0.3);
    }

    .card:focus {
      outline: none;
      box-shadow: 0 0 30px rgba(0,255,255,0.6);
    }

    .face {
      position: absolute;
      width: 100%;
      height: 100%;
      backface-visibility: hidden;
      border-radius: 16px;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: space-between;
      padding: 20px;
      box-sizing: border-box;
      transform: rotateY(0deg);
      background: linear-gradient(135deg, #000, #111);
      color: #fff;
      font-weight: bold;
      text-shadow: 0 0 10px rgba(255,255,255,0.3);
    }

    .backface {
      transform: rotateY(180deg);
    }

    .front .name {
      font-size: 1.5rem;
      margin-bottom: 10px;
    }

    .stats {
      font-size: 0.9rem;
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      grid-gap: 10px;
      width: 100%;
      margin-top: 20px;
    }

    .stat {
      background: #333;
      padding: 8px;
      border-radius: 8px;
      text-align: center;
      font-weight: bold;
    }

    .flip {
      transform: rotateY(180deg);
    }

    .head-to-head {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      z-index: 10;
      text-align: center;
      padding: 2rem;
      background: rgba(0,0,0,0.5);
      border-radius: 16px;
      font-size: 1.5rem;
      color: #fff;
      display: none;
      justify-content: center;
      align-items: center;
      min-width: 250px;
      min-height: 120px;
      box-shadow: 0 0 30px rgba(255,255,255,0.2);
    }

    .head-to-head.show {
      display: flex;
    }

    .nav {
      display: flex;
      justify-content: center;
      gap: 1rem;
      padding: 1rem;
      background: #111;
      border-top: 1px solid #333;
      font-size: 0.9rem;
    }

    .nav button {
      background: #222;
      color: #fff;
      border: none;
      padding: 0.4rem 0.8rem;
      border-radius: 8px;
      cursor: pointer;
      font-weight: bold;
    }

    .nav button:hover {
      background: #333;
    }

    .nav button:focus {
      outline: none;
      box-shadow: 0 0 10px rgba(0,255,255,0.6);
    }

    .error {
      color: #f00;
      font-size: 0.8rem;
      margin-top: 0.5rem;
    }

    .empty-state {
      font-size: 1rem;
      text-align: center;
      color: #888;
      padding: 2rem;
    }

    .card[data-empty] {
      opacity: 0.5;
    }

    @media (max-width: 768px) {
      .card {
        width: 250px;
        height: 380px;
      }
    }

    @media (prefers-reduced-motion: no-preference) {
      .card:hover {
        animation: pulse 1s infinite alternate;
      }

      @keyframes pulse {
        from { transform: rotateX(0deg) rotateY(0deg); }
        to { transform: rotateX(4deg) rotateY(4deg); }
      }
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="header">HoloCard Arena</div>
    <div class="card-container">
      <div class="card" id="card1" data-empty>
        <div class="face front" tabindex="0">
          <div class="name">Tal Vex</div>
          <div class="stats">
            <div class="stat">Speed: 92</div>
            <div class="stat">Endurance: 78</div>
            <div class="stat">Precision: 89</div>
            <div class="stat">Agility: 94</div>
          </div>
          <div class="error" id="error1"></div>
        </div>
        <div class="face backface" tabindex="0">
          <div class="name">Radar Stats</div>
          <div class="stats">
            <div class="stat">Power: 84</div>
            <div class="stat">Vision: 91</div>
            <div class="stat">Tactics: 87</div>
            <div class="stat">Reaction: 85</div>
          </div>
        </div>
      </div>
      <div class="card" id="card2" data-empty>
        <div class="face front" tabindex="0">
          <div class="name">Zyla Korr</div>
          <div class="stats">
            <div class="stat">Speed: 86</div>
            <div class="stat">Endurance: 82</div>
            <div class="stat">Precision: 88</div>
            <div class="stat">Agility: 90</div>
          </div>
          <div class="error" id="error2"></div>
        </div>
        <div class="face backface" tabindex="0">
          <div class="name">Radar Stats</div>
          <div class="stats">
            <div class="stat">Power: 88</div>
            <div class="stat">Vision: 89</div>
            <div class="stat">Tactics: 85</div>
            <div class="stat">Reaction: 92</div>
          </div>
        </div>
      </div>
    </div>
    <div class="head-to-head" id="head-to-head">
      <span id="winner"></span>
    </div>
    <div class="nav">
      <button id="flip-button">Flip Card</button>
      <button id="head-to-head-button">Head-to-Head</button>
      <button id="clear-button">Clear Cards</button>
    </div>
    <div class="empty-state" id="empty-state">
      No athletes selected. Click on a card or use buttons above.
    </div>
  </div>

  <script>
    const card1 = document.getElementById("card1");
    const card2 = document.getElementById("card2");
    const headToHead = document.getElementById("head-to-head");
    const winnerDisplay = document.getElementById("winner");
    const flipButton = document.getElementById("flip-button");
    const headToHeadButton = document.getElementById("head-to-head-button");
    const clearButton = document.getElementById("clear-button");
    const emptyState = document.getElementById("empty-state");
    const error1 = document.getElementById("error1");
    const error2 = document.getElementById("error2");

    let card1Flipped = false;
    let card2Flipped = false;
    let card1Selected = false;
    let card2Selected = false;

    function flipCard(card, target) {
      if (card.classList.contains("flip")) {
        card.classList.remove("flip");
        target.style.transform = "rotateY(0deg)";
      } else {
        card.classList.add("flip");
        target.style.transform = "rotateY(180deg)";
      }
    }

    function updateEmptyState() {
      if (card1.getAttribute("data-empty") === "true" && card2.getAttribute("data-empty") === "true") {
        emptyState.style.display = "block";
      } else {
        emptyState.style.display = "none";
      }
    }

    function randomWinner() {
      const names = ["Tal Vex", "Zyla Korr"];
      const winner = names[Math.floor(Math.random() * 2)];
      winnerDisplay.textContent = `${winner} emerges victorious!`;
      headToHead.classList.add("show");
      setTimeout(() => {
        headToHead.classList.remove("show");
      }, 2500);
    }

    function clearCards() {
      card1.setAttribute("data-empty", "true");
      card2.setAttribute("data-empty", "true");
      card1.classList.remove("flip");
      card2.classList.remove("flip");
      card1.querySelector(".face.front .name").textContent = "Tal Vex";
      card2.querySelector(".face.front .name").textContent = "Zyla Korr";
      card1Flipped = false;
      card2Flipped = false;
      card1Selected = false;
      card2Selected = false;
      updateEmptyState();
      error1.textContent = "";
      error2.textContent = "";
    }

    function setupCardListeners(card, idx) {
      let isFlipping = false;
      card.addEventListener("click", () => {
        if (isFlipping) return;
        isFlipping = true;

        if (card.getAttribute("data-empty") === "true") {
          error1.textContent = "Card must be selected before flipping.";
          setTimeout(() => error1.textContent = "", 2000);
          isFlipping = false;
          return;
        }

        flipCard(card, card.querySelector(".face.front"));
        setTimeout(() => isFlipping = false, 300);
      });

      card.addEventListener("keydown", (e) => {
        if (e.key === "Enter" || e.key === " ") {
          e.preventDefault();
          card.click();
        }
      });

      card.addEventListener("focus", () => {
        if (card.getAttribute("data-empty") === "true") {
          error1.textContent = "Card must be selected before flipping.";
          setTimeout(() => error1.textContent = "", 2000);
        }
      });
    }

    setupCardListeners(card1, 1);
    setupCardListeners(card2, 2);

    flipButton.addEventListener("click", () => {
      if (card1.getAttribute("data-empty") === "true" || card2.getAttribute("data-empty") === "true") {
        error1.textContent = "No cards selected yet.";
        error2.textContent = "No cards selected yet.";
        setTimeout(() => {
          error1.textContent = "";
          error2.textContent = "";
        }, 2000);
        return;
      }

      flipCard(card1, card1.querySelector(".face.front"));
      flipCard(card2, card2.querySelector(".face.front"));
    });

    headToHeadButton.addEventListener("click", () => {
      if (card1.getAttribute("data-empty") === "true" || card2.getAttribute("data-empty") === "true") {
        error1.textContent = "No cards selected yet.";
        error2.textContent = "No cards selected yet.";
        setTimeout(() => {
          error1.textContent = "";
          error2.textContent = "";
        }, 2000);
        return;
      }
      randomWinner();
    });

    clearButton.addEventListener("click", () => {
      clearCards();
    });

    // Keyboard navigation
    document.addEventListener("keydown", (e) => {
      if (e.key === "Enter" && (e.target === flipButton || e.target === headToHeadButton || e.target === clearButton)) {
        e.preventDefault();
        e.target.click();
      }
    });

    updateEmptyState();
  </script>
</body>
</html>