Appearance
Conversation Block Redesign - Feasibility
The Problem
The conversation block is the most complex and least flexible block in the creative system. Several pain points have accumulated:
1. Styling is awkward
messageProperties,choiceProperties, andresponsePropertieseach have their own style objects, but they share a single conversation container- Getting choices centered, sized, or positioned how you want requires fighting the default layout with custom CSS resets
- The
hiddenproperty onresponsePropertiescauses subtle bugs:visibility: hiddenbreaksinnerTextin custom scripts while the element still exists in DOM (seecustom-scripts-tag-operator.md) - No way to style individual messages or choice sets differently within the same conversation
2. No quiz feedback mode
- When a choice is clicked,
inputEnteredimmediately switches the Choice component to a Text component (the response bubble) - The other choice buttons are gone from the DOM instantly
- No way to show "correct/incorrect" visual feedback before advancing
- Custom scripts run AFTER the transition, so they can't manipulate the choice buttons
3. Choice layout is limited
- All choices in a step share a single
.choicescontainer withfloat: rightand inline display - No grid/flex layout options for choices (e.g., 2x2 grid, horizontal row, vertical stack)
- Choice sizing is content-driven; no way to set uniform dimensions without custom CSS
- The
fitproperty (solelySingleetc.) exists but is limited
4. No grouping of conversation elements
- Messages, choices, and responses are individual flow steps rendered by MessageHolder
- You can't group a message + its choices as a visual unit for shared background/border
- You can't create a "question card" that contains the question text, choices, and feedback as one styled container
- The only wrapper available is
co1-scroll-content, which has excessive built-in logic (scroll behavior, overflow handling, padding resets) that causes unwanted side effects when you just want a clean container
5. No CSS reset / clean slate option
- Conversation blocks come with heavy default styling that's hard to override
- No toggle to start from a minimal base and build up (like a "reset" mode)
- This problem exists for all block types but is worst in conversation because it has the most built-in layout opinions
- Designers end up writing extensive custom CSS just to undo defaults before they can style how they want
Current Architecture
liveFlow: FlowComponentInterface[][] (reactive array of arrays)
|
v
CreativeConversationBlock.vue
v-for (componentArray, index) in liveFlow
|
v
MessageHolder.vue (one per liveFlow entry)
- Wraps everything in .message-wrap div
- If text payload + no input needed: renders in .message-bubble > Text component
- If choice/link: renders Choice component with :block-array="all choices"
- If inputEntered: switches to Text component showing selected answer
|
v
Choice.vue (renders ALL choices for one step)
- .choices container div
- v-for over blockArray: <a> buttons
- Styles from choiceProperties applied to each buttonKey facts:
- All choices for one question ARE in a single message-wrap (not separate wraps)
- Choice buttons ARE in a single
.choicesdiv - Styling comes from
conversationProperties.choiceProperties(global) + per-buttonblockStyles(overrides) - The Choice-to-Response transition is instant:
inputEntered = trueswaps the component
Proposed Approaches
Approach A: Quiz Mode Only (Minimal Change)
Add a quiz feedback phase between choice click and flow progression.
Engine changes:
Choice.vue: NewquizModeprop. When enabled,doSelection()delaysinput-enteredemission- During delay: apply CSS classes to buttons (
.quiz-correct,.quiz-incorrect,.quiz-selected) isGoalflag on flow components already marks the correct answer- After delay: emit
input-entered+progress-flowas normal
Frontend changes:
- New toggle in Choice configuration: "Quiz mode"
- Configurable feedback duration (default 2s)
- Optional: color pickers for correct/incorrect states
Pros: Small change, solves the quiz use case Cons: Doesn't address broader styling/layout issues
Estimated complexity: Low-Medium
Approach B: Choice Layout Improvements (Medium Change)
Make choice buttons more configurable without redesigning the conversation system.
New choiceProperties options:
layout:'inline'(current),'stack','grid'columns: number (for grid layout)uniformSize: boolean (all buttons same width/height)gap: size between buttonsalignment: already exists but expand options
Engine changes:
Choice.vue: Swapfloat: rightfor flexbox/grid based onlayoutproperty- Support uniform sizing via CSS grid with
1frcolumns
Frontend changes:
- New layout section in Choice configuration
- OptionList for layout mode, number input for columns
Pros: Makes choices much more flexible without major refactoring Cons: Still global per conversation (all choice sets styled the same)
Estimated complexity: Low-Medium
Approach C: Conversation Element Grouping (Larger Change)
Allow grouping of message + choices as a visual unit, similar to how block grouping works.
Concept: A "Question Group" that wraps a message step + choice step in a shared container with its own background, border, padding. Crucially, this must be a new clean wrapper -- NOT co1-scroll-content, which carries too much built-in logic (scroll behavior, overflow handling, padding resets) that causes unwanted side effects.
This requires:
- New data structure in flow: a grouping layer between liveFlow entries
- A new lightweight wrapper element (e.g.,
.conversation-group) with minimal default styles - CreativeConversationBlock to recognize grouped steps and wrap them in the new container
- Frontend flow editor: ability to select message + choices and group them
- Separate styling for the group container vs individual elements
Pros: Most flexible, enables complex layouts like "question cards" Cons: Significant complexity, touches flow data model
Estimated complexity: High
Approach B2: CSS Reset Toggle (Cross-Block)
Add a "reset styles" or "clean slate" toggle to conversation (and eventually all block types).
Concept: When enabled, the block renders with minimal default CSS -- no opinionated padding, margins, float, or layout rules. Designers start from a blank canvas and build up.
Engine changes:
- Each block type gets a
resetStylesboolean in its properties - When
true, a.css-resetclass is added to the block container .css-resetappliesall: unsetor targeted resets on child elements- Conversation: resets
co1-scroll-contentpadding,.choicesfloat,.message-wrapmargins
Frontend changes:
- Toggle in block configuration: "Clean slate" or "Reset default styles"
- Could live in the block's main config or in a shared "Advanced" section
Pros: Solves the "fighting defaults" problem for all blocks, not just conversation Cons: Needs careful scoping so resets don't break functionality (scroll, click handlers). Backward-compat: existing creatives must default to false
Estimated complexity: Medium
Approach D: Full Conversation Redesign (Major Change)
Rethink conversation as a modern layout container rather than a chat-style sequential flow.
Vision:
- Conversation steps become layout slots rather than just sequential chat bubbles
- Each "step" (message, choice set, response) can be positioned and styled independently
- Choices can have flex/grid layout with configurable gaps, alignment, sizing
- "Question cards" are native: message + choices + feedback in a styled container
- Quiz mode is a first-class feature, not a bolt-on
- Response behavior is configurable: hide, show inline, show in a specific location
This would touch:
MessageHolder.vue(or replace it)CreativeConversationBlock.vueChoice.vueconversationPropertiesdata modelconversationFlow.ts(flow progression)- Frontend configuration UI for conversation
Pros: Solves all current pain points, future-proof Cons: Largest effort, risk of regression in existing creatives
Estimated complexity: Very High
Recommendation
Start with A + B + B2, plan toward D.
A (quiz mode), B (choice layout), and B2 (CSS reset toggle) are independent changes that solve immediate pain points. They can ship quickly and don't conflict with a future redesign. B2 in particular benefits all block types long-term, not just conversation.
C (grouping) is interesting but adds complexity to the flow data model that might be obsoleted by a full redesign. The key insight: the wrapper must NOT be co1-scroll-content -- it needs to be a new lightweight container without the scroll/overflow logic.
D (full redesign) is the right long-term direction but needs its own design phase. The conversation block is the most-used feature and a redesign must be backward-compatible with all existing creatives.
Key Source Files
| File | Repo | Role |
|---|---|---|
src/components/blocks/basic/Choice.vue | Creative-Engine | Choice button rendering, click handling |
src/components/conversationflow/MessageHolder.vue | Creative-Engine | Wraps each flow step, manages input/response transition |
src/components/creative/CreativeConversationBlock/CreativeConversationBlock.vue | Creative-Engine | Iterates liveFlow, creates MessageHolders |
src/logic-system/processors/conversationFlow.ts | Creative-Engine | Flow step processing, progression |
src/logic-system/effect-modules/flowModifier.ts | Creative-Engine | Adds steps to liveFlow |
src/services/dataStore.ts | Creative-Engine | liveFlow reactive array, global state |
src/components/blocks/functional/Script.ts | Creative-Engine | Custom script execution |
src/components/blocks/functional/Reset.ts | Creative-Engine | Wipe operator (clears liveFlow) |
src/interfaces/jsonTypes/payload-v2/index.ts | Creative-Engine | ConversationProperties type definitions |
Related Documents
architecture/custom-scripts-tag-operator.md-- innerText vs textContent gotcha caused by responseProperties.hiddenarchitecture/unified-container-block-vision.md-- Future vision treating conversation as a ContainerBlocktodos/BlockGrouping/progress.md-- Container-in-Group support (conversation can live inside a Group block)