import { useLayoutEffect, useRef, useState, type CSSProperties } from 'react' import { Phone, Stage, Window } from '../kit' import './scenes.css' export const sceneLessons = [ { id: 'dashboard-phone', title: 'Compose the two-device story', note: 'A payment arrives on the dashboard and phone. Give each device a readable role; keep the amount and confirmation visible together.', bad: 'The phone hides the payment it is explaining', good: 'Dashboard and phone share the story without covering it' }, { id: 'window-satellite', title: 'Place a satellite around the story', note: 'An export window and its finished package. The receipt can overlap the window, but the settings and export action still need their own space.', bad: 'The receipt sits over the settings and action', good: 'The receipt straddles a quiet edge of the window' }, { id: 'window-focus', title: 'Choose one window to lead', note: 'Assets, resolved feedback and a release ready to publish. Use depth to keep the supporting windows present while the final action leads.', bad: 'Three active windows compete for attention', good: 'Supporting windows recede behind the publish step' }, { id: 'colored-layers', title: 'Use the ground to frame the layers', note: 'A paid invoice and its upcoming bank deposit. The background can carry warmth without painting every surface and status the same color.', bad: 'Ground, invoice and deposit compete in one saturated field', good: 'A warm ground frames distinct, readable layers' }, { id: 'material-contrast', title: 'Separate dark and light materials', note: 'A dark file workspace with a light document preview. Each material needs its own foreground, edge and depth against the surrounding scene.', bad: 'Inherited colors flatten the dark and light surfaces', good: 'Each surface keeps readable ink and a distinct boundary' }, { id: 'story-crop', title: 'Crop to the action and payoff', note: 'A library with a launch package ready to download. Keep the useful part at reading size; the rest of the application can continue beyond the frame.', bad: 'The whole application becomes a thumbnail', good: 'A deliberate crop keeps the package and action readable' }, { id: 'result-weight', title: 'Give the result the most weight', note: 'A file has just uploaded into a folder. Ask what the eye lands on first: it should be the file the story is about, not the list around it.', bad: 'The new file is one thin row in a long list', good: 'Fewer, larger rows; the new file is the heaviest thing in the frame' }, { id: 'crop-filler', title: 'Crop filler, never the story', note: 'The same folder, run off the right edge. A crop may cut placeholder columns; it must leave every value the story depends on whole.', bad: 'The crop cuts the size the story ends on', good: 'The crop falls past the last value that matters' }, { id: 'tile-lead', title: 'Give one tile the lead', note: 'Four features in a grid. Equal tiles with equal content read as a template; one hero tile and quieter neighbors give the eye a place to start.', bad: 'Four equal tiles, each a heading and bars', good: 'One hero tile with the product; the others a number, a sentence, a mark' }, ] as const type SceneId = typeof sceneLessons[number]['id'] type SceneProps = { good: boolean; compact: boolean } function Mark({ kind = 'check' }: { kind?: 'check' | 'file' | 'arrow' | 'download' }) { const paths = { check: 'm4 10 4 4 8-8', file: 'M5 2h7l4 4v12H5zM12 2v4h4M8 10h5M8 13h5', arrow: 'M3 10h14m-5-5 5 5-5 5', download: 'M10 2v10m-4-4 4 4 4-4M4 14v4h12v-4' } return } function Action({ children }: { children: string }) { return {children} } function Status({ children }: { children: string }) { return {children} } function DashboardPhone({ good, compact }: SceneProps) { return
Today
Fable Studio · Invoice 1042
24 assets selected
Campaign-assets.zip
24 files · 18.6 MBReviewed by Maya and Jon
Homepage · Summer release
Design retainer · June
Arriving tomorrow
Shared with the product team
A simpler way to work together.
Shared projects, clear ownership, and one place for feedback.
Everything your team needs to publish.
Edits on the plane merge when you land.
)} {tile('Connects your tools',{lesson.note}