Skip to content

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, and responseProperties each 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 hidden property on responseProperties causes subtle bugs: visibility: hidden breaks innerText in custom scripts while the element still exists in DOM (see custom-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, inputEntered immediately 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 .choices container with float: right and 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 fit property (solelySingle etc.) 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 button

Key facts:

  • All choices for one question ARE in a single message-wrap (not separate wraps)
  • Choice buttons ARE in a single .choices div
  • Styling comes from conversationProperties.choiceProperties (global) + per-button blockStyles (overrides)
  • The Choice-to-Response transition is instant: inputEntered = true swaps 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: New quizMode prop. When enabled, doSelection() delays input-entered emission
  • During delay: apply CSS classes to buttons (.quiz-correct, .quiz-incorrect, .quiz-selected)
  • isGoal flag on flow components already marks the correct answer
  • After delay: emit input-entered + progress-flow as 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 buttons
  • alignment: already exists but expand options

Engine changes:

  • Choice.vue: Swap float: right for flexbox/grid based on layout property
  • Support uniform sizing via CSS grid with 1fr columns

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 resetStyles boolean in its properties
  • When true, a .css-reset class is added to the block container
  • .css-reset applies all: unset or targeted resets on child elements
  • Conversation: resets co1-scroll-content padding, .choices float, .message-wrap margins

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.vue
  • Choice.vue
  • conversationProperties data model
  • conversationFlow.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

FileRepoRole
src/components/blocks/basic/Choice.vueCreative-EngineChoice button rendering, click handling
src/components/conversationflow/MessageHolder.vueCreative-EngineWraps each flow step, manages input/response transition
src/components/creative/CreativeConversationBlock/CreativeConversationBlock.vueCreative-EngineIterates liveFlow, creates MessageHolders
src/logic-system/processors/conversationFlow.tsCreative-EngineFlow step processing, progression
src/logic-system/effect-modules/flowModifier.tsCreative-EngineAdds steps to liveFlow
src/services/dataStore.tsCreative-EngineliveFlow reactive array, global state
src/components/blocks/functional/Script.tsCreative-EngineCustom script execution
src/components/blocks/functional/Reset.tsCreative-EngineWipe operator (clears liveFlow)
src/interfaces/jsonTypes/payload-v2/index.tsCreative-EngineConversationProperties type definitions
  • architecture/custom-scripts-tag-operator.md -- innerText vs textContent gotcha caused by responseProperties.hidden
  • architecture/unified-container-block-vision.md -- Future vision treating conversation as a ContainerBlock
  • todos/BlockGrouping/progress.md -- Container-in-Group support (conversation can live inside a Group block)

Internal documentation