v0.2 Phase 7.3: FirstRunPage — wrapper sweep

Migrated the onboarding step cluster's ad-hoc button pairs to the new
grammar. Skip-link tertiary buttons stay as plain <button> with underline
because they're intentionally low-emphasis (text-only).

  - Step CTA buttons (primary + secondary) → LumotiaButton variants
  - Autostart "Saving…" pair → LumotiaButton loading + disabled
  - Error notice → LumotiaNotice tone=danger with body content snippet
  - Download progress bar → LumotiaProgress

Bespoke surfaces left verbatim: model-pick cards (rich content tiles
with Recommended/Downloaded pills), UnicodeSpinner, and the
test-recording quote-block.

Per-page gate: npm run check (0/0/5704 files). e2e baseline untouched.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-15 08:55:59 +01:00
parent d812410039
commit cb69772f4e

View File

@@ -6,6 +6,9 @@
import UnicodeSpinner from "$lib/components/UnicodeSpinner.svelte";
import { toasts } from "$lib/stores/toasts.svelte.js";
import { Download, CheckCircle, Sunrise, Moon, Play, Mic } from 'lucide-svelte';
import LumotiaButton from "$lib/ui/LumotiaButton.svelte";
import LumotiaNotice from "$lib/ui/LumotiaNotice.svelte";
import LumotiaProgress from "$lib/ui/LumotiaProgress.svelte";
// ---------------------------------------------------------------------------
// Onboarding event helpers (best-effort — failures are logged, never blocking)
@@ -261,11 +264,9 @@
The main dictation screen is just a button press away. Try your first real recording there — it's the same experience you'll use every day.
</p>
<div class="flex items-center justify-center gap-3 mt-6">
<button
class="px-4 py-2 rounded-lg text-sm bg-accent btn-filled-text hover:bg-accent-hover"
style="transition-duration: var(--duration-ui)"
onclick={deferTestToMainUi}
>Open the main app and try recording there</button>
<LumotiaButton variant="primary" onclick={deferTestToMainUi}>
Open the main app and try recording there
</LumotiaButton>
</div>
<button
class="mt-5 text-xs text-text-tertiary hover:text-text-secondary underline"
@@ -290,14 +291,8 @@
</p>
<p class="text-[12px] text-text-secondary mt-3">Off by default. You can change your mind any time in Settings.</p>
<div class="flex items-center justify-center gap-3 mt-6">
<button
class="px-4 py-2 rounded-lg text-sm border border-border text-text-secondary hover:bg-hover"
onclick={() => answerMorning(false)}
>No thanks</button>
<button
class="px-4 py-2 rounded-lg text-sm bg-accent btn-filled-text hover:bg-accent-hover"
onclick={() => answerMorning(true)}
>Yes, turn it on</button>
<LumotiaButton variant="secondary" onclick={() => answerMorning(false)}>No thanks</LumotiaButton>
<LumotiaButton variant="primary" onclick={() => answerMorning(true)}>Yes, turn it on</LumotiaButton>
</div>
<button
class="mt-5 text-xs text-text-tertiary hover:text-text-secondary underline"
@@ -314,14 +309,8 @@
</p>
<p class="text-[12px] text-text-secondary mt-3">Off by default. Always opt-in.</p>
<div class="flex items-center justify-center gap-3 mt-6">
<button
class="px-4 py-2 rounded-lg text-sm border border-border text-text-secondary hover:bg-hover"
onclick={() => answerEvening(false)}
>No thanks</button>
<button
class="px-4 py-2 rounded-lg text-sm bg-accent btn-filled-text hover:bg-accent-hover"
onclick={() => answerEvening(true)}
>Yes, turn it on</button>
<LumotiaButton variant="secondary" onclick={() => answerEvening(false)}>No thanks</LumotiaButton>
<LumotiaButton variant="primary" onclick={() => answerEvening(true)}>Yes, turn it on</LumotiaButton>
</div>
<button
class="mt-5 text-xs text-text-tertiary hover:text-text-secondary underline"
@@ -338,16 +327,17 @@
</p>
<p class="text-[12px] text-text-secondary mt-3">You can change this any time in Settings.</p>
<div class="flex items-center justify-center gap-3 mt-6">
<button
class="px-4 py-2 rounded-lg text-sm border border-border text-text-secondary hover:bg-hover"
<LumotiaButton
variant="secondary"
disabled={autostartApplying}
onclick={() => answerAutostart(false)}
>No thanks</LumotiaButton>
<LumotiaButton
variant="primary"
loading={autostartApplying}
disabled={autostartApplying}
>No thanks</button>
<button
class="px-4 py-2 rounded-lg text-sm bg-accent text-white hover:bg-accent-hover disabled:opacity-60"
onclick={() => answerAutostart(true)}
disabled={autostartApplying}
>{autostartApplying ? 'Saving…' : 'Yes, launch at login'}</button>
>{autostartApplying ? 'Saving…' : 'Yes, launch at login'}</LumotiaButton>
</div>
</div>
@@ -363,11 +353,8 @@
<Download size={32} strokeWidth={1.5} class="text-accent mx-auto mb-3" />
<h2 class="text-xl font-medium text-text">Downloading model</h2>
<p class="text-sm text-text-secondary mt-2">{downloadingModel}</p>
<div class="w-full bg-bg-input rounded-full h-2 mt-6">
<div
class="bg-accent h-2 rounded-full"
style="width: {downloadProgress}%; transition-duration: var(--duration-ui)"
></div>
<div class="mt-6">
<LumotiaProgress value={downloadProgress} max={100} ariaLabel="Model download progress" />
</div>
<p class="text-xs text-text-tertiary mt-2">{downloadProgress}%</p>
{#if estimatedMinutes > 2}
@@ -383,21 +370,18 @@
{#if error}
<!-- Sub-task 5: failure recovery — plain-English error + Try again / Skip -->
<div class="mt-4 p-3 rounded-lg bg-danger/10 border border-danger/20">
<p class="text-sm text-danger font-medium mb-1">Something went wrong</p>
<p class="text-xs text-danger/80 whitespace-pre-line leading-relaxed">{error}</p>
<div class="flex gap-2 mt-3">
<button
class="px-3 py-1.5 rounded-md text-xs bg-danger btn-filled-text hover:bg-danger/80"
style="transition-duration: var(--duration-ui)"
onclick={() => { error = ""; probe(); }}
>Try again</button>
<button
class="px-3 py-1.5 rounded-md text-xs border border-danger/40 text-danger hover:bg-danger/10"
style="transition-duration: var(--duration-ui)"
onclick={skipSetup}
>Skip this step</button>
</div>
<div class="mt-4">
<LumotiaNotice tone="danger" title="Something went wrong">
<p class="whitespace-pre-line leading-relaxed">{error}</p>
<div class="flex gap-2 mt-3">
<LumotiaButton variant="destructive" size="sm" onclick={() => { error = ""; probe(); }}>
Try again
</LumotiaButton>
<LumotiaButton variant="tertiary" size="sm" onclick={skipSetup}>
Skip this step
</LumotiaButton>
</div>
</LumotiaNotice>
</div>
{/if}