Design Journal — The Meaning Canvas (First Pass)
🎯 Intent
What was I trying to achieve today?
- Build the first working version of the Meaning Canvas — an overlay that shows all answers grouped by pod in a multi-column layout.
- Keep it content-agnostic: works for ikigai (4 columns), mini-proposal (6 columns), or any future content set.
- Wire it into the dialogue flow via a floating action button so the actor can review their answers at any point.
- Follow the chunked approach from earlier planning: start with the overlay shell + column grouping + answer cards as a single deliverable.
🧭 Guiding Questions
What questions are shaping my thinking right now?
- What’s the right entry point for the canvas — a FAB, a stage direction, or both?
- Should the canvas be a separate route or an overlay on top of the dialogue? Overlay keeps context, route gives more room.
- How does this scale when a pod has 16 answers? Does it need collapse/scroll within a column?
- What role do tags play — are they per-answer metadata the actor adds, or auto-derived from the pod category?
- Is the canvas read-only, or should the actor be able to edit/delete answers from here?
🧠 Insight
What clicked?
- The canvas is fundamentally a different mode of seeing the same data. The dialogue is temporal (one answer at a time, in sequence). The canvas is spatial (all answers at once, grouped by theme). Both views compound — the dialogue generates meaning, the canvas reveals patterns.
- Keeping MeaningCanvas as a pure presentational component (
pods+allAnswersin, close event out) means it doesn’t care about the dialogue engine at all. It just renders what’s in the answer store. - The overlay pattern (backdrop + panel) feels right for now. It’s a pause from the conversation, not a departure. Escape and backdrop click to dismiss keep it lightweight.
- Mobile stacking (columns go vertical under 640px) is the obvious responsive move and works naturally with the flex layout.
🧱 Structure
What did I define?
- MeaningCanvas.svelte: Overlay component. Takes
pods[]andallAnswers[]as props. Groups answers byquestionIdmatching each pod. Renders one column per pod with title, category label, and answer cards. - Answer cards: Text + optional colored pill tag. Tags use
data-tagattribute for per-category color (passion = pink, skill = blue, need = green, paid = gold). - Header: Back arrow (← Meaning Canvas) on the left, centered title, close button (✕) on the right. Matches the UI sketch layout.
- Footer: “Entries stored locally on this device” — privacy signal, keeps expectations clear.
- FAB trigger: “Canvas” button fixed to bottom-right alongside “Resume later”. Both use the same pill-shaped FAB style with backdrop blur.
- Integration:
showCanvasboolean in DialogueController toggles the overlay. Canvas receives the active content set’s pods and all answers.
⚙️ Decisions
What did I choose (and why)?
- Overlay, not route — The canvas is a lens on the current content set, not a destination. Keeping it as an overlay means the actor stays in the dialogue context and can dismiss quickly.
- FAB as entry point — Simple and always available. A stage direction (
[SHOW_ANSWERS]) can come later as a director-triggered entry, but the FAB gives the actor agency to review whenever they want. - No export yet — The UI sketch shows an “Export JSON” button. Skipped for now — the canvas needs to prove its value as a review tool first before adding data portability.
- Tag colors hardcoded to ikigai categories — Pragmatic shortcut. The tag system needs to become content-driven (defined in screenplay or pod frontmatter) rather than hardcoded CSS selectors. Good enough for now, but this is technical debt.
- Answers sorted by createdAt — Chronological within each column. The actor sees their journey of thought, earliest to latest.
🔄 Friction
What felt messy or uncomfortable?
- The FAB positioning is manual (
right: 130pxfor canvas,right: 18pxfor resume). Two fixed buttons side by side works for now but doesn’t scale if more actions appear. A proper action bar or bottom sheet would be cleaner. - Tag colors are hardcoded to four ikigai categories (
passion,skill,need,paid). Any new content set with different categories would need new CSS. This should be driven by content configuration. - The
titlein the header is absolutely positioned (left: 50%; transform: translateX(-50%)). Works visually but fragile — long titles or translated text could overlap the buttons. - No empty state for the canvas as a whole — if no answers exist at all, you get four columns of “No entries yet” which isn’t very helpful. Could show a message like “Start answering to see your canvas take shape.”
🌱 Learning
What new mental model formed?
- The dialogue and the canvas are two projections of the same underlying data. The dialogue is a process (sequential, time-bound). The canvas is a product (spatial, persistent). Good tools let you move fluidly between process and product views.
- Starting with the overlay shell as a single deliverable was the right chunk size. It’s immediately useful (you can review your answers) and creates the scaffolding for everything else (inline columns, export, editing).
- The
pods + allAnswersprop interface is the right abstraction boundary. The canvas doesn’t need to know about screenplays, directors, or dialogue state. It just needs the content structure and the actor’s data.
➡️ Next Move
Single clear next step.
- Content-driven tag colors: Move tag definitions into pod frontmatter or the screenplay so any content set can define its own color palette.
- Canvas empty state: Show a meaningful message when no answers exist instead of N columns of “No entries yet.”
- Inline column mode: Reuse the column component to show a single pod’s answers inline in the dialogue (triggered by
[SHOW_ANSWERS]stage direction after completion). - Export: Add JSON export from the canvas footer — the actor’s data is theirs to keep.
- Column scroll: Test with 16 answers per pod and decide if columns need internal scroll or collapse.