/* Goald admin panel — hand-rolled design tokens matching the Goald
   mobile app's design language: magenta/pink brand colour, dark-violet
   chrome, neon-green accent, Bai Jamjuree throughout. The admin stays
   a desktop information-dense tool (light-surface tables and
   dashboard cards, dark-violet sidebar chrome) — this is a re-palette
   and typography pass, not a mobile-pattern rebuild. No CSS framework
   dependency — keeps the wasm bundle and build graph small. Palette
   reference: docs/superpowers/plans/2026-07-10-web-app-reskin.md. */

/* Bai Jamjuree, self-hosted (SIL OFL 1.1 — /OFL.txt). The font files
   sit at the dist root: see index.html for why they must not live
   under a subdirectory. Weights 400/500/600/700 — the family tops out
   at 700; the mobile app's heavier strokes are synthesised. */

@font-face {
	font-family: "Bai Jamjuree";
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("/bai-jamjuree-latin-400.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
		U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: "Bai Jamjuree";
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("/bai-jamjuree-latin-ext-400.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
		U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: "Bai Jamjuree";
	font-style: normal;
	font-weight: 500;
	font-display: swap;
	src: url("/bai-jamjuree-latin-500.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
		U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: "Bai Jamjuree";
	font-style: normal;
	font-weight: 500;
	font-display: swap;
	src: url("/bai-jamjuree-latin-ext-500.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
		U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: "Bai Jamjuree";
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url("/bai-jamjuree-latin-600.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
		U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: "Bai Jamjuree";
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url("/bai-jamjuree-latin-ext-600.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
		U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: "Bai Jamjuree";
	font-style: normal;
	font-weight: 700;
	font-display: swap;
	src: url("/bai-jamjuree-latin-700.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
		U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: "Bai Jamjuree";
	font-style: normal;
	font-weight: 700;
	font-display: swap;
	src: url("/bai-jamjuree-latin-ext-700.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
		U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* The palette — the UI Refresh V2 tokens, taken from "Goald screens 1"
   (which supersedes the earlier developer handoff where the two
   disagree; the handoff's #EC008C pink and its 180deg four-stop
   gradient are both superseded). The admin stays a desktop
   information-dense tool: this is a re-palette, not a mobile-pattern
   rebuild, so only the colour values move — every shape, spacing and
   layout token below is untouched.

   Values were read off the design's own swatches and verified by
   sampling the rendered pixels, so they are the design's numbers
   rather than an eyeballed approximation. */

:root {
	--color-bg:             #f8f8f8; /* page canvas */
	--color-bg-raised:      #ffffff; /* card white — card / table surfaces */
	--color-bg-sunken:      #f4f1f6; /* violet-tinted, for fills and idle badges */
	--color-border:         #e7e2ea; /* dividerGrey, violet-tinted */
	--color-text:           #23083a; /* ink on white */
	--color-text-muted:     #6b6280; /* meta text, placeholders */
	--color-brand:          #ec0a8c; /* pink / CTA */
	--color-cta:            #ec0a8c; /* pink / CTA — one pink now, not two */
	--color-violet:         #1a0340; /* nav / bars — sidebar chrome */
	--color-violet-soft:    #20034b; /* indigo */
	--color-nav-idle:       #6a5a8a; /* idle nav item on the dark chrome */
	--color-btn2-text:      #a0016b; /* magenta — secondary button text */
	--color-green:          #00c46a; /* impact green — success / verified only */
	--color-yellow:         #e8b33c; /* prize gold */
	--color-danger:         #ed4c5c; /* errorRed — unchanged, not a brand colour */
	--color-danger-text:    #ffffff;
	--color-shadow:         rgb(26 16 48 / 8%); /* card shadow on light */

	/* The Goald Gradient — the only purple. One gradient everywhere:
	   same angle, same stops. Do not re-declare it per surface. */
	--gradient-auth:        linear-gradient(100deg, #a0016b 0%, #5b0356 45%, #20034b 100%);

	/* Aliases kept for the shared class vocabulary. */
	--color-accent:         var(--color-brand);
	--color-accent-text:    #ffffff;
	--color-success:        var(--color-green);
	--color-warning:        var(--color-yellow);

	--space-1: 0.25rem;
	--space-2: 0.5rem;
	--space-3: 0.75rem;
	--space-4: 1rem;
	--space-6: 1.5rem;
	--space-8: 2rem;

	/* The mobile shape grammar: 5px chips, 10px buttons / inputs /
	   cards. */
	--radius-sm: 5px;
	--radius-md: 10px;

	--shadow-card: 0 2px 3px var(--color-shadow);

	--font-sans:
		"Bai Jamjuree", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	--font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* The dark override is secondary — the brand reference (and therefore
   the default look) is light. Violet-tinted darks keep the brand
   feel; the sidebar stays dark violet in both schemes since it is
   fixed chrome, not a themed surface. */
@media (prefers-color-scheme: dark) {
	:root {
		--color-bg:         #170b1d;
		--color-bg-raised:  #21112b;
		--color-bg-sunken:  #100716;
		--color-border:     #3a2547;
		--color-text:       #f3f3f3;
		--color-text-muted: #b6a9bf;
		--color-shadow:     rgb(0 0 0 / 40%);
	}
}

* {
	box-sizing: border-box;
}

html,
body {
	margin: 0;
	padding: 0;
	height: 100%;
	background: var(--color-bg);
	color: var(--color-text);
	font-family: var(--font-sans);
	font-size: 15px;
	line-height: 1.5;
}

a {
	color: var(--color-brand);
	font-weight: 600;
}

button,
input,
select,
textarea {
	font: inherit;
	color: inherit;
}

/* App shell: dark-violet sidebar chrome + light content column. */

.app-shell {
	display: grid;
	grid-template-columns: 220px 1fr;
	min-height: 100vh;
}

.app-sidebar {
	background: var(--color-violet);
	border-right: none;
	padding: var(--space-4);
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
}

.app-sidebar__brand {
	font-weight: 700;
	font-size: 1.2rem;
	color: #ffffff;
	margin-bottom: var(--space-4);
}

.app-sidebar a {
	display: block;
	padding: var(--space-2) var(--space-3);
	border-radius: var(--radius-sm);
	color: rgb(255 255 255 / 70%);
	font-weight: 600;
	text-decoration: none;
}

.app-sidebar a:hover,
.app-sidebar a.active,
.app-sidebar a[aria-current] {
	background: rgb(255 255 255 / 10%);
	color: var(--color-cta);
}

.app-sidebar button {
	margin-top: var(--space-4);
}

/* The signed-in identity, pinned above Sign out at the sidebar foot. */
.app-sidebar__user {
	margin-top: auto;
	color: rgb(255 255 255 / 70%);
	font-size: 0.8rem;
	word-break: break-all;
}

.app-sidebar .btn {
	background: rgb(255 255 255 / 10%);
	color: #ffffff;
}

.app-sidebar .btn:hover {
	background: rgb(255 255 255 / 18%);
}

.app-main {
	padding: var(--space-6);
	overflow-x: auto;
}

.page-title {
	font-size: 1.4rem;
	font-weight: 700;
	color: var(--color-violet-soft);
	margin: 0 0 var(--space-4);
}

@media (prefers-color-scheme: dark) {
	.page-title {
		color: var(--color-text);
	}
}

/* Group headings between dashboard sections (Growth / Engagement /
   Fundraising). */
.section-title {
	font-size: 1.1rem;
	font-weight: 600;
	color: var(--color-violet-soft);
	margin: var(--space-6) 0 var(--space-4);
}

@media (prefers-color-scheme: dark) {
	.section-title {
		color: var(--color-text);
	}
}

.card {
	background: var(--color-bg-raised);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-md);
	box-shadow: var(--shadow-card);
	padding: var(--space-4);
}

.card + .card {
	margin-top: var(--space-4);
}

.stat-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
	gap: var(--space-4);
	margin-bottom: var(--space-6);
}

.stat-tile {
	background: var(--color-bg-raised);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-md);
	box-shadow: var(--shadow-card);
	padding: var(--space-4);
	transition:
		transform 150ms ease,
		box-shadow 150ms ease;
}

.stat-tile:hover {
	transform: translateY(-2px);
	box-shadow: 0 6px 14px var(--color-shadow);
}

.stat-tile__label {
	color: var(--color-text-muted);
	font-size: 0.8rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.03em;
}

.stat-tile__value {
	font-size: 1.6rem;
	font-weight: 700;
	color: var(--color-brand);
	margin-top: var(--space-1);
}

table {
	width: 100%;
	border-collapse: collapse;
	font-size: 0.9rem;
}

th,
td {
	text-align: left;
	padding: var(--space-2) var(--space-3);
	border-bottom: 1px solid var(--color-border);
	white-space: nowrap;
}

th {
	color: var(--color-text-muted);
	font-weight: 600;
	font-size: 0.75rem;
	text-transform: uppercase;
	letter-spacing: 0.03em;
}

.table-scroll {
	overflow-x: auto;
	background: var(--color-bg-raised);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-md);
	box-shadow: var(--shadow-card);
}

/* Buttons, inputs — the mobile shapes: 10px radius, filled, borderless. */

.btn {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	background: var(--color-bg-sunken);
	border: none;
	border-radius: var(--radius-md);
	color: var(--color-btn2-text);
	font-weight: 700;
	padding: var(--space-2) var(--space-3);
	cursor: pointer;
}

@media (prefers-color-scheme: dark) {
	.btn {
		color: var(--color-text);
	}
}

.btn:hover {
	filter: brightness(0.96);
}

.btn:disabled {
	opacity: 0.5;
	cursor: not-allowed;
}

.btn-primary {
	background: var(--color-cta);
	color: #ffffff;
}

.btn-primary:hover {
	filter: brightness(1.05);
}

.btn-danger {
	background: var(--color-danger);
	color: var(--color-danger-text);
}

.input {
	background: var(--color-bg-raised);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-md);
	color: var(--color-text);
	padding: var(--space-2) var(--space-3);
}

.input:focus {
	outline: 2px solid var(--color-brand);
	outline-offset: -1px;
}

/* Badges — the mobile grammar: guppieGreen fill with darkViolet
   content for success, brand-consistent fills for the other tones. */

.badge {
	display: inline-block;
	padding: 0.15rem 0.6rem;
	border-radius: 999px;
	font-size: 0.75rem;
	font-weight: 700;
	background: var(--color-bg-sunken);
	color: var(--color-violet-soft);
}

@media (prefers-color-scheme: dark) {
	.badge {
		color: var(--color-text);
	}
}

.badge-success {
	background: var(--color-green);
	color: var(--color-violet);
}

/* Dark-violet text like .badge-success — white on mustard is ~1.9:1
   contrast, unreadable. */
.badge-warning {
	background: var(--color-yellow);
	color: var(--color-violet);
}

.badge-danger {
	background: var(--color-danger);
	color: var(--color-danger-text);
}

/* Flash notices (`components/flash.rs`) — mutation feedback shown as
   a fixed overlay: success auto-dismisses, errors stay until
   dismissed. */

.flash {
	position: fixed;
	top: var(--space-4);
	right: var(--space-4);
	z-index: 100;
	display: flex;
	align-items: center;
	gap: var(--space-3);
	max-width: 420px;
	padding: var(--space-3) var(--space-4);
	border-radius: var(--radius-md);
	box-shadow: 0 6px 14px var(--color-shadow);
	font-weight: 600;
}

.flash-success {
	background: var(--color-green);
	color: var(--color-violet);
}

.flash-error {
	background: var(--color-danger);
	color: var(--color-danger-text);
}

.flash-dismiss {
	background: none;
	border: none;
	cursor: pointer;
	color: inherit;
	font-size: 1.1rem;
	font-weight: 700;
	line-height: 1;
	padding: 0;
}

.error-banner {
	background: color-mix(in srgb, var(--color-danger) 12%, var(--color-bg-raised));
	border: 1px solid var(--color-danger);
	color: var(--color-text);
	border-radius: var(--radius-md);
	padding: var(--space-3);
	margin-bottom: var(--space-4);
}

/* Login shell — the one full-bleed screen that gets the mobile app's
   auth look in full: purple→pink gradient, white heading, floating
   white inputs, uppercase pink CTA. The `.card` the login form also
   carries is neutralised here rather than restructuring the markup. */

.login-shell {
	min-height: 100vh;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--space-4);
	background: var(--gradient-auth);
}

.login-shell .card {
	background: transparent;
	border: none;
	box-shadow: none;
}

.login-card {
	width: 320px;
	max-width: 100%;
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
}

.login-card .page-title {
	color: #ffffff;
	text-align: center;
	font-size: 1.8rem;
	margin-bottom: var(--space-4);
}

.login-card .field label {
	color: rgb(255 255 255 / 85%);
}

.login-card .input {
	background: #ffffff;
	color: var(--color-text);
	border: none;
	box-shadow: 0 4px 12px rgb(0 0 0 / 20%);
}

.login-card .input::placeholder {
	color: #808080;
}

.login-card .btn-primary {
	width: 100%;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	justify-content: center;
	margin-top: var(--space-2);
}

.field {
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
}

.field label {
	font-size: 0.8rem;
	font-weight: 600;
	color: var(--color-text-muted);
}

.toolbar {
	display: flex;
	gap: var(--space-2);
	align-items: center;
	margin-bottom: var(--space-4);
	flex-wrap: wrap;
}

.pagination {
	display: flex;
	gap: var(--space-2);
	align-items: center;
	margin-top: var(--space-4);
}

.muted {
	color: var(--color-text-muted);
}

/* The shared "no results" table row (`components/empty_row.rs`). */
.empty-row {
	text-align: center;
	padding: var(--space-6) var(--space-3);
	white-space: normal;
}

/* Dashboard charts — hand-rolled inline SVG (`components/charts.rs`),
   no charting dependency. Brand colours only; the hover/focus states
   below drive the hand-authored interactivity (guide line, point /
   bar highlight, tooltip) in tandem with the Leptos signals that
   toggle these classes. */

.chart {
	width: 100%;
	height: auto;
	overflow: visible;
}

.chart-caption {
	color: var(--color-text-muted);
	font-size: 0.8rem;
	margin-top: var(--space-2);
}

.chart-gridline {
	stroke: var(--color-border);
	stroke-width: 1;
}

.chart-axis-label {
	fill: var(--color-text-muted);
	font-size: 9px;
	font-family: var(--font-sans);
}

.chart-area-fill {
	fill: var(--color-cta);
	fill-opacity: 16%;
}

.chart-line {
	stroke: var(--color-brand);
	stroke-width: 2.5;
	stroke-linejoin: round;
	stroke-linecap: round;
}

.chart-point {
	fill: var(--color-bg-raised);
	stroke: var(--color-brand);
	stroke-width: 2;
	transition: r 120ms ease;
}

.chart-point--active {
	fill: var(--color-cta);
	stroke: var(--color-violet);
}

.chart-hit-target {
	fill: transparent;
	cursor: pointer;
}

.chart-guide {
	stroke: var(--color-nav-idle);
	stroke-width: 1;
	stroke-dasharray: 4 3;
}

.chart-tooltip rect {
	fill: var(--color-violet);
	filter: drop-shadow(0 2px 4px var(--color-shadow));
}

.chart-tooltip text {
	fill: #ffffff;
	font-size: 11px;
	font-weight: 600;
	font-family: var(--font-sans);
}

.chart-bar-row {
	cursor: pointer;
}

.chart-bar-hit {
	fill: transparent;
}

.chart-bar-label {
	fill: var(--color-text);
	font-size: 11px;
	font-family: var(--font-sans);
}

.chart-bar {
	fill: var(--color-brand);
	transition:
		fill 120ms ease,
		filter 120ms ease;
}

.chart-bar--active {
	fill: var(--color-cta);
	filter: drop-shadow(0 0 4px var(--color-shadow));
}

.chart-bar-value {
	fill: var(--color-text-muted);
	font-size: 10.5px;
	font-weight: 600;
	font-family: var(--font-sans);
}

/* User-location map (`pages/map.rs`) — the same hand-rolled inline
   SVG approach as the dashboard charts, with a zoom/pan stage: the
   vendored country outlines sit inside a scaled <g>, while the
   tooltip reuses the .chart-tooltip vocabulary outside it. */

.map-toolbar {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: var(--space-2);
	margin-bottom: var(--space-3);
	flex-wrap: wrap;
}

.map-toolbar__group {
	display: flex;
	gap: var(--space-1);
}

.map-toggle--active {
	background: var(--color-brand);
	border-color: var(--color-brand);
	color: var(--color-accent-text);
}

.map-toggle--active:hover {
	background: var(--color-cta);
}

.map-zoom-btn {
	min-width: 2.25rem;
	font-weight: 700;
}

.map-stage {
	width: 100%;
	height: auto;
	background: var(--color-bg-sunken);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-md);
	cursor: grab;
	touch-action: none;
	user-select: none;
}

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

.map-country {
	fill: var(--color-bg-raised);
	stroke: var(--color-border);
	stroke-width: 0.75;
}

.map-cluster {
	fill: var(--color-brand);
	fill-opacity: 55%;
	stroke: var(--color-cta);
	stroke-width: 1.5;
	cursor: pointer;
	transition: fill-opacity 120ms ease;
}

.map-cluster:hover {
	fill-opacity: 80%;
}

.map-region {
	fill: var(--color-nav-idle);
	fill-opacity: 18%;
	stroke: var(--color-nav-idle);
	stroke-width: 1.5;
	stroke-dasharray: 3 2;
	cursor: pointer;
	transition: fill-opacity 120ms ease;
}

.map-region:hover {
	fill-opacity: 40%;
}

.map-legend {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	color: var(--color-text-muted);
	font-size: 0.8rem;
	margin-top: var(--space-2);
}

.map-legend__scale {
	width: 68px;
	height: 12px;
	flex: none;
}

.map-legend__swatch {
	stroke: var(--color-border);
	stroke-width: 0.5;
}

/* Media — compact table thumbnails (content listings) and the
   moderation review panel's inline hls.js player
   (`components/video_player.rs`). */

.thumb {
	width: 44px;
	height: 44px;
	object-fit: cover;
	border-radius: var(--radius-sm);
	background: var(--color-bg-sunken);
	display: block;
}

.thumb-placeholder {
	width: 44px;
	height: 44px;
	border-radius: var(--radius-sm);
	background: var(--color-bg-sunken);
	border: 1px dashed var(--color-border);
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--color-text-muted);
	font-size: 0.65rem;
	text-align: center;
}

.video-frame {
	display: block;
	width: 100%;
	max-width: 360px;
	max-height: 60vh;
	/* Overridden inline (`style=("aspect-ratio", …)`) once the media's
	   real width/height are known; this is the pre-metadata / unknown-
	   dimensions fallback — portrait 9:16 is the common case. */
	aspect-ratio: 9 / 16;
	margin: 0 auto var(--space-2);
	background: #000;
	border-radius: var(--radius-md);
	object-fit: contain;
}

.video-placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	max-width: 360px;
	min-height: 180px;
	margin: 0 auto var(--space-2);
	background: var(--color-bg-sunken);
	border: 1px dashed var(--color-border);
	border-radius: var(--radius-md);
}
