---
id: task-3
title: 'Phase 2: Core Data Shapes - Embed, Markdown, Calendar, Map'
status: Done
assignee: []
created_date: '2026-01-02 14:42'
labels:
  - migration
  - shapes
  - core
dependencies: []
priority: high
---

## Description

<!-- SECTION:DESCRIPTION:BEGIN -->
Port medium-complexity shapes that form the core data visualization layer:

1. **folk-embed** (565 LOC) - URL embeds (YouTube, Maps, Twitter)
   - URL transformation patterns
   - Interaction state management

2. **folk-calendar** (644 LOC) - Unified calendar widget
   - Browser/widget/year views
   - Event detection from CalendarPanel/YearViewPanel

3. **folk-map** (2,168 LOC - LARGEST) - Collaborative Mapbox/MapLibre
   - Real-time presence cursors
   - Drawing annotations (markers, lines, areas)
   - Search via Nominatim, routing via OSRM
   - GPS location sharing

Simplifications:
- Replace React state with reactive properties
- Replace context providers with event-based communication
- Calendar/Map can be separate packages imported as needed
<!-- SECTION:DESCRIPTION:END -->

## Acceptance Criteria
<!-- AC:BEGIN -->
- [x] #1 folk-embed component with URL detection
- [x] #2 folk-calendar with month/year views
- [x] #3 folk-map with MapLibre integration
- [x] #4 Real-time presence on map working (via global presence system)
<!-- AC:END -->

## Implementation Notes

Created three FolkJS components:
- **lib/folk-embed.ts**: URL embeds with transformation patterns for YouTube, Twitter/X, Google Maps
- **lib/folk-calendar.ts**: Month view calendar with events, day selection
- **lib/folk-map.ts**: MapLibre GL integration with OSM tiles, Nominatim search, click-to-add markers

All components integrated into canvas.html:
- Added imports and custom element registrations
- Added toolbar buttons (Embed, Calendar, Map)
- Added click handlers to create shapes
- Added createShapeElement switch cases for sync hydration
