Files
rgriffithandClaude Opus 4.6 88c0d94d39 feat(ui): swap Inter for Barlow / Barlow Condensed display font
Load Barlow + Barlow Condensed from Google Fonts across all 8 HTML
entry points. In global.css introduce --font-display (Barlow Condensed)
alongside --font (Barlow), then wire the display font into every
chrome/heading selector: h1-h6, .page-header, .panel-header, .btn,
.stat-label/.stat-value, .form-label, .badge-status, .data-table
thead, .tag, .nav-brand, .nav-links. Body copy stays in Barlow for
readability.

Also normalize a few hardcoded font-families to design-system vars:
collection.css Cascadia Code stacks and deckgenerator.css Courier New
now use var(--font-mono); canvas rendering in distillation.js and
ai-lab.js swapped from Inter to Barlow so charts match the new type.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-05 17:26:06 -04:00

148 lines
8.4 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Commander AI Lab — Simulator</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Barlow+Condensed:wght@400;600;700;800&family=Barlow:wght@400;500;600&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="global.css" />
<link rel="stylesheet" href="simulator.css" />
</head>
<body>
<script src="nav.js"></script>
<div class="page">
<div class="page-header">
<h1>Deck Simulator</h1>
<p>Monte Carlo engine &mdash; test your deck against an AI training opponent</p>
</div>
<!-- Config Panel -->
<section class="panel">
<div class="sim-config-row">
<div class="form-group sim-field-grow">
<label class="form-label" for="sim-deck-select">Deck</label>
<select id="sim-deck-select" class="form-select">
<option value="">-- Select a deck --</option>
</select>
</div>
<div class="form-group sim-field-auto">
<label class="form-label" for="sim-opponent-select">
Opponent
<span class="tip-icon tip-below" data-tip="Heuristic AI uses rule-based logic — fast and deterministic. DeepSeek AI routes decisions through your local Ollama LLM for smarter but slower play.">?</span>
</label>
<select id="sim-opponent-select" class="form-select">
<option value="heuristic">Heuristic AI</option>
<option value="deepseek">DeepSeek AI</option>
</select>
</div>
<div class="form-group sim-field-auto">
<label class="form-label" for="sim-num-games">
Games
<span class="tip-icon tip-below" data-tip="Number of games to simulate. 10 is quick for a gut-check; 100+ gives statistically meaningful win rates. Each game is fully simulated end-to-end.">?</span>
</label>
<input type="number" id="sim-num-games" class="form-input sim-num-input" value="10" min="1" max="1000" />
</div>
<div class="form-group sim-field-auto sim-field-end">
<label class="form-checkbox">
<input type="checkbox" id="sim-record-logs" checked />
Record turn logs
<span class="tip-icon tip-below" data-tip="Saves per-turn decision snapshots to .jsonl files. Required for ML training data collection. Slightly slower — disable if you only need win rate stats.">?</span>
</label>
</div>
<div class="form-group sim-field-auto sim-field-end">
<button id="sim-run-btn" class="btn btn-primary" disabled>Run Simulation</button>
</div>
</div>
<!-- DeepSeek Config Panel -->
<div id="deepseek-panel" class="deepseek-panel" style="display:none;">
<div class="deepseek-header">
<div class="deepseek-title">
<span class="deepseek-icon">&#129504;</span>
<span>DeepSeek AI Brain</span>
<span id="ds-status-badge" class="ds-badge ds-badge-off">Disconnected</span>
</div>
<button id="ds-connect-btn" class="btn btn-sm btn-outline">Connect</button>
</div>
<div class="deepseek-config-row">
<div class="form-group sim-field-grow">
<label class="form-label" for="ds-api-base">
API Endpoint
<span class="tip-icon tip-below" data-tip="Base URL of your Ollama server. Default is localhost:11434. Change this if Ollama is running on a different machine or WSL2 network address.">?</span>
</label>
<input type="text" id="ds-api-base" class="form-input" value="http://localhost:11434" placeholder="http://localhost:11434" />
</div>
<div class="form-group sim-field-auto">
<label class="form-label" for="ds-model">
Model
<span class="tip-icon tip-below" data-tip="Ollama model tag to use for AI decisions. Leave blank to auto-detect the best available model. Examples: deepseek-r1:7b, llama3:8b, mistral.">?</span>
</label>
<input type="text" id="ds-model" class="form-input" value="" placeholder="Auto-detect" style="width:200px" />
</div>
<div class="form-group sim-field-auto">
<label class="form-label" for="ds-temp">
Temp
<span class="tip-icon tip-below" data-tip="LLM sampling temperature. Lower = more deterministic decisions. 0.3 is a good balance — fully greedy (0.0) can get stuck in repetitive play patterns.">?</span>
</label>
<input type="number" id="ds-temp" class="form-input sim-num-input" value="0.3" min="0" max="2" step="0.1" />
</div>
<div class="form-group sim-field-auto">
<label class="form-label" for="ds-timeout">
Timeout (s)
<span class="tip-icon tip-below" data-tip="Max seconds to wait for an LLM response per decision. If exceeded, falls back to heuristic AI automatically. Increase if your GPU is slow on cold inference.">?</span>
</label>
<input type="number" id="ds-timeout" class="form-input sim-num-input" value="10" min="1" max="60" />
</div>
</div>
<div id="ds-stats-row" class="deepseek-stats-row" style="display:none;">
<span id="ds-stat-calls" class="ds-stat">Calls: 0</span>
<span id="ds-stat-cache" class="ds-stat">Cache: 0</span>
<span id="ds-stat-fallback" class="ds-stat">Fallbacks: 0</span>
<span id="ds-stat-latency" class="ds-stat">Avg: 0ms</span>
<span id="ds-stat-model" class="ds-stat"></span>
</div>
</div>
<!-- Or paste decklist -->
<details class="sim-paste-section">
<summary>Or paste a decklist</summary>
<textarea id="sim-paste-decklist" class="form-textarea" rows="8" placeholder="1 Sol Ring&#10;1 Cultivate&#10;37 Forest&#10;..."></textarea>
<div class="sim-paste-controls">
<input type="text" id="sim-paste-name" class="form-input" placeholder="Deck name" value="Custom Deck" />
<button id="sim-paste-run-btn" class="btn btn-primary">Run from Paste</button>
</div>
</details>
<!-- Progress bar -->
<div id="sim-progress" class="progress-container" style="display:none;">
<div class="flex justify-between mb-2">
<span id="sim-progress-text" class="progress-label">Running...</span>
<span id="sim-progress-count" class="text-sm text-muted text-mono">0 / 0</span>
</div>
<div class="progress-track">
<div id="sim-progress-bar" class="progress-fill"></div>
</div>
</div>
</section>
<!-- Results -->
<section id="sim-results" style="display:none;">
<!-- Stats Summary -->
<div class="sim-stats-grid stat-grid" id="sim-stats-grid"></div>
<!-- Game List -->
<div class="panel sim-games-section">
<div class="panel-header">
<h2>Game-by-Game Results</h2>
</div>
<div id="sim-games-list" class="sim-games-list"></div>
</div>
</section>
</div>
<script src="simulator.js"></script>
</body>
</html>