Skip to content

Slide 01 / 07

Click the deck, then use the arrow keys like a real presentation.

Readout

Family
Spatial
Theme
Light
Type
Sora
Accent
#0f9d7a
Corners
20px
Moves on
Keys, swipe
Studio
Ready

10 of 30, Spatial

Zoom Canvas.

Every slide is a frame on one big map; the camera pans, tilts and zooms between them.

Look
As designed

How it moves

Warm paper, white artboards, one teal accent, and a physical camera move instead of a cut. Use it when the deck has a shape worth seeing: the closing slide pulls all the way out and the visited frames become a small map under the title.

This is the specification the Studio sends to the model, written for Zoom Canvas's own look. Change the look in the Studio and every value follows.

Palette

  • Background#f4efe6
  • Text#1c1a17
  • Muted#6f6a62
  • Accent#0f9d7a
  • Surface#ffffff
  • Hairlinergba(28,26,23,.12)

Type: Sora. Corners: 20px.

Layout

  • One large 2D canvas on a light paper ground (#f4efe6). A faint dot grid lives on the canvas itself (a pseudo-element with inset -6000px and a radial-gradient dot of rgba(28,26,23,.12), 44px spacing) so it pans and scales with the camera; that is what makes travel legible.
  • Every slide is a fixed 1280×720px white frame (#ffffff), 28px radius, 1px hairline (rgba(28,26,23,.12)), shadow 0 24px 80px rgba(28,26,23,.10), padding 64px 72px, a flex column with 28px gaps. Type inside a frame is in px because the frame is an artboard: kicker 15px weight 600 in #0f9d7a, title 64px weight 800 letter-spacing -0.03em line-height 1, lede 22px #6f6a62; the cover title is 128px at -0.045em. Objects are sized in px too (card h3 21px / p 16px, stat value 60px, ring 150px, quote 30px, bullets 24px); the body block centers vertically in the space under the lede.
  • Placement. each frame is positioned by inline custom properties style="--x:1400;--y:-540;--r:-4;--s:.85" (center in canvas px, rotation in deg, scale) with CSS left: calc(var(--x)*1px - 640px); top: calc(var(--y)*1px - 360px); transform: rotate(calc(var(--r)*1deg)) scale(var(--s)), origin 50% 50%. Rule: the cover sits at (0,0) r0 s1.2; slides 2–6 loop clockwise around it with small tilts (-7° to 6°) and scales .8–.85, never overlapping: (1400,-540,-4,.85) (1760,380,5,.85) (1000,1200,-3,.8) (-500,1150,6,.85) (-1420,250,-7,.85). The closing slide has class "overview" and sits at the loop's center (170,320) with --s:3, transparent background, no border or shadow: title 176px, lede 30px, bullets 40px weight 500 with 16px dots. It is invisible (opacity 0, pointer-events none) until it is active, then fades in over 900ms delayed 400ms; when it is active the other frames dim to .3 and show through beneath it as a map.
  • Camera. .stage is fixed inset 0 overflow hidden and holds .zoom > .pan > .canvas, all absolute at 0 0 with size 0 and transform-origin 0 0. .zoom { transform: translate(50vw,50vh) scale(calc(var(--fit) / var(--s))); transition: transform 1.25s cubic-bezier(.45,0,.15,1) }. .pan { transform: rotate(calc(var(--r) * -1deg)) translate(calc(var(--x) * -1px), calc(var(--y) * -1px)); transition: transform 1.25s cubic-bezier(.65,0,.35,1) }. --fit = min(innerWidth/1280, innerHeight/720) × .78, set on :root by JS on load and resize (the .78 inset keeps the map, shadow and HUD visible around the active frame). On deck:change JS copies the active slide's inline --x/--y/--r/--s onto .stage; the active frame then lands exactly centered, upright, at the fit scale. Because pan and zoom ease differently the path between frames bows like an arc. The stage starts at --x:170 --y:320 --s:3.6, so the first slide arrives by descending onto the map.
  • Non-active frames stay on the map at opacity .55 (hover .8, cursor pointer) showing only kicker and title; the lede and every object carry class reveal and are hidden until active. Body objects appear after the camera lands: <body data-reveal-delay="1000" data-animate-delay="900">. Every slide carries data-goto with its own index, so clicking a frame on the map travels to it (clicks inside the active frame are a no-op).
  • HUD. bottom-left a muted 13px tabular counter "01 / 07" and the hint "Press → to travel" that fades after the first slide. Bottom-right a 112×70px minimap: an inline SVG (viewBox 0 0 160 100) drawn by JS from the slides' --x/--y with a polyline through the centers in rgba(28,26,23,.12), the visited part of the route in #0f9d7a (a second polyline with pathLength=1 whose stroke-dasharray transitions), and one 8px round button per slide positioned in % over the SVG: muted at 45% opacity, accent once visited, the active one scaled 1.75. Above 1600px the minimap grows to 144×90px and the HUD to 15px; under 760px the minimap is hidden and the inset rises to .94.

Navigation. ← → ↑ ↓ Space PageUp/PageDown travel; Home/End; number keys 1-9 jump; clicking any non-active frame on the map or any minimap dot travels there. No wheel navigation.