Add landing screen as the app's entry point
Introduce a simple, show-don't-tell entry screen that lowers the "what counts as a protocol" barrier and frames the activity as a short journey: - Lead line "Examine the protocols around you" over a rotating, cross-fading list of deliberately diverse examples (traffic, code, kitchens, ritual, governance, play) - Prominent "Begin" CTA above a three-step path: Describe / Understand / Share - "About the Bicorder" link opens the existing help modal Shown on first arrival; returning users with a reading in progress skip straight to the diagnostic (computed synchronously, no flash). Remove the now-redundant inline description from the focused flow. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
import FormRecommendation from './components/FormRecommendation.svelte';
|
||||
import AnalysisTransitionBanner from './components/AnalysisTransitionBanner.svelte';
|
||||
import HamburgerMenu from './components/HamburgerMenu.svelte';
|
||||
import Landing from './components/Landing.svelte';
|
||||
import { BicorderClassifier } from './bicorder-classifier';
|
||||
|
||||
// Load bicorder data and model from build-time constants
|
||||
@@ -30,6 +31,32 @@
|
||||
let refreshKey = 0; // Used to force component refresh in focused mode
|
||||
let isHelpOpen = false;
|
||||
|
||||
// Show the landing screen on first arrival. Returning users who already have
|
||||
// a reading in progress skip straight to the diagnostic. Computed
|
||||
// synchronously (not in onMount) so the landing never flashes for them.
|
||||
function hasReadingInProgress(): boolean {
|
||||
if (typeof localStorage === 'undefined') return false;
|
||||
try {
|
||||
const saved = localStorage.getItem('bicorder-state');
|
||||
if (!saved) return false;
|
||||
const s = JSON.parse(saved);
|
||||
const hasProtocol = !!s?.metadata?.protocol;
|
||||
const hasValue = s?.diagnostic?.some(
|
||||
(set: any) => set?.gradients?.some((g: any) => g?.value !== null && g?.value !== undefined)
|
||||
);
|
||||
return hasProtocol || hasValue;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
let started = hasReadingInProgress();
|
||||
|
||||
function startReading() {
|
||||
started = true;
|
||||
currentScreen = 0;
|
||||
}
|
||||
|
||||
// Screen types
|
||||
type Screen =
|
||||
| { type: 'metadata' }
|
||||
@@ -432,6 +459,9 @@
|
||||
|
||||
<HelpModal bind:isOpen={isHelpOpen} />
|
||||
|
||||
{#if !started}
|
||||
<Landing on:begin={startReading} on:about={openHelp} />
|
||||
{:else}
|
||||
<main>
|
||||
<div class="header">
|
||||
<div class="header-left">
|
||||
@@ -519,12 +549,6 @@
|
||||
|
||||
{:else}
|
||||
<!-- FOCUSED MODE: Show one screen at a time -->
|
||||
{#if currentScreen === 0}
|
||||
<div class="description">
|
||||
<p>A diagnostic tool for the study of protocols</p>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="focused-container">
|
||||
{#if currentScreenData.type === 'metadata'}
|
||||
<div class="focused-screen">
|
||||
@@ -679,6 +703,7 @@
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
main {
|
||||
|
||||
Reference in New Issue
Block a user