/* Theme tokens moved to theme.css (loaded via its own <link> tag before this file) - single source of
   truth shared with landing.css. See theme.css's header comment. */

* {
	box-sizing: border-box;
}

html,
body {
	height: 100%;
	margin: 0;
}

body {
	background: var(--bg-base);
	color: var(--text-primary);
	font-family: var(--font-body);
	overflow: hidden;
}

.visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
}

.app {
	display: flex;
	flex-direction: column;
	height: 100vh;
}

/* ---------- top bar ---------- */

.topbar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding: 0.75rem 1.25rem;
	background: linear-gradient(to bottom, var(--surface-1), var(--bg-base));
	border-bottom: 1px solid var(--rim);
	flex-wrap: wrap;
}

/* .brand is a link back to the wiki home (/) - shares the wiki header's own rune-mark + wordmark
   (wiki/css/wiki.css .wk-logo/.wk-logo-mark) so the map reads as the same product, not a bolted-on
   tool. `?app=1` still hides this entirely (body.app-embed rule below) - the native app supplies its
   own header/back affordance. */
.brand {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	font-family: var(--font-display);
	letter-spacing: 0.04em;
	white-space: nowrap;
	color: var(--text-primary);
	text-decoration: none;
}

.brand:hover,
.brand:focus-visible {
	text-decoration: none;
}

.brand-mark {
	display: inline-flex;
	color: var(--accent);
	filter: drop-shadow(0 0 6px color-mix(in srgb, var(--accent) 55%, transparent));
	transition: transform 150ms ease, filter 150ms ease;
}

.brand:hover .brand-mark,
.brand:focus-visible .brand-mark {
	transform: rotate(-8deg) scale(1.07);
	filter: drop-shadow(0 0 10px color-mix(in srgb, var(--accent) 70%, transparent));
}

.brand-name em {
	font-style: normal;
	color: var(--text-secondary);
	font-weight: 400;
}

.brand-name b {
	color: var(--accent);
}

.seed-form {
	display: flex;
	gap: 0.5rem;
	flex: 1 1 320px;
	max-width: 480px;
}

#seed-input {
	flex: 1;
	background: var(--bg-deep);
	border: 1px solid var(--rim);
	border-radius: 4px;
	color: var(--text-primary);
	padding: 0.55rem 0.75rem;
	font-size: 0.95rem;
	font-family: var(--font-body);
}

#seed-input::placeholder {
	color: var(--text-muted);
}

#seed-input:focus {
	outline: none;
	border-color: var(--accent);
	box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 35%, transparent);
}

#generate-btn {
	background: var(--surface-2);
	color: var(--text-primary);
	border: 1px solid var(--rim);
	border-radius: 4px;
	padding: 0.55rem 1.1rem;
	font-family: var(--font-display);
	letter-spacing: 0.03em;
	cursor: pointer;
	white-space: nowrap;
	transition: border-color 150ms ease, box-shadow 150ms ease;
}

#generate-btn:hover,
#generate-btn:focus-visible {
	border-color: var(--accent);
	box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 45%, transparent);
}

/* ---------- map stage ---------- */

.map-stage {
	position: relative;
	flex: 1;
	background: var(--bg-deep);
	overflow: hidden;
	cursor: grab;
}

.map-stage.dragging {
	cursor: grabbing;
}

#map-canvas {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	display: block;
}

/* Transparent overlay for POI pins, sits above #map-canvas and is redrawn independently on pan/zoom
   (no world-gen recomputation needed - see src/map/poiLayer.js). */
#poi-canvas {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	display: block;
	pointer-events: none; /* hit-testing is done manually in app.js against pixel positions */
}

.poi-search-form {
	flex: 0 1 240px;
}

#poi-search-input {
	width: 100%;
	background: var(--bg-deep);
	border: 1px solid var(--rim);
	border-radius: 4px;
	color: var(--text-primary);
	padding: 0.55rem 0.75rem;
	font-size: 0.85rem;
	font-family: var(--font-body);
}

#poi-search-input:disabled {
	opacity: 0.5;
	cursor: not-allowed;
}

#poi-search-input::placeholder {
	color: var(--text-muted);
}

#poi-search-input:focus {
	outline: none;
	border-color: var(--accent);
	box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 35%, transparent);
}

.poi-search-results {
	position: absolute;
	top: calc(100% + 0.25rem);
	left: 0;
	right: 0;
	background: var(--surface-1);
	border: 1px solid var(--rim);
	border-radius: 6px;
	max-height: 240px;
	overflow-y: auto;
	z-index: 5;
}

.poi-search-result {
	padding: 0.4rem 0.6rem;
	font-size: 0.8rem;
	cursor: pointer;
	color: var(--text-secondary);
	border-bottom: 1px solid var(--rim);
}

.poi-search-result:last-child {
	border-bottom: none;
}

.poi-search-result:hover,
.poi-search-result.active {
	background: var(--surface-2);
	color: var(--text-primary);
}

.hud {
	position: absolute;
	background: color-mix(in srgb, var(--surface-1) 88%, transparent);
	border: 1px solid var(--rim);
	border-radius: 6px;
	padding: 0.5rem 0.75rem;
	font-size: 0.8rem;
	color: var(--text-secondary);
	backdrop-filter: blur(2px);
}

.hud-top-left {
	top: 1rem;
	left: 1rem;
}

.hud-line {
	color: var(--text-primary);
}

.hud-line.muted {
	color: var(--text-muted);
	font-size: 0.75rem;
}

.hud-bottom-left {
	left: 1rem;
	bottom: 1rem;
	max-width: 220px;
}

.legend-title {
	font-family: var(--font-display);
	letter-spacing: 0.03em;
	color: var(--text-primary);
	margin-bottom: 0.35rem;
}

.legend-row {
	display: flex;
	align-items: center;
	gap: 0.4rem;
	font-size: 0.75rem;
	line-height: 1.5;
}

.legend-swatch {
	width: 0.7rem;
	height: 0.7rem;
	border-radius: 2px;
	border: 1px solid var(--rim);
	flex: none;
}

.legend-title-poi {
	margin-top: 0.5rem;
}

.legend-poi-row {
	display: flex;
	align-items: center;
	gap: 0.4rem;
	font-size: 0.75rem;
	line-height: 1.5;
}

.legend-poi-row label {
	display: flex;
	align-items: center;
	gap: 0.4rem;
	cursor: pointer;
}

.legend-poi-icon {
	width: 0.9rem;
	height: 0.9rem;
	flex: none;
	image-rendering: pixelated;
}

/* ---------- POI popup ---------- */

.poi-popup {
	position: absolute;
	transform: translate(-50%, calc(-100% - 14px));
	background: var(--surface-1);
	border: 1px solid var(--accent);
	border-radius: 6px;
	padding: 0.6rem 0.75rem;
	box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
	min-width: 160px;
	z-index: 6;
}

.poi-popup.hidden {
	display: none;
}

.poi-popup-title {
	font-family: var(--font-display);
	color: var(--text-primary);
	font-size: 0.85rem;
	margin-bottom: 0.25rem;
	padding-right: 1rem;
}

.poi-popup-coords {
	font-size: 0.75rem;
	color: var(--text-secondary);
	margin-bottom: 0.5rem;
	font-family: monospace;
}

.poi-popup-copy {
	width: 100%;
}

.poi-popup-close {
	position: absolute;
	top: 0.3rem;
	right: 0.4rem;
	background: none;
	border: none;
	color: var(--text-muted);
	cursor: pointer;
	font-size: 1rem;
	line-height: 1;
}

.poi-popup-close:hover {
	color: var(--text-primary);
}

.foot-link {
	color: var(--accent);
	margin-left: 0.75rem;
}

.hud-top-right {
	top: 1rem;
	right: 1rem;
	display: flex;
	flex-direction: column;
	gap: 0.35rem;
	padding: 0.4rem;
}

.hud-bottom-right {
	right: 1rem;
	bottom: 1rem;
}

.ghost-btn {
	background: var(--surface-2);
	color: var(--text-primary);
	border: 1px solid var(--rim);
	border-radius: 4px;
	padding: 0.4rem 0.6rem;
	cursor: pointer;
	font-size: 0.85rem;
	line-height: 1;
}

.ghost-btn:hover,
.ghost-btn:focus-visible {
	border-color: var(--accent);
	color: var(--accent);
}

.empty-state {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	pointer-events: none;
	text-align: center;
	padding: 2rem;
}

.hugin-tip {
	color: var(--text-secondary);
	font-family: var(--font-display);
	letter-spacing: 0.02em;
	max-width: 26rem;
}

.empty-state.hidden {
	display: none;
}

/* ---------- footer ---------- */

.foot-note {
	padding: 0.4rem 1.25rem;
	font-size: 0.7rem;
	color: var(--text-muted);
	background: var(--bg-base);
	border-top: 1px solid var(--rim);
}

@media (max-width: 640px) {
	.topbar {
		flex-direction: column;
		align-items: stretch;
	}
	/* Real bug found verifying stage 3's in-app embed at true phone widths (narrower than this site had
	   previously been screenshotted at): `.seed-form`'s `flex: 1 1 320px` is a ROW-context sizing rule
	   (grow/shrink apply to WIDTH there). Once `.topbar` switches to `flex-direction: column` here, the
	   same rule's grow/shrink now apply to HEIGHT (column mode's main axis) instead - `flex-grow: 1` made
	   the seed form balloon to fill the entire remaining vertical space, squeezing the actual map/legend
	   far below the fold. Reset to a fixed-height row that just stretches to the column's full WIDTH
	   (`align-items: stretch` above, cross-axis in column mode) instead. */
	.seed-form {
		flex: 0 0 auto;
		max-width: none;
	}
	.hud-bottom-left {
		max-width: 60vw;
	}
}

/* ---------- stage 3: wiki popup (icon + key stats), apps/hub/data/poi-wiki.js ---------- */

.poi-popup-header {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	padding-right: 1rem;
	margin-bottom: 0.25rem;
}

.poi-popup-icon {
	width: 1.4rem;
	height: 1.4rem;
	flex: none;
	image-rendering: pixelated;
}

.poi-popup-header .poi-popup-title {
	margin-bottom: 0;
	padding-right: 0;
}

.poi-popup-stats {
	font-size: 0.72rem;
	color: var(--text-secondary);
	margin-bottom: 0.5rem;
	line-height: 1.4;
}

.poi-popup-stats.hidden {
	display: none;
}

.poi-popup-stat-line {
	white-space: nowrap;
}

/* ---------- stage 3: chrome-less app embed (`?app=1`, apps/hub/README.md Stage 3) ---------- */
/* The native app supplies its own header/back affordance and detail screens (Companion for Valheim
   itself is the "back to the app" path) - hide the site's own wordmark and the footer's "Back to
   Companion for Valheim" link. Seed input, POI search, legend, zoom/export controls, and the
   not-affiliated disclaimer text all stay untouched. */

body.app-embed .brand,
body.app-embed .foot-link {
	display: none;
}
