/* Design tokens. Appearance (day/night) is coupled to sun status at the
   selected location -- weather.php sets body.theme-day / body.theme-night --
   so it mirrors the day/night variants of the hand-drawn weather icons rather
   than the OS theme. Day is the default (:root); night overrides the tokens. */
:root {
	--bg: #f4f6f9;
	--card: #ffffff;
	--ink: #1f2a37;
	--muted: #6b7683;
	--accent: #4688d1;
	--soft: #dbe7f4;
	--border: #e7ebf1;
	--rain: #a9c3e3;
}

body.theme-night {
	--bg: #0f1822;
	--card: #182430;
	--ink: #e9eff5;
	--muted: #8fa0b1;
	--accent: #6fb0f0;
	--soft: #22364b;
	--border: #26333f;
	--rain: #3f5f86;
}

* {
	box-sizing: border-box;
}

html {
	height: 100%;
}

body {
	margin: 0;
	min-height: 100%;
	background: var(--bg);
	color: var(--ink);
	font-family: 'Raleway', system-ui, -apple-system, sans-serif;
	-webkit-font-smoothing: antialiased;
}

/* Single scrolling column, sized for a phone and centered on wider screens.
   Gutter 18px per the design's scroll-area padding. */
.app {
	width: 100%;
	max-width: 430px;
	margin: 0 auto;
	padding: 6px 18px 28px;
}

img {
	-webkit-user-drag: none;
}

/* Horizontal strips (saved chips, 7-day) scroll independently; hide the bar. */
.hscroll {
	overflow-x: auto;
	overflow-y: hidden;
	scrollbar-width: none;
	-webkit-overflow-scrolling: touch;
}

.hscroll::-webkit-scrollbar {
	width: 0;
	height: 0;
	background: transparent;
}

/* ---- Location actions toolbar ---------------------------------------- */
/* The place name moved into the current card (see .place-name); this row now
   carries the saved-location chips (left, flex-growing and scrolling) and the
   action buttons (right, fixed), on a single line above the card. */
.loc-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	margin-top: 2px;
}

/* Place name, now the header of the current-conditions card. Centered above
   the temperature so it reads as a label for the data rather than a detached
   page title. */
.place-name {
	font-size: 22px;
	font-weight: 700;
	line-height: 1.02;
	color: var(--ink);
	margin: 0 0 2px;
	text-align: center;
}

.loc-actions {
	display: flex;
	gap: 8px;
	flex: 0 0 auto;
}

.icon-btn {
	width: 42px;
	height: 42px;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 13px;
	cursor: pointer;
	padding: 0;
	transition: transform .08s ease;
}

.icon-btn:active {
	transform: scale(.94);
}

.icon-btn-primary {
	border: none;
	background: var(--accent);
	color: #fff;
}

.icon-btn-ghost {
	border: 1.5px solid var(--border);
	background: transparent;
	color: var(--ink);
}

/* Button text label: hidden on mobile (icon-only buttons), shown on desktop. */
.btn-label {
	display: none;
}

/* ---- Saved-location chips -------------------------------------------- */
.chips {
	display: flex;
	gap: 7px;
	/* Shares the toolbar row with .loc-actions: take the leftover width and
	   scroll horizontally rather than pushing the buttons off the row. */
	flex: 1 1 auto;
	min-width: 0;
	padding-bottom: 2px;
}

.chip {
	display: inline-flex;
	align-items: center;
	padding: 7px 13px;
	border-radius: 999px;
	font-size: 12.5px;
	font-weight: 600;
	white-space: nowrap;
	background: var(--soft);
	color: var(--ink);
	border: 1px solid var(--border);
}

.chip-active {
	background: var(--accent);
	color: #fff;
	border-color: var(--accent);
}

.chip a {
	color: inherit;
	text-decoration: none;
}

.chip-remove {
	background: none;
	border: none;
	padding: 0 0 0 7px;
	margin: 0;
	font-size: 14px;
	line-height: 1;
	color: inherit;
	cursor: pointer;
	opacity: .7;
}

/* ---- Cards ----------------------------------------------------------- */
.card {
	background: var(--card);
	border: 1px solid var(--border);
	border-radius: 26px;
	box-shadow: 0 12px 30px -20px rgba(24, 44, 74, .35);
}

/* ---- Current conditions ---------------------------------------------- */
.current-card {
	padding: 16px 22px 14px;
	margin-top: 12px;
}

.hero {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 6px;
}

/* Holds the temperature and the two flanking icons; the icons are absolutely
   positioned against this row so they stay level with the number. */
.hero-main {
	position: relative;
	align-self: stretch;
	display: flex;
	justify-content: center;
}

.hero-temp-row {
	display: flex;
	align-items: flex-start;
	gap: 3px;
}

.hero-temp {
	font-size: 66px;
	font-weight: 300;
	line-height: .82;
	letter-spacing: -.03em;
	color: var(--ink);
	font-variant-numeric: tabular-nums;
}

.hero-unit {
	font-size: 24px;
	font-weight: 300;
	color: var(--muted);
	margin-top: 4px;
}

.hero-symbol {
	position: absolute;
	right: 9%;
	top: 50%;
	transform: translateY(-50%);
	width: 64px;
	height: 64px;
	object-fit: contain;
}

.hero-wind {
	position: absolute;
	left: 9%;
	top: 50%;
	width: 34px;
	height: 34px;
	object-fit: contain;
}

.feels {
	font-size: 13px;
	font-weight: 300;
	color: var(--muted);
	margin: 0;
}

.sun-row {
	display: flex;
	margin-top: 12px;
	padding-top: 12px;
	border-top: 1px solid var(--border);
}

.sun-col {
	flex: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 9px;
}

.sun-col + .sun-col {
	padding-left: 10px;
	border-left: 1px solid var(--border);
}

.sun-col img {
	width: 32px;
	height: 32px;
	object-fit: contain;
}

.sun-time {
	font-size: 16px;
	font-weight: 600;
	color: var(--ink);
	font-variant-numeric: tabular-nums;
}

/* The sunset column stacks its time over the sunset-quality meter. Both
   columns stay centred in the row, so the taller sunset side grows the row
   symmetrically rather than tipping the footer to one side. */
.sun-stack {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
}

/* Sunset-quality meter (experimental -- see includes/sunset.php). The bar is
   the whole rating: no number, no label. Fixed 68px wide whatever the score;
   only the gradient's opacity and the marker's position move. */
.ss-meter {
	position: relative;
	width: 68px;
	height: 6px;
	margin-top: 5px;
}

.ss-meter svg {
	display: block;
	border-radius: 3px;
	overflow: hidden;
}

/* Halo ring in the card colour so the marker stays legible wherever it lands
   on the gradient -- against the pale dusk blue as well as the hot orange. */
.ss-marker {
	position: absolute;
	top: -3px;
	width: 2.5px;
	height: 12px;
	border-radius: 2px;
	background: var(--ink);
	box-shadow: 0 0 0 1.5px var(--card);
}

/* ---- Sections & labels ----------------------------------------------- */
.section {
	margin-top: 22px;
}

.section-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin: 0 4px 8px;
}

.section-label {
	font-size: 11px;
	font-weight: 700;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--muted);
}

.legend {
	display: flex;
	gap: 12px;
	align-items: center;
}

.legend-item {
	display: flex;
	align-items: center;
	gap: 5px;
	font-size: 11px;
	font-weight: 500;
	color: var(--muted);
}

/* A miniature of the temperature colour scale (cold -> warm), matching the
   gradient the temp/feels lines are now stroked with in chart.js. The two
   themes carry their own tunings, same stop values as TEMP_GRADIENTS there. */
.legend-temp {
	width: 14px;
	height: 3px;
	border-radius: 2px;
	background: linear-gradient(90deg,
		#7b1fa2, #4030a3, #1156b0, #0f8fd6, #12b3a0, #6fbf3b,
		#d8c62a, #f2a53c, #f2712c, #e24b57, #d0338a);
}

body.theme-night .legend-temp {
	background: linear-gradient(90deg,
		#b061d6, #6f63e0, #3f86e6, #35b0ef, #2fd0bb, #8fd85a,
		#ecdd4a, #f6b85f, #f78a4e, #ef6a75, #e85aa6);
}

.legend-feels {
	width: 14px;
	height: 0;
	border-top: 2px dotted var(--muted);
}

.legend-rain {
	width: 8px;
	height: 11px;
	border-radius: 2px;
	background: var(--rain);
}

/* Radar-card legend: mirrors the two lightning encodings in map.js — shape is
   ground (filled dot + glow) vs cloud (hollow ring), colour is recency. The
   swatches use the freshest step (rgb(229,72,77)); the age bar spans the full
   LIGHTNING_STEPS ramp, fresh red -> oldest grey. */
.map-legend {
	gap: 10px;
}

.legend-strike-ground {
	width: 10px;
	height: 10px;
	border-radius: 50%;
	background: rgb(229,72,77);
	box-shadow: 0 0 5px 1px rgb(229,72,77);
}

.legend-strike-cloud {
	width: 10px;
	height: 10px;
	border-radius: 50%;
	border: 2px solid rgb(229,72,77);
	box-sizing: border-box;
}

.legend-strike-age {
	width: 18px;
	height: 4px;
	border-radius: 2px;
	background: linear-gradient(90deg,
		rgb(229,72,77), rgb(242,132,60), rgb(230,178,58),
		rgb(176,168,150), rgb(154,160,166));
}

/* ---- Chart card ------------------------------------------------------ */
.chart-card {
	padding: 14px 12px 12px;
}

.chart-card svg {
	display: block;
	width: 100%;
}

/* ---- Radar / lightning map ------------------------------------------- */
.map-box {
	position: relative;
	height: 300px;
	border-radius: 26px;
	overflow: hidden;
	border: 1px solid var(--border);
	background: #d7dee3;
}

#map {
	width: 100%;
	height: 100%;
	margin: 0;
	padding: 0;
}

/* Radar overlay. Fixed opacity — the animated GIF's own frame cycling already
   reads as a live loop, so no CSS pulse is needed. Blend mode differs by
   appearance so the overlay stays legible over the light vs dark basemap tiles.
   The Leaflet image overlay carries the .radar-overlay class (added in map.js). */
.radar-overlay {
	opacity: .75;
}

body.theme-day .radar-overlay {
	mix-blend-mode: multiply;
}

body.theme-night .radar-overlay {
	mix-blend-mode: screen;
}

.attribution {
	font-size: 10px;
	font-weight: 300;
	color: var(--muted);
	text-align: right;
	margin: 6px 6px 0;
}

.leaflet-control-attribution {
	font-size: 10px;
}

/* Lightning strikes are HTML divIcons; drop Leaflet's default white box so only
   the dot/ring shows. */
.strike {
	background: transparent;
	border: none;
}

/* ---- 7-day forecast -------------------------------------------------- */
/* No top padding: the day cells should sit the same ~8px below the heading as
   the chart card and map do (that gap comes from .section-head's margin). The
   2px sides keep cell borders off the scroll edges; 6px below gives a little
   separation before the graph. */
.forecast {
	display: flex;
	gap: 8px;
	padding: 0 2px 6px;
}

.day-cell {
	flex: 0 0 auto;
	width: 66px;
	display: flex;
	flex-direction: column;
	align-items: center;
	padding: 12px 6px 10px;
	border-radius: 18px;
	background: var(--card);
	border: 1px solid var(--border);
	transition: border-color 0.15s, background 0.15s;
}

/* Every day is a selector for the graph below, so all cells get the click
   affordance. */
.day-cell {
	cursor: pointer;
}

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

/* The day currently driving the graph (today by default). */
.day-cell.active {
	background: var(--soft);
	border-color: var(--accent);
}

.day-label {
	font-size: 13px;
	font-weight: 700;
	color: var(--ink);
	white-space: nowrap;
}

.day-date {
	font-size: 10px;
	font-weight: 300;
	color: var(--muted);
	margin-top: 1px;
}

.day-symbol {
	width: 44px;
	height: 44px;
	object-fit: contain;
	margin: 8px 0 6px;
}

.day-hi {
	font-size: 15px;
	font-weight: 700;
	color: var(--ink);
	font-variant-numeric: tabular-nums;
}

.day-lo {
	font-size: 13px;
	font-weight: 300;
	color: var(--muted);
	font-variant-numeric: tabular-nums;
}

.day-wind {
	width: 20px;
	height: 20px;
	object-fit: contain;
	margin-top: 4px;
}

/* ---- Desktop arrangement --------------------------------------------- */
/* A wider, multi-column layout for large screens (see the desktop mockup).
   Everything above is the mobile single-column base; this only reflows it. */
@media (min-width: 900px) {
	.app {
		max-width: 1360px;
		padding: 20px 40px 48px;
	}

	.place-name {
		font-size: 28px;
	}

	/* Action buttons grow to show their text label. */
	.btn-label {
		display: inline;
	}

	.icon-btn {
		width: auto;
		height: 44px;
		padding: 0 18px;
		gap: 8px;
		border-radius: 14px;
		font-family: inherit;
		font-size: 15px;
		font-weight: 600;
	}

	/* The whole page is one full-width stack (current card -> forecast strip ->
	   graph -> map); the forecast strip drives the graph slot below it. The
	   wide current-conditions card is centered at a comfortable width so its
	   hero doesn't stretch thin across the full column. */
	.current-card {
		max-width: 640px;
		margin-left: auto;
		margin-right: auto;
	}

	/* Roomier map on the wide layout. */
	.map-box {
		height: 460px;
	}

	/* 7-day fills the width evenly instead of scrolling. */
	.forecast {
		display: grid;
		grid-template-columns: repeat(7, 1fr);
		gap: 12px;
		padding: 0 2px 6px;
	}

	.day-cell {
		width: auto;
	}
}

/* Pull-to-refresh indicator. A standalone/pinned PWA has no browser chrome,
   so iOS Safari's native pull-to-refresh is unavailable; refresh.js
   reimplements the gesture and drives this spinner. It rests just off the top
   edge and is pulled into view by the drag (pointer-events: none so it never
   swallows touches). */
.ptr {
	position: fixed;
	top: -48px;
	left: 50%;
	transform: translateX(-50%);
	z-index: 1200;
	width: 34px;
	height: 34px;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	background: var(--card);
	box-shadow: 0 2px 10px rgba(0, 0, 0, .18);
	opacity: 0;
	pointer-events: none;
}

/* Applied only for the snap-back after release so the finger-tracking drag
   itself stays 1:1 with no lag. */
.ptr-return {
	transition: transform .25s ease, opacity .25s ease;
}

.ptr-spinner {
	width: 18px;
	height: 18px;
	border-radius: 50%;
	border: 2px solid var(--soft);
	border-top-color: var(--accent);
}

/* Pulled past the trigger threshold: flip the spinner to signal that
   releasing now will refresh. */
.ptr-armed .ptr-spinner {
	transform: rotate(180deg);
	transition: transform .15s ease;
}

/* Released while armed: spin while the reload is in flight. */
.ptr-loading {
	transition: transform .2s ease;
}

.ptr-loading .ptr-spinner {
	animation: ptrSpin .7s linear infinite;
}

@keyframes ptrSpin {
	to { transform: rotate(360deg); }
}
