Slide 01 / 07
Click the deck, then use the arrow keys like a real presentation.
Readout
- Family
- Spatial
- Theme
- Light
- Type
- Space Grotesk
- Accent
- #e8442b
- Corners
- 10px
- Moves on
- Keys, wheel, swipe
- Studio
- Ready
17 of 30, Spatial
Transit Map.
A subway map is the navigation: the camera rides the line from stop to stop while the slide sits in a card.
How it moves
Light, printed-diagram feel. A big SVG route map fills the background, each slide is a station, and moving on pans and zooms the camera to the next stop while a dashed trail fills in behind you. The slide itself lives in a floating panel on the right. Use it for journeys, roadmaps and anything with a natural order and a few branches.
This is the specification the Studio sends to the model, written for Transit Map's own look. Change the look in the Studio and every value follows.
Palette
- Background#f6f5f2
- Text#14161a
- Muted#6a6f78
- Accent#e8442b
- Surface#ffffff
- Hairlinergba(20,22,26,.12)
Type: Space Grotesk. Corners: 10px.
Layout
- Two layers. Behind everything, a full-viewport SVG route map (viewBox 0 0 1600 900, preserveAspectRatio "xMidYMid slice") on the page ground (#f6f5f2). On top, one floating slide panel pinned to the right: right 3vw, top 8vh, bottom 8vh, width clamp(330px, 34vw, 620px), background #ffffff, 1px rgba(20,22,26,.12) border, radius calc(10px + 6px), a soft two-layer shadow (0 30px 70px rgba(20,22,26,.12), 0 2px 6px rgba(20,22,26,.05)), padding clamp(1.3rem, 1.9vw, 2.1rem). The panel is a two-row grid: a head row and the slide stage.
- The map is a larger world than the viewport (about 2400 x 900 units). It holds three routes drawn as 8px round-capped, round-joined strokes with no fill and only horizontal, vertical and 45 degree segments, like a real transit diagram: the primary line in #e8442b at 35% opacity, plus two secondary lines (blue #1b74d8 and green #0f9d58, both 68% opacity) that cross it. On top of the primary line sits an identical path, the trail, drawn at full #e8442b using pathLength=1, stroke-dasharray 1px 1px and a stroke-dashoffset of (1 - trail) so it fills like a progress bar as you advance (transition .8s cubic-bezier(.22,1,.36,1)).
- One station per slide, laid along the primary line, all built in JS from the slides' data-title. An ordinary stop is a 13px-radius circle filled #ffffff with a 4px #14161a stroke. An interchange stop (where the slide is a hub for numbers or a comparison) is a 62 x 26 capsule rotated to the local track angle (0, 45 or -45 degrees). The station name is 21px / 600 in #6a6f78, painted with a 7px #f6f5f2 outline (paint-order: stroke) so it stays legible over a track, and it is placed with a per-stop offset and text-anchor so it never crosses a line. Visited stops (done) get an #e8442b stroke and a #14161a name.
- The active stop swaps its dot for a halo: a 27px circle, #ffffff fill, 6px #e8442b stroke, scaling from .2 to 1 with opacity in .55s cubic-bezier(.22,1,.36,1) after .1s, with the two-digit stop number (21px / 700) fading in inside it. Its name goes bold #14161a. Each stop has a transparent 34px hit circle and a dashed 2.5px focus ring shown only on :focus-visible.
- The panel head is a hairline-bottomed row: left a badge (a 1.1rem x .3rem #e8442b pill plus "Practice line" in .72rem caps, tracked .14em, #6a6f78), right a counter "Stop 03 / 07" in .78rem tabular figures. Each slide is a stop-no eyebrow (.72rem caps, #e8442b: Terminus, Stop 02, Stop 03 · interchange ...), an h2 at clamp(1.45rem, 2.05vw, 2.3rem) / 700, a muted lede, then objects. Because the panel is narrow, shared objects are re-metred inside it: cards one column, stats three columns, timeline turned vertical with a 2px rail on the left, carousel one per view, compare tight, checks 1.1rem.
- Legend fixed bottom-left (left 3vw, bottom 4.5vh): a small "Lines" caps label and three rows, each a 1.6rem x .32rem pill in the line colour plus its meaning (Practice, Numbers, People). A hint "Scroll to ride the line" sits top-left and fades out after slide 1.
- Cover slide: vertically centred in the panel, h2 clamp(2.1rem, 3.3vw, 3.7rem) / -0.035em / line-height .98, a stop-no "Terminus", and a small board line ("Board at stop 01") with a hollow #e8442b ring. Closing slide: "Stop 07 · terminus", the camera relaxes to zoom 1 on the final station at the far end of the route, and the trail reaches the end of the line (trail = 1).
Motion
- The camera is a single SVG <g> with transform translate(--fx, --fy) scale(--k) translate(-sx, -sy) (transform-box: view-box, origin 0 0). --sx/--sy are the active stop's map coordinates, --fx/--fy is the screen point the active stop should land on (430px, 450px on desktop, left of the panel), --k is zoom (.9 on the cover, 1.2 on middle stops, 1 on the last). On every slide change JS only rewrites --sx, --sy, --k and --trail; the camera transitions transform over .7s cubic-bezier(.22,1,.36,1), so the whole map glides and the active station stays anchored at the same screen point.
- The slide swap inside the panel: inactive slides sit at opacity 0, translateY(26px); the active one rises in (opacity .5s ease, transform .6s cubic-bezier(.22,1,.36,1)) with a .32s delay so the camera arrives first. Set body data-reveal-delay="820" data-animate-delay="820".
- Trail position per stop is measured, not typed: sample the primary path 400 times with getPointAtLength and take the nearest sample to each stop.
- Under 760px the panel becomes a bottom sheet (left/right 4vw, bottom 3vh, height 56vh), --fx/--fy shift to 800px / 250px so the active stop sits in the upper part, the legend becomes a top row, and the hint is hidden.
Navigation. arrows / Space / PageUp / PageDown / Home / End / 1-9; wheel and trackpad move one slide per gesture; every station on the map is a real link (<a href="#n" data-goto>) and jumps to its slide.