card-grader/static/index.html

118 lines
5.3 KiB
HTML

<!doctype html>
<html lang="en" data-base="__BASE__">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Card Grader</title>
<link rel="manifest" href="__BASE__/static/manifest.json">
<link rel="icon" href="__BASE__/static/icon.svg">
<meta name="theme-color" content="#16224a">
<!-- iOS ignores the web app manifest for install behaviour and needs its own
meta tags. Without these, "Add to Home Screen" on an iPhone produces a
bookmark that opens in Safari with the address bar showing, rather than
something that looks and behaves like an installed app. -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="Card Grader">
<link rel="apple-touch-icon" href="__BASE__/static/icon-180.png">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap">
<link rel="stylesheet" href="__BASE__/static/style.css">
</head>
<body>
<header class="topbar">
<div class="topbar-inner">
<div class="brand">
<!-- A graded slab: the case, its label, and the card sealed inside.
This is the literal object the whole app estimates, so it says
what this is without belonging to any one card game — which a
checkmark (or any single game's iconography) doesn't. -->
<svg class="brand-mark" viewBox="0 0 24 30" fill="none" aria-hidden="true" focusable="false">
<rect class="mark-case" x="1.15" y="1.15" width="21.7" height="27.7" rx="3.4" stroke-width="1.7"/>
<rect class="mark-label" x="5.2" y="5.3" width="13.6" height="3.3" rx="1.3"/>
<rect class="mark-card" x="5.2" y="11.9" width="13.6" height="12.9" rx="1.6"/>
</svg>
<h1>Card Grader</h1>
</div>
<div class="topbar-actions">
<button id="btn-install" class="btn" hidden>Install app</button>
<button id="btn-settings" class="btn btn-quiet">Settings</button>
</div>
</div>
</header>
<div id="banner" class="banner" hidden></div>
<main>
<!-- ------------------------------------------------------------- grade -->
<section class="panel">
<div class="panel-head">
<h2>Grade a card</h2>
<span class="hint" id="model-cost-hint"></span>
</div>
<div class="note">Front straight-on is the minimum. Adding the back lets it judge
back centering, and it can only tell a print line from a crease — about five PSA
grades apart — if it can check both sides.</div>
<div style="display:flex;gap:10px;flex-wrap:wrap;margin-top:12px">
<button id="btn-camera" class="btn">Take photo…</button>
<button id="btn-grade" class="btn btn-quiet">Choose from library…</button>
<input id="grade-label" class="input" placeholder="Card name (optional, for your history)" style="flex:1 1 220px">
</div>
<input id="grade-file" type="file" accept="image/*" multiple hidden>
<!-- capture="environment" is what skips straight to the rear camera
instead of showing the OS's photo-library picker — the library
input above already offers a camera option buried in that picker
on most phones, but a dedicated button is one tap instead of two,
and makes "take a fresh photo" the obvious default rather than
something you have to notice. Desktop browsers just ignore
`capture` and fall back to a normal file picker. -->
<input id="grade-camera" type="file" accept="image/*" capture="environment" hidden>
<div id="grade-status" class="search-status" hidden></div>
<div id="grade-review"></div>
</section>
<!-- Fallback photo picker for Regrade on a card saved before this feature
existed (or otherwise missing its stored photo) — regradeTargetId in
app.js tracks which row this fires for. -->
<input id="regrade-file" type="file" accept="image/*" multiple hidden>
<!-- ----------------------------------------------------------- history -->
<section class="panel">
<div class="panel-head">
<h2>History</h2>
<span class="hint" id="history-count"></span>
</div>
<div class="table-scroll">
<table class="grid" id="history-table">
<thead>
<tr>
<th class="col-card">Card</th>
<th>Grade</th>
<th>Confidence</th>
<th>When</th>
<th></th>
</tr>
</thead>
<tbody id="history-body"></tbody>
</table>
</div>
<p id="history-empty" class="empty" hidden>No cards graded yet — every estimate you run
gets saved here, with the full category breakdown.</p>
</section>
</main>
<!-- ----------------------------------------------------------- settings -->
<div id="modal-scrim" class="scrim" hidden></div>
<div id="settings-modal" class="modal" hidden role="dialog" aria-label="Settings"></div>
<!-- ------------------------------------------------------- history entry -->
<div id="entry-scrim" class="scrim" hidden></div>
<div id="entry-modal" class="modal" hidden role="dialog" aria-label="Grade detail"></div>
<script src="__BASE__/static/app.js"></script>
</body>
</html>