/*
 * Chrome, layout and the map.
 *
 * Two halves. The map is drawn by js/ui/sprites.js and only needs placement
 * rules here -- every tile position is a `calc()` off `--tile`, which is
 * published once by MapView so nothing recomputes it. Everything else is the
 * floating furniture over the top: the bar, the dock, the sheet.
 *
 * Sunlit and warm rather than the usual slate. A town you are meant to want to
 * come back to should not look like a dashboard.
 */

:root {
	--grass: #86b56a;
	--grass-deep: #4c6f42; /* the land beyond the fence */
	--grass-line: #78a85e;

	--paper: #fdf6e7;
	--cream: #fffaf0;
	--sand: #f3e6cf;

	--ink: #43372a;
	--ink-soft: #8a7963;
	--ink-faint: #b8ab97;

	--accent: #ef8f3c;
	--accent-deep: #d3712a;
	--green: #5f9e4a;
	--green-deep: #4a8038;
	--danger: #c9534e;

	--edge: #e6d6b8;
	--edge-strong: #d3bd97;
	--disabled: #efe7d8;

	--radius: 14px;
	--radius-card: 22px;
	--shadow: 0 6px 18px rgb(63 45 20 / 18%);
	--shadow-soft: 0 2px 6px rgb(63 45 20 / 12%);

	--bar-top: max(0.6rem, env(safe-area-inset-top));
	--bar-bottom: max(0.6rem, env(safe-area-inset-bottom));
	/* The dock's height is fixed so the sheet and the quick buttons can sit
	   exactly above it rather than guessing. */
	--dock-height: 3.8rem;

	color-scheme: light;
}

* {
	box-sizing: border-box;
}

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

body {
	background: var(--grass-deep);
	color: var(--ink);
	font-family: ui-rounded, "SF Pro Rounded", "Segoe UI Variable Display", system-ui,
		-apple-system, "Helvetica Neue", sans-serif;
	font-size: clamp(0.9rem, 3.3vw, 1.02rem);
	line-height: 1.35;
	overscroll-behavior: none;
	-webkit-text-size-adjust: 100%;
	-webkit-tap-highlight-color: transparent;
}

/*
 * The browser never zooms the app: scrolling is the only touch behaviour it is
 * allowed, so neither a pinch nor a double tap grows the dock, the bar or the
 * sheet over the map. Every element says so, not just body, because WebKit
 * reads touch-action from the element under the finger.
 *
 * The map allows nothing at all. A drag there pans it and a pinch zooms it,
 * both from the pointer events, and neither scrolls the page.
 */
#app,
#app * {
	touch-action: pan-y;
}

#app .map,
#app .map * {
	touch-action: none;
}

#app {
	position: relative;
	width: 100%;
	height: 100%;
	overflow: hidden;
}

[hidden] {
	display: none !important;
}

/* --- Controls ------------------------------------------------------------- */

button {
	min-height: 2.75rem;
	padding: 0.45rem 0.9rem;
	border: 2px solid var(--edge);
	border-radius: var(--radius);
	background: var(--cream);
	color: var(--ink);
	font: inherit;
	font-weight: 650;
	cursor: pointer;
	-webkit-user-select: none;
	user-select: none;
	transition: background-color 90ms ease-out, border-color 90ms ease-out, transform 90ms ease-out;
}

button.primary {
	border-color: var(--green-deep);
	background: var(--green);
	color: #fff;
}

button.warn {
	border-color: #a83f3b;
	background: var(--danger);
	color: #fff;
}

button.ghost {
	border-color: transparent;
	background: var(--sand);
	color: var(--ink-soft);
}

button.wide {
	width: 100%;
}

button:active:not(:disabled) {
	transform: translateY(1px);
}

button:disabled {
	background: var(--disabled);
	border-color: transparent;
	color: var(--ink-faint);
	cursor: default;
}

button:focus-visible {
	outline: 3px solid var(--accent);
	outline-offset: 2px;
}

/* --- The map -------------------------------------------------------------- */

.map {
	position: absolute;
	inset: 0;
	overflow: hidden;
	background: var(--grass-deep);
	-webkit-user-select: none;
	user-select: none;
	-webkit-touch-callout: none;
}

.map.is-placing {
	cursor: copy;
}

.world {
	position: absolute;
	top: 0;
	left: 0;
	transform-origin: 0 0;
	will-change: transform;
}

.layer {
	position: absolute;
	inset: 0;
}

/* The land you own: brighter, fenced, and gridded so a footprint is countable. */
.land {
	position: absolute;
	border: 4px solid #6d5236;
	border-radius: 10px;
	background: var(--grass);
	box-shadow: inset 0 0 0 3px rgb(255 255 255 / 12%), 0 0 22px rgb(24 42 20 / 30%);
}

.grid {
	position: absolute;
	inset: 0;
	background-image:
		repeating-linear-gradient(to right, var(--grass-line) 0 1px, transparent 1px var(--tile)),
		repeating-linear-gradient(to bottom, var(--grass-line) 0 1px, transparent 1px var(--tile));
	opacity: 0.55;
}

.tree {
	position: absolute;
	translate: -50% -50%;
	pointer-events: none;
}

.tree svg {
	display: block;
	width: 100%;
	height: auto;
}

.objects {
	pointer-events: none;
}

.obj {
	position: absolute;
	left: calc(var(--x) * var(--tile));
	top: calc(var(--y) * var(--tile));
	width: calc(var(--w) * var(--tile));
	height: calc(var(--h) * var(--tile));
}

/* Faded and lifted while it is being carried, so it reads as somewhere it has
   not settled yet and the ghost is the thing to watch. */
.obj.is-lifted {
	opacity: 0.45;
	filter: drop-shadow(0 6px 8px rgb(63 45 20 / 45%));
}

.obj-art svg {
	display: block;
	width: 100%;
	height: 100%;
	overflow: visible;
}

/*
 * The countdown sits under the building rather than on it: a bar across the
 * roof hides the one thing that says which building it is.
 */
.obj-meta {
	position: absolute;
	right: 6%;
	bottom: -6px;
	left: 6%;
	display: flex;
	align-items: center;
	gap: 4px;
	font-size: 11px;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	color: #fff;
	text-shadow: 0 1px 2px rgb(30 40 25 / 70%);
}

.map.no-timers .obj-meta {
	display: none;
}

.obj-bar {
	flex: 1;
	height: 6px;
	border-radius: 3px;
	background: rgb(30 45 25 / 45%);
	overflow: hidden;
}

.obj-bar i {
	display: block;
	width: calc(var(--p, 0) * 100%);
	height: 100%;
	border-radius: 3px;
	background: linear-gradient(90deg, #ffd479, var(--accent));
}

.obj-badge {
	position: absolute;
	top: -10px;
	right: -6px;
	display: grid;
	place-items: center;
	width: 30px;
	height: 30px;
	border: 2px solid #fff;
	border-radius: 50%;
	background: var(--cream);
	box-shadow: var(--shadow-soft);
	scale: clamp(1, var(--inv-scale, 1), 2);
	animation: bob 1.4s ease-in-out infinite;
}

.obj-badge svg {
	width: 20px;
	height: 20px;
}

.obj-badge b {
	position: absolute;
	right: -6px;
	bottom: -6px;
	min-width: 17px;
	padding: 0 3px;
	border-radius: 9px;
	background: var(--accent-deep);
	color: #fff;
	font-size: 11px;
	line-height: 17px;
	text-align: center;
}

@keyframes bob {
	0%, 100% { transform: translateY(0); }
	50% { transform: translateY(-4px); }
}

/* Where the building being placed would land. */
.footprint {
	position: absolute;
	left: calc(var(--x, 0) * var(--tile));
	top: calc(var(--y, 0) * var(--tile));
	width: calc(var(--w, 1) * var(--tile));
	height: calc(var(--h, 1) * var(--tile));
	border: 3px dashed #fff;
	border-radius: 8px;
	background: rgb(255 255 255 / 28%);
	pointer-events: none;
}

.footprint.is-blocked {
	border-color: #ffd9d7;
	background: rgb(201 83 78 / 38%);
}

/* --- Top bar -------------------------------------------------------------- */

.hud {
	position: absolute;
	top: var(--bar-top);
	right: 0.6rem;
	left: 0.6rem;
	display: flex;
	align-items: center;
	gap: 0.5rem;
	max-width: 34rem;
	margin-inline: auto;
	pointer-events: none;
}

.level-block {
	display: flex;
	align-items: center;
	gap: 0.45rem;
	padding: 0.3rem 0.55rem 0.3rem 0.3rem;
	border-radius: 999px;
	background: rgb(255 250 240 / 92%);
	box-shadow: var(--shadow);
}

.level-num {
	display: grid;
	place-items: center;
	width: 2rem;
	height: 2rem;
	border-radius: 50%;
	background: var(--green);
	color: #fff;
	font-weight: 800;
}

.xp {
	display: flex;
	flex-direction: column;
	gap: 2px;
	width: 5.5rem;
}

.xp-text {
	font-size: 0.68rem;
	font-variant-numeric: tabular-nums;
	color: var(--ink-soft);
}

.meter {
	height: 7px;
	border-radius: 4px;
	background: var(--sand);
	overflow: hidden;
}

.meter i {
	display: block;
	width: calc(min(var(--p, 0), 1) * 100%);
	height: 100%;
	border-radius: 4px;
	background: linear-gradient(90deg, #8fd06f, var(--green));
}

.chips {
	display: flex;
	flex: 1;
	flex-wrap: wrap;
	gap: 0.3rem;
	justify-content: flex-end;
}

.chip {
	display: inline-flex;
	align-items: center;
	gap: 0.25rem;
	padding: 0.28rem 0.55rem;
	border-radius: 999px;
	background: rgb(255 250 240 / 92%);
	box-shadow: var(--shadow-soft);
	font-size: 0.82rem;
	font-variant-numeric: tabular-nums;
	font-weight: 700;
}

.chip.is-full {
	background: #ffe0dd;
	color: var(--danger);
}

.icon {
	display: inline-flex;
	flex: none;
}

.icon svg {
	display: block;
	width: 1.1em;
	height: 1.1em;
}

.icon.big svg {
	width: 2rem;
	height: 2rem;
}

.icon.huge svg {
	width: 3.5rem;
	height: 3.5rem;
}

/* --- Quick actions and the placement bar ---------------------------------- */

.quick {
	position: absolute;
	right: 0.6rem;
	bottom: calc(var(--bar-bottom) + var(--dock-height) + 0.6rem);
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
	align-items: flex-end;
}

.quick-button {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	min-height: 2.75rem;
	padding: 0.35rem 0.7rem;
	border: none;
	border-radius: 999px;
	background: var(--cream);
	box-shadow: var(--shadow);
	font-size: 0.85rem;
}

.quick-button b {
	min-width: 1.3rem;
	padding: 0 0.3rem;
	border-radius: 999px;
	background: var(--accent);
	color: #fff;
	font-size: 0.78rem;
	text-align: center;
}

#app:has(#placing:not([hidden])) .quick {
	display: none;
}

.placing {
	position: absolute;
	right: 0.6rem;
	bottom: calc(var(--bar-bottom) + var(--dock-height) + 0.6rem);
	left: 0.6rem;
	display: flex;
	gap: 0.6rem;
	align-items: center;
	justify-content: center;
	max-width: 34rem;
	margin-inline: auto;
	padding: 0.5rem 0.6rem 0.5rem 0.9rem;
	border-radius: var(--radius);
	background: rgb(255 250 240 / 95%);
	box-shadow: var(--shadow);
}

.placing p {
	margin: 0;
	flex: 1;
}

/* --- Dock ----------------------------------------------------------------- */

/*
 * Above the scrim on purpose. A sheet dims the map, not the menu: switching from
 * the orders to the barn to check what you have is the most common move in the
 * game, and it should be one tap.
 */
.dock {
	position: absolute;
	z-index: 4;
	right: 0.6rem;
	bottom: var(--bar-bottom);
	left: 0.6rem;
	display: grid;
	height: var(--dock-height);
	grid-template-columns: repeat(4, 1fr);
	gap: 0.35rem;
	max-width: 34rem;
	margin-inline: auto;
	padding: 0.35rem;
	border-radius: 18px;
	background: rgb(255 250 240 / 95%);
	box-shadow: var(--shadow);
}

.dock button {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 1px;
	min-height: 3.1rem;
	padding: 0.3rem 0.2rem;
	border: none;
	border-radius: 12px;
	background: transparent;
	font-size: 0.72rem;
	font-weight: 700;
	color: var(--ink-soft);
}

.dock button .icon svg {
	width: 1.55rem;
	height: 1.55rem;
}

.dock button.is-active {
	background: var(--sand);
	color: var(--ink);
}

/* --- Sheet ---------------------------------------------------------------- */

.scrim {
	position: absolute;
	z-index: 2;
	inset: 0;
	background: rgb(40 30 18 / 34%);
}

/* Floats just above the dock, so the dock is never under it. */
.sheet {
	position: absolute;
	z-index: 3;
	right: 0.6rem;
	bottom: calc(var(--bar-bottom) + var(--dock-height) + 0.4rem);
	left: 0.6rem;
	display: flex;
	flex-direction: column;
	max-height: min(66vh, 38rem);
	max-width: 34rem;
	margin-inline: auto;
	border-radius: var(--radius-card);
	background: var(--paper);
	box-shadow: 0 8px 30px rgb(40 30 18 / 28%);
	animation: rise 180ms ease-out;
}

@keyframes rise {
	from { transform: translateY(18px); opacity: 0.4; }
}

.sheet-head {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	padding: 0.7rem 0.9rem 0.5rem;
	border-bottom: 2px solid var(--edge);
}

.sheet-title {
	flex: 1;
	margin: 0;
	font-size: 1.15rem;
	font-weight: 800;
}

.sheet-body {
	flex: 1;
	padding: 0.7rem 0.9rem 0.9rem;
	overflow-y: auto;
	overscroll-behavior: contain;
	-webkit-overflow-scrolling: touch;
}

.panel-note,
.prose {
	margin: 0 0 0.7rem;
	color: var(--ink-soft);
	text-wrap: pretty;
}

.muted {
	color: var(--ink-soft);
	font-size: 0.85em;
}

.pad {
	padding: 1.5rem 0;
	text-align: center;
}

.sheet-inner > * + * {
	margin-top: 1.1rem;
}

.group h3 {
	margin: 0 0 0.4rem;
	font-size: 0.78rem;
	font-weight: 800;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--ink-faint);
}

/* --- Rows ----------------------------------------------------------------- */

.rows {
	display: flex;
	flex-direction: column;
	gap: 0.45rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.rows.tight {
	gap: 0.25rem;
}

.row {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	padding: 0.6rem 0.7rem;
	border: 2px solid var(--edge);
	border-radius: var(--radius);
	background: var(--cream);
}

.row.is-locked {
	background: var(--disabled);
	border-color: transparent;
}

.row.danger {
	border-color: #eccbc8;
}

.row-main {
	display: flex;
	flex: 1;
	flex-direction: column;
	gap: 1px;
	min-width: 0;
}

.row-main b {
	font-weight: 750;
}

.cost {
	display: inline-flex;
	align-items: center;
	gap: 0.2rem;
	margin-top: 0.15rem;
	font-size: 0.85em;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
}

.cost em {
	font-style: normal;
	font-weight: 600;
	color: var(--accent-deep);
}

.pill {
	padding: 0.15rem 0.5rem;
	border-radius: 999px;
	background: var(--sand);
	font-weight: 800;
	font-variant-numeric: tabular-nums;
}

.acts {
	display: flex;
	gap: 0.3rem;
	align-items: center;
}

.acts button {
	min-height: 2.6rem;
	padding-inline: 0.6rem;
	font-size: 0.85rem;
}

.thumb {
	display: grid;
	place-items: center;
	width: 3.4rem;
	height: 3.4rem;
	flex: none;
	border-radius: 10px;
	background: var(--grass);
}

.thumb svg {
	width: 100%;
	height: 100%;
	overflow: visible;
}

.land-thumb {
	background:
		linear-gradient(135deg, var(--grass) 0 50%, var(--grass-deep) 50% 100%);
}

/* --- Orders --------------------------------------------------------------- */

.cards {
	display: flex;
	flex-direction: column;
	gap: 0.6rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.card {
	padding: 0.7rem 0.8rem;
	border: 2px solid var(--edge);
	border-radius: var(--radius);
	background: var(--cream);
}

.card.is-waiting {
	display: flex;
	align-items: center;
	gap: 0.7rem;
	border-style: dashed;
	background: transparent;
}

.card.is-waiting p {
	margin: 0;
}

.order-items {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
}

.req {
	display: inline-flex;
	align-items: center;
	gap: 0.28rem;
	padding: 0.28rem 0.5rem;
	border-radius: 999px;
	background: var(--sand);
	font-size: 0.85rem;
}

.req-count {
	font-weight: 800;
	font-variant-numeric: tabular-nums;
}

.req.is-short .req-count {
	color: var(--danger);
}

.req.is-met .req-count {
	color: var(--green-deep);
}

.order-foot {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	margin-top: 0.7rem;
	padding-top: 0.6rem;
	border-top: 2px dashed var(--edge);
}

.pays {
	display: flex;
	flex: 1;
	gap: 0.45rem;
}

.tag {
	display: inline-flex;
	align-items: center;
	gap: 0.22rem;
	font-weight: 800;
	font-variant-numeric: tabular-nums;
}

/* --- Barn ----------------------------------------------------------------- */

.barn-head {
	display: flex;
	flex-direction: column;
	gap: 0.45rem;
	margin-bottom: 0.9rem;
}

.barn-count {
	margin: 0;
	display: flex;
	align-items: center;
	gap: 0.35rem;
	color: var(--ink-soft);
}

.barn-count b {
	color: var(--ink);
}

/* --- Fields and workshops ------------------------------------------------- */

.field-growing {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.3rem;
	padding: 1.6rem 0;
	text-align: center;
}

.field-growing p {
	margin: 0;
}

.queue-block {
	margin-bottom: 1rem;
}

.queue {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 0.4rem;
	margin-bottom: 0.5rem;
}

.slot {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 0.2rem;
	min-height: 5rem;
	padding: 0.4rem 0.3rem;
	border: 2px solid var(--edge);
	border-radius: var(--radius);
	background: var(--cream);
}

.slot.is-empty {
	border-style: dashed;
	background: transparent;
}

.slot.is-done {
	border-color: var(--green);
	background: #f0f8ea;
}

.slot .meter {
	width: 100%;
}

.slot-time {
	font-size: 0.72rem;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	color: var(--ink-soft);
}

.icon.tick svg {
	width: 1.2rem;
	height: 1.2rem;
}

.chip-x {
	position: absolute;
	top: -10px;
	right: -10px;
	display: grid;
	place-items: center;
	width: 2rem;
	height: 2rem;
	min-height: 0;
	padding: 0;
	border: 2px solid var(--edge);
	border-radius: 50%;
	background: var(--cream);
	font-size: 1rem;
	line-height: 1;
	color: var(--ink-soft);
}

.recipe .reqs {
	display: flex;
	flex-wrap: wrap;
	gap: 0.25rem;
	margin-top: 0.25rem;
}

.recipe .reqs em {
	font-style: normal;
	color: var(--accent-deep);
	font-size: 0.85em;
}

/* --- Town hall ------------------------------------------------------------ */

.figures {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 0.4rem;
	margin-bottom: 1rem;
}

.figure {
	display: flex;
	flex-direction: column;
	align-items: center;
	padding: 0.6rem 0.2rem;
	border-radius: var(--radius);
	background: var(--cream);
	border: 2px solid var(--edge);
	text-align: center;
}

.figure b {
	font-size: 1rem;
	font-variant-numeric: tabular-nums;
}

.figure span {
	font-size: 0.68rem;
	color: var(--ink-soft);
}

.toggle {
	width: 3.2rem;
	min-height: 2rem;
	padding: 0.2rem;
	border-radius: 999px;
	background: var(--sand);
	border-color: transparent;
}

.toggle span {
	display: block;
	width: 1.5rem;
	height: 1.5rem;
	border-radius: 50%;
	background: #fff;
	box-shadow: var(--shadow-soft);
	transition: translate 120ms ease-out;
}

.toggle.is-on {
	background: var(--green);
}

.toggle.is-on span {
	translate: 1.35rem 0;
}

/* --- Overlay card --------------------------------------------------------- */

.overlay {
	position: absolute;
	inset: 0;
	z-index: 5;
	display: grid;
	place-items: center;
	padding: 1.2rem;
	background: rgb(40 30 18 / 45%);
}

.card-panel {
	display: flex;
	flex-direction: column;
	gap: 0.7rem;
	width: 100%;
	max-width: 24rem;
	padding: 1.4rem;
	border-radius: var(--radius-card);
	background: var(--paper);
	box-shadow: var(--shadow);
	text-align: center;
	animation: rise 200ms ease-out;
}

.card-title {
	margin: 0;
	font-size: 1.7rem;
	font-weight: 800;
}

.card-lead {
	margin: 0;
	color: var(--ink-soft);
}

.card-list {
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
	margin: 0;
	padding: 0;
	list-style: none;
	text-align: left;
}

.card-list li {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	padding: 0.5rem 0.7rem;
	border-radius: var(--radius);
	background: var(--cream);
}

.card-list li div {
	display: flex;
	flex-direction: column;
}

/* --- Toasts --------------------------------------------------------------- */

.toasts {
	position: absolute;
	top: calc(var(--bar-top) + 5.4rem);
	right: 0.6rem;
	left: 0.6rem;
	z-index: 6;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.35rem;
	pointer-events: none;
}

.toast {
	max-width: 22rem;
	padding: 0.5rem 0.85rem;
	border-radius: 999px;
	background: rgb(67 55 42 / 94%);
	color: #fff8ec;
	font-size: 0.85rem;
	font-weight: 650;
	box-shadow: var(--shadow);
	animation: rise 160ms ease-out;
}

.toast.is-reward {
	background: rgb(74 128 56 / 96%);
}

.toast.is-warn {
	background: rgb(180 74 68 / 96%);
}

.toast.is-leaving {
	opacity: 0;
	transition: opacity 240ms ease-out;
}

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 1ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 1ms !important;
	}
}
