/* Ballpark Design tool. Self-contained — this page does not load the site chrome. */

:root {
	--ink:       #e8eae7;
	--ink-soft:  #9aa39b;
	--ink-faint: #6b746d;
	--ground:    #14181a;
	--panel:     #1c2124;
	--panel-2:   #232a2d;
	--edge:      #2d3538;
	--accent:    #2fa96a;
	--accent-in: #0d1a12;
	--warn:      #d9534f;
	--unit:      8px;
}

* { box-sizing: border-box; }

body {
	margin: 0;
	background: var(--ground);
	color: var(--ink);
	font: 14px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
	-webkit-font-smoothing: antialiased;
}

code { font: 12px/1 ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--ink-soft); }
a { color: var(--accent); }

/* ---------------------------------------------------------------- topbar */

.topbar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	padding: 16px 24px;
	background: var(--panel);
	border-bottom: 1px solid var(--edge);
	position: sticky;
	top: 0;
	z-index: 10;
}

.brand strong { display: block; font-size: 15px; letter-spacing: .01em; }
.brand span   { display: block; font-size: 12px; color: var(--ink-faint); }

.picker { display: flex; flex: 1; max-width: 560px; }
.picker select { flex: 1; }

/* ---------------------------------------------------------------- layout */

.layout {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 400px;
	gap: 24px;
	padding: 24px;
	align-items: start;
}

@media (max-width: 1180px) {
	.layout { grid-template-columns: minmax(0, 1fr); }
}

.stage { position: sticky; top: 96px; }

.canvases { display: flex; flex-wrap: wrap; gap: 24px; }

/* Both boards share the stage; each caps at its native 600px. */
.canvases figure { margin: 0; flex: 1 1 320px; max-width: 600px; }

.canvases img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: 4px;
	background: var(--panel);
	transition: opacity .12s ease;
}

.canvases img.working { opacity: .55; }

.canvases figcaption {
	display: flex;
	align-items: baseline;
	gap: 12px;
	margin-top: 8px;
	font-size: 12px;
	color: var(--ink-faint);
}

/* ---------------------------------------------------------------- outline editor */

.board { position: relative; line-height: 0; }

.editor {
	display: none;
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	touch-action: none;
}

.editor.on { display: block; }

.editor .rest   { fill: none; stroke: rgba(255,255,255,.28); stroke-width: 1; stroke-dasharray: 3 4; }
.editor .wall   { fill: none; stroke: var(--pole, #ffd200); stroke-width: 2; stroke-linejoin: round; pointer-events: none; }
.editor .hit    { fill: none; stroke: transparent; stroke-width: 16; cursor: copy; }
.editor .handle { fill: var(--ground); stroke: #ffd200; stroke-width: 2; cursor: grab; }
.editor .handle.base { fill: #ffd200; }
.editor .handle:active { cursor: grabbing; }

/* Foul ground is shaped through its five profile controls, drawn square to tell
   them apart from the round fence handles. */
.editor .foulline { fill: none; stroke: #4ad2ff; stroke-width: 1.5; stroke-dasharray: 6 4; pointer-events: none; }
.editor .foul     { fill: var(--ground); stroke: #4ad2ff; stroke-width: 2; cursor: grab; }
.editor .foul.back { fill: #4ad2ff; }
.editor .foul:active { cursor: grabbing; }

.linky {
	padding: 0;
	background: none;
	border: 0;
	color: var(--accent);
	font: inherit;
	font-size: 12px;
	text-decoration: underline;
	cursor: pointer;
}

.linky.active { color: #ffd200; }

.editbar {
	display: none;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	margin-top: 12px;
	padding: 12px 16px;
	background: var(--panel);
	border: 1px solid var(--edge);
	border-radius: 4px;
}

.editbar.on {
	display: flex;
}

.editbar p { margin: 0; font-size: 12px; color: var(--ink-faint); max-width: 46ch; }
.editbar div { display: flex; gap: 8px; flex: 0 0 auto; }

/* ---------------------------------------------------------------- meta */

.meta {
	display: flex;
	flex-wrap: wrap;
	gap: 8px 32px;
	margin: 24px 0 0;
	padding: 16px;
	background: var(--panel);
	border: 1px solid var(--edge);
	border-radius: 4px;
}

.meta dt { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-faint); }
.meta dd { margin: 2px 0 0; font-size: 14px; }

/* ---------------------------------------------------------------- save bar */

.savebar { margin-top: 16px; }

.savebar .fields {
	display: flex;
	align-items: flex-start;
	gap: 12px;
}

.savebar .fld { margin-bottom: 0; }
.savebar .fld:first-child { flex: 1 1 auto; min-width: 180px; }
.savebar .fld:nth-child(2),
.savebar .fld:nth-child(3) { flex: 0 0 110px; }

/* Line the actions up with the inputs, not the labels above them. */
.savebar .fields .primary,
.savebar .fields .ghost {
	flex: 0 0 auto;
	margin-top: 20px;
	padding: 7px 22px;
	white-space: nowrap;
}

/* A note sitting directly above another field needs to give it room. */
.panel .note + .fld { margin-top: 12px; }

/* ---------------------------------------------------------------- rail */

.rail { display: flex; flex-direction: column; gap: 16px; }

.panel {
	background: var(--panel);
	border: 1px solid var(--edge);
	border-radius: 4px;
	padding: 16px;
}

.panel h2 {
	margin: 0 0 12px;
	font-size: 11px;
	text-transform: uppercase;
	letter-spacing: .08em;
	color: var(--ink-soft);
	font-weight: 600;
}

.note { margin: 12px 0 0; font-size: 12px; color: var(--ink-faint); }

/* ---------------------------------------------------------------- fields */

.fld { display: block; margin-bottom: 12px; }
.fld:last-child { margin-bottom: 0; }

.lbl {
	display: block;
	margin-bottom: 4px;
	font-size: 12px;
	color: var(--ink-soft);
}

.hint { display: block; margin-top: 4px; font-size: 11px; color: var(--ink-faint); }

input[type=text],
input[type=search],
input[type=number],
select {
	width: 100%;
	padding: 7px 8px;
	background: var(--panel-2);
	border: 1px solid var(--edge);
	border-radius: 3px;
	color: var(--ink);
	font: inherit;
	font-size: 13px;
}

select { appearance: none; padding-right: 24px;
	background-image: linear-gradient(45deg, transparent 50%, var(--ink-soft) 50%),
	                  linear-gradient(135deg, var(--ink-soft) 50%, transparent 50%);
	background-position: calc(100% - 13px) 50%, calc(100% - 8px) 50%;
	background-size: 5px 5px, 5px 5px;
	background-repeat: no-repeat;
}

input:focus, select:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: var(--accent); }

input[type=color] {
	width: 100%;
	height: 30px;
	padding: 2px;
	background: var(--panel-2);
	border: 1px solid var(--edge);
	border-radius: 3px;
	cursor: pointer;
}

.row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.row.three { grid-template-columns: 1fr 1fr 1fr; }

.swatches { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.swatches .fld { margin-bottom: 0; }

.checks { display: grid; gap: 8px; margin-bottom: 12px; }

.chk { display: flex; align-items: center; gap: 8px; font-size: 13px; cursor: pointer; }
.chk input { accent-color: var(--accent); width: 15px; height: 15px; }

/* ---------------------------------------------------------------- dimensions grid */

.grid7 {
	display: grid;
	grid-template-columns: 38px repeat(7, 1fr);
	gap: 4px;
	align-items: center;
}

.grid7 .col {
	font-size: 10px;
	color: var(--ink-faint);
	text-align: center;
	line-height: 1.2;
}

.grid7 .side { font-size: 11px; color: var(--ink-soft); }

.grid7 input { padding: 6px 2px; text-align: center; font-size: 12px; }

/* Chrome/Safari number spinners eat the width in a grid this tight. */
.grid7 input::-webkit-outer-spin-button,
.grid7 input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.grid7 input { -moz-appearance: textfield; }

/* ---------------------------------------------------------------- actions */

/* Element-agnostic, because the primary action is sometimes a link and sometimes
   a submit — "Save to computer" is an anchor, "Save to output/" is a button. */

.primary, .ghost {
	display: inline-block;
	padding: 8px 12px;
	border-radius: 3px;
	font: inherit;
	font-size: 13px;
	text-align: center;
	text-decoration: none;
	cursor: pointer;
}

.primary {
	background: var(--accent);
	color: var(--accent-in);
	border: 0;
	font-weight: 600;
}

.primary:hover { filter: brightness(1.08); }

.ghost {
	background: none;
	border: 1px solid var(--edge);
	color: var(--ink);
}

.ghost:hover { border-color: var(--accent); color: var(--accent); }

/* ---------------------------------------------------------------- flags */

.flag {
	margin: 0;
	padding: 12px 24px;
	font-size: 13px;
}

.flag.ok  { background: #16301f; color: #8fdcaf; border-bottom: 1px solid #1e4a2d; }
.flag.bad { background: #34191a; color: #f0a5a3; border-bottom: 1px solid #4c2223; }

/* ---------------------------------------------------------------- templates tool

   templates.php and template_edit.php. Kept here rather than inline in the two
   pages so they share one set of rules and stay on the tokens above — the first
   version set light panel backgrounds inline and inherited the page's near-white
   --ink, which read as white text on a pale card.                              */

.tally {
	display: flex;
	flex-wrap: wrap;
	gap: 22px;
	margin: 16px 24px;
	padding: 12px 16px;
	background: var(--panel);
	border: 1px solid var(--edge);
	border-radius: 4px;
	font-size: 12px;
	color: var(--ink-soft);
}

.tally b {
	display: block;
	font-size: 18px;
	color: var(--ink);
	font-variant-numeric: tabular-nums;
}

.filters { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 24px 14px; font-size: 12px; }

.filters a {
	padding: 4px 11px;
	border-radius: 999px;
	background: var(--panel-2);
	border: 1px solid var(--edge);
	color: var(--ink-soft);
	text-decoration: none;
}

.filters a:hover { border-color: var(--accent); color: var(--accent); }
.filters a.on { background: var(--accent); border-color: var(--accent); color: var(--accent-in); font-weight: 600; }

.tpl { width: calc(100% - 48px); margin: 0 24px 40px; border-collapse: collapse; font-size: 13px; }

.tpl th {
	text-align: left;
	padding: 8px;
	border-bottom: 1px solid var(--edge);
	font-size: 10px;
	text-transform: uppercase;
	letter-spacing: .06em;
	color: var(--ink-faint);
	font-weight: 600;
}

.tpl td { padding: 7px 8px; border-bottom: 1px solid var(--edge); vertical-align: middle; color: var(--ink); }
.tpl tbody tr:hover td { background: var(--panel); }
.tpl .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

.tpl .thumb { width: 58px; }

.tpl .thumb img {
	width: 58px;
	height: 46px;
	object-fit: contain;
	background: var(--panel-2);
	border: 1px solid var(--edge);
	border-radius: 3px;
	display: block;
}

.tpl select { font-size: 12px; padding: 5px 24px 5px 7px; }
.tpl form { display: flex; gap: 6px; align-items: center; }
.tpl form select { max-width: 240px; }

.score { font-size: 11px; color: var(--ink-faint); }

/* Sits in the caption when a traced outline exists but is too far off its own
   season to be drawn. Warmer than the caption around it so it reads as a
   condition rather than as more of the same sentence, but not an error — the
   picture is fine, it is just being built from the seven distances instead. */
.warn {
	color: #e0b26a;
	border-bottom: 1px dotted #7a6132;
	cursor: help;
}

/* Status is carried by a filled chip. Each keeps its own foreground so none of
   them can end up light-on-light the way the first pass did. */
.pill {
	display: inline-block;
	padding: 2px 9px;
	border-radius: 999px;
	font-size: 11px;
	font-weight: 700;
	letter-spacing: .02em;
}

.pill.verified { background: var(--accent);  color: var(--accent-in); }
.pill.auto     { background: #b8860b;        color: #17120a; }
.pill.pending  { background: var(--panel-2); color: var(--ink-soft); border: 1px solid var(--edge); }
.pill.skipped  { background: var(--edge);    color: var(--ink-faint); }

/* ---------------------------------------------------------------- template editor */

.tewrap { display: flex; gap: 24px; align-items: flex-start; flex-wrap: wrap; padding: 0 24px 40px; }

.testage {
	position: relative;
	line-height: 0;
	background: var(--panel-2);
	border: 1px solid var(--edge);
	border-radius: 4px;
	overflow: hidden;
}

.testage img { display: block; max-width: 100%; height: auto; }
.testage svg { position: absolute; inset: 0; width: 100%; height: 100%; cursor: crosshair; }

.tepanel { min-width: 320px; flex: 1 1 320px; max-width: 460px; }

.step {
	padding: 11px 13px;
	border-radius: 4px;
	background: var(--panel);
	border: 1px solid var(--edge);
	margin-bottom: 10px;
	font-size: 12px;
	color: var(--ink-soft);
}

.step b { display: block; margin-bottom: 4px; color: var(--ink); font-size: 13px; }
.step.on { border-color: var(--accent); background: var(--panel-2); }
.step select { margin-top: 6px; }

.rowline { display: flex; gap: 10px; align-items: center; margin-bottom: 9px; font-size: 12px; }
.rowline label { min-width: 84px; color: var(--ink-soft); }
.rowline input[type=range] { flex: 1; accent-color: var(--accent); }
.rowline select { flex: 0 1 auto; width: auto; }

.val { font-variant-numeric: tabular-nums; min-width: 58px; text-align: right; color: var(--ink-faint); }

.legend { font-size: 11px; color: var(--ink-faint); margin-top: 10px; line-height: 1.6; }
.legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 5px; vertical-align: middle; }

.tezoom { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; font-size: 12px; }
.tezoom label { color: var(--ink-soft); }
.tezoom .zoombtn { padding: 4px 12px; font-size: 12px; }
.tezoom .zoombtn.on { border-color: var(--accent); color: var(--accent-in); background: var(--accent); font-weight: 600; }

/* The stage is sized in px by the zoom control, so it must not be squeezed by
   the flex row it sits in — the image scales to the stage, not the other way. */
.testage { flex: 0 0 auto; max-width: 100%; }
.testage img { width: 100%; }

/* Calibration is click, read, click — so the instructions and the angle picker
   have to stay reachable while the diagram is scrolled. */
.tepanel { position: sticky; top: 84px; align-self: flex-start; }
