diff --git a/agents/coder_agent/MobileChartShell.tsx b/agents/coder_agent/MobileChartShell.tsx
new file mode 100644
index 0000000..50ee54f
--- /dev/null
+++ b/agents/coder_agent/MobileChartShell.tsx
@@ -0,0 +1,122 @@
+"use client";
+
+import {
+ Bar,
+ BarChart,
+ CartesianGrid,
+ Cell,
+ ComposedChart,
+ Legend,
+ Line,
+ LineChart,
+ Pie,
+ PieChart,
+ ResponsiveContainer,
+ Tooltip,
+ XAxis,
+ YAxis,
+} from "recharts";
+
+// [AGENT_ACTION]: INSERT DATA HERE
+// Expected format: array of objects
+const DATA = [
+ { name: "A", value: 400 },
+ { name: "B", value: 300 },
+ { name: "C", value: 300 },
+ { name: "D", value: 200 },
+];
+
+// [AGENT_ACTION]: CONFIGURE HEIGHT LOGIC
+// If the chart needs to scroll (e.g., many bars), set a threshold and calculate height.
+// Otherwise, use a fixed height (e.g., 300 or 400).
+const ROW_HEIGHT = 50;
+const SCROLL_THRESHOLD = 10;
+const isScrollable = DATA.length > SCROLL_THRESHOLD;
+const CHART_HEIGHT = isScrollable ? DATA.length * ROW_HEIGHT : 400;
+
+// [AGENT_ACTION]: DEFINE CUSTOM TOOLTIP IF NEEDED
+// interface CustomTooltipProps { ... }
+// const CustomTooltip = ({ active, payload, label }: CustomTooltipProps) => { ... }
+
+export default function MobileChartShell() {
+ return (
+ // [AGENT_ACTION]: PRESERVE UI SHELL STYLING
+
+ {/* Header Section */}
+
+ {/* [AGENT_ACTION]: INSERT TITLE */}
+
+ Chart Title
+
+ {/* [AGENT_ACTION]: INSERT DESCRIPTION */}
+
+ Chart description goes here. Explain what the user is seeing.
+
+
+
+ {/* Chart Container */}
+ {/* [AGENT_ACTION]: CONFIGURE CHART LAYOUT */}
+
+
+ {/* [AGENT_ACTION]: REPLACE WITH SPECIFIC CHART TYPE (BarChart, LineChart, PieChart, etc.) */}
+
+
+
+ {/* [AGENT_ACTION]: CONFIGURE AXES */}
+
+
+
+ }
+ />
+
+ {/* [AGENT_ACTION]: INSERT CHART ELEMENTS (Bar, Line, Pie, etc.) */}
+
+
+
+
+
+ {/* Footer / Legend / Scroll Hint */}
+
+ {/* [AGENT_ACTION]: INSERT LEGEND OR SCROLL HINT */}
+ {isScrollable ? (
+ Scroll for more data
+ ) : (
+ Data source: Source Name
+ )}
+
+
+ );
+}
diff --git a/agents/coder_agent/action_space.md b/agents/coder_agent/action_space.md
new file mode 100644
index 0000000..350d55f
--- /dev/null
+++ b/agents/coder_agent/action_space.md
@@ -0,0 +1,396 @@
+# Mobile Visualization Action Space (Agent Optimized)
+
+## Part 1: Component Taxonomy & DOM Heuristics
+| Component ID | Description | DOM Identification Strategies (Selector Hints) |
+| --- | --- | --- |
+| **L0_Container** | Root visualization container | `svg`, `div[role="graphics-document"]`, `.chart-container`, `.vis-wrapper` |
+| **L1_DataModel** | Data Transformation Layer (Aggregation, Filtering) | N/A (Internal Logic / Data State) |
+| **L1_Chart** | Individual chart in a multi-chart layout | `g.panel`, `g.facet`, `svg.small-multiple` |
+| **L1_Interaction** | Interaction controls and state | `div.tooltip`, `g.brush`, Mouse/Touch Event Listeners |
+| **L2_TitleBlock** | Block containing main title and subtitle | `g.title-group`, `text.chart-title`, `g[aria-label="title"]` |
+| **L2_CoordSys** | Coordinate system wrapper | `g.grid-layer`, `g.cartesian-layer` |
+| **L2_DataMarks** | The primary data visualization elements | `g.mark-layer`, `g.series-group`, `.bars`, `.lines`, `.scatter` |
+| **L2_Annotations** | Text annotations overlaid on chart | `g.annotation-group`, `text.annotation` |
+| **L3_Axes** | X or Y Axis container | `g.axis`, `g.x-axis`, `g.y-axis`, `g[role="graphics-axis"]` |
+| **L3_Legend** | Legend block container | `g.legend`, `.legend-wrapper`, `div.legend`, `g[role="complementary"]` |
+| **L4_Ticks** | Group of tick marks and labels | `g.tick`, `.tick` elements inside axis |
+| **L4_MarkInstance** | Individual geometric shapes (bars, points) | `rect.bar`, `circle.dot`, `path.line-segment` |
+| **L4_MarkLabel** | Labels attached to specific data marks | `text.bar-label`, `g.label-group` |
+| **L5_TickLabel** | Text labels on axes | `text` inside `g.tick`, `text.tick-label` |
+
+## Part 2: Planner Action Rules (Decision Matrix)
+
+### Level 0/1: Container & Data Strategies
+* **Component: L0_Container (Viewport)**
+ * **Condition**: `viewport_overflow == true` OR `content_width > screen_width` `(Source: DOM/Visual)`
+ * **Action**: `RESCALE_VIEWBOX`
+ * **Param Schema**: `{ "fit": "contain" | "cover", "width": string }`
+ * **Requires Data**: `[FALSE]`
+
+* **Component: L0_Container (Margins)**
+ * **Condition**: `whitespace_ratio > 0.3` `(Source: Visual)`
+ * **Action**: `REPOSITION_MARGINS`
+ * **Param Schema**: `{ "margin": number | string }`
+ * **Requires Data**: `[FALSE]`
+
+* **Component: L1_DataModel (Density)**
+ * **Condition**: `data_density > 30 points` AND `screen_width < 400px` `(Source: Data)`
+ * **Action**: `AGGREGATE_DATA`
+ * **Param Schema**: `{ "method": "avg" | "sum" | "count", "interval": "monthly" | "weekly" }`
+ * **Requires Data**: `[REQUIRES_DATA]`
+
+* **Component: L1_DataModel (Series)**
+ * **Condition**: `series_count > 5` AND `chart_type == "line"` `(Source: Data)`
+ * **Action**: `FILTER_SERIES`
+ * **Param Schema**: `{ "keep": "top_k", "k": number, "others": "gray" | "remove" }`
+ * **Requires Data**: `[REQUIRES_DATA]`
+
+* **Component: L1_Interaction**
+ * **Condition**: `device_type == "touch"` `(Source: Environment)`
+ * **Action**: `DISABLE_HOVER`
+ * **Param Schema**: `{ "fallback": "click" | "tap" }`
+ * **Requires Data**: `[FALSE]`
+
+* **Component: L1_Interaction (Widgets)**
+ * **Condition**: `screen_width < 600px` AND `has_widget == true` `(Source: DOM)`
+ * **Action**: `REMOVE_WIDGETS`
+ * **Param Schema**: `{ "target": "search" | "filter_dropdown", "fallback": "simple_toggle" }`
+ * **Requires Data**: `[FALSE]`
+
+* **Component: L1_Chart (Small Multiples)**
+ * **Condition**: `facet_layout == "grid"` AND `columns > 1` `(Source: DOM)`
+ * **Action**: `SERIALIZE_LAYOUT`
+ * **Param Schema**: `{ "columns": 1 }`
+ * **Requires Data**: `[FALSE]`
+
+* **Component: L1_Chart (Pagination)**
+ * **Condition**: `panel_count > 3` AND `vertical_space_constrained == true` `(Source: DOM)`
+ * **Action**: `PAGINATE_PANELS`
+ * **Param Schema**: `{ "page_size": 1, "control": "dots" | "arrows" }`
+ * **Requires Data**: `[FALSE]`
+
+* **Component: L1_Chart (Type Switching)**
+ * **Condition**: `chart_type == "bar"` AND `mark_density > 0.8` `(Source: Visual)`
+ * **Action**: `SWITCH_CHART_TYPE`
+ * **Param Schema**: `{ "to_type": "line" | "heatmap" | "list" }`
+ * **Requires Data**: `[REQUIRES_DATA]`
+
+### Level 2/3: Components & Layout
+* **Component: L2_TitleBlock (Title)**
+ * **Condition**: `title_width > screen_width - padding` `(Source: Visual)`
+ * **Action**: `RESCALE_FONT`
+ * **Param Schema**: `{ "target_size": string | number, "unit": "px" | "rem" }`
+ * **Requires Data**: `[FALSE]`
+
+* **Component: L2_TitleBlock (Subtitle)**
+ * **Condition**: `screen_width < 400px` `(Source: DOM)`
+ * **Action**: `REMOVE_SUBTITLE`
+ * **Param Schema**: `{}`
+ * **Requires Data**: `[FALSE]`
+
+* **Component: L2_Legend**
+ * **Condition**: `screen_width < 500px` AND `position == "right"` `(Source: DOM/Visual)`
+ * **Action**: `REPOSITION_LEGEND`
+ * **Param Schema**: `{ "target": "bottom" | "top", "layout": "flex_row" | "flex_col" }`
+ * **Requires Data**: `[FALSE]`
+
+* **Component: L2_Legend (Overflow)**
+ * **Condition**: `item_count > 10` AND `layout == "horizontal"` `(Source: DOM)`
+ * **Action**: `COMPENSATE_TOGGLE`
+ * **Param Schema**: `{ "widget": "dropdown" | "modal" | "accordion" }`
+ * **Requires Data**: `[FALSE]`
+
+* **Component: L2_Legend (Nuance)**
+ * **Condition**: `item_count > 5` AND `screen_width < 380px` `(Source: Data)`
+ * **Action**: `FILTER_LEGEND_ITEMS`
+ * **Param Schema**: `{ "keep": "top_k", "k": 3, "hide_corresponding_data": boolean }`
+ * **Requires Data**: `[REQUIRES_DATA]`
+
+* **Component: L2_DataMarks (Simplification)**
+ * **Condition**: `mark_type == "image"` AND `screen_width < 400px` `(Source: DOM)`
+ * **Action**: `SIMPLIFY_MARK`
+ * **Param Schema**: `{ "fallback_shape": "rect" | "circle", "keep_color": boolean }`
+ * **Requires Data**: `[FALSE]`
+
+* **Component: L2_DataMarks (Focus)**
+ * **Condition**: `data_density > 50` OR `user_intent == "focus"` `(Source: Visual/User)`
+ * **Action**: `GRAY_OUT_CONTEXT`
+ * **Param Schema**: `{ "trigger": "static" | "interactive", "opacity_ratio": 0.1 }`
+ * **Requires Data**: `[REQUIRES_DATA]`
+
+* **Component: L2_Annotations**
+ * **Condition**: `overlap_ratio > 0` `(Source: Visual)`
+ * **Action**: `EXTERNALIZE_ANNOTATIONS`
+ * **Param Schema**: `{ "position": "below" | "side", "link_style": "numbered" | "line" }`
+ * **Requires Data**: `[FALSE]`
+
+* **Component: L3_Axes (Structure)**
+ * **Condition**: `chart_type == "bar"` AND `x_axis_label_count > 10` AND `screen_width < 400px` `(Source: Code/DOM)`
+ * **Action**: `TRANSPOSE_CHART`
+ * **Param Schema**: `{ "swap_axes": boolean }`
+ * **Requires Data**: `[REQUIRES_DATA]`
+
+* **Component: L3_Axes (Noise Reduction)**
+ * **Condition**: `screen_width < 360px` `(Source: DOM)`
+ * **Action**: `REMOVE_AXIS_TITLE`
+ * **Param Schema**: `{ "axis": "y" | "x" | "both" }`
+ * **Requires Data**: `[FALSE]`
+
+* **Component: L3_Axes (Interaction)**
+ * **Condition**: `content_width > screen_width` AND `interaction_policy == "allow_scroll"` `(Source: Config)`
+ * **Action**: `ENABLE_PAN_ZOOM`
+ * **Param Schema**: `{ "axis": "x" | "y", "mode": "pan" | "zoom" }`
+ * **Requires Data**: `[FALSE]`
+
+* **Component: L3_Axes (Domain)**
+ * **Condition**: `has_outliers == true` AND `screen_width < 400px` `(Source: Data)`
+ * **Action**: `CROP_AXIS_DOMAIN`
+ * **Param Schema**: `{ "percentile": [5, 95], "max_crop_ratio": 0.2 }`
+ * **Requires Data**: `[REQUIRES_DATA]`
+
+* **Component: L3_Gridlines**
+ * **Condition**: `density > 0.5` OR `screen_width < 400px` `(Source: Visual)`
+ * **Action**: `REMOVE_GRIDLINES`
+ * **Param Schema**: `{ "axis": "x" | "both" }`
+ * **Requires Data**: `[FALSE]`
+
+* **Component: L3_Gridlines / L4_AxisLine / L5_TickLine (De-cluttering)**
+ * **Condition**: `ink_ratio > 0.1` AND `screen_width < 360px` `(Source: Visual)`
+ * **Action**: `REMOVE_DECORATIONS`
+ * **Param Schema**: `{ "targets": ["gridlines", "axis_line", "tick_line"] }`
+ * **Requires Data**: `[FALSE]`
+
+### Level 4/5: Marks & Ticks
+* **Component: L4_MarkInstance**
+ * **Condition**: `mark_overlap > 0` OR `mark_width > available_space` `(Source: Visual)`
+ * **Action**: `RESCALE_MARK_WIDTH`
+ * **Param Schema**: `{ "scale_factor": number, "min_width": number }`
+ * **Requires Data**: `[REQUIRES_DATA]`
+
+* **Component: L4_MarkLabel (Priority 1)**
+ * **Condition**: `label_width > mark_width` OR `overlap > 0` `(Source: Visual)`
+ * **Action**: `EXTERNALIZE_LABEL`
+ * **Param Schema**: `{ "position": "top" | "side" }`
+ * **Requires Data**: `[FALSE]`
+
+* **Component: L4_MarkLabel (Priority 2)**
+ * **Condition**: `external_space_available == false` `(Source: Visual)`
+ * **Action**: `REMOVE_LABEL`
+ * **Param Schema**: `{ "fallback": "tooltip" }`
+ * **Requires Data**: `[FALSE]`
+
+* **Component: L4_Ticks**
+ * **Condition**: `tick_overlap_predicted == true` `(Source: Visual)`
+ * **Action**: `DECIMATE_TICKS`
+ * **Param Schema**: `{ "target_count": number | "auto", "strategy": "uniform" | "extents_only" }`
+ * **Requires Data**: `[FALSE]`
+
+* **Component: L5_TickLabel**
+ * **Condition**: `text_overflow == true` OR `label_length > 8 chars` `(Source: Visual/DOM)`
+ * **Action**: `SIMPLIFY_LABEL`
+ * **Param Schema**: `{ "format": "abbreviate" | "truncate" | "rotate" | "date_format" }`
+ * **Requires Data**: `[FALSE]`
+
+* **Component: L5_LegendSymbol**
+ * **Condition**: `horizontal_space_constrained == true` `(Source: Visual)`
+ * **Action**: `RESCALE_LEGEND_SYMBOL`
+ * **Param Schema**: `{ "scale": 0.5 }`
+ * **Requires Data**: `[FALSE]`
+
+## Part 3: Coder Implementation Logic
+
+### 3.1 Structural Changes (SVG/XML Attributes)
+* **Action**: `TRANSPOSE_AXES`
+ * **Strategy**: Swap layout definitions. Map X-scale to Y-range and Y-scale to X-range.
+ * **Logic**:
+ $$
+ \text{Op}_{Transpose}(S_{LS}) \Rightarrow S_{SS} = \begin{cases}
+ \text{Axis}_{x} \leftarrow S_{LS}.\text{Axis}_{y} \\
+ \text{Axis}_{y} \leftarrow S_{LS}.\text{Axis}_{x} \\
+ \text{Range}_{x} \leftarrow [0, W_{screen}] \\
+ \text{Range}_{y} \leftarrow [0, \infty) \quad (\text{Scrollable})
+ \end{cases}
+ $$
+ * **Target**: SVG Attributes (`transform`, `d`, `x`, `y`)
+
+* **Action**: `SERIALIZE_LAYOUT`
+ * **Strategy**: Stack multiple chart panels vertically using a cumulative height offset.
+ * **Logic**:
+ $$
+ \text{Pos}_{SS}(i) = \left( 0, \sum_{k=0}^{i-1} (H_{\text{mark}} + H_{\text{padding}}) \right)
+ $$
+ * **Target**: SVG transforms (``)
+
+* **Action**: `DECIMATE_TICKS`
+ * **Strategy**: Calculate maximum possible ticks based on tick label width and screen width, then filter.
+ * **Logic**:
+ $$
+ N_{ticks} = \left\lfloor \frac{W_{screen}}{\text{Width}_{\text{label}} \times \alpha} \right\rfloor
+ $$
+ If `strategy == "extents_only"`, return `[min, max]`.
+ * **Target**: DOM Structure (Removes `` elements)
+
+* **Action**: `RESCALE_MARK_WIDTH`
+ * **Strategy**: Reduce width of geometrical marks (rects) while ensuring minimum touch target.
+ * **Constraint**: If $W_{new} < 40px$, create a transparent overlay rect ($W=40px$, opacity=0) to maintain interaction.
+ * **Target**: Attribute `width` or `r` + New Overlay DOM Element.
+
+* **Action**: `REMOVE_DECORATIONS`
+ * **Strategy**: Minimize "Data-Ink" ratio by hiding non-essential structural lines.
+ * **Logic**:
+ Set `stroke: none`, `display: none` or `opacity: 0`.
+ * **Target**: CSS/SVG Attributes on `.grid-line`, `.domain`, `.tick-line`.
+
+* **Action**: `REMOVE_WIDGETS`
+ * **Strategy**: Detect and hide complex HTML widgets that consume vertical space.
+ * **Logic**: `display: none`.
+ * **Target**: DOM containers (`.search-bar`, `.filter-panel`).
+
+### 3.2 Behavioral Changes (JS/Events Injection)
+* **Action**: `FIX_TOOLTIP_POSITION`
+ * **Strategy**: Inject script to override default mouse-follow behavior. Force tooltip to fixed coordinates on touch devices.
+ * **Logic**:
+ $$
+ P_{\text{tooltip}}(x, y) = \begin{cases}
+ (x_{\text{cursor}} + \delta, y_{\text{cursor}} + \delta) & \text{if Desktop (Hover)} \\
+ (W_{screen}/2, H_{screen} - H_{\text{tooltip}}) & \text{if Mobile (Touch)}
+ \end{cases}
+ $$
+ * **Target**: `