CICERO · HOME · MACRO 1
The first macro — geometry. Built on Mapbox Maps SDK for Flutter (iOS + Android), not web. This page is a design spec: every asset, state, and behavior the Flutter implementation needs. The HTML drawings here are static; the real map is camera-driven, gesture-driven, and runtime-styled.
Each tier surfaces a different cluster shape. Pinch in/out triggers card-type swap. This is one of the biggest behaviors in the system — the home cluster reshapes as the user zooms.
Country borders, major cities. One pin per nation.
Major cities, regions. 1–3 markers per region.
Neighborhoods, major districts. Anchor pins only.
Many POIs, transit lines visible. 8–15 visible pins.
Streets visible, all POIs. 15–30 pins, focused state common.
Building-level, doorway pins. <8 visible. Standing-in-front cluster.
Squircle pin chassis (matches the reference screenshot). Each icon is a category. Sprite atlas in production: 14 icons × 6 states × 2 resolutions = ~168 PNG variants.
Museum
Church / basilica
Sculpture / monument
Trattoria
Bar / aperitivo
Gelato
Coffee
Viewpoint
Garden / park
Transit
Shop
Toilet
Pharmacy
Generic POI
Same chassis, different visual treatment per state. Backend swaps state via runtime style change (icon-image + paint properties).
Default
Beige fill, neutral. Ambient pin.
Focused
Yellow, 1.4× size, bounce on entry.
Pinned (+)
User pressed + when far. Will resurface.
Completed (✓)
Visited. Cyan with checkmark.
Soft-pinned
Pinned for the day. Faded yellow + dashed.
Suggested
Outline only. Next Up candidate.
Line geography — a street, alley, riverside, garden walk worth doing as a path. Terracotta to distinguish from Routes (slate).
Continuous · default
Default stretch. 4px solid, terracotta, rounded caps.
Dashed · soft-pinned
Soft-pinned for the day. 8/4 dash pattern.
Dotted · suggested
Suggested but not committed. 2/4 dot, 60% alpha.
Treasure-map-not-GPS principle — routes encourage deviation. Slate color (distinct from Stretch terracotta), default = inviting dashed, never directive.
Dashed inviting · default
Default route. 6/4 dash, soft-pinnable. Rounded caps.
Continuous · committed
User is on this route, on track. Solid 4px slate.
Faded ghost · diverged
User wandered off. 30% alpha, dashed.
Hand-drawn feel. 8–14 vertices, smoothed bezier. Sage green, three states.
Default
Visible at City tier. 12% sage fill, no stroke, name label centered.
Soft-pinned for the day
22% sage fill, 1.5px dashed sage stroke. Checkmark on label.
You are inside
18% sage fill, 2px solid sage stroke. "Exploring" eyebrow on label.
When brain is in #19 mode. Anchor is large + named. Dashed slate path from user to anchor. Detour pins along the way pulse subtly to invite.
When the Next Up Selector card surfaces with 3 options, the map shows all 3 candidates as Suggested pins (outline-dashed) with their respective routes from the user dot, each labeled with time. On tap of a tile → that path becomes solid, the chosen pin transitions to Focused, the other two fade. Camera flies to frame user + chosen.
A · 3 candidates visible (before tap)
All 3 in Suggested state. 3 dashed paths from user dot. Time labels at midpoints.
B · After tap (Gelato chosen)
Chosen path becomes solid. Chosen pin → Focused. Others fade to ghost. Camera flies to frame both.
Apple-style. Inner blue dot, pulsing halo, optional direction cone (when device heading available), optional accuracy circle (when GPS poor).
Default
With direction cone
For booked anchors (#25) and the day's hero anchor. Larger pin · persistent label · subtle glow when within 200m.
Handoff notes for the Flutter build. The HTML drawings above are specifications; here's how each surface maps to Mapbox SDK constructs.
cicero-pins.png + cicero-pins.json manifestpins · stretches · routes · neighborhoods · user-location{ category, state, anchor_id, label } — runtime style picks icon + colors{ kind, state } — used by line-dasharray + line-color expressionsicon-image from sprite, text-field for callouts, icon-allow-overlap: true for focused state, icon-size interpolated by zoomline-dasharray per pattern ([2,1] dashed, [1,2] dotted, no array = solid), line-cap: roundfill-opacity per state (12/22/18%), separate line layer for strokecircle-radius animated in code (Flutter side), not in style specflyTo with custom easing (~600ms, ease-out cubic) framing user + chosen pinlayer.visibility = "none" / "visible" on zoom-change eventsicon-size with tween (Flutter) on selection eventonMapClick → queryRenderedFeatures at tap point with layer filter — find which pin was hitcicero-pins component set → exported PNG spriteWhy not web Mapbox? The home is mobile-first iOS/Android. Mapbox GL JS would mean a different rendering pipeline. Sticking with native SDK avoids two implementations.
Why HTML mockups for a native build? Faster iteration on visual design before committing to Flutter widget tree. Once locked here, the spec → Flutter is a one-week port, not a discovery loop.
Source spec for backend → docs/specs/brain-pill-and-map-plan.md · use case table → docs/specs/cicero-home-use-cases-table.md