Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions src/components/student-space/sheets/ProfileSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -795,20 +795,20 @@ function TldrHero({
const meta = [`${total} capture${total === 1 ? '' : 's'}`, refined].filter(Boolean).join(' · ')

return (
<section className="rounded-2xl border border-(--profile-accent)/20 bg-[linear-gradient(135deg,var(--profile-soft),rgba(255,255,255,0.78))] p-5 shadow-(--shadow-sheet-tile)">
<p className="text-xs font-semibold text-(--profile-ink)">
<section className="relative isolate overflow-hidden rounded-2xl border border-(--profile-accent)/15 bg-(--color-sheet-pane-left) p-6 shadow-(--shadow-sheet-tile) before:pointer-events-none before:absolute before:inset-0 before:-z-10 before:bg-[radial-gradient(120%_140%_at_0%_0%,color-mix(in_srgb,var(--profile-accent)_22%,transparent)_0%,color-mix(in_srgb,var(--profile-accent)_8%,transparent)_38%,transparent_72%)] after:pointer-events-none after:absolute after:inset-0 after:-z-10 after:bg-[radial-gradient(80%_100%_at_100%_100%,color-mix(in_srgb,var(--profile-accent)_10%,transparent)_0%,transparent_55%)]">
<p className="text-xs font-semibold tracking-wide text-(--profile-ink)">
{voiced.length >= 3
? `Top voices in your ${PROFILE_HEADERS[tab].tag}`
: `In your ${PROFILE_HEADERS[tab].tag}`}
</p>
<h3 className="mt-2 max-w-3xl text-xl font-semibold leading-snug text-(--color-sheet-ink)">
<h3 className="mt-1.5 max-w-[34ch] text-balance text-lg font-semibold leading-snug text-(--color-sheet-ink)">
{voiced.length >= 3
? tldrHeadline(tab, voiced.length)
: 'Few captures yet — capture a moment on the island to see what shows up.'}
</h3>
{voiced.length >= 3 ? (
<div className="mt-4 flex flex-wrap gap-2">
{voiced.slice(0, 5).map((claim) => {
{voiced.slice(0, 4).map((claim) => {
const selected = selectedClaimId === claim.id
return (
<button
Expand Down Expand Up @@ -862,7 +862,7 @@ function PersonalityTldr({ tldr }: { tldr: BigFiveTldr }) {
{tldr.eyebrow ?? 'Your personality at a glance'}
</p>
{tldr.headline ? (
<h3 className="mt-2 max-w-3xl text-xl font-semibold leading-snug text-(--color-sheet-ink)">
<h3 className="mt-2 max-w-3xl text-balance text-lg font-semibold leading-snug text-(--color-sheet-ink)">
{tldr.headline}
</h3>
) : null}
Expand Down Expand Up @@ -1207,10 +1207,13 @@ function ShareDialog({
<section className="w-full max-w-lg animate-[sheet-popover-in_180ms_var(--ease-sheet)_both] rounded-2xl border border-(--color-sheet-divider) bg-white p-5 shadow-(--shadow-sheet-dialog)">
<header className="flex items-start justify-between gap-4">
<div>
<h2 id="share-dialog-title" className="text-xl font-semibold text-(--color-sheet-ink)">
<h2
id="share-dialog-title"
className="text-balance text-lg font-semibold text-(--color-sheet-ink)"
>
Share your profile
</h2>
<p className="mt-1 text-base leading-relaxed text-(--color-sheet-ink-soft)">
<p className="mt-1 text-pretty text-sm leading-relaxed text-(--color-sheet-ink-soft)">
Generate a link for parents, teachers, or friends. Quotes are hidden by default.
</p>
</div>
Expand Down
10 changes: 3 additions & 7 deletions src/components/student-space/sheets/SettingsSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
SheetContent,
SheetDescription,
SheetIdentityHeader,
SheetPageHeader,
SheetSidebar,
SheetTitle,
usePageEscape,
Expand Down Expand Up @@ -68,17 +67,14 @@ export function SettingsSheet() {
<SheetDescription>Tools for adjusting how the world behaves.</SheetDescription>
</SheetIdentityHeader>
<div className="px-7 pb-6">
<p className="text-base leading-relaxed text-(--color-sheet-ink-soft)">
<p className="text-pretty text-sm leading-relaxed text-(--color-sheet-ink-soft)">
Adjust how the world behaves and replay the first-run ceremony. Changes apply
immediately and persist across sessions.
</p>
</div>
</SheetSidebar>
<SheetContent>
<SheetPageHeader data-stagger-slot="2">
<SheetTitle>Settings</SheetTitle>
</SheetPageHeader>
<SheetBody data-stagger-slot="3">
<SheetBody data-stagger-slot="2">
<SettingsGroup
title="World & weather"
help="Scrub the time of day and force weather effects."
Expand Down Expand Up @@ -138,7 +134,7 @@ function SettingsGroup({
}) {
return (
<section className="border-b border-(--color-sheet-divider) py-6 last:border-b-0">
<h2 className="mb-1.5 text-xs font-semibold text-(--color-sheet-ink-soft)">{title}</h2>
<h2 className="mb-1 text-sm font-semibold text-(--color-sheet-ink)">{title}</h2>
<p className="mb-3 text-sm leading-[1.5] text-(--color-sheet-ink-soft)">{help}</p>
{children}
</section>
Expand Down
2 changes: 1 addition & 1 deletion src/components/student-space/sheets/TrajectorySheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ function SearchingBody({ capture }: { capture: TrajectoryCapture }) {
<span className="grid size-7 shrink-0 place-items-center rounded-full bg-[#d4e6fb] text-sm font-bold tabular-nums text-[#2166aa]">
{i + 1}
</span>
<h3 className="text-balance text-xl font-semibold leading-tight text-(--color-sheet-ink)">
<h3 className="text-balance text-lg font-semibold leading-snug text-(--color-sheet-ink)">
{bearing.title}
</h3>
</header>
Expand Down
35 changes: 35 additions & 0 deletions src/lib/student-space/onboarding-skip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,55 @@ import { OFFLINE_DEMO_STUDENTS } from '~/engine/student-space/Game/View/Onboardi
* Shared between the React `SkipButton` (floating dev escape hatch) and any
* inline skip affordance an individual stage renders.
*/
type SeedPin = {
id: string
createdAt: string
entryDate: string
emotion: string
intensity: number
cause: null
note: null
}
type SkipContext = {
state?: {
backend?: unknown
onboarding?: { complete?: () => unknown }
persistence?: { flush?: () => unknown }
moodPins?: { pins?: unknown[]; hydrate?: (snapshot: SeedPin[]) => unknown }
} | null
profile?: { setIdentity?: (id: { name: string; className: string }) => unknown } | null
}

const DEMO_MOOD_EMOTIONS = ['joy', 'anxiety', 'sadness', 'envy', 'ennui', 'fear', 'joy'] as const

function seedDemoMoodWeek(moodPins: NonNullable<SkipContext['state']>['moodPins']) {
if (!moodPins?.hydrate) return
if (Array.isArray(moodPins.pins) && moodPins.pins.length > 0) return
const today = new Date()
today.setHours(12, 0, 0, 0)
const pins: SeedPin[] = DEMO_MOOD_EMOTIONS.map((emotion, offset) => {
const day = new Date(today)
day.setDate(today.getDate() - (DEMO_MOOD_EMOTIONS.length - 1 - offset))
const entryDate = `${day.getFullYear()}-${String(day.getMonth() + 1).padStart(2, '0')}-${String(day.getDate()).padStart(2, '0')}`
return {
id: `demo-mood-${entryDate}`,
createdAt: day.toISOString(),
entryDate,
emotion,
intensity: 0.45 + ((offset * 13) % 35) / 100,
cause: null,
note: null,
}
})
moodPins.hydrate(pins)
}

export function performOnboardingSkip(ctx: SkipContext): void {
try {
if (!ctx.state?.backend) {
const pick = OFFLINE_DEMO_STUDENTS[Math.floor(Math.random() * OFFLINE_DEMO_STUDENTS.length)]
if (pick) ctx.profile?.setIdentity?.({ name: pick.name, className: pick.className })
seedDemoMoodWeek(ctx.state?.moodPins)
}
ctx.state?.onboarding?.complete?.()
ctx.state?.persistence?.flush?.()
Expand Down
Loading