<script lang="ts">
	import { onMount, onDestroy } from "svelte";
	import { fly } from "svelte/transition";
	import { bibleBooks } from "$lib/types/bible";

	let {
		isLoggedIn = false,
		anonymousId = "",
		localDate = "",
	}: {
		isLoggedIn?: boolean;
		anonymousId?: string;
		localDate?: string;
	} = $props();

	// ── Status (logged-in state) ───────────────────────────────────────────
	type Status = {
		canSubmit: boolean;
		cooldownEndsAt: number | null;
		lastSubmission: { scheduledDate: string; reference: string } | null;
		upcoming: { scheduledDate: string; reference: string }[];
	};
	let status = $state<Status | null>(null);
	let statusError = $state<string | null>(null);

	// ── Bible structure (Book → chapters → verse counts) ──────────────────
	type Structure = { bookId: string; chapters: number[] }[];
	let structure = $state<Structure | null>(null);

	// ── Selector state ─────────────────────────────────────────────────────
	let selectedBookId = $state<string>("");
	let selectedChapter = $state<number>(0);
	let selectedVerse = $state<number>(0);

	// ── Preview state ──────────────────────────────────────────────────────
	type Preview = {
		windowVerses: string[];
		reference: string;
		bookId: string;
		selectedVerse: number;
	};
	let preview = $state<Preview | null>(null);
	let previewLoading = $state(false);

	// ── Submission state ───────────────────────────────────────────────────
	let submitting = $state(false);
	let submitError = $state<string | null>(null);
	let submitResult = $state<{ scheduledDate: string; reference: string } | null>(
		null,
	);

	// ── UI state ───────────────────────────────────────────────────────────
	let expanded = $state(false);
	let countdownText = $state("");
	let countdownId: number | null = null;

	// Book list grouped by Testament for the <select> optgroups.
	const oldBooks = $derived(bibleBooks.filter((b) => b.testament === "old"));
	const newBooks = $derived(bibleBooks.filter((b) => b.testament === "new"));

	// Chapter list for the currently selected book (1..N).
	const chapterCount = $derived(
		structure && selectedBookId
			? structure.find((b) => b.bookId === selectedBookId)?.chapters.length ??
				0
			: 0,
	);
	// Verse count for the currently selected chapter.
	const verseCount = $derived(
		structure && selectedBookId && selectedChapter
			? structure.find((b) => b.bookId === selectedBookId)?.chapters[
					selectedChapter - 1
				] ?? 0
			: 0,
	);

	// Whether the user is currently on cooldown (only meaningful when logged in).
	const onCooldown = $derived(
		!!status && !status.canSubmit && status.cooldownEndsAt !== null,
	);

	// Debounce handle for the live preview fetch.
	let previewTimer: ReturnType<typeof setTimeout> | null = null;

	function trackEvent(name: string) {
		try {
			(window as any).rybbit?.event?.(name);
		} catch {
			/* noop */
		}
	}

	function fmtDateLong(dateStr: string): string {
		// dateStr is YYYY-MM-DD; format as "August 24, 2026" in UTC to avoid drift.
		const d = new Date(dateStr + "T00:00:00Z");
		return d.toLocaleDateString("en-US", {
			weekday: "long",
			year: "numeric",
			month: "long",
			day: "numeric",
			timeZone: "UTC",
		});
	}

	function fmtDateVague(dateStr: string): string {
		// dateStr is YYYY-MM-DD. Return a deliberately vague timeframe instead of
		// revealing the exact scheduled date.
		const scheduled = new Date(dateStr + "T00:00:00Z");
		const now = new Date();
		const today = new Date(
			Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()),
		);
		const diffDays = Math.round(
			(scheduled.getTime() - today.getTime()) / (1000 * 60 * 60 * 24),
		);
		if (diffDays <= 14) return "a few days from now";
		if (diffDays <= 60) return "a few weeks from now";
		return "within the next few months";
	}

	async function loadStatus() {
		if (!isLoggedIn || !localDate) return;
		try {
			const res = await fetch(
				`/api/submit-verse/status?localDate=${encodeURIComponent(localDate)}`,
			);
			if (res.status === 401) {
				status = null;
				return;
			}
			if (!res.ok) {
				statusError = "Couldn't load submission status.";
				return;
			}
			status = await res.json();
		} catch {
			statusError = "Couldn't load submission status.";
		}
	}

	async function loadStructure() {
		if (structure) return;
		try {
			const res = await fetch("/api/bible/structure");
			if (!res.ok) return;
			const data = await res.json();
			structure = data;
			// Default selection: first book, chapter 1, verse 1.
			if (data.length > 0 && !selectedBookId) {
				selectedBookId = data[0].bookId;
				selectedChapter = 1;
				selectedVerse = 1;
			}
		} catch {
			/* noop */
		}
	}

	function fetchPreview() {
		if (previewTimer) clearTimeout(previewTimer);
		previewTimer = setTimeout(async () => {
			if (!selectedBookId || !selectedChapter || !selectedVerse) {
				preview = null;
				return;
			}
			previewLoading = true;
			try {
				const res = await fetch(
					`/api/verse-window?bookId=${encodeURIComponent(
						selectedBookId,
					)}&chapter=${selectedChapter}&verse=${selectedVerse}`,
				);
				if (res.ok) {
					preview = await res.json();
				}
			} catch {
				/* noop */
			} finally {
				previewLoading = false;
			}
		}, 250);
	}

	function onBookChange() {
		selectedChapter = 1;
		selectedVerse = 1;
		submitError = null;
		fetchPreview();
	}

	function onChapterChange() {
		selectedVerse = 1;
		submitError = null;
		fetchPreview();
	}

	function onVerseChange() {
		submitError = null;
		fetchPreview();
	}

	async function handleSubmit() {
		if (!isLoggedIn) return;
		submitting = true;
		submitError = null;
		try {
			const res = await fetch("/api/submit-verse", {
				method: "POST",
				headers: { "Content-Type": "application/json" },
				body: JSON.stringify({
					bookId: selectedBookId,
					chapter: selectedChapter,
					verse: selectedVerse,
					localDate,
				}),
			});
			const data = await res.json();
			if (!res.ok) {
				if (res.status === 429 && data?.cooldownEndsAt) {
					// Refresh status so the cooldown UI kicks in.
					await loadStatus();
					submitError = "You're on cooldown — try again later.";
				} else {
					submitError = data?.error ?? "Submission failed.";
				}
				return;
			}
			submitResult = {
				scheduledDate: data.scheduledDate,
				reference: data.reference,
			};
			trackEvent("Submit a verse");
			// Refresh status so the cooldown reflects the new submission.
			await loadStatus();
		} catch {
			submitError = "Network error — please try again.";
		} finally {
			submitting = false;
		}
	}

	function updateCountdown() {
		if (!status?.cooldownEndsAt) {
			countdownText = "";
			return;
		}
		const diff = status.cooldownEndsAt - Date.now();
		if (diff <= 0) {
			countdownText = "";
			// Cooldown elapsed — refresh status once.
			loadStatus();
			if (countdownId) {
				clearInterval(countdownId);
				countdownId = null;
			}
			return;
		}
		const days = Math.floor(diff / (1000 * 60 * 60 * 24));
		const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
		const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
		const seconds = Math.floor((diff % (1000 * 60)) / 1000);
		countdownText =
			(days > 0 ? `${days}d ` : "") +
			`${hours.toString().padStart(2, "0")}h ${minutes
				.toString()
				.padStart(2, "0")}m ${seconds.toString().padStart(2, "0")}s`;
	}

	onMount(() => {
		if (isLoggedIn) {
			loadStatus();
			loadStructure();
		}
	});

	// Start/stop the countdown timer as cooldown state changes.
	$effect(() => {
		if (onCooldown && status?.cooldownEndsAt && !countdownId) {
			updateCountdown();
			countdownId = window.setInterval(updateCountdown, 1000);
		} else if (!onCooldown && countdownId) {
			clearInterval(countdownId);
			countdownId = null;
			countdownText = "";
		}
	});

	// (Re)load status + structure when the user logs in.
	$effect(() => {
		if (isLoggedIn) {
			loadStatus();
			loadStructure();
		} else {
			status = null;
			structure = null;
			expanded = false;
			submitResult = null;
		}
	});

	onDestroy(() => {
		if (countdownId) clearInterval(countdownId);
		if (previewTimer) clearTimeout(previewTimer);
	});
</script>

<div class="signin-prompt submit-verse-wrap">
	{#if submitResult}
		<!-- ── Confirmation state (replaces the panel after success) ──────── -->
		<div class="confirm-card" in:fly={{ y: -8, duration: 220 }}>
			<p class="confirm-title">
				✅ Your verse is scheduled for
				<strong>{fmtDateVague(submitResult.scheduledDate)}</strong>
			</p>
			<p class="confirm-ref">{submitResult.reference}</p>
			<button
				type="button"
				class="submit-another-btn"
				onclick={() => {
					submitResult = null;
					expanded = false;
				}}
			>
				Done
			</button>
		</div>
	{:else if !isLoggedIn}
		<!-- ── State 1: logged out — sign-in dropdown ─────────────────────── -->
		<button
			type="button"
			class="progress-btn w-full"
			aria-expanded={expanded}
			onclick={() => (expanded = !expanded)}
			data-umami-event="Submit a verse (logged out)"
		>
			<span>✨ Submit a verse</span>
			<svg
				class="progress-chev"
				class:open={expanded}
				viewBox="0 0 24 24"
				fill="none"
				stroke="currentColor"
				stroke-width="2.5"
				stroke-linecap="round"
				stroke-linejoin="round"
				aria-hidden="true"
			>
				<path d="m6 9 6 6 6-6" />
			</svg>
		</button>
		{#if expanded}
			<p class="signin-text text-gray-800 dark:text-gray-300">
				Sign in to submit a verse for a future day
			</p>
			<form method="POST" action="/auth/apple" class="w-full">
				<input type="hidden" name="anonymousId" value={anonymousId} />
				<button
					type="submit"
					class="apple-signin-btn"
					data-umami-event="Sign in with Apple"
				>
					<svg class="apple-icon" viewBox="0 0 24 24" fill="currentColor">
						<path
							d="M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.48-3.24 0-1.44.62-2.2.44-3.06-.4C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z"
						/>
					</svg>
					Sign in with Apple
				</button>
			</form>
			<form method="POST" action="/auth/google" class="w-full">
				<input type="hidden" name="anonymousId" value={anonymousId} />
				<button
					type="submit"
					class="google-signin-btn"
					data-umami-event="Sign in with Google"
				>
					<svg
						class="google-icon"
						viewBox="0 0 24 24"
						xmlns="http://www.w3.org/2000/svg"
					>
						<path
							fill="#4285F4"
							d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
						/>
						<path
							fill="#34A853"
							d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
						/>
						<path
							fill="#FBBC05"
							d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l3.66-2.84z"
						/>
						<path
							fill="#EA4335"
							d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
						/>
					</svg>
					Sign in with Google
				</button>
			</form>
		{/if}
	{:else if onCooldown}
		<!-- ── State 2: logged in, cooldown active — disabled + countdown ─── -->
		<button
			type="button"
			class="progress-btn w-full progress-btn-disabled"
			disabled
			aria-disabled="true"
		>
			<span>✨ Submit a verse</span>
			<span class="lock-icon" aria-hidden="true">⏳</span>
		</button>
		{#if countdownText}
			<p class="countdown-text">Next submission in {countdownText}</p>
		{/if}
	{:else}
		<!-- ── State 3: logged in, can submit — selector + preview ────────── -->
		<button
			type="button"
			class="progress-btn w-full"
			aria-expanded={expanded}
			onclick={() => (expanded = !expanded)}
			data-umami-event="Submit a verse (logged in)"
		>
			<span>✨ Submit a verse</span>
			<svg
				class="progress-chev"
				class:open={expanded}
				viewBox="0 0 24 24"
				fill="none"
				stroke="currentColor"
				stroke-width="2.5"
				stroke-linecap="round"
				stroke-linejoin="round"
				aria-hidden="true"
			>
				<path d="m6 9 6 6 6-6" />
			</svg>
		</button>
		{#if expanded}
			<div class="submit-panel" in:fly={{ y: -8, duration: 220 }}>
				{#if statusError}
					<p class="panel-error">{statusError}</p>
				{/if}

				{#if !structure}
					<p class="panel-hint">Loading Bible structure…</p>
				{:else}
					<div class="select-row">
						<label class="select-label">
							<span class="select-cap">Book</span>
							<select
								class="cascading-select"
								value={selectedBookId}
								onchange={(e) => {
									selectedBookId = e.currentTarget.value;
									onBookChange();
								}}
							>
								<optgroup label="Old Testament">
									{#each oldBooks as book (book.id)}
										<option value={book.id}>{book.name}</option>
									{/each}
								</optgroup>
								<optgroup label="New Testament">
									{#each newBooks as book (book.id)}
										<option value={book.id}>{book.name}</option>
									{/each}
								</optgroup>
							</select>
						</label>

						<label class="select-label">
							<span class="select-cap">Chapter</span>
							<select
								class="cascading-select"
								value={selectedChapter}
								onchange={(e) => {
									selectedChapter = Number(e.currentTarget.value);
									onChapterChange();
								}}
							>
								{#if chapterCount === 0}
									<option value={0}>—</option>
								{:else}
									{#each Array(chapterCount) as _, i (i)}
										<option value={i + 1}>{i + 1}</option>
									{/each}
								{/if}
							</select>
						</label>

						<label class="select-label">
							<span class="select-cap">Verse</span>
							<select
								class="cascading-select"
								value={selectedVerse}
								onchange={(e) => {
									selectedVerse = Number(e.currentTarget.value);
									onVerseChange();
								}}
							>
								{#if verseCount === 0}
									<option value={0}>—</option>
								{:else}
									{#each Array(verseCount) as _, i (i)}
										<option value={i + 1}>{i + 1}</option>
									{/each}
								{/if}
							</select>
						</label>
					</div>

					<!-- Live 3-verse preview -->
					<div class="preview-card">
						{#if previewLoading}
							<p class="preview-hint">Loading preview…</p>
						{:else if preview}
							<p class="preview-ref">{preview.reference}</p>
							<div class="preview-verses">
								{#each preview.windowVerses as verseText, i (i)}
									<p class="preview-verse">{verseText}</p>
								{/each}
							</div>
						{:else}
							<p class="preview-hint">Select a verse to preview.</p>
						{/if}
					</div>

					{#if submitError}
						<p class="panel-error">{submitError}</p>
					{/if}

					<button
						type="button"
						class="submit-btn"
						disabled={submitting ||
							!selectedBookId ||
							!selectedChapter ||
							!selectedVerse ||
							!preview}
						onclick={handleSubmit}
					>
						{submitting ? "Scheduling…" : "Submit verse"}
					</button>
					{#if status?.upcoming && status.upcoming.length > 0}
						<p class="upcoming-text">
							Your upcoming verse{status.upcoming.length > 1
								? "s"
								: ""}:
							{#each status.upcoming as u, i (i)}
								{#if i > 0}<span class="upcoming-sep">·</span>{/if}
								<span class="upcoming-item"
									>{u.reference} ({fmtDateVague(u.scheduledDate)})</span
								>
							{/each}
						</p>
					{/if}
				{/if}
			</div>
		{/if}
	{/if}
</div>

<style>
	.submit-verse-wrap {
		gap: 0.75rem;
	}

	/* Reuse WinScreen's neobrutalist .progress-btn base (scoped here too). */
	:global(.submit-verse-wrap .progress-btn) {
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 0.5rem;
		padding: 0.85rem 1.25rem;
		background: #fff;
		color: #111;
		border: 2px solid #000;
		border-radius: 0.75rem;
		font-size: 1rem;
		font-weight: 700;
		text-decoration: none;
		cursor: pointer;
		box-shadow: 6px 6px 0 0 #000;
		transition:
			transform 80ms ease,
			box-shadow 80ms ease;
	}
	:global(.submit-verse-wrap .progress-btn:hover) {
		transform: translate(-2px, -2px);
		box-shadow: 8px 8px 0 0 #000;
	}
	:global(.submit-verse-wrap .progress-btn:active) {
		transform: translate(2px, 2px);
		box-shadow: 2px 2px 0 0 #000;
	}
	:global(.submit-verse-wrap .progress-chev) {
		width: 1.25rem;
		height: 1.25rem;
		transition: transform 200ms ease;
	}
	:global(.submit-verse-wrap .progress-chev.open) {
		transform: rotate(180deg);
	}
	@media (prefers-color-scheme: dark) {
		:global(.submit-verse-wrap .progress-btn) {
			background: #111827;
			color: #f9fafb;
			border-color: #fff;
			box-shadow: 6px 6px 0 0 #fff;
		}
		:global(.submit-verse-wrap .progress-btn:hover) {
			box-shadow: 8px 8px 0 0 #fff;
		}
		:global(.submit-verse-wrap .progress-btn:active) {
			box-shadow: 2px 2px 0 0 #fff;
		}
	}

	/* Disabled (cooldown) variant. */
	:global(.submit-verse-wrap .progress-btn-disabled) {
		opacity: 0.55;
		cursor: not-allowed;
		box-shadow: 4px 4px 0 0 #000;
	}
	:global(.submit-verse-wrap .progress-btn-disabled:hover),
	:global(.submit-verse-wrap .progress-btn-disabled:active) {
		transform: none;
		box-shadow: 4px 4px 0 0 #000;
	}
	@media (prefers-color-scheme: dark) {
		:global(.submit-verse-wrap .progress-btn-disabled) {
			box-shadow: 4px 4px 0 0 #fff;
		}
		:global(.submit-verse-wrap .progress-btn-disabled:hover),
		:global(.submit-verse-wrap .progress-btn-disabled:active) {
			box-shadow: 4px 4px 0 0 #fff;
		}
	}

	.lock-icon {
		font-size: 1rem;
	}

	.countdown-text {
		padding-top: 12px;
		font-size: 0.8rem;
		font-weight: 600;
		color: #6b7280;
		letter-spacing: 0.01em;
		font-variant-numeric: tabular-nums;
		text-align: center;
		width: 100%;
	}
	@media (prefers-color-scheme: dark) {
		.countdown-text {
			color: #9ca3af;
		}
	}

	.signin-text {
		font-size: 0.85rem;
		text-align: center;
		font-weight: 500;
	}

	/* ── Apple / Google sign-in buttons (mirror WinScreen) ── */
	:global(.submit-verse-wrap .apple-signin-btn),
	:global(.submit-verse-wrap .google-signin-btn) {
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 0.5rem;
		padding: 0.6rem 1rem;
		width: 100%;
		background: #000;
		color: #fff;
		border-radius: 0.5rem;
		font-size: 0.95rem;
		font-weight: 600;
		border: none;
		cursor: pointer;
		transition:
			background 150ms ease,
			transform 80ms ease;
	}
	:global(.submit-verse-wrap .apple-signin-btn) {
		margin-bottom: 0.6rem;
	}
	:global(.submit-verse-wrap .apple-signin-btn:hover),
	:global(.submit-verse-wrap .google-signin-btn:hover) {
		background: #222;
		transform: translateY(-1px);
	}
	:global(.submit-verse-wrap .apple-signin-btn:active),
	:global(.submit-verse-wrap .google-signin-btn:active) {
		background: #111;
		transform: scale(0.98);
	}
	@media (prefers-color-scheme: dark) {
		:global(.submit-verse-wrap .apple-signin-btn),
		:global(.submit-verse-wrap .google-signin-btn) {
			background: #fff;
			color: #000;
		}
		:global(.submit-verse-wrap .apple-signin-btn:hover),
		:global(.submit-verse-wrap .google-signin-btn:hover) {
			background: #e5e5e5;
		}
		:global(.submit-verse-wrap .apple-signin-btn:active),
		:global(.submit-verse-wrap .google-signin-btn:active) {
			background: #ccc;
		}
	}
	:global(.submit-verse-wrap .apple-icon),
	:global(.submit-verse-wrap .google-icon) {
		width: 1.1rem;
		height: 1.1rem;
		flex-shrink: 0;
	}

	/* ── Submit panel ── */
	.submit-panel {
		display: flex;
		flex-direction: column;
		gap: 0.85rem;
		width: 100%;
		padding: 1rem;
		background: oklch(94% 0.028 298.626);
		border: 2px solid #000;
		border-radius: 0.75rem;
		box-shadow: 6px 6px 0 0 #000;
	}
	@media (prefers-color-scheme: dark) {
		.submit-panel {
			background: oklch(22% 0.025 298.626);
			border-color: #fff;
			box-shadow: 6px 6px 0 0 #fff;
		}
	}

	.panel-hint,
	.preview-hint {
		font-size: 0.85rem;
		color: #6b7280;
		text-align: center;
	}
	@media (prefers-color-scheme: dark) {
		.panel-hint,
		.preview-hint {
			color: #9ca3af;
		}
	}

	.panel-error {
		font-size: 0.85rem;
		color: #b91c1c;
		text-align: center;
		font-weight: 600;
	}
	@media (prefers-color-scheme: dark) {
		.panel-error {
			color: #f87171;
		}
	}

	.select-row {
		display: flex;
		gap: 0.5rem;
		flex-wrap: wrap;
	}

	.select-label {
		display: flex;
		flex-direction: column;
		gap: 0.25rem;
		flex: 1;
		min-width: 5rem;
	}

	.select-cap {
		font-size: 0.7rem;
		font-weight: 700;
		text-transform: uppercase;
		letter-spacing: 0.08em;
		color: #6b7280;
	}
	@media (prefers-color-scheme: dark) {
		.select-cap {
			color: #9ca3af;
		}
	}

	.cascading-select {
		width: 100%;
		padding: 0.5rem 0.6rem;
		border: 2px solid #000;
		border-radius: 0.5rem;
		background: #fff;
		color: #111;
		font-size: 0.9rem;
		font-weight: 600;
		cursor: pointer;
	}
	@media (prefers-color-scheme: dark) {
		.cascading-select {
			background: #111827;
			color: #f9fafb;
			border-color: #fff;
		}
	}

	/* ── Preview card ── */
	.preview-card {
		padding: 0.75rem;
		border: 1px solid rgba(0, 0, 0, 0.15);
		border-radius: 0.5rem;
		background: rgba(255, 255, 255, 0.5);
	}
	@media (prefers-color-scheme: dark) {
		.preview-card {
			border-color: rgba(255, 255, 255, 0.15);
			background: rgba(0, 0, 0, 0.25);
		}
	}

	.preview-ref {
		font-size: 0.8rem;
		font-weight: 700;
		color: #374151;
		margin-bottom: 0.4rem;
	}
	@media (prefers-color-scheme: dark) {
		.preview-ref {
			color: #d1d5db;
		}
	}

	.preview-verses {
		display: flex;
		flex-direction: column;
		gap: 0.35rem;
	}

	.preview-verse {
		font-size: 0.82rem;
		line-height: 1.45;
		color: #4b5563;
		font-style: italic;
	}
	@media (prefers-color-scheme: dark) {
		.preview-verse {
			color: #9ca3af;
		}
	}

	/* ── Submit button (neobrutalist) ── */
	.submit-btn {
		padding: 0.7rem 1rem;
		background: #16a34a;
		color: #fff;
		border: 2px solid #000;
		border-radius: 0.6rem;
		font-size: 0.95rem;
		font-weight: 700;
		cursor: pointer;
		box-shadow: 4px 4px 0 0 #000;
		transition:
			transform 80ms ease,
			box-shadow 80ms ease,
			background-color 120ms ease;
	}
	.submit-btn:hover:not(:disabled) {
		transform: translate(-2px, -2px);
		box-shadow: 6px 6px 0 0 #000;
		background: #15803d;
	}
	.submit-btn:active:not(:disabled) {
		transform: translate(2px, 2px);
		box-shadow: 2px 2px 0 0 #000;
	}
	.submit-btn:disabled {
		opacity: 0.55;
		cursor: not-allowed;
	}
	@media (prefers-color-scheme: dark) {
		.submit-btn {
			border-color: #fff;
			box-shadow: 4px 4px 0 0 #fff;
		}
		.submit-btn:hover:not(:disabled) {
			box-shadow: 6px 6px 0 0 #fff;
		}
		.submit-btn:active:not(:disabled) {
			box-shadow: 2px 2px 0 0 #fff;
		}
	}

	/* ── Upcoming list ── */
	.upcoming-text {
		font-size: 0.72rem;
		color: #6b7280;
		text-align: center;
		line-height: 1.5;
	}
	@media (prefers-color-scheme: dark) {
		.upcoming-text {
			color: #9ca3af;
		}
	}
	.upcoming-item {
		font-weight: 600;
	}
	.upcoming-sep {
		margin: 0 0.25rem;
		opacity: 0.6;
	}

	/* ── Confirmation card ── */
	.confirm-card {
		display: flex;
		flex-direction: column;
		gap: 0.5rem;
		align-items: center;
		width: 100%;
		padding: 1.1rem;
		background: oklch(94% 0.028 298.626);
		border: 2px solid #000;
		border-radius: 0.75rem;
		box-shadow: 6px 6px 0 0 #000;
		text-align: center;
	}
	@media (prefers-color-scheme: dark) {
		.confirm-card {
			background: oklch(22% 0.025 298.626);
			border-color: #fff;
			box-shadow: 6px 6px 0 0 #fff;
		}
	}

	.confirm-title {
		font-size: 1rem;
		font-weight: 700;
		color: #111;
	}
	@media (prefers-color-scheme: dark) {
		.confirm-title {
			color: #f9fafb;
		}
	}

	.confirm-ref {
		font-size: 0.85rem;
		font-weight: 600;
		color: #374151;
	}
	@media (prefers-color-scheme: dark) {
		.confirm-ref {
			color: #d1d5db;
		}
	}

	.submit-another-btn {
		padding: 0.5rem 1.1rem;
		background: #fff;
		color: #111;
		border: 2px solid #000;
		border-radius: 0.5rem;
		font-size: 0.85rem;
		font-weight: 700;
		cursor: pointer;
		box-shadow: 3px 3px 0 0 #000;
		transition:
			transform 80ms ease,
			box-shadow 80ms ease;
	}
	.submit-another-btn:hover {
		transform: translate(-1px, -1px);
		box-shadow: 4px 4px 0 0 #000;
	}
	.submit-another-btn:active {
		transform: translate(1px, 1px);
		box-shadow: 2px 2px 0 0 #000;
	}
	@media (prefers-color-scheme: dark) {
		.submit-another-btn {
			background: #111827;
			color: #f9fafb;
			border-color: #fff;
			box-shadow: 3px 3px 0 0 #fff;
		}
		.submit-another-btn:hover {
			box-shadow: 4px 4px 0 0 #fff;
		}
		.submit-another-btn:active {
			box-shadow: 2px 2px 0 0 #fff;
		}
	}
</style>
