((set, get) =
// Fetch full artifact with content
const fullArtifact = await artifactService.getById(artifact.id);
- // Only fetch content as text for text-based types (not images/slides/PDFs)
+ // Only fetch content as text for text-based types (not images/PDFs)
const isTextType = ["research", "markdown", "html", "code"].includes(fullArtifact.content_type) ||
(fullArtifact.content_type === "document" && fullArtifact.mime_type?.startsWith("text/"));
diff --git a/apps/web/src/stores/right-sidebar-store.ts b/apps/web/src/stores/right-sidebar-store.ts
index f087e43e..00fffb6c 100644
--- a/apps/web/src/stores/right-sidebar-store.ts
+++ b/apps/web/src/stores/right-sidebar-store.ts
@@ -3,20 +3,14 @@ import { persist, createJSONStorage } from "zustand/middleware";
type SidebarVariant = "sidebar" | "floating";
-export type SlideImage = {
- id: string;
- thumb: string;
-};
-
export type ArtifactItem = {
id: string;
filename: string;
- contentType: string; // e.g., "slides", "document", "research"
- mimeType: string; // e.g., "application/vnd.openxmlformats-officedocument.presentationml.presentation", "text/markdown"
+ contentType: string; // e.g., "document", "research"
+ mimeType: string; // e.g., "text/markdown", "application/octet-stream"
size: number;
downloadUrl: string;
createdAt?: string;
- slidesImages?: SlideImage[];
content?: string; // markdown content for research artifacts
};
diff --git a/docs/configuration/env-var-mapping.md b/docs/configuration/env-var-mapping.md
index d4b04ef4..0ba8e13e 100644
--- a/docs/configuration/env-var-mapping.md
+++ b/docs/configuration/env-var-mapping.md
@@ -209,8 +209,6 @@ This document maps centralized configuration (`pkg/config/types.go`) environment
| `RESPONSE_TOOL_TIMEOUT` | duration | `45s` | `TOOL_TIMEOUT` | TODO Need prefix |
| `RESPONSE_LLM_DISABLE_CUSTOM_TEMPERATURE` | bool | `false` | `RESPONSE_LLM_DISABLE_CUSTOM_TEMPERATURE` | New |
| `RESPONSE_LLM_STREAM_MODE` | string | `auto` | `RESPONSE_LLM_STREAM_MODE` | New |
-| `SLIDE_RENDERER_SCRIPT` | string | (empty) | `SLIDE_RENDERER_SCRIPT` | New |
-| `SLIDE_RENDERER_ENABLED` | bool | `true` | `SLIDE_RENDERER_ENABLED` | New |
## Monitoring
diff --git a/infra/docker/apps-web.yml b/infra/docker/apps-web.yml
index 760e9802..e9cbf833 100644
--- a/infra/docker/apps-web.yml
+++ b/infra/docker/apps-web.yml
@@ -23,7 +23,7 @@ services:
ports:
- "${WEB_PORT:-3001}:3001"
healthcheck:
- test: ["CMD", "wget", "-q", "--spider", "http://localhost:3001/health"]
+ test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:3001/health"]
interval: 30s
timeout: 10s
retries: 3
diff --git a/services/llm-api/internal/domain/mcptool/mcp_tool.go b/services/llm-api/internal/domain/mcptool/mcp_tool.go
index 017725f5..e6c86335 100644
--- a/services/llm-api/internal/domain/mcptool/mcp_tool.go
+++ b/services/llm-api/internal/domain/mcptool/mcp_tool.go
@@ -63,7 +63,6 @@ const (
ToolKeyMemoryRetrieve = "memory_retrieve"
// Agent tools
- ToolKeySlideGenerate = "slide_generate"
ToolKeyDeepResearch = "deep_research"
ToolKeyArtifactCreate = "artifact_create"
ToolKeyArtifactUpdate = "artifact_update"
diff --git a/services/mcp-tools/internal/domain/generation/service.go b/services/mcp-tools/internal/domain/generation/service.go
deleted file mode 100644
index 1f5f6c69..00000000
--- a/services/mcp-tools/internal/domain/generation/service.go
+++ /dev/null
@@ -1,77 +0,0 @@
-package generation
-
-import (
- "context"
-)
-
-// GenerationClient defines the generation operations required by the domain layer.
-type GenerationClient interface {
- GenerateSlides(ctx context.Context, req SlideGenerationRequest) (*SlideGenerationResponse, error)
- DeepResearch(ctx context.Context, req DeepResearchRequest) (*DeepResearchResponse, error)
-}
-
-// GenerationService orchestrates content generation operations.
-type GenerationService struct {
- client GenerationClient
-}
-
-// NewGenerationService creates a new generation service.
-func NewGenerationService(client GenerationClient) *GenerationService {
- return &GenerationService{
- client: client,
- }
-}
-
-// GenerateSlides creates a slide presentation based on the request.
-func (s *GenerationService) GenerateSlides(ctx context.Context, req SlideGenerationRequest) (*SlideGenerationResponse, error) {
- // Apply defaults
- if req.SlideCount == nil {
- defaultCount := 10
- req.SlideCount = &defaultCount
- }
- if req.Theme == nil {
- defaultTheme := "professional"
- req.Theme = &defaultTheme
- }
- if req.AspectRatio == nil {
- defaultRatio := "16:9"
- req.AspectRatio = &defaultRatio
- }
- if req.IncludeNotes == nil {
- defaultNotes := true
- req.IncludeNotes = &defaultNotes
- }
- if req.Language == nil {
- defaultLang := "en"
- req.Language = &defaultLang
- }
-
- return s.client.GenerateSlides(ctx, req)
-}
-
-// DeepResearch performs deep research on a topic.
-func (s *GenerationService) DeepResearch(ctx context.Context, req DeepResearchRequest) (*DeepResearchResponse, error) {
- // Apply defaults
- if req.MaxSources == nil {
- defaultMax := 10
- req.MaxSources = &defaultMax
- }
- if req.SearchDepth == nil {
- defaultDepth := 2
- req.SearchDepth = &defaultDepth
- }
- if req.IncludeCitations == nil {
- defaultCitations := true
- req.IncludeCitations = &defaultCitations
- }
- if req.OutputFormat == nil {
- defaultFormat := "detailed"
- req.OutputFormat = &defaultFormat
- }
- if req.Language == nil {
- defaultLang := "en"
- req.Language = &defaultLang
- }
-
- return s.client.DeepResearch(ctx, req)
-}
diff --git a/services/mcp-tools/internal/domain/generation/types.go b/services/mcp-tools/internal/domain/generation/types.go
deleted file mode 100644
index 82d67df8..00000000
--- a/services/mcp-tools/internal/domain/generation/types.go
+++ /dev/null
@@ -1,109 +0,0 @@
-// Package generation provides types for content generation tools.
-package generation
-
-import "encoding/json"
-
-// SlideGenerationRequest represents a request to generate slides.
-type SlideGenerationRequest struct {
- Topic string `json:"topic"`
- SlideCount *int `json:"slide_count,omitempty"` // Target number of slides (default: 10)
- Theme *string `json:"theme,omitempty"` // Theme/style: "professional", "creative", "minimal"
- AspectRatio *string `json:"aspect_ratio,omitempty"` // "16:9", "4:3"
- IncludeNotes *bool `json:"include_notes,omitempty"` // Include speaker notes
- Outline []string `json:"outline,omitempty"` // Optional outline/structure
- SourceMaterial *string `json:"source_material,omitempty"` // Reference content
- Audience *string `json:"audience,omitempty"` // Target audience description
- Language *string `json:"language,omitempty"` // Language (default: "en")
- MaxContentDepth *int `json:"max_content_depth,omitempty"` // Level of detail (1-3)
-}
-
-// SlideGenerationResponse represents the result of slide generation.
-type SlideGenerationResponse struct {
- Slides []Slide `json:"slides"`
- Outline []string `json:"outline"`
- Theme string `json:"theme"`
- Title string `json:"title"`
- Subtitle *string `json:"subtitle,omitempty"`
- ArtifactID *string `json:"artifact_id,omitempty"` // If artifact was created
- Metadata json.RawMessage `json:"metadata,omitempty"`
-}
-
-// Slide represents a single slide in a presentation.
-type Slide struct {
- Index int `json:"index"`
- Title string `json:"title"`
- Content string `json:"content"`
- Layout SlideLayout `json:"layout"`
- SpeakerNotes *string `json:"speaker_notes,omitempty"`
- Images []SlideImage `json:"images,omitempty"`
- BulletPoints []string `json:"bullet_points,omitempty"`
-}
-
-// SlideLayout defines the layout type for a slide.
-type SlideLayout string
-
-const (
- LayoutTitle SlideLayout = "title"
- LayoutContent SlideLayout = "content"
- LayoutTwoColumn SlideLayout = "two_column"
- LayoutImageLeft SlideLayout = "image_left"
- LayoutImageRight SlideLayout = "image_right"
- LayoutImageFull SlideLayout = "image_full"
- LayoutQuote SlideLayout = "quote"
- LayoutBullets SlideLayout = "bullets"
- LayoutConclusion SlideLayout = "conclusion"
-)
-
-// SlideImage represents an image reference in a slide.
-type SlideImage struct {
- URL string `json:"url,omitempty"`
- Caption *string `json:"caption,omitempty"`
- AltText string `json:"alt_text"`
- Placeholder bool `json:"placeholder"` // True if image needs to be sourced
-}
-
-// DeepResearchRequest represents a request for deep research.
-type DeepResearchRequest struct {
- Query string `json:"query"`
- MaxSources *int `json:"max_sources,omitempty"` // Maximum sources to analyze (default: 10)
- SearchDepth *int `json:"search_depth,omitempty"` // Depth of research (1-3)
- IncludeCitations *bool `json:"include_citations,omitempty"` // Include source citations
- OutputFormat *string `json:"output_format,omitempty"` // "summary", "detailed", "outline"
- FocusAreas []string `json:"focus_areas,omitempty"` // Specific areas to focus on
- ExcludeDomains []string `json:"exclude_domains,omitempty"` // Domains to exclude
- IncludeDomains []string `json:"include_domains,omitempty"` // Domains to prefer
- TimeRange *string `json:"time_range,omitempty"` // "day", "week", "month", "year"
- Language *string `json:"language,omitempty"` // Language preference
-}
-
-// DeepResearchResponse represents the result of deep research.
-type DeepResearchResponse struct {
- Summary string `json:"summary"`
- Sections []ResearchSection `json:"sections"`
- Sources []ResearchSource `json:"sources"`
- KeyFindings []string `json:"key_findings"`
- RelatedTopics []string `json:"related_topics,omitempty"`
- WordCount int `json:"word_count"`
- SourceCount int `json:"source_count"`
- ArtifactID *string `json:"artifact_id,omitempty"`
- Metadata json.RawMessage `json:"metadata,omitempty"`
-}
-
-// ResearchSection represents a section in a research report.
-type ResearchSection struct {
- Title string `json:"title"`
- Content string `json:"content"`
- Sources []int `json:"sources"` // Indices into Sources array
- Subsections []ResearchSection `json:"subsections,omitempty"`
-}
-
-// ResearchSource represents a source used in research.
-type ResearchSource struct {
- Index int `json:"index"`
- URL string `json:"url"`
- Title string `json:"title"`
- Domain string `json:"domain"`
- Snippet *string `json:"snippet,omitempty"`
- PublishedAt *string `json:"published_at,omitempty"`
- Reliability *string `json:"reliability,omitempty"` // "high", "medium", "low"
-}
diff --git a/services/mcp-tools/internal/interfaces/httpserver/routes/mcp/agent_proxy_mcp.go b/services/mcp-tools/internal/interfaces/httpserver/routes/mcp/agent_proxy_mcp.go
index a7968673..e5e57bce 100644
--- a/services/mcp-tools/internal/interfaces/httpserver/routes/mcp/agent_proxy_mcp.go
+++ b/services/mcp-tools/internal/interfaces/httpserver/routes/mcp/agent_proxy_mcp.go
@@ -128,21 +128,6 @@ func (a *AgentProxyMCP) handleRunAgent(ctx context.Context, req *mcpsdk.CallTool
input.AgentType = input.Type
}
- if input.AgentType == "slide_creator" {
- if input.Options == nil {
- input.Options = map[string]interface{}{}
- }
- if _, ok := input.Options["num_slides"]; !ok {
- input.Options["num_slides"] = 5
- }
- if _, ok := input.Options["user_input"]; !ok {
- input.Options["user_input"] = input.Prompt
- }
- if _, ok := input.Options["topic"]; !ok {
- input.Options["topic"] = input.Prompt
- }
- }
-
log.Info().
Str("tool", "run_agent").
Str("agent_type", input.AgentType).
@@ -448,15 +433,7 @@ func (a *AgentProxyMCP) buildRunAgentDescription(agents []AgentMetadataCache) st
sb.WriteString("- type (required): The type of agent to run (alias: agent_type)\n")
sb.WriteString("- prompt (required): The task description for the agent\n")
sb.WriteString("- model (optional): The model to use. If not provided, uses the first available model\n")
- sb.WriteString("- options (optional): Agent-specific options (e.g., research_depth, num_slides, format)\n")
- sb.WriteString("\nIf type is slide_creator, require and provide in options:\n")
- sb.WriteString("- topic: summarized topic for the deck\n")
- sb.WriteString("- tone: template tone (must be one of the predefined tones)\n")
- sb.WriteString("- num_slides: target number of slides (default: 5)\n")
- sb.WriteString("- user_input: original user prompt (must match user request)\n")
- sb.WriteString("Available slide_creator tones:\n- ")
- sb.WriteString(strings.Join(slideCreatorTones, "\n- "))
- sb.WriteString("\n")
+ sb.WriteString("- options (optional): Agent-specific options (e.g., research_depth, format)\n")
sb.WriteString("Available agents:\n")
for _, agent := range agents {
@@ -468,38 +445,6 @@ func (a *AgentProxyMCP) buildRunAgentDescription(agents []AgentMetadataCache) st
return sb.String()
}
-var slideCreatorTones = []string{
- "Corporate Consulting",
- "Creative Studio",
- "Data Analyst",
- "Editorial Serif",
- "Education Friendly",
- "Finance Professional",
- "Government/Public Sector",
- "Gradient Modern",
- "Healthcare Calm",
- "Luxury Elegant",
- "Marketing Vibrant",
- "Minimal Clean",
- "Monochrome",
- "Neon Cyberpunk",
- "Playful Pastel",
- "Retro",
- "Sports/Energy",
- "Startup Bold",
- "Sustainability Earthy",
- "Tech Dark",
-}
-
-func isSlideCreatorTone(tone string) bool {
- for _, candidate := range slideCreatorTones {
- if tone == candidate {
- return true
- }
- }
- return false
-}
-
func isAgentDisabled(agentType string) bool {
_, disabled := disabledAgentTypes[strings.TrimSpace(agentType)]
return disabled
@@ -544,17 +489,6 @@ func (a *AgentProxyMCP) getDefaultAgents() []AgentMetadataCache {
UseWhen: "User wants to research, investigate, analyze, or learn about a topic in depth",
Enabled: true,
},
- {
- Type: "slide_creator",
- Name: "Slide Creator Agent",
- Description: "Builds HTML-based slide decks and exports them to editable PPTX with research-backed content",
- Keywords: []string{"slides", "presentation", "powerpoint", "deck", "pitch"},
- Capabilities: []string{"research", "outline", "html_slide_generation", "template_selection", "pptx_export"},
- OutputFormats: []string{"pptx", "html"},
- EstimatedDuration: "3-15 minutes",
- UseWhen: "User wants an editable PPTX generated from HTML slide layouts with template control",
- Enabled: true,
- },
}
}
diff --git a/services/media-api/internal/interfaces/httpserver/routes/v1/routes.go b/services/media-api/internal/interfaces/httpserver/routes/v1/routes.go
index 7b58d85b..c09248f7 100644
--- a/services/media-api/internal/interfaces/httpserver/routes/v1/routes.go
+++ b/services/media-api/internal/interfaces/httpserver/routes/v1/routes.go
@@ -32,9 +32,8 @@ func (r *Routes) Register(router gin.IRouter) {
group.GET("/files/:id", r.handlers.Media.Proxy)
group.GET("/files/:id/metadata", r.handlers.Media.GetMetadata)
- // Serve static files from local storage if configured
- if r.cfg.IsLocalStorage() && r.cfg.LocalStoragePath != "" {
- // Strip /v1 prefix and serve files from /v1/files/*
- group.Static("/files", r.cfg.LocalStoragePath)
- }
+ // NOTE: Local files are served by ID through the Proxy handler above
+ // (GET /v1/files/:id -> service.Download). A path-based gin Static mount at
+ // "/files" registers "/v1/files/*filepath", which conflicts with the
+ // "/v1/files/:id" route and panics at startup, so it is intentionally omitted.
}
diff --git a/services/response-api/README.md b/services/response-api/README.md
index 8d90abb8..d41fa416 100644
--- a/services/response-api/README.md
+++ b/services/response-api/README.md
@@ -480,11 +480,11 @@ jobs:
## Agent Response System
-The Response API includes an advanced agent response system for orchestrating multi-step AI workflows like deep research and slide generation.
+The Response API includes an advanced agent response system for orchestrating multi-step AI workflows like deep research and document generation.
### Plans and Tasks
-When processing complex requests that require multiple steps (e.g., researching a topic, generating slides), the service creates an execution **Plan** consisting of:
+When processing complex requests that require multiple steps (e.g., researching a topic, generating a document), the service creates an execution **Plan** consisting of:
- **Tasks**: High-level work units (search, analyze, generate, etc.)
- **Steps**: Individual operations within each task
@@ -514,7 +514,7 @@ When processing complex requests that require multiple steps (e.g., researching
### Artifacts
-Plans can produce **Artifacts** - structured output files like slide decks, research documents, or code files.
+Plans can produce **Artifacts** - structured output files like research documents, spreadsheets, or code files.
| Endpoint | Method | Description |
| --------------------------------------------- | ------ | ---------------------------------- |
@@ -527,7 +527,6 @@ Plans can produce **Artifacts** - structured output files like slide decks, rese
### Artifact Content Types
-- `slides`: Presentation slides (JSON structure)
- `document`: Research documents, reports
- `image`: Generated images
- `code`: Code files
diff --git a/services/response-api/assets/slide_creator/embedded.go b/services/response-api/assets/slide_creator/embedded.go
deleted file mode 100644
index 287232bd..00000000
--- a/services/response-api/assets/slide_creator/embedded.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package slidecreator
-
-import _ "embed"
-
-// ExportPPTXFullScript embeds export_pptx_full.js for PPTX export.
-//
-//go:embed export_pptx_full.js
-var ExportPPTXFullScript string
diff --git a/services/response-api/assets/slide_creator/export_pptx_full.js b/services/response-api/assets/slide_creator/export_pptx_full.js
deleted file mode 100644
index 81663d18..00000000
--- a/services/response-api/assets/slide_creator/export_pptx_full.js
+++ /dev/null
@@ -1,510 +0,0 @@
-const fs = require('fs');
-const path = require('path');
-
-/**
- * HTML -> PPTX exporter
- *
- * Modes:
- * --mode dom : Convert rendered HTML DOM into an *editable* PPTX (text boxes/shapes/images)
- * using a client-side converter injected into Playwright.
- * --mode raster : Screenshot HTML slides into PNGs (not editable) and place full-bleed in PPTX.
- * Optional: overlay PPTX-native charts (bar/line/pie) on top of the raster slide.
- * --mode auto : Prefer dom if slide HTML exists, otherwise raster.
- *
- * Why this exists:
- * The current "screenshot" approach preserves visuals but produces a non-editable PPTX.
- * DOM conversion rebuilds the slide as PPTX objects so you can edit text/images in PowerPoint.
- */
-
-async function main() {
- const args = process.argv.slice(2);
- const inputDir = getArg(args, '--in', 'output');
- const outFile = getArg(args, '--out', 'deck.pptx');
- const modeArg = (getArg(args, '--mode', 'auto') || 'auto').toLowerCase();
-
- const vw = toInt(getArg(args, '--vw', '1920'), 1920);
- const vh = toInt(getArg(args, '--vh', '1080'), 1080);
- const rootSelector = getArg(args, '--root', 'body > div');
-
- // dom-to-pptx bundle source (pick one)
- const domBundlePath = getArg(args, '--domjs', '');
- const domBundleUrl = getArg(
- args,
- '--domurl',
- 'https://cdn.jsdelivr.net/npm/dom-to-pptx@latest/dist/dom-to-pptx.bundle.js'
- );
-
- // Raster quality scale (higher = sharper, larger files)
- const rasterScale = toNumber(getArg(args, '--scale', '2'), 2);
- const chartsArg = getArg(args, '--charts', '');
-
- if (!fs.existsSync(inputDir)) {
- throw new Error(`Input directory not found: ${inputDir}`);
- }
-
- const htmlFiles = listSlideHtmlFiles(inputDir);
- if (htmlFiles.length === 0) {
- throw new Error(`No slide-*.html files found in ${inputDir}`);
- }
-
- let mode = modeArg;
- if (mode === 'auto') {
- // If you have HTML slides, default to DOM conversion (editable) instead of raster.
- mode = htmlFiles.length > 0 ? 'dom' : 'raster';
- }
-
- const chartsPath = chartsArg || path.join(inputDir, 'charts.json');
- const chartsById = loadCharts(chartsPath);
- if (chartsById && mode !== 'raster') {
- console.warn(
- 'Chart overlay is only supported in raster mode. Use --mode raster to apply PPTX-native charts.'
- );
- }
-
- ensureParentDir(outFile);
-
- if (mode === 'dom') {
- await exportDomEditable({
- inputDir,
- htmlFiles,
- outFile,
- vw,
- vh,
- rootSelector,
- domBundlePath,
- domBundleUrl,
- });
- return;
- }
-
- if (mode === 'raster') {
- await exportRaster({
- inputDir,
- htmlFiles,
- outFile,
- vw,
- vh,
- rootSelector,
- rasterScale,
- chartsById,
- });
- return;
- }
-
- throw new Error(`Unknown --mode "${modeArg}". Use: auto | dom | raster`);
-}
-
-function listSlideHtmlFiles(inputDir) {
- return fs
- .readdirSync(inputDir)
- .filter((f) => /^slide-\d+\.html$/i.test(f))
- .sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
-}
-
-function ensureParentDir(outFile) {
- const dir = path.dirname(path.resolve(outFile));
- if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
-}
-
-function getArg(args, key, fallback) {
- const idx = args.indexOf(key);
- if (idx === -1) return fallback;
- const val = args[idx + 1];
- if (!val || val.startsWith('--')) return fallback;
- return val;
-}
-
-function toNumber(val, fallback) {
- const n = Number(val);
- return Number.isFinite(n) ? n : fallback;
-}
-
-function toInt(val, fallback) {
- const n = Number.parseInt(String(val), 10);
- return Number.isFinite(n) ? n : fallback;
-}
-
-
-function loadCharts(chartsPath) {
- if (!chartsPath || !fs.existsSync(chartsPath)) return null;
- try {
- const raw = fs.readFileSync(chartsPath, 'utf-8');
- const parsed = JSON.parse(raw);
- const slides = Array.isArray(parsed) ? parsed : parsed.slides || [];
- const byId = {};
- for (const item of slides) {
- if (!item || typeof item !== 'object') continue;
- const id = Number(item.id);
- if (!Number.isFinite(id) || id <= 0) continue;
- byId[id] = item;
- }
- return Object.keys(byId).length ? byId : null;
- } catch (err) {
- console.warn(`Failed to parse charts JSON: ${chartsPath}`, err.message || err);
- return null;
- }
-}
-
-function slideIdFromFile(file) {
- const match = /slide-(\d+)\.html/i.exec(file);
- if (!match) return 0;
- return Number(match[1]);
-}
-
-function buildPptxChart(chartCfg, pptx, { vw, vh }) {
- if (!chartCfg || !chartCfg.type || !chartCfg.series) return null;
-
- const type = chartTypeFromString(chartCfg.type, pptx);
- if (!type) return null;
-
- const series = Array.isArray(chartCfg.series) ? chartCfg.series : [];
- if (series.length === 0) return null;
-
- const categories =
- chartCfg.categories ||
- chartCfg.labels ||
- (series[0] ? series[0].labels || series[0].categories : null);
-
- const maxLen = Math.max(
- 0,
- ...series.map((s) => (Array.isArray(s.values) ? s.values.length : 0))
- );
- const fallbackLabels = Array.from({ length: maxLen }, (_, i) => `${i + 1}`);
-
- const data = series.map((s, idx) => ({
- name: s.name || `Series ${idx + 1}`,
- labels: categories || fallbackLabels,
- values: Array.isArray(s.values) ? s.values : [],
- }));
-
- const pos = normalizeChartPosition(chartCfg.position, { vw, vh });
- const options = {
- x: pos.x,
- y: pos.y,
- w: pos.w,
- h: pos.h,
- showLegend: chartCfg.showLegend !== false,
- };
- if (chartCfg.title) {
- options.title = chartCfg.title;
- }
-
- return { type, data, options };
-}
-
-function chartTypeFromString(type, pptx) {
- const t = String(type || '').toLowerCase();
- if (t === 'bar' || t === 'column') return pptx.ChartType.bar;
- if (t === 'line') return pptx.ChartType.line;
- if (t === 'pie') return pptx.ChartType.pie;
- return null;
-}
-
-function normalizeChartPosition(position, { vw, vh }) {
- const fallback = { x: 1.1, y: 1.3, w: 11.2, h: 5.3 };
- if (!position || typeof position !== 'object') return fallback;
-
- const units = String(position.units || '').toLowerCase();
- if (units === 'px') {
- const toIn = (val, totalPx, totalIn) =>
- Number.isFinite(val) ? (val / totalPx) * totalIn : null;
- const x = toIn(position.x, vw, 13.333);
- const y = toIn(position.y, vh, 7.5);
- const w = toIn(position.w, vw, 13.333);
- const h = toIn(position.h, vh, 7.5);
- return {
- x: x ?? fallback.x,
- y: y ?? fallback.y,
- w: w ?? fallback.w,
- h: h ?? fallback.h,
- };
- }
-
- const toNum = (v) => (Number.isFinite(v) ? v : null);
- return {
- x: toNum(position.x) ?? fallback.x,
- y: toNum(position.y) ?? fallback.y,
- w: toNum(position.w) ?? fallback.w,
- h: toNum(position.h) ?? fallback.h,
- };
-}
-
-async function exportRaster({ inputDir, htmlFiles, outFile, vw, vh, rootSelector, rasterScale, chartsById }) {
- const pptxgen = require('pptxgenjs');
- const { chromium } = require('playwright');
-
- const pptx = new pptxgen();
- pptx.layout = 'LAYOUT_WIDE';
- const outDir = path.dirname(path.resolve(outFile));
-
- const browser = await chromium.launch();
- const context = await browser.newContext({
- viewport: { width: vw, height: vh },
- deviceScaleFactor: Math.max(1, rasterScale),
- });
- const page = await context.newPage();
-
- for (let i = 0; i < htmlFiles.length; i += 1) {
- const file = htmlFiles[i];
- const slideId = slideIdFromFile(file);
- const fullPath = path.resolve(inputDir, file);
- await page.goto(`file://${fullPath}`, { waitUntil: 'load' });
- await waitForFontsAndImages(page);
-
- const container = await page.$(rootSelector);
- if (!container) throw new Error(`No slide root found with selector "${rootSelector}" in ${file}`);
-
- const box = await container.boundingBox();
- if (!box) throw new Error(`Failed to get bounding box for ${file}`);
- const slide = pptx.addSlide();
-
- const chartCfg = chartsById ? chartsById[slideId] : null;
- const overlayChart = !!(chartCfg && chartCfg.overlay !== false);
- const image = await page.screenshot({
- type: 'png',
- clip: {
- x: Math.max(0, Math.floor(box.x)),
- y: Math.max(0, Math.floor(box.y)),
- width: Math.max(1, Math.floor(box.width)),
- height: Math.max(1, Math.floor(box.height)),
- },
- });
- const imageName = `slide-${slideId || i + 1}.png`;
- const imagePath = path.join(outDir, imageName);
- fs.writeFileSync(imagePath, image);
-
- if (!chartCfg || overlayChart) {
- slide.addImage({
- data: `image/png;base64,${image.toString('base64')}` ,
- x: 0,
- y: 0,
- w: 13.333,
- h: 7.5,
- });
- }
-
- if (chartCfg) {
- const chart = buildPptxChart(chartCfg, pptx, { vw, vh });
- if (chart) {
- slide.addChart(chart.type, chart.data, chart.options);
- }
- }
- }
-
- await browser.close();
- await pptx.writeFile({ fileName: outFile });
- console.log(`Wrote ${outFile} (raster)`);
-}
-
-async function exportDomEditable({
- inputDir,
- htmlFiles,
- outFile,
- vw,
- vh,
- rootSelector,
- domBundlePath,
- domBundleUrl,
-}) {
- const { chromium } = require('playwright');
- const outDir = path.dirname(path.resolve(outFile));
-
- // 1) Load each slide file to normalize resources (absolute , fixed root size, etc.)
- // 2) Assemble all slide roots into one "deck" page
- // 3) Inject dom-to-pptx and export multi-slide PPTX
-
- const browser = await chromium.launch();
- const context = await browser.newContext({
- viewport: { width: vw, height: vh },
- acceptDownloads: true,
- });
- const page = await context.newPage();
-
- const slideOuterHtml = [];
-
- for (let i = 0; i < htmlFiles.length; i += 1) {
- const file = htmlFiles[i];
- const slideId = slideIdFromFile(file) || i + 1;
- const fullPath = path.resolve(inputDir, file);
- await page.goto(`file://${fullPath}`, { waitUntil: 'load' });
- await waitForFontsAndImages(page);
-
- const root = await page.$(rootSelector);
- if (!root) throw new Error(`No slide root found with selector "${rootSelector}" in ${file}`);
-
- // Normalize: lock the slide root to a deterministic 1920x1080 (or --vw/--vh)
- // and convert any relative image src -> absolute URL.
- await page.evaluate(
- ({ rootSelector, vw, vh }) => {
- const root = document.querySelector(rootSelector);
- if (!root) return;
-
- // Force deterministic size (dom-to-pptx recommends building at 1920x1080)
- root.style.width = `${vw}px`;
- root.style.height = `${vh}px`;
- root.style.maxWidth = `${vw}px`;
-
- // Make image URLs absolute + enable CORS-friendly loading.
- root.querySelectorAll('img').forEach((img) => {
- try {
- img.setAttribute('src', img.src);
- } catch (_) {
- // ignore
- }
- if (!img.getAttribute('crossorigin')) {
- img.setAttribute('crossorigin', 'anonymous');
- }
- });
- },
- { rootSelector, vw, vh }
- );
-
- try {
- const box = await root.boundingBox();
- if (box) {
- const image = await page.screenshot({
- type: 'png',
- clip: {
- x: Math.max(0, Math.floor(box.x)),
- y: Math.max(0, Math.floor(box.y)),
- width: Math.max(1, Math.floor(box.width)),
- height: Math.max(1, Math.floor(box.height)),
- },
- });
- const imageName = `slide-${slideId}.png`;
- fs.writeFileSync(path.join(outDir, imageName), image);
- }
- } catch (err) {
- const message = err && err.message ? err.message : err;
- console.warn(`Failed to capture slide preview for ${file}:`, message);
- }
-
- const outer = await page.$eval(rootSelector, (el) => el.outerHTML);
- slideOuterHtml.push(outer);
- }
-
- // Build a single page containing all slides as separate DOM roots.
- const deckHtml = buildDeckHtml(slideOuterHtml, { vw, vh });
- await page.setContent(deckHtml, { waitUntil: 'load' });
- await waitForFontsAndImages(page);
-
- // Inject dom-to-pptx bundle
- if (domBundlePath && fs.existsSync(domBundlePath)) {
- await page.addScriptTag({ path: path.resolve(domBundlePath) });
- } else {
- // Falls back to CDN (requires internet)
- await page.addScriptTag({ url: domBundleUrl });
- }
-
- // Wait for the global to appear (script-tag usage exposes `domToPptx`).
- await page.waitForFunction(() => !!window.domToPptx && !!window.domToPptx.exportToPptx, null, {
- timeout: 60_000,
- });
-
- // Prefer capturing the browser download (avoids shipping a huge Blob through Playwright RPC)
- const outName = path.basename(outFile);
-
- const download = await Promise.race([
- // Trigger export + wait for download
- (async () => {
- const [dl] = await Promise.all([
- page.waitForEvent('download', { timeout: 180_000 }),
- page.evaluate(async (outName) => {
- const nodes = Array.from(document.querySelectorAll('.pptx-slide'));
- if (!nodes.length) throw new Error('No .pptx-slide nodes found');
- // skipDownload=false (default) should trigger a file download
- await window.domToPptx.exportToPptx(nodes, { fileName: outName });
- }, outName),
- ]);
- return dl;
- })(),
- // If download path fails for any reason, fall back to Blob-return mode.
- (async () => {
- // short delay to let download race win when supported
- await new Promise((r) => setTimeout(r, 1000));
- return null;
- })(),
- ]);
-
- if (download) {
- await download.saveAs(outFile);
- await browser.close();
- console.log(`Wrote ${outFile} (dom, editable)`);
- return;
- }
-
- // Fallback: get Blob back and write it
- const b64 = await page.evaluate(async (outName) => {
- const nodes = Array.from(document.querySelectorAll('.pptx-slide'));
- if (!nodes.length) throw new Error('No .pptx-slide nodes found');
-
- const blob = await window.domToPptx.exportToPptx(nodes, {
- fileName: outName,
- skipDownload: true,
- });
-
- const ab = await blob.arrayBuffer();
- const bytes = new Uint8Array(ab);
-
- // Convert to base64 in chunks to avoid call-stack limits.
- let binary = '';
- const chunk = 0x8000;
- for (let i = 0; i < bytes.length; i += chunk) {
- binary += String.fromCharCode.apply(null, bytes.subarray(i, i + chunk));
- }
- return btoa(binary);
- }, outName);
-
- fs.writeFileSync(outFile, Buffer.from(b64, 'base64'));
- await browser.close();
- console.log(`Wrote ${outFile} (dom, editable)`);
-}
-
-function buildDeckHtml(slideOuterHtml, { vw, vh }) {
- // Keep the DOM simple: each slide root is wrapped in a predictable container.
- // The wrapper is what we pass to dom-to-pptx.
- const slides = slideOuterHtml
- .map(
- (outer, i) =>
- `${outer}
`
- )
- .join('\n');
-
- return `
-
-
-
-
-
-
-
- ${slides}
-
-
-`;
-}
-
-async function waitForFontsAndImages(page) {
- // Fonts
- try {
- await page.evaluate(() => (document.fonts ? document.fonts.ready : Promise.resolve()));
- } catch (_) {
- // ignore
- }
-
- // Images
- try {
- await page.waitForFunction(
- () => Array.from(document.images || []).every((img) => img.complete),
- null,
- { timeout: 60_000 }
- );
- } catch (_) {
- // ignore; we still export even if some images didn't load
- }
-}
-
-main().catch((err) => {
- console.error(err?.stack || err?.message || String(err));
- process.exit(1);
-});
diff --git a/services/response-api/assets/slide_creator/templates/1/base.html b/services/response-api/assets/slide_creator/templates/1/base.html
deleted file mode 100644
index a3388e2b..00000000
--- a/services/response-api/assets/slide_creator/templates/1/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/1/bullets.html b/services/response-api/assets/slide_creator/templates/1/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/1/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/1/chart.html b/services/response-api/assets/slide_creator/templates/1/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/1/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/1/hero.html b/services/response-api/assets/slide_creator/templates/1/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/1/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/1/llm.html b/services/response-api/assets/slide_creator/templates/1/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/1/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/1/meta.json b/services/response-api/assets/slide_creator/templates/1/meta.json
deleted file mode 100644
index ffe31a08..00000000
--- a/services/response-api/assets/slide_creator/templates/1/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 1,
- "dir": "1",
- "name": "Neon City",
- "tone": "Neon Cyberpunk",
- "description": "Aurora glows + high-energy composition for futuristic themes.",
- "variants": {
- "base": 1,
- "bullets": 1,
- "split": 1,
- "hero": 1,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/1/split.html b/services/response-api/assets/slide_creator/templates/1/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/1/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/1/table.html b/services/response-api/assets/slide_creator/templates/1/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/1/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/1/title.html b/services/response-api/assets/slide_creator/templates/1/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/1/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/10/base.html b/services/response-api/assets/slide_creator/templates/10/base.html
deleted file mode 100644
index cbd839f2..00000000
--- a/services/response-api/assets/slide_creator/templates/10/base.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/10/bullets.html b/services/response-api/assets/slide_creator/templates/10/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/10/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/10/chart.html b/services/response-api/assets/slide_creator/templates/10/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/10/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/10/hero.html b/services/response-api/assets/slide_creator/templates/10/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/10/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/10/llm.html b/services/response-api/assets/slide_creator/templates/10/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/10/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/10/meta.json b/services/response-api/assets/slide_creator/templates/10/meta.json
deleted file mode 100644
index cb5ffc00..00000000
--- a/services/response-api/assets/slide_creator/templates/10/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 10,
- "dir": "10",
- "name": "Mono Minimal",
- "tone": "Minimal Clean",
- "description": "Whitespace-forward, neutral framing, restrained accents.",
- "variants": {
- "base": 2,
- "bullets": 5,
- "split": 1,
- "hero": 2,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/10/split.html b/services/response-api/assets/slide_creator/templates/10/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/10/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/10/table.html b/services/response-api/assets/slide_creator/templates/10/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/10/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/10/title.html b/services/response-api/assets/slide_creator/templates/10/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/10/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/100/base.html b/services/response-api/assets/slide_creator/templates/100/base.html
deleted file mode 100644
index 1608815d..00000000
--- a/services/response-api/assets/slide_creator/templates/100/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/100/bullets.html b/services/response-api/assets/slide_creator/templates/100/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/100/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/100/chart.html b/services/response-api/assets/slide_creator/templates/100/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/100/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/100/hero.html b/services/response-api/assets/slide_creator/templates/100/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/100/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/100/llm.html b/services/response-api/assets/slide_creator/templates/100/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/100/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/100/meta.json b/services/response-api/assets/slide_creator/templates/100/meta.json
deleted file mode 100644
index 57406a01..00000000
--- a/services/response-api/assets/slide_creator/templates/100/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 100,
- "dir": "100",
- "name": "High Energy",
- "tone": "Sports/Energy",
- "description": "Bold band framing; dynamic pacing and clear takeaways.",
- "variants": {
- "base": 4,
- "bullets": 5,
- "split": 4,
- "hero": 2,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/100/split.html b/services/response-api/assets/slide_creator/templates/100/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/100/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/100/table.html b/services/response-api/assets/slide_creator/templates/100/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/100/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/100/title.html b/services/response-api/assets/slide_creator/templates/100/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/100/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/11/base.html b/services/response-api/assets/slide_creator/templates/11/base.html
deleted file mode 100644
index 982ae99a..00000000
--- a/services/response-api/assets/slide_creator/templates/11/base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/11/bullets.html b/services/response-api/assets/slide_creator/templates/11/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/11/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/11/chart.html b/services/response-api/assets/slide_creator/templates/11/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/11/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/11/hero.html b/services/response-api/assets/slide_creator/templates/11/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/11/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/11/llm.html b/services/response-api/assets/slide_creator/templates/11/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/11/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/11/meta.json b/services/response-api/assets/slide_creator/templates/11/meta.json
deleted file mode 100644
index 0d8f0d95..00000000
--- a/services/response-api/assets/slide_creator/templates/11/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 11,
- "dir": "11",
- "name": "Consulting Edge",
- "tone": "Corporate Consulting",
- "description": "Executive framing, clear hierarchy, client-ready polish.",
- "variants": {
- "base": 9,
- "bullets": 1,
- "split": 3,
- "hero": 1,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/11/split.html b/services/response-api/assets/slide_creator/templates/11/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/11/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/11/table.html b/services/response-api/assets/slide_creator/templates/11/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/11/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/11/title.html b/services/response-api/assets/slide_creator/templates/11/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/11/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/12/base.html b/services/response-api/assets/slide_creator/templates/12/base.html
deleted file mode 100644
index 982ae99a..00000000
--- a/services/response-api/assets/slide_creator/templates/12/base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/12/bullets.html b/services/response-api/assets/slide_creator/templates/12/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/12/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/12/chart.html b/services/response-api/assets/slide_creator/templates/12/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/12/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/12/hero.html b/services/response-api/assets/slide_creator/templates/12/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/12/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/12/llm.html b/services/response-api/assets/slide_creator/templates/12/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/12/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/12/meta.json b/services/response-api/assets/slide_creator/templates/12/meta.json
deleted file mode 100644
index f0d4a2dd..00000000
--- a/services/response-api/assets/slide_creator/templates/12/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 12,
- "dir": "12",
- "name": "Boardroom Brief",
- "tone": "Corporate Consulting",
- "description": "Executive framing, clear hierarchy, client-ready polish.",
- "variants": {
- "base": 9,
- "bullets": 2,
- "split": 4,
- "hero": 2,
- "title": 2
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/12/split.html b/services/response-api/assets/slide_creator/templates/12/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/12/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/12/table.html b/services/response-api/assets/slide_creator/templates/12/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/12/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/12/title.html b/services/response-api/assets/slide_creator/templates/12/title.html
deleted file mode 100644
index e4e39fb6..00000000
--- a/services/response-api/assets/slide_creator/templates/12/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
Slide {{.Index}} / {{.Total}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/13/base.html b/services/response-api/assets/slide_creator/templates/13/base.html
deleted file mode 100644
index 982ae99a..00000000
--- a/services/response-api/assets/slide_creator/templates/13/base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/13/bullets.html b/services/response-api/assets/slide_creator/templates/13/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/13/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/13/chart.html b/services/response-api/assets/slide_creator/templates/13/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/13/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/13/hero.html b/services/response-api/assets/slide_creator/templates/13/hero.html
deleted file mode 100644
index dafda5d3..00000000
--- a/services/response-api/assets/slide_creator/templates/13/hero.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 150}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/13/llm.html b/services/response-api/assets/slide_creator/templates/13/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/13/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/13/meta.json b/services/response-api/assets/slide_creator/templates/13/meta.json
deleted file mode 100644
index 6514d4a3..00000000
--- a/services/response-api/assets/slide_creator/templates/13/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 13,
- "dir": "13",
- "name": "Executive Slate",
- "tone": "Corporate Consulting",
- "description": "Executive framing, clear hierarchy, client-ready polish.",
- "variants": {
- "base": 9,
- "bullets": 3,
- "split": 5,
- "hero": 3,
- "title": 3
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/13/split.html b/services/response-api/assets/slide_creator/templates/13/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/13/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/13/table.html b/services/response-api/assets/slide_creator/templates/13/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/13/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/13/title.html b/services/response-api/assets/slide_creator/templates/13/title.html
deleted file mode 100644
index 45161794..00000000
--- a/services/response-api/assets/slide_creator/templates/13/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
-
- Slide {{.Index}}/{{.Total}}
- {{if .Title.Notes}}{{trimToRunes .Title.Notes 90}} {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/14/base.html b/services/response-api/assets/slide_creator/templates/14/base.html
deleted file mode 100644
index 982ae99a..00000000
--- a/services/response-api/assets/slide_creator/templates/14/base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/14/bullets.html b/services/response-api/assets/slide_creator/templates/14/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/14/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/14/chart.html b/services/response-api/assets/slide_creator/templates/14/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/14/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/14/hero.html b/services/response-api/assets/slide_creator/templates/14/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/14/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/14/llm.html b/services/response-api/assets/slide_creator/templates/14/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/14/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/14/meta.json b/services/response-api/assets/slide_creator/templates/14/meta.json
deleted file mode 100644
index 75bd50a6..00000000
--- a/services/response-api/assets/slide_creator/templates/14/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 14,
- "dir": "14",
- "name": "Strategy Pack",
- "tone": "Corporate Consulting",
- "description": "Executive framing, clear hierarchy, client-ready polish.",
- "variants": {
- "base": 9,
- "bullets": 4,
- "split": 1,
- "hero": 1,
- "title": 4
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/14/split.html b/services/response-api/assets/slide_creator/templates/14/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/14/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/14/table.html b/services/response-api/assets/slide_creator/templates/14/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/14/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/14/title.html b/services/response-api/assets/slide_creator/templates/14/title.html
deleted file mode 100644
index fcdc0d92..00000000
--- a/services/response-api/assets/slide_creator/templates/14/title.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
{{.Index}}
-
of {{.Total}}
-
-
-
{{.Plan.Title}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 90}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/15/base.html b/services/response-api/assets/slide_creator/templates/15/base.html
deleted file mode 100644
index 982ae99a..00000000
--- a/services/response-api/assets/slide_creator/templates/15/base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/15/bullets.html b/services/response-api/assets/slide_creator/templates/15/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/15/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/15/chart.html b/services/response-api/assets/slide_creator/templates/15/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/15/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/15/hero.html b/services/response-api/assets/slide_creator/templates/15/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/15/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/15/llm.html b/services/response-api/assets/slide_creator/templates/15/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/15/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/15/meta.json b/services/response-api/assets/slide_creator/templates/15/meta.json
deleted file mode 100644
index 0e504e0f..00000000
--- a/services/response-api/assets/slide_creator/templates/15/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 15,
- "dir": "15",
- "name": "Client Brief",
- "tone": "Corporate Consulting",
- "description": "Executive framing, clear hierarchy, client-ready polish.",
- "variants": {
- "base": 9,
- "bullets": 5,
- "split": 2,
- "hero": 2,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/15/split.html b/services/response-api/assets/slide_creator/templates/15/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/15/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/15/table.html b/services/response-api/assets/slide_creator/templates/15/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/15/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/15/title.html b/services/response-api/assets/slide_creator/templates/15/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/15/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/16/base.html b/services/response-api/assets/slide_creator/templates/16/base.html
deleted file mode 100644
index b63eec42..00000000
--- a/services/response-api/assets/slide_creator/templates/16/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/16/bullets.html b/services/response-api/assets/slide_creator/templates/16/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/16/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/16/chart.html b/services/response-api/assets/slide_creator/templates/16/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/16/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/16/hero.html b/services/response-api/assets/slide_creator/templates/16/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/16/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/16/llm.html b/services/response-api/assets/slide_creator/templates/16/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/16/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/16/meta.json b/services/response-api/assets/slide_creator/templates/16/meta.json
deleted file mode 100644
index 9fd99c7c..00000000
--- a/services/response-api/assets/slide_creator/templates/16/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 16,
- "dir": "16",
- "name": "Dark Terminal",
- "tone": "Tech Dark",
- "description": "Dark glass + glow, strong contrast, product/engineering feel.",
- "variants": {
- "base": 5,
- "bullets": 1,
- "split": 4,
- "hero": 1,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/16/split.html b/services/response-api/assets/slide_creator/templates/16/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/16/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/16/table.html b/services/response-api/assets/slide_creator/templates/16/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/16/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/16/title.html b/services/response-api/assets/slide_creator/templates/16/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/16/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/17/base.html b/services/response-api/assets/slide_creator/templates/17/base.html
deleted file mode 100644
index b63eec42..00000000
--- a/services/response-api/assets/slide_creator/templates/17/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/17/bullets.html b/services/response-api/assets/slide_creator/templates/17/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/17/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/17/chart.html b/services/response-api/assets/slide_creator/templates/17/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/17/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/17/hero.html b/services/response-api/assets/slide_creator/templates/17/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/17/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/17/llm.html b/services/response-api/assets/slide_creator/templates/17/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/17/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/17/meta.json b/services/response-api/assets/slide_creator/templates/17/meta.json
deleted file mode 100644
index e5659ccf..00000000
--- a/services/response-api/assets/slide_creator/templates/17/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 17,
- "dir": "17",
- "name": "Night Ops",
- "tone": "Tech Dark",
- "description": "Dark glass + glow, strong contrast, product/engineering feel.",
- "variants": {
- "base": 5,
- "bullets": 2,
- "split": 5,
- "hero": 2,
- "title": 2
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/17/split.html b/services/response-api/assets/slide_creator/templates/17/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/17/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/17/table.html b/services/response-api/assets/slide_creator/templates/17/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/17/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/17/title.html b/services/response-api/assets/slide_creator/templates/17/title.html
deleted file mode 100644
index e4e39fb6..00000000
--- a/services/response-api/assets/slide_creator/templates/17/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
Slide {{.Index}} / {{.Total}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/18/base.html b/services/response-api/assets/slide_creator/templates/18/base.html
deleted file mode 100644
index b63eec42..00000000
--- a/services/response-api/assets/slide_creator/templates/18/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/18/bullets.html b/services/response-api/assets/slide_creator/templates/18/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/18/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/18/chart.html b/services/response-api/assets/slide_creator/templates/18/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/18/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/18/hero.html b/services/response-api/assets/slide_creator/templates/18/hero.html
deleted file mode 100644
index dafda5d3..00000000
--- a/services/response-api/assets/slide_creator/templates/18/hero.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 150}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/18/llm.html b/services/response-api/assets/slide_creator/templates/18/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/18/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/18/meta.json b/services/response-api/assets/slide_creator/templates/18/meta.json
deleted file mode 100644
index 47d07b6b..00000000
--- a/services/response-api/assets/slide_creator/templates/18/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 18,
- "dir": "18",
- "name": "Quantum Slate",
- "tone": "Tech Dark",
- "description": "Dark glass + glow, strong contrast, product/engineering feel.",
- "variants": {
- "base": 5,
- "bullets": 3,
- "split": 1,
- "hero": 3,
- "title": 3
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/18/split.html b/services/response-api/assets/slide_creator/templates/18/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/18/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/18/table.html b/services/response-api/assets/slide_creator/templates/18/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/18/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/18/title.html b/services/response-api/assets/slide_creator/templates/18/title.html
deleted file mode 100644
index 45161794..00000000
--- a/services/response-api/assets/slide_creator/templates/18/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
-
- Slide {{.Index}}/{{.Total}}
- {{if .Title.Notes}}{{trimToRunes .Title.Notes 90}} {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/19/base.html b/services/response-api/assets/slide_creator/templates/19/base.html
deleted file mode 100644
index b63eec42..00000000
--- a/services/response-api/assets/slide_creator/templates/19/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/19/bullets.html b/services/response-api/assets/slide_creator/templates/19/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/19/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/19/chart.html b/services/response-api/assets/slide_creator/templates/19/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/19/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/19/hero.html b/services/response-api/assets/slide_creator/templates/19/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/19/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/19/llm.html b/services/response-api/assets/slide_creator/templates/19/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/19/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/19/meta.json b/services/response-api/assets/slide_creator/templates/19/meta.json
deleted file mode 100644
index 9d1a7c66..00000000
--- a/services/response-api/assets/slide_creator/templates/19/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 19,
- "dir": "19",
- "name": "Carbon Studio",
- "tone": "Tech Dark",
- "description": "Dark glass + glow, strong contrast, product/engineering feel.",
- "variants": {
- "base": 5,
- "bullets": 4,
- "split": 2,
- "hero": 1,
- "title": 4
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/19/split.html b/services/response-api/assets/slide_creator/templates/19/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/19/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/19/table.html b/services/response-api/assets/slide_creator/templates/19/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/19/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/19/title.html b/services/response-api/assets/slide_creator/templates/19/title.html
deleted file mode 100644
index fcdc0d92..00000000
--- a/services/response-api/assets/slide_creator/templates/19/title.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
{{.Index}}
-
of {{.Total}}
-
-
-
{{.Plan.Title}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 90}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/2/base.html b/services/response-api/assets/slide_creator/templates/2/base.html
deleted file mode 100644
index a3388e2b..00000000
--- a/services/response-api/assets/slide_creator/templates/2/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/2/bullets.html b/services/response-api/assets/slide_creator/templates/2/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/2/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/2/chart.html b/services/response-api/assets/slide_creator/templates/2/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/2/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/2/hero.html b/services/response-api/assets/slide_creator/templates/2/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/2/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/2/llm.html b/services/response-api/assets/slide_creator/templates/2/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/2/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/2/meta.json b/services/response-api/assets/slide_creator/templates/2/meta.json
deleted file mode 100644
index 1e66de4b..00000000
--- a/services/response-api/assets/slide_creator/templates/2/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 2,
- "dir": "2",
- "name": "Cyber Grid",
- "tone": "Neon Cyberpunk",
- "description": "Aurora glows + high-energy composition for futuristic themes.",
- "variants": {
- "base": 1,
- "bullets": 2,
- "split": 2,
- "hero": 2,
- "title": 2
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/2/split.html b/services/response-api/assets/slide_creator/templates/2/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/2/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/2/table.html b/services/response-api/assets/slide_creator/templates/2/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/2/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/2/title.html b/services/response-api/assets/slide_creator/templates/2/title.html
deleted file mode 100644
index e4e39fb6..00000000
--- a/services/response-api/assets/slide_creator/templates/2/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
Slide {{.Index}} / {{.Total}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/20/base.html b/services/response-api/assets/slide_creator/templates/20/base.html
deleted file mode 100644
index b63eec42..00000000
--- a/services/response-api/assets/slide_creator/templates/20/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/20/bullets.html b/services/response-api/assets/slide_creator/templates/20/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/20/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/20/chart.html b/services/response-api/assets/slide_creator/templates/20/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/20/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/20/hero.html b/services/response-api/assets/slide_creator/templates/20/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/20/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/20/llm.html b/services/response-api/assets/slide_creator/templates/20/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/20/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/20/meta.json b/services/response-api/assets/slide_creator/templates/20/meta.json
deleted file mode 100644
index cbe1f740..00000000
--- a/services/response-api/assets/slide_creator/templates/20/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 20,
- "dir": "20",
- "name": "Midnight Grid",
- "tone": "Tech Dark",
- "description": "Dark glass + glow, strong contrast, product/engineering feel.",
- "variants": {
- "base": 5,
- "bullets": 5,
- "split": 3,
- "hero": 2,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/20/split.html b/services/response-api/assets/slide_creator/templates/20/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/20/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/20/table.html b/services/response-api/assets/slide_creator/templates/20/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/20/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/20/title.html b/services/response-api/assets/slide_creator/templates/20/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/20/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/21/base.html b/services/response-api/assets/slide_creator/templates/21/base.html
deleted file mode 100644
index 1608815d..00000000
--- a/services/response-api/assets/slide_creator/templates/21/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/21/bullets.html b/services/response-api/assets/slide_creator/templates/21/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/21/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/21/chart.html b/services/response-api/assets/slide_creator/templates/21/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/21/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/21/hero.html b/services/response-api/assets/slide_creator/templates/21/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/21/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/21/llm.html b/services/response-api/assets/slide_creator/templates/21/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/21/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/21/meta.json b/services/response-api/assets/slide_creator/templates/21/meta.json
deleted file mode 100644
index 1a97c602..00000000
--- a/services/response-api/assets/slide_creator/templates/21/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 21,
- "dir": "21",
- "name": "Launchpad Pitch",
- "tone": "Startup Bold",
- "description": "Accent band + bold rhythm, pitch-deck energy.",
- "variants": {
- "base": 4,
- "bullets": 1,
- "split": 5,
- "hero": 1,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/21/split.html b/services/response-api/assets/slide_creator/templates/21/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/21/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/21/table.html b/services/response-api/assets/slide_creator/templates/21/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/21/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/21/title.html b/services/response-api/assets/slide_creator/templates/21/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/21/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/22/base.html b/services/response-api/assets/slide_creator/templates/22/base.html
deleted file mode 100644
index 1608815d..00000000
--- a/services/response-api/assets/slide_creator/templates/22/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/22/bullets.html b/services/response-api/assets/slide_creator/templates/22/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/22/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/22/chart.html b/services/response-api/assets/slide_creator/templates/22/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/22/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/22/hero.html b/services/response-api/assets/slide_creator/templates/22/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/22/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/22/llm.html b/services/response-api/assets/slide_creator/templates/22/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/22/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/22/meta.json b/services/response-api/assets/slide_creator/templates/22/meta.json
deleted file mode 100644
index 6755f68d..00000000
--- a/services/response-api/assets/slide_creator/templates/22/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 22,
- "dir": "22",
- "name": "Venture Bold",
- "tone": "Startup Bold",
- "description": "Accent band + bold rhythm, pitch-deck energy.",
- "variants": {
- "base": 4,
- "bullets": 2,
- "split": 1,
- "hero": 2,
- "title": 2
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/22/split.html b/services/response-api/assets/slide_creator/templates/22/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/22/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/22/table.html b/services/response-api/assets/slide_creator/templates/22/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/22/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/22/title.html b/services/response-api/assets/slide_creator/templates/22/title.html
deleted file mode 100644
index e4e39fb6..00000000
--- a/services/response-api/assets/slide_creator/templates/22/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
Slide {{.Index}} / {{.Total}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/23/base.html b/services/response-api/assets/slide_creator/templates/23/base.html
deleted file mode 100644
index 1608815d..00000000
--- a/services/response-api/assets/slide_creator/templates/23/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/23/bullets.html b/services/response-api/assets/slide_creator/templates/23/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/23/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/23/chart.html b/services/response-api/assets/slide_creator/templates/23/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/23/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/23/hero.html b/services/response-api/assets/slide_creator/templates/23/hero.html
deleted file mode 100644
index dafda5d3..00000000
--- a/services/response-api/assets/slide_creator/templates/23/hero.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 150}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/23/llm.html b/services/response-api/assets/slide_creator/templates/23/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/23/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/23/meta.json b/services/response-api/assets/slide_creator/templates/23/meta.json
deleted file mode 100644
index c7be4d5c..00000000
--- a/services/response-api/assets/slide_creator/templates/23/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 23,
- "dir": "23",
- "name": "Momentum Deck",
- "tone": "Startup Bold",
- "description": "Accent band + bold rhythm, pitch-deck energy.",
- "variants": {
- "base": 4,
- "bullets": 3,
- "split": 2,
- "hero": 3,
- "title": 3
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/23/split.html b/services/response-api/assets/slide_creator/templates/23/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/23/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/23/table.html b/services/response-api/assets/slide_creator/templates/23/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/23/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/23/title.html b/services/response-api/assets/slide_creator/templates/23/title.html
deleted file mode 100644
index 45161794..00000000
--- a/services/response-api/assets/slide_creator/templates/23/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
-
- Slide {{.Index}}/{{.Total}}
- {{if .Title.Notes}}{{trimToRunes .Title.Notes 90}} {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/24/base.html b/services/response-api/assets/slide_creator/templates/24/base.html
deleted file mode 100644
index 1608815d..00000000
--- a/services/response-api/assets/slide_creator/templates/24/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/24/bullets.html b/services/response-api/assets/slide_creator/templates/24/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/24/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/24/chart.html b/services/response-api/assets/slide_creator/templates/24/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/24/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/24/hero.html b/services/response-api/assets/slide_creator/templates/24/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/24/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/24/llm.html b/services/response-api/assets/slide_creator/templates/24/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/24/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/24/meta.json b/services/response-api/assets/slide_creator/templates/24/meta.json
deleted file mode 100644
index feff0204..00000000
--- a/services/response-api/assets/slide_creator/templates/24/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 24,
- "dir": "24",
- "name": "Growth Sprint",
- "tone": "Startup Bold",
- "description": "Accent band + bold rhythm, pitch-deck energy.",
- "variants": {
- "base": 4,
- "bullets": 4,
- "split": 3,
- "hero": 1,
- "title": 4
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/24/split.html b/services/response-api/assets/slide_creator/templates/24/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/24/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/24/table.html b/services/response-api/assets/slide_creator/templates/24/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/24/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/24/title.html b/services/response-api/assets/slide_creator/templates/24/title.html
deleted file mode 100644
index fcdc0d92..00000000
--- a/services/response-api/assets/slide_creator/templates/24/title.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
{{.Index}}
-
of {{.Total}}
-
-
-
{{.Plan.Title}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 90}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/25/base.html b/services/response-api/assets/slide_creator/templates/25/base.html
deleted file mode 100644
index 1608815d..00000000
--- a/services/response-api/assets/slide_creator/templates/25/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/25/bullets.html b/services/response-api/assets/slide_creator/templates/25/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/25/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/25/chart.html b/services/response-api/assets/slide_creator/templates/25/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/25/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/25/hero.html b/services/response-api/assets/slide_creator/templates/25/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/25/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/25/llm.html b/services/response-api/assets/slide_creator/templates/25/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/25/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/25/meta.json b/services/response-api/assets/slide_creator/templates/25/meta.json
deleted file mode 100644
index 21a1fda4..00000000
--- a/services/response-api/assets/slide_creator/templates/25/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 25,
- "dir": "25",
- "name": "Demo Day",
- "tone": "Startup Bold",
- "description": "Accent band + bold rhythm, pitch-deck energy.",
- "variants": {
- "base": 4,
- "bullets": 5,
- "split": 4,
- "hero": 2,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/25/split.html b/services/response-api/assets/slide_creator/templates/25/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/25/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/25/table.html b/services/response-api/assets/slide_creator/templates/25/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/25/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/25/title.html b/services/response-api/assets/slide_creator/templates/25/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/25/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/26/base.html b/services/response-api/assets/slide_creator/templates/26/base.html
deleted file mode 100644
index 7dc1fc61..00000000
--- a/services/response-api/assets/slide_creator/templates/26/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/26/bullets.html b/services/response-api/assets/slide_creator/templates/26/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/26/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/26/chart.html b/services/response-api/assets/slide_creator/templates/26/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/26/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/26/hero.html b/services/response-api/assets/slide_creator/templates/26/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/26/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/26/llm.html b/services/response-api/assets/slide_creator/templates/26/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/26/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/26/meta.json b/services/response-api/assets/slide_creator/templates/26/meta.json
deleted file mode 100644
index 72c5d400..00000000
--- a/services/response-api/assets/slide_creator/templates/26/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 26,
- "dir": "26",
- "name": "Cotton Candy",
- "tone": "Playful Pastel",
- "description": "Soft patterns and friendly shapes; great for consumer topics.",
- "variants": {
- "base": 7,
- "bullets": 1,
- "split": 1,
- "hero": 1,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/26/split.html b/services/response-api/assets/slide_creator/templates/26/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/26/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/26/table.html b/services/response-api/assets/slide_creator/templates/26/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/26/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/26/title.html b/services/response-api/assets/slide_creator/templates/26/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/26/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/27/base.html b/services/response-api/assets/slide_creator/templates/27/base.html
deleted file mode 100644
index 7dc1fc61..00000000
--- a/services/response-api/assets/slide_creator/templates/27/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/27/bullets.html b/services/response-api/assets/slide_creator/templates/27/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/27/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/27/chart.html b/services/response-api/assets/slide_creator/templates/27/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/27/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/27/hero.html b/services/response-api/assets/slide_creator/templates/27/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/27/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/27/llm.html b/services/response-api/assets/slide_creator/templates/27/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/27/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/27/meta.json b/services/response-api/assets/slide_creator/templates/27/meta.json
deleted file mode 100644
index 7f539cb3..00000000
--- a/services/response-api/assets/slide_creator/templates/27/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 27,
- "dir": "27",
- "name": "Peach Pop",
- "tone": "Playful Pastel",
- "description": "Soft patterns and friendly shapes; great for consumer topics.",
- "variants": {
- "base": 7,
- "bullets": 2,
- "split": 2,
- "hero": 2,
- "title": 2
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/27/split.html b/services/response-api/assets/slide_creator/templates/27/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/27/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/27/table.html b/services/response-api/assets/slide_creator/templates/27/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/27/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/27/title.html b/services/response-api/assets/slide_creator/templates/27/title.html
deleted file mode 100644
index e4e39fb6..00000000
--- a/services/response-api/assets/slide_creator/templates/27/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
Slide {{.Index}} / {{.Total}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/28/base.html b/services/response-api/assets/slide_creator/templates/28/base.html
deleted file mode 100644
index 7dc1fc61..00000000
--- a/services/response-api/assets/slide_creator/templates/28/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/28/bullets.html b/services/response-api/assets/slide_creator/templates/28/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/28/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/28/chart.html b/services/response-api/assets/slide_creator/templates/28/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/28/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/28/hero.html b/services/response-api/assets/slide_creator/templates/28/hero.html
deleted file mode 100644
index dafda5d3..00000000
--- a/services/response-api/assets/slide_creator/templates/28/hero.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 150}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/28/llm.html b/services/response-api/assets/slide_creator/templates/28/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/28/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/28/meta.json b/services/response-api/assets/slide_creator/templates/28/meta.json
deleted file mode 100644
index 1b0a880b..00000000
--- a/services/response-api/assets/slide_creator/templates/28/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 28,
- "dir": "28",
- "name": "Mint Joy",
- "tone": "Playful Pastel",
- "description": "Soft patterns and friendly shapes; great for consumer topics.",
- "variants": {
- "base": 7,
- "bullets": 3,
- "split": 3,
- "hero": 3,
- "title": 3
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/28/split.html b/services/response-api/assets/slide_creator/templates/28/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/28/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/28/table.html b/services/response-api/assets/slide_creator/templates/28/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/28/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/28/title.html b/services/response-api/assets/slide_creator/templates/28/title.html
deleted file mode 100644
index 45161794..00000000
--- a/services/response-api/assets/slide_creator/templates/28/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
-
- Slide {{.Index}}/{{.Total}}
- {{if .Title.Notes}}{{trimToRunes .Title.Notes 90}} {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/29/base.html b/services/response-api/assets/slide_creator/templates/29/base.html
deleted file mode 100644
index 7dc1fc61..00000000
--- a/services/response-api/assets/slide_creator/templates/29/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/29/bullets.html b/services/response-api/assets/slide_creator/templates/29/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/29/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/29/chart.html b/services/response-api/assets/slide_creator/templates/29/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/29/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/29/hero.html b/services/response-api/assets/slide_creator/templates/29/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/29/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/29/llm.html b/services/response-api/assets/slide_creator/templates/29/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/29/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/29/meta.json b/services/response-api/assets/slide_creator/templates/29/meta.json
deleted file mode 100644
index 684d4416..00000000
--- a/services/response-api/assets/slide_creator/templates/29/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 29,
- "dir": "29",
- "name": "Lavender Fun",
- "tone": "Playful Pastel",
- "description": "Soft patterns and friendly shapes; great for consumer topics.",
- "variants": {
- "base": 7,
- "bullets": 4,
- "split": 4,
- "hero": 1,
- "title": 4
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/29/split.html b/services/response-api/assets/slide_creator/templates/29/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/29/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/29/table.html b/services/response-api/assets/slide_creator/templates/29/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/29/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/29/title.html b/services/response-api/assets/slide_creator/templates/29/title.html
deleted file mode 100644
index fcdc0d92..00000000
--- a/services/response-api/assets/slide_creator/templates/29/title.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
{{.Index}}
-
of {{.Total}}
-
-
-
{{.Plan.Title}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 90}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/3/base.html b/services/response-api/assets/slide_creator/templates/3/base.html
deleted file mode 100644
index a3388e2b..00000000
--- a/services/response-api/assets/slide_creator/templates/3/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/3/bullets.html b/services/response-api/assets/slide_creator/templates/3/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/3/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/3/chart.html b/services/response-api/assets/slide_creator/templates/3/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/3/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/3/hero.html b/services/response-api/assets/slide_creator/templates/3/hero.html
deleted file mode 100644
index dafda5d3..00000000
--- a/services/response-api/assets/slide_creator/templates/3/hero.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 150}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/3/llm.html b/services/response-api/assets/slide_creator/templates/3/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/3/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/3/meta.json b/services/response-api/assets/slide_creator/templates/3/meta.json
deleted file mode 100644
index ed831ca2..00000000
--- a/services/response-api/assets/slide_creator/templates/3/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 3,
- "dir": "3",
- "name": "Laser Night",
- "tone": "Neon Cyberpunk",
- "description": "Aurora glows + high-energy composition for futuristic themes.",
- "variants": {
- "base": 1,
- "bullets": 3,
- "split": 3,
- "hero": 3,
- "title": 3
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/3/split.html b/services/response-api/assets/slide_creator/templates/3/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/3/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/3/table.html b/services/response-api/assets/slide_creator/templates/3/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/3/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/3/title.html b/services/response-api/assets/slide_creator/templates/3/title.html
deleted file mode 100644
index 45161794..00000000
--- a/services/response-api/assets/slide_creator/templates/3/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
-
- Slide {{.Index}}/{{.Total}}
- {{if .Title.Notes}}{{trimToRunes .Title.Notes 90}} {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/30/base.html b/services/response-api/assets/slide_creator/templates/30/base.html
deleted file mode 100644
index 7dc1fc61..00000000
--- a/services/response-api/assets/slide_creator/templates/30/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/30/bullets.html b/services/response-api/assets/slide_creator/templates/30/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/30/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/30/chart.html b/services/response-api/assets/slide_creator/templates/30/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/30/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/30/hero.html b/services/response-api/assets/slide_creator/templates/30/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/30/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/30/llm.html b/services/response-api/assets/slide_creator/templates/30/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/30/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/30/meta.json b/services/response-api/assets/slide_creator/templates/30/meta.json
deleted file mode 100644
index 1fce72d8..00000000
--- a/services/response-api/assets/slide_creator/templates/30/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 30,
- "dir": "30",
- "name": "Bubblegum",
- "tone": "Playful Pastel",
- "description": "Soft patterns and friendly shapes; great for consumer topics.",
- "variants": {
- "base": 7,
- "bullets": 5,
- "split": 5,
- "hero": 2,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/30/split.html b/services/response-api/assets/slide_creator/templates/30/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/30/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/30/table.html b/services/response-api/assets/slide_creator/templates/30/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/30/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/30/title.html b/services/response-api/assets/slide_creator/templates/30/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/30/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/31/base.html b/services/response-api/assets/slide_creator/templates/31/base.html
deleted file mode 100644
index 9bcb057f..00000000
--- a/services/response-api/assets/slide_creator/templates/31/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/31/bullets.html b/services/response-api/assets/slide_creator/templates/31/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/31/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/31/chart.html b/services/response-api/assets/slide_creator/templates/31/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/31/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/31/hero.html b/services/response-api/assets/slide_creator/templates/31/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/31/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/31/llm.html b/services/response-api/assets/slide_creator/templates/31/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/31/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/31/meta.json b/services/response-api/assets/slide_creator/templates/31/meta.json
deleted file mode 100644
index ca447d54..00000000
--- a/services/response-api/assets/slide_creator/templates/31/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 31,
- "dir": "31",
- "name": "Magazine Serif",
- "tone": "Editorial Serif",
- "description": "Paper/grid editorial vibe; strong reading flow.",
- "variants": {
- "base": 6,
- "bullets": 1,
- "split": 2,
- "hero": 1,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/31/split.html b/services/response-api/assets/slide_creator/templates/31/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/31/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/31/table.html b/services/response-api/assets/slide_creator/templates/31/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/31/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/31/title.html b/services/response-api/assets/slide_creator/templates/31/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/31/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/32/base.html b/services/response-api/assets/slide_creator/templates/32/base.html
deleted file mode 100644
index 9bcb057f..00000000
--- a/services/response-api/assets/slide_creator/templates/32/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/32/bullets.html b/services/response-api/assets/slide_creator/templates/32/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/32/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/32/chart.html b/services/response-api/assets/slide_creator/templates/32/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/32/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/32/hero.html b/services/response-api/assets/slide_creator/templates/32/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/32/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/32/llm.html b/services/response-api/assets/slide_creator/templates/32/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/32/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/32/meta.json b/services/response-api/assets/slide_creator/templates/32/meta.json
deleted file mode 100644
index fe79f26d..00000000
--- a/services/response-api/assets/slide_creator/templates/32/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 32,
- "dir": "32",
- "name": "Op-Ed",
- "tone": "Editorial Serif",
- "description": "Paper/grid editorial vibe; strong reading flow.",
- "variants": {
- "base": 6,
- "bullets": 2,
- "split": 3,
- "hero": 2,
- "title": 2
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/32/split.html b/services/response-api/assets/slide_creator/templates/32/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/32/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/32/table.html b/services/response-api/assets/slide_creator/templates/32/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/32/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/32/title.html b/services/response-api/assets/slide_creator/templates/32/title.html
deleted file mode 100644
index e4e39fb6..00000000
--- a/services/response-api/assets/slide_creator/templates/32/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
Slide {{.Index}} / {{.Total}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/33/base.html b/services/response-api/assets/slide_creator/templates/33/base.html
deleted file mode 100644
index 9bcb057f..00000000
--- a/services/response-api/assets/slide_creator/templates/33/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/33/bullets.html b/services/response-api/assets/slide_creator/templates/33/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/33/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/33/chart.html b/services/response-api/assets/slide_creator/templates/33/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/33/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/33/hero.html b/services/response-api/assets/slide_creator/templates/33/hero.html
deleted file mode 100644
index dafda5d3..00000000
--- a/services/response-api/assets/slide_creator/templates/33/hero.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 150}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/33/llm.html b/services/response-api/assets/slide_creator/templates/33/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/33/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/33/meta.json b/services/response-api/assets/slide_creator/templates/33/meta.json
deleted file mode 100644
index 7a649bbd..00000000
--- a/services/response-api/assets/slide_creator/templates/33/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 33,
- "dir": "33",
- "name": "Pressroom",
- "tone": "Editorial Serif",
- "description": "Paper/grid editorial vibe; strong reading flow.",
- "variants": {
- "base": 6,
- "bullets": 3,
- "split": 4,
- "hero": 3,
- "title": 3
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/33/split.html b/services/response-api/assets/slide_creator/templates/33/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/33/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/33/table.html b/services/response-api/assets/slide_creator/templates/33/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/33/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/33/title.html b/services/response-api/assets/slide_creator/templates/33/title.html
deleted file mode 100644
index 45161794..00000000
--- a/services/response-api/assets/slide_creator/templates/33/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
-
- Slide {{.Index}}/{{.Total}}
- {{if .Title.Notes}}{{trimToRunes .Title.Notes 90}} {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/34/base.html b/services/response-api/assets/slide_creator/templates/34/base.html
deleted file mode 100644
index 9bcb057f..00000000
--- a/services/response-api/assets/slide_creator/templates/34/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/34/bullets.html b/services/response-api/assets/slide_creator/templates/34/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/34/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/34/chart.html b/services/response-api/assets/slide_creator/templates/34/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/34/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/34/hero.html b/services/response-api/assets/slide_creator/templates/34/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/34/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/34/llm.html b/services/response-api/assets/slide_creator/templates/34/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/34/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/34/meta.json b/services/response-api/assets/slide_creator/templates/34/meta.json
deleted file mode 100644
index 3453316b..00000000
--- a/services/response-api/assets/slide_creator/templates/34/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 34,
- "dir": "34",
- "name": "Classic Journal",
- "tone": "Editorial Serif",
- "description": "Paper/grid editorial vibe; strong reading flow.",
- "variants": {
- "base": 6,
- "bullets": 4,
- "split": 5,
- "hero": 1,
- "title": 4
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/34/split.html b/services/response-api/assets/slide_creator/templates/34/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/34/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/34/table.html b/services/response-api/assets/slide_creator/templates/34/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/34/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/34/title.html b/services/response-api/assets/slide_creator/templates/34/title.html
deleted file mode 100644
index fcdc0d92..00000000
--- a/services/response-api/assets/slide_creator/templates/34/title.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
{{.Index}}
-
of {{.Total}}
-
-
-
{{.Plan.Title}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 90}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/35/base.html b/services/response-api/assets/slide_creator/templates/35/base.html
deleted file mode 100644
index 9bcb057f..00000000
--- a/services/response-api/assets/slide_creator/templates/35/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/35/bullets.html b/services/response-api/assets/slide_creator/templates/35/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/35/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/35/chart.html b/services/response-api/assets/slide_creator/templates/35/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/35/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/35/hero.html b/services/response-api/assets/slide_creator/templates/35/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/35/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/35/llm.html b/services/response-api/assets/slide_creator/templates/35/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/35/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/35/meta.json b/services/response-api/assets/slide_creator/templates/35/meta.json
deleted file mode 100644
index 66a9fc28..00000000
--- a/services/response-api/assets/slide_creator/templates/35/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 35,
- "dir": "35",
- "name": "Notebook Editorial",
- "tone": "Editorial Serif",
- "description": "Paper/grid editorial vibe; strong reading flow.",
- "variants": {
- "base": 6,
- "bullets": 5,
- "split": 1,
- "hero": 2,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/35/split.html b/services/response-api/assets/slide_creator/templates/35/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/35/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/35/table.html b/services/response-api/assets/slide_creator/templates/35/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/35/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/35/title.html b/services/response-api/assets/slide_creator/templates/35/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/35/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/36/base.html b/services/response-api/assets/slide_creator/templates/36/base.html
deleted file mode 100644
index cc32fe71..00000000
--- a/services/response-api/assets/slide_creator/templates/36/base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/36/bullets.html b/services/response-api/assets/slide_creator/templates/36/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/36/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/36/chart.html b/services/response-api/assets/slide_creator/templates/36/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/36/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/36/hero.html b/services/response-api/assets/slide_creator/templates/36/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/36/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/36/llm.html b/services/response-api/assets/slide_creator/templates/36/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/36/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/36/meta.json b/services/response-api/assets/slide_creator/templates/36/meta.json
deleted file mode 100644
index 0c7f9215..00000000
--- a/services/response-api/assets/slide_creator/templates/36/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 36,
- "dir": "36",
- "name": "Onyx Luxe",
- "tone": "Luxury Elegant",
- "description": "Rounded stage, premium spacing, gallery-like feel.",
- "variants": {
- "base": 10,
- "bullets": 1,
- "split": 3,
- "hero": 1,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/36/split.html b/services/response-api/assets/slide_creator/templates/36/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/36/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/36/table.html b/services/response-api/assets/slide_creator/templates/36/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/36/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/36/title.html b/services/response-api/assets/slide_creator/templates/36/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/36/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/37/base.html b/services/response-api/assets/slide_creator/templates/37/base.html
deleted file mode 100644
index cc32fe71..00000000
--- a/services/response-api/assets/slide_creator/templates/37/base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/37/bullets.html b/services/response-api/assets/slide_creator/templates/37/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/37/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/37/chart.html b/services/response-api/assets/slide_creator/templates/37/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/37/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/37/hero.html b/services/response-api/assets/slide_creator/templates/37/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/37/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/37/llm.html b/services/response-api/assets/slide_creator/templates/37/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/37/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/37/meta.json b/services/response-api/assets/slide_creator/templates/37/meta.json
deleted file mode 100644
index abb0a14c..00000000
--- a/services/response-api/assets/slide_creator/templates/37/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 37,
- "dir": "37",
- "name": "Silk Gallery",
- "tone": "Luxury Elegant",
- "description": "Rounded stage, premium spacing, gallery-like feel.",
- "variants": {
- "base": 10,
- "bullets": 2,
- "split": 4,
- "hero": 2,
- "title": 2
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/37/split.html b/services/response-api/assets/slide_creator/templates/37/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/37/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/37/table.html b/services/response-api/assets/slide_creator/templates/37/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/37/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/37/title.html b/services/response-api/assets/slide_creator/templates/37/title.html
deleted file mode 100644
index e4e39fb6..00000000
--- a/services/response-api/assets/slide_creator/templates/37/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
Slide {{.Index}} / {{.Total}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/38/base.html b/services/response-api/assets/slide_creator/templates/38/base.html
deleted file mode 100644
index cc32fe71..00000000
--- a/services/response-api/assets/slide_creator/templates/38/base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/38/bullets.html b/services/response-api/assets/slide_creator/templates/38/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/38/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/38/chart.html b/services/response-api/assets/slide_creator/templates/38/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/38/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/38/hero.html b/services/response-api/assets/slide_creator/templates/38/hero.html
deleted file mode 100644
index dafda5d3..00000000
--- a/services/response-api/assets/slide_creator/templates/38/hero.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 150}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/38/llm.html b/services/response-api/assets/slide_creator/templates/38/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/38/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/38/meta.json b/services/response-api/assets/slide_creator/templates/38/meta.json
deleted file mode 100644
index 0396af91..00000000
--- a/services/response-api/assets/slide_creator/templates/38/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 38,
- "dir": "38",
- "name": "Chateau",
- "tone": "Luxury Elegant",
- "description": "Rounded stage, premium spacing, gallery-like feel.",
- "variants": {
- "base": 10,
- "bullets": 3,
- "split": 5,
- "hero": 3,
- "title": 3
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/38/split.html b/services/response-api/assets/slide_creator/templates/38/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/38/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/38/table.html b/services/response-api/assets/slide_creator/templates/38/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/38/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/38/title.html b/services/response-api/assets/slide_creator/templates/38/title.html
deleted file mode 100644
index 45161794..00000000
--- a/services/response-api/assets/slide_creator/templates/38/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
-
- Slide {{.Index}}/{{.Total}}
- {{if .Title.Notes}}{{trimToRunes .Title.Notes 90}} {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/39/base.html b/services/response-api/assets/slide_creator/templates/39/base.html
deleted file mode 100644
index cc32fe71..00000000
--- a/services/response-api/assets/slide_creator/templates/39/base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/39/bullets.html b/services/response-api/assets/slide_creator/templates/39/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/39/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/39/chart.html b/services/response-api/assets/slide_creator/templates/39/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/39/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/39/hero.html b/services/response-api/assets/slide_creator/templates/39/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/39/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/39/llm.html b/services/response-api/assets/slide_creator/templates/39/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/39/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/39/meta.json b/services/response-api/assets/slide_creator/templates/39/meta.json
deleted file mode 100644
index 5e90b705..00000000
--- a/services/response-api/assets/slide_creator/templates/39/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 39,
- "dir": "39",
- "name": "Noir Elegant",
- "tone": "Luxury Elegant",
- "description": "Rounded stage, premium spacing, gallery-like feel.",
- "variants": {
- "base": 10,
- "bullets": 4,
- "split": 1,
- "hero": 1,
- "title": 4
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/39/split.html b/services/response-api/assets/slide_creator/templates/39/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/39/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/39/table.html b/services/response-api/assets/slide_creator/templates/39/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/39/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/39/title.html b/services/response-api/assets/slide_creator/templates/39/title.html
deleted file mode 100644
index fcdc0d92..00000000
--- a/services/response-api/assets/slide_creator/templates/39/title.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
{{.Index}}
-
of {{.Total}}
-
-
-
{{.Plan.Title}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 90}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/4/base.html b/services/response-api/assets/slide_creator/templates/4/base.html
deleted file mode 100644
index a3388e2b..00000000
--- a/services/response-api/assets/slide_creator/templates/4/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/4/bullets.html b/services/response-api/assets/slide_creator/templates/4/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/4/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/4/chart.html b/services/response-api/assets/slide_creator/templates/4/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/4/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/4/hero.html b/services/response-api/assets/slide_creator/templates/4/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/4/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/4/llm.html b/services/response-api/assets/slide_creator/templates/4/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/4/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/4/meta.json b/services/response-api/assets/slide_creator/templates/4/meta.json
deleted file mode 100644
index c444e9b0..00000000
--- a/services/response-api/assets/slide_creator/templates/4/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 4,
- "dir": "4",
- "name": "Synthwave",
- "tone": "Neon Cyberpunk",
- "description": "Aurora glows + high-energy composition for futuristic themes.",
- "variants": {
- "base": 1,
- "bullets": 4,
- "split": 4,
- "hero": 1,
- "title": 4
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/4/split.html b/services/response-api/assets/slide_creator/templates/4/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/4/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/4/table.html b/services/response-api/assets/slide_creator/templates/4/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/4/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/4/title.html b/services/response-api/assets/slide_creator/templates/4/title.html
deleted file mode 100644
index fcdc0d92..00000000
--- a/services/response-api/assets/slide_creator/templates/4/title.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
{{.Index}}
-
of {{.Total}}
-
-
-
{{.Plan.Title}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 90}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/40/base.html b/services/response-api/assets/slide_creator/templates/40/base.html
deleted file mode 100644
index cc32fe71..00000000
--- a/services/response-api/assets/slide_creator/templates/40/base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/40/bullets.html b/services/response-api/assets/slide_creator/templates/40/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/40/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/40/chart.html b/services/response-api/assets/slide_creator/templates/40/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/40/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/40/hero.html b/services/response-api/assets/slide_creator/templates/40/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/40/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/40/llm.html b/services/response-api/assets/slide_creator/templates/40/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/40/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/40/meta.json b/services/response-api/assets/slide_creator/templates/40/meta.json
deleted file mode 100644
index 3dfd9e8d..00000000
--- a/services/response-api/assets/slide_creator/templates/40/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 40,
- "dir": "40",
- "name": "Gold Accent",
- "tone": "Luxury Elegant",
- "description": "Rounded stage, premium spacing, gallery-like feel.",
- "variants": {
- "base": 10,
- "bullets": 5,
- "split": 2,
- "hero": 2,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/40/split.html b/services/response-api/assets/slide_creator/templates/40/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/40/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/40/table.html b/services/response-api/assets/slide_creator/templates/40/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/40/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/40/title.html b/services/response-api/assets/slide_creator/templates/40/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/40/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/41/base.html b/services/response-api/assets/slide_creator/templates/41/base.html
deleted file mode 100644
index cbd839f2..00000000
--- a/services/response-api/assets/slide_creator/templates/41/base.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/41/bullets.html b/services/response-api/assets/slide_creator/templates/41/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/41/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/41/chart.html b/services/response-api/assets/slide_creator/templates/41/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/41/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/41/hero.html b/services/response-api/assets/slide_creator/templates/41/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/41/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/41/llm.html b/services/response-api/assets/slide_creator/templates/41/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/41/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/41/meta.json b/services/response-api/assets/slide_creator/templates/41/meta.json
deleted file mode 100644
index 044ef6c3..00000000
--- a/services/response-api/assets/slide_creator/templates/41/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 41,
- "dir": "41",
- "name": "Clinic Clean",
- "tone": "Healthcare Calm",
- "description": "Clean, calm, accessible layouts; works well with light themes.",
- "variants": {
- "base": 2,
- "bullets": 1,
- "split": 4,
- "hero": 1,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/41/split.html b/services/response-api/assets/slide_creator/templates/41/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/41/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/41/table.html b/services/response-api/assets/slide_creator/templates/41/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/41/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/41/title.html b/services/response-api/assets/slide_creator/templates/41/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/41/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/42/base.html b/services/response-api/assets/slide_creator/templates/42/base.html
deleted file mode 100644
index cbd839f2..00000000
--- a/services/response-api/assets/slide_creator/templates/42/base.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/42/bullets.html b/services/response-api/assets/slide_creator/templates/42/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/42/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/42/chart.html b/services/response-api/assets/slide_creator/templates/42/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/42/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/42/hero.html b/services/response-api/assets/slide_creator/templates/42/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/42/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/42/llm.html b/services/response-api/assets/slide_creator/templates/42/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/42/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/42/meta.json b/services/response-api/assets/slide_creator/templates/42/meta.json
deleted file mode 100644
index 46e285f5..00000000
--- a/services/response-api/assets/slide_creator/templates/42/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 42,
- "dir": "42",
- "name": "Care Path",
- "tone": "Healthcare Calm",
- "description": "Clean, calm, accessible layouts; works well with light themes.",
- "variants": {
- "base": 2,
- "bullets": 2,
- "split": 5,
- "hero": 2,
- "title": 2
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/42/split.html b/services/response-api/assets/slide_creator/templates/42/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/42/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/42/table.html b/services/response-api/assets/slide_creator/templates/42/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/42/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/42/title.html b/services/response-api/assets/slide_creator/templates/42/title.html
deleted file mode 100644
index e4e39fb6..00000000
--- a/services/response-api/assets/slide_creator/templates/42/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
Slide {{.Index}} / {{.Total}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/43/base.html b/services/response-api/assets/slide_creator/templates/43/base.html
deleted file mode 100644
index cbd839f2..00000000
--- a/services/response-api/assets/slide_creator/templates/43/base.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/43/bullets.html b/services/response-api/assets/slide_creator/templates/43/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/43/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/43/chart.html b/services/response-api/assets/slide_creator/templates/43/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/43/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/43/hero.html b/services/response-api/assets/slide_creator/templates/43/hero.html
deleted file mode 100644
index dafda5d3..00000000
--- a/services/response-api/assets/slide_creator/templates/43/hero.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 150}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/43/llm.html b/services/response-api/assets/slide_creator/templates/43/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/43/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/43/meta.json b/services/response-api/assets/slide_creator/templates/43/meta.json
deleted file mode 100644
index 711aa1d9..00000000
--- a/services/response-api/assets/slide_creator/templates/43/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 43,
- "dir": "43",
- "name": "Wellness Calm",
- "tone": "Healthcare Calm",
- "description": "Clean, calm, accessible layouts; works well with light themes.",
- "variants": {
- "base": 2,
- "bullets": 3,
- "split": 1,
- "hero": 3,
- "title": 3
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/43/split.html b/services/response-api/assets/slide_creator/templates/43/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/43/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/43/table.html b/services/response-api/assets/slide_creator/templates/43/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/43/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/43/title.html b/services/response-api/assets/slide_creator/templates/43/title.html
deleted file mode 100644
index 45161794..00000000
--- a/services/response-api/assets/slide_creator/templates/43/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
-
- Slide {{.Index}}/{{.Total}}
- {{if .Title.Notes}}{{trimToRunes .Title.Notes 90}} {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/44/base.html b/services/response-api/assets/slide_creator/templates/44/base.html
deleted file mode 100644
index cbd839f2..00000000
--- a/services/response-api/assets/slide_creator/templates/44/base.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/44/bullets.html b/services/response-api/assets/slide_creator/templates/44/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/44/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/44/chart.html b/services/response-api/assets/slide_creator/templates/44/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/44/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/44/hero.html b/services/response-api/assets/slide_creator/templates/44/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/44/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/44/llm.html b/services/response-api/assets/slide_creator/templates/44/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/44/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/44/meta.json b/services/response-api/assets/slide_creator/templates/44/meta.json
deleted file mode 100644
index 6045dc9d..00000000
--- a/services/response-api/assets/slide_creator/templates/44/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 44,
- "dir": "44",
- "name": "Aqua Relief",
- "tone": "Healthcare Calm",
- "description": "Clean, calm, accessible layouts; works well with light themes.",
- "variants": {
- "base": 2,
- "bullets": 4,
- "split": 2,
- "hero": 1,
- "title": 4
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/44/split.html b/services/response-api/assets/slide_creator/templates/44/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/44/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/44/table.html b/services/response-api/assets/slide_creator/templates/44/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/44/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/44/title.html b/services/response-api/assets/slide_creator/templates/44/title.html
deleted file mode 100644
index fcdc0d92..00000000
--- a/services/response-api/assets/slide_creator/templates/44/title.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
{{.Index}}
-
of {{.Total}}
-
-
-
{{.Plan.Title}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 90}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/45/base.html b/services/response-api/assets/slide_creator/templates/45/base.html
deleted file mode 100644
index cbd839f2..00000000
--- a/services/response-api/assets/slide_creator/templates/45/base.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/45/bullets.html b/services/response-api/assets/slide_creator/templates/45/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/45/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/45/chart.html b/services/response-api/assets/slide_creator/templates/45/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/45/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/45/hero.html b/services/response-api/assets/slide_creator/templates/45/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/45/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/45/llm.html b/services/response-api/assets/slide_creator/templates/45/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/45/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/45/meta.json b/services/response-api/assets/slide_creator/templates/45/meta.json
deleted file mode 100644
index 0a6f411c..00000000
--- a/services/response-api/assets/slide_creator/templates/45/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 45,
- "dir": "45",
- "name": "Soft Green",
- "tone": "Healthcare Calm",
- "description": "Clean, calm, accessible layouts; works well with light themes.",
- "variants": {
- "base": 2,
- "bullets": 5,
- "split": 3,
- "hero": 2,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/45/split.html b/services/response-api/assets/slide_creator/templates/45/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/45/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/45/table.html b/services/response-api/assets/slide_creator/templates/45/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/45/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/45/title.html b/services/response-api/assets/slide_creator/templates/45/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/45/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/46/base.html b/services/response-api/assets/slide_creator/templates/46/base.html
deleted file mode 100644
index 5b0e198f..00000000
--- a/services/response-api/assets/slide_creator/templates/46/base.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/46/bullets.html b/services/response-api/assets/slide_creator/templates/46/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/46/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/46/chart.html b/services/response-api/assets/slide_creator/templates/46/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/46/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/46/hero.html b/services/response-api/assets/slide_creator/templates/46/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/46/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/46/llm.html b/services/response-api/assets/slide_creator/templates/46/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/46/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/46/meta.json b/services/response-api/assets/slide_creator/templates/46/meta.json
deleted file mode 100644
index 46b39865..00000000
--- a/services/response-api/assets/slide_creator/templates/46/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 46,
- "dir": "46",
- "name": "Classroom",
- "tone": "Education Friendly",
- "description": "Sidebar guidance + structured body; classroom/learning friendly.",
- "variants": {
- "base": 3,
- "bullets": 1,
- "split": 5,
- "hero": 1,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/46/split.html b/services/response-api/assets/slide_creator/templates/46/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/46/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/46/table.html b/services/response-api/assets/slide_creator/templates/46/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/46/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/46/title.html b/services/response-api/assets/slide_creator/templates/46/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/46/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/47/base.html b/services/response-api/assets/slide_creator/templates/47/base.html
deleted file mode 100644
index 5b0e198f..00000000
--- a/services/response-api/assets/slide_creator/templates/47/base.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/47/bullets.html b/services/response-api/assets/slide_creator/templates/47/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/47/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/47/chart.html b/services/response-api/assets/slide_creator/templates/47/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/47/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/47/hero.html b/services/response-api/assets/slide_creator/templates/47/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/47/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/47/llm.html b/services/response-api/assets/slide_creator/templates/47/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/47/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/47/meta.json b/services/response-api/assets/slide_creator/templates/47/meta.json
deleted file mode 100644
index 5037e4f2..00000000
--- a/services/response-api/assets/slide_creator/templates/47/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 47,
- "dir": "47",
- "name": "Notebook",
- "tone": "Education Friendly",
- "description": "Sidebar guidance + structured body; classroom/learning friendly.",
- "variants": {
- "base": 3,
- "bullets": 2,
- "split": 1,
- "hero": 2,
- "title": 2
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/47/split.html b/services/response-api/assets/slide_creator/templates/47/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/47/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/47/table.html b/services/response-api/assets/slide_creator/templates/47/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/47/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/47/title.html b/services/response-api/assets/slide_creator/templates/47/title.html
deleted file mode 100644
index e4e39fb6..00000000
--- a/services/response-api/assets/slide_creator/templates/47/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
Slide {{.Index}} / {{.Total}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/48/base.html b/services/response-api/assets/slide_creator/templates/48/base.html
deleted file mode 100644
index 5b0e198f..00000000
--- a/services/response-api/assets/slide_creator/templates/48/base.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/48/bullets.html b/services/response-api/assets/slide_creator/templates/48/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/48/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/48/chart.html b/services/response-api/assets/slide_creator/templates/48/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/48/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/48/hero.html b/services/response-api/assets/slide_creator/templates/48/hero.html
deleted file mode 100644
index dafda5d3..00000000
--- a/services/response-api/assets/slide_creator/templates/48/hero.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 150}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/48/llm.html b/services/response-api/assets/slide_creator/templates/48/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/48/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/48/meta.json b/services/response-api/assets/slide_creator/templates/48/meta.json
deleted file mode 100644
index 3f804b0b..00000000
--- a/services/response-api/assets/slide_creator/templates/48/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 48,
- "dir": "48",
- "name": "Campus",
- "tone": "Education Friendly",
- "description": "Sidebar guidance + structured body; classroom/learning friendly.",
- "variants": {
- "base": 3,
- "bullets": 3,
- "split": 2,
- "hero": 3,
- "title": 3
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/48/split.html b/services/response-api/assets/slide_creator/templates/48/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/48/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/48/table.html b/services/response-api/assets/slide_creator/templates/48/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/48/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/48/title.html b/services/response-api/assets/slide_creator/templates/48/title.html
deleted file mode 100644
index 45161794..00000000
--- a/services/response-api/assets/slide_creator/templates/48/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
-
- Slide {{.Index}}/{{.Total}}
- {{if .Title.Notes}}{{trimToRunes .Title.Notes 90}} {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/49/base.html b/services/response-api/assets/slide_creator/templates/49/base.html
deleted file mode 100644
index 5b0e198f..00000000
--- a/services/response-api/assets/slide_creator/templates/49/base.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/49/bullets.html b/services/response-api/assets/slide_creator/templates/49/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/49/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/49/chart.html b/services/response-api/assets/slide_creator/templates/49/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/49/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/49/hero.html b/services/response-api/assets/slide_creator/templates/49/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/49/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/49/llm.html b/services/response-api/assets/slide_creator/templates/49/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/49/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/49/meta.json b/services/response-api/assets/slide_creator/templates/49/meta.json
deleted file mode 100644
index 668287fc..00000000
--- a/services/response-api/assets/slide_creator/templates/49/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 49,
- "dir": "49",
- "name": "Study Buddy",
- "tone": "Education Friendly",
- "description": "Sidebar guidance + structured body; classroom/learning friendly.",
- "variants": {
- "base": 3,
- "bullets": 4,
- "split": 3,
- "hero": 1,
- "title": 4
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/49/split.html b/services/response-api/assets/slide_creator/templates/49/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/49/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/49/table.html b/services/response-api/assets/slide_creator/templates/49/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/49/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/49/title.html b/services/response-api/assets/slide_creator/templates/49/title.html
deleted file mode 100644
index fcdc0d92..00000000
--- a/services/response-api/assets/slide_creator/templates/49/title.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
{{.Index}}
-
of {{.Total}}
-
-
-
{{.Plan.Title}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 90}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/5/base.html b/services/response-api/assets/slide_creator/templates/5/base.html
deleted file mode 100644
index a3388e2b..00000000
--- a/services/response-api/assets/slide_creator/templates/5/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/5/bullets.html b/services/response-api/assets/slide_creator/templates/5/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/5/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/5/chart.html b/services/response-api/assets/slide_creator/templates/5/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/5/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/5/hero.html b/services/response-api/assets/slide_creator/templates/5/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/5/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/5/llm.html b/services/response-api/assets/slide_creator/templates/5/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/5/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/5/meta.json b/services/response-api/assets/slide_creator/templates/5/meta.json
deleted file mode 100644
index aea1080b..00000000
--- a/services/response-api/assets/slide_creator/templates/5/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 5,
- "dir": "5",
- "name": "Night Neon",
- "tone": "Neon Cyberpunk",
- "description": "Aurora glows + high-energy composition for futuristic themes.",
- "variants": {
- "base": 1,
- "bullets": 5,
- "split": 5,
- "hero": 2,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/5/split.html b/services/response-api/assets/slide_creator/templates/5/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/5/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/5/table.html b/services/response-api/assets/slide_creator/templates/5/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/5/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/5/title.html b/services/response-api/assets/slide_creator/templates/5/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/5/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/50/base.html b/services/response-api/assets/slide_creator/templates/50/base.html
deleted file mode 100644
index 5b0e198f..00000000
--- a/services/response-api/assets/slide_creator/templates/50/base.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/50/bullets.html b/services/response-api/assets/slide_creator/templates/50/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/50/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/50/chart.html b/services/response-api/assets/slide_creator/templates/50/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/50/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/50/hero.html b/services/response-api/assets/slide_creator/templates/50/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/50/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/50/llm.html b/services/response-api/assets/slide_creator/templates/50/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/50/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/50/meta.json b/services/response-api/assets/slide_creator/templates/50/meta.json
deleted file mode 100644
index dfa056d9..00000000
--- a/services/response-api/assets/slide_creator/templates/50/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 50,
- "dir": "50",
- "name": "Lesson Plan",
- "tone": "Education Friendly",
- "description": "Sidebar guidance + structured body; classroom/learning friendly.",
- "variants": {
- "base": 3,
- "bullets": 5,
- "split": 4,
- "hero": 2,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/50/split.html b/services/response-api/assets/slide_creator/templates/50/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/50/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/50/table.html b/services/response-api/assets/slide_creator/templates/50/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/50/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/50/title.html b/services/response-api/assets/slide_creator/templates/50/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/50/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/51/base.html b/services/response-api/assets/slide_creator/templates/51/base.html
deleted file mode 100644
index 982ae99a..00000000
--- a/services/response-api/assets/slide_creator/templates/51/base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/51/bullets.html b/services/response-api/assets/slide_creator/templates/51/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/51/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/51/chart.html b/services/response-api/assets/slide_creator/templates/51/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/51/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/51/hero.html b/services/response-api/assets/slide_creator/templates/51/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/51/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/51/llm.html b/services/response-api/assets/slide_creator/templates/51/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/51/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/51/meta.json b/services/response-api/assets/slide_creator/templates/51/meta.json
deleted file mode 100644
index f2c17116..00000000
--- a/services/response-api/assets/slide_creator/templates/51/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 51,
- "dir": "51",
- "name": "Market Brief",
- "tone": "Finance Professional",
- "description": "Structured, conservative frames for finance/strategy decks.",
- "variants": {
- "base": 9,
- "bullets": 1,
- "split": 1,
- "hero": 1,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/51/split.html b/services/response-api/assets/slide_creator/templates/51/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/51/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/51/table.html b/services/response-api/assets/slide_creator/templates/51/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/51/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/51/title.html b/services/response-api/assets/slide_creator/templates/51/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/51/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/52/base.html b/services/response-api/assets/slide_creator/templates/52/base.html
deleted file mode 100644
index 982ae99a..00000000
--- a/services/response-api/assets/slide_creator/templates/52/base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/52/bullets.html b/services/response-api/assets/slide_creator/templates/52/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/52/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/52/chart.html b/services/response-api/assets/slide_creator/templates/52/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/52/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/52/hero.html b/services/response-api/assets/slide_creator/templates/52/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/52/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/52/llm.html b/services/response-api/assets/slide_creator/templates/52/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/52/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/52/meta.json b/services/response-api/assets/slide_creator/templates/52/meta.json
deleted file mode 100644
index 6ea185a4..00000000
--- a/services/response-api/assets/slide_creator/templates/52/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 52,
- "dir": "52",
- "name": "Investor Note",
- "tone": "Finance Professional",
- "description": "Structured, conservative frames for finance/strategy decks.",
- "variants": {
- "base": 9,
- "bullets": 2,
- "split": 2,
- "hero": 2,
- "title": 2
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/52/split.html b/services/response-api/assets/slide_creator/templates/52/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/52/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/52/table.html b/services/response-api/assets/slide_creator/templates/52/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/52/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/52/title.html b/services/response-api/assets/slide_creator/templates/52/title.html
deleted file mode 100644
index e4e39fb6..00000000
--- a/services/response-api/assets/slide_creator/templates/52/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
Slide {{.Index}} / {{.Total}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/53/base.html b/services/response-api/assets/slide_creator/templates/53/base.html
deleted file mode 100644
index 982ae99a..00000000
--- a/services/response-api/assets/slide_creator/templates/53/base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/53/bullets.html b/services/response-api/assets/slide_creator/templates/53/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/53/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/53/chart.html b/services/response-api/assets/slide_creator/templates/53/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/53/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/53/hero.html b/services/response-api/assets/slide_creator/templates/53/hero.html
deleted file mode 100644
index dafda5d3..00000000
--- a/services/response-api/assets/slide_creator/templates/53/hero.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 150}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/53/llm.html b/services/response-api/assets/slide_creator/templates/53/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/53/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/53/meta.json b/services/response-api/assets/slide_creator/templates/53/meta.json
deleted file mode 100644
index b46cd119..00000000
--- a/services/response-api/assets/slide_creator/templates/53/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 53,
- "dir": "53",
- "name": "Capital Ledger",
- "tone": "Finance Professional",
- "description": "Structured, conservative frames for finance/strategy decks.",
- "variants": {
- "base": 9,
- "bullets": 3,
- "split": 3,
- "hero": 3,
- "title": 3
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/53/split.html b/services/response-api/assets/slide_creator/templates/53/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/53/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/53/table.html b/services/response-api/assets/slide_creator/templates/53/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/53/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/53/title.html b/services/response-api/assets/slide_creator/templates/53/title.html
deleted file mode 100644
index 45161794..00000000
--- a/services/response-api/assets/slide_creator/templates/53/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
-
- Slide {{.Index}}/{{.Total}}
- {{if .Title.Notes}}{{trimToRunes .Title.Notes 90}} {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/54/base.html b/services/response-api/assets/slide_creator/templates/54/base.html
deleted file mode 100644
index 982ae99a..00000000
--- a/services/response-api/assets/slide_creator/templates/54/base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/54/bullets.html b/services/response-api/assets/slide_creator/templates/54/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/54/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/54/chart.html b/services/response-api/assets/slide_creator/templates/54/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/54/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/54/hero.html b/services/response-api/assets/slide_creator/templates/54/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/54/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/54/llm.html b/services/response-api/assets/slide_creator/templates/54/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/54/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/54/meta.json b/services/response-api/assets/slide_creator/templates/54/meta.json
deleted file mode 100644
index 052db40f..00000000
--- a/services/response-api/assets/slide_creator/templates/54/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 54,
- "dir": "54",
- "name": "Quarterly Review",
- "tone": "Finance Professional",
- "description": "Structured, conservative frames for finance/strategy decks.",
- "variants": {
- "base": 9,
- "bullets": 4,
- "split": 4,
- "hero": 1,
- "title": 4
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/54/split.html b/services/response-api/assets/slide_creator/templates/54/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/54/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/54/table.html b/services/response-api/assets/slide_creator/templates/54/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/54/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/54/title.html b/services/response-api/assets/slide_creator/templates/54/title.html
deleted file mode 100644
index fcdc0d92..00000000
--- a/services/response-api/assets/slide_creator/templates/54/title.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
{{.Index}}
-
of {{.Total}}
-
-
-
{{.Plan.Title}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 90}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/55/base.html b/services/response-api/assets/slide_creator/templates/55/base.html
deleted file mode 100644
index 982ae99a..00000000
--- a/services/response-api/assets/slide_creator/templates/55/base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/55/bullets.html b/services/response-api/assets/slide_creator/templates/55/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/55/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/55/chart.html b/services/response-api/assets/slide_creator/templates/55/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/55/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/55/hero.html b/services/response-api/assets/slide_creator/templates/55/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/55/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/55/llm.html b/services/response-api/assets/slide_creator/templates/55/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/55/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/55/meta.json b/services/response-api/assets/slide_creator/templates/55/meta.json
deleted file mode 100644
index 87731822..00000000
--- a/services/response-api/assets/slide_creator/templates/55/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 55,
- "dir": "55",
- "name": "Risk Report",
- "tone": "Finance Professional",
- "description": "Structured, conservative frames for finance/strategy decks.",
- "variants": {
- "base": 9,
- "bullets": 5,
- "split": 5,
- "hero": 2,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/55/split.html b/services/response-api/assets/slide_creator/templates/55/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/55/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/55/table.html b/services/response-api/assets/slide_creator/templates/55/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/55/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/55/title.html b/services/response-api/assets/slide_creator/templates/55/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/55/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/56/base.html b/services/response-api/assets/slide_creator/templates/56/base.html
deleted file mode 100644
index 9bcb057f..00000000
--- a/services/response-api/assets/slide_creator/templates/56/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/56/bullets.html b/services/response-api/assets/slide_creator/templates/56/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/56/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/56/chart.html b/services/response-api/assets/slide_creator/templates/56/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/56/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/56/hero.html b/services/response-api/assets/slide_creator/templates/56/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/56/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/56/llm.html b/services/response-api/assets/slide_creator/templates/56/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/56/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/56/meta.json b/services/response-api/assets/slide_creator/templates/56/meta.json
deleted file mode 100644
index 88dc3753..00000000
--- a/services/response-api/assets/slide_creator/templates/56/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 56,
- "dir": "56",
- "name": "Earth Brief",
- "tone": "Sustainability Earthy",
- "description": "Grid/paper background pairs well with earthy palettes.",
- "variants": {
- "base": 6,
- "bullets": 1,
- "split": 2,
- "hero": 1,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/56/split.html b/services/response-api/assets/slide_creator/templates/56/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/56/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/56/table.html b/services/response-api/assets/slide_creator/templates/56/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/56/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/56/title.html b/services/response-api/assets/slide_creator/templates/56/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/56/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/57/base.html b/services/response-api/assets/slide_creator/templates/57/base.html
deleted file mode 100644
index 9bcb057f..00000000
--- a/services/response-api/assets/slide_creator/templates/57/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/57/bullets.html b/services/response-api/assets/slide_creator/templates/57/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/57/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/57/chart.html b/services/response-api/assets/slide_creator/templates/57/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/57/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/57/hero.html b/services/response-api/assets/slide_creator/templates/57/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/57/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/57/llm.html b/services/response-api/assets/slide_creator/templates/57/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/57/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/57/meta.json b/services/response-api/assets/slide_creator/templates/57/meta.json
deleted file mode 100644
index 28b04050..00000000
--- a/services/response-api/assets/slide_creator/templates/57/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 57,
- "dir": "57",
- "name": "Forest Notes",
- "tone": "Sustainability Earthy",
- "description": "Grid/paper background pairs well with earthy palettes.",
- "variants": {
- "base": 6,
- "bullets": 2,
- "split": 3,
- "hero": 2,
- "title": 2
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/57/split.html b/services/response-api/assets/slide_creator/templates/57/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/57/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/57/table.html b/services/response-api/assets/slide_creator/templates/57/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/57/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/57/title.html b/services/response-api/assets/slide_creator/templates/57/title.html
deleted file mode 100644
index e4e39fb6..00000000
--- a/services/response-api/assets/slide_creator/templates/57/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
Slide {{.Index}} / {{.Total}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/58/base.html b/services/response-api/assets/slide_creator/templates/58/base.html
deleted file mode 100644
index 9bcb057f..00000000
--- a/services/response-api/assets/slide_creator/templates/58/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/58/bullets.html b/services/response-api/assets/slide_creator/templates/58/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/58/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/58/chart.html b/services/response-api/assets/slide_creator/templates/58/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/58/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/58/hero.html b/services/response-api/assets/slide_creator/templates/58/hero.html
deleted file mode 100644
index dafda5d3..00000000
--- a/services/response-api/assets/slide_creator/templates/58/hero.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 150}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/58/llm.html b/services/response-api/assets/slide_creator/templates/58/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/58/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/58/meta.json b/services/response-api/assets/slide_creator/templates/58/meta.json
deleted file mode 100644
index e96a879e..00000000
--- a/services/response-api/assets/slide_creator/templates/58/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 58,
- "dir": "58",
- "name": "Leaf Strategy",
- "tone": "Sustainability Earthy",
- "description": "Grid/paper background pairs well with earthy palettes.",
- "variants": {
- "base": 6,
- "bullets": 3,
- "split": 4,
- "hero": 3,
- "title": 3
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/58/split.html b/services/response-api/assets/slide_creator/templates/58/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/58/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/58/table.html b/services/response-api/assets/slide_creator/templates/58/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/58/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/58/title.html b/services/response-api/assets/slide_creator/templates/58/title.html
deleted file mode 100644
index 45161794..00000000
--- a/services/response-api/assets/slide_creator/templates/58/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
-
- Slide {{.Index}}/{{.Total}}
- {{if .Title.Notes}}{{trimToRunes .Title.Notes 90}} {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/59/base.html b/services/response-api/assets/slide_creator/templates/59/base.html
deleted file mode 100644
index 9bcb057f..00000000
--- a/services/response-api/assets/slide_creator/templates/59/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/59/bullets.html b/services/response-api/assets/slide_creator/templates/59/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/59/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/59/chart.html b/services/response-api/assets/slide_creator/templates/59/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/59/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/59/hero.html b/services/response-api/assets/slide_creator/templates/59/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/59/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/59/llm.html b/services/response-api/assets/slide_creator/templates/59/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/59/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/59/meta.json b/services/response-api/assets/slide_creator/templates/59/meta.json
deleted file mode 100644
index 029f5eec..00000000
--- a/services/response-api/assets/slide_creator/templates/59/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 59,
- "dir": "59",
- "name": "Eco Report",
- "tone": "Sustainability Earthy",
- "description": "Grid/paper background pairs well with earthy palettes.",
- "variants": {
- "base": 6,
- "bullets": 4,
- "split": 5,
- "hero": 1,
- "title": 4
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/59/split.html b/services/response-api/assets/slide_creator/templates/59/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/59/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/59/table.html b/services/response-api/assets/slide_creator/templates/59/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/59/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/59/title.html b/services/response-api/assets/slide_creator/templates/59/title.html
deleted file mode 100644
index fcdc0d92..00000000
--- a/services/response-api/assets/slide_creator/templates/59/title.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
{{.Index}}
-
of {{.Total}}
-
-
-
{{.Plan.Title}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 90}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/6/base.html b/services/response-api/assets/slide_creator/templates/6/base.html
deleted file mode 100644
index cbd839f2..00000000
--- a/services/response-api/assets/slide_creator/templates/6/base.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/6/bullets.html b/services/response-api/assets/slide_creator/templates/6/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/6/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/6/chart.html b/services/response-api/assets/slide_creator/templates/6/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/6/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/6/hero.html b/services/response-api/assets/slide_creator/templates/6/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/6/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/6/llm.html b/services/response-api/assets/slide_creator/templates/6/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/6/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/6/meta.json b/services/response-api/assets/slide_creator/templates/6/meta.json
deleted file mode 100644
index c8a717a4..00000000
--- a/services/response-api/assets/slide_creator/templates/6/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 6,
- "dir": "6",
- "name": "Ivory Minimal",
- "tone": "Minimal Clean",
- "description": "Whitespace-forward, neutral framing, restrained accents.",
- "variants": {
- "base": 2,
- "bullets": 1,
- "split": 2,
- "hero": 1,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/6/split.html b/services/response-api/assets/slide_creator/templates/6/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/6/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/6/table.html b/services/response-api/assets/slide_creator/templates/6/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/6/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/6/title.html b/services/response-api/assets/slide_creator/templates/6/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/6/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/60/base.html b/services/response-api/assets/slide_creator/templates/60/base.html
deleted file mode 100644
index 9bcb057f..00000000
--- a/services/response-api/assets/slide_creator/templates/60/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/60/bullets.html b/services/response-api/assets/slide_creator/templates/60/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/60/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/60/chart.html b/services/response-api/assets/slide_creator/templates/60/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/60/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/60/hero.html b/services/response-api/assets/slide_creator/templates/60/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/60/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/60/llm.html b/services/response-api/assets/slide_creator/templates/60/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/60/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/60/meta.json b/services/response-api/assets/slide_creator/templates/60/meta.json
deleted file mode 100644
index 16d411a8..00000000
--- a/services/response-api/assets/slide_creator/templates/60/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 60,
- "dir": "60",
- "name": "Green Path",
- "tone": "Sustainability Earthy",
- "description": "Grid/paper background pairs well with earthy palettes.",
- "variants": {
- "base": 6,
- "bullets": 5,
- "split": 1,
- "hero": 2,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/60/split.html b/services/response-api/assets/slide_creator/templates/60/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/60/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/60/table.html b/services/response-api/assets/slide_creator/templates/60/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/60/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/60/title.html b/services/response-api/assets/slide_creator/templates/60/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/60/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/61/base.html b/services/response-api/assets/slide_creator/templates/61/base.html
deleted file mode 100644
index 1608815d..00000000
--- a/services/response-api/assets/slide_creator/templates/61/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/61/bullets.html b/services/response-api/assets/slide_creator/templates/61/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/61/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/61/chart.html b/services/response-api/assets/slide_creator/templates/61/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/61/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/61/hero.html b/services/response-api/assets/slide_creator/templates/61/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/61/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/61/llm.html b/services/response-api/assets/slide_creator/templates/61/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/61/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/61/meta.json b/services/response-api/assets/slide_creator/templates/61/meta.json
deleted file mode 100644
index ad38be45..00000000
--- a/services/response-api/assets/slide_creator/templates/61/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 61,
- "dir": "61",
- "name": "Campaign Studio",
- "tone": "Marketing Vibrant",
- "description": "Top band + punchy accents; campaign and brand stories.",
- "variants": {
- "base": 4,
- "bullets": 1,
- "split": 3,
- "hero": 1,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/61/split.html b/services/response-api/assets/slide_creator/templates/61/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/61/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/61/table.html b/services/response-api/assets/slide_creator/templates/61/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/61/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/61/title.html b/services/response-api/assets/slide_creator/templates/61/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/61/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/62/base.html b/services/response-api/assets/slide_creator/templates/62/base.html
deleted file mode 100644
index 1608815d..00000000
--- a/services/response-api/assets/slide_creator/templates/62/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/62/bullets.html b/services/response-api/assets/slide_creator/templates/62/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/62/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/62/chart.html b/services/response-api/assets/slide_creator/templates/62/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/62/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/62/hero.html b/services/response-api/assets/slide_creator/templates/62/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/62/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/62/llm.html b/services/response-api/assets/slide_creator/templates/62/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/62/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/62/meta.json b/services/response-api/assets/slide_creator/templates/62/meta.json
deleted file mode 100644
index 661ab946..00000000
--- a/services/response-api/assets/slide_creator/templates/62/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 62,
- "dir": "62",
- "name": "Spotlight",
- "tone": "Marketing Vibrant",
- "description": "Top band + punchy accents; campaign and brand stories.",
- "variants": {
- "base": 4,
- "bullets": 2,
- "split": 4,
- "hero": 2,
- "title": 2
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/62/split.html b/services/response-api/assets/slide_creator/templates/62/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/62/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/62/table.html b/services/response-api/assets/slide_creator/templates/62/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/62/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/62/title.html b/services/response-api/assets/slide_creator/templates/62/title.html
deleted file mode 100644
index e4e39fb6..00000000
--- a/services/response-api/assets/slide_creator/templates/62/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
Slide {{.Index}} / {{.Total}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/63/base.html b/services/response-api/assets/slide_creator/templates/63/base.html
deleted file mode 100644
index 1608815d..00000000
--- a/services/response-api/assets/slide_creator/templates/63/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/63/bullets.html b/services/response-api/assets/slide_creator/templates/63/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/63/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/63/chart.html b/services/response-api/assets/slide_creator/templates/63/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/63/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/63/hero.html b/services/response-api/assets/slide_creator/templates/63/hero.html
deleted file mode 100644
index dafda5d3..00000000
--- a/services/response-api/assets/slide_creator/templates/63/hero.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 150}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/63/llm.html b/services/response-api/assets/slide_creator/templates/63/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/63/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/63/meta.json b/services/response-api/assets/slide_creator/templates/63/meta.json
deleted file mode 100644
index c57bfe42..00000000
--- a/services/response-api/assets/slide_creator/templates/63/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 63,
- "dir": "63",
- "name": "Brand Burst",
- "tone": "Marketing Vibrant",
- "description": "Top band + punchy accents; campaign and brand stories.",
- "variants": {
- "base": 4,
- "bullets": 3,
- "split": 5,
- "hero": 3,
- "title": 3
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/63/split.html b/services/response-api/assets/slide_creator/templates/63/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/63/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/63/table.html b/services/response-api/assets/slide_creator/templates/63/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/63/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/63/title.html b/services/response-api/assets/slide_creator/templates/63/title.html
deleted file mode 100644
index 45161794..00000000
--- a/services/response-api/assets/slide_creator/templates/63/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
-
- Slide {{.Index}}/{{.Total}}
- {{if .Title.Notes}}{{trimToRunes .Title.Notes 90}} {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/64/base.html b/services/response-api/assets/slide_creator/templates/64/base.html
deleted file mode 100644
index 1608815d..00000000
--- a/services/response-api/assets/slide_creator/templates/64/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/64/bullets.html b/services/response-api/assets/slide_creator/templates/64/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/64/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/64/chart.html b/services/response-api/assets/slide_creator/templates/64/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/64/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/64/hero.html b/services/response-api/assets/slide_creator/templates/64/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/64/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/64/llm.html b/services/response-api/assets/slide_creator/templates/64/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/64/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/64/meta.json b/services/response-api/assets/slide_creator/templates/64/meta.json
deleted file mode 100644
index 07db166f..00000000
--- a/services/response-api/assets/slide_creator/templates/64/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 64,
- "dir": "64",
- "name": "Creative Ad",
- "tone": "Marketing Vibrant",
- "description": "Top band + punchy accents; campaign and brand stories.",
- "variants": {
- "base": 4,
- "bullets": 4,
- "split": 1,
- "hero": 1,
- "title": 4
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/64/split.html b/services/response-api/assets/slide_creator/templates/64/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/64/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/64/table.html b/services/response-api/assets/slide_creator/templates/64/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/64/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/64/title.html b/services/response-api/assets/slide_creator/templates/64/title.html
deleted file mode 100644
index fcdc0d92..00000000
--- a/services/response-api/assets/slide_creator/templates/64/title.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
{{.Index}}
-
of {{.Total}}
-
-
-
{{.Plan.Title}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 90}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/65/base.html b/services/response-api/assets/slide_creator/templates/65/base.html
deleted file mode 100644
index 1608815d..00000000
--- a/services/response-api/assets/slide_creator/templates/65/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/65/bullets.html b/services/response-api/assets/slide_creator/templates/65/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/65/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/65/chart.html b/services/response-api/assets/slide_creator/templates/65/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/65/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/65/hero.html b/services/response-api/assets/slide_creator/templates/65/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/65/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/65/llm.html b/services/response-api/assets/slide_creator/templates/65/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/65/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/65/meta.json b/services/response-api/assets/slide_creator/templates/65/meta.json
deleted file mode 100644
index 71cf4c02..00000000
--- a/services/response-api/assets/slide_creator/templates/65/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 65,
- "dir": "65",
- "name": "Launch Creative",
- "tone": "Marketing Vibrant",
- "description": "Top band + punchy accents; campaign and brand stories.",
- "variants": {
- "base": 4,
- "bullets": 5,
- "split": 2,
- "hero": 2,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/65/split.html b/services/response-api/assets/slide_creator/templates/65/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/65/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/65/table.html b/services/response-api/assets/slide_creator/templates/65/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/65/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/65/title.html b/services/response-api/assets/slide_creator/templates/65/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/65/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/66/base.html b/services/response-api/assets/slide_creator/templates/66/base.html
deleted file mode 100644
index 9bcb057f..00000000
--- a/services/response-api/assets/slide_creator/templates/66/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/66/bullets.html b/services/response-api/assets/slide_creator/templates/66/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/66/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/66/chart.html b/services/response-api/assets/slide_creator/templates/66/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/66/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/66/hero.html b/services/response-api/assets/slide_creator/templates/66/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/66/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/66/llm.html b/services/response-api/assets/slide_creator/templates/66/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/66/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/66/meta.json b/services/response-api/assets/slide_creator/templates/66/meta.json
deleted file mode 100644
index 31ec02e5..00000000
--- a/services/response-api/assets/slide_creator/templates/66/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 66,
- "dir": "66",
- "name": "Dashboard",
- "tone": "Data Analyst",
- "description": "Grid-forward layout for charts/tables and analytic narratives.",
- "variants": {
- "base": 6,
- "bullets": 1,
- "split": 4,
- "hero": 1,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/66/split.html b/services/response-api/assets/slide_creator/templates/66/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/66/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/66/table.html b/services/response-api/assets/slide_creator/templates/66/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/66/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/66/title.html b/services/response-api/assets/slide_creator/templates/66/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/66/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/67/base.html b/services/response-api/assets/slide_creator/templates/67/base.html
deleted file mode 100644
index 9bcb057f..00000000
--- a/services/response-api/assets/slide_creator/templates/67/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/67/bullets.html b/services/response-api/assets/slide_creator/templates/67/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/67/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/67/chart.html b/services/response-api/assets/slide_creator/templates/67/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/67/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/67/hero.html b/services/response-api/assets/slide_creator/templates/67/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/67/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/67/llm.html b/services/response-api/assets/slide_creator/templates/67/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/67/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/67/meta.json b/services/response-api/assets/slide_creator/templates/67/meta.json
deleted file mode 100644
index 44aaa5ec..00000000
--- a/services/response-api/assets/slide_creator/templates/67/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 67,
- "dir": "67",
- "name": "Gridline",
- "tone": "Data Analyst",
- "description": "Grid-forward layout for charts/tables and analytic narratives.",
- "variants": {
- "base": 6,
- "bullets": 2,
- "split": 5,
- "hero": 2,
- "title": 2
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/67/split.html b/services/response-api/assets/slide_creator/templates/67/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/67/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/67/table.html b/services/response-api/assets/slide_creator/templates/67/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/67/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/67/title.html b/services/response-api/assets/slide_creator/templates/67/title.html
deleted file mode 100644
index e4e39fb6..00000000
--- a/services/response-api/assets/slide_creator/templates/67/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
Slide {{.Index}} / {{.Total}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/68/base.html b/services/response-api/assets/slide_creator/templates/68/base.html
deleted file mode 100644
index 9bcb057f..00000000
--- a/services/response-api/assets/slide_creator/templates/68/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/68/bullets.html b/services/response-api/assets/slide_creator/templates/68/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/68/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/68/chart.html b/services/response-api/assets/slide_creator/templates/68/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/68/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/68/hero.html b/services/response-api/assets/slide_creator/templates/68/hero.html
deleted file mode 100644
index dafda5d3..00000000
--- a/services/response-api/assets/slide_creator/templates/68/hero.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 150}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/68/llm.html b/services/response-api/assets/slide_creator/templates/68/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/68/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/68/meta.json b/services/response-api/assets/slide_creator/templates/68/meta.json
deleted file mode 100644
index 87ba06f5..00000000
--- a/services/response-api/assets/slide_creator/templates/68/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 68,
- "dir": "68",
- "name": "Analytics",
- "tone": "Data Analyst",
- "description": "Grid-forward layout for charts/tables and analytic narratives.",
- "variants": {
- "base": 6,
- "bullets": 3,
- "split": 1,
- "hero": 3,
- "title": 3
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/68/split.html b/services/response-api/assets/slide_creator/templates/68/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/68/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/68/table.html b/services/response-api/assets/slide_creator/templates/68/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/68/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/68/title.html b/services/response-api/assets/slide_creator/templates/68/title.html
deleted file mode 100644
index 45161794..00000000
--- a/services/response-api/assets/slide_creator/templates/68/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
-
- Slide {{.Index}}/{{.Total}}
- {{if .Title.Notes}}{{trimToRunes .Title.Notes 90}} {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/69/base.html b/services/response-api/assets/slide_creator/templates/69/base.html
deleted file mode 100644
index 9bcb057f..00000000
--- a/services/response-api/assets/slide_creator/templates/69/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/69/bullets.html b/services/response-api/assets/slide_creator/templates/69/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/69/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/69/chart.html b/services/response-api/assets/slide_creator/templates/69/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/69/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/69/hero.html b/services/response-api/assets/slide_creator/templates/69/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/69/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/69/llm.html b/services/response-api/assets/slide_creator/templates/69/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/69/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/69/meta.json b/services/response-api/assets/slide_creator/templates/69/meta.json
deleted file mode 100644
index a9e40c29..00000000
--- a/services/response-api/assets/slide_creator/templates/69/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 69,
- "dir": "69",
- "name": "Insight Pack",
- "tone": "Data Analyst",
- "description": "Grid-forward layout for charts/tables and analytic narratives.",
- "variants": {
- "base": 6,
- "bullets": 4,
- "split": 2,
- "hero": 1,
- "title": 4
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/69/split.html b/services/response-api/assets/slide_creator/templates/69/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/69/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/69/table.html b/services/response-api/assets/slide_creator/templates/69/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/69/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/69/title.html b/services/response-api/assets/slide_creator/templates/69/title.html
deleted file mode 100644
index fcdc0d92..00000000
--- a/services/response-api/assets/slide_creator/templates/69/title.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
{{.Index}}
-
of {{.Total}}
-
-
-
{{.Plan.Title}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 90}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/7/base.html b/services/response-api/assets/slide_creator/templates/7/base.html
deleted file mode 100644
index cbd839f2..00000000
--- a/services/response-api/assets/slide_creator/templates/7/base.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/7/bullets.html b/services/response-api/assets/slide_creator/templates/7/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/7/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/7/chart.html b/services/response-api/assets/slide_creator/templates/7/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/7/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/7/hero.html b/services/response-api/assets/slide_creator/templates/7/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/7/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/7/llm.html b/services/response-api/assets/slide_creator/templates/7/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/7/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/7/meta.json b/services/response-api/assets/slide_creator/templates/7/meta.json
deleted file mode 100644
index 6903b3bf..00000000
--- a/services/response-api/assets/slide_creator/templates/7/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 7,
- "dir": "7",
- "name": "Stone Minimal",
- "tone": "Minimal Clean",
- "description": "Whitespace-forward, neutral framing, restrained accents.",
- "variants": {
- "base": 2,
- "bullets": 2,
- "split": 3,
- "hero": 2,
- "title": 2
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/7/split.html b/services/response-api/assets/slide_creator/templates/7/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/7/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/7/table.html b/services/response-api/assets/slide_creator/templates/7/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/7/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/7/title.html b/services/response-api/assets/slide_creator/templates/7/title.html
deleted file mode 100644
index e4e39fb6..00000000
--- a/services/response-api/assets/slide_creator/templates/7/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
Slide {{.Index}} / {{.Total}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/70/base.html b/services/response-api/assets/slide_creator/templates/70/base.html
deleted file mode 100644
index 9bcb057f..00000000
--- a/services/response-api/assets/slide_creator/templates/70/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/70/bullets.html b/services/response-api/assets/slide_creator/templates/70/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/70/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/70/chart.html b/services/response-api/assets/slide_creator/templates/70/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/70/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/70/hero.html b/services/response-api/assets/slide_creator/templates/70/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/70/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/70/llm.html b/services/response-api/assets/slide_creator/templates/70/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/70/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/70/meta.json b/services/response-api/assets/slide_creator/templates/70/meta.json
deleted file mode 100644
index bb16b0a0..00000000
--- a/services/response-api/assets/slide_creator/templates/70/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 70,
- "dir": "70",
- "name": "Metrics Review",
- "tone": "Data Analyst",
- "description": "Grid-forward layout for charts/tables and analytic narratives.",
- "variants": {
- "base": 6,
- "bullets": 5,
- "split": 3,
- "hero": 2,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/70/split.html b/services/response-api/assets/slide_creator/templates/70/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/70/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/70/table.html b/services/response-api/assets/slide_creator/templates/70/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/70/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/70/title.html b/services/response-api/assets/slide_creator/templates/70/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/70/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/71/base.html b/services/response-api/assets/slide_creator/templates/71/base.html
deleted file mode 100644
index 7dc1fc61..00000000
--- a/services/response-api/assets/slide_creator/templates/71/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/71/bullets.html b/services/response-api/assets/slide_creator/templates/71/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/71/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/71/chart.html b/services/response-api/assets/slide_creator/templates/71/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/71/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/71/hero.html b/services/response-api/assets/slide_creator/templates/71/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/71/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/71/llm.html b/services/response-api/assets/slide_creator/templates/71/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/71/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/71/meta.json b/services/response-api/assets/slide_creator/templates/71/meta.json
deleted file mode 100644
index 6198469f..00000000
--- a/services/response-api/assets/slide_creator/templates/71/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 71,
- "dir": "71",
- "name": "Retro Wave",
- "tone": "Retro",
- "description": "Dot pattern + playful framing; retro/nostalgia tone.",
- "variants": {
- "base": 7,
- "bullets": 1,
- "split": 5,
- "hero": 1,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/71/split.html b/services/response-api/assets/slide_creator/templates/71/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/71/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/71/table.html b/services/response-api/assets/slide_creator/templates/71/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/71/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/71/title.html b/services/response-api/assets/slide_creator/templates/71/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/71/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/72/base.html b/services/response-api/assets/slide_creator/templates/72/base.html
deleted file mode 100644
index 7dc1fc61..00000000
--- a/services/response-api/assets/slide_creator/templates/72/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/72/bullets.html b/services/response-api/assets/slide_creator/templates/72/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/72/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/72/chart.html b/services/response-api/assets/slide_creator/templates/72/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/72/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/72/hero.html b/services/response-api/assets/slide_creator/templates/72/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/72/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/72/llm.html b/services/response-api/assets/slide_creator/templates/72/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/72/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/72/meta.json b/services/response-api/assets/slide_creator/templates/72/meta.json
deleted file mode 100644
index 733eb46c..00000000
--- a/services/response-api/assets/slide_creator/templates/72/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 72,
- "dir": "72",
- "name": "Cassette",
- "tone": "Retro",
- "description": "Dot pattern + playful framing; retro/nostalgia tone.",
- "variants": {
- "base": 7,
- "bullets": 2,
- "split": 1,
- "hero": 2,
- "title": 2
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/72/split.html b/services/response-api/assets/slide_creator/templates/72/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/72/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/72/table.html b/services/response-api/assets/slide_creator/templates/72/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/72/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/72/title.html b/services/response-api/assets/slide_creator/templates/72/title.html
deleted file mode 100644
index e4e39fb6..00000000
--- a/services/response-api/assets/slide_creator/templates/72/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
Slide {{.Index}} / {{.Total}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/73/base.html b/services/response-api/assets/slide_creator/templates/73/base.html
deleted file mode 100644
index 7dc1fc61..00000000
--- a/services/response-api/assets/slide_creator/templates/73/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/73/bullets.html b/services/response-api/assets/slide_creator/templates/73/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/73/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/73/chart.html b/services/response-api/assets/slide_creator/templates/73/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/73/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/73/hero.html b/services/response-api/assets/slide_creator/templates/73/hero.html
deleted file mode 100644
index dafda5d3..00000000
--- a/services/response-api/assets/slide_creator/templates/73/hero.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 150}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/73/llm.html b/services/response-api/assets/slide_creator/templates/73/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/73/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/73/meta.json b/services/response-api/assets/slide_creator/templates/73/meta.json
deleted file mode 100644
index 9826120b..00000000
--- a/services/response-api/assets/slide_creator/templates/73/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 73,
- "dir": "73",
- "name": "Polaroid",
- "tone": "Retro",
- "description": "Dot pattern + playful framing; retro/nostalgia tone.",
- "variants": {
- "base": 7,
- "bullets": 3,
- "split": 2,
- "hero": 3,
- "title": 3
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/73/split.html b/services/response-api/assets/slide_creator/templates/73/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/73/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/73/table.html b/services/response-api/assets/slide_creator/templates/73/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/73/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/73/title.html b/services/response-api/assets/slide_creator/templates/73/title.html
deleted file mode 100644
index 45161794..00000000
--- a/services/response-api/assets/slide_creator/templates/73/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
-
- Slide {{.Index}}/{{.Total}}
- {{if .Title.Notes}}{{trimToRunes .Title.Notes 90}} {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/74/base.html b/services/response-api/assets/slide_creator/templates/74/base.html
deleted file mode 100644
index 7dc1fc61..00000000
--- a/services/response-api/assets/slide_creator/templates/74/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/74/bullets.html b/services/response-api/assets/slide_creator/templates/74/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/74/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/74/chart.html b/services/response-api/assets/slide_creator/templates/74/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/74/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/74/hero.html b/services/response-api/assets/slide_creator/templates/74/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/74/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/74/llm.html b/services/response-api/assets/slide_creator/templates/74/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/74/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/74/meta.json b/services/response-api/assets/slide_creator/templates/74/meta.json
deleted file mode 100644
index aa96bcdb..00000000
--- a/services/response-api/assets/slide_creator/templates/74/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 74,
- "dir": "74",
- "name": "Arcade",
- "tone": "Retro",
- "description": "Dot pattern + playful framing; retro/nostalgia tone.",
- "variants": {
- "base": 7,
- "bullets": 4,
- "split": 3,
- "hero": 1,
- "title": 4
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/74/split.html b/services/response-api/assets/slide_creator/templates/74/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/74/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/74/table.html b/services/response-api/assets/slide_creator/templates/74/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/74/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/74/title.html b/services/response-api/assets/slide_creator/templates/74/title.html
deleted file mode 100644
index fcdc0d92..00000000
--- a/services/response-api/assets/slide_creator/templates/74/title.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
{{.Index}}
-
of {{.Total}}
-
-
-
{{.Plan.Title}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 90}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/75/base.html b/services/response-api/assets/slide_creator/templates/75/base.html
deleted file mode 100644
index 7dc1fc61..00000000
--- a/services/response-api/assets/slide_creator/templates/75/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/75/bullets.html b/services/response-api/assets/slide_creator/templates/75/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/75/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/75/chart.html b/services/response-api/assets/slide_creator/templates/75/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/75/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/75/hero.html b/services/response-api/assets/slide_creator/templates/75/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/75/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/75/llm.html b/services/response-api/assets/slide_creator/templates/75/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/75/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/75/meta.json b/services/response-api/assets/slide_creator/templates/75/meta.json
deleted file mode 100644
index e6630272..00000000
--- a/services/response-api/assets/slide_creator/templates/75/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 75,
- "dir": "75",
- "name": "Vintage Print",
- "tone": "Retro",
- "description": "Dot pattern + playful framing; retro/nostalgia tone.",
- "variants": {
- "base": 7,
- "bullets": 5,
- "split": 4,
- "hero": 2,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/75/split.html b/services/response-api/assets/slide_creator/templates/75/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/75/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/75/table.html b/services/response-api/assets/slide_creator/templates/75/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/75/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/75/title.html b/services/response-api/assets/slide_creator/templates/75/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/75/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/76/base.html b/services/response-api/assets/slide_creator/templates/76/base.html
deleted file mode 100644
index cbd839f2..00000000
--- a/services/response-api/assets/slide_creator/templates/76/base.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/76/bullets.html b/services/response-api/assets/slide_creator/templates/76/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/76/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/76/chart.html b/services/response-api/assets/slide_creator/templates/76/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/76/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/76/hero.html b/services/response-api/assets/slide_creator/templates/76/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/76/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/76/llm.html b/services/response-api/assets/slide_creator/templates/76/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/76/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/76/meta.json b/services/response-api/assets/slide_creator/templates/76/meta.json
deleted file mode 100644
index 904fa199..00000000
--- a/services/response-api/assets/slide_creator/templates/76/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 76,
- "dir": "76",
- "name": "Mono Black",
- "tone": "Monochrome",
- "description": "Minimal frame tuned for black/white/gray palettes.",
- "variants": {
- "base": 2,
- "bullets": 1,
- "split": 1,
- "hero": 1,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/76/split.html b/services/response-api/assets/slide_creator/templates/76/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/76/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/76/table.html b/services/response-api/assets/slide_creator/templates/76/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/76/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/76/title.html b/services/response-api/assets/slide_creator/templates/76/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/76/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/77/base.html b/services/response-api/assets/slide_creator/templates/77/base.html
deleted file mode 100644
index cbd839f2..00000000
--- a/services/response-api/assets/slide_creator/templates/77/base.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/77/bullets.html b/services/response-api/assets/slide_creator/templates/77/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/77/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/77/chart.html b/services/response-api/assets/slide_creator/templates/77/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/77/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/77/hero.html b/services/response-api/assets/slide_creator/templates/77/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/77/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/77/llm.html b/services/response-api/assets/slide_creator/templates/77/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/77/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/77/meta.json b/services/response-api/assets/slide_creator/templates/77/meta.json
deleted file mode 100644
index b22b2558..00000000
--- a/services/response-api/assets/slide_creator/templates/77/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 77,
- "dir": "77",
- "name": "Mono White",
- "tone": "Monochrome",
- "description": "Minimal frame tuned for black/white/gray palettes.",
- "variants": {
- "base": 2,
- "bullets": 2,
- "split": 2,
- "hero": 2,
- "title": 2
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/77/split.html b/services/response-api/assets/slide_creator/templates/77/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/77/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/77/table.html b/services/response-api/assets/slide_creator/templates/77/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/77/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/77/title.html b/services/response-api/assets/slide_creator/templates/77/title.html
deleted file mode 100644
index e4e39fb6..00000000
--- a/services/response-api/assets/slide_creator/templates/77/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
Slide {{.Index}} / {{.Total}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/78/base.html b/services/response-api/assets/slide_creator/templates/78/base.html
deleted file mode 100644
index cbd839f2..00000000
--- a/services/response-api/assets/slide_creator/templates/78/base.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/78/bullets.html b/services/response-api/assets/slide_creator/templates/78/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/78/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/78/chart.html b/services/response-api/assets/slide_creator/templates/78/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/78/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/78/hero.html b/services/response-api/assets/slide_creator/templates/78/hero.html
deleted file mode 100644
index dafda5d3..00000000
--- a/services/response-api/assets/slide_creator/templates/78/hero.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 150}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/78/llm.html b/services/response-api/assets/slide_creator/templates/78/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/78/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/78/meta.json b/services/response-api/assets/slide_creator/templates/78/meta.json
deleted file mode 100644
index 505bc3fe..00000000
--- a/services/response-api/assets/slide_creator/templates/78/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 78,
- "dir": "78",
- "name": "Grayscale",
- "tone": "Monochrome",
- "description": "Minimal frame tuned for black/white/gray palettes.",
- "variants": {
- "base": 2,
- "bullets": 3,
- "split": 3,
- "hero": 3,
- "title": 3
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/78/split.html b/services/response-api/assets/slide_creator/templates/78/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/78/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/78/table.html b/services/response-api/assets/slide_creator/templates/78/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/78/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/78/title.html b/services/response-api/assets/slide_creator/templates/78/title.html
deleted file mode 100644
index 45161794..00000000
--- a/services/response-api/assets/slide_creator/templates/78/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
-
- Slide {{.Index}}/{{.Total}}
- {{if .Title.Notes}}{{trimToRunes .Title.Notes 90}} {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/79/base.html b/services/response-api/assets/slide_creator/templates/79/base.html
deleted file mode 100644
index cbd839f2..00000000
--- a/services/response-api/assets/slide_creator/templates/79/base.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/79/bullets.html b/services/response-api/assets/slide_creator/templates/79/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/79/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/79/chart.html b/services/response-api/assets/slide_creator/templates/79/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/79/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/79/hero.html b/services/response-api/assets/slide_creator/templates/79/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/79/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/79/llm.html b/services/response-api/assets/slide_creator/templates/79/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/79/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/79/meta.json b/services/response-api/assets/slide_creator/templates/79/meta.json
deleted file mode 100644
index 86115042..00000000
--- a/services/response-api/assets/slide_creator/templates/79/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 79,
- "dir": "79",
- "name": "Ink",
- "tone": "Monochrome",
- "description": "Minimal frame tuned for black/white/gray palettes.",
- "variants": {
- "base": 2,
- "bullets": 4,
- "split": 4,
- "hero": 1,
- "title": 4
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/79/split.html b/services/response-api/assets/slide_creator/templates/79/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/79/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/79/table.html b/services/response-api/assets/slide_creator/templates/79/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/79/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/79/title.html b/services/response-api/assets/slide_creator/templates/79/title.html
deleted file mode 100644
index fcdc0d92..00000000
--- a/services/response-api/assets/slide_creator/templates/79/title.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
{{.Index}}
-
of {{.Total}}
-
-
-
{{.Plan.Title}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 90}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/8/base.html b/services/response-api/assets/slide_creator/templates/8/base.html
deleted file mode 100644
index cbd839f2..00000000
--- a/services/response-api/assets/slide_creator/templates/8/base.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/8/bullets.html b/services/response-api/assets/slide_creator/templates/8/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/8/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/8/chart.html b/services/response-api/assets/slide_creator/templates/8/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/8/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/8/hero.html b/services/response-api/assets/slide_creator/templates/8/hero.html
deleted file mode 100644
index dafda5d3..00000000
--- a/services/response-api/assets/slide_creator/templates/8/hero.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 150}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/8/llm.html b/services/response-api/assets/slide_creator/templates/8/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/8/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/8/meta.json b/services/response-api/assets/slide_creator/templates/8/meta.json
deleted file mode 100644
index f95bd95a..00000000
--- a/services/response-api/assets/slide_creator/templates/8/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 8,
- "dir": "8",
- "name": "Cloud Minimal",
- "tone": "Minimal Clean",
- "description": "Whitespace-forward, neutral framing, restrained accents.",
- "variants": {
- "base": 2,
- "bullets": 3,
- "split": 4,
- "hero": 3,
- "title": 3
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/8/split.html b/services/response-api/assets/slide_creator/templates/8/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/8/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/8/table.html b/services/response-api/assets/slide_creator/templates/8/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/8/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/8/title.html b/services/response-api/assets/slide_creator/templates/8/title.html
deleted file mode 100644
index 45161794..00000000
--- a/services/response-api/assets/slide_creator/templates/8/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
-
- Slide {{.Index}}/{{.Total}}
- {{if .Title.Notes}}{{trimToRunes .Title.Notes 90}} {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/80/base.html b/services/response-api/assets/slide_creator/templates/80/base.html
deleted file mode 100644
index cbd839f2..00000000
--- a/services/response-api/assets/slide_creator/templates/80/base.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/80/bullets.html b/services/response-api/assets/slide_creator/templates/80/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/80/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/80/chart.html b/services/response-api/assets/slide_creator/templates/80/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/80/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/80/hero.html b/services/response-api/assets/slide_creator/templates/80/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/80/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/80/llm.html b/services/response-api/assets/slide_creator/templates/80/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/80/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/80/meta.json b/services/response-api/assets/slide_creator/templates/80/meta.json
deleted file mode 100644
index 96c1454d..00000000
--- a/services/response-api/assets/slide_creator/templates/80/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 80,
- "dir": "80",
- "name": "Charcoal",
- "tone": "Monochrome",
- "description": "Minimal frame tuned for black/white/gray palettes.",
- "variants": {
- "base": 2,
- "bullets": 5,
- "split": 5,
- "hero": 2,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/80/split.html b/services/response-api/assets/slide_creator/templates/80/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/80/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/80/table.html b/services/response-api/assets/slide_creator/templates/80/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/80/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/80/title.html b/services/response-api/assets/slide_creator/templates/80/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/80/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/81/base.html b/services/response-api/assets/slide_creator/templates/81/base.html
deleted file mode 100644
index 1608815d..00000000
--- a/services/response-api/assets/slide_creator/templates/81/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/81/bullets.html b/services/response-api/assets/slide_creator/templates/81/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/81/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/81/chart.html b/services/response-api/assets/slide_creator/templates/81/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/81/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/81/hero.html b/services/response-api/assets/slide_creator/templates/81/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/81/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/81/llm.html b/services/response-api/assets/slide_creator/templates/81/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/81/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/81/meta.json b/services/response-api/assets/slide_creator/templates/81/meta.json
deleted file mode 100644
index 6a110c2b..00000000
--- a/services/response-api/assets/slide_creator/templates/81/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 81,
- "dir": "81",
- "name": "Gradient Flow",
- "tone": "Gradient Modern",
- "description": "Band gradient + modern spacing; works with gradient palettes.",
- "variants": {
- "base": 4,
- "bullets": 1,
- "split": 2,
- "hero": 1,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/81/split.html b/services/response-api/assets/slide_creator/templates/81/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/81/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/81/table.html b/services/response-api/assets/slide_creator/templates/81/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/81/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/81/title.html b/services/response-api/assets/slide_creator/templates/81/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/81/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/82/base.html b/services/response-api/assets/slide_creator/templates/82/base.html
deleted file mode 100644
index 1608815d..00000000
--- a/services/response-api/assets/slide_creator/templates/82/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/82/bullets.html b/services/response-api/assets/slide_creator/templates/82/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/82/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/82/chart.html b/services/response-api/assets/slide_creator/templates/82/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/82/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/82/hero.html b/services/response-api/assets/slide_creator/templates/82/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/82/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/82/llm.html b/services/response-api/assets/slide_creator/templates/82/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/82/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/82/meta.json b/services/response-api/assets/slide_creator/templates/82/meta.json
deleted file mode 100644
index 46f844d6..00000000
--- a/services/response-api/assets/slide_creator/templates/82/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 82,
- "dir": "82",
- "name": "Sunrise",
- "tone": "Gradient Modern",
- "description": "Band gradient + modern spacing; works with gradient palettes.",
- "variants": {
- "base": 4,
- "bullets": 2,
- "split": 3,
- "hero": 2,
- "title": 2
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/82/split.html b/services/response-api/assets/slide_creator/templates/82/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/82/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/82/table.html b/services/response-api/assets/slide_creator/templates/82/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/82/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/82/title.html b/services/response-api/assets/slide_creator/templates/82/title.html
deleted file mode 100644
index e4e39fb6..00000000
--- a/services/response-api/assets/slide_creator/templates/82/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
Slide {{.Index}} / {{.Total}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/83/base.html b/services/response-api/assets/slide_creator/templates/83/base.html
deleted file mode 100644
index 1608815d..00000000
--- a/services/response-api/assets/slide_creator/templates/83/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/83/bullets.html b/services/response-api/assets/slide_creator/templates/83/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/83/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/83/chart.html b/services/response-api/assets/slide_creator/templates/83/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/83/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/83/hero.html b/services/response-api/assets/slide_creator/templates/83/hero.html
deleted file mode 100644
index dafda5d3..00000000
--- a/services/response-api/assets/slide_creator/templates/83/hero.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 150}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/83/llm.html b/services/response-api/assets/slide_creator/templates/83/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/83/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/83/meta.json b/services/response-api/assets/slide_creator/templates/83/meta.json
deleted file mode 100644
index 76236bf5..00000000
--- a/services/response-api/assets/slide_creator/templates/83/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 83,
- "dir": "83",
- "name": "Aurora Modern",
- "tone": "Gradient Modern",
- "description": "Band gradient + modern spacing; works with gradient palettes.",
- "variants": {
- "base": 4,
- "bullets": 3,
- "split": 4,
- "hero": 3,
- "title": 3
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/83/split.html b/services/response-api/assets/slide_creator/templates/83/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/83/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/83/table.html b/services/response-api/assets/slide_creator/templates/83/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/83/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/83/title.html b/services/response-api/assets/slide_creator/templates/83/title.html
deleted file mode 100644
index 45161794..00000000
--- a/services/response-api/assets/slide_creator/templates/83/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
-
- Slide {{.Index}}/{{.Total}}
- {{if .Title.Notes}}{{trimToRunes .Title.Notes 90}} {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/84/base.html b/services/response-api/assets/slide_creator/templates/84/base.html
deleted file mode 100644
index 1608815d..00000000
--- a/services/response-api/assets/slide_creator/templates/84/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/84/bullets.html b/services/response-api/assets/slide_creator/templates/84/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/84/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/84/chart.html b/services/response-api/assets/slide_creator/templates/84/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/84/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/84/hero.html b/services/response-api/assets/slide_creator/templates/84/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/84/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/84/llm.html b/services/response-api/assets/slide_creator/templates/84/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/84/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/84/meta.json b/services/response-api/assets/slide_creator/templates/84/meta.json
deleted file mode 100644
index a9d46d40..00000000
--- a/services/response-api/assets/slide_creator/templates/84/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 84,
- "dir": "84",
- "name": "Spectrum",
- "tone": "Gradient Modern",
- "description": "Band gradient + modern spacing; works with gradient palettes.",
- "variants": {
- "base": 4,
- "bullets": 4,
- "split": 5,
- "hero": 1,
- "title": 4
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/84/split.html b/services/response-api/assets/slide_creator/templates/84/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/84/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/84/table.html b/services/response-api/assets/slide_creator/templates/84/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/84/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/84/title.html b/services/response-api/assets/slide_creator/templates/84/title.html
deleted file mode 100644
index fcdc0d92..00000000
--- a/services/response-api/assets/slide_creator/templates/84/title.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
{{.Index}}
-
of {{.Total}}
-
-
-
{{.Plan.Title}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 90}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/85/base.html b/services/response-api/assets/slide_creator/templates/85/base.html
deleted file mode 100644
index 1608815d..00000000
--- a/services/response-api/assets/slide_creator/templates/85/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/85/bullets.html b/services/response-api/assets/slide_creator/templates/85/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/85/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/85/chart.html b/services/response-api/assets/slide_creator/templates/85/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/85/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/85/hero.html b/services/response-api/assets/slide_creator/templates/85/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/85/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/85/llm.html b/services/response-api/assets/slide_creator/templates/85/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/85/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/85/meta.json b/services/response-api/assets/slide_creator/templates/85/meta.json
deleted file mode 100644
index 8398eb33..00000000
--- a/services/response-api/assets/slide_creator/templates/85/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 85,
- "dir": "85",
- "name": "Horizon",
- "tone": "Gradient Modern",
- "description": "Band gradient + modern spacing; works with gradient palettes.",
- "variants": {
- "base": 4,
- "bullets": 5,
- "split": 1,
- "hero": 2,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/85/split.html b/services/response-api/assets/slide_creator/templates/85/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/85/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/85/table.html b/services/response-api/assets/slide_creator/templates/85/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/85/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/85/title.html b/services/response-api/assets/slide_creator/templates/85/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/85/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/86/base.html b/services/response-api/assets/slide_creator/templates/86/base.html
deleted file mode 100644
index 982ae99a..00000000
--- a/services/response-api/assets/slide_creator/templates/86/base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/86/bullets.html b/services/response-api/assets/slide_creator/templates/86/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/86/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/86/chart.html b/services/response-api/assets/slide_creator/templates/86/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/86/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/86/hero.html b/services/response-api/assets/slide_creator/templates/86/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/86/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/86/llm.html b/services/response-api/assets/slide_creator/templates/86/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/86/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/86/meta.json b/services/response-api/assets/slide_creator/templates/86/meta.json
deleted file mode 100644
index 48a6aa60..00000000
--- a/services/response-api/assets/slide_creator/templates/86/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 86,
- "dir": "86",
- "name": "Public Brief",
- "tone": "Government/Public Sector",
- "description": "Formal, legible, and conservative layout for public comms.",
- "variants": {
- "base": 9,
- "bullets": 1,
- "split": 3,
- "hero": 1,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/86/split.html b/services/response-api/assets/slide_creator/templates/86/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/86/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/86/table.html b/services/response-api/assets/slide_creator/templates/86/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/86/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/86/title.html b/services/response-api/assets/slide_creator/templates/86/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/86/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/87/base.html b/services/response-api/assets/slide_creator/templates/87/base.html
deleted file mode 100644
index 982ae99a..00000000
--- a/services/response-api/assets/slide_creator/templates/87/base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/87/bullets.html b/services/response-api/assets/slide_creator/templates/87/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/87/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/87/chart.html b/services/response-api/assets/slide_creator/templates/87/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/87/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/87/hero.html b/services/response-api/assets/slide_creator/templates/87/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/87/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/87/llm.html b/services/response-api/assets/slide_creator/templates/87/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/87/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/87/meta.json b/services/response-api/assets/slide_creator/templates/87/meta.json
deleted file mode 100644
index 5760bacd..00000000
--- a/services/response-api/assets/slide_creator/templates/87/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 87,
- "dir": "87",
- "name": "Policy Note",
- "tone": "Government/Public Sector",
- "description": "Formal, legible, and conservative layout for public comms.",
- "variants": {
- "base": 9,
- "bullets": 2,
- "split": 4,
- "hero": 2,
- "title": 2
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/87/split.html b/services/response-api/assets/slide_creator/templates/87/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/87/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/87/table.html b/services/response-api/assets/slide_creator/templates/87/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/87/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/87/title.html b/services/response-api/assets/slide_creator/templates/87/title.html
deleted file mode 100644
index e4e39fb6..00000000
--- a/services/response-api/assets/slide_creator/templates/87/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
Slide {{.Index}} / {{.Total}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/88/base.html b/services/response-api/assets/slide_creator/templates/88/base.html
deleted file mode 100644
index 982ae99a..00000000
--- a/services/response-api/assets/slide_creator/templates/88/base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/88/bullets.html b/services/response-api/assets/slide_creator/templates/88/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/88/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/88/chart.html b/services/response-api/assets/slide_creator/templates/88/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/88/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/88/hero.html b/services/response-api/assets/slide_creator/templates/88/hero.html
deleted file mode 100644
index dafda5d3..00000000
--- a/services/response-api/assets/slide_creator/templates/88/hero.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 150}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/88/llm.html b/services/response-api/assets/slide_creator/templates/88/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/88/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/88/meta.json b/services/response-api/assets/slide_creator/templates/88/meta.json
deleted file mode 100644
index 116aff00..00000000
--- a/services/response-api/assets/slide_creator/templates/88/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 88,
- "dir": "88",
- "name": "Civic Update",
- "tone": "Government/Public Sector",
- "description": "Formal, legible, and conservative layout for public comms.",
- "variants": {
- "base": 9,
- "bullets": 3,
- "split": 5,
- "hero": 3,
- "title": 3
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/88/split.html b/services/response-api/assets/slide_creator/templates/88/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/88/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/88/table.html b/services/response-api/assets/slide_creator/templates/88/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/88/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/88/title.html b/services/response-api/assets/slide_creator/templates/88/title.html
deleted file mode 100644
index 45161794..00000000
--- a/services/response-api/assets/slide_creator/templates/88/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
-
- Slide {{.Index}}/{{.Total}}
- {{if .Title.Notes}}{{trimToRunes .Title.Notes 90}} {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/89/base.html b/services/response-api/assets/slide_creator/templates/89/base.html
deleted file mode 100644
index 982ae99a..00000000
--- a/services/response-api/assets/slide_creator/templates/89/base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/89/bullets.html b/services/response-api/assets/slide_creator/templates/89/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/89/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/89/chart.html b/services/response-api/assets/slide_creator/templates/89/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/89/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/89/hero.html b/services/response-api/assets/slide_creator/templates/89/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/89/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/89/llm.html b/services/response-api/assets/slide_creator/templates/89/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/89/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/89/meta.json b/services/response-api/assets/slide_creator/templates/89/meta.json
deleted file mode 100644
index 997dc715..00000000
--- a/services/response-api/assets/slide_creator/templates/89/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 89,
- "dir": "89",
- "name": "Agency Report",
- "tone": "Government/Public Sector",
- "description": "Formal, legible, and conservative layout for public comms.",
- "variants": {
- "base": 9,
- "bullets": 4,
- "split": 1,
- "hero": 1,
- "title": 4
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/89/split.html b/services/response-api/assets/slide_creator/templates/89/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/89/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/89/table.html b/services/response-api/assets/slide_creator/templates/89/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/89/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/89/title.html b/services/response-api/assets/slide_creator/templates/89/title.html
deleted file mode 100644
index fcdc0d92..00000000
--- a/services/response-api/assets/slide_creator/templates/89/title.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
{{.Index}}
-
of {{.Total}}
-
-
-
{{.Plan.Title}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 90}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/9/base.html b/services/response-api/assets/slide_creator/templates/9/base.html
deleted file mode 100644
index cbd839f2..00000000
--- a/services/response-api/assets/slide_creator/templates/9/base.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/9/bullets.html b/services/response-api/assets/slide_creator/templates/9/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/9/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/9/chart.html b/services/response-api/assets/slide_creator/templates/9/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/9/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/9/hero.html b/services/response-api/assets/slide_creator/templates/9/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/9/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/9/llm.html b/services/response-api/assets/slide_creator/templates/9/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/9/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/9/meta.json b/services/response-api/assets/slide_creator/templates/9/meta.json
deleted file mode 100644
index 6fe13077..00000000
--- a/services/response-api/assets/slide_creator/templates/9/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 9,
- "dir": "9",
- "name": "Calm Minimal",
- "tone": "Minimal Clean",
- "description": "Whitespace-forward, neutral framing, restrained accents.",
- "variants": {
- "base": 2,
- "bullets": 4,
- "split": 5,
- "hero": 1,
- "title": 4
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/9/split.html b/services/response-api/assets/slide_creator/templates/9/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/9/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/9/table.html b/services/response-api/assets/slide_creator/templates/9/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/9/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/9/title.html b/services/response-api/assets/slide_creator/templates/9/title.html
deleted file mode 100644
index fcdc0d92..00000000
--- a/services/response-api/assets/slide_creator/templates/9/title.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
{{.Index}}
-
of {{.Total}}
-
-
-
{{.Plan.Title}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 90}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/90/base.html b/services/response-api/assets/slide_creator/templates/90/base.html
deleted file mode 100644
index 982ae99a..00000000
--- a/services/response-api/assets/slide_creator/templates/90/base.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/90/bullets.html b/services/response-api/assets/slide_creator/templates/90/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/90/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/90/chart.html b/services/response-api/assets/slide_creator/templates/90/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/90/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/90/hero.html b/services/response-api/assets/slide_creator/templates/90/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/90/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/90/llm.html b/services/response-api/assets/slide_creator/templates/90/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/90/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/90/meta.json b/services/response-api/assets/slide_creator/templates/90/meta.json
deleted file mode 100644
index b5a79ca0..00000000
--- a/services/response-api/assets/slide_creator/templates/90/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 90,
- "dir": "90",
- "name": "Gov Pack",
- "tone": "Government/Public Sector",
- "description": "Formal, legible, and conservative layout for public comms.",
- "variants": {
- "base": 9,
- "bullets": 5,
- "split": 2,
- "hero": 2,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/90/split.html b/services/response-api/assets/slide_creator/templates/90/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/90/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/90/table.html b/services/response-api/assets/slide_creator/templates/90/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/90/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/90/title.html b/services/response-api/assets/slide_creator/templates/90/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/90/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/91/base.html b/services/response-api/assets/slide_creator/templates/91/base.html
deleted file mode 100644
index a3388e2b..00000000
--- a/services/response-api/assets/slide_creator/templates/91/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/91/bullets.html b/services/response-api/assets/slide_creator/templates/91/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/91/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/91/chart.html b/services/response-api/assets/slide_creator/templates/91/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/91/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/91/hero.html b/services/response-api/assets/slide_creator/templates/91/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/91/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/91/llm.html b/services/response-api/assets/slide_creator/templates/91/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/91/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/91/meta.json b/services/response-api/assets/slide_creator/templates/91/meta.json
deleted file mode 100644
index a4dd25c2..00000000
--- a/services/response-api/assets/slide_creator/templates/91/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 91,
- "dir": "91",
- "name": "Studio Deck",
- "tone": "Creative Studio",
- "description": "Gallery/glass composition for portfolios and creative pitches.",
- "variants": {
- "base": 1,
- "bullets": 1,
- "split": 4,
- "hero": 1,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/91/split.html b/services/response-api/assets/slide_creator/templates/91/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/91/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/91/table.html b/services/response-api/assets/slide_creator/templates/91/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/91/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/91/title.html b/services/response-api/assets/slide_creator/templates/91/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/91/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/92/base.html b/services/response-api/assets/slide_creator/templates/92/base.html
deleted file mode 100644
index a3388e2b..00000000
--- a/services/response-api/assets/slide_creator/templates/92/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/92/bullets.html b/services/response-api/assets/slide_creator/templates/92/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/92/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/92/chart.html b/services/response-api/assets/slide_creator/templates/92/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/92/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/92/hero.html b/services/response-api/assets/slide_creator/templates/92/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/92/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/92/llm.html b/services/response-api/assets/slide_creator/templates/92/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/92/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/92/meta.json b/services/response-api/assets/slide_creator/templates/92/meta.json
deleted file mode 100644
index c18955a6..00000000
--- a/services/response-api/assets/slide_creator/templates/92/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 92,
- "dir": "92",
- "name": "Portfolio",
- "tone": "Creative Studio",
- "description": "Gallery/glass composition for portfolios and creative pitches.",
- "variants": {
- "base": 1,
- "bullets": 2,
- "split": 5,
- "hero": 2,
- "title": 2
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/92/split.html b/services/response-api/assets/slide_creator/templates/92/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/92/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/92/table.html b/services/response-api/assets/slide_creator/templates/92/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/92/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/92/title.html b/services/response-api/assets/slide_creator/templates/92/title.html
deleted file mode 100644
index e4e39fb6..00000000
--- a/services/response-api/assets/slide_creator/templates/92/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
Slide {{.Index}} / {{.Total}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/93/base.html b/services/response-api/assets/slide_creator/templates/93/base.html
deleted file mode 100644
index a3388e2b..00000000
--- a/services/response-api/assets/slide_creator/templates/93/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/93/bullets.html b/services/response-api/assets/slide_creator/templates/93/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/93/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/93/chart.html b/services/response-api/assets/slide_creator/templates/93/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/93/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/93/hero.html b/services/response-api/assets/slide_creator/templates/93/hero.html
deleted file mode 100644
index dafda5d3..00000000
--- a/services/response-api/assets/slide_creator/templates/93/hero.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 150}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/93/llm.html b/services/response-api/assets/slide_creator/templates/93/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/93/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/93/meta.json b/services/response-api/assets/slide_creator/templates/93/meta.json
deleted file mode 100644
index 425b6d88..00000000
--- a/services/response-api/assets/slide_creator/templates/93/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 93,
- "dir": "93",
- "name": "Moodboard",
- "tone": "Creative Studio",
- "description": "Gallery/glass composition for portfolios and creative pitches.",
- "variants": {
- "base": 1,
- "bullets": 3,
- "split": 1,
- "hero": 3,
- "title": 3
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/93/split.html b/services/response-api/assets/slide_creator/templates/93/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/93/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/93/table.html b/services/response-api/assets/slide_creator/templates/93/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/93/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/93/title.html b/services/response-api/assets/slide_creator/templates/93/title.html
deleted file mode 100644
index 45161794..00000000
--- a/services/response-api/assets/slide_creator/templates/93/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
-
- Slide {{.Index}}/{{.Total}}
- {{if .Title.Notes}}{{trimToRunes .Title.Notes 90}} {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/94/base.html b/services/response-api/assets/slide_creator/templates/94/base.html
deleted file mode 100644
index a3388e2b..00000000
--- a/services/response-api/assets/slide_creator/templates/94/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/94/bullets.html b/services/response-api/assets/slide_creator/templates/94/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/94/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/94/chart.html b/services/response-api/assets/slide_creator/templates/94/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/94/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/94/hero.html b/services/response-api/assets/slide_creator/templates/94/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/94/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/94/llm.html b/services/response-api/assets/slide_creator/templates/94/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/94/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/94/meta.json b/services/response-api/assets/slide_creator/templates/94/meta.json
deleted file mode 100644
index c137fb6d..00000000
--- a/services/response-api/assets/slide_creator/templates/94/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 94,
- "dir": "94",
- "name": "Art Direction",
- "tone": "Creative Studio",
- "description": "Gallery/glass composition for portfolios and creative pitches.",
- "variants": {
- "base": 1,
- "bullets": 4,
- "split": 2,
- "hero": 1,
- "title": 4
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/94/split.html b/services/response-api/assets/slide_creator/templates/94/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/94/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/94/table.html b/services/response-api/assets/slide_creator/templates/94/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/94/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/94/title.html b/services/response-api/assets/slide_creator/templates/94/title.html
deleted file mode 100644
index fcdc0d92..00000000
--- a/services/response-api/assets/slide_creator/templates/94/title.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
{{.Index}}
-
of {{.Total}}
-
-
-
{{.Plan.Title}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 90}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/95/base.html b/services/response-api/assets/slide_creator/templates/95/base.html
deleted file mode 100644
index a3388e2b..00000000
--- a/services/response-api/assets/slide_creator/templates/95/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/95/bullets.html b/services/response-api/assets/slide_creator/templates/95/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/95/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/95/chart.html b/services/response-api/assets/slide_creator/templates/95/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/95/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/95/hero.html b/services/response-api/assets/slide_creator/templates/95/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/95/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/95/llm.html b/services/response-api/assets/slide_creator/templates/95/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/95/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/95/meta.json b/services/response-api/assets/slide_creator/templates/95/meta.json
deleted file mode 100644
index b85f1b06..00000000
--- a/services/response-api/assets/slide_creator/templates/95/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 95,
- "dir": "95",
- "name": "Design Sprint",
- "tone": "Creative Studio",
- "description": "Gallery/glass composition for portfolios and creative pitches.",
- "variants": {
- "base": 1,
- "bullets": 5,
- "split": 3,
- "hero": 2,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/95/split.html b/services/response-api/assets/slide_creator/templates/95/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/95/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/95/table.html b/services/response-api/assets/slide_creator/templates/95/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/95/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/95/title.html b/services/response-api/assets/slide_creator/templates/95/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/95/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/96/base.html b/services/response-api/assets/slide_creator/templates/96/base.html
deleted file mode 100644
index 1608815d..00000000
--- a/services/response-api/assets/slide_creator/templates/96/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/96/bullets.html b/services/response-api/assets/slide_creator/templates/96/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/96/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/96/chart.html b/services/response-api/assets/slide_creator/templates/96/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/96/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/96/hero.html b/services/response-api/assets/slide_creator/templates/96/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/96/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/96/llm.html b/services/response-api/assets/slide_creator/templates/96/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/96/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/96/meta.json b/services/response-api/assets/slide_creator/templates/96/meta.json
deleted file mode 100644
index 8920e2d6..00000000
--- a/services/response-api/assets/slide_creator/templates/96/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 96,
- "dir": "96",
- "name": "Stadium",
- "tone": "Sports/Energy",
- "description": "Bold band framing; dynamic pacing and clear takeaways.",
- "variants": {
- "base": 4,
- "bullets": 1,
- "split": 5,
- "hero": 1,
- "title": 1
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/96/split.html b/services/response-api/assets/slide_creator/templates/96/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/96/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/96/table.html b/services/response-api/assets/slide_creator/templates/96/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/96/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/96/title.html b/services/response-api/assets/slide_creator/templates/96/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/96/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/97/base.html b/services/response-api/assets/slide_creator/templates/97/base.html
deleted file mode 100644
index 1608815d..00000000
--- a/services/response-api/assets/slide_creator/templates/97/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/97/bullets.html b/services/response-api/assets/slide_creator/templates/97/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/97/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/97/chart.html b/services/response-api/assets/slide_creator/templates/97/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/97/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/97/hero.html b/services/response-api/assets/slide_creator/templates/97/hero.html
deleted file mode 100644
index d5cebff3..00000000
--- a/services/response-api/assets/slide_creator/templates/97/hero.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 170}}
-
-
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/97/llm.html b/services/response-api/assets/slide_creator/templates/97/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/97/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/97/meta.json b/services/response-api/assets/slide_creator/templates/97/meta.json
deleted file mode 100644
index b54b7dde..00000000
--- a/services/response-api/assets/slide_creator/templates/97/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 97,
- "dir": "97",
- "name": "Pulse",
- "tone": "Sports/Energy",
- "description": "Bold band framing; dynamic pacing and clear takeaways.",
- "variants": {
- "base": 4,
- "bullets": 2,
- "split": 1,
- "hero": 2,
- "title": 2
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/97/split.html b/services/response-api/assets/slide_creator/templates/97/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/97/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/97/table.html b/services/response-api/assets/slide_creator/templates/97/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/97/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/97/title.html b/services/response-api/assets/slide_creator/templates/97/title.html
deleted file mode 100644
index e4e39fb6..00000000
--- a/services/response-api/assets/slide_creator/templates/97/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
Slide {{.Index}} / {{.Total}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/98/base.html b/services/response-api/assets/slide_creator/templates/98/base.html
deleted file mode 100644
index 1608815d..00000000
--- a/services/response-api/assets/slide_creator/templates/98/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/98/bullets.html b/services/response-api/assets/slide_creator/templates/98/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/98/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/98/chart.html b/services/response-api/assets/slide_creator/templates/98/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/98/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/98/hero.html b/services/response-api/assets/slide_creator/templates/98/hero.html
deleted file mode 100644
index dafda5d3..00000000
--- a/services/response-api/assets/slide_creator/templates/98/hero.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 150}}
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/98/llm.html b/services/response-api/assets/slide_creator/templates/98/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/98/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/98/meta.json b/services/response-api/assets/slide_creator/templates/98/meta.json
deleted file mode 100644
index b11802e1..00000000
--- a/services/response-api/assets/slide_creator/templates/98/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 98,
- "dir": "98",
- "name": "Game Plan",
- "tone": "Sports/Energy",
- "description": "Bold band framing; dynamic pacing and clear takeaways.",
- "variants": {
- "base": 4,
- "bullets": 3,
- "split": 2,
- "hero": 3,
- "title": 3
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/98/split.html b/services/response-api/assets/slide_creator/templates/98/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/98/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/98/table.html b/services/response-api/assets/slide_creator/templates/98/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/98/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/98/title.html b/services/response-api/assets/slide_creator/templates/98/title.html
deleted file mode 100644
index 45161794..00000000
--- a/services/response-api/assets/slide_creator/templates/98/title.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{define "body"}}
-
-
-
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
-
- Slide {{.Index}}/{{.Total}}
- {{if .Title.Notes}}{{trimToRunes .Title.Notes 90}} {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/99/base.html b/services/response-api/assets/slide_creator/templates/99/base.html
deleted file mode 100644
index 1608815d..00000000
--- a/services/response-api/assets/slide_creator/templates/99/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
- {{.Index}} / {{.Total}}
- {{.Plan.Title}}
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/99/bullets.html b/services/response-api/assets/slide_creator/templates/99/bullets.html
deleted file mode 100644
index 504c832b..00000000
--- a/services/response-api/assets/slide_creator/templates/99/bullets.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{define "body"}}
-
- {{if .Bullets.HasImage}}
- {{/* Layout with image on right */}}
-
- {{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 120}}
{{end}}
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 200}}
-
- {{end}}
-
-
-
-
-
-
-
- {{if .Bullets.ImageCaption}}{{trimToRunes .Bullets.ImageCaption 100}} {{end}}
-
-
- {{else}}
- {{/* Full-width layout with stats bar */}}
-
-
-
-
{{if .Bullets.Label}}{{.Bullets.Label}}{{else}}Overview{{end}}
-
{{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}
{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/99/chart.html b/services/response-api/assets/slide_creator/templates/99/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/99/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/99/hero.html b/services/response-api/assets/slide_creator/templates/99/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/99/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/99/llm.html b/services/response-api/assets/slide_creator/templates/99/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/99/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/99/meta.json b/services/response-api/assets/slide_creator/templates/99/meta.json
deleted file mode 100644
index 99d2a357..00000000
--- a/services/response-api/assets/slide_creator/templates/99/meta.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": 99,
- "dir": "99",
- "name": "Athlete Story",
- "tone": "Sports/Energy",
- "description": "Bold band framing; dynamic pacing and clear takeaways.",
- "variants": {
- "base": 4,
- "bullets": 4,
- "split": 3,
- "hero": 1,
- "title": 4
- }
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/99/split.html b/services/response-api/assets/slide_creator/templates/99/split.html
deleted file mode 100644
index 7e4099f4..00000000
--- a/services/response-api/assets/slide_creator/templates/99/split.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 120}}
{{end}}
-
- {{if .Split.Stats}}
-
- {{range .Split.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 20}}
-
- {{end}}
-
- {{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 180}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{if .Split.ImageCaption}}{{trimToRunes .Split.ImageCaption 100}} {{end}}
-
- {{else}}
- {{/* No image - show stats panel or highlights */}}
-
-
Key Insights
-
- {{if .Bullets.Stats}}
-
- {{range .Bullets.Stats}}
-
-
{{.Value}}
-
{{trimToRunes .Label 24}}
-
- {{end}}
-
- {{else}}
-
-
{{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 160}}
{{end}}
-
- {{end}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/99/table.html b/services/response-api/assets/slide_creator/templates/99/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/99/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/99/title.html b/services/response-api/assets/slide_creator/templates/99/title.html
deleted file mode 100644
index fcdc0d92..00000000
--- a/services/response-api/assets/slide_creator/templates/99/title.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
{{.Index}}
-
of {{.Total}}
-
-
-
{{.Plan.Title}}
-
{{trimToRunes .Slide.Title 130}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 240}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 90}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/embedded.go b/services/response-api/assets/slide_creator/templates/embedded.go
deleted file mode 100644
index 9d2488c4..00000000
--- a/services/response-api/assets/slide_creator/templates/embedded.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package templates
-
-import "embed"
-
-// FS embeds the built-in HTML template catalog.
-//
-//go:embed index.json index.md */*
-var FS embed.FS
diff --git a/services/response-api/assets/slide_creator/templates/index.json b/services/response-api/assets/slide_creator/templates/index.json
deleted file mode 100644
index 4f2d6e05..00000000
--- a/services/response-api/assets/slide_creator/templates/index.json
+++ /dev/null
@@ -1,1405 +0,0 @@
-{
- "count": 100,
- "templates": [
- {
- "id": 1,
- "dir": "1",
- "name": "Neon City",
- "tone": "Neon Cyberpunk",
- "description": "Aurora glows + high-energy composition for futuristic themes.",
- "variants": {
- "base": 1,
- "bullets": 1,
- "split": 1,
- "hero": 1,
- "title": 1
- }
- },
- {
- "id": 2,
- "dir": "2",
- "name": "Cyber Grid",
- "tone": "Neon Cyberpunk",
- "description": "Aurora glows + high-energy composition for futuristic themes.",
- "variants": {
- "base": 1,
- "bullets": 2,
- "split": 2,
- "hero": 2,
- "title": 2
- }
- },
- {
- "id": 3,
- "dir": "3",
- "name": "Laser Night",
- "tone": "Neon Cyberpunk",
- "description": "Aurora glows + high-energy composition for futuristic themes.",
- "variants": {
- "base": 1,
- "bullets": 3,
- "split": 3,
- "hero": 3,
- "title": 3
- }
- },
- {
- "id": 4,
- "dir": "4",
- "name": "Synthwave",
- "tone": "Neon Cyberpunk",
- "description": "Aurora glows + high-energy composition for futuristic themes.",
- "variants": {
- "base": 1,
- "bullets": 4,
- "split": 4,
- "hero": 1,
- "title": 4
- }
- },
- {
- "id": 5,
- "dir": "5",
- "name": "Night Neon",
- "tone": "Neon Cyberpunk",
- "description": "Aurora glows + high-energy composition for futuristic themes.",
- "variants": {
- "base": 1,
- "bullets": 5,
- "split": 5,
- "hero": 2,
- "title": 1
- }
- },
- {
- "id": 6,
- "dir": "6",
- "name": "Ivory Minimal",
- "tone": "Minimal Clean",
- "description": "Whitespace-forward, neutral framing, restrained accents.",
- "variants": {
- "base": 2,
- "bullets": 1,
- "split": 2,
- "hero": 1,
- "title": 1
- }
- },
- {
- "id": 7,
- "dir": "7",
- "name": "Stone Minimal",
- "tone": "Minimal Clean",
- "description": "Whitespace-forward, neutral framing, restrained accents.",
- "variants": {
- "base": 2,
- "bullets": 2,
- "split": 3,
- "hero": 2,
- "title": 2
- }
- },
- {
- "id": 8,
- "dir": "8",
- "name": "Cloud Minimal",
- "tone": "Minimal Clean",
- "description": "Whitespace-forward, neutral framing, restrained accents.",
- "variants": {
- "base": 2,
- "bullets": 3,
- "split": 4,
- "hero": 3,
- "title": 3
- }
- },
- {
- "id": 9,
- "dir": "9",
- "name": "Calm Minimal",
- "tone": "Minimal Clean",
- "description": "Whitespace-forward, neutral framing, restrained accents.",
- "variants": {
- "base": 2,
- "bullets": 4,
- "split": 5,
- "hero": 1,
- "title": 4
- }
- },
- {
- "id": 10,
- "dir": "10",
- "name": "Mono Minimal",
- "tone": "Minimal Clean",
- "description": "Whitespace-forward, neutral framing, restrained accents.",
- "variants": {
- "base": 2,
- "bullets": 5,
- "split": 1,
- "hero": 2,
- "title": 1
- }
- },
- {
- "id": 11,
- "dir": "11",
- "name": "Consulting Edge",
- "tone": "Corporate Consulting",
- "description": "Executive framing, clear hierarchy, client-ready polish.",
- "variants": {
- "base": 9,
- "bullets": 1,
- "split": 3,
- "hero": 1,
- "title": 1
- }
- },
- {
- "id": 12,
- "dir": "12",
- "name": "Boardroom Brief",
- "tone": "Corporate Consulting",
- "description": "Executive framing, clear hierarchy, client-ready polish.",
- "variants": {
- "base": 9,
- "bullets": 2,
- "split": 4,
- "hero": 2,
- "title": 2
- }
- },
- {
- "id": 13,
- "dir": "13",
- "name": "Executive Slate",
- "tone": "Corporate Consulting",
- "description": "Executive framing, clear hierarchy, client-ready polish.",
- "variants": {
- "base": 9,
- "bullets": 3,
- "split": 5,
- "hero": 3,
- "title": 3
- }
- },
- {
- "id": 14,
- "dir": "14",
- "name": "Strategy Pack",
- "tone": "Corporate Consulting",
- "description": "Executive framing, clear hierarchy, client-ready polish.",
- "variants": {
- "base": 9,
- "bullets": 4,
- "split": 1,
- "hero": 1,
- "title": 4
- }
- },
- {
- "id": 15,
- "dir": "15",
- "name": "Client Brief",
- "tone": "Corporate Consulting",
- "description": "Executive framing, clear hierarchy, client-ready polish.",
- "variants": {
- "base": 9,
- "bullets": 5,
- "split": 2,
- "hero": 2,
- "title": 1
- }
- },
- {
- "id": 16,
- "dir": "16",
- "name": "Dark Terminal",
- "tone": "Tech Dark",
- "description": "Dark glass + glow, strong contrast, product/engineering feel.",
- "variants": {
- "base": 5,
- "bullets": 1,
- "split": 4,
- "hero": 1,
- "title": 1
- }
- },
- {
- "id": 17,
- "dir": "17",
- "name": "Night Ops",
- "tone": "Tech Dark",
- "description": "Dark glass + glow, strong contrast, product/engineering feel.",
- "variants": {
- "base": 5,
- "bullets": 2,
- "split": 5,
- "hero": 2,
- "title": 2
- }
- },
- {
- "id": 18,
- "dir": "18",
- "name": "Quantum Slate",
- "tone": "Tech Dark",
- "description": "Dark glass + glow, strong contrast, product/engineering feel.",
- "variants": {
- "base": 5,
- "bullets": 3,
- "split": 1,
- "hero": 3,
- "title": 3
- }
- },
- {
- "id": 19,
- "dir": "19",
- "name": "Carbon Studio",
- "tone": "Tech Dark",
- "description": "Dark glass + glow, strong contrast, product/engineering feel.",
- "variants": {
- "base": 5,
- "bullets": 4,
- "split": 2,
- "hero": 1,
- "title": 4
- }
- },
- {
- "id": 20,
- "dir": "20",
- "name": "Midnight Grid",
- "tone": "Tech Dark",
- "description": "Dark glass + glow, strong contrast, product/engineering feel.",
- "variants": {
- "base": 5,
- "bullets": 5,
- "split": 3,
- "hero": 2,
- "title": 1
- }
- },
- {
- "id": 21,
- "dir": "21",
- "name": "Launchpad Pitch",
- "tone": "Startup Bold",
- "description": "Accent band + bold rhythm, pitch-deck energy.",
- "variants": {
- "base": 4,
- "bullets": 1,
- "split": 5,
- "hero": 1,
- "title": 1
- }
- },
- {
- "id": 22,
- "dir": "22",
- "name": "Venture Bold",
- "tone": "Startup Bold",
- "description": "Accent band + bold rhythm, pitch-deck energy.",
- "variants": {
- "base": 4,
- "bullets": 2,
- "split": 1,
- "hero": 2,
- "title": 2
- }
- },
- {
- "id": 23,
- "dir": "23",
- "name": "Momentum Deck",
- "tone": "Startup Bold",
- "description": "Accent band + bold rhythm, pitch-deck energy.",
- "variants": {
- "base": 4,
- "bullets": 3,
- "split": 2,
- "hero": 3,
- "title": 3
- }
- },
- {
- "id": 24,
- "dir": "24",
- "name": "Growth Sprint",
- "tone": "Startup Bold",
- "description": "Accent band + bold rhythm, pitch-deck energy.",
- "variants": {
- "base": 4,
- "bullets": 4,
- "split": 3,
- "hero": 1,
- "title": 4
- }
- },
- {
- "id": 25,
- "dir": "25",
- "name": "Demo Day",
- "tone": "Startup Bold",
- "description": "Accent band + bold rhythm, pitch-deck energy.",
- "variants": {
- "base": 4,
- "bullets": 5,
- "split": 4,
- "hero": 2,
- "title": 1
- }
- },
- {
- "id": 26,
- "dir": "26",
- "name": "Cotton Candy",
- "tone": "Playful Pastel",
- "description": "Soft patterns and friendly shapes; great for consumer topics.",
- "variants": {
- "base": 7,
- "bullets": 1,
- "split": 1,
- "hero": 1,
- "title": 1
- }
- },
- {
- "id": 27,
- "dir": "27",
- "name": "Peach Pop",
- "tone": "Playful Pastel",
- "description": "Soft patterns and friendly shapes; great for consumer topics.",
- "variants": {
- "base": 7,
- "bullets": 2,
- "split": 2,
- "hero": 2,
- "title": 2
- }
- },
- {
- "id": 28,
- "dir": "28",
- "name": "Mint Joy",
- "tone": "Playful Pastel",
- "description": "Soft patterns and friendly shapes; great for consumer topics.",
- "variants": {
- "base": 7,
- "bullets": 3,
- "split": 3,
- "hero": 3,
- "title": 3
- }
- },
- {
- "id": 29,
- "dir": "29",
- "name": "Lavender Fun",
- "tone": "Playful Pastel",
- "description": "Soft patterns and friendly shapes; great for consumer topics.",
- "variants": {
- "base": 7,
- "bullets": 4,
- "split": 4,
- "hero": 1,
- "title": 4
- }
- },
- {
- "id": 30,
- "dir": "30",
- "name": "Bubblegum",
- "tone": "Playful Pastel",
- "description": "Soft patterns and friendly shapes; great for consumer topics.",
- "variants": {
- "base": 7,
- "bullets": 5,
- "split": 5,
- "hero": 2,
- "title": 1
- }
- },
- {
- "id": 31,
- "dir": "31",
- "name": "Magazine Serif",
- "tone": "Editorial Serif",
- "description": "Paper/grid editorial vibe; strong reading flow.",
- "variants": {
- "base": 6,
- "bullets": 1,
- "split": 2,
- "hero": 1,
- "title": 1
- }
- },
- {
- "id": 32,
- "dir": "32",
- "name": "Op-Ed",
- "tone": "Editorial Serif",
- "description": "Paper/grid editorial vibe; strong reading flow.",
- "variants": {
- "base": 6,
- "bullets": 2,
- "split": 3,
- "hero": 2,
- "title": 2
- }
- },
- {
- "id": 33,
- "dir": "33",
- "name": "Pressroom",
- "tone": "Editorial Serif",
- "description": "Paper/grid editorial vibe; strong reading flow.",
- "variants": {
- "base": 6,
- "bullets": 3,
- "split": 4,
- "hero": 3,
- "title": 3
- }
- },
- {
- "id": 34,
- "dir": "34",
- "name": "Classic Journal",
- "tone": "Editorial Serif",
- "description": "Paper/grid editorial vibe; strong reading flow.",
- "variants": {
- "base": 6,
- "bullets": 4,
- "split": 5,
- "hero": 1,
- "title": 4
- }
- },
- {
- "id": 35,
- "dir": "35",
- "name": "Notebook Editorial",
- "tone": "Editorial Serif",
- "description": "Paper/grid editorial vibe; strong reading flow.",
- "variants": {
- "base": 6,
- "bullets": 5,
- "split": 1,
- "hero": 2,
- "title": 1
- }
- },
- {
- "id": 36,
- "dir": "36",
- "name": "Onyx Luxe",
- "tone": "Luxury Elegant",
- "description": "Rounded stage, premium spacing, gallery-like feel.",
- "variants": {
- "base": 10,
- "bullets": 1,
- "split": 3,
- "hero": 1,
- "title": 1
- }
- },
- {
- "id": 37,
- "dir": "37",
- "name": "Silk Gallery",
- "tone": "Luxury Elegant",
- "description": "Rounded stage, premium spacing, gallery-like feel.",
- "variants": {
- "base": 10,
- "bullets": 2,
- "split": 4,
- "hero": 2,
- "title": 2
- }
- },
- {
- "id": 38,
- "dir": "38",
- "name": "Chateau",
- "tone": "Luxury Elegant",
- "description": "Rounded stage, premium spacing, gallery-like feel.",
- "variants": {
- "base": 10,
- "bullets": 3,
- "split": 5,
- "hero": 3,
- "title": 3
- }
- },
- {
- "id": 39,
- "dir": "39",
- "name": "Noir Elegant",
- "tone": "Luxury Elegant",
- "description": "Rounded stage, premium spacing, gallery-like feel.",
- "variants": {
- "base": 10,
- "bullets": 4,
- "split": 1,
- "hero": 1,
- "title": 4
- }
- },
- {
- "id": 40,
- "dir": "40",
- "name": "Gold Accent",
- "tone": "Luxury Elegant",
- "description": "Rounded stage, premium spacing, gallery-like feel.",
- "variants": {
- "base": 10,
- "bullets": 5,
- "split": 2,
- "hero": 2,
- "title": 1
- }
- },
- {
- "id": 41,
- "dir": "41",
- "name": "Clinic Clean",
- "tone": "Healthcare Calm",
- "description": "Clean, calm, accessible layouts; works well with light themes.",
- "variants": {
- "base": 2,
- "bullets": 1,
- "split": 4,
- "hero": 1,
- "title": 1
- }
- },
- {
- "id": 42,
- "dir": "42",
- "name": "Care Path",
- "tone": "Healthcare Calm",
- "description": "Clean, calm, accessible layouts; works well with light themes.",
- "variants": {
- "base": 2,
- "bullets": 2,
- "split": 5,
- "hero": 2,
- "title": 2
- }
- },
- {
- "id": 43,
- "dir": "43",
- "name": "Wellness Calm",
- "tone": "Healthcare Calm",
- "description": "Clean, calm, accessible layouts; works well with light themes.",
- "variants": {
- "base": 2,
- "bullets": 3,
- "split": 1,
- "hero": 3,
- "title": 3
- }
- },
- {
- "id": 44,
- "dir": "44",
- "name": "Aqua Relief",
- "tone": "Healthcare Calm",
- "description": "Clean, calm, accessible layouts; works well with light themes.",
- "variants": {
- "base": 2,
- "bullets": 4,
- "split": 2,
- "hero": 1,
- "title": 4
- }
- },
- {
- "id": 45,
- "dir": "45",
- "name": "Soft Green",
- "tone": "Healthcare Calm",
- "description": "Clean, calm, accessible layouts; works well with light themes.",
- "variants": {
- "base": 2,
- "bullets": 5,
- "split": 3,
- "hero": 2,
- "title": 1
- }
- },
- {
- "id": 46,
- "dir": "46",
- "name": "Classroom",
- "tone": "Education Friendly",
- "description": "Sidebar guidance + structured body; classroom/learning friendly.",
- "variants": {
- "base": 3,
- "bullets": 1,
- "split": 5,
- "hero": 1,
- "title": 1
- }
- },
- {
- "id": 47,
- "dir": "47",
- "name": "Notebook",
- "tone": "Education Friendly",
- "description": "Sidebar guidance + structured body; classroom/learning friendly.",
- "variants": {
- "base": 3,
- "bullets": 2,
- "split": 1,
- "hero": 2,
- "title": 2
- }
- },
- {
- "id": 48,
- "dir": "48",
- "name": "Campus",
- "tone": "Education Friendly",
- "description": "Sidebar guidance + structured body; classroom/learning friendly.",
- "variants": {
- "base": 3,
- "bullets": 3,
- "split": 2,
- "hero": 3,
- "title": 3
- }
- },
- {
- "id": 49,
- "dir": "49",
- "name": "Study Buddy",
- "tone": "Education Friendly",
- "description": "Sidebar guidance + structured body; classroom/learning friendly.",
- "variants": {
- "base": 3,
- "bullets": 4,
- "split": 3,
- "hero": 1,
- "title": 4
- }
- },
- {
- "id": 50,
- "dir": "50",
- "name": "Lesson Plan",
- "tone": "Education Friendly",
- "description": "Sidebar guidance + structured body; classroom/learning friendly.",
- "variants": {
- "base": 3,
- "bullets": 5,
- "split": 4,
- "hero": 2,
- "title": 1
- }
- },
- {
- "id": 51,
- "dir": "51",
- "name": "Market Brief",
- "tone": "Finance Professional",
- "description": "Structured, conservative frames for finance/strategy decks.",
- "variants": {
- "base": 9,
- "bullets": 1,
- "split": 1,
- "hero": 1,
- "title": 1
- }
- },
- {
- "id": 52,
- "dir": "52",
- "name": "Investor Note",
- "tone": "Finance Professional",
- "description": "Structured, conservative frames for finance/strategy decks.",
- "variants": {
- "base": 9,
- "bullets": 2,
- "split": 2,
- "hero": 2,
- "title": 2
- }
- },
- {
- "id": 53,
- "dir": "53",
- "name": "Capital Ledger",
- "tone": "Finance Professional",
- "description": "Structured, conservative frames for finance/strategy decks.",
- "variants": {
- "base": 9,
- "bullets": 3,
- "split": 3,
- "hero": 3,
- "title": 3
- }
- },
- {
- "id": 54,
- "dir": "54",
- "name": "Quarterly Review",
- "tone": "Finance Professional",
- "description": "Structured, conservative frames for finance/strategy decks.",
- "variants": {
- "base": 9,
- "bullets": 4,
- "split": 4,
- "hero": 1,
- "title": 4
- }
- },
- {
- "id": 55,
- "dir": "55",
- "name": "Risk Report",
- "tone": "Finance Professional",
- "description": "Structured, conservative frames for finance/strategy decks.",
- "variants": {
- "base": 9,
- "bullets": 5,
- "split": 5,
- "hero": 2,
- "title": 1
- }
- },
- {
- "id": 56,
- "dir": "56",
- "name": "Earth Brief",
- "tone": "Sustainability Earthy",
- "description": "Grid/paper background pairs well with earthy palettes.",
- "variants": {
- "base": 6,
- "bullets": 1,
- "split": 2,
- "hero": 1,
- "title": 1
- }
- },
- {
- "id": 57,
- "dir": "57",
- "name": "Forest Notes",
- "tone": "Sustainability Earthy",
- "description": "Grid/paper background pairs well with earthy palettes.",
- "variants": {
- "base": 6,
- "bullets": 2,
- "split": 3,
- "hero": 2,
- "title": 2
- }
- },
- {
- "id": 58,
- "dir": "58",
- "name": "Leaf Strategy",
- "tone": "Sustainability Earthy",
- "description": "Grid/paper background pairs well with earthy palettes.",
- "variants": {
- "base": 6,
- "bullets": 3,
- "split": 4,
- "hero": 3,
- "title": 3
- }
- },
- {
- "id": 59,
- "dir": "59",
- "name": "Eco Report",
- "tone": "Sustainability Earthy",
- "description": "Grid/paper background pairs well with earthy palettes.",
- "variants": {
- "base": 6,
- "bullets": 4,
- "split": 5,
- "hero": 1,
- "title": 4
- }
- },
- {
- "id": 60,
- "dir": "60",
- "name": "Green Path",
- "tone": "Sustainability Earthy",
- "description": "Grid/paper background pairs well with earthy palettes.",
- "variants": {
- "base": 6,
- "bullets": 5,
- "split": 1,
- "hero": 2,
- "title": 1
- }
- },
- {
- "id": 61,
- "dir": "61",
- "name": "Campaign Studio",
- "tone": "Marketing Vibrant",
- "description": "Top band + punchy accents; campaign and brand stories.",
- "variants": {
- "base": 4,
- "bullets": 1,
- "split": 3,
- "hero": 1,
- "title": 1
- }
- },
- {
- "id": 62,
- "dir": "62",
- "name": "Spotlight",
- "tone": "Marketing Vibrant",
- "description": "Top band + punchy accents; campaign and brand stories.",
- "variants": {
- "base": 4,
- "bullets": 2,
- "split": 4,
- "hero": 2,
- "title": 2
- }
- },
- {
- "id": 63,
- "dir": "63",
- "name": "Brand Burst",
- "tone": "Marketing Vibrant",
- "description": "Top band + punchy accents; campaign and brand stories.",
- "variants": {
- "base": 4,
- "bullets": 3,
- "split": 5,
- "hero": 3,
- "title": 3
- }
- },
- {
- "id": 64,
- "dir": "64",
- "name": "Creative Ad",
- "tone": "Marketing Vibrant",
- "description": "Top band + punchy accents; campaign and brand stories.",
- "variants": {
- "base": 4,
- "bullets": 4,
- "split": 1,
- "hero": 1,
- "title": 4
- }
- },
- {
- "id": 65,
- "dir": "65",
- "name": "Launch Creative",
- "tone": "Marketing Vibrant",
- "description": "Top band + punchy accents; campaign and brand stories.",
- "variants": {
- "base": 4,
- "bullets": 5,
- "split": 2,
- "hero": 2,
- "title": 1
- }
- },
- {
- "id": 66,
- "dir": "66",
- "name": "Dashboard",
- "tone": "Data Analyst",
- "description": "Grid-forward layout for charts/tables and analytic narratives.",
- "variants": {
- "base": 6,
- "bullets": 1,
- "split": 4,
- "hero": 1,
- "title": 1
- }
- },
- {
- "id": 67,
- "dir": "67",
- "name": "Gridline",
- "tone": "Data Analyst",
- "description": "Grid-forward layout for charts/tables and analytic narratives.",
- "variants": {
- "base": 6,
- "bullets": 2,
- "split": 5,
- "hero": 2,
- "title": 2
- }
- },
- {
- "id": 68,
- "dir": "68",
- "name": "Analytics",
- "tone": "Data Analyst",
- "description": "Grid-forward layout for charts/tables and analytic narratives.",
- "variants": {
- "base": 6,
- "bullets": 3,
- "split": 1,
- "hero": 3,
- "title": 3
- }
- },
- {
- "id": 69,
- "dir": "69",
- "name": "Insight Pack",
- "tone": "Data Analyst",
- "description": "Grid-forward layout for charts/tables and analytic narratives.",
- "variants": {
- "base": 6,
- "bullets": 4,
- "split": 2,
- "hero": 1,
- "title": 4
- }
- },
- {
- "id": 70,
- "dir": "70",
- "name": "Metrics Review",
- "tone": "Data Analyst",
- "description": "Grid-forward layout for charts/tables and analytic narratives.",
- "variants": {
- "base": 6,
- "bullets": 5,
- "split": 3,
- "hero": 2,
- "title": 1
- }
- },
- {
- "id": 71,
- "dir": "71",
- "name": "Retro Wave",
- "tone": "Retro",
- "description": "Dot pattern + playful framing; retro/nostalgia tone.",
- "variants": {
- "base": 7,
- "bullets": 1,
- "split": 5,
- "hero": 1,
- "title": 1
- }
- },
- {
- "id": 72,
- "dir": "72",
- "name": "Cassette",
- "tone": "Retro",
- "description": "Dot pattern + playful framing; retro/nostalgia tone.",
- "variants": {
- "base": 7,
- "bullets": 2,
- "split": 1,
- "hero": 2,
- "title": 2
- }
- },
- {
- "id": 73,
- "dir": "73",
- "name": "Polaroid",
- "tone": "Retro",
- "description": "Dot pattern + playful framing; retro/nostalgia tone.",
- "variants": {
- "base": 7,
- "bullets": 3,
- "split": 2,
- "hero": 3,
- "title": 3
- }
- },
- {
- "id": 74,
- "dir": "74",
- "name": "Arcade",
- "tone": "Retro",
- "description": "Dot pattern + playful framing; retro/nostalgia tone.",
- "variants": {
- "base": 7,
- "bullets": 4,
- "split": 3,
- "hero": 1,
- "title": 4
- }
- },
- {
- "id": 75,
- "dir": "75",
- "name": "Vintage Print",
- "tone": "Retro",
- "description": "Dot pattern + playful framing; retro/nostalgia tone.",
- "variants": {
- "base": 7,
- "bullets": 5,
- "split": 4,
- "hero": 2,
- "title": 1
- }
- },
- {
- "id": 76,
- "dir": "76",
- "name": "Mono Black",
- "tone": "Monochrome",
- "description": "Minimal frame tuned for black/white/gray palettes.",
- "variants": {
- "base": 2,
- "bullets": 1,
- "split": 1,
- "hero": 1,
- "title": 1
- }
- },
- {
- "id": 77,
- "dir": "77",
- "name": "Mono White",
- "tone": "Monochrome",
- "description": "Minimal frame tuned for black/white/gray palettes.",
- "variants": {
- "base": 2,
- "bullets": 2,
- "split": 2,
- "hero": 2,
- "title": 2
- }
- },
- {
- "id": 78,
- "dir": "78",
- "name": "Grayscale",
- "tone": "Monochrome",
- "description": "Minimal frame tuned for black/white/gray palettes.",
- "variants": {
- "base": 2,
- "bullets": 3,
- "split": 3,
- "hero": 3,
- "title": 3
- }
- },
- {
- "id": 79,
- "dir": "79",
- "name": "Ink",
- "tone": "Monochrome",
- "description": "Minimal frame tuned for black/white/gray palettes.",
- "variants": {
- "base": 2,
- "bullets": 4,
- "split": 4,
- "hero": 1,
- "title": 4
- }
- },
- {
- "id": 80,
- "dir": "80",
- "name": "Charcoal",
- "tone": "Monochrome",
- "description": "Minimal frame tuned for black/white/gray palettes.",
- "variants": {
- "base": 2,
- "bullets": 5,
- "split": 5,
- "hero": 2,
- "title": 1
- }
- },
- {
- "id": 81,
- "dir": "81",
- "name": "Gradient Flow",
- "tone": "Gradient Modern",
- "description": "Band gradient + modern spacing; works with gradient palettes.",
- "variants": {
- "base": 4,
- "bullets": 1,
- "split": 2,
- "hero": 1,
- "title": 1
- }
- },
- {
- "id": 82,
- "dir": "82",
- "name": "Sunrise",
- "tone": "Gradient Modern",
- "description": "Band gradient + modern spacing; works with gradient palettes.",
- "variants": {
- "base": 4,
- "bullets": 2,
- "split": 3,
- "hero": 2,
- "title": 2
- }
- },
- {
- "id": 83,
- "dir": "83",
- "name": "Aurora Modern",
- "tone": "Gradient Modern",
- "description": "Band gradient + modern spacing; works with gradient palettes.",
- "variants": {
- "base": 4,
- "bullets": 3,
- "split": 4,
- "hero": 3,
- "title": 3
- }
- },
- {
- "id": 84,
- "dir": "84",
- "name": "Spectrum",
- "tone": "Gradient Modern",
- "description": "Band gradient + modern spacing; works with gradient palettes.",
- "variants": {
- "base": 4,
- "bullets": 4,
- "split": 5,
- "hero": 1,
- "title": 4
- }
- },
- {
- "id": 85,
- "dir": "85",
- "name": "Horizon",
- "tone": "Gradient Modern",
- "description": "Band gradient + modern spacing; works with gradient palettes.",
- "variants": {
- "base": 4,
- "bullets": 5,
- "split": 1,
- "hero": 2,
- "title": 1
- }
- },
- {
- "id": 86,
- "dir": "86",
- "name": "Public Brief",
- "tone": "Government/Public Sector",
- "description": "Formal, legible, and conservative layout for public comms.",
- "variants": {
- "base": 9,
- "bullets": 1,
- "split": 3,
- "hero": 1,
- "title": 1
- }
- },
- {
- "id": 87,
- "dir": "87",
- "name": "Policy Note",
- "tone": "Government/Public Sector",
- "description": "Formal, legible, and conservative layout for public comms.",
- "variants": {
- "base": 9,
- "bullets": 2,
- "split": 4,
- "hero": 2,
- "title": 2
- }
- },
- {
- "id": 88,
- "dir": "88",
- "name": "Civic Update",
- "tone": "Government/Public Sector",
- "description": "Formal, legible, and conservative layout for public comms.",
- "variants": {
- "base": 9,
- "bullets": 3,
- "split": 5,
- "hero": 3,
- "title": 3
- }
- },
- {
- "id": 89,
- "dir": "89",
- "name": "Agency Report",
- "tone": "Government/Public Sector",
- "description": "Formal, legible, and conservative layout for public comms.",
- "variants": {
- "base": 9,
- "bullets": 4,
- "split": 1,
- "hero": 1,
- "title": 4
- }
- },
- {
- "id": 90,
- "dir": "90",
- "name": "Gov Pack",
- "tone": "Government/Public Sector",
- "description": "Formal, legible, and conservative layout for public comms.",
- "variants": {
- "base": 9,
- "bullets": 5,
- "split": 2,
- "hero": 2,
- "title": 1
- }
- },
- {
- "id": 91,
- "dir": "91",
- "name": "Studio Deck",
- "tone": "Creative Studio",
- "description": "Gallery/glass composition for portfolios and creative pitches.",
- "variants": {
- "base": 1,
- "bullets": 1,
- "split": 4,
- "hero": 1,
- "title": 1
- }
- },
- {
- "id": 92,
- "dir": "92",
- "name": "Portfolio",
- "tone": "Creative Studio",
- "description": "Gallery/glass composition for portfolios and creative pitches.",
- "variants": {
- "base": 1,
- "bullets": 2,
- "split": 5,
- "hero": 2,
- "title": 2
- }
- },
- {
- "id": 93,
- "dir": "93",
- "name": "Moodboard",
- "tone": "Creative Studio",
- "description": "Gallery/glass composition for portfolios and creative pitches.",
- "variants": {
- "base": 1,
- "bullets": 3,
- "split": 1,
- "hero": 3,
- "title": 3
- }
- },
- {
- "id": 94,
- "dir": "94",
- "name": "Art Direction",
- "tone": "Creative Studio",
- "description": "Gallery/glass composition for portfolios and creative pitches.",
- "variants": {
- "base": 1,
- "bullets": 4,
- "split": 2,
- "hero": 1,
- "title": 4
- }
- },
- {
- "id": 95,
- "dir": "95",
- "name": "Design Sprint",
- "tone": "Creative Studio",
- "description": "Gallery/glass composition for portfolios and creative pitches.",
- "variants": {
- "base": 1,
- "bullets": 5,
- "split": 3,
- "hero": 2,
- "title": 1
- }
- },
- {
- "id": 96,
- "dir": "96",
- "name": "Stadium",
- "tone": "Sports/Energy",
- "description": "Bold band framing; dynamic pacing and clear takeaways.",
- "variants": {
- "base": 4,
- "bullets": 1,
- "split": 5,
- "hero": 1,
- "title": 1
- }
- },
- {
- "id": 97,
- "dir": "97",
- "name": "Pulse",
- "tone": "Sports/Energy",
- "description": "Bold band framing; dynamic pacing and clear takeaways.",
- "variants": {
- "base": 4,
- "bullets": 2,
- "split": 1,
- "hero": 2,
- "title": 2
- }
- },
- {
- "id": 98,
- "dir": "98",
- "name": "Game Plan",
- "tone": "Sports/Energy",
- "description": "Bold band framing; dynamic pacing and clear takeaways.",
- "variants": {
- "base": 4,
- "bullets": 3,
- "split": 2,
- "hero": 3,
- "title": 3
- }
- },
- {
- "id": 99,
- "dir": "99",
- "name": "Athlete Story",
- "tone": "Sports/Energy",
- "description": "Bold band framing; dynamic pacing and clear takeaways.",
- "variants": {
- "base": 4,
- "bullets": 4,
- "split": 3,
- "hero": 1,
- "title": 4
- }
- },
- {
- "id": 100,
- "dir": "100",
- "name": "High Energy",
- "tone": "Sports/Energy",
- "description": "Bold band framing; dynamic pacing and clear takeaways.",
- "variants": {
- "base": 4,
- "bullets": 5,
- "split": 4,
- "hero": 2,
- "title": 1
- }
- }
- ]
-}
\ No newline at end of file
diff --git a/services/response-api/assets/slide_creator/templates/index.md b/services/response-api/assets/slide_creator/templates/index.md
deleted file mode 100644
index 5126ded6..00000000
--- a/services/response-api/assets/slide_creator/templates/index.md
+++ /dev/null
@@ -1,105 +0,0 @@
-# Template Catalog (1–100)
-Each template folder contains: `base.html`, `title.html`, `bullets.html`, `split.html`, `hero.html`, `llm.html`, and `meta.json`.
-`tone` is the design *vibe*; the actual colors/fonts come from your deck theme.
-| ID | Name | Tone | Notes |
-|---:|---|---|---|
-| 1 | Neon City | Neon Cyberpunk | Aurora glows + high-energy composition for futuristic themes. |
-| 2 | Cyber Grid | Neon Cyberpunk | Aurora glows + high-energy composition for futuristic themes. |
-| 3 | Laser Night | Neon Cyberpunk | Aurora glows + high-energy composition for futuristic themes. |
-| 4 | Synthwave | Neon Cyberpunk | Aurora glows + high-energy composition for futuristic themes. |
-| 5 | Night Neon | Neon Cyberpunk | Aurora glows + high-energy composition for futuristic themes. |
-| 6 | Ivory Minimal | Minimal Clean | Whitespace-forward, neutral framing, restrained accents. |
-| 7 | Stone Minimal | Minimal Clean | Whitespace-forward, neutral framing, restrained accents. |
-| 8 | Cloud Minimal | Minimal Clean | Whitespace-forward, neutral framing, restrained accents. |
-| 9 | Calm Minimal | Minimal Clean | Whitespace-forward, neutral framing, restrained accents. |
-| 10 | Mono Minimal | Minimal Clean | Whitespace-forward, neutral framing, restrained accents. |
-| 11 | Consulting Edge | Corporate Consulting | Executive framing, clear hierarchy, client-ready polish. |
-| 12 | Boardroom Brief | Corporate Consulting | Executive framing, clear hierarchy, client-ready polish. |
-| 13 | Executive Slate | Corporate Consulting | Executive framing, clear hierarchy, client-ready polish. |
-| 14 | Strategy Pack | Corporate Consulting | Executive framing, clear hierarchy, client-ready polish. |
-| 15 | Client Brief | Corporate Consulting | Executive framing, clear hierarchy, client-ready polish. |
-| 16 | Dark Terminal | Tech Dark | Dark glass + glow, strong contrast, product/engineering feel. |
-| 17 | Night Ops | Tech Dark | Dark glass + glow, strong contrast, product/engineering feel. |
-| 18 | Quantum Slate | Tech Dark | Dark glass + glow, strong contrast, product/engineering feel. |
-| 19 | Carbon Studio | Tech Dark | Dark glass + glow, strong contrast, product/engineering feel. |
-| 20 | Midnight Grid | Tech Dark | Dark glass + glow, strong contrast, product/engineering feel. |
-| 21 | Launchpad Pitch | Startup Bold | Accent band + bold rhythm, pitch-deck energy. |
-| 22 | Venture Bold | Startup Bold | Accent band + bold rhythm, pitch-deck energy. |
-| 23 | Momentum Deck | Startup Bold | Accent band + bold rhythm, pitch-deck energy. |
-| 24 | Growth Sprint | Startup Bold | Accent band + bold rhythm, pitch-deck energy. |
-| 25 | Demo Day | Startup Bold | Accent band + bold rhythm, pitch-deck energy. |
-| 26 | Cotton Candy | Playful Pastel | Soft patterns and friendly shapes; great for consumer topics. |
-| 27 | Peach Pop | Playful Pastel | Soft patterns and friendly shapes; great for consumer topics. |
-| 28 | Mint Joy | Playful Pastel | Soft patterns and friendly shapes; great for consumer topics. |
-| 29 | Lavender Fun | Playful Pastel | Soft patterns and friendly shapes; great for consumer topics. |
-| 30 | Bubblegum | Playful Pastel | Soft patterns and friendly shapes; great for consumer topics. |
-| 31 | Magazine Serif | Editorial Serif | Paper/grid editorial vibe; strong reading flow. |
-| 32 | Op-Ed | Editorial Serif | Paper/grid editorial vibe; strong reading flow. |
-| 33 | Pressroom | Editorial Serif | Paper/grid editorial vibe; strong reading flow. |
-| 34 | Classic Journal | Editorial Serif | Paper/grid editorial vibe; strong reading flow. |
-| 35 | Notebook Editorial | Editorial Serif | Paper/grid editorial vibe; strong reading flow. |
-| 36 | Onyx Luxe | Luxury Elegant | Rounded stage, premium spacing, gallery-like feel. |
-| 37 | Silk Gallery | Luxury Elegant | Rounded stage, premium spacing, gallery-like feel. |
-| 38 | Chateau | Luxury Elegant | Rounded stage, premium spacing, gallery-like feel. |
-| 39 | Noir Elegant | Luxury Elegant | Rounded stage, premium spacing, gallery-like feel. |
-| 40 | Gold Accent | Luxury Elegant | Rounded stage, premium spacing, gallery-like feel. |
-| 41 | Clinic Clean | Healthcare Calm | Clean, calm, accessible layouts; works well with light themes. |
-| 42 | Care Path | Healthcare Calm | Clean, calm, accessible layouts; works well with light themes. |
-| 43 | Wellness Calm | Healthcare Calm | Clean, calm, accessible layouts; works well with light themes. |
-| 44 | Aqua Relief | Healthcare Calm | Clean, calm, accessible layouts; works well with light themes. |
-| 45 | Soft Green | Healthcare Calm | Clean, calm, accessible layouts; works well with light themes. |
-| 46 | Classroom | Education Friendly | Sidebar guidance + structured body; classroom/learning friendly. |
-| 47 | Notebook | Education Friendly | Sidebar guidance + structured body; classroom/learning friendly. |
-| 48 | Campus | Education Friendly | Sidebar guidance + structured body; classroom/learning friendly. |
-| 49 | Study Buddy | Education Friendly | Sidebar guidance + structured body; classroom/learning friendly. |
-| 50 | Lesson Plan | Education Friendly | Sidebar guidance + structured body; classroom/learning friendly. |
-| 51 | Market Brief | Finance Professional | Structured, conservative frames for finance/strategy decks. |
-| 52 | Investor Note | Finance Professional | Structured, conservative frames for finance/strategy decks. |
-| 53 | Capital Ledger | Finance Professional | Structured, conservative frames for finance/strategy decks. |
-| 54 | Quarterly Review | Finance Professional | Structured, conservative frames for finance/strategy decks. |
-| 55 | Risk Report | Finance Professional | Structured, conservative frames for finance/strategy decks. |
-| 56 | Earth Brief | Sustainability Earthy | Grid/paper background pairs well with earthy palettes. |
-| 57 | Forest Notes | Sustainability Earthy | Grid/paper background pairs well with earthy palettes. |
-| 58 | Leaf Strategy | Sustainability Earthy | Grid/paper background pairs well with earthy palettes. |
-| 59 | Eco Report | Sustainability Earthy | Grid/paper background pairs well with earthy palettes. |
-| 60 | Green Path | Sustainability Earthy | Grid/paper background pairs well with earthy palettes. |
-| 61 | Campaign Studio | Marketing Vibrant | Top band + punchy accents; campaign and brand stories. |
-| 62 | Spotlight | Marketing Vibrant | Top band + punchy accents; campaign and brand stories. |
-| 63 | Brand Burst | Marketing Vibrant | Top band + punchy accents; campaign and brand stories. |
-| 64 | Creative Ad | Marketing Vibrant | Top band + punchy accents; campaign and brand stories. |
-| 65 | Launch Creative | Marketing Vibrant | Top band + punchy accents; campaign and brand stories. |
-| 66 | Dashboard | Data Analyst | Grid-forward layout for charts/tables and analytic narratives. |
-| 67 | Gridline | Data Analyst | Grid-forward layout for charts/tables and analytic narratives. |
-| 68 | Analytics | Data Analyst | Grid-forward layout for charts/tables and analytic narratives. |
-| 69 | Insight Pack | Data Analyst | Grid-forward layout for charts/tables and analytic narratives. |
-| 70 | Metrics Review | Data Analyst | Grid-forward layout for charts/tables and analytic narratives. |
-| 71 | Retro Wave | Retro | Dot pattern + playful framing; retro/nostalgia tone. |
-| 72 | Cassette | Retro | Dot pattern + playful framing; retro/nostalgia tone. |
-| 73 | Polaroid | Retro | Dot pattern + playful framing; retro/nostalgia tone. |
-| 74 | Arcade | Retro | Dot pattern + playful framing; retro/nostalgia tone. |
-| 75 | Vintage Print | Retro | Dot pattern + playful framing; retro/nostalgia tone. |
-| 76 | Mono Black | Monochrome | Minimal frame tuned for black/white/gray palettes. |
-| 77 | Mono White | Monochrome | Minimal frame tuned for black/white/gray palettes. |
-| 78 | Grayscale | Monochrome | Minimal frame tuned for black/white/gray palettes. |
-| 79 | Ink | Monochrome | Minimal frame tuned for black/white/gray palettes. |
-| 80 | Charcoal | Monochrome | Minimal frame tuned for black/white/gray palettes. |
-| 81 | Gradient Flow | Gradient Modern | Band gradient + modern spacing; works with gradient palettes. |
-| 82 | Sunrise | Gradient Modern | Band gradient + modern spacing; works with gradient palettes. |
-| 83 | Aurora Modern | Gradient Modern | Band gradient + modern spacing; works with gradient palettes. |
-| 84 | Spectrum | Gradient Modern | Band gradient + modern spacing; works with gradient palettes. |
-| 85 | Horizon | Gradient Modern | Band gradient + modern spacing; works with gradient palettes. |
-| 86 | Public Brief | Government/Public Sector | Formal, legible, and conservative layout for public comms. |
-| 87 | Policy Note | Government/Public Sector | Formal, legible, and conservative layout for public comms. |
-| 88 | Civic Update | Government/Public Sector | Formal, legible, and conservative layout for public comms. |
-| 89 | Agency Report | Government/Public Sector | Formal, legible, and conservative layout for public comms. |
-| 90 | Gov Pack | Government/Public Sector | Formal, legible, and conservative layout for public comms. |
-| 91 | Studio Deck | Creative Studio | Gallery/glass composition for portfolios and creative pitches. |
-| 92 | Portfolio | Creative Studio | Gallery/glass composition for portfolios and creative pitches. |
-| 93 | Moodboard | Creative Studio | Gallery/glass composition for portfolios and creative pitches. |
-| 94 | Art Direction | Creative Studio | Gallery/glass composition for portfolios and creative pitches. |
-| 95 | Design Sprint | Creative Studio | Gallery/glass composition for portfolios and creative pitches. |
-| 96 | Stadium | Sports/Energy | Bold band framing; dynamic pacing and clear takeaways. |
-| 97 | Pulse | Sports/Energy | Bold band framing; dynamic pacing and clear takeaways. |
-| 98 | Game Plan | Sports/Energy | Bold band framing; dynamic pacing and clear takeaways. |
-| 99 | Athlete Story | Sports/Energy | Bold band framing; dynamic pacing and clear takeaways. |
-| 100 | High Energy | Sports/Energy | Bold band framing; dynamic pacing and clear takeaways. |
diff --git a/services/response-api/assets/slide_creator/templates/standards/base.html b/services/response-api/assets/slide_creator/templates/standards/base.html
deleted file mode 100644
index a3388e2b..00000000
--- a/services/response-api/assets/slide_creator/templates/standards/base.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{template "body" .}}
-
-
-
-
-
-
-
diff --git a/services/response-api/assets/slide_creator/templates/standards/bullets.html b/services/response-api/assets/slide_creator/templates/standards/bullets.html
deleted file mode 100644
index 02c88f31..00000000
--- a/services/response-api/assets/slide_creator/templates/standards/bullets.html
+++ /dev/null
@@ -1,18 +0,0 @@
-{{define "body"}}
-
- Overview
- {{trimToRunes .Slide.Title 90}}
- {{if .Bullets.Subtitle}}{{trimToRunes .Bullets.Subtitle 140}}
{{end}}
-
-
-
- {{range .Bullets.Bullets}}
-
-
- {{trimToRunes . 140}}
-
- {{end}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/standards/chart.html b/services/response-api/assets/slide_creator/templates/standards/chart.html
deleted file mode 100644
index e2a43c16..00000000
--- a/services/response-api/assets/slide_creator/templates/standards/chart.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{{define "body"}}
-
-
- Data Insights
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
- {{if .Slide.Bullets}}
-
-
- {{range .Slide.Bullets}}
-
-
- {{trimToRunes . 120}}
-
- {{end}}
-
-
- {{end}}
-
-
-
- {{if .Chart.Title}}
{{.Chart.Title}}
{{end}}
-
- {{if eq .Chart.Type "bar"}}
-
-
- {{range .Chart.Bars}}
-
- {{end}}
-
- {{else if eq .Chart.Type "line"}}
-
-
- {{range $i, $path := .Chart.LinePaths}}
-
- {{end}}
- {{range $si, $series := .Chart.Points}}
- {{range $pt := $series}}
-
- {{end}}
- {{end}}
-
- {{else if eq .Chart.Type "pie"}}
-
- {{range .Chart.Slices}}
-
- {{end}}
-
- {{end}}
-
- {{if .Chart.Notes}}
{{trimToRunes .Chart.Notes 200}}
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/standards/hero.html b/services/response-api/assets/slide_creator/templates/standards/hero.html
deleted file mode 100644
index cf5343f0..00000000
--- a/services/response-api/assets/slide_creator/templates/standards/hero.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{define "body"}}
-
-
-
-
-
-
{{trimToRunes .Hero.Kicker 80}}
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Hero.ImageCaption 140}}
-
-
-
{{trimToRunes .Hero.Badge 80}}
-
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/standards/llm.html b/services/response-api/assets/slide_creator/templates/standards/llm.html
deleted file mode 100644
index 0ab79680..00000000
--- a/services/response-api/assets/slide_creator/templates/standards/llm.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{{define "body"}}
-{{.BodyHTML}}
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/standards/split.html b/services/response-api/assets/slide_creator/templates/standards/split.html
deleted file mode 100644
index 1dedece0..00000000
--- a/services/response-api/assets/slide_creator/templates/standards/split.html
+++ /dev/null
@@ -1,34 +0,0 @@
-{{define "body"}}
-
-
- {{.Split.Label}}
- {{trimToRunes .Slide.Title 90}}
- {{if .Split.Subtitle}}{{trimToRunes .Split.Subtitle 140}}
{{end}}
-
-
-
- {{range .Split.Bullets}}
-
-
- {{trimToRunes . 140}}
-
- {{end}}
-
-
-
-
- {{if .Split.HasImage}}
-
-
-
- {{trimToRunes .Split.ImageCaption 110}}
-
- {{else}}
-
-
Highlights
-
{{trimToRunes .Slide.Title 90}}
-
{{trimToRunes .Slide.Subtitle 160}}
-
- {{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/standards/table.html b/services/response-api/assets/slide_creator/templates/standards/table.html
deleted file mode 100644
index cea95415..00000000
--- a/services/response-api/assets/slide_creator/templates/standards/table.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{define "body"}}
-
- {{if .Table.Title}}{{.Table.Title}}{{else}}Data Overview{{end}}
- {{trimToRunes .Slide.Title 80}}
- {{if .Slide.Subtitle}}{{trimToRunes .Slide.Subtitle 120}}
{{end}}
-
-
-
-
-
- {{range .Table.Columns}}
- {{trimToRunes . 24}}
- {{end}}
-
-
-
- {{range $row := .Table.Rows}}
-
- {{range $ci, $cell := $row}}
- {{trimToRunes $cell 28}}
- {{end}}
-
- {{end}}
-
-
-
-
- {{if .Table.Notes}}{{trimToRunes .Table.Notes 200}}
{{end}}
-
-{{end}}
diff --git a/services/response-api/assets/slide_creator/templates/standards/title.html b/services/response-api/assets/slide_creator/templates/standards/title.html
deleted file mode 100644
index 38f2b2c7..00000000
--- a/services/response-api/assets/slide_creator/templates/standards/title.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{define "body"}}
-
-
-
Slide {{.Index}}/{{.Total}}
-
{{trimToRunes .Slide.Title 120}}
- {{if .Slide.Subtitle}}
{{trimToRunes .Slide.Subtitle 220}}
{{end}}
- {{if .Title.Notes}}
- {{trimToRunes .Title.Notes 80}}
-
{{end}}
-
-
-{{end}}
diff --git a/services/response-api/assets/slide_renderer/embedded.go b/services/response-api/assets/slide_renderer/embedded.go
deleted file mode 100644
index ddfe2696..00000000
--- a/services/response-api/assets/slide_renderer/embedded.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package sliderenderer
-
-import _ "embed"
-
-// RenderDeckScript embeds render_deck.py for sandbox execution.
-//
-//go:embed render_deck.py
-var RenderDeckScript string
diff --git a/services/response-api/assets/slide_renderer/render_deck.py b/services/response-api/assets/slide_renderer/render_deck.py
deleted file mode 100644
index c94904a7..00000000
--- a/services/response-api/assets/slide_renderer/render_deck.py
+++ /dev/null
@@ -1,1247 +0,0 @@
-#!/usr/bin/env python3
-"""
-render_deck.py
-Render a DeckSpec-like JSON to PPTX using python-pptx.
-
-Supported:
-- theme.canvas.size: WIDE_16x9, STANDARD_4x3, or CUSTOM (inches)
-- masters.globalElements applied to each slide via layout.masterId
-- components referenced by slide.useComponents
-- element types: text, shape, table, chart, image (file & URL), group (flatten)
-- chart: bar|line|pie|area, dataset kind: series
-- text: rich text runs, bullets, alignment
-- shape: fill (solid/gradient), stroke, rotation, opacity
-- speakerNotes
-
-Usage:
- python render_deck.py input.json output.pptx
-"""
-# CRITICAL: Print immediately to confirm module loading starts
-import sys
-print(">>> MODULE LOAD: render_deck.py starting", file=sys.stderr, flush=True)
-
-import json
-import re
-import logging
-import tempfile
-import io
-from pathlib import Path
-from urllib.parse import urlparse
-
-print(">>> MODULE LOAD: stdlib imports OK", file=sys.stderr, flush=True)
-
-print(">>> MODULE LOAD: stdlib imports OK", file=sys.stderr, flush=True)
-
-try:
- import requests
- HAS_REQUESTS = True
- print(">>> MODULE LOAD: requests available", file=sys.stderr, flush=True)
-except ImportError:
- HAS_REQUESTS = False
- print(">>> MODULE LOAD: requests NOT available", file=sys.stderr, flush=True)
-
-try:
- from PIL import Image
- HAS_PIL = True
-except ImportError:
- HAS_PIL = False
-
-print(">>> MODULE LOAD: importing pptx...", file=sys.stderr, flush=True)
-from pptx import Presentation
-from pptx.util import Inches, Pt
-from pptx.dml.color import RGBColor
-from pptx.oxml.ns import qn
-from pptx.enum.text import PP_ALIGN, MSO_VERTICAL_ANCHOR, MSO_AUTO_SIZE
-from pptx.enum.shapes import MSO_SHAPE, MSO_CONNECTOR
-from pptx.chart.data import ChartData
-from pptx.enum.chart import XL_CHART_TYPE
-print(">>> MODULE LOAD: pptx imports OK", file=sys.stderr, flush=True)
-
-print(">>> MODULE LOAD: pptx imports OK", file=sys.stderr, flush=True)
-
-# ----------------------------
-# Logging setup
-# ----------------------------
-print(">>> MODULE LOAD: configuring logging", file=sys.stderr, flush=True)
-logging.basicConfig(
- level=logging.INFO,
- format='%(asctime)s - %(levelname)s - %(message)s',
- stream=sys.stderr, # Explicitly write to stderr for subprocess capture
- force=True # Override any existing config
-)
-logger = logging.getLogger(__name__)
-logger.info("Logger initialized")
-print(">>> MODULE LOAD: logging configured", file=sys.stderr, flush=True)
-
-# ----------------------------
-# Constants
-# ----------------------------
-WIDE_16x9_DIMS = (13.333, 7.5)
-STANDARD_4x3_DIMS = (10.0, 7.5)
-EMU_PER_INCH = 914400 # PowerPoint internal units
-
-# ----------------------------
-# Helpers
-# ----------------------------
-def hex_to_rgb(hex_color: str):
- if not hex_color:
- return None
- h = hex_color.strip()
- if h.startswith("#"):
- h = h[1:]
- if len(h) == 8: # ignore alpha
- h = h[:6]
- if len(h) != 6:
- return None
- r = int(h[0:2], 16)
- g = int(h[2:4], 16)
- b = int(h[4:6], 16)
- return RGBColor(r, g, b)
-
-def emu_in(x_in: float):
- return Inches(float(x_in))
-
-# Global unit setting - will be set by render()
-_current_unit = "in"
-
-def set_unit(unit: str):
- global _current_unit
- _current_unit = unit
-
-def convert_to_inches(val: float) -> float:
- """Convert value from current unit to inches (no scaling)."""
- if _current_unit == "pt":
- return val / 72.0
- elif _current_unit == "cm":
- return val / 2.54
- return val # already inches
-
-def rect_in(rect: dict):
- """Convert rect coordinates to PowerPoint Inches based on current unit."""
- x = convert_to_inches(float(rect.get("x", 0)))
- y = convert_to_inches(float(rect.get("y", 0)))
- w = convert_to_inches(float(rect.get("w", 0)))
- h = convert_to_inches(float(rect.get("h", 0)))
- return (emu_in(x), emu_in(y), emu_in(w), emu_in(h))
-
-def rect_from_grid(grid: dict, y: float, h: float, theme: dict):
- """Compute rect (in deck units) from grid + y/h using theme.canvas.safeMargins."""
- if not grid:
- return None
- canvas = (theme or {}).get("canvas", {}) or {}
- safe = canvas.get("safeMargins", {"top": 36, "right": 36, "bottom": 36, "left": 36})
- grid_cfg = (theme or {}).get("grid", {}) or {}
- columns = int(grid_cfg.get("columns", 12) or 12)
- gutter = float(grid_cfg.get("gutter", 16) or 0)
- baseline = float(grid_cfg.get("baseline", 8) or 8)
- snap = bool(grid_cfg.get("snap", True))
-
- slide_w = 960.0
- usable_w = slide_w - float(safe.get("left", 36)) - float(safe.get("right", 36))
- col_w = (usable_w - gutter * (columns - 1)) / columns
- col = int(grid.get("col", 1))
- span = int(grid.get("span", 1))
- x = float(safe.get("left", 36)) + (col - 1) * (col_w + gutter)
- w = span * col_w + (span - 1) * gutter
- if snap and baseline:
- y = round(float(y) / baseline) * baseline
- h = round(float(h) / baseline) * baseline
- return {"x": x, "y": y, "w": w, "h": h}
-
-def resolve_slot_rects(layout: dict, elements: list, theme: dict):
- """Fill rects for elements that reference slotId."""
- if not layout:
- return
- slots = {s.get("id"): s for s in layout.get("slots", []) if isinstance(s, dict)}
- if not slots:
- return
- for el in elements or []:
- if not isinstance(el, dict):
- continue
- if el.get("rect"):
- continue
- slot_id = el.get("slotId")
- if not slot_id:
- continue
- slot = slots.get(slot_id)
- if not slot:
- continue
- if isinstance(slot.get("rect"), dict):
- rect = slot.get("rect")
- else:
- grid = slot.get("grid", {}) or {}
- y = slot.get("y", 0)
- h = slot.get("h", 0)
- rect = rect_from_grid(grid, y, h, theme)
- if rect:
- el["rect"] = rect
-
-ALIGN_MAP = {
- "left": PP_ALIGN.LEFT,
- "center": PP_ALIGN.CENTER,
- "right": PP_ALIGN.RIGHT,
- "justify": PP_ALIGN.JUSTIFY
-}
-VALIGN_MAP = {
- "top": MSO_VERTICAL_ANCHOR.TOP,
- "middle": MSO_VERTICAL_ANCHOR.MIDDLE,
- "bottom": MSO_VERTICAL_ANCHOR.BOTTOM
-}
-
-
-
-VAR_PATTERN = re.compile(r"\{\{\s*([a-zA-Z0-9_.-]+)\s*\}\}")
-
-def substitute_vars(s: str, ctx: dict, page_num: int, total_pages: int) -> str:
- """Replace {page}, {total_pages}, and {{var}} placeholders using ctx."""
- if s is None:
- return ""
- out = str(s)
- out = out.replace("{page}", str(page_num))
- out = out.replace("{total_pages}", str(total_pages)).replace("{totalPages}", str(total_pages))
-
- def _lookup(key: str):
- if key in ("page", "pageNumber"):
- return str(page_num)
- if key in ("total_pages", "totalPages", "totalPagesCount"):
- return str(total_pages)
- if not ctx:
- return None
- if key in ctx and ctx[key] is not None:
- return ctx[key]
- if "." in key:
- cur = ctx
- for part in key.split('.'):
- if isinstance(cur, dict) and part in cur:
- cur = cur[part]
- else:
- return None
- return cur
- return None
-
- def repl(m):
- key = m.group(1)
- val = _lookup(key)
- return str(val) if val is not None else m.group(0)
-
- return VAR_PATTERN.sub(repl, out)
-def safe_contains(rect, safe):
- """Check if rect is within safe margins (all values in inches after conversion)."""
- x = convert_to_inches(float(rect.get("x", 0)))
- y = convert_to_inches(float(rect.get("y", 0)))
- w = convert_to_inches(float(rect.get("w", 0)))
- h = convert_to_inches(float(rect.get("h", 0)))
- return (x >= safe["left"] and
- y >= safe["top"] and
- x + w <= (safe["slide_w"] - safe["right"]) and
- y + h <= (safe["slide_h"] - safe["bottom"]))
-
-def set_fill(shape, fill_spec: dict):
- """Apply fill to a shape - supports solid and gradient fills."""
- if not fill_spec or fill_spec.get("type") in (None, "none"):
- return
- ftype = fill_spec.get("type")
- if ftype == "solid":
- color = fill_spec.get("color")
- rgb = hex_to_rgb(color)
- if rgb:
- shape.fill.solid()
- shape.fill.fore_color.rgb = rgb
- elif ftype == "gradient":
- # python-pptx has limited gradient support, use first/last stops as approximation
- gradient = fill_spec.get("gradient", {})
- stops = gradient.get("stops", [])
- if stops:
- # Use first color as solid fill (gradient approximation)
- first_color = stops[0].get("color")
- rgb = hex_to_rgb(first_color)
- if rgb:
- shape.fill.solid()
- shape.fill.fore_color.rgb = rgb
- logger.debug(f"Gradient fill approximated with solid color: {first_color}")
-
-def set_line(shape, stroke_spec: dict):
- if not stroke_spec:
- return
- line = shape.line
- color = stroke_spec.get("color")
- width = stroke_spec.get("width")
- if color:
- rgb = hex_to_rgb(color)
- if rgb:
- line.color.rgb = rgb
- if width is not None:
- line.width = Pt(float(width))
-
-
-
-def _remove_effects(shape):
- """Remove effect lists (shadow/glow) from a shape/picture/chart."""
- try:
- sp = shape._element
- spPr = sp.find(qn('p:spPr'))
- if spPr is None:
- return
- for tag in ('a:effectLst', 'a:effectDag'):
- eff = spPr.find(qn(tag))
- if eff is not None:
- spPr.remove(eff)
- except Exception:
- pass
-
-
-def disable_shadow(shape):
- """Best-effort: disable any drop shadow (cleaner, flatter templates)."""
- try:
- sh = getattr(shape, 'shadow', None)
- if sh is not None:
- try:
- sh.inherit = False
- except Exception:
- pass
- try:
- sh.visible = False
- except Exception:
- pass
- except Exception:
- pass
-
- # Also remove effect lists in underlying XML (more reliable than the API)
- _remove_effects(shape)
-
-def _enable_bullet(p, bullet_spec: dict):
- """Enable bullets on paragraph, with optional indent/hanging (in pt)."""
- try:
- from lxml import etree
- p.level = 0
- pPr = p._p.get_or_add_pPr()
- buChar = pPr.find(qn('a:buChar'))
- if buChar is None:
- buChar = etree.SubElement(pPr, qn('a:buChar'))
- buChar.set('char', '•')
-
- # Indentation values in DrawingML are in EMU
- indent = bullet_spec.get('indent')
- hanging = bullet_spec.get('hanging')
- if indent is not None:
- marL = int((float(indent) / 72.0) * EMU_PER_INCH)
- pPr.set('marL', str(marL))
- if hanging is not None:
- ind = -int((float(hanging) / 72.0) * EMU_PER_INCH)
- pPr.set('indent', str(ind))
- except Exception:
- pass
-
-
-def _extract_text_obj(el: dict) -> dict:
- text_obj = el.get("text")
- if isinstance(text_obj, dict):
- return text_obj
-
- content = el.get("content")
- if isinstance(content, dict):
- # Possible shapes:
- # {"text": {"content": "...", "style": {...}}}
- # {"text": "...", "style": {...}}
- # {"content": "...", "style": {...}}
- nested = content.get("text")
- if isinstance(nested, dict):
- return nested
- if isinstance(nested, str):
- return {"content": nested, "style": content.get("style", {})}
- raw = content.get("content")
- if isinstance(raw, str):
- return {"content": raw, "style": content.get("style", {})}
- if "style" in content:
- return {"content": "", "style": content.get("style", {})}
-
- if isinstance(content, str):
- return {"content": content}
-
- return {}
-
-def add_text(slide, el, theme_defaults_text, slide_number: int, total_pages: int, text_ctx: dict):
- """Add text element with support for rich text runs, bullets, and auto-fit."""
- left, top, width, height = rect_in(el["rect"])
- tb = slide.shapes.add_textbox(left, top, width, height)
- tf = tb.text_frame
- tf.clear()
- tf.word_wrap = True
-
- text_obj = _extract_text_obj(el)
- content = text_obj.get("content", "") or ""
-
- # If content uses "|" as newline delimiter, normalize it (common in prompts)
- if "|" in content and "\n" not in content:
- content = content.replace("|", "\n")
-
- # Substitute template variables for simple content (avoid breaking run offsets)
- runs = text_obj.get("runs", []) or []
- if not runs:
- content = substitute_vars(content, text_ctx, slide_number, total_pages)
-
- style = text_obj.get("style") or {}
-
- # Auto-fit controls (schema field text.autoFit)
- auto_fit = text_obj.get("autoFit") or "shrink"
- try:
- if auto_fit == "shrink":
- tf.auto_size = MSO_AUTO_SIZE.TEXT_TO_FIT_SHAPE
- elif auto_fit == "resizeBox":
- tf.auto_size = MSO_AUTO_SIZE.SHAPE_TO_FIT_TEXT
- else:
- tf.auto_size = MSO_AUTO_SIZE.NONE
- except Exception:
- pass
-
- bullet_spec = style.get("bullet") or {}
- bullet_enabled = bool(bullet_spec.get("enabled", False))
-
- lines = content.split("\n") if content else [""]
-
- # Heuristic: if content already looks like a bulleted list, enable bullets
- if not bullet_enabled:
- markers = ("•", "-", "–", "—", "*")
- if any((ln.strip() and ln.lstrip().startswith(markers)) for ln in lines):
- bullet_enabled = True
-
- def _strip_bullet_marker(ln: str) -> str:
- t = ln.strip()
- for m in ("•", "-", "–", "—", "*"):
- if t.startswith(m):
- return t[len(m):].lstrip()
- return t
-
- char_offset = 0 # Track position in original content for runs
-
- for idx, line in enumerate(lines):
- p = tf.paragraphs[0] if idx == 0 else tf.add_paragraph()
-
- line_start = char_offset
- line_end = char_offset + len(line)
- line_runs = [r for r in runs if r.get("start", 0) < line_end and r.get("end", 0) > line_start]
-
- if line_runs:
- # Rich text runs are applied verbatim; bullet-marker stripping is not safe here.
- _apply_rich_text_line(p, line, line_runs, line_start, style, theme_defaults_text)
- else:
- txt = _strip_bullet_marker(line) if bullet_enabled else line.strip()
- p.text = txt
- _apply_paragraph_style(p, style, theme_defaults_text)
-
- if bullet_enabled and (p.text or "").strip():
- _enable_bullet(p, bullet_spec)
-
- align = style.get("align")
- if align in ALIGN_MAP:
- p.alignment = ALIGN_MAP[align]
-
- char_offset = line_end + 1
-
- valign = style.get("valign")
- if valign in VALIGN_MAP:
- tf.vertical_anchor = VALIGN_MAP[valign]
-
- link = el.get("link", {}) or {}
- url = link.get("url")
- if url:
- p0 = tf.paragraphs[0]
- if p0.runs:
- p0.runs[0].hyperlink.address = url
-
- rotation = el.get("rotation")
- if rotation:
- tb.rotation = float(rotation)
-
- disable_shadow(tb)
- return tb
-
-
-
-
-
-def _apply_paragraph_style(p, style: dict, theme_defaults_text: dict):
- """Apply style to all text in a paragraph."""
- font = p.font
- family = style.get("fontFamily") or theme_defaults_text.get("fontFamily")
- if family:
- font.name = family
- size = style.get("fontSize") or theme_defaults_text.get("fontSize")
- if size:
- font.size = Pt(float(size))
- if "bold" in style:
- font.bold = bool(style["bold"])
- if "italic" in style:
- font.italic = bool(style["italic"])
- if "underline" in style:
- font.underline = bool(style["underline"])
- color = style.get("color") or theme_defaults_text.get("color")
- rgb = hex_to_rgb(color) if color else None
- if rgb:
- font.color.rgb = rgb
-
- # Line height (multiple) if provided
- lh = style.get("lineHeight")
- if lh is None:
- lh = theme_defaults_text.get("lineHeight")
- if isinstance(lh, (int, float)):
- try:
- p.line_spacing = float(lh)
- except Exception:
- pass
-
-
-
-def _apply_rich_text_line(p, line: str, runs: list, line_start: int, base_style: dict, theme_defaults_text: dict):
- """Apply rich text runs to a paragraph line."""
- # Clear existing text, we'll add runs manually
- p.clear()
-
- # Sort runs by start position
- runs = sorted(runs, key=lambda r: r.get("start", 0))
-
- current_pos = 0
- for run_spec in runs:
- run_start = max(0, run_spec.get("start", 0) - line_start)
- run_end = min(len(line), run_spec.get("end", 0) - line_start)
-
- if run_start > len(line) or run_end < 0:
- continue
-
- # Add text before this run with base style
- if run_start > current_pos:
- r = p.add_run()
- r.text = line[current_pos:run_start]
- _apply_run_style(r, base_style, theme_defaults_text)
-
- # Add the styled run
- if run_end > run_start:
- r = p.add_run()
- r.text = line[run_start:run_end]
- merged_style = {**base_style, **(run_spec.get("style", {}))}
- _apply_run_style(r, merged_style, theme_defaults_text)
- current_pos = run_end
-
- # Add remaining text after last run
- if current_pos < len(line):
- r = p.add_run()
- r.text = line[current_pos:]
- _apply_run_style(r, base_style, theme_defaults_text)
-
-
-def _apply_run_style(run, style: dict, theme_defaults_text: dict):
- """Apply style to a text run."""
- font = run.font
- family = style.get("fontFamily") or theme_defaults_text.get("fontFamily")
- if family:
- font.name = family
- size = style.get("fontSize") or theme_defaults_text.get("fontSize")
- if size:
- font.size = Pt(float(size))
- if "bold" in style:
- font.bold = bool(style["bold"])
- if "italic" in style:
- font.italic = bool(style["italic"])
- if "underline" in style:
- font.underline = bool(style["underline"])
- color = style.get("color") or theme_defaults_text.get("color")
- rgb = hex_to_rgb(color) if color else None
- if rgb:
- font.color.rgb = rgb
-
-
-def add_shape(slide, el):
- """Add shape element with rotation and opacity support.
-
- Guardrails:
- - No rounded rectangles or decorative circles: anything not in the allowed set is rendered as a plain rectangle.
- - Shadows are removed.
- """
- left, top, width, height = rect_in(el["rect"])
- s = el.get("shape", {})
- kind = (s.get("kind") or "rect")
- kind = str(kind)
- style = s.get("style", {}) or {}
-
- if kind in ("line", "arrow"):
- conn = slide.shapes.add_connector(MSO_CONNECTOR.STRAIGHT, left, top, left + width, top + height)
- set_line(conn, (style.get("stroke") or {}))
- if kind == "arrow":
- conn.line.end_arrowhead = True
- disable_shadow(conn)
- return conn
-
- allowed = {"rect", "triangle", "diamond"}
- if kind not in allowed:
- kind = "rect"
-
- SHAPE_MAP = {
- "rect": MSO_SHAPE.RECTANGLE,
- # Any rounded/oval requests are forced to RECTANGLE by design
- "roundRect": MSO_SHAPE.RECTANGLE,
- "roundedRect": MSO_SHAPE.RECTANGLE,
- "pill": MSO_SHAPE.RECTANGLE,
- "ellipse": MSO_SHAPE.RECTANGLE,
- "circle": MSO_SHAPE.RECTANGLE,
- "oval": MSO_SHAPE.RECTANGLE,
- "triangle": MSO_SHAPE.ISOSCELES_TRIANGLE,
- "diamond": MSO_SHAPE.DIAMOND,
- }
- shape_type = SHAPE_MAP.get(kind, MSO_SHAPE.RECTANGLE)
- shp = slide.shapes.add_shape(shape_type, left, top, width, height)
- set_fill(shp, style.get("fill"))
- set_line(shp, (style.get("stroke") or {}))
- disable_shadow(shp)
-
- rotation = el.get("rotation")
- if rotation:
- shp.rotation = float(rotation)
-
- return shp
-
-
-def add_table(slide, el, theme_defaults_text, slide_number: int):
- left, top, width, height = rect_in(el["rect"])
- t = el.get("table", {})
- cols = t.get("columns", [])
- rows = t.get("rows", [])
- nrows = 1 + len(rows)
- ncols = max(1, len(cols))
- table_shape = slide.shapes.add_table(nrows, ncols, left, top, width, height)
- table = table_shape.table
-
- def _col_header(col):
- if isinstance(col, dict):
- for key in ("header", "title", "name", "label", "text"):
- val = col.get(key)
- if val is not None:
- return str(val)
- return ""
- if col is None:
- return ""
- return str(col)
-
- def _col_width(col):
- if isinstance(col, dict):
- width_val = col.get("width")
- if isinstance(width_val, (int, float)):
- return float(width_val)
- return None
-
- for c in range(ncols):
- hdr = cols[c] if c < len(cols) else ""
- table.cell(0, c).text = _col_header(hdr)
- col_width = _col_width(hdr)
- if col_width is not None:
- table.columns[c].width = Pt(col_width)
-
- for r_i, row in enumerate(rows, start=1):
- for c in range(ncols):
- val = row[c] if c < len(row) else ""
- if isinstance(val, dict):
- for key in ("text", "value", "label", "name"):
- if key in val:
- val = val[key]
- break
- table.cell(r_i, c).text = "" if val is None else str(val)
-
- style = t.get("style", {})
- hdr_style = style.get("headerTextStyle", {})
- cell_style = style.get("cellTextStyle", {})
-
- def style_cell(cell, st):
- tf = cell.text_frame
- p = tf.paragraphs[0]
- font = p.font
- family = st.get("fontFamily") or theme_defaults_text.get("fontFamily")
- if family:
- font.name = family
- size = st.get("fontSize") or theme_defaults_text.get("fontSize")
- if size:
- font.size = Pt(float(size))
- color = st.get("color") or theme_defaults_text.get("color")
- rgb = hex_to_rgb(color) if color else None
- if rgb:
- font.color.rgb = rgb
- if "bold" in st:
- font.bold = bool(st["bold"])
-
- for c in range(ncols):
- style_cell(table.cell(0, c), hdr_style)
- for r in range(1, nrows):
- for c in range(ncols):
- style_cell(table.cell(r, c), cell_style)
-
- return table_shape
-
-def _extract_chart_obj(el: dict) -> dict:
- chart_obj = el.get("chart")
- if isinstance(chart_obj, dict):
- return chart_obj
-
- content = el.get("content")
- if isinstance(content, dict):
- nested = content.get("chart")
- if isinstance(nested, dict):
- return nested
- if "chartType" in content or "datasetRef" in content:
- return content
-
- return {}
-
-
-def add_chart(slide, el, datasets_by_id):
- """Add chart element with support for bar, line, pie, and area charts."""
- left, top, width, height = rect_in(el["rect"])
- c = _extract_chart_obj(el)
- chart_type = c.get("chartType", "bar")
- ds_id = c.get("datasetRef")
- ds = datasets_by_id.get(ds_id) if ds_id else None
-
- if not ds:
- raise ValueError(f"Chart datasetRef '{ds_id}' not found")
-
- data = ds.get("data", {})
- categories = data.get("labels", [])
- series = data.get("series", [])
- if not categories or not series:
- raise ValueError(f"Chart dataset '{ds_id}' missing labels/series")
-
- chart_data = ChartData()
- chart_data.categories = categories
- for s in series:
- chart_data.add_series(s.get("name", "Series"), s.get("values", []))
-
- # Map chart types including area
- CHART_TYPE_MAP = {
- "line": XL_CHART_TYPE.LINE,
- "pie": XL_CHART_TYPE.PIE,
- "bar": XL_CHART_TYPE.BAR_CLUSTERED,
- }
- if chart_type not in CHART_TYPE_MAP:
- raise ValueError(f"Unsupported chart type: {chart_type}")
- xl_type = CHART_TYPE_MAP.get(chart_type)
-
- chart_shape = slide.shapes.add_chart(xl_type, left, top, width, height, chart_data)
- chart = chart_shape.chart
-
- title = c.get("title")
- if title:
- chart.has_title = True
- chart.chart_title.text_frame.text = title
-
- style = c.get("style", {})
- chart.has_legend = bool(style.get("showLegend", True))
-
- return chart_shape
-
-def _extract_image_obj(el: dict) -> dict:
- image_obj = el.get("image")
- if isinstance(image_obj, dict):
- return image_obj
-
- content = el.get("content")
- if isinstance(content, dict):
- nested = content.get("image")
- if isinstance(nested, dict):
- return nested
- return content
-
- return {}
-
-
-def add_image(slide, el, assets_by_id):
- """Add image element with support for file and URL sources."""
- left, top, width, height = rect_in(el["rect"])
- img = _extract_image_obj(el)
- ref = img.get("ref")
- asset = assets_by_id.get(ref)
- if not asset:
- fallback = None
- if ref:
- for key, value in assets_by_id.items():
- if isinstance(key, str) and (key.startswith(ref) or ref in key):
- fallback = value
- logger.warning(f"Image ref '{ref}' matched asset id '{key}'.")
- break
- if not fallback:
- logger.warning(f"Image ref not found in assets: {ref}. Skipping image.")
- return None
- asset = fallback
-
- src = asset.get("source", {})
- source_type = src.get("type")
-
- image_stream = None
-
- if source_type == "url":
- # Fetch image from URL
- url = src.get("url")
- if not url:
- raise ValueError(f"Image source type is 'url' but no URL provided for ref: {ref}")
-
- if not HAS_REQUESTS:
- raise ImportError("'requests' library is required for URL images. Install with: pip install requests")
-
- logger.info(f"Fetching image from URL: {url}")
- try:
- response = requests.get(url, timeout=30, headers={
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
- })
- response.raise_for_status()
- image_stream = io.BytesIO(response.content)
- logger.info(f"Successfully fetched image: {len(response.content)} bytes")
- except requests.RequestException as e:
- raise ValueError(f"Failed to fetch image from URL {url}: {e}")
-
- elif source_type == "file":
- raw_path_str = src.get("filePath")
- if not raw_path_str:
- raise ValueError(f"Image source type is 'file' but no filePath provided for ref: {ref}")
-
- path = Path(raw_path_str)
-
- # Fallback to local file if absolute path not found
- if not path.exists():
- local_path = Path.cwd() / path.name
- if local_path.exists():
- path = local_path
- else:
- # Also try relative to script if CWD is different
- script_dir_path = Path(__file__).parent / path.name
- if script_dir_path.exists():
- path = script_dir_path
- else:
- raise FileNotFoundError(f"Image file not found: {path} (also checked {local_path})")
-
- image_stream = str(path)
-
- elif source_type == "generated":
- # Placeholder for AI-generated images - log warning and skip
- prompt = src.get("prompt", "")
- logger.warning(f"Generated image type not yet supported. Prompt: {prompt[:50]}...")
- return None
-
- elif source_type == "base64":
- encoded = src.get("base64")
- if not encoded:
- raise ValueError(f"Image source type is 'base64' but no base64 provided for ref: {ref}")
- try:
- import base64
- image_stream = io.BytesIO(base64.b64decode(encoded))
- except Exception as e:
- raise ValueError(f"Failed to decode base64 image for ref {ref}: {e}")
-
- else:
- raise ValueError(f"Unsupported image source type: {source_type}. Use 'file' or 'url'.")
-
- if image_stream is None:
- return None
-
- fit = img.get("fit", "cover")
-
- if fit == "stretch":
- pic = slide.shapes.add_picture(image_stream, left, top, width=width, height=height)
- else:
- pic = slide.shapes.add_picture(image_stream, left, top)
- try:
- img_w_px, img_h_px = pic.image.size
- except Exception:
- img_w_px, img_h_px = (1, 1)
- img_ar = float(img_w_px) / float(img_h_px) if img_h_px else 1.0
- target_ar = float(width) / float(height) if height else 1.0
-
- if fit == "contain":
- if img_ar > target_ar:
- new_w = float(width)
- new_h = new_w / img_ar
- else:
- new_h = float(height)
- new_w = new_h * img_ar
- pic.width = int(new_w)
- pic.height = int(new_h)
- pic.left = int(left + (float(width) - new_w) / 2)
- pic.top = int(top + (float(height) - new_h) / 2)
- else:
- pic.width = int(width)
- pic.height = int(height)
- if img_ar > target_ar:
- crop = (1 - target_ar / img_ar) / 2
- pic.crop_left = crop
- pic.crop_right = crop
- elif img_ar < target_ar:
- crop = (1 - img_ar / target_ar) / 2
- pic.crop_top = crop
- pic.crop_bottom = crop
-
- rotation = el.get("rotation")
- if rotation:
- pic.rotation = float(rotation)
-
- return pic
-
-def flatten_elements(elements, dx: float = 0.0, dy: float = 0.0, dz: int = 0):
- """Flatten nested group structures, applying group rect offsets to children.
-
- This fixes common overlap bugs where children coordinates are relative to the group.
- """
- flat = []
- for el in elements or []:
- if not isinstance(el, dict):
- continue
-
- if el.get("type") == "group":
- g = el.get("group") or {}
- children = g.get("children") or []
- g_rect = el.get("rect") or g.get("rect") or {}
- try:
- gx = float(g_rect.get("x", 0))
- gy = float(g_rect.get("y", 0))
- gw = float(g_rect.get("w", 0))
- gh = float(g_rect.get("h", 0))
- except (TypeError, ValueError):
- gx, gy, gw, gh = 0.0, 0.0, 0.0, 0.0
-
- try:
- gz = int(el.get("zIndex", 0))
- except (TypeError, ValueError):
- gz = 0
- adjusted_children = []
- for child in children:
- if isinstance(child, dict) and isinstance(child.get("rel"), dict) and gw > 0 and gh > 0:
- rel = child.get("rel", {})
- try:
- rx = float(rel.get("x", 0))
- ry = float(rel.get("y", 0))
- rw = float(rel.get("w", 0))
- rh = float(rel.get("h", 0))
- child = dict(child)
- child["rect"] = {
- "x": gx + rx * gw,
- "y": gy + ry * gh,
- "w": rw * gw,
- "h": rh * gh,
- }
- child.pop("rel", None)
- except (TypeError, ValueError):
- pass
- adjusted_children.append(child)
-
- flat.extend(flatten_elements(adjusted_children, dx + gx, dy + gy, dz + gz))
- continue
-
- # Non-group: copy and offset rect
- out = dict(el)
- r = dict(out.get("rect") or {})
- if r:
- try:
- r["x"] = float(r.get("x", 0)) + dx
- r["y"] = float(r.get("y", 0)) + dy
- except (TypeError, ValueError):
- pass
- out["rect"] = r
-
- try:
- out["zIndex"] = int(out.get("zIndex", 0)) + dz
- except (TypeError, ValueError):
- out["zIndex"] = dz
-
- flat.append(out)
-
- return flat
-
-def resolve_top_text_overlaps(slide, region_in: float = 1.75, pad_pt: float = 10.0):
- """Very small, targeted overlap fix:
-
- If two text boxes in the top region overlap significantly in X, push the lower one down.
- This addresses the common title/subtitle overlap when titles wrap unexpectedly.
- """
- try:
- region = int(region_in * EMU_PER_INCH)
- pad = int((pad_pt / 72.0) * EMU_PER_INCH)
-
- texts = [sh for sh in slide.shapes if getattr(sh, 'has_text_frame', False)]
- texts.sort(key=lambda sh: int(sh.top))
-
- # Two passes to reduce cascading overlaps
- for _ in range(2):
- for i in range(len(texts) - 1):
- upper = texts[i]
- lower = texts[i + 1]
- if int(upper.top) > region or int(lower.top) > region:
- continue
-
- ux1, uy1 = int(upper.left), int(upper.top)
- ux2, uy2 = ux1 + int(upper.width), uy1 + int(upper.height)
- lx1, ly1 = int(lower.left), int(lower.top)
- lx2, ly2 = lx1 + int(lower.width), ly1 + int(lower.height)
-
- x_overlap = min(ux2, lx2) - max(ux1, lx1)
- if x_overlap <= 0:
- continue
- if x_overlap < 0.4 * min(int(upper.width), int(lower.width)):
- continue
-
- # If Y-overlap, shift lower down
- if ly1 < uy2 and uy1 < ly2:
- new_top = uy2 + pad
- if new_top > ly1:
- lower.top = new_top
- except Exception:
- pass
-
-
-def render(deck: dict, out_path: Path):
- prs = Presentation()
-
- theme = deck.get("theme", {})
- canvas = theme.get("canvas", {})
- size = canvas.get("size", "WIDE_16x9")
- unit = canvas.get("unit", "in")
-
- # Map common canvas size strings to dimensions (in inches)
- SIZE_MAP = {
- "WIDE_16x9": WIDE_16x9_DIMS,
- "1920x1080": WIDE_16x9_DIMS,
- "1280x720": WIDE_16x9_DIMS,
- "STANDARD_4x3": STANDARD_4x3_DIMS,
- "1024x768": STANDARD_4x3_DIMS,
- }
-
- if size in SIZE_MAP:
- slide_w, slide_h = SIZE_MAP[size]
- elif size == "CUSTOM":
- cs = canvas.get("customSize", {}) or {}
- slide_w, slide_h = float(cs.get("width", 13.333)), float(cs.get("height", 7.5))
- else:
- logger.warning(f"Unknown canvas size '{size}', defaulting to WIDE_16x9")
- slide_w, slide_h = WIDE_16x9_DIMS
-
- # Set global unit for rect_in conversions (no scaling - use coordinates as-is)
- set_unit(unit)
- logger.info(f"Canvas: {size}, unit: {unit}, slide size: {slide_w}x{slide_h} inches")
-
- # Convert safe margins to inches based on unit
- def to_inches(val, src_unit):
- if src_unit == "pt":
- return val / 72.0
- elif src_unit == "cm":
- return val / 2.54
- return val # already inches
-
- prs.slide_width = Inches(slide_w)
- prs.slide_height = Inches(slide_h)
-
- safe = canvas.get("safeMargins", {"top": 0.5, "right": 0.5, "bottom": 0.5, "left": 0.5})
- safe_ctx = {
- "top": to_inches(safe.get("top", 0.5), unit),
- "right": to_inches(safe.get("right", 0.5), unit),
- "bottom": to_inches(safe.get("bottom", 0.5), unit),
- "left": to_inches(safe.get("left", 0.5), unit),
- }
- safe_ctx["slide_w"] = slide_w
- safe_ctx["slide_h"] = slide_h
- safe_ctx["unit"] = unit
-
- defaults = (theme.get("defaults", {}) or {})
- theme_text_default = defaults.get("textStyle", {}) or {}
-
- masters = {m["id"]: m for m in deck.get("masters", []) if isinstance(m, dict) and "id" in m}
- layouts = {l["id"]: l for l in deck.get("layouts", []) if isinstance(l, dict) and "id" in l}
- components = {c["id"]: c for c in deck.get("components", []) if isinstance(c, dict) and "id" in c}
-
- assets = deck.get("assets", {}) or {}
- images = assets.get("images", []) or []
- assets_by_id = {img["id"]: img for img in images if isinstance(img, dict) and "id" in img}
-
- data = deck.get("data", {}) or {}
- datasets = data.get("datasets", []) or []
- datasets_by_id = {ds["id"]: ds for ds in datasets if isinstance(ds, dict) and "id" in ds}
-
- slides = sorted(deck.get("slides", []), key=lambda s: s.get("order", 0))
-
- # Context for template variable substitution in text elements
- text_ctx = {}
- meta = deck.get("metadata") or {}
- if isinstance(meta, dict):
- for k, v in meta.items():
- if v is not None:
- text_ctx[k] = v
- constraints_text = None
- if isinstance(meta, dict):
- constraints_text = meta.get("constraints")
- if isinstance(constraints_text, str):
- for line in constraints_text.splitlines():
- if ":" in line:
- k, v = line.split(":", 1)
- k = k.strip()
- v = v.strip()
- if k and v and k not in text_ctx:
- text_ctx[k] = v
-
- # Get blank layout safely
- try:
- blank_layout = prs.slide_layouts[6] # blank
- except IndexError:
- logger.warning("Slide layout index 6 not found, using last available layout")
- blank_layout = prs.slide_layouts[-1]
-
- logger.info(f"Rendering {len(slides)} slides at {slide_w}x{slide_h} inches")
-
- for idx, s in enumerate(slides, start=1):
- slide = prs.slides.add_slide(blank_layout)
-
- layout_id = s.get("layoutId")
- layout = layouts.get(layout_id)
- if not layout:
- logger.warning(f"Slide {s.get('id')} references unknown layoutId: {layout_id}. Rendering without master.")
- master = masters.get(layout.get("masterId")) if layout else None
-
- # Background
- bg = s.get("backgroundOverride") or (master.get("background") if master else None) or defaults.get("background")
- if bg and bg.get("type") == "solid" and bg.get("color"):
- fill = slide.background.fill
- fill.solid()
- fill.fore_color.rgb = hex_to_rgb(bg["color"])
-
- all_elements = []
- if master:
- all_elements.extend(master.get("globalElements", []))
- for comp_id in s.get("useComponents", []) or []:
- comp = components.get(comp_id)
- if comp:
- all_elements.extend(comp.get("elements", []))
- all_elements.extend(s.get("elements", []))
-
- resolve_slot_rects(layout, all_elements, theme)
- all_elements = flatten_elements(all_elements)
- all_elements.sort(key=lambda e: e.get("zIndex", 0))
-
- for el in all_elements:
- rect = el.get("rect", {})
- if rect and not safe_contains(rect, safe_ctx):
- logger.warning(f"Element {el.get('id')} on slide {idx} is outside safe margins: {rect}")
- # Continue anyway instead of raising - let user see the output
-
- etype = el.get("type")
- try:
- if etype == "text":
- add_text(slide, el, theme_text_default, idx, len(slides), text_ctx)
- elif etype == "shape":
- add_shape(slide, el)
- elif etype == "table":
- add_table(slide, el, theme_text_default, idx)
- elif etype == "chart":
- add_chart(slide, el, datasets_by_id)
- elif etype == "image":
- add_image(slide, el, assets_by_id)
- else:
- logger.warning(f"Unknown element type '{etype}' on slide {idx}, skipping")
- except Exception as e:
- logger.error(f"Error rendering element {el.get('id')} on slide {idx}: {e}")
- raise
-
- # Small overlap fix for top-of-slide text boxes
- resolve_top_text_overlaps(slide)
-
- notes = s.get("speakerNotes")
- if notes:
- ns = slide.notes_slide
- ns.notes_text_frame.text = notes
-
- # Validate that slides were actually added
- if len(prs.slides) == 0:
- raise ValueError("Cannot save presentation: no slides were added to the presentation")
-
- out_path.parent.mkdir(parents=True, exist_ok=True)
- prs.save(str(out_path))
- logger.info(f"Successfully saved presentation to {out_path}")
-
- # Verify file was actually created
- if not out_path.exists():
- raise IOError(f"Failed to create output file: {out_path}")
-
- file_size = out_path.stat().st_size
- if file_size < 1000:
- raise ValueError(f"Generated PPTX is suspiciously small ({file_size} bytes) - likely corrupt")
-
- logger.info(f"Verified output file: {file_size} bytes")
-
-
-def main():
- # Immediate output to confirm script execution
- print("=== render_deck.py starting ===")
- sys.stdout.flush()
-
- if len(sys.argv) < 3:
- print("Usage: python render_deck.py input.json output.pptx", file=sys.stderr)
- sys.exit(2)
-
- in_path = Path(sys.argv[1])
- out_path = Path(sys.argv[2])
-
- print(f"Input: {in_path}")
- print(f"Output: {out_path}")
- sys.stdout.flush()
-
- if not in_path.exists():
- logger.error(f"Input file not found: {in_path}")
- sys.exit(1)
-
- try:
- deck = json.loads(in_path.read_text(encoding="utf-8"))
- except json.JSONDecodeError as e:
- error_msg = f"Invalid JSON in {in_path}: {e}"
- logger.error(error_msg)
- print(f"ERROR: {error_msg}", file=sys.stderr)
- sys.stderr.flush()
- sys.exit(1)
-
- # Validate deck structure
- if not isinstance(deck, dict):
- error_msg = f"Deck JSON is not an object: {type(deck)}"
- print(f"ERROR: {error_msg}", file=sys.stderr)
- sys.stderr.flush()
- sys.exit(1)
-
- slides = deck.get("slides", [])
- print(f"Deck loaded: {len(slides)} slides, version={deck.get('version', 'unknown')}")
- sys.stdout.flush()
-
- if not slides:
- error_msg = "Deck has no slides array or slides array is empty"
- print(f"ERROR: {error_msg}", file=sys.stderr)
- sys.stderr.flush()
- sys.exit(1)
-
- try:
- render(deck, out_path)
- success_msg = f"SUCCESS: Wrote {out_path} ({out_path.stat().st_size} bytes)"
- print(success_msg)
- sys.stdout.flush() # Ensure output is captured by subprocess
- logger.info(success_msg)
- except Exception as e:
- logger.error(f"Rendering failed: {e}")
- # Print to stderr for visibility in subprocess output
- error_msg = f"ERROR: Rendering failed: {e}"
- print(error_msg, file=sys.stderr)
- sys.stderr.flush() # Ensure error is captured
- import traceback
- traceback.print_exc(file=sys.stderr)
- sys.stderr.flush()
- sys.exit(1)
-
-
-if __name__ == "__main__":
- print(">>> SCRIPT ENTRY: __main__ block starting", file=sys.stderr, flush=True)
- try:
- print(">>> SCRIPT ENTRY: calling main()", file=sys.stderr, flush=True)
- main()
- print(">>> SCRIPT ENTRY: main() completed successfully", file=sys.stderr, flush=True)
- except Exception as e:
- # Catch any uncaught exceptions and print them
- print(f">>> SCRIPT ENTRY: FATAL ERROR in main(): {e}", file=sys.stderr, flush=True)
- import traceback
- traceback.print_exc(file=sys.stderr)
- sys.stderr.flush()
- sys.exit(1)
diff --git a/services/response-api/cmd/server/server.go b/services/response-api/cmd/server/server.go
index b59f174a..740101fa 100644
--- a/services/response-api/cmd/server/server.go
+++ b/services/response-api/cmd/server/server.go
@@ -13,12 +13,11 @@ import (
"jan-server/services/response-api/internal/config"
"jan-server/services/response-api/internal/domain/agent"
- "jan-server/services/response-api/internal/domain/agent/planners"
+ artifactexec "jan-server/services/response-api/internal/domain/agent/planners/artifactexec"
deepresearch "jan-server/services/response-api/internal/domain/agent/planners/deep_research"
docplanner "jan-server/services/response-api/internal/domain/agent/planners/doc"
pdfplanner "jan-server/services/response-api/internal/domain/agent/planners/pdf"
skillexec "jan-server/services/response-api/internal/domain/agent/planners/skill"
- slide_creator "jan-server/services/response-api/internal/domain/agent/planners/slide_creator"
spreadsheetplanner "jan-server/services/response-api/internal/domain/agent/planners/spreadsheet"
"jan-server/services/response-api/internal/domain/artifact"
"jan-server/services/response-api/internal/domain/llm"
@@ -147,12 +146,6 @@ func main() {
log.Warn().Err(err).Msg("failed to register deep research planner")
}
- // Register slide creator planner
- slideCreatorPlanner := slide_creator.NewSlideCreatorPlanner(planService, artifactService)
- if err := agentRegistry.RegisterPlanner(slideCreatorPlanner); err != nil {
- log.Warn().Err(err).Msg("failed to register slide creator planner")
- }
-
docGeneratorPlanner := docplanner.NewPlanner(planService, artifactService)
if err := agentRegistry.RegisterPlanner(docGeneratorPlanner); err != nil {
log.Warn().Err(err).Msg("failed to register doc generator planner")
@@ -186,27 +179,21 @@ func main() {
cfg.SkillMaxFileSize,
cfg.SkillExecutionTimeout,
map[skill.SkillType]bool{
- skill.SkillTypeSlides: cfg.SkillSlidesEnabled,
skill.SkillTypeDocs: cfg.SkillDocsEnabled,
skill.SkillTypePDFs: cfg.SkillPDFsEnabled,
skill.SkillTypeSpreadsheets: cfg.SkillSpreadsheetsEnabled,
},
)
- slideCreatorExecutor := slide_creator.NewSlideCreatorExecutor(mcpClient, codeFixer, artifactService, mediaClient, cfg)
- routingExecutor := planners.NewRoutingExecutor(deepResearchExecutor, slideCreatorExecutor)
- artifactRoutingExecutor := planners.NewRoutingExecutor(slideCreatorExecutor, slideCreatorExecutor)
- if err := agentRegistry.RegisterExecutor(plan.ActionTypeToolCall, routingExecutor); err != nil {
+ genericArtifactExecutor := artifactexec.NewGenericArtifactExecutor(mcpClient, artifactService, mediaClient, cfg)
+ if err := agentRegistry.RegisterExecutor(plan.ActionTypeToolCall, deepResearchExecutor); err != nil {
log.Warn().Err(err).Msg("failed to register tool call executor")
}
- if err := agentRegistry.RegisterExecutor(plan.ActionTypeLLMCall, routingExecutor); err != nil {
+ if err := agentRegistry.RegisterExecutor(plan.ActionTypeLLMCall, deepResearchExecutor); err != nil {
log.Warn().Err(err).Msg("failed to register llm call executor")
}
- if err := agentRegistry.RegisterExecutor(plan.ActionTypeArtifactCreate, artifactRoutingExecutor); err != nil {
+ if err := agentRegistry.RegisterExecutor(plan.ActionTypeArtifactCreate, genericArtifactExecutor); err != nil {
log.Warn().Err(err).Msg("failed to register artifact create executor")
}
- if err := agentRegistry.RegisterExecutor(plan.ActionTypeTransform, slideCreatorExecutor); err != nil {
- log.Warn().Err(err).Msg("failed to register transform executor")
- }
if err := agentRegistry.RegisterExecutor(plan.ActionTypeSkillExecute, skillExecutor); err != nil {
log.Warn().Err(err).Msg("failed to register skill execute executor")
}
diff --git a/services/response-api/cmd/server/wire.go b/services/response-api/cmd/server/wire.go
index aafff1ee..94de451c 100644
--- a/services/response-api/cmd/server/wire.go
+++ b/services/response-api/cmd/server/wire.go
@@ -14,12 +14,11 @@ import (
"jan-server/services/response-api/internal/config"
"jan-server/services/response-api/internal/domain/agent"
- "jan-server/services/response-api/internal/domain/agent/planners"
+ artifactexec "jan-server/services/response-api/internal/domain/agent/planners/artifactexec"
deepresearch "jan-server/services/response-api/internal/domain/agent/planners/deep_research"
docplanner "jan-server/services/response-api/internal/domain/agent/planners/doc"
pdfplanner "jan-server/services/response-api/internal/domain/agent/planners/pdf"
skillexec "jan-server/services/response-api/internal/domain/agent/planners/skill"
- slide_creator "jan-server/services/response-api/internal/domain/agent/planners/slide_creator"
spreadsheetplanner "jan-server/services/response-api/internal/domain/agent/planners/spreadsheet"
"jan-server/services/response-api/internal/domain/artifact"
"jan-server/services/response-api/internal/domain/conversation"
@@ -159,12 +158,6 @@ func newAgentRegistry(planService plan.Service, mcpClient tool.MCPClient, llmPro
_ = err
}
- // Register the slide creator planner
- slideCreatorPlanner := slide_creator.NewSlideCreatorPlanner(planService, artifactService)
- if err := registry.RegisterPlanner(slideCreatorPlanner); err != nil {
- _ = err
- }
-
docGeneratorPlanner := docplanner.NewPlanner(planService, artifactService)
if err := registry.RegisterPlanner(docGeneratorPlanner); err != nil {
_ = err
@@ -198,19 +191,15 @@ func newAgentRegistry(planService plan.Service, mcpClient tool.MCPClient, llmPro
cfg.SkillMaxFileSize,
cfg.SkillExecutionTimeout,
map[skill.SkillType]bool{
- skill.SkillTypeSlides: cfg.SkillSlidesEnabled,
skill.SkillTypeDocs: cfg.SkillDocsEnabled,
skill.SkillTypePDFs: cfg.SkillPDFsEnabled,
skill.SkillTypeSpreadsheets: cfg.SkillSpreadsheetsEnabled,
},
)
- slideCreatorExecutor := slide_creator.NewSlideCreatorExecutor(mcpClient, codeFixer, artifactService, mediaClient, cfg)
- routingExecutor := planners.NewRoutingExecutor(deepResearchExecutor, slideCreatorExecutor)
- artifactRoutingExecutor := planners.NewRoutingExecutor(slideCreatorExecutor, slideCreatorExecutor)
- _ = registry.RegisterExecutor(plan.ActionTypeToolCall, routingExecutor)
- _ = registry.RegisterExecutor(plan.ActionTypeLLMCall, routingExecutor)
- _ = registry.RegisterExecutor(plan.ActionTypeArtifactCreate, artifactRoutingExecutor)
- _ = registry.RegisterExecutor(plan.ActionTypeTransform, slideCreatorExecutor)
+ genericArtifactExecutor := artifactexec.NewGenericArtifactExecutor(mcpClient, artifactService, mediaClient, cfg)
+ _ = registry.RegisterExecutor(plan.ActionTypeToolCall, deepResearchExecutor)
+ _ = registry.RegisterExecutor(plan.ActionTypeLLMCall, deepResearchExecutor)
+ _ = registry.RegisterExecutor(plan.ActionTypeArtifactCreate, genericArtifactExecutor)
_ = registry.RegisterExecutor(plan.ActionTypeSkillExecute, skillExecutor)
return registry
diff --git a/services/response-api/cmd/server/wire_gen.go b/services/response-api/cmd/server/wire_gen.go
index 4f8448cd..6a6f0baf 100644
--- a/services/response-api/cmd/server/wire_gen.go
+++ b/services/response-api/cmd/server/wire_gen.go
@@ -15,11 +15,11 @@ import (
"jan-server/services/response-api/internal/config"
"jan-server/services/response-api/internal/domain/agent"
"jan-server/services/response-api/internal/domain/agent/planners"
+ artifactexec "jan-server/services/response-api/internal/domain/agent/planners/artifactexec"
deepresearch "jan-server/services/response-api/internal/domain/agent/planners/deep_research"
docplanner "jan-server/services/response-api/internal/domain/agent/planners/doc"
pdfplanner "jan-server/services/response-api/internal/domain/agent/planners/pdf"
skillexec "jan-server/services/response-api/internal/domain/agent/planners/skill"
- "jan-server/services/response-api/internal/domain/agent/planners/slide_creator"
spreadsheetplanner "jan-server/services/response-api/internal/domain/agent/planners/spreadsheet"
artifact2 "jan-server/services/response-api/internal/domain/artifact"
conversation2 "jan-server/services/response-api/internal/domain/conversation"
@@ -162,11 +162,6 @@ func newAgentRegistry(planService plan2.Service, mcpClient tool.MCPClient, llmPr
_ = err
}
- slideCreatorPlanner := slide_creator.NewSlideCreatorPlanner(planService, artifactService)
- if err := registry.RegisterPlanner(slideCreatorPlanner); err != nil {
- _ = err
- }
-
docGeneratorPlanner := docplanner.NewPlanner(planService, artifactService)
if err := registry.RegisterPlanner(docGeneratorPlanner); err != nil {
_ = err
@@ -196,15 +191,12 @@ func newAgentRegistry(planService plan2.Service, mcpClient tool.MCPClient, llmPr
cfg.SkillMaxCodeFixRetries,
cfg.SkillMaxFileSize,
cfg.SkillExecutionTimeout,
- map[skill.SkillType]bool{skill.SkillTypeSlides: cfg.SkillSlidesEnabled, skill.SkillTypeDocs: cfg.SkillDocsEnabled, skill.SkillTypePDFs: cfg.SkillPDFsEnabled, skill.SkillTypeSpreadsheets: cfg.SkillSpreadsheetsEnabled},
+ map[skill.SkillType]bool{skill.SkillTypeDocs: cfg.SkillDocsEnabled, skill.SkillTypePDFs: cfg.SkillPDFsEnabled, skill.SkillTypeSpreadsheets: cfg.SkillSpreadsheetsEnabled},
)
- slideCreatorExecutor := slide_creator.NewSlideCreatorExecutor(mcpClient, codeFixer, artifactService, mediaClient, cfg)
- routingExecutor := planners.NewRoutingExecutor(deepResearchExecutor, slideCreatorExecutor)
- artifactRoutingExecutor := planners.NewRoutingExecutor(slideCreatorExecutor, slideCreatorExecutor)
- _ = registry.RegisterExecutor(plan2.ActionTypeToolCall, routingExecutor)
- _ = registry.RegisterExecutor(plan2.ActionTypeLLMCall, routingExecutor)
- _ = registry.RegisterExecutor(plan2.ActionTypeArtifactCreate, artifactRoutingExecutor)
- _ = registry.RegisterExecutor(plan2.ActionTypeTransform, slideCreatorExecutor)
+ genericArtifactExecutor := artifactexec.NewGenericArtifactExecutor(mcpClient, artifactService, mediaClient, cfg)
+ _ = registry.RegisterExecutor(plan2.ActionTypeToolCall, deepResearchExecutor)
+ _ = registry.RegisterExecutor(plan2.ActionTypeLLMCall, deepResearchExecutor)
+ _ = registry.RegisterExecutor(plan2.ActionTypeArtifactCreate, genericArtifactExecutor)
_ = registry.RegisterExecutor(plan2.ActionTypeSkillExecute, skillExecutor)
return registry
diff --git a/services/response-api/internal/config/config.go b/services/response-api/internal/config/config.go
index fa7a5a2d..3e2bca2c 100644
--- a/services/response-api/internal/config/config.go
+++ b/services/response-api/internal/config/config.go
@@ -36,12 +36,10 @@ type Config struct {
AuthJWKSURL string `env:"AUTH_JWKS_URL"`
// External Services
- LLMAPIURL string `env:"RESPONSE_LLM_API_URL" envDefault:"http://localhost:8080"`
- MCPToolsURL string `env:"RESPONSE_MCP_TOOLS_URL" envDefault:"http://localhost:8091"`
- MediaAPIURL string `env:"RESPONSE_MEDIA_API_URL" envDefault:"http://media-api:8285"`
- AIOURL string `env:"AIO_URL" envDefault:""`
- SlideRendererScript string `env:"SLIDE_RENDERER_SCRIPT" envDefault:""`
- SlideRendererEnabled bool `env:"SLIDE_RENDERER_ENABLED" envDefault:"true"`
+ LLMAPIURL string `env:"RESPONSE_LLM_API_URL" envDefault:"http://localhost:8080"`
+ MCPToolsURL string `env:"RESPONSE_MCP_TOOLS_URL" envDefault:"http://localhost:8091"`
+ MediaAPIURL string `env:"RESPONSE_MEDIA_API_URL" envDefault:"http://media-api:8285"`
+ AIOURL string `env:"AIO_URL" envDefault:""`
// Tool Execution
MaxToolDepth int `env:"RESPONSE_MAX_TOOL_DEPTH" envDefault:"50"`
@@ -58,7 +56,6 @@ type Config struct {
SkillMaxFileSize int64 `env:"SKILL_MAX_FILE_SIZE" envDefault:"52428800"` // 50MB
SkillMaxCodeFixRetries int `env:"SKILL_MAX_CODE_FIX_RETRIES" envDefault:"3"`
SkillMaxInstallRetries int `env:"SKILL_MAX_INSTALL_RETRIES" envDefault:"3"`
- SkillSlidesEnabled bool `env:"SKILL_SLIDES_ENABLED" envDefault:"true"`
SkillDocsEnabled bool `env:"SKILL_DOCS_ENABLED" envDefault:"true"`
SkillPDFsEnabled bool `env:"SKILL_PDFS_ENABLED" envDefault:"true"`
SkillSpreadsheetsEnabled bool `env:"SKILL_SPREADSHEETS_ENABLED" envDefault:"true"`
diff --git a/services/response-api/internal/domain/agent/metadata.go b/services/response-api/internal/domain/agent/metadata.go
index 3800c0f7..561eb98e 100644
--- a/services/response-api/internal/domain/agent/metadata.go
+++ b/services/response-api/internal/domain/agent/metadata.go
@@ -8,7 +8,7 @@ import (
// AgentMetadata contains descriptive information about an agent for discovery.
type AgentMetadata struct {
- // Type is the unique identifier for this agent (e.g., "deep_research", "slide_creator")
+ // Type is the unique identifier for this agent (e.g., "deep_research", "doc_generator")
Type string `json:"type"`
// Name is the human-readable name of the agent
@@ -147,12 +147,6 @@ func GetAgentCapabilityRequirements(agentType string) AgentCapabilityRequirement
RequiresBrowser: false,
RequiresCodeExecution: false, // Code execution is optional enhancement
}
- case "slide_creator":
- return AgentCapabilityRequirements{
- RequiresSandbox: true, // Needs sandbox for PPTX export (runs Node.js + pptxgenjs)
- RequiresBrowser: false,
- RequiresCodeExecution: true, // Runs code to generate PPTX
- }
case "doc_generator":
return AgentCapabilityRequirements{
RequiresSandbox: true, // Needs sandbox for DOCX generation
@@ -199,7 +193,6 @@ func GetEnabledAgentTypes(sandboxProvider string) []string {
sandbox := GetSandboxCapabilities(sandboxProvider)
allAgents := []string{
"deep_research",
- "slide_creator",
"doc_generator",
"pdf_generator",
"spreadsheet_generator",
@@ -235,27 +228,6 @@ func DeepResearchMetadata() AgentMetadata {
}
}
-// SlideCreatorMetadata returns metadata for the slide creator agent.
-func SlideCreatorMetadata() AgentMetadata {
- return AgentMetadata{
- Type: "slide_creator",
- Name: "Slide Creator Agent",
- Description: "Builds HTML-based slide decks and exports them to editable PPTX with research-backed content.",
- Keywords: []string{
- "slides", "presentation", "powerpoint", "deck", "pitch",
- "pptx", "html slides", "editable slides",
- },
- Capabilities: []string{
- "research", "outline", "html_slide_generation", "template_selection",
- "pptx_export", "theme_customization",
- },
- OutputFormats: []string{"pptx", "html"},
- EstimatedDuration: "3-15 minutes",
- UseWhen: "User wants an editable PPTX generated from HTML slide layouts with template control",
- Enabled: true,
- }
-}
-
// DocGeneratorMetadata returns metadata for the document generator agent.
func DocGeneratorMetadata() AgentMetadata {
return AgentMetadata{
@@ -350,79 +322,6 @@ func DeepResearchInputSchema() *AgentInputSchema {
}
}
-// SlideCreatorInputSchema returns the input schema for slide creation.
-func SlideCreatorInputSchema() *AgentInputSchema {
- min3 := 3
- max50 := 50
- return &AgentInputSchema{
- Type: "object",
- Properties: map[string]SchemaProperty{
- "prompt": {
- Type: "string",
- Description: "Description of the presentation to create",
- },
- "num_slides": {
- Type: "integer",
- Description: "Target number of slides",
- Default: 10,
- Minimum: &min3,
- Maximum: &max50,
- },
- "theme": {
- Type: "string",
- Description: "Visual theme for the presentation",
- Enum: []string{"modern", "corporate", "minimal", "creative", "dark"},
- Default: "modern",
- },
- "format": {
- Type: "string",
- Description: "Output format for the presentation",
- Enum: []string{"pptx"},
- Default: "pptx",
- },
- "research_depth": {
- Type: "string",
- Description: "How much web research to perform",
- Enum: []string{"minimal", "standard", "deep"},
- Default: "standard",
- },
- "options_count": {
- Type: "integer",
- Description: "Number of variations to generate for user selection",
- Default: 1,
- },
- "template_dir": {
- Type: "string",
- Description: "Override template directory (absolute path for custom templates)",
- },
- "template_catalog": {
- Type: "string",
- Description: "Template catalog JSON path (defaults to embedded catalog)",
- },
- "template_id": {
- Type: "integer",
- Description: "Force a specific template ID",
- },
- "tone": {
- Type: "string",
- Description: "Preferred tone for template selection",
- },
- "body_mode": {
- Type: "string",
- Description: "Slide body rendering mode",
- Enum: []string{"template", "llm"},
- Default: "template",
- },
- "debug": {
- Type: "boolean",
- Description: "Write debug outputs into the HTML bundle",
- Default: false,
- },
- },
- Required: []string{"prompt"},
- }
-}
-
// DocGeneratorInputSchema returns the input schema for document generation.
func DocGeneratorInputSchema() *AgentInputSchema {
return &AgentInputSchema{
@@ -519,39 +418,6 @@ func DeepResearchOutputSchema() *AgentOutputSchema {
}
}
-// SlideCreatorOutputSchema returns the output schema for slide creation.
-func SlideCreatorOutputSchema() *AgentOutputSchema {
- return &AgentOutputSchema{
- Type: "object",
- Properties: map[string]SchemaProperty{
- "pptx_artifact_id": {
- Type: "string",
- Description: "ID of the generated PPTX artifact",
- },
- "html_artifact_id": {
- Type: "string",
- Description: "ID of the generated HTML bundle artifact",
- },
- "images_artifact_id": {
- Type: "string",
- Description: "ID of the slide images artifact (if available)",
- },
- "slides_count": {
- Type: "integer",
- Description: "Number of slides generated",
- },
- "download_url": {
- Type: "string",
- Description: "URL to download the presentation",
- },
- "preview_url": {
- Type: "string",
- Description: "URL to preview the HTML slides",
- },
- },
- }
-}
-
// DocGeneratorOutputSchema returns the output schema for document generation.
func DocGeneratorOutputSchema() *AgentOutputSchema {
return &AgentOutputSchema{
@@ -617,20 +483,6 @@ func DeepResearchExamples() []AgentExample {
}
}
-// SlideCreatorExamples returns usage examples for slide creation.
-func SlideCreatorExamples() []AgentExample {
- return []AgentExample{
- {
- Input: json.RawMessage(`{"prompt": "Create a pitch deck for a SaaS startup", "num_slides": 12, "theme": "modern", "body_mode": "template"}`),
- Description: "Creates a 12-slide PPTX using HTML templates for layout",
- },
- {
- Input: json.RawMessage(`{"prompt": "Make slides about AI safety for executives", "template_id": 12, "tone": "corporate"}`),
- Description: "Uses a specific template pack and tone to guide selection",
- },
- }
-}
-
// DocGeneratorExamples returns usage examples for document generation.
func DocGeneratorExamples() []AgentExample {
return []AgentExample{
@@ -671,13 +523,6 @@ func GetAgentDetail(agentType string) *AgentDetail {
OutputSchema: DeepResearchOutputSchema(),
Examples: DeepResearchExamples(),
}
- case "slide_creator":
- return &AgentDetail{
- AgentMetadata: SlideCreatorMetadata(),
- InputSchema: SlideCreatorInputSchema(),
- OutputSchema: SlideCreatorOutputSchema(),
- Examples: SlideCreatorExamples(),
- }
case "doc_generator":
return &AgentDetail{
AgentMetadata: DocGeneratorMetadata(),
@@ -708,7 +553,6 @@ func GetAgentDetail(agentType string) *AgentDetail {
func GetAllAgentMetadata() []AgentMetadata {
return []AgentMetadata{
DeepResearchMetadata(),
- SlideCreatorMetadata(),
DocGeneratorMetadata(),
PDFGeneratorMetadata(),
SpreadsheetGeneratorMetadata(),
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/artifact_steps.go b/services/response-api/internal/domain/agent/planners/artifactexec/executor.go
similarity index 52%
rename from services/response-api/internal/domain/agent/planners/slide_creator/steps/artifact_steps.go
rename to services/response-api/internal/domain/agent/planners/artifactexec/executor.go
index 8b7f6756..56ac2e76 100644
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/artifact_steps.go
+++ b/services/response-api/internal/domain/agent/planners/artifactexec/executor.go
@@ -1,7 +1,10 @@
-package steps
+// Package artifactexec provides a generic executor for ActionTypeArtifactCreate
+// steps. It stores the output of a preceding step (typically a skill execution)
+// as an artifact via the media service. It is shared by the document, PDF,
+// spreadsheet, and deep-research agents.
+package artifactexec
import (
- "archive/zip"
"context"
"encoding/base64"
"encoding/json"
@@ -9,13 +12,12 @@ import (
"io"
"net/http"
"net/url"
- "os"
- "path/filepath"
- "sort"
"strings"
"time"
+ "jan-server/services/response-api/internal/config"
"jan-server/services/response-api/internal/domain/agent"
+ "jan-server/services/response-api/internal/domain/agent/planners"
"jan-server/services/response-api/internal/domain/agent/planners/skill"
"jan-server/services/response-api/internal/domain/artifact"
"jan-server/services/response-api/internal/domain/plan"
@@ -26,389 +28,82 @@ import (
"github.com/rs/zerolog/log"
)
-func (e *SlideCreatorExecutor) executeArtifactCreation(ctx context.Context, step *plan.Step, input agent.ExecutionInput) (*agent.ExecutionResult, error) {
- var params map[string]interface{}
- if err := json.Unmarshal(input.StepParams, ¶ms); err != nil {
- log.Error().Err(err).Msg("[slide_creator] failed to parse artifact parameters")
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "PARSE_ERROR",
- Message: "failed to parse artifact parameters",
- Severity: status.ErrorSeverityFatal,
- },
- }, nil
- }
-
- action, _ := params["action"].(string)
- config, _ := params["config"].(map[string]interface{})
- retentionPolicy := strings.TrimSpace(stringValue(config, "retention_policy"))
- if retentionPolicy == "" {
- retentionPolicy = "session"
- }
-
- switch action {
- case "store_html_artifact":
- return e.storeHTMLArtifact(ctx, input, retentionPolicy)
- case "store_pptx_artifact":
- return e.storePPTXArtifact(ctx, input, retentionPolicy)
- case "store_slide_images":
- return e.storeSlideImagesArtifact(ctx, input, retentionPolicy)
- case "store_artifact":
- return e.storeGenericArtifact(ctx, input, params, retentionPolicy)
- default:
- return &agent.ExecutionResult{Status: status.StatusCompleted}, nil
- }
+// GenericArtifactExecutor handles ActionTypeArtifactCreate steps by persisting
+// the previous step's output as an artifact.
+type GenericArtifactExecutor struct {
+ mcpClient planners.MCPClient
+ artifactService artifact.Service
+ mediaClient *media.Client
+ aioBaseURL string
}
-func (e *SlideCreatorExecutor) storeHTMLArtifact(ctx context.Context, input agent.ExecutionInput, retentionPolicy string) (*agent.ExecutionResult, error) {
- outDir := extractOutputDir(input)
- if outDir == "" {
- outDir = outputDirForPlan(input)
- }
- files, err := collectHTMLBundleFiles(outDir)
- if err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{Code: "HTML_BUNDLE_ERROR", Message: err.Error(), Severity: status.ErrorSeverityRetryable},
- }, nil
- }
-
- zipPath := filepath.Join(outDir, "slides-html.zip")
- if err := zipFiles(zipPath, files, outDir); err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{Code: "ZIP_ERROR", Message: err.Error(), Severity: status.ErrorSeverityRetryable},
- }, nil
+// NewGenericArtifactExecutor creates a new generic artifact executor.
+func NewGenericArtifactExecutor(mcpClient planners.MCPClient, artifactService artifact.Service, mediaClient *media.Client, cfg *config.Config) *GenericArtifactExecutor {
+ aioBaseURL := ""
+ if cfg != nil {
+ aioBaseURL = strings.TrimSpace(cfg.AIOURL)
}
-
- zipBytes, err := os.ReadFile(zipPath)
- if err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{Code: "ZIP_READ_ERROR", Message: err.Error(), Severity: status.ErrorSeverityRetryable},
- }, nil
+ return &GenericArtifactExecutor{
+ mcpClient: mcpClient,
+ artifactService: artifactService,
+ mediaClient: mediaClient,
+ aioBaseURL: aioBaseURL,
}
-
- return e.uploadFileArtifact(ctx, input, zipBytes, "slides-html.zip", artifact.ContentTypeHTML, "application/zip", "Slide HTML Bundle", retentionPolicy)
}
-func (e *SlideCreatorExecutor) storePPTXArtifact(ctx context.Context, input agent.ExecutionInput, retentionPolicy string) (*agent.ExecutionResult, error) {
- outDir := extractOutputDir(input)
- if outDir == "" {
- outDir = outputDirForPlan(input)
- }
-
- pptxPath := extractPPTXPath(input)
- if pptxPath == "" {
- matches, _ := filepath.Glob(filepath.Join(outDir, "*.pptx"))
- sort.Strings(matches)
- if len(matches) > 0 {
- pptxPath = matches[0]
- }
- }
- if pptxPath == "" {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{Code: "PPTX_MISSING", Message: "pptx file not found in output directory", Severity: status.ErrorSeverityRetryable},
- }, nil
- }
-
- pptxBytes, err := os.ReadFile(pptxPath)
- if err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{Code: "PPTX_READ_ERROR", Message: err.Error(), Severity: status.ErrorSeverityRetryable},
- }, nil
- }
-
- filename := filepath.Base(pptxPath)
- slideImages := e.uploadSlidePreviewImages(ctx, input, collectSlideImages(outDir))
- return e.uploadFileArtifact(ctx, input, pptxBytes, filename, artifact.ContentTypeSlides, artifact.ContentTypeSlides.MimeTypeFor(), "Presentation", retentionPolicy, slideImages...)
+// CanExecute checks if this executor can handle the given action type.
+func (e *GenericArtifactExecutor) CanExecute(action plan.ActionType) bool {
+ return action == plan.ActionTypeArtifactCreate
}
-func (e *SlideCreatorExecutor) storeSlideImagesArtifact(ctx context.Context, input agent.ExecutionInput, retentionPolicy string) (*agent.ExecutionResult, error) {
- outDir := extractOutputDir(input)
- if outDir == "" {
- outDir = outputDirForPlan(input)
- }
-
- images := collectSlideImages(outDir)
- if len(images) == 0 {
- stepOutput := &plan.StepOutput{
- Status: "skipped",
- Type: "artifact_create",
- Content: "no slide images found",
- CreatedAt: time.Now(),
- }
- outputBytes, _ := json.Marshal(stepOutput)
- return &agent.ExecutionResult{Status: status.StatusCompleted, Output: outputBytes}, nil
- }
-
- zipPath := filepath.Join(outDir, "slide-images.zip")
- if err := zipFiles(zipPath, images, outDir); err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{Code: "ZIP_ERROR", Message: err.Error(), Severity: status.ErrorSeverityRetryable},
- }, nil
- }
+// Rollback attempts to undo a step's effects.
+func (e *GenericArtifactExecutor) Rollback(ctx context.Context, step *plan.Step) error {
+ return nil
+}
- zipBytes, err := os.ReadFile(zipPath)
- if err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{Code: "ZIP_READ_ERROR", Message: err.Error(), Severity: status.ErrorSeverityRetryable},
- }, nil
+// Execute runs a single step and returns the result.
+func (e *GenericArtifactExecutor) Execute(ctx context.Context, step *plan.Step, input agent.ExecutionInput) (*agent.ExecutionResult, error) {
+ log.Debug().Str("step_id", step.ID).Str("action", string(step.Action)).Int("sequence", step.Sequence).Msg("[artifact] Execute started")
+ switch step.Action {
+ case plan.ActionTypeArtifactCreate:
+ return e.executeArtifactCreation(ctx, step, input)
+ default:
+ return &agent.ExecutionResult{Status: status.StatusCompleted}, nil
}
-
- return e.uploadFileArtifact(ctx, input, zipBytes, "slide-images.zip", artifact.ContentTypeImage, "application/zip", "Slide Images", retentionPolicy)
}
-func (e *SlideCreatorExecutor) uploadFileArtifact(ctx context.Context, input agent.ExecutionInput, content []byte, filename string, contentType artifact.ContentType, mimeType string, title string, retentionPolicy string, slidesImages ...plan.MediaArtifactImage) (*agent.ExecutionResult, error) {
- if e.mediaClient == nil {
+func (e *GenericArtifactExecutor) executeArtifactCreation(ctx context.Context, step *plan.Step, input agent.ExecutionInput) (*agent.ExecutionResult, error) {
+ var params map[string]interface{}
+ if err := json.Unmarshal(input.StepParams, ¶ms); err != nil {
+ log.Error().Err(err).Msg("[artifact] failed to parse artifact parameters")
return &agent.ExecutionResult{
Status: status.StatusFailed,
Error: &agent.ExecutionError{
- Code: "MEDIA_CLIENT_MISSING",
- Message: "media client not configured",
+ Code: "PARSE_ERROR",
+ Message: "failed to parse artifact parameters",
Severity: status.ErrorSeverityFatal,
},
}, nil
}
- responseID := ""
- conversationID := ""
- userID := ""
- if input.PlanContext != nil {
- responseID = input.PlanContext.ResponseID
- conversationID = input.PlanContext.ConversationID
- userID = input.PlanContext.UserID
- }
-
- mediaArtifact, err := e.mediaClient.UploadArtifact(ctx, &media.UploadRequest{
- Content: content,
- Filename: filename,
- ContentType: mimeType,
- ConversationID: conversationID,
- ResponseID: responseID,
- UserID: userID,
- })
- if err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{Code: "UPLOAD_ERROR", Message: err.Error(), Severity: status.ErrorSeverityRetryable},
- }, nil
- }
-
- createdArtifact, err := e.artifactService.Create(ctx, artifact.CreateParams{
- ResponseID: responseID,
- ContentType: contentType,
- MimeType: &mimeType,
- Title: title,
- StoragePath: &mediaArtifact.DownloadURL,
- SizeBytes: int64(len(content)),
- RetentionPolicy: artifact.RetentionPolicy(retentionPolicy),
- })
- if err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{Code: "ARTIFACT_ERROR", Message: err.Error(), Severity: status.ErrorSeverityRetryable},
- }, nil
- }
-
- downloadURL := mediaArtifact.DownloadURL
- if downloadURL == "" {
- downloadURL = fmt.Sprintf("/responses/v1/artifacts/%s/download", createdArtifact.ID)
- }
-
- stepOutput := &plan.StepOutput{
- Status: "completed",
- Type: "artifact_create",
- CreatedAt: time.Now(),
- Artifact: &plan.MediaArtifact{
- ID: createdArtifact.ID,
- Type: string(contentType),
- Filename: filename,
- DownloadURL: downloadURL,
- Size: int64(len(content)),
- ContentType: mimeType,
- SlidesImages: slidesImages,
- },
- }
- outputBytes, _ := json.Marshal(stepOutput)
-
- return &agent.ExecutionResult{
- Status: status.StatusCompleted,
- Output: outputBytes,
- ArtifactID: &createdArtifact.ID,
- }, nil
-}
-
-func (e *SlideCreatorExecutor) uploadSlidePreviewImages(ctx context.Context, input agent.ExecutionInput, imagePaths []string) []plan.MediaArtifactImage {
- if e.mediaClient == nil || len(imagePaths) == 0 {
- return nil
- }
-
- responseID := ""
- conversationID := ""
- userID := ""
- if input.PlanContext != nil {
- responseID = input.PlanContext.ResponseID
- conversationID = input.PlanContext.ConversationID
- userID = input.PlanContext.UserID
- }
-
- results := make([]plan.MediaArtifactImage, 0, len(imagePaths))
- for _, path := range imagePaths {
- content, err := os.ReadFile(path)
- if err != nil {
- log.Warn().Err(err).Str("path", path).Msg("[slide_creator] failed to read slide preview")
- continue
- }
- filename := filepath.Base(path)
- mediaArtifact, err := e.mediaClient.UploadArtifact(ctx, &media.UploadRequest{
- Content: content,
- Filename: filename,
- ContentType: "",
- ConversationID: conversationID,
- ResponseID: responseID,
- UserID: userID,
- })
- if err != nil {
- log.Warn().Err(err).Str("filename", filename).Msg("[slide_creator] failed to upload slide preview")
- continue
- }
- id := strings.TrimSuffix(filename, filepath.Ext(filename))
- url := mediaArtifact.DownloadURL
- results = append(results, plan.MediaArtifactImage{
- ID: id,
- URL: url,
- Thumb: url,
- })
- }
- return results
-}
-
-func collectHTMLBundleFiles(outDir string) ([]string, error) {
- files := []string{}
-
- index := filepath.Join(outDir, "index.html")
- if fileExistsOnDisk(index) {
- files = append(files, index)
- }
-
- slides, _ := filepath.Glob(filepath.Join(outDir, "slide-*.html"))
- sort.Strings(slides)
- files = append(files, slides...)
-
- for _, name := range []string{"plan.json", "charts.json", "images.json"} {
- path := filepath.Join(outDir, name)
- if fileExistsOnDisk(path) {
- files = append(files, path)
- }
- }
-
- if len(files) == 0 {
- return nil, fmt.Errorf("no HTML outputs found in %s", outDir)
- }
-
- return files, nil
-}
-
-func collectSlideImages(outDir string) []string {
- all := []string{}
- for _, pattern := range []string{"slide-*.png", "slide-*.jpg", "slide-*.jpeg"} {
- matches, _ := filepath.Glob(filepath.Join(outDir, pattern))
- all = append(all, matches...)
- }
- sort.Strings(all)
- return all
-}
-
-func zipFiles(zipPath string, files []string, baseDir string) error {
- if len(files) == 0 {
- return fmt.Errorf("no files to zip")
- }
-
- file, err := os.Create(zipPath)
- if err != nil {
- return err
- }
- defer func() {
- _ = file.Close()
- }()
-
- writer := zip.NewWriter(file)
-
- for _, path := range files {
- info, err := os.Stat(path)
- if err != nil {
- return err
- }
- if info.IsDir() {
- continue
- }
- rel, err := filepath.Rel(baseDir, path)
- if err != nil {
- return err
- }
- header, err := zip.FileInfoHeader(info)
- if err != nil {
- return err
- }
- header.Name = filepath.ToSlash(rel)
- header.Method = zip.Deflate
-
- entry, err := writer.CreateHeader(header)
- if err != nil {
- return err
- }
- src, err := os.Open(path)
- if err != nil {
- return err
- }
- if _, err := io.Copy(entry, src); err != nil {
- _ = src.Close()
- return err
- }
- _ = src.Close()
- }
-
- return writer.Close()
-}
-
-func fileExistsOnDisk(path string) bool {
- info, err := os.Stat(path)
- if err != nil {
- return false
+ action, _ := params["action"].(string)
+ cfg, _ := params["config"].(map[string]interface{})
+ retentionPolicy := strings.TrimSpace(stringValue(cfg, "retention_policy"))
+ if retentionPolicy == "" {
+ retentionPolicy = "session"
}
- return !info.IsDir()
-}
-func extractPPTXPath(input agent.ExecutionInput) string {
- outputs := make([]json.RawMessage, 0, len(input.AccumulatedOutputs)+1)
- outputs = append(outputs, input.AccumulatedOutputs...)
- if len(input.PreviousOutput) > 0 {
- outputs = append(outputs, input.PreviousOutput)
- }
- for i := len(outputs) - 1; i >= 0; i-- {
- var payload map[string]any
- if err := json.Unmarshal(outputs[i], &payload); err != nil {
- continue
- }
- if path, ok := payload["pptx_path"].(string); ok && strings.TrimSpace(path) != "" {
- return path
- }
+ switch action {
+ case "store_artifact":
+ return e.storeGenericArtifact(ctx, input, params, retentionPolicy)
+ default:
+ return &agent.ExecutionResult{Status: status.StatusCompleted}, nil
}
- return ""
}
-func (e *SlideCreatorExecutor) storeGenericArtifact(ctx context.Context, input agent.ExecutionInput, params map[string]interface{}, retentionPolicy string) (*agent.ExecutionResult, error) {
- config, _ := params["config"].(map[string]interface{})
- format, _ := config["format"].(string)
- if format == "" {
- format = "pptx"
- }
+func (e *GenericArtifactExecutor) storeGenericArtifact(ctx context.Context, input agent.ExecutionInput, params map[string]interface{}, retentionPolicy string) (*agent.ExecutionResult, error) {
+ cfg, _ := params["config"].(map[string]interface{})
+ format, _ := cfg["format"].(string)
artifactType, _ := params["artifact_type"].(string)
if input.PreviousOutput != nil {
@@ -459,7 +154,7 @@ func (e *SlideCreatorExecutor) storeGenericArtifact(ctx context.Context, input a
UserID: userID,
})
if err != nil {
- log.Warn().Err(err).Str("response_id", responseID).Msg("[slide_creator] failed to upload artifact to media-api, falling back to inline storage")
+ log.Warn().Err(err).Str("response_id", responseID).Msg("[artifact] failed to upload artifact to media-api, falling back to inline storage")
} else {
storagePath = &mediaArtifact.DownloadURL
downloadURL = mediaArtifact.DownloadURL
@@ -517,12 +212,12 @@ func (e *SlideCreatorExecutor) storeGenericArtifact(ctx context.Context, input a
}, nil
}
-func (e *SlideCreatorExecutor) uploadSkillArtifact(ctx context.Context, input agent.ExecutionInput, skillOutput skill.ExecuteOutput, artifactType string, retentionPolicy string) (*agent.ExecutionResult, error) {
+func (e *GenericArtifactExecutor) uploadSkillArtifact(ctx context.Context, input agent.ExecutionInput, skillOutput skill.ExecuteOutput, artifactType string, retentionPolicy string) (*agent.ExecutionResult, error) {
log.Debug().
Str("artifact_type", artifactType).
Str("filename", skillOutput.FileName).
Str("mime_type", skillOutput.MimeType).
- Msg("[slide_creator] uploadSkillArtifact started")
+ Msg("[artifact] uploadSkillArtifact started")
if e.mediaClient == nil {
return &agent.ExecutionResult{
Status: status.StatusFailed,
@@ -656,7 +351,7 @@ func (e *SlideCreatorExecutor) uploadSkillArtifact(ctx context.Context, input ag
}, nil
}
-func (e *SlideCreatorExecutor) readBinaryFileFromSandbox(ctx context.Context, path string, input agent.ExecutionInput) ([]byte, error) {
+func (e *GenericArtifactExecutor) readBinaryFileFromSandbox(ctx context.Context, path string, input agent.ExecutionInput) ([]byte, error) {
if strings.TrimSpace(e.aioBaseURL) != "" {
if payload, err := downloadAIOFile(ctx, e.aioBaseURL, path); err == nil {
return payload, nil
@@ -794,7 +489,7 @@ func resolveArtifactContentType(artifactType string, format string) artifact.Con
if format == "markdown" {
return artifact.ContentTypeMarkdown
}
- return artifact.ContentTypeSlides
+ return artifact.ContentTypeDocument
}
}
@@ -807,7 +502,7 @@ func resolveArtifactTitle(artifactType string) string {
case "spreadsheet":
return "Spreadsheet"
default:
- return "Presentation"
+ return "Document"
}
}
@@ -826,9 +521,9 @@ func resolveArtifactFilename(artifactType string, format string) string {
return "content.md"
default:
if format == "pdf" {
- return "presentation.pdf"
+ return "document.pdf"
}
- return "presentation.pptx"
+ return "document.md"
}
}
@@ -840,3 +535,13 @@ func firstTextContent(content []tool.MCPContent) string {
}
return ""
}
+
+func stringValue(values map[string]interface{}, key string) string {
+ if values == nil {
+ return ""
+ }
+ if value, ok := values[key].(string); ok {
+ return value
+ }
+ return ""
+}
diff --git a/services/response-api/internal/domain/agent/planners/routing_executor.go b/services/response-api/internal/domain/agent/planners/routing_executor.go
deleted file mode 100644
index 5d42b3b2..00000000
--- a/services/response-api/internal/domain/agent/planners/routing_executor.go
+++ /dev/null
@@ -1,67 +0,0 @@
-package planners
-
-import (
- "context"
-
- "jan-server/services/response-api/internal/domain/agent"
- "jan-server/services/response-api/internal/domain/plan"
- "jan-server/services/response-api/internal/domain/status"
-)
-
-// RoutingExecutor delegates execution based on the plan's agent type.
-type RoutingExecutor struct {
- defaultExecutor agent.Executor
- slideCreatorExecutor agent.Executor
-}
-
-// NewRoutingExecutor creates a new routing executor.
-func NewRoutingExecutor(defaultExecutor agent.Executor, slideCreatorExecutor agent.Executor) *RoutingExecutor {
- return &RoutingExecutor{
- defaultExecutor: defaultExecutor,
- slideCreatorExecutor: slideCreatorExecutor,
- }
-}
-
-// Execute routes execution to the slide executor for slide plans, otherwise uses the default executor.
-func (e *RoutingExecutor) Execute(ctx context.Context, step *plan.Step, input agent.ExecutionInput) (*agent.ExecutionResult, error) {
- if input.PlanContext != nil {
- switch input.PlanContext.AgentType {
- case plan.AgentTypeSlideCreator:
- if e.slideCreatorExecutor != nil {
- return e.slideCreatorExecutor.Execute(ctx, step, input)
- }
- }
- }
- if e.defaultExecutor == nil {
- return &agent.ExecutionResult{Status: status.StatusFailed, Error: &agent.ExecutionError{
- Code: "executor_missing",
- Message: "no default executor configured",
- Severity: status.ErrorSeverityFatal,
- }}, nil
- }
- return e.defaultExecutor.Execute(ctx, step, input)
-}
-
-// CanExecute returns true if either delegate can handle the action type.
-func (e *RoutingExecutor) CanExecute(action plan.ActionType) bool {
- if e.slideCreatorExecutor != nil && e.slideCreatorExecutor.CanExecute(action) {
- return true
- }
- if e.defaultExecutor != nil && e.defaultExecutor.CanExecute(action) {
- return true
- }
- return false
-}
-
-// Rollback delegates rollback based on agent type if possible, otherwise no-op.
-func (e *RoutingExecutor) Rollback(ctx context.Context, step *plan.Step) error {
- if e.slideCreatorExecutor != nil {
- return e.slideCreatorExecutor.Rollback(ctx, step)
- }
- if e.defaultExecutor != nil {
- return e.defaultExecutor.Rollback(ctx, step)
- }
- return nil
-}
-
-var _ agent.Executor = (*RoutingExecutor)(nil)
diff --git a/services/response-api/internal/domain/agent/planners/skill/executor.go b/services/response-api/internal/domain/agent/planners/skill/executor.go
index f1206b2e..c44f0077 100644
--- a/services/response-api/internal/domain/agent/planners/skill/executor.go
+++ b/services/response-api/internal/domain/agent/planners/skill/executor.go
@@ -513,7 +513,7 @@ func (e *Executor) extractContentFromPreviousOutput(output json.RawMessage) inte
}
// findContentInAccumulatedOutputs searches through accumulated outputs from previous tasks
-// to find content suitable for skill execution (e.g., JSON slides data from LLM generation)
+// to find content suitable for skill execution (e.g., JSON structured data from LLM generation)
func (e *Executor) findContentInAccumulatedOutputs(outputs []json.RawMessage, skillType domainskill.SkillType) interface{} {
// Search backwards through accumulated outputs to find the most recent valid content
for i := len(outputs) - 1; i >= 0; i-- {
@@ -586,23 +586,16 @@ func (e *Executor) extractAndValidateContent(content interface{}, skillType doma
// isValidSkillContentValue checks if the already-parsed content is valid for the given skill type.
func (e *Executor) isValidSkillContentValue(content interface{}, skillType domainskill.SkillType) bool {
- // Handle array content (slides are typically an array)
+ // Handle array content
if arr, ok := content.([]interface{}); ok {
if len(arr) > 0 {
- // Check if first element looks like a slide
- if slide, ok := arr[0].(map[string]interface{}); ok {
- if _, hasTitle := slide["slide_title"]; hasTitle {
- return true
- }
- if _, hasContent := slide["content"]; hasContent {
+ // Check if first element looks like a structured item
+ if item, ok := arr[0].(map[string]interface{}); ok {
+ if _, hasContent := item["content"]; hasContent {
return true
}
}
}
- // For slides, an array is valid
- if skillType == domainskill.SkillTypeSlides && len(arr) > 0 {
- return true
- }
}
// Handle map content
@@ -612,14 +605,6 @@ func (e *Executor) isValidSkillContentValue(content interface{}, skillType domai
}
switch skillType {
- case domainskill.SkillTypeSlides:
- // For slides, look for "slides" array or presentation structure
- if _, hasSlides := contentMap["slides"]; hasSlides {
- return true
- }
- if _, hasSlideTitle := contentMap["slide_title"]; hasSlideTitle {
- return true
- }
case domainskill.SkillTypeDocs:
if _, hasSections := contentMap["sections"]; hasSections {
return true
@@ -658,8 +643,6 @@ func (e *Executor) resolveOutputPath(params executeParams) string {
func (e *Executor) getFileExtension(skillType domainskill.SkillType) string {
switch skillType {
- case domainskill.SkillTypeSlides:
- return ".pptx"
case domainskill.SkillTypeDocs:
return ".docx"
case domainskill.SkillTypePDFs:
@@ -679,8 +662,6 @@ func (e *Executor) getFileName(params executeParams) string {
func (e *Executor) getMimeType(skillType domainskill.SkillType) string {
switch skillType {
- case domainskill.SkillTypeSlides:
- return "application/vnd.openxmlformats-officedocument.presentationml.presentation"
case domainskill.SkillTypeDocs:
return "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
case domainskill.SkillTypePDFs:
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/executor_bridge.go b/services/response-api/internal/domain/agent/planners/slide_creator/executor_bridge.go
deleted file mode 100644
index c66b5fd9..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/executor_bridge.go
+++ /dev/null
@@ -1,15 +0,0 @@
-package slide_creator
-
-import (
- "jan-server/services/response-api/internal/config"
- "jan-server/services/response-api/internal/domain/agent/planners"
- steps "jan-server/services/response-api/internal/domain/agent/planners/slide_creator/steps"
- "jan-server/services/response-api/internal/domain/artifact"
- "jan-server/services/response-api/internal/infrastructure/media"
-)
-
-type SlideCreatorExecutor = steps.SlideCreatorExecutor
-
-func NewSlideCreatorExecutor(mcpClient planners.MCPClient, llmProvider planners.LLMProvider, artifactService artifact.Service, mediaClient *media.Client, cfg *config.Config) *steps.SlideCreatorExecutor {
- return steps.NewSlideCreatorExecutor(mcpClient, llmProvider, artifactService, mediaClient, cfg)
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/planner.go b/services/response-api/internal/domain/agent/planners/slide_creator/planner.go
deleted file mode 100644
index f616bce5..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/planner.go
+++ /dev/null
@@ -1,786 +0,0 @@
-// Package slide_creator contains slide creator planner/executor implementations.
-package slide_creator
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "strconv"
- "strings"
-
- "jan-server/services/response-api/internal/domain/agent"
- "jan-server/services/response-api/internal/domain/agent/planners/slide_creator/schemas"
- "jan-server/services/response-api/internal/domain/artifact"
- "jan-server/services/response-api/internal/domain/plan"
-
- "github.com/rs/zerolog/log"
-)
-
-// SlideCreatorPlanner creates execution plans for slide creation tasks (HTML -> PPTX flow).
-type SlideCreatorPlanner struct {
- planService plan.Service
- artifactService artifact.Service
-}
-
-// SlideCreatorConfig holds configuration for slide creation.
-type SlideCreatorConfig struct {
- NumSlides int `json:"num_slides"`
- Theme string `json:"theme"`
- ColorScheme string `json:"color_scheme"`
- Style string `json:"style"`
- Format string `json:"format"` // pptx
- ResearchDepth string `json:"research_depth"` // minimal, standard, deep
- OptionsCount int `json:"options_count"`
- TemplateDir string `json:"template_dir"`
- TemplateCatalog string `json:"template_catalog"`
- TemplateID int `json:"template_id"`
- Tone string `json:"tone"`
- BodyMode string `json:"body_mode"` // template|llm
- Debug bool `json:"debug"`
-}
-
-// DefaultSlideCreatorConfig returns sensible defaults.
-func DefaultSlideCreatorConfig() SlideCreatorConfig {
- return SlideCreatorConfig{
- NumSlides: 5,
- Theme: "modern",
- Format: "pptx",
- ResearchDepth: "standard",
- OptionsCount: 1,
- BodyMode: "template",
- }
-}
-
-// NewSlideCreatorPlanner creates a new slide creator planner.
-func NewSlideCreatorPlanner(planService plan.Service, artifactService artifact.Service) *SlideCreatorPlanner {
- return &SlideCreatorPlanner{
- planService: planService,
- artifactService: artifactService,
- }
-}
-
-// Name returns the planner's unique identifier.
-func (p *SlideCreatorPlanner) Name() string {
- return string(plan.AgentTypeSlideCreator)
-}
-
-// CanHandle determines if this planner can handle the given request.
-func (p *SlideCreatorPlanner) CanHandle(ctx context.Context, request *agent.PlanRequest) bool {
- if request.Metadata == nil {
- return false
- }
- agentType, ok := request.Metadata["agent_type"]
- if !ok {
- return false
- }
- agentTypeStr, ok := agentType.(string)
- if !ok {
- return false
- }
- return agentTypeStr == string(plan.AgentTypeSlideCreator)
-}
-
-// CreatePlan analyzes the request and creates an execution plan for slide creation.
-func (p *SlideCreatorPlanner) CreatePlan(ctx context.Context, request *agent.PlanRequest) (*agent.PlanResult, error) {
- log.Debug().Interface("request", request).Msg("[slide_creator] CreatePlan started")
- config := p.parseConfig(request)
- log.Debug().Interface("config", config).Msg("[slide_creator] parsed config")
- estimatedSteps := p.calculateEstimatedSteps(config)
- log.Debug().Int("estimated_steps", estimatedSteps).Msg("[slide_creator] calculated estimated steps")
-
- createdPlan, err := p.planService.Create(ctx, plan.CreateParams{
- ResponseID: request.ResponseID,
- Model: request.Model,
- AgentType: plan.AgentTypeSlideCreator,
- EstimatedSteps: estimatedSteps,
- Config: &plan.PlanConfig{
- MaxRetries: 5,
- TimeoutPerStep: 300000000000, // 5 minutes in nanoseconds
- EnableFallback: true,
- UserApproval: config.OptionsCount > 1,
- StreamProgress: true,
- ArtifactRetention: "session",
- },
- })
- if err != nil {
- return nil, err
- }
-
- taskSequence := 1
-
- if config.OptionsCount > 1 {
- selectionTask, err := p.planService.CreateTask(ctx, createdPlan.ID, plan.CreateTaskParams{
- Sequence: taskSequence,
- TaskType: plan.TaskTypeValidation,
- Title: "User Selection",
- Description: strPtr("Wait for user to select a presentation option"),
- })
- if err != nil {
- return nil, err
- }
-
- selectionParams, _ := json.Marshal(map[string]interface{}{
- "action": "request_selection",
- "requires_user": true,
- "prompt": "Select a presentation option to continue",
- "options_count": config.OptionsCount,
- "selection_type": "option",
- })
- _, err = p.planService.CreateStep(ctx, selectionTask.ID, plan.CreateStepParams{
- Sequence: 1,
- Action: plan.ActionTypeLLMCall,
- Title: "Request User Selection",
- Description: strPtr("Wait for user to select a presentation option"),
- InputParams: selectionParams,
- MaxRetries: 3,
- })
- if err != nil {
- return nil, err
- }
-
- taskSequence++
- }
-
- if config.ResearchDepth != "minimal" {
- log.Debug().Str("research_depth", config.ResearchDepth).Msg("[slide_creator] creating research task")
- researchTask, err := p.planService.CreateTask(ctx, createdPlan.ID, plan.CreateTaskParams{
- Sequence: taskSequence,
- TaskType: plan.TaskTypeResearch,
- Title: "Research",
- Description: strPtr("Collect background and supporting facts for the presentation"),
- })
- if err != nil {
- return nil, err
- }
- log.Debug().Str("task_id", researchTask.ID).Msg("[slide_creator] research task created")
-
- searchParams1, _ := json.Marshal(map[string]interface{}{
- "tool": "google_search",
- "description": "Find key ideas for the topic",
- "q": request.UserMessage,
- })
- _, err = p.planService.CreateStep(ctx, researchTask.ID, plan.CreateStepParams{
- Sequence: 1,
- Action: plan.ActionTypeToolCall,
- Title: "Topic Research",
- Description: strPtr("Find key ideas for the topic"),
- InputParams: searchParams1,
- MaxRetries: 3,
- })
- if err != nil {
- return nil, err
- }
-
- if config.ResearchDepth == "deep" {
- searchParams2, _ := json.Marshal(map[string]interface{}{
- "tool": "google_search",
- "description": "Find supporting data and examples",
- "q": request.UserMessage + " examples data statistics",
- })
- _, err = p.planService.CreateStep(ctx, researchTask.ID, plan.CreateStepParams{
- Sequence: 2,
- Action: plan.ActionTypeToolCall,
- Title: "Supporting Research",
- Description: strPtr("Find supporting data and examples"),
- InputParams: searchParams2,
- MaxRetries: 3,
- })
- if err != nil {
- return nil, err
- }
-
- scrapeParams, _ := json.Marshal(map[string]interface{}{
- "tool": "scrape",
- "description": "Capture key details from top sources",
- })
- _, err = p.planService.CreateStep(ctx, researchTask.ID, plan.CreateStepParams{
- Sequence: 3,
- Action: plan.ActionTypeToolCall,
- Title: "Capture Source Details",
- Description: strPtr("Capture key details from top sources"),
- InputParams: scrapeParams,
- MaxRetries: 3,
- })
- if err != nil {
- return nil, err
- }
- }
-
- taskSequence++
- }
-
- log.Debug().Int("task_sequence", taskSequence).Msg("[slide_creator] creating outline task")
- outlineTask, err := p.planService.CreateTask(ctx, createdPlan.ID, plan.CreateTaskParams{
- Sequence: taskSequence,
- TaskType: plan.TaskTypeValidation,
- Title: "Outline & Structure",
- Description: strPtr("Define the storyline and slide flow"),
- })
- if err != nil {
- return nil, err
- }
- log.Debug().Str("task_id", outlineTask.ID).Msg("[slide_creator] outline task created")
-
- outlineParams, _ := json.Marshal(map[string]interface{}{
- "action": "reasoning",
- "description": "Draft the slide outline and flow",
- "brief": request.UserMessage,
- "config": map[string]interface{}{
- "num_slides": config.NumSlides,
- "theme": config.Theme,
- },
- })
- _, err = p.planService.CreateStep(ctx, outlineTask.ID, plan.CreateStepParams{
- Sequence: 1,
- Action: plan.ActionTypeLLMCall,
- Title: "Draft Outline",
- Description: strPtr("Draft the slide outline and flow"),
- InputParams: outlineParams,
- MaxRetries: 5,
- })
- if err != nil {
- return nil, err
- }
-
- taskSequence++
-
- log.Debug().Int("task_sequence", taskSequence).Msg("[slide_creator] creating data bank task")
- dataBankTask, err := p.planService.CreateTask(ctx, createdPlan.ID, plan.CreateTaskParams{
- Sequence: taskSequence,
- TaskType: plan.TaskTypeGeneration,
- Title: "Key Facts",
- Description: strPtr("Extract facts, figures, and data for the presentation"),
- })
- if err != nil {
- return nil, err
- }
- log.Debug().Str("task_id", dataBankTask.ID).Msg("[slide_creator] data bank task created")
-
- dataBankParams, _ := json.Marshal(map[string]interface{}{
- "action": "data_bank",
- "description": "Extract facts, figures, and datasets",
- "brief": request.UserMessage,
- "schema": schemas.DataBankSchema,
- "config": map[string]interface{}{
- "num_slides": config.NumSlides,
- },
- })
- _, err = p.planService.CreateStep(ctx, dataBankTask.ID, plan.CreateStepParams{
- Sequence: 1,
- Action: plan.ActionTypeLLMCall,
- Title: "Extract Key Facts",
- Description: strPtr("Extract facts, figures, and datasets"),
- InputParams: dataBankParams,
- MaxRetries: 3,
- })
- if err != nil {
- return nil, err
- }
-
- taskSequence++
-
- log.Debug().Int("task_sequence", taskSequence).Msg("[slide_creator] creating slide drafting task")
- htmlTask, err := p.planService.CreateTask(ctx, createdPlan.ID, plan.CreateTaskParams{
- Sequence: taskSequence,
- TaskType: plan.TaskTypeGeneration,
- Title: "Slide Drafting",
- Description: strPtr("Select a style, plan slides, and prepare drafts"),
- })
- if err != nil {
- return nil, err
- }
-
- stepSequence := 1
- selectTemplateParams, _ := json.Marshal(map[string]interface{}{
- "action": "select_templates",
- "description": "Select a slide style and layout set",
- "brief": request.UserMessage,
- "config": map[string]interface{}{
- "template_dir": config.TemplateDir,
- "template_catalog": config.TemplateCatalog,
- "template_id": config.TemplateID,
- "tone": config.Tone,
- "color_scheme": config.ColorScheme,
- "style": config.Style,
- },
- })
- _, err = p.planService.CreateStep(ctx, htmlTask.ID, plan.CreateStepParams{
- Sequence: stepSequence,
- Action: plan.ActionTypeLLMCall,
- Title: "Select Slide Style",
- Description: strPtr("Select a slide style and layout set"),
- InputParams: selectTemplateParams,
- MaxRetries: 3,
- })
- if err != nil {
- return nil, err
- }
- stepSequence++
-
- themeParams, _ := json.Marshal(map[string]interface{}{
- "action": "deck_theme",
- "description": "Select deck title and theme colors",
- "brief": request.UserMessage,
- "config": map[string]interface{}{
- "theme": config.Theme,
- "color_scheme": config.ColorScheme,
- "style": config.Style,
- },
- })
- _, err = p.planService.CreateStep(ctx, htmlTask.ID, plan.CreateStepParams{
- Sequence: stepSequence,
- Action: plan.ActionTypeLLMCall,
- Title: "Select Deck Theme",
- Description: strPtr("Select deck title and theme colors"),
- InputParams: themeParams,
- MaxRetries: 3,
- })
- if err != nil {
- return nil, err
- }
- stepSequence++
-
- for i := 1; i <= config.NumSlides; i++ {
- planParams, _ := json.Marshal(map[string]interface{}{
- "action": "slide_plan_slide",
- "description": fmt.Sprintf("Draft slide plan for slide %d", i),
- "brief": request.UserMessage,
- "slide_index": i,
- "max_retries": 3,
- "config": map[string]interface{}{
- "num_slides": config.NumSlides,
- "theme": config.Theme,
- "color_scheme": config.ColorScheme,
- "style": config.Style,
- },
- })
- _, err = p.planService.CreateStep(ctx, htmlTask.ID, plan.CreateStepParams{
- Sequence: stepSequence,
- Action: plan.ActionTypeLLMCall,
- Title: fmt.Sprintf("Draft Slide Plan for Slide %d", i),
- Description: strPtr(fmt.Sprintf("Draft slide plan for slide %d", i)),
- InputParams: planParams,
- MaxRetries: 3,
- })
- if err != nil {
- return nil, err
- }
- stepSequence++
-
- stepTitle := fmt.Sprintf("Find Images for Slide %d", i)
- stepDescription := fmt.Sprintf("Find images for slide %d", i)
- perSlideNum := 6
- if config.NumSlides == 1 {
- perSlideNum = 4
- }
- imageParams, _ := json.Marshal(map[string]interface{}{
- "action": "image_search_slide",
- "description": stepDescription,
- "slide_index": i,
- "num": perSlideNum,
- "color_scheme": config.ColorScheme,
- "style": config.Style,
- })
- _, err = p.planService.CreateStep(ctx, htmlTask.ID, plan.CreateStepParams{
- Sequence: stepSequence,
- Action: plan.ActionTypeToolCall,
- Title: stepTitle,
- Description: strPtr(stepDescription),
- InputParams: imageParams,
- MaxRetries: 2,
- })
- if err != nil {
- return nil, err
- }
- stepSequence++
- }
-
- mergeParams, _ := json.Marshal(map[string]interface{}{
- "action": "merge_slide_plans",
- "description": "Combine per-slide plans into a single deck plan",
- "brief": request.UserMessage,
- "config": map[string]interface{}{
- "num_slides": config.NumSlides,
- },
- })
- _, err = p.planService.CreateStep(ctx, htmlTask.ID, plan.CreateStepParams{
- Sequence: stepSequence,
- Action: plan.ActionTypeTransform,
- Title: "Merge Slide Plans",
- Description: strPtr("Combine per-slide plans into a single deck plan"),
- InputParams: mergeParams,
- MaxRetries: 2,
- })
- if err != nil {
- return nil, err
- }
- stepSequence++
-
- normalizeParams, _ := json.Marshal(map[string]interface{}{
- "action": "normalize_plan",
- "description": "Refine the plan for layout consistency",
- "config": map[string]interface{}{
- "num_slides": config.NumSlides,
- },
- })
- _, err = p.planService.CreateStep(ctx, htmlTask.ID, plan.CreateStepParams{
- Sequence: stepSequence,
- Action: plan.ActionTypeTransform,
- Title: "Refine Slide Plan",
- Description: strPtr("Refine the plan for layout consistency"),
- InputParams: normalizeParams,
- MaxRetries: 2,
- })
- if err != nil {
- return nil, err
- }
- stepSequence++
-
- renderParams, _ := json.Marshal(map[string]interface{}{
- "action": "render_slides",
- "description": "Compose slide drafts from the plan",
- "config": map[string]interface{}{
- "body_mode": config.BodyMode,
- },
- })
- _, err = p.planService.CreateStep(ctx, htmlTask.ID, plan.CreateStepParams{
- Sequence: stepSequence,
- Action: plan.ActionTypeTransform,
- Title: "Compose Slides",
- Description: strPtr("Compose slide drafts from the plan"),
- InputParams: renderParams,
- MaxRetries: 2,
- })
- if err != nil {
- return nil, err
- }
- stepSequence++
-
- writeParams, _ := json.Marshal(map[string]interface{}{
- "action": "write_outputs",
- "description": "Save slide drafts and supporting files",
- "config": map[string]interface{}{
- "debug": config.Debug,
- },
- })
- _, err = p.planService.CreateStep(ctx, htmlTask.ID, plan.CreateStepParams{
- Sequence: stepSequence,
- Action: plan.ActionTypeTransform,
- Title: "Save Draft Files",
- Description: strPtr("Save slide drafts and supporting files"),
- InputParams: writeParams,
- MaxRetries: 2,
- })
- if err != nil {
- return nil, err
- }
- stepSequence++
-
- artifactParams, _ := json.Marshal(map[string]interface{}{
- "action": "store_html_artifact",
- "description": "Save the slide draft package",
- "artifact_type": "slides_html",
- "config": map[string]interface{}{
- "retention_policy": "session",
- },
- })
- _, err = p.planService.CreateStep(ctx, htmlTask.ID, plan.CreateStepParams{
- Sequence: stepSequence,
- Action: plan.ActionTypeArtifactCreate,
- Title: "Save Draft Package",
- Description: strPtr("Save the slide draft package"),
- InputParams: artifactParams,
- MaxRetries: 2,
- })
- if err != nil {
- return nil, err
- }
-
- taskSequence++
-
- exportTask, err := p.planService.CreateTask(ctx, createdPlan.ID, plan.CreateTaskParams{
- Sequence: taskSequence,
- TaskType: plan.TaskTypeFinalization,
- Title: "Export Presentation",
- Description: strPtr("Export and save the final presentation"),
- })
- if err != nil {
- return nil, err
- }
-
- exportParams, _ := json.Marshal(map[string]interface{}{
- "action": "export_pptx_dom",
- "description": "Export the final presentation file",
- "mode": "dom",
- })
- _, err = p.planService.CreateStep(ctx, exportTask.ID, plan.CreateStepParams{
- Sequence: 1,
- Action: plan.ActionTypeToolCall,
- Title: "Export Presentation",
- Description: strPtr("Export the final presentation file"),
- InputParams: exportParams,
- MaxRetries: 2,
- })
- if err != nil {
- return nil, err
- }
-
- pptxArtifactParams, _ := json.Marshal(map[string]interface{}{
- "action": "store_pptx_artifact",
- "description": "Save the presentation for download",
- "artifact_type": "slides",
- "config": map[string]interface{}{
- "format": config.Format,
- "retention_policy": "session",
- },
- })
- _, err = p.planService.CreateStep(ctx, exportTask.ID, plan.CreateStepParams{
- Sequence: 2,
- Action: plan.ActionTypeArtifactCreate,
- Title: "Save Presentation",
- Description: strPtr("Save the presentation for download"),
- InputParams: pptxArtifactParams,
- MaxRetries: 2,
- })
- if err != nil {
- return nil, err
- }
-
- imageArtifactParams, _ := json.Marshal(map[string]interface{}{
- "action": "store_slide_images",
- "description": "Save slide preview images",
- "artifact_type": "slide_images",
- "config": map[string]interface{}{
- "retention_policy": "session",
- },
- })
- _, err = p.planService.CreateStep(ctx, exportTask.ID, plan.CreateStepParams{
- Sequence: 3,
- Action: plan.ActionTypeArtifactCreate,
- Title: "Save Slide Previews",
- Description: strPtr("Save slide preview images"),
- InputParams: imageArtifactParams,
- MaxRetries: 1,
- })
- if err != nil {
- return nil, err
- }
-
- planWithDetails, err := p.planService.GetPlanWithDetails(ctx, createdPlan.ID)
- if err != nil {
- return nil, err
- }
-
- result := &agent.PlanResult{
- Plan: planWithDetails,
- Tasks: make([]*plan.Task, len(planWithDetails.Tasks)),
- RequiresApproval: config.OptionsCount > 1,
- }
-
- for i := range planWithDetails.Tasks {
- result.Tasks[i] = &planWithDetails.Tasks[i]
- }
-
- log.Info().
- Str("plan_id", createdPlan.ID).
- Str("response_id", request.ResponseID).
- Int("num_slides", config.NumSlides).
- Str("theme", config.Theme).
- Str("color_scheme", config.ColorScheme).
- Str("style", config.Style).
- Str("format", config.Format).
- Str("research_depth", config.ResearchDepth).
- Int("estimated_steps", estimatedSteps).
- Msg("created slide creator plan")
-
- return result, nil
-}
-
-// parseConfig extracts slide configuration from the request metadata.
-func (p *SlideCreatorPlanner) parseConfig(request *agent.PlanRequest) SlideCreatorConfig {
- config := DefaultSlideCreatorConfig()
-
- if request.Metadata == nil {
- return config
- }
-
- applySlideCreatorConfigFromMap(&config, request.Metadata)
-
- if options, ok := request.Metadata["options"].(map[string]interface{}); ok {
- applySlideCreatorConfigFromMap(&config, options)
- }
-
- if config.NumSlides < 1 {
- config.NumSlides = 1
- }
- if config.NumSlides > 50 {
- config.NumSlides = 50
- }
- if config.OptionsCount < 1 {
- config.OptionsCount = 1
- }
- if config.OptionsCount > 5 {
- config.OptionsCount = 5
- }
- if strings.TrimSpace(config.BodyMode) == "" {
- config.BodyMode = "template"
- }
-
- log.Debug().
- Int("num_slides", config.NumSlides).
- Str("theme", config.Theme).
- Str("color_scheme", config.ColorScheme).
- Str("style", config.Style).
- Str("format", config.Format).
- Str("research_depth", config.ResearchDepth).
- Int("options_count", config.OptionsCount).
- Str("template_dir", config.TemplateDir).
- Int("template_id", config.TemplateID).
- Str("template_catalog", config.TemplateCatalog).
- Str("tone", config.Tone).
- Str("body_mode", config.BodyMode).
- Bool("debug", config.Debug).
- Msg("[slide_creator] parsed plan config")
-
- return config
-}
-
-func applySlideCreatorConfigFromMap(config *SlideCreatorConfig, values map[string]interface{}) {
- if values == nil {
- return
- }
- if numSlides, ok := parseIntFromInterface(values["num_slides"]); ok {
- config.NumSlides = numSlides
- }
- if theme, ok := values["theme"].(string); ok {
- config.Theme = theme
- }
- if colorScheme, ok := values["color_scheme"].(string); ok {
- config.ColorScheme = colorScheme
- }
- if style, ok := values["style"].(string); ok {
- config.Style = style
- }
- if format, ok := values["format"].(string); ok {
- config.Format = format
- }
- if researchDepth, ok := values["research_depth"].(string); ok {
- config.ResearchDepth = researchDepth
- }
- if optionsCount, ok := parseIntFromInterface(values["options_count"]); ok {
- config.OptionsCount = optionsCount
- }
- if templateDir, ok := values["template_dir"].(string); ok {
- config.TemplateDir = templateDir
- }
- if templateCatalog, ok := values["template_catalog"].(string); ok {
- config.TemplateCatalog = templateCatalog
- }
- if templateID, ok := parseIntFromInterface(values["template_id"]); ok {
- config.TemplateID = templateID
- }
- if tone, ok := values["tone"].(string); ok {
- config.Tone = tone
- }
- if bodyMode, ok := values["body_mode"].(string); ok {
- config.BodyMode = bodyMode
- }
- if debug, ok := parseBoolFromInterface(values["debug"]); ok {
- config.Debug = debug
- }
-}
-
-func parseIntFromInterface(value interface{}) (int, bool) {
- switch v := value.(type) {
- case int:
- return v, true
- case int8:
- return int(v), true
- case int16:
- return int(v), true
- case int32:
- return int(v), true
- case int64:
- return int(v), true
- case uint:
- return int(v), true
- case uint8:
- return int(v), true
- case uint16:
- return int(v), true
- case uint32:
- return int(v), true
- case uint64:
- return int(v), true
- case float32:
- return int(v), true
- case float64:
- return int(v), true
- case json.Number:
- if n, err := v.Int64(); err == nil {
- return int(n), true
- }
- case string:
- if n, err := strconv.Atoi(strings.TrimSpace(v)); err == nil {
- return n, true
- }
- }
- return 0, false
-}
-
-func parseBoolFromInterface(value interface{}) (bool, bool) {
- switch v := value.(type) {
- case bool:
- return v, true
- case string:
- switch strings.ToLower(strings.TrimSpace(v)) {
- case "true", "1", "yes", "y":
- return true, true
- case "false", "0", "no", "n":
- return false, true
- }
- case float64:
- return v != 0, true
- case int:
- return v != 0, true
- }
- return false, false
-}
-
-// calculateEstimatedSteps returns the expected number of steps based on configuration.
-func (p *SlideCreatorPlanner) calculateEstimatedSteps(config SlideCreatorConfig) int {
- steps := 0
-
- if config.OptionsCount > 1 {
- steps++
- }
-
- switch config.ResearchDepth {
- case "minimal":
- steps += 0
- case "standard":
- steps += 1
- case "deep":
- steps += 3
- }
-
- steps += 1 // outline
- steps += 1 // data bank
- steps += 7 + (config.NumSlides * 2) // html generation: template + theme + per-slide plan + per-slide search + merge + normalize + render + write + artifact
- steps += 3 // pptx export + artifacts
-
- log.Debug().
- Int("num_slides", config.NumSlides).
- Str("research_depth", config.ResearchDepth).
- Int("estimated_steps", steps).
- Msg("[slide_creator] estimated steps calculated")
-
- return steps
-}
-
-// Verify interface compliance at compile time
-var _ agent.Planner = (*SlideCreatorPlanner)(nil)
-
-func strPtr(s string) *string {
- return &s
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/schemas/data_bank_schema.go b/services/response-api/internal/domain/agent/planners/slide_creator/schemas/data_bank_schema.go
deleted file mode 100644
index 90377032..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/schemas/data_bank_schema.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package schemas
-
-// DataBankSchema is the JSON schema for extracted facts and datasets.
-var DataBankSchema = map[string]any{
- "type": "object",
- "properties": map[string]any{
- "facts": map[string]any{
- "type": "array",
- "description": "Atomic facts with sources",
- "items": map[string]any{
- "type": "object",
- "properties": map[string]any{
- "claim": map[string]any{"type": "string"},
- "value": map[string]any{"type": "string"},
- "unit": map[string]any{"type": "string"},
- "sourceUrl": map[string]any{"type": "string"},
- "date": map[string]any{"type": "string"},
- },
- "required": []string{"claim", "value", "unit", "sourceUrl", "date"},
- "additionalProperties": false,
- },
- },
- "datasets": map[string]any{
- "type": "array",
- "description": "Ready-to-use datasets for charts/tables",
- "items": map[string]any{
- "type": "object",
- "properties": map[string]any{
- "id": map[string]any{"type": "string"},
- "kind": map[string]any{"type": "string", "enum": []string{"series"}},
- "data": map[string]any{
- "type": "object",
- "properties": map[string]any{
- "labels": map[string]any{"type": "array", "items": map[string]any{"type": "string"}},
- "series": map[string]any{
- "type": "array",
- "items": map[string]any{
- "type": "object",
- "properties": map[string]any{
- "name": map[string]any{"type": "string"},
- "values": map[string]any{"type": "array", "items": map[string]any{"type": "number"}},
- },
- "required": []string{"name", "values"},
- "additionalProperties": false,
- },
- },
- },
- "required": []string{"labels", "series"},
- "additionalProperties": false,
- },
- "sourceNote": map[string]any{"type": "string"},
- },
- "required": []string{"id", "kind", "data", "sourceNote"},
- "additionalProperties": false,
- },
- },
- },
- "required": []string{"facts", "datasets"},
- "additionalProperties": false,
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/schemas/types.go b/services/response-api/internal/domain/agent/planners/slide_creator/schemas/types.go
deleted file mode 100644
index a0aaf84a..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/schemas/types.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package schemas
-
-// DataBank contains extracted facts and datasets.
-type DataBank struct {
- Facts []Fact `json:"facts"`
- Datasets []Dataset `json:"datasets"`
-}
-
-// Fact is a single sourced claim.
-type Fact struct {
- Claim string `json:"claim"`
- Value string `json:"value"`
- Unit string `json:"unit"`
- SourceURL string `json:"sourceUrl"`
- Date string `json:"date"`
-}
-
-// Dataset is a chart-ready dataset.
-type Dataset struct {
- ID string `json:"id"`
- Kind string `json:"kind"`
- Data DatasetData `json:"data"`
- SourceNote string `json:"sourceNote"`
-}
-
-// DatasetData holds labels and series values.
-type DatasetData struct {
- Labels []string `json:"labels"`
- Series []DatasetSeries `json:"series"`
-}
-
-// DatasetSeries is one series in a dataset.
-type DatasetSeries struct {
- Name string `json:"name"`
- Values []float64 `json:"values"`
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/aio_export.go b/services/response-api/internal/domain/agent/planners/slide_creator/steps/aio_export.go
deleted file mode 100644
index 456765ca..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/aio_export.go
+++ /dev/null
@@ -1,1012 +0,0 @@
-package steps
-
-import (
- "bytes"
- "context"
- "encoding/base64"
- "encoding/json"
- "errors"
- "fmt"
- "io"
- "net"
- "net/http"
- "net/url"
- "os"
- "path/filepath"
- "sort"
- "strings"
- "time"
-
- slidecreatorassets "jan-server/services/response-api/assets/slide_creator"
- "jan-server/services/response-api/internal/domain/agent"
- "jan-server/services/response-api/internal/domain/status"
-
- "github.com/rs/zerolog/log"
-)
-
-type nodeJSExecuteRequest struct {
- Code string `json:"code"`
- Timeout *int `json:"timeout,omitempty"`
- Stdin *string `json:"stdin,omitempty"`
- Files map[string]string `json:"files,omitempty"`
-}
-
-type nodeJSExecuteResponse struct {
- Data *struct {
- Status *string `json:"status"`
- Stdout *string `json:"stdout"`
- Stderr *string `json:"stderr"`
- ExitCode *int `json:"exit_code"`
- } `json:"data"`
-}
-
-type filePayload struct {
- Path string `json:"path"`
- B64 string `json:"b64"`
-}
-
-type fileListRequest struct {
- Path string `json:"path"`
- Recursive *bool `json:"recursive,omitempty"`
- ShowHidden *bool `json:"show_hidden,omitempty"`
- FileTypes []string `json:"file_types,omitempty"`
-}
-
-type fileInfo struct {
- Name string `json:"name"`
- Path string `json:"path"`
- IsDirectory bool `json:"is_directory"`
- Extension string `json:"extension"`
-}
-
-type fileListResult struct {
- Path string `json:"path"`
- Files []fileInfo `json:"files"`
-}
-
-type responseWrapper[T any] struct {
- Success bool `json:"success"`
- Message *string `json:"message"`
- Data *T `json:"data"`
-}
-
-// Shell execution types for AIO API
-type shellExecRequest struct {
- ID *string `json:"id,omitempty"`
- ExecDir *string `json:"exec_dir,omitempty"`
- Command string `json:"command"`
- AsyncMode bool `json:"async_mode"`
- Timeout *float64 `json:"timeout,omitempty"`
-}
-
-type shellCommandResult struct {
- SessionID string `json:"session_id"`
- Command string `json:"command"`
- Status string `json:"status"`
- Output *string `json:"output"`
- ExitCode *int `json:"exit_code"`
-}
-
-type shellExecResponse struct {
- Success bool `json:"success"`
- Message *string `json:"message"`
- Data *shellCommandResult `json:"data"`
-}
-
-// ensurePlaywrightBrowsers installs Playwright browsers via AIO shell API
-// Key fixes: cleans up incomplete installations, copies chrome to headless shell path if missing
-func ensurePlaywrightBrowsers(ctx context.Context, baseURL, cacheDir string) error {
- browsersDir := cacheDir + "/pw_browsers"
- nodeEnvDir := cacheDir + "/node_env"
-
- // Commands to run (using sudo for system deps)
- commands := []struct {
- name string
- cmd string
- timeout float64
- }{
- {
- name: "Create cache directories",
- cmd: fmt.Sprintf("mkdir -p %s %s %s/outputs && chmod -R 777 %s 2>/dev/null || true", nodeEnvDir, browsersDir, cacheDir, cacheDir),
- timeout: 30,
- },
- {
- name: "Initialize npm package",
- cmd: fmt.Sprintf("cd %s && [ -f package.json ] || npm init -y 2>/dev/null", nodeEnvDir),
- timeout: 30,
- },
- {
- name: "Install npm packages",
- cmd: fmt.Sprintf("cd %s && PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm install --no-fund --no-audit playwright pptxgenjs 2>&1", nodeEnvDir),
- timeout: 180,
- },
- {
- name: "Install Playwright system dependencies",
- cmd: fmt.Sprintf("cd %s && sudo npx playwright install-deps 2>&1 || true", nodeEnvDir),
- timeout: 180,
- },
- {
- name: "Clean up incomplete browser installations",
- cmd: fmt.Sprintf(`cd %s && for d in chromium_headless_shell-*; do if [ -d "$d" ]; then exe="$d/chrome-headless-shell-linux64/chrome-headless-shell"; if [ ! -f "$exe" ]; then echo "Removing incomplete: $d"; rm -rf "$d"; fi; fi; done 2>/dev/null; echo "Cleanup done"`, browsersDir),
- timeout: 30,
- },
- {
- name: "Install Playwright browsers",
- cmd: fmt.Sprintf(`cd %s && echo "Playwright version:" && npx playwright --version 2>&1 && echo "Installing browsers..." && PLAYWRIGHT_BROWSERS_PATH=%s npx playwright install chromium 2>&1`, nodeEnvDir, browsersDir),
- timeout: 300,
- },
- {
- name: "Check and fix headless shell",
- cmd: fmt.Sprintf(`cd %s && echo "=== Current browser structure ===" && ls -la 2>&1 && EXPECTED="%s/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell" && if [ -f "$EXPECTED" ]; then echo "Headless shell exists at $EXPECTED"; else echo "Headless shell MISSING at $EXPECTED" && echo "Checking directory structure:" && ls -laR chromium_headless_shell-* 2>&1 | head -30 && CHROME="%s/chromium-1200/chrome-linux64/chrome" && if [ -f "$CHROME" ]; then echo "Chrome found, creating headless shell structure..." && mkdir -p chromium_headless_shell-1200/chrome-headless-shell-linux64 && cp "$CHROME" "$EXPECTED" 2>&1 && chmod +x "$EXPECTED" 2>&1 && echo "Copied chrome to $EXPECTED"; else echo "Chrome also missing at $CHROME"; fi; fi`, browsersDir, browsersDir, browsersDir),
- timeout: 60,
- },
- {
- name: "Verify browser paths",
- cmd: fmt.Sprintf(`echo '=== Browser directories ===' && ls -la %s/ 2>&1 && echo '=== All chrome executables ===' && find %s -type f \( -name 'chrome' -o -name 'chrome-headless-shell' -o -name 'chromium' \) 2>/dev/null && echo '=== Checking headless shell ===' && ls -la %s/chromium_headless_shell-*/chrome-headless-shell-linux64/ 2>&1 || echo 'Headless shell dir not found' && echo '=== Checking regular chromium ===' && ls -la %s/chromium-*/chrome-linux64/ 2>&1 || echo 'Regular chromium dir not found'`, browsersDir, browsersDir, browsersDir, browsersDir),
- timeout: 30,
- },
- }
-
- endpoint := strings.TrimRight(baseURL, "/") + "/v1/shell/exec"
- client := &http.Client{Timeout: 10 * time.Minute}
-
- for _, c := range commands {
- log.Debug().Str("command", c.name).Msg("[slide_creator] Running shell command")
-
- req := shellExecRequest{
- Command: c.cmd,
- AsyncMode: false,
- Timeout: &c.timeout,
- }
-
- body, err := json.Marshal(req)
- if err != nil {
- return fmt.Errorf("marshal request: %w", err)
- }
-
- httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, bytes.NewReader(body))
- if err != nil {
- return fmt.Errorf("create request: %w", err)
- }
- httpReq.Header.Set("Content-Type", "application/json")
-
- resp, err := client.Do(httpReq)
- if err != nil {
- return fmt.Errorf("execute request: %w", err)
- }
-
- respBody, err := io.ReadAll(resp.Body)
- resp.Body.Close()
- if err != nil {
- return fmt.Errorf("read response: %w", err)
- }
-
- if resp.StatusCode != http.StatusOK {
- return fmt.Errorf("shell exec failed %d: %s", resp.StatusCode, truncateForLog(string(respBody), 1000))
- }
-
- var result shellExecResponse
- if err := json.Unmarshal(respBody, &result); err != nil {
- return fmt.Errorf("decode response: %w", err)
- }
-
- if result.Data != nil {
- if result.Data.Output != nil && *result.Data.Output != "" {
- // Log output for debugging (first few lines)
- output := *result.Data.Output
- lines := strings.Split(output, "\n")
- for i, line := range lines {
- if i < 5 {
- log.Debug().Str("line", line).Msg("[slide_creator] Shell output")
- } else if i == 5 {
- log.Debug().Int("remaining", len(lines)-5).Msg("[slide_creator] ... more lines")
- break
- }
- }
- }
- if result.Data.ExitCode != nil && *result.Data.ExitCode != 0 {
- log.Warn().Int("exit_code", *result.Data.ExitCode).Str("command", c.name).Msg("[slide_creator] Shell command exited with non-zero code")
- }
- }
- }
-
- return nil
-}
-
-func (e *SlideCreatorExecutor) executeExportPPTX(ctx context.Context, params map[string]interface{}, input agent.ExecutionInput) (*agent.ExecutionResult, error) {
- // Prefer MCP-based sandbox execution if mcpClient is available
- if e.mcpClient != nil {
- log.Info().Msg("[slide_creator] Using MCP sandbox tools for PPTX export")
- return e.executeExportPPTXViaMCP(ctx, params, input)
- }
-
- // Fallback to direct AIO HTTP calls (deprecated)
- log.Warn().Msg("[slide_creator] MCP client not available, falling back to direct AIO HTTP calls (deprecated)")
-
- if strings.TrimSpace(e.aioBaseURL) == "" {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "AIO_NOT_CONFIGURED",
- Message: "AIO_URL not configured for PPTX export",
- Severity: status.ErrorSeverityFatal,
- },
- }, nil
- }
-
- outDir := extractOutputDir(input)
- if outDir == "" {
- outDir = outputDirForPlan(input)
- }
- if _, err := os.Stat(outDir); err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "OUTPUT_DIR_ERROR",
- Message: fmt.Sprintf("output directory not found: %v", err),
- Severity: status.ErrorSeverityRetryable,
- },
- }, nil
- }
-
- mode := strings.ToLower(strings.TrimSpace(stringValue(params, "mode")))
- if mode == "" {
- mode = "dom"
- }
- // CDP disabled entirely - it was timing out, so we use local browsers instead
- useCDP := false
-
- payloads, rootName, err := collectAIOInputFiles(outDir)
- if err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "EXPORT_INPUT_ERROR",
- Message: err.Error(),
- Severity: status.ErrorSeverityRetryable,
- },
- }, nil
- }
-
- inputsJSON, _ := json.Marshal(payloads)
- files := map[string]string{
- "inputs.json": string(inputsJSON),
- "export_pptx_full.js": slidecreatorassets.ExportPPTXFullScript,
- }
-
- baseURL := discoverAIOBase(ctx, aioBaseCandidates(e.aioBaseURL))
- if baseURL == "" {
- baseURL = strings.TrimRight(e.aioBaseURL, "/")
- }
-
- // CDP disabled - always use local browsers
- cdpURL := ""
-
- outputFile := "presentation.pptx"
- cacheDir := "/home/gem/.cache/pptx_export"
-
- // Ensure Playwright browsers are installed via shell API
- // This cleans up incomplete installations and copies chrome to headless shell path if needed
- log.Info().Str("cache_dir", cacheDir).Msg("[slide_creator] Ensuring Playwright browsers are installed")
- if err := ensurePlaywrightBrowsers(ctx, baseURL, cacheDir); err != nil {
- log.Warn().Err(err).Msg("[slide_creator] Playwright browser installation may have failed, continuing anyway")
- // Continue anyway - the JS code will also try to install
- }
-
- code := buildAIOWrapperCode(rootName, outputFile, mode, cdpURL, cacheDir, useCDP)
-
- stdout, err := executeAIONodeJS(ctx, baseURL, code, files, 5*time.Minute)
- if err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "AIO_EXPORT_FAILED",
- Message: err.Error(),
- Severity: status.ErrorSeverityRetryable,
- },
- }, nil
- }
-
- pptxB64, err := extractBase64(stdout)
- if err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "EXPORT_PARSE_ERROR",
- Message: err.Error(),
- Severity: status.ErrorSeverityRetryable,
- },
- }, nil
- }
- pptxBytes, err := base64.StdEncoding.DecodeString(pptxB64)
- if err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "EXPORT_DECODE_ERROR",
- Message: fmt.Sprintf("failed to decode PPTX base64: %v", err),
- Severity: status.ErrorSeverityRetryable,
- },
- }, nil
- }
-
- pptxPath := filepath.Join(outDir, outputFile)
- if err := os.WriteFile(pptxPath, pptxBytes, 0644); err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "EXPORT_WRITE_ERROR",
- Message: fmt.Sprintf("failed to write PPTX: %v", err),
- Severity: status.ErrorSeverityRetryable,
- },
- }, nil
- }
-
- imageNames := []string{}
- images, imgErr := extractImages(stdout)
- if imgErr != nil {
- log.Warn().Err(imgErr).Msg("[slide_creator] failed to parse slide images from export output")
- }
- for name, b64 := range images {
- data, err := base64.StdEncoding.DecodeString(b64)
- if err != nil {
- log.Warn().Err(err).Str("image", name).Msg("[slide_creator] failed to decode slide image")
- continue
- }
- if err := os.WriteFile(filepath.Join(outDir, name), data, 0644); err != nil {
- log.Warn().Err(err).Str("image", name).Msg("[slide_creator] failed to write slide image")
- continue
- }
- imageNames = append(imageNames, name)
- }
- sort.Strings(imageNames)
-
- if len(imageNames) == 0 {
- outputDir := extractOutputDirFromStdout(stdout)
- if outputDir == "" {
- outputDir = filepath.ToSlash(filepath.Join(cacheDir, "outputs"))
- }
- if outputDir != "" {
- downloaded, err := downloadSlideImages(ctx, baseURL, outputDir, outDir)
- if err != nil {
- log.Warn().Err(err).Msg("[slide_creator] failed to download slide images from AIO")
- } else if len(downloaded) > 0 {
- imageNames = append(imageNames, downloaded...)
- sort.Strings(imageNames)
- }
- }
- }
-
- output := map[string]interface{}{
- "type": "pptx_export",
- "output_dir": outDir,
- "pptx_path": pptxPath,
- "pptx_file": outputFile,
- "pptx_size": len(pptxBytes),
- "images": imageNames,
- "image_count": len(imageNames),
- }
- outputBytes, _ := json.Marshal(output)
-
- return &agent.ExecutionResult{
- Status: status.StatusCompleted,
- Output: outputBytes,
- }, nil
-}
-
-func collectAIOInputFiles(outDir string) ([]filePayload, string, error) {
- root := filepath.Clean(outDir)
- rootName := filepath.Base(root)
- if rootName == "" || rootName == "." {
- rootName = "slides"
- }
-
- payloads := []filePayload{}
- allowed := map[string]bool{
- ".html": true,
- ".json": true,
- ".css": true,
- ".svg": true,
- ".png": true,
- ".jpg": true,
- ".jpeg": true,
- ".webp": true,
- ".gif": true,
- ".txt": true,
- ".md": true,
- ".woff": true,
- ".woff2": true,
- ".ttf": true,
- ".otf": true,
- }
-
- err := filepath.WalkDir(root, func(path string, d os.DirEntry, err error) error {
- if err != nil {
- return err
- }
- if d.IsDir() {
- return nil
- }
- ext := strings.ToLower(filepath.Ext(path))
- if ext == ".pptx" || ext == ".zip" {
- return nil
- }
- if !allowed[ext] {
- return nil
- }
- rel, err := filepath.Rel(root, path)
- if err != nil {
- return err
- }
- data, err := os.ReadFile(path)
- if err != nil {
- return err
- }
- payloads = append(payloads, filePayload{
- Path: filepath.ToSlash(filepath.Join(rootName, rel)),
- B64: base64.StdEncoding.EncodeToString(data),
- })
- return nil
- })
- if err != nil {
- return nil, "", err
- }
- if len(payloads) == 0 {
- return nil, "", fmt.Errorf("no exportable files found in %s", outDir)
- }
- return payloads, rootName, nil
-}
-
-func buildAIOWrapperCode(inputDir, outFile, mode, cdpURL, cacheDir string, useCDP bool) string {
- // CDP is disabled entirely - it was timing out, so we use local browsers instead
- // The useCDP and cdpURL parameters are kept for compatibility but ignored
- code := fmt.Sprintf(`
-const fs = require("fs");
-const path = require("path");
-const { spawnSync, execSync } = require("child_process");
-
-const workdir = process.cwd();
-const INPUT_DIR = %s;
-const OUT_FILE = %s;
-const MODE = %s;
-
-// CDP is unreliable (often times out), so we disable it and use local browsers
-const USE_CDP = false;
-const CDP_URL = "";
-const CACHE_DIR = (process.env.AIO_CACHE_DIR && process.env.AIO_CACHE_DIR.trim()) ? process.env.AIO_CACHE_DIR.trim() : %s;
-
-const RUN_ID = String(Date.now());
-const OUTPUT_DIR = path.join(CACHE_DIR, "outputs", RUN_ID);
-const OUT_PATH = path.join(OUTPUT_DIR, path.basename(OUT_FILE));
-
-function run(cmd, args, opts) {
- const res = spawnSync(cmd, args, Object.assign({ encoding: "utf8", maxBuffer: 50 * 1024 * 1024 }, opts || {}));
- if (res.stdout) process.stdout.write(res.stdout);
- if (res.stderr) process.stderr.write(res.stderr);
- const code = (typeof res.status === "number") ? res.status : 1;
- return { code };
-}
-
-console.log("[AIO] workdir=" + workdir);
-console.log("[AIO] cache_dir=" + CACHE_DIR);
-
-const files = JSON.parse(fs.readFileSync(path.join(workdir, "inputs.json"), "utf8"));
-const exportJs = fs.readFileSync(path.join(workdir, "export_pptx_full.js"), "utf8");
-
-// Write input files into temp workdir
-for (const f of files) {
- const fullPath = path.join(workdir, f.path);
- fs.mkdirSync(path.dirname(fullPath), { recursive: true });
- fs.writeFileSync(fullPath, Buffer.from(f.b64, "base64"));
-}
-fs.writeFileSync(path.join(workdir, "export_pptx_full.js"), exportJs);
-console.log("[AIO] wrote " + files.length + " input files + export_pptx_full.js");
-
-// Persistent env dirs
-const nodeEnvDir = path.join(CACHE_DIR, "node_env");
-const browsersDir = path.join(CACHE_DIR, "pw_browsers");
-fs.mkdirSync(nodeEnvDir, { recursive: true });
-fs.mkdirSync(browsersDir, { recursive: true });
-fs.mkdirSync(OUTPUT_DIR, { recursive: true });
-
-const pkgJson = path.join(nodeEnvDir, "package.json");
-if (!fs.existsSync(pkgJson)) {
- fs.writeFileSync(pkgJson, JSON.stringify({ name: "pptx_export_env", private: true }, null, 2));
-}
-
-// Ensure deps
-const nmPlaywright = path.join(nodeEnvDir, "node_modules", "playwright");
-const nmPptx = path.join(nodeEnvDir, "node_modules", "pptxgenjs");
-if (!fs.existsSync(nmPlaywright) || !fs.existsSync(nmPptx)) {
- console.log("[AIO] Installing npm deps (playwright, pptxgenjs) into " + nodeEnvDir);
- const envNpm = Object.assign({}, process.env, {
- PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "1",
- });
- let r = run("npm", ["install", "--no-fund", "--no-audit", "playwright", "pptxgenjs"], { cwd: nodeEnvDir, env: envNpm });
- if (r.code !== 0) {
- console.error("[AIO] ERROR: npm install failed");
- process.exit(2);
- }
-} else {
- console.log("[AIO] npm deps already present in cache");
-}
-
-// Check browser installation
-console.log("[AIO] Checking browser installation in " + browsersDir);
-try {
- const dirs = fs.readdirSync(browsersDir);
- console.log("[AIO] Browser dirs: " + dirs.join(", "));
-} catch (e) {
- console.log("[AIO] Could not list browser dirs: " + e.message);
-}
-
-// Install browsers if needed (using the cached playwright)
-const pwBin = path.join(nodeEnvDir, "node_modules", ".bin", "playwright");
-if (fs.existsSync(pwBin)) {
- console.log("[AIO] Ensuring browsers are installed via " + pwBin);
- const envPwInstall = Object.assign({}, process.env, {
- PLAYWRIGHT_BROWSERS_PATH: browsersDir,
- });
- let r = run(pwBin, ["install", "chromium"], { cwd: nodeEnvDir, env: envPwInstall });
- if (r.code !== 0) {
- console.warn("[AIO] WARNING: playwright install chromium returned " + r.code);
- }
-}
-
-// Find actual chrome executable
-let chromeExe = "";
-let headlessShellExe = "";
-try {
- // Find regular chrome
- const findChrome = execSync("find " + browsersDir + " -type f -name 'chrome' -executable 2>/dev/null | grep -v headless | head -1", { encoding: "utf8" });
- chromeExe = findChrome.trim();
- if (chromeExe) {
- console.log("[AIO] Found chrome executable: " + chromeExe);
- }
-
- // Find headless shell
- const findHeadless = execSync("find " + browsersDir + " -type f -name 'chrome-headless-shell' -executable 2>/dev/null | head -1", { encoding: "utf8" });
- headlessShellExe = findHeadless.trim();
- if (headlessShellExe) {
- console.log("[AIO] Found headless shell executable: " + headlessShellExe);
- }
-
- // If no headless shell, try to find any chrome in headless_shell dir
- if (!headlessShellExe) {
- const findAny = execSync("find " + browsersDir + "/chromium_headless_shell* -type f -executable 2>/dev/null | head -1", { encoding: "utf8" });
- headlessShellExe = findAny.trim();
- if (headlessShellExe) {
- console.log("[AIO] Found alternative headless executable: " + headlessShellExe);
- }
- }
-} catch (e) {
- console.log("[AIO] Error finding chrome executables: " + e.message);
-}
-
-// If headless shell is missing but chrome exists, create a copy
-if (!headlessShellExe && chromeExe) {
- console.log("[AIO] Headless shell missing, copying chrome to headless shell path...");
- const targetDir = path.join(browsersDir, "chromium_headless_shell-1200", "chrome-headless-shell-linux64");
- const targetFile = path.join(targetDir, "chrome-headless-shell");
- try {
- fs.mkdirSync(targetDir, { recursive: true });
- // Remove existing file if any
- try { fs.unlinkSync(targetFile); } catch (e) {}
- // Copy chrome to headless shell location
- fs.copyFileSync(chromeExe, targetFile);
- fs.chmodSync(targetFile, 0o755);
- headlessShellExe = targetFile;
- console.log("[AIO] Copied chrome to: " + targetFile);
- } catch (e) {
- console.log("[AIO] Could not copy chrome: " + e.message);
- }
-}
-
-const envRun = Object.assign({}, process.env, {
- NODE_PATH: path.join(nodeEnvDir, "node_modules"),
- AIO_CACHE_DIR: CACHE_DIR,
- AIO_CDP_URL: "", // Disabled
- PLAYWRIGHT_BROWSERS_PATH: browsersDir,
- PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "0",
-});
-
-// Set executable paths if found
-if (chromeExe) {
- envRun.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH = chromeExe;
-}
-if (headlessShellExe) {
- envRun.PLAYWRIGHT_CHROMIUM_HEADLESS_SHELL_EXECUTABLE_PATH = headlessShellExe;
-}
-
-const args = [path.join(workdir, "export_pptx_full.js"), "--in", INPUT_DIR, "--out", OUT_PATH, "--mode", MODE];
-console.log("[AIO] Running: node " + args.join(" "));
-const res = spawnSync("node", args, { cwd: workdir, env: envRun, stdio: "inherit", maxBuffer: 50 * 1024 * 1024 });
-if (typeof res.status === "number" && res.status !== 0) process.exit(res.status);
-
-// Return PPTX as base64
-const pptxPath = OUT_PATH;
-const pptx = fs.readFileSync(pptxPath);
-console.log("===OUTPUT_DIR===");
-console.log(OUTPUT_DIR);
-console.log("===OUTPUT_DIR_START===");
-console.log(OUTPUT_DIR);
-console.log("===OUTPUT_DIR_END===");
-console.log("===BASE64_START===");
-console.log(pptx.toString("base64"));
-console.log("===BASE64_END===");
-
-// Try to get slide images
-let images = {};
-try {
- const outDir = OUTPUT_DIR;
- const imageFiles = fs.readdirSync(outDir).filter((f) => /^slide-\d+\.png$/i.test(f));
- for (const f of imageFiles) {
- images[f] = fs.readFileSync(path.join(outDir, f)).toString("base64");
- }
-} catch (e) {
- console.log("[AIO] Could not read slide images: " + e.message);
-}
-console.log("===IMAGES_START===");
-console.log(JSON.stringify(images));
-console.log("===IMAGES_END===");
-`,
- jsQuote(inputDir),
- jsQuote(outFile),
- jsQuote(mode),
- jsQuote(cacheDir),
- )
-
- return strings.TrimSpace(code) + "\n"
-}
-
-func jsQuote(s string) string {
- encoded, _ := json.Marshal(s)
- return string(encoded)
-}
-
-func executeAIONodeJS(ctx context.Context, baseURL, code string, files map[string]string, timeout time.Duration) (string, error) {
- timeoutSec := int(mathRoundSeconds(timeout))
- if timeoutSec < 1 {
- timeoutSec = 1
- }
- if timeoutSec > 300 {
- timeoutSec = 300
- }
-
- stdin := ""
- payload := nodeJSExecuteRequest{
- Code: code,
- Timeout: &timeoutSec,
- Stdin: &stdin,
- Files: files,
- }
- body, err := json.Marshal(payload)
- if err != nil {
- return "", err
- }
-
- endpoint := strings.TrimRight(baseURL, "/") + "/v1/nodejs/execute"
- client := &http.Client{Timeout: 10 * time.Minute}
- maxAttempts := 3
-
- for attempt := 1; attempt <= maxAttempts; attempt++ {
- req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, bytes.NewReader(body))
- if err != nil {
- return "", err
- }
- req.Header.Set("Content-Type", "application/json")
-
- resp, err := client.Do(req)
- if err != nil {
- if isRetryableNetErr(err) && attempt < maxAttempts {
- time.Sleep(time.Duration(attempt*2) * time.Second)
- continue
- }
- return "", err
- }
-
- respBody, readErr := io.ReadAll(resp.Body)
- resp.Body.Close()
- if readErr != nil {
- if isRetryableNetErr(readErr) && attempt < maxAttempts {
- time.Sleep(time.Duration(attempt*2) * time.Second)
- continue
- }
- return "", readErr
- }
-
- if resp.StatusCode != http.StatusOK {
- return "", fmt.Errorf("aio nodejs error %d: %s", resp.StatusCode, truncateForLog(string(respBody), 2000))
- }
-
- var decoded nodeJSExecuteResponse
- if err := json.Unmarshal(respBody, &decoded); err != nil {
- return "", fmt.Errorf("nodejs response decode failed: %v", err)
- }
- if decoded.Data == nil {
- return "", errors.New("nodejs response missing data")
- }
-
- stdout := ""
- stderr := ""
- exitCode := 0
- if decoded.Data.Stdout != nil {
- stdout = *decoded.Data.Stdout
- }
- if decoded.Data.Stderr != nil {
- stderr = *decoded.Data.Stderr
- }
- if decoded.Data.ExitCode != nil {
- exitCode = *decoded.Data.ExitCode
- }
- if exitCode != 0 {
- msg := stderr
- if msg == "" {
- msg = stdout
- }
- return "", fmt.Errorf("nodejs exit %d: %s", exitCode, truncateForLog(msg, 4000))
- }
-
- if stderr != "" {
- stdout += "\n" + stderr
- }
- return stdout, nil
- }
-
- return "", errors.New("nodejs request failed after retries")
-}
-
-func extractBase64(output string) (string, error) {
- start := strings.Index(output, "===BASE64_START===")
- end := strings.Index(output, "===BASE64_END===")
- if start == -1 || end == -1 || end <= start {
- return "", errors.New("base64 markers not found")
- }
- chunk := strings.TrimSpace(output[start+len("===BASE64_START===") : end])
- if chunk == "" {
- return "", errors.New("base64 content empty")
- }
- return chunk, nil
-}
-
-func extractImages(output string) (map[string]string, error) {
- start := strings.Index(output, "===IMAGES_START===")
- end := strings.Index(output, "===IMAGES_END===")
- if start == -1 || end == -1 || end <= start {
- return map[string]string{}, nil
- }
- chunk := strings.TrimSpace(output[start+len("===IMAGES_START===") : end])
- if chunk == "" {
- return map[string]string{}, nil
- }
- var decoded map[string]string
- if err := json.Unmarshal([]byte(chunk), &decoded); err != nil {
- return nil, err
- }
- return decoded, nil
-}
-
-func extractOutputDirFromStdout(output string) string {
- singleMarker := "===OUTPUT_DIR==="
- if idx := strings.Index(output, singleMarker); idx != -1 {
- rest := output[idx+len(singleMarker):]
- rest = strings.TrimLeft(rest, "\r\n")
- if rest == "" {
- return ""
- }
- if lineEnd := strings.IndexAny(rest, "\r\n"); lineEnd != -1 {
- rest = rest[:lineEnd]
- }
- return strings.TrimSpace(rest)
- }
- start := strings.Index(output, "===OUTPUT_DIR_START===")
- end := strings.Index(output, "===OUTPUT_DIR_END===")
- if start == -1 || end == -1 || end <= start {
- return ""
- }
- chunk := strings.TrimSpace(output[start+len("===OUTPUT_DIR_START===") : end])
- return chunk
-}
-
-func aioBaseCandidates(raw string) []string {
- base := strings.TrimRight(strings.TrimSpace(raw), "/")
- if base == "" {
- return nil
- }
- seen := map[string]bool{}
- out := []string{}
- add := func(u string) {
- u = strings.TrimRight(strings.TrimSpace(u), "/")
- if u == "" || seen[u] {
- return
- }
- seen[u] = true
- out = append(out, u)
- }
- add(base)
- for _, suffix := range []string{"/zh/api", "/api"} {
- if strings.HasSuffix(base, suffix) {
- add(strings.TrimSuffix(base, suffix))
- }
- }
- return out
-}
-
-func discoverAIOBase(ctx context.Context, candidates []string) string {
- if len(candidates) == 0 {
- return ""
- }
- client := &http.Client{Timeout: 10 * time.Second}
- for _, base := range candidates {
- endpoint := strings.TrimRight(base, "/") + "/v1/nodejs/info"
- req, _ := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
- req.Header.Set("Accept", "application/json")
- resp, err := client.Do(req)
- if err != nil {
- continue
- }
- _, _ = io.ReadAll(resp.Body)
- resp.Body.Close()
- if resp.StatusCode == http.StatusOK {
- return base
- }
- }
- return candidates[0]
-}
-
-func fetchBrowserCDPURL(ctx context.Context, baseURL string) (string, error) {
- endpoint := strings.TrimRight(baseURL, "/") + "/v1/browser/info"
- req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
- if err != nil {
- return "", err
- }
- req.Header.Set("Accept", "application/json")
-
- client := &http.Client{Timeout: 15 * time.Second}
- resp, err := client.Do(req)
- if err != nil {
- return "", err
- }
- defer resp.Body.Close()
- body, _ := io.ReadAll(resp.Body)
- if resp.StatusCode != http.StatusOK {
- return "", fmt.Errorf("browser/info status=%s body=%s", resp.Status, truncateForLog(string(body), 800))
- }
-
- var decoded struct {
- Data *struct {
- CDPURL *string `json:"cdp_url"`
- } `json:"data"`
- }
- if err := json.Unmarshal(body, &decoded); err != nil {
- return "", err
- }
- if decoded.Data == nil || decoded.Data.CDPURL == nil || strings.TrimSpace(*decoded.Data.CDPURL) == "" {
- return "", errors.New("cdp_url missing in response")
- }
- return *decoded.Data.CDPURL, nil
-}
-
-func isLocalhostURL(raw string) bool {
- u, err := url.Parse(raw)
- if err != nil {
- return false
- }
- host := strings.ToLower(strings.TrimSpace(u.Hostname()))
- return host == "localhost" || host == "127.0.0.1" || host == "::1"
-}
-
-func isRetryableNetErr(err error) bool {
- if err == nil {
- return false
- }
- if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {
- return true
- }
- if ne, ok := err.(net.Error); ok && (ne.Timeout() || ne.Temporary()) {
- return true
- }
- msg := err.Error()
- return strings.Contains(msg, "unexpected EOF") || strings.Contains(msg, "connection reset") || strings.Contains(msg, "broken pipe")
-}
-
-func truncateForLog(s string, max int) string {
- if len(s) <= max {
- return s
- }
- return s[:max] + "... (truncated)"
-}
-
-func mathRoundSeconds(d time.Duration) int64 {
- seconds := d.Seconds()
- if seconds < 0 {
- return 0
- }
- return int64(seconds + 0.5)
-}
-
-func downloadSlideImages(ctx context.Context, baseURL, outputDir, localDir string) ([]string, error) {
- showHidden := true
- req := fileListRequest{
- Path: outputDir,
- ShowHidden: &showHidden,
- FileTypes: []string{".png"},
- }
- var resp responseWrapper[fileListResult]
- if err := postJSON(ctx, strings.TrimRight(baseURL, "/")+"/v1/file/list", req, &resp); err != nil {
- return nil, err
- }
- if resp.Data == nil {
- return nil, nil
- }
- var names []string
- for _, f := range resp.Data.Files {
- if f.IsDirectory {
- continue
- }
- name := f.Name
- if !strings.HasPrefix(strings.ToLower(name), "slide-") || !strings.HasSuffix(strings.ToLower(name), ".png") {
- continue
- }
- localPath := filepath.Join(localDir, name)
- if err := downloadFile(ctx, baseURL, f.Path, localPath); err != nil {
- return names, err
- }
- names = append(names, name)
- }
- return names, nil
-}
-
-func downloadFile(ctx context.Context, baseURL, remotePath, localPath string) error {
- u := strings.TrimRight(baseURL, "/") + "/v1/file/download?path=" + url.QueryEscape(remotePath)
- req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil)
- if err != nil {
- return err
- }
- client := &http.Client{Timeout: 10 * time.Minute}
- resp, err := client.Do(req)
- if err != nil {
- return err
- }
- defer resp.Body.Close()
- if resp.StatusCode != http.StatusOK {
- body, _ := io.ReadAll(resp.Body)
- return fmt.Errorf("download failed %d: %s", resp.StatusCode, truncateForLog(string(body), 800))
- }
- data, err := io.ReadAll(resp.Body)
- if err != nil {
- return err
- }
- return os.WriteFile(localPath, data, 0644)
-}
-
-func postJSON(ctx context.Context, url string, payload any, out any) error {
- body, err := json.Marshal(payload)
- if err != nil {
- return err
- }
- req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))
- if err != nil {
- return err
- }
- req.Header.Set("Content-Type", "application/json")
- client := &http.Client{Timeout: 10 * time.Minute}
- resp, err := client.Do(req)
- if err != nil {
- return err
- }
- defer resp.Body.Close()
- respBody, err := io.ReadAll(resp.Body)
- if err != nil {
- return err
- }
- if resp.StatusCode != http.StatusOK {
- return fmt.Errorf("AIO error %d: %s", resp.StatusCode, truncateForLog(string(respBody), 1200))
- }
- if out != nil {
- if err := json.Unmarshal(respBody, out); err != nil {
- return fmt.Errorf("response decode failed: %v; body=%s", err, truncateForLog(string(respBody), 1200))
- }
- }
- return nil
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/assets.go b/services/response-api/internal/domain/agent/planners/slide_creator/steps/assets.go
deleted file mode 100644
index 072fa33c..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/assets.go
+++ /dev/null
@@ -1,321 +0,0 @@
-package steps
-
-import (
- "crypto/sha1"
- "encoding/hex"
- "encoding/json"
- "fmt"
- "net/url"
- "sort"
- "strings"
-
- "jan-server/services/response-api/internal/domain/agent"
-
- "github.com/rs/zerolog/log"
-)
-
-func collectDataBankText(input agent.ExecutionInput) string {
- outputs := make([]json.RawMessage, 0, len(input.AccumulatedOutputs)+1)
- outputs = append(outputs, input.AccumulatedOutputs...)
- if len(input.PreviousOutput) > 0 {
- outputs = append(outputs, input.PreviousOutput)
- }
- for i := len(outputs) - 1; i >= 0; i-- {
- var payload map[string]any
- if err := json.Unmarshal(outputs[i], &payload); err != nil {
- continue
- }
- if payloadType, _ := payload["type"].(string); payloadType == "data_bank" {
- if skipped, ok := payload["skipped"].(bool); ok && skipped {
- continue
- }
- if content, ok := payload["content"].(string); ok && content != "" {
- log.Debug().Int("content_length", len(content)).Msg("[slide_creator] data bank text collected")
- return content
- }
- if data, ok := payload["data"]; ok {
- if raw, err := json.Marshal(data); err == nil {
- log.Debug().Int("content_length", len(raw)).Msg("[slide_creator] data bank text collected")
- return string(raw)
- }
- }
- }
- }
- return ""
-}
-
-const (
- slidePlanImageAssetLimitSingle = 4
- slidePlanImageAssetLimitPerSlide = 3
- slidePlanImageAssetMaxTotal = 12
-)
-
-func limitImageAssets(assets []map[string]any, max int) []map[string]any {
- if max <= 0 || len(assets) <= max {
- return assets
- }
- return assets[:max]
-}
-
-func limitSlidePlanImageAssets(assets []map[string]any, numSlides int) []map[string]any {
- if len(assets) == 0 {
- return assets
- }
- limitPerSlide := slidePlanImageAssetLimitPerSlide
- if numSlides <= 1 {
- limitPerSlide = slidePlanImageAssetLimitSingle
- }
- if numSlides <= 0 {
- numSlides = 1
- }
- maxTotal := limitPerSlide * numSlides
- if maxTotal > slidePlanImageAssetMaxTotal {
- maxTotal = slidePlanImageAssetMaxTotal
- }
- return limitImageAssets(assets, maxTotal)
-}
-
-func compactImageAssetsForPrompt(assets []map[string]any) []map[string]any {
- if len(assets) == 0 {
- return assets
- }
- out := make([]map[string]any, 0, len(assets))
- for _, asset := range assets {
- if asset == nil {
- continue
- }
- prompt := map[string]any{}
- if id, ok := asset["id"].(string); ok && strings.TrimSpace(id) != "" {
- prompt["id"] = id
- }
- if kind, ok := asset["kind"].(string); ok && strings.TrimSpace(kind) != "" {
- prompt["kind"] = kind
- }
- if url := promptImageURL(asset); url != "" {
- prompt["source"] = map[string]any{"type": "url", "url": url}
- }
- if title, ok := asset["title"].(string); ok && strings.TrimSpace(title) != "" {
- prompt["title"] = title
- }
- if alt, ok := asset["altText"].(string); ok && strings.TrimSpace(alt) != "" {
- prompt["altText"] = alt
- }
- if attribution, ok := asset["attribution"].(string); ok && strings.TrimSpace(attribution) != "" {
- prompt["attribution"] = attribution
- }
- if license, ok := asset["license"]; ok {
- prompt["license"] = license
- }
- if len(prompt) > 0 {
- out = append(out, prompt)
- }
- }
- return out
-}
-
-func promptImageURL(asset map[string]any) string {
- if asset == nil {
- return ""
- }
- if thumb, ok := asset["thumbnailUrl"].(string); ok && strings.TrimSpace(thumb) != "" {
- return thumb
- }
- if img, ok := asset["imageUrl"].(string); ok && strings.TrimSpace(img) != "" {
- return img
- }
- if source, ok := asset["source"].(map[string]any); ok {
- if url, ok := source["url"].(string); ok && strings.TrimSpace(url) != "" {
- return url
- }
- }
- return ""
-}
-
-func collectImageAssets(input agent.ExecutionInput) []map[string]any {
- outputs := make([]json.RawMessage, 0, len(input.AccumulatedOutputs)+1)
- outputs = append(outputs, input.AccumulatedOutputs...)
- if len(input.PreviousOutput) > 0 {
- outputs = append(outputs, input.PreviousOutput)
- }
-
- assetsByID := map[string]map[string]any{}
- for _, output := range outputs {
- for _, asset := range extractImageAssetsFromOutput(output) {
- id, _ := asset["id"].(string)
- if id == "" {
- continue
- }
- if _, exists := assetsByID[id]; !exists {
- assetsByID[id] = asset
- }
- }
- }
-
- assets := make([]map[string]any, 0, len(assetsByID))
- for _, asset := range assetsByID {
- assets = append(assets, asset)
- }
- sort.Slice(assets, func(i, j int) bool {
- return fmt.Sprint(assets[i]["id"]) < fmt.Sprint(assets[j]["id"])
- })
- log.Debug().Int("assets", len(assets)).Msg("[slide_creator] image assets collected")
- return assets
-}
-
-func replacePlanImageSources(plan DeckPlan, assets []map[string]any) (DeckPlan, int) {
- if len(assets) == 0 || len(plan.Slides) == 0 {
- return plan, 0
- }
- replacements := make(map[string]string)
- for _, asset := range assets {
- thumb := firstString(asset, "thumbnailUrl")
- img := firstString(asset, "imageUrl")
- if thumb == "" || img == "" {
- continue
- }
- if strings.TrimSpace(thumb) == strings.TrimSpace(img) {
- continue
- }
- replacements[thumb] = img
- }
- if len(replacements) == 0 {
- return plan, 0
- }
- replaced := 0
- for i := range plan.Slides {
- for j := range plan.Slides[i].Images {
- src := strings.TrimSpace(plan.Slides[i].Images[j].Src)
- if src == "" {
- continue
- }
- if full, ok := replacements[src]; ok && strings.TrimSpace(full) != "" {
- plan.Slides[i].Images[j].Src = full
- replaced++
- }
- }
- }
- return plan, replaced
-}
-
-func extractImageAssetsFromOutput(output json.RawMessage) []map[string]any {
- if len(output) == 0 {
- return nil
- }
- var parsed map[string]any
- if err := json.Unmarshal(output, &parsed); err != nil {
- return nil
- }
-
- results := []map[string]any{}
- if content, ok := parsed["content"].([]any); ok {
- for _, item := range content {
- if itemMap, ok := item.(map[string]any); ok {
- if text, ok := itemMap["text"].(string); ok && text != "" {
- var nested map[string]any
- if err := json.Unmarshal([]byte(text), &nested); err == nil {
- results = append(results, extractImageAssetsFromMap(nested)...)
- }
- }
- }
- }
- }
-
- results = append(results, extractImageAssetsFromMap(parsed)...)
- return results
-}
-
-func extractImageAssetsFromMap(data map[string]any) []map[string]any {
- results := []map[string]any{}
- for _, key := range []string{"images", "results", "items", "data"} {
- if arr, ok := data[key].([]any); ok {
- results = append(results, extractImageAssetsFromArray(arr)...)
- }
- }
- for _, value := range data {
- switch typed := value.(type) {
- case map[string]any:
- results = append(results, extractImageAssetsFromMap(typed)...)
- case []any:
- results = append(results, extractImageAssetsFromArray(typed)...)
- }
- }
- return results
-}
-
-func extractImageAssetsFromArray(arr []any) []map[string]any {
- results := []map[string]any{}
- for _, item := range arr {
- itemMap, ok := item.(map[string]any)
- if !ok {
- continue
- }
- if asset := assetFromImageResult(itemMap); asset != nil {
- results = append(results, asset)
- }
- }
- return results
-}
-
-func assetFromImageResult(item map[string]any) map[string]any {
- imageURL := firstString(item, "imageUrl", "image_url")
- thumbURL := firstString(item, "thumbnailUrl", "thumbnail_url", "thumbnail", "thumb", "previewUrl", "preview_url")
- if imageURL == "" && thumbURL == "" {
- return nil
- }
- sourceURL := imageURL
- if sourceURL == "" {
- sourceURL = thumbURL
- }
- parsed, _ := url.Parse(sourceURL)
- host := ""
- if parsed != nil {
- host = parsed.Host
- }
- title := firstString(item, "title", "alt", "altText", "snippet", "description")
- altText := title
- if altText == "" {
- altText = host
- }
- license := firstString(item, "license")
- attribution := firstString(item, "attribution", "source")
- if attribution == "" {
- attribution = host
- }
- id := assetIDFromURL(sourceURL)
- asset := map[string]any{
- "id": id,
- "kind": "image",
- "source": map[string]any{
- "type": "url",
- "url": sourceURL,
- },
- "altText": altText,
- "license": license,
- "attribution": attribution,
- }
- if title != "" {
- asset["title"] = title
- }
- if imageURL != "" {
- asset["imageUrl"] = imageURL
- }
- if thumbURL != "" {
- asset["thumbnailUrl"] = thumbURL
- }
- return asset
-}
-
-func assetIDFromURL(urlStr string) string {
- hasher := sha1.New()
- hasher.Write([]byte(urlStr))
- return "img_" + hex.EncodeToString(hasher.Sum(nil))[:12]
-}
-
-func firstString(item map[string]any, keys ...string) string {
- for _, key := range keys {
- if value, ok := item[key].(string); ok && strings.TrimSpace(value) != "" {
- return value
- }
- }
- return ""
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/config_helpers.go b/services/response-api/internal/domain/agent/planners/slide_creator/steps/config_helpers.go
deleted file mode 100644
index ea2b60ae..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/config_helpers.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package steps
-
-import (
- "encoding/json"
- "strconv"
- "strings"
-)
-
-func parseIntFromInterface(value interface{}) (int, bool) {
- switch v := value.(type) {
- case int:
- return v, true
- case int8:
- return int(v), true
- case int16:
- return int(v), true
- case int32:
- return int(v), true
- case int64:
- return int(v), true
- case uint:
- return int(v), true
- case uint8:
- return int(v), true
- case uint16:
- return int(v), true
- case uint32:
- return int(v), true
- case uint64:
- return int(v), true
- case float32:
- return int(v), true
- case float64:
- return int(v), true
- case json.Number:
- if n, err := v.Int64(); err == nil {
- return int(n), true
- }
- case string:
- if n, err := strconv.Atoi(strings.TrimSpace(v)); err == nil {
- return n, true
- }
- }
- return 0, false
-}
-
-func parseBoolFromInterface(value interface{}) (bool, bool) {
- switch v := value.(type) {
- case bool:
- return v, true
- case string:
- switch strings.ToLower(strings.TrimSpace(v)) {
- case "true", "1", "yes", "y":
- return true, true
- case "false", "0", "no", "n":
- return false, true
- }
- case float64:
- return v != 0, true
- case int:
- return v != 0, true
- }
- return false, false
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/context_build.go b/services/response-api/internal/domain/agent/planners/slide_creator/steps/context_build.go
deleted file mode 100644
index e86e0542..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/context_build.go
+++ /dev/null
@@ -1,281 +0,0 @@
-package steps
-
-import (
- "bytes"
- "encoding/json"
- "fmt"
- "strings"
-
- "jan-server/services/response-api/internal/domain/agent"
-
- "github.com/rs/zerolog/log"
-)
-
-const (
- defaultContextPartLimit = 10000
- slidePlanContextPerSlideLimit = 3000
- slidePlanContextMaxTotal = 12000
- slidePlanContextPartLimit = 3000
-)
-
-type contextBuildOptions struct {
- maxTotalChars int
- maxPartChars int
- excludedToolNames map[string]struct{}
- excludedTypes map[string]struct{}
- excludePayload func(map[string]interface{}) bool
-}
-
-func buildSlidePlanContext(input agent.ExecutionInput, numSlides int) string {
- maxTotal := slidePlanContextPerSlideLimit
- if numSlides > 0 {
- maxTotal = slidePlanContextPerSlideLimit * numSlides
- }
- if maxTotal > slidePlanContextMaxTotal {
- maxTotal = slidePlanContextMaxTotal
- }
- return buildAccumulatedContextWithOptions(input, contextBuildOptions{
- maxTotalChars: maxTotal,
- maxPartChars: slidePlanContextPartLimit,
- excludedToolNames: toKeySet(
- "google_search",
- "image_search",
- "image_search_slide",
- "scrape",
- ),
- excludedTypes: toKeySet(
- "google_search",
- "image_search",
- "image_search_slide",
- "scrape",
- "data_bank",
- ),
- excludePayload: excludeOutlinePayload,
- })
-}
-
-func buildAccumulatedContext(input agent.ExecutionInput) string {
- return buildAccumulatedContextWithOptions(input, contextBuildOptions{
- maxPartChars: defaultContextPartLimit,
- excludedToolNames: toKeySet(
- "image_search",
- "image_search_slide",
- ),
- excludedTypes: toKeySet(
- "image_search",
- "image_search_slide",
- ),
- })
-}
-
-func buildAccumulatedContextWithOptions(input agent.ExecutionInput, opts contextBuildOptions) string {
- outputs := make([]json.RawMessage, 0, len(input.AccumulatedOutputs)+1)
- outputs = append(outputs, input.AccumulatedOutputs...)
- if len(input.PreviousOutput) > 0 {
- if len(outputs) == 0 || !bytes.Equal(outputs[len(outputs)-1], input.PreviousOutput) {
- outputs = append(outputs, input.PreviousOutput)
- }
- }
-
- contextParts := []string{}
- for _, output := range outputs {
- if len(output) == 0 {
- continue
- }
- extracted := extractContextFromOutputWithOptions(output, opts)
- if strings.TrimSpace(extracted) == "" {
- continue
- }
- if opts.maxPartChars > 0 {
- extracted = truncateWithSuffix(extracted, opts.maxPartChars)
- }
- contextParts = append(contextParts, extracted)
- }
-
- if len(contextParts) == 0 {
- return ""
- }
- if opts.maxTotalChars > 0 {
- contextParts = trimContextPartsToLimit(contextParts, opts.maxTotalChars)
- }
-
- return strings.Join(contextParts, "\n\n---\n\n")
-}
-
-func extractContextFromOutputWithOptions(output json.RawMessage, opts contextBuildOptions) string {
- if len(output) == 0 {
- return ""
- }
-
- var data map[string]interface{}
- if err := json.Unmarshal(output, &data); err != nil {
- return string(output)
- }
- if shouldSkipContextPayload(data, opts) {
- return ""
- }
- if opts.excludePayload != nil && opts.excludePayload(data) {
- return ""
- }
-
- if content, ok := data["content"].(string); ok && content != "" {
- return content
- }
- if text, ok := data["text"].(string); ok && text != "" {
- return text
- }
-
- if toolName, ok := data["tool_name"].(string); ok && toolName != "" {
- if content, ok := data["content"].([]interface{}); ok {
- texts := []string{}
- for _, item := range content {
- if itemMap, ok := item.(map[string]interface{}); ok {
- if text, ok := itemMap["text"].(string); ok && text != "" {
- texts = append(texts, text)
- }
- }
- }
- if len(texts) > 0 {
- return fmt.Sprintf("[%s result]: %s", toolName, strings.Join(texts, "\n"))
- }
- }
- }
-
- return string(output)
-}
-
-func shouldSkipContextPayload(data map[string]interface{}, opts contextBuildOptions) bool {
- if data == nil {
- return false
- }
- if len(opts.excludedTypes) > 0 {
- if payloadType, ok := data["type"].(string); ok {
- if _, excluded := opts.excludedTypes[normalizeKey(payloadType)]; excluded {
- return true
- }
- }
- }
- if len(opts.excludedToolNames) > 0 {
- if toolName, ok := data["tool_name"].(string); ok {
- if _, excluded := opts.excludedToolNames[normalizeKey(toolName)]; excluded {
- return true
- }
- }
- if toolName, ok := data["tool"].(string); ok {
- if _, excluded := opts.excludedToolNames[normalizeKey(toolName)]; excluded {
- return true
- }
- }
- }
- return false
-}
-
-func trimContextPartsToLimit(parts []string, limit int) []string {
- if limit <= 0 {
- return parts
- }
-
- total := 0
- kept := make([]string, 0, len(parts))
- for i := len(parts) - 1; i >= 0; i-- {
- part := parts[i]
- partLen := len(part)
- if total+partLen <= limit {
- kept = append(kept, part)
- total += partLen
- continue
- }
-
- remaining := limit - total
- if remaining <= 0 {
- break
- }
- truncated := truncateWithSuffix(part, remaining)
- if strings.TrimSpace(truncated) != "" {
- kept = append(kept, truncated)
- }
- break
- }
-
- for i, j := 0, len(kept)-1; i < j; i, j = i+1, j-1 {
- kept[i], kept[j] = kept[j], kept[i]
- }
-
- return kept
-}
-
-func truncateWithSuffix(text string, limit int) string {
- if limit <= 0 || len(text) <= limit {
- return text
- }
- const suffix = "... [truncated]"
- if limit <= len(suffix) {
- return text[:limit]
- }
- return text[:limit-len(suffix)] + suffix
-}
-
-func normalizeKey(value string) string {
- return strings.ToLower(strings.TrimSpace(value))
-}
-
-func toKeySet(values ...string) map[string]struct{} {
- if len(values) == 0 {
- return nil
- }
- set := make(map[string]struct{}, len(values))
- for _, value := range values {
- key := normalizeKey(value)
- if key == "" {
- continue
- }
- set[key] = struct{}{}
- }
- return set
-}
-
-func collectOutlineText(input agent.ExecutionInput) string {
- outputs := make([]json.RawMessage, 0, len(input.AccumulatedOutputs)+1)
- outputs = append(outputs, input.AccumulatedOutputs...)
- if len(input.PreviousOutput) > 0 {
- outputs = append(outputs, input.PreviousOutput)
- }
-
- for i := len(outputs) - 1; i >= 0; i-- {
- if len(outputs[i]) == 0 {
- continue
- }
- var payload map[string]interface{}
- if err := json.Unmarshal(outputs[i], &payload); err != nil {
- continue
- }
- if !isOutlinePayload(payload) {
- continue
- }
- if content, ok := payload["content"].(string); ok && strings.TrimSpace(content) != "" {
- log.Debug().Int("content_length", len(content)).Msg("[slide_creator] outline text collected")
- return content
- }
- }
- return ""
-}
-
-func excludeOutlinePayload(payload map[string]interface{}) bool {
- return isOutlinePayload(payload)
-}
-
-func isOutlinePayload(payload map[string]interface{}) bool {
- if payload == nil {
- return false
- }
- payloadType, _ := payload["type"].(string)
- if normalizeKey(payloadType) != "llm_response" {
- return false
- }
- action, _ := payload["action"].(string)
- if normalizeKey(action) == "reasoning" {
- return true
- }
- description, _ := payload["description"].(string)
- return strings.Contains(strings.ToLower(description), "outline")
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/deck_theme.go b/services/response-api/internal/domain/agent/planners/slide_creator/steps/deck_theme.go
deleted file mode 100644
index ecad1088..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/deck_theme.go
+++ /dev/null
@@ -1,133 +0,0 @@
-package steps
-
-import (
- "context"
- "encoding/json"
- "errors"
- "fmt"
- "strings"
- "time"
-
- "jan-server/services/response-api/internal/domain/agent"
- "jan-server/services/response-api/internal/domain/status"
-
- "github.com/rs/zerolog/log"
-)
-
-func (e *SlideCreatorExecutor) executeDeckTheme(ctx context.Context, params map[string]interface{}, input agent.ExecutionInput) (*agent.ExecutionResult, error) {
- brief, _ := params["brief"].(string)
- config, _ := params["config"].(map[string]interface{})
- themePref := formatThemePreferences(config)
- colorScheme := strings.TrimSpace(stringValue(config, "color_scheme"))
- outlineText := strings.TrimSpace(collectOutlineText(input))
- if outlineText != "" {
- outlineText = truncateWithSuffix(outlineText, slidePlanContextPerSlideLimit)
- }
-
- promptParts := []string{
- "Select a concise deck title and a high-contrast theme.",
- "Return ONLY JSON with this shape:",
- `{"title":"...","theme":{"primary_color":"#RRGGBB","accent_color":"#RRGGBB","background_color":"#RRGGBB","text_color":"#RRGGBB","font_family":"Segoe UI, Arial, Helvetica, sans-serif"}}`,
- "HARD RULES:",
- "- title length: 6-60 characters.",
- "- background must be very dark or very light.",
- "- text_color must contrast with background (near-white on dark, near-black on light).",
- "- Output JSON only. No commentary.",
- }
-
- if strings.TrimSpace(brief) != "" {
- promptParts = append(promptParts, "Brief:\n"+strings.TrimSpace(brief))
- }
- if themePref != "" {
- promptParts = append(promptParts, "Theme preferences:\n"+themePref)
- }
- if outlineText != "" {
- promptParts = append(promptParts, "Outline (summary):\n"+outlineText)
- }
-
- prompt := strings.Join(promptParts, "\n\n")
-
- log.Debug().
- Str("plan_id", planContextValue(input, "plan_id")).
- Str("prompt", sanitizeForLog(prompt)).
- Msg("[slide_creator] deck theme prompt")
-
- model := getModelFromContext(input)
- if e.llmProvider == nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "LLM_PROVIDER_MISSING",
- Message: "LLM provider not configured",
- Severity: status.ErrorSeverityFatal,
- },
- }, nil
- }
-
- var content string
- var err error
- var lastErr error
- for attempt := 1; attempt <= 3; attempt++ {
- attemptStart := time.Now()
- content, err = e.generateWithStructuredOutput(ctx, "", prompt, model, DeckThemeSchema, 0.2)
- if err == nil {
- log.Info().
- Str("plan_id", planContextValue(input, "plan_id")).
- Int("attempt", attempt).
- Int64("duration_ms", time.Since(attemptStart).Milliseconds()).
- Msg("[slide_creator] deck theme structured output succeeded")
- lastErr = nil
- break
- }
- lastErr = err
- log.Warn().
- Err(err).
- Str("plan_id", planContextValue(input, "plan_id")).
- Int("attempt", attempt).
- Int64("duration_ms", time.Since(attemptStart).Milliseconds()).
- Msg("[slide_creator] deck theme structured output failed")
- if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) {
- break
- }
- }
- if lastErr != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "LLM_CALL_FAILED",
- Message: fmt.Sprintf("LLM generation failed: %v", lastErr),
- Severity: status.ErrorSeverityRetryable,
- },
- }, nil
- }
-
- var theme DeckTheme
- if err := json.Unmarshal([]byte(content), &theme); err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "PARSE_ERROR",
- Message: fmt.Sprintf("could not parse deck theme JSON: %v", err),
- Severity: status.ErrorSeverityRetryable,
- },
- }, nil
- }
- if strings.TrimSpace(theme.Title) == "" {
- theme.Title = fallbackDeckTitle(outlineText, brief)
- }
- theme.Title = trimToRunesNoEllipsis(strings.TrimSpace(theme.Title), 60)
- theme.Theme = normalizeTheme(theme.Theme)
- theme.Theme = applyColorScheme(theme.Theme, colorScheme, theme.Title)
-
- output := map[string]interface{}{
- "type": "deck_theme",
- "title": theme.Title,
- "theme": theme.Theme,
- }
- outputBytes, _ := json.Marshal(output)
-
- return &agent.ExecutionResult{
- Status: status.StatusCompleted,
- Output: outputBytes,
- }, nil
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/embedded_templates.go b/services/response-api/internal/domain/agent/planners/slide_creator/steps/embedded_templates.go
deleted file mode 100644
index 8e2ba07b..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/embedded_templates.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package steps
-
-import (
- "io/fs"
-
- templateassets "jan-server/services/response-api/assets/slide_creator/templates"
-)
-
-func embeddedTemplatesRoot() fs.FS {
- return templateassets.FS
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/executor.go b/services/response-api/internal/domain/agent/planners/slide_creator/steps/executor.go
deleted file mode 100644
index a64ea0e9..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/executor.go
+++ /dev/null
@@ -1,146 +0,0 @@
-package steps
-
-import (
- "context"
- "strings"
-
- "jan-server/services/response-api/internal/config"
- "jan-server/services/response-api/internal/domain/agent"
- "jan-server/services/response-api/internal/domain/agent/planners"
- "jan-server/services/response-api/internal/domain/artifact"
- "jan-server/services/response-api/internal/domain/plan"
- "jan-server/services/response-api/internal/domain/status"
- "jan-server/services/response-api/internal/infrastructure/media"
-
- "github.com/rs/zerolog/log"
-)
-
-// SlideCreatorExecutor executes steps for slide creation plans.
-type SlideCreatorExecutor struct {
- mcpClient planners.MCPClient
- llmProvider planners.LLMProvider
- artifactService artifact.Service
- mediaClient *media.Client
- aioBaseURL string
- temperature float64
- sandboxHelper *agent.SandboxHelper
-}
-
-type llmProviderWithTemperature interface {
- GenerateWithModelWithTemperature(ctx context.Context, prompt string, model string, temperature float64) (string, error)
- GenerateWithSystemPromptWithTemperature(ctx context.Context, systemPrompt string, userPrompt string, model string, temperature float64) (string, error)
- GenerateWithStructuredOutputWithTemperature(ctx context.Context, systemPrompt string, userPrompt string, model string, schema map[string]any, temperature float64) (string, error)
-}
-
-type llmProviderWithMaxTokens interface {
- GenerateWithModelWithMaxTokens(ctx context.Context, prompt string, model string, maxTokens *int) (string, error)
- GenerateWithSystemPromptWithMaxTokens(ctx context.Context, systemPrompt string, userPrompt string, model string, maxTokens *int) (string, error)
- GenerateWithStructuredOutputWithMaxTokens(ctx context.Context, systemPrompt string, userPrompt string, model string, schema map[string]any, maxTokens *int) (string, error)
-}
-
-type llmProviderWithTemperatureAndMaxTokens interface {
- GenerateWithModelWithTemperatureAndMaxTokens(ctx context.Context, prompt string, model string, temperature float64, maxTokens *int) (string, error)
- GenerateWithSystemPromptWithTemperatureAndMaxTokens(ctx context.Context, systemPrompt string, userPrompt string, model string, temperature float64, maxTokens *int) (string, error)
- GenerateWithStructuredOutputWithTemperatureAndMaxTokens(ctx context.Context, systemPrompt string, userPrompt string, model string, schema map[string]any, temperature float64, maxTokens *int) (string, error)
-}
-
-// NewSlideCreatorExecutor creates a new slide creator executor.
-func NewSlideCreatorExecutor(mcpClient planners.MCPClient, llmProvider planners.LLMProvider, artifactService artifact.Service, mediaClient *media.Client, cfg *config.Config) *SlideCreatorExecutor {
- aioBaseURL := ""
- if cfg != nil {
- aioBaseURL = strings.TrimSpace(cfg.AIOURL)
- }
-
- // Create sandbox helper if MCP client supports it
- var sandboxHelper *agent.SandboxHelper
- if toolCaller, ok := mcpClient.(agent.MCPToolCaller); ok {
- sandboxHelper = agent.NewSandboxHelper(toolCaller)
- }
-
- log.Debug().
- Str("aio_url", aioBaseURL).
- Bool("sandbox_helper_enabled", sandboxHelper != nil).
- Msg("[slide_creator] executor initialized")
-
- return &SlideCreatorExecutor{
- mcpClient: mcpClient,
- llmProvider: llmProvider,
- artifactService: artifactService,
- mediaClient: mediaClient,
- aioBaseURL: aioBaseURL,
- temperature: 0.2,
- sandboxHelper: sandboxHelper,
- }
-}
-
-func (e *SlideCreatorExecutor) generateWithModel(ctx context.Context, prompt string, model string, temperature float64) (string, error) {
- if provider, ok := e.llmProvider.(llmProviderWithTemperature); ok {
- return provider.GenerateWithModelWithTemperature(ctx, prompt, model, temperature)
- }
- return e.llmProvider.GenerateWithModel(ctx, prompt, model)
-}
-
-func (e *SlideCreatorExecutor) generateWithSystemPrompt(ctx context.Context, systemPrompt string, userPrompt string, model string, temperature float64) (string, error) {
- if provider, ok := e.llmProvider.(llmProviderWithTemperature); ok {
- return provider.GenerateWithSystemPromptWithTemperature(ctx, systemPrompt, userPrompt, model, temperature)
- }
- return e.llmProvider.GenerateWithSystemPrompt(ctx, systemPrompt, userPrompt, model)
-}
-
-func (e *SlideCreatorExecutor) generateWithStructuredOutput(ctx context.Context, systemPrompt string, userPrompt string, model string, schema map[string]any, temperature float64) (string, error) {
- if provider, ok := e.llmProvider.(llmProviderWithTemperature); ok {
- return provider.GenerateWithStructuredOutputWithTemperature(ctx, systemPrompt, userPrompt, model, schema, temperature)
- }
- return e.llmProvider.GenerateWithStructuredOutput(ctx, systemPrompt, userPrompt, model, schema)
-}
-
-func (e *SlideCreatorExecutor) generateWithStructuredOutputWithMaxTokens(ctx context.Context, systemPrompt string, userPrompt string, model string, schema map[string]any, temperature float64, maxTokens *int) (string, error) {
- if provider, ok := e.llmProvider.(llmProviderWithTemperatureAndMaxTokens); ok {
- return provider.GenerateWithStructuredOutputWithTemperatureAndMaxTokens(ctx, systemPrompt, userPrompt, model, schema, temperature, maxTokens)
- }
- if provider, ok := e.llmProvider.(llmProviderWithMaxTokens); ok {
- return provider.GenerateWithStructuredOutputWithMaxTokens(ctx, systemPrompt, userPrompt, model, schema, maxTokens)
- }
- return e.llmProvider.GenerateWithStructuredOutput(ctx, systemPrompt, userPrompt, model, schema)
-}
-
-// CanExecute checks if this executor can handle the given action type.
-func (e *SlideCreatorExecutor) CanExecute(action plan.ActionType) bool {
- switch action {
- case plan.ActionTypeToolCall, plan.ActionTypeLLMCall, plan.ActionTypeTransform, plan.ActionTypeArtifactCreate:
- return true
- default:
- return false
- }
-}
-
-// Rollback attempts to undo a step's effects.
-func (e *SlideCreatorExecutor) Rollback(ctx context.Context, step *plan.Step) error {
- return nil
-}
-
-// Execute runs a single step and returns the result.
-func (e *SlideCreatorExecutor) Execute(ctx context.Context, step *plan.Step, input agent.ExecutionInput) (*agent.ExecutionResult, error) {
- log.Debug().Str("step_id", step.ID).Str("action", string(step.Action)).Int("sequence", step.Sequence).Msg("[slide_creator] Execute started")
- switch step.Action {
- case plan.ActionTypeToolCall:
- return e.executeToolCall(ctx, step, input)
- case plan.ActionTypeLLMCall:
- return e.executeLLMCall(ctx, step, input)
- case plan.ActionTypeTransform:
- return e.executeTransform(ctx, step, input)
- case plan.ActionTypeArtifactCreate:
- return e.executeArtifactCreation(ctx, step, input)
- default:
- return &agent.ExecutionResult{Status: status.StatusCompleted}, nil
- }
-}
-
-func getModelFromContext(input agent.ExecutionInput) string {
- if input.PlanContext != nil && strings.TrimSpace(input.PlanContext.Model) != "" {
- return input.PlanContext.Model
- }
- return ""
-}
-
-var _ agent.Executor = (*SlideCreatorExecutor)(nil)
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/extractors.go b/services/response-api/internal/domain/agent/planners/slide_creator/steps/extractors.go
deleted file mode 100644
index fa741d4e..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/extractors.go
+++ /dev/null
@@ -1,223 +0,0 @@
-package steps
-
-import (
- "encoding/json"
- "fmt"
- "io/fs"
- "os"
- "path/filepath"
- "strings"
-
- "jan-server/services/response-api/internal/domain/agent"
-)
-
-func extractDeckPlanFromOutputs(input agent.ExecutionInput) (*DeckPlan, error) {
- outputs := make([]json.RawMessage, 0, len(input.AccumulatedOutputs)+1)
- outputs = append(outputs, input.AccumulatedOutputs...)
- if len(input.PreviousOutput) > 0 {
- outputs = append(outputs, input.PreviousOutput)
- }
-
- for i := len(outputs) - 1; i >= 0; i-- {
- var payload map[string]any
- if err := json.Unmarshal(outputs[i], &payload); err != nil {
- continue
- }
- payloadType, _ := payload["type"].(string)
- if payloadType != "slide_plan" && payloadType != "normalized_plan" {
- continue
- }
- if planAny, ok := payload["plan"]; ok {
- raw, _ := json.Marshal(planAny)
- var plan DeckPlan
- if err := json.Unmarshal(raw, &plan); err == nil {
- return &plan, nil
- }
- }
- if content, ok := payload["content"].(string); ok && strings.TrimSpace(content) != "" {
- if plan, err := parseDeckPlan(content); err == nil {
- return &plan, nil
- }
- }
- }
- return nil, fmt.Errorf("plan not found in outputs")
-}
-
-func extractNormalizedPlan(input agent.ExecutionInput) (*DeckPlan, error) {
- outputs := make([]json.RawMessage, 0, len(input.AccumulatedOutputs)+1)
- outputs = append(outputs, input.AccumulatedOutputs...)
- if len(input.PreviousOutput) > 0 {
- outputs = append(outputs, input.PreviousOutput)
- }
-
- for i := len(outputs) - 1; i >= 0; i-- {
- var payload map[string]any
- if err := json.Unmarshal(outputs[i], &payload); err != nil {
- continue
- }
- payloadType, _ := payload["type"].(string)
- if payloadType != "normalized_plan" {
- continue
- }
- if planAny, ok := payload["plan"]; ok {
- raw, _ := json.Marshal(planAny)
- var plan DeckPlan
- if err := json.Unmarshal(raw, &plan); err == nil {
- return &plan, nil
- }
- }
- if content, ok := payload["content"].(string); ok && strings.TrimSpace(content) != "" {
- if plan, err := parseDeckPlan(content); err == nil {
- return &plan, nil
- }
- }
- }
-
- return extractDeckPlanFromOutputs(input)
-}
-
-func extractTemplateSelection(input agent.ExecutionInput) TemplateSelection {
- outputs := make([]json.RawMessage, 0, len(input.AccumulatedOutputs)+1)
- outputs = append(outputs, input.AccumulatedOutputs...)
- if len(input.PreviousOutput) > 0 {
- outputs = append(outputs, input.PreviousOutput)
- }
-
- for i := len(outputs) - 1; i >= 0; i-- {
- var payload TemplateSelection
- if err := json.Unmarshal(outputs[i], &payload); err != nil {
- continue
- }
- if payload.Type == "template_selection" {
- return payload
- }
- }
-
- return TemplateSelection{
- Type: "template_selection",
- TemplateDir: "standards",
- Source: "embedded",
- }
-}
-
-func resolveTemplateSources(selection TemplateSelection) (fs.FS, string, fs.FS, string, error) {
- if selection.TemplateDir == "" {
- selection.TemplateDir = "standards"
- }
-
- if selection.Source == "filesystem" || filepath.IsAbs(selection.TemplateDir) {
- templateFS := os.DirFS(selection.TemplateDir)
- templateDir := "."
- fallbackDir := strings.TrimSpace(selection.FallbackDir)
- if fallbackDir == "" {
- fallbackDir = filepath.Join(filepath.Dir(selection.TemplateDir), "standards")
- }
- if stat, err := os.Stat(fallbackDir); err == nil && stat.IsDir() {
- return templateFS, templateDir, os.DirFS(fallbackDir), ".", nil
- }
- return templateFS, templateDir, embeddedTemplatesRoot(), "standards", nil
- }
-
- return embeddedTemplatesRoot(), selection.TemplateDir, embeddedTemplatesRoot(), "standards", nil
-}
-
-func extractOutputDir(input agent.ExecutionInput) string {
- outputs := make([]json.RawMessage, 0, len(input.AccumulatedOutputs)+1)
- outputs = append(outputs, input.AccumulatedOutputs...)
- if len(input.PreviousOutput) > 0 {
- outputs = append(outputs, input.PreviousOutput)
- }
-
- for i := len(outputs) - 1; i >= 0; i-- {
- var payload map[string]any
- if err := json.Unmarshal(outputs[i], &payload); err != nil {
- continue
- }
- if outDir, ok := payload["output_dir"].(string); ok && strings.TrimSpace(outDir) != "" {
- return outDir
- }
- }
- return ""
-}
-
-func outputDirForPlan(input agent.ExecutionInput) string {
- responseID := "slide_creator"
- if input.PlanContext != nil && strings.TrimSpace(input.PlanContext.ResponseID) != "" {
- responseID = input.PlanContext.ResponseID
- }
- return filepath.Join(os.TempDir(), "jan_slide_creator", responseID)
-}
-
-func extractDeckTheme(input agent.ExecutionInput) (DeckTheme, bool) {
- outputs := make([]json.RawMessage, 0, len(input.AccumulatedOutputs)+1)
- outputs = append(outputs, input.AccumulatedOutputs...)
- if len(input.PreviousOutput) > 0 {
- outputs = append(outputs, input.PreviousOutput)
- }
-
- for i := len(outputs) - 1; i >= 0; i-- {
- var payload map[string]any
- if err := json.Unmarshal(outputs[i], &payload); err != nil {
- continue
- }
- if payloadType, _ := payload["type"].(string); payloadType != "deck_theme" {
- continue
- }
- raw, _ := json.Marshal(payload)
- var theme DeckTheme
- if err := json.Unmarshal(raw, &theme); err == nil {
- return theme, true
- }
- }
- return DeckTheme{}, false
-}
-
-func extractDeckTitle(input agent.ExecutionInput) string {
- if theme, ok := extractDeckTheme(input); ok {
- return strings.TrimSpace(theme.Title)
- }
- return ""
-}
-
-func extractSlidePlanDraft(input agent.ExecutionInput, slideIndex int) (SlidePlanDraft, bool) {
- if slideIndex <= 0 {
- return SlidePlanDraft{}, false
- }
- drafts := collectSlidePlanDrafts(input)
- if draft, ok := drafts[slideIndex]; ok {
- return draft, true
- }
- return SlidePlanDraft{}, false
-}
-
-func collectSlidePlanDrafts(input agent.ExecutionInput) map[int]SlidePlanDraft {
- outputs := make([]json.RawMessage, 0, len(input.AccumulatedOutputs)+1)
- outputs = append(outputs, input.AccumulatedOutputs...)
- if len(input.PreviousOutput) > 0 {
- outputs = append(outputs, input.PreviousOutput)
- }
-
- drafts := map[int]SlidePlanDraft{}
- for _, output := range outputs {
- if len(output) == 0 {
- continue
- }
- var payload map[string]any
- if err := json.Unmarshal(output, &payload); err != nil {
- continue
- }
- if payloadType, _ := payload["type"].(string); payloadType != "slide_plan_slide" {
- continue
- }
- raw, _ := json.Marshal(payload)
- var draft SlidePlanDraft
- if err := json.Unmarshal(raw, &draft); err != nil {
- continue
- }
- if draft.SlideIndex <= 0 {
- continue
- }
- drafts[draft.SlideIndex] = draft
- }
- return drafts
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/image_search.go b/services/response-api/internal/domain/agent/planners/slide_creator/steps/image_search.go
deleted file mode 100644
index 90e479e7..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/image_search.go
+++ /dev/null
@@ -1,401 +0,0 @@
-package steps
-
-import (
- "context"
- "encoding/json"
- "strings"
-
- "jan-server/services/response-api/internal/domain/agent"
- "jan-server/services/response-api/internal/domain/status"
- "jan-server/services/response-api/internal/domain/tool"
-
- "github.com/rs/zerolog/log"
-)
-
-const perSlideImageSearchDefaultNum = 6
-
-func (e *SlideCreatorExecutor) executeSlideImageSearch(ctx context.Context, params map[string]interface{}, input agent.ExecutionInput) (*agent.ExecutionResult, error) {
- slideIndex, _ := parseIntFromInterface(params["slide_index"])
- if slideIndex <= 0 {
- return buildSkippedImageSearchResult(slideIndex, "invalid_slide_index"), nil
- }
-
- draft, ok := extractSlidePlanDraft(input, slideIndex)
- deckTitle := extractDeckTitle(input)
- if ok {
- slide := draft.Slide
- if slideHasImage(slide) {
- return buildSkippedImageSearchResult(slideIndex, "already_has_image"), nil
- }
- if draft.ImageRequired != nil && !*draft.ImageRequired {
- return buildSkippedImageSearchResult(slideIndex, "image_not_required"), nil
- }
- if !slideNeedsImage(slide) && (draft.ImageRequired == nil || !*draft.ImageRequired) {
- return buildSkippedImageSearchResult(slideIndex, "layout_not_image"), nil
- }
- query := strings.TrimSpace(draft.ImageQuery)
- if query == "" {
- query = buildSlideImageQuery(deckTitle, slide)
- }
- if query == "" {
- return buildSkippedImageSearchResult(slideIndex, "empty_query"), nil
- }
- return e.executeImageSearch(ctx, input, slideIndex, query, params)
- }
-
- plan, err := extractDeckPlanFromOutputs(input)
- if err != nil {
- return buildSkippedImageSearchResult(slideIndex, "plan_missing"), nil
- }
- arrayIndex := slideIndex - 1
- if arrayIndex < 0 || arrayIndex >= len(plan.Slides) {
- return buildSkippedImageSearchResult(slideIndex, "slide_out_of_range"), nil
- }
-
- slide := plan.Slides[arrayIndex]
- if slideHasImage(slide) {
- return buildSkippedImageSearchResult(slideIndex, "already_has_image"), nil
- }
- if !slideNeedsImage(slide) {
- return buildSkippedImageSearchResult(slideIndex, "layout_not_image"), nil
- }
-
- query := buildSlideImageQuery(plan.Title, slide)
- if query == "" {
- return buildSkippedImageSearchResult(slideIndex, "empty_query"), nil
- }
-
- return e.executeImageSearch(ctx, input, slideIndex, query, params)
-}
-
-func (e *SlideCreatorExecutor) executeImageSearch(ctx context.Context, input agent.ExecutionInput, slideIndex int, query string, params map[string]interface{}) (*agent.ExecutionResult, error) {
- num := perSlideImageSearchDefaultNum
- if parsed, ok := parseIntFromInterface(params["num"]); ok && parsed > 0 {
- num = parsed
- }
- colorScheme := strings.TrimSpace(stringValue(params, "color_scheme"))
- style := strings.TrimSpace(stringValue(params, "style"))
- query = decorateImageQuery(query, colorScheme, style)
-
- args := map[string]interface{}{
- "q": query,
- "num": num,
- }
- if gl, ok := params["gl"].(string); ok && strings.TrimSpace(gl) != "" {
- args["gl"] = strings.TrimSpace(gl)
- }
- if hl, ok := params["hl"].(string); ok && strings.TrimSpace(hl) != "" {
- args["hl"] = strings.TrimSpace(hl)
- }
-
- if e.mcpClient == nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "MCP_CLIENT_MISSING",
- Message: "mcp client not configured",
- Severity: status.ErrorSeverityFatal,
- },
- }, nil
- }
-
- callReq := tool.CallRequest{
- Name: "image_search",
- Arguments: args,
- }
- if input.PlanContext != nil {
- callReq.RequestID = input.PlanContext.ResponseID
- callReq.ConversationID = input.PlanContext.ConversationID
- callReq.UserID = input.PlanContext.UserID
- }
-
- log.Debug().Int("slide_index", slideIndex).Str("query", query).Msg("[slide_creator] image search per slide")
- result, err := e.mcpClient.CallTool(ctx, callReq)
- if err != nil {
- log.Warn().Err(err).Int("slide_index", slideIndex).Msg("[slide_creator] image search failed")
- return buildSkippedImageSearchResult(slideIndex, "tool_call_failed"), nil
- }
- if result == nil {
- return buildSkippedImageSearchResult(slideIndex, "tool_empty"), nil
- }
- if result.IsError {
- log.Warn().Int("slide_index", slideIndex).Msg("[slide_creator] image search returned error")
- return buildSkippedImageSearchResult(slideIndex, "tool_error"), nil
- }
-
- output := map[string]interface{}{
- "type": "image_search_slide",
- "slide_index": slideIndex,
- "query": query,
- "tool_name": "image_search",
- "content": result.Content,
- "is_error": false,
- }
- outputBytes, _ := json.Marshal(output)
-
- return &agent.ExecutionResult{
- Status: status.StatusCompleted,
- Output: outputBytes,
- }, nil
-}
-
-func buildSlideImageQuery(deckTitle string, slide SlidePlan) string {
- parts := []string{}
- if title := strings.TrimSpace(deckTitle); title != "" {
- parts = append(parts, title)
- }
- if title := strings.TrimSpace(slide.Title); title != "" {
- parts = append(parts, title)
- }
- if subtitle := strings.TrimSpace(slide.Subtitle); subtitle != "" {
- parts = append(parts, subtitle)
- }
- for _, bullet := range slide.Bullets {
- bullet = strings.TrimSpace(bullet)
- if bullet != "" {
- parts = append(parts, bullet)
- }
- if len(parts) >= 6 {
- break
- }
- }
-
- query := strings.Join(parts, " ")
- query = strings.TrimSpace(query)
- if len(query) > 200 {
- query = query[:200]
- }
- return query
-}
-
-func decorateImageQuery(query string, colorScheme string, style string) string {
- query = strings.TrimSpace(query)
- hints := buildImageSearchHints(colorScheme, style)
- if hints == "" {
- return query
- }
- if query == "" {
- if len(hints) > 200 {
- return hints[:200]
- }
- return hints
- }
- const maxLen = 200
- decorated := strings.TrimSpace(query + " " + hints)
- if len(decorated) <= maxLen {
- return decorated
- }
- if len(hints) >= maxLen-1 {
- return hints[:maxLen]
- }
- allowedBaseLen := maxLen - len(hints) - 1
- if allowedBaseLen <= 0 {
- return hints
- }
- base := query
- if len(base) > allowedBaseLen {
- base = strings.TrimSpace(base[:allowedBaseLen])
- }
- if base == "" {
- return hints
- }
- return strings.TrimSpace(base + " " + hints)
-}
-
-func buildImageSearchHints(colorScheme string, style string) string {
- parts := []string{}
- if isBrightColorScheme(colorScheme) {
- parts = append(parts, "bright", "colorful", "light background", "high contrast", "well lit")
- }
-
- style = strings.ToLower(strings.TrimSpace(style))
- switch {
- case strings.Contains(style, "modern"):
- parts = append(parts, "modern", "clean")
- case strings.Contains(style, "minimal"):
- parts = append(parts, "minimal", "clean")
- case strings.Contains(style, "futuristic"):
- parts = append(parts, "futuristic", "sleek")
- case strings.Contains(style, "corporate"):
- parts = append(parts, "corporate", "professional")
- }
-
- parts = append(parts, "no text", "no watermark")
- if len(parts) == 0 {
- return ""
- }
-
- seen := map[string]struct{}{}
- out := make([]string, 0, len(parts))
- for _, part := range parts {
- part = strings.TrimSpace(part)
- if part == "" {
- continue
- }
- if _, ok := seen[part]; ok {
- continue
- }
- seen[part] = struct{}{}
- out = append(out, part)
- }
- return strings.Join(out, " ")
-}
-
-func slideNeedsImage(slide SlidePlan) bool {
- layout := strings.ToLower(strings.TrimSpace(slide.Layout))
- if layout == "" {
- layout = chooseLayout(slide)
- }
- if strings.Contains(layout, "image") {
- return true
- }
- return layout == "split" || layout == "hero"
-}
-
-func slideHasImage(slide SlidePlan) bool {
- for _, img := range slide.Images {
- if strings.TrimSpace(img.Src) != "" {
- return true
- }
- }
- return false
-}
-
-func mergeSlideImagesFromSearch(plan DeckPlan, input agent.ExecutionInput) DeckPlan {
- perSlide := collectPerSlideImageAssets(input)
- if len(perSlide) == 0 {
- return plan
- }
-
- for i := range plan.Slides {
- slideIndex := i + 1
- slide := &plan.Slides[i]
- if slideHasImage(*slide) || !slideNeedsImage(*slide) {
- continue
- }
-
- // Filter assets to only valid images
- assets := FilterValidImages(perSlide[slideIndex])
- if len(assets) == 0 {
- continue
- }
-
- // Try each asset until we find a valid image
- var validImage SlideImage
- for _, asset := range assets {
- image := slideImageFromAsset(asset, slide.Title)
- if strings.TrimSpace(image.Src) != "" {
- validImage = image
- break
- }
- }
-
- if strings.TrimSpace(validImage.Src) == "" {
- continue
- }
- slide.Images = []SlideImage{validImage}
- }
-
- return plan
-}
-
-func collectPerSlideImageAssets(input agent.ExecutionInput) map[int][]map[string]any {
- outputs := make([]json.RawMessage, 0, len(input.AccumulatedOutputs)+1)
- outputs = append(outputs, input.AccumulatedOutputs...)
- if len(input.PreviousOutput) > 0 {
- outputs = append(outputs, input.PreviousOutput)
- }
-
- results := map[int][]map[string]any{}
- for _, output := range outputs {
- if len(output) == 0 {
- continue
- }
- var payload map[string]any
- if err := json.Unmarshal(output, &payload); err != nil {
- continue
- }
- if payloadType, _ := payload["type"].(string); payloadType != "image_search_slide" {
- continue
- }
- slideIndex, _ := parseIntFromInterface(payload["slide_index"])
- if slideIndex <= 0 {
- continue
- }
- assets := extractImageAssetsFromOutput(output)
- if len(assets) == 0 {
- continue
- }
- results[slideIndex] = assets
- }
-
- return results
-}
-
-func slideImageFromAsset(asset map[string]any, fallbackAlt string) SlideImage {
- // Use PreferredImageURL which validates and sanitizes the URL
- src := PreferredImageURL(asset)
- if src == "" {
- // Fallback to basic extraction if preferred fails
- src = assetImageURL(asset)
- if strings.TrimSpace(src) == "" {
- return SlideImage{}
- }
- // Validate the fallback URL
- result := ValidateImageURL(src)
- if !result.IsValid {
- return SlideImage{}
- }
- src = SanitizeImageURL(src)
- }
-
- title := strings.TrimSpace(firstString(asset, "title", "altText", "alt"))
- alt := title
- if alt == "" {
- alt = strings.TrimSpace(fallbackAlt)
- }
- // Ensure alt text is not empty
- if alt == "" {
- alt = "Slide image"
- }
-
- image := SlideImage{
- Src: src,
- Alt: alt,
- }
- if title != "" {
- image.Caption = title
- }
- return image
-}
-
-func assetImageURL(asset map[string]any) string {
- if asset == nil {
- return ""
- }
- if img, ok := asset["imageUrl"].(string); ok && strings.TrimSpace(img) != "" {
- return img
- }
- if thumb, ok := asset["thumbnailUrl"].(string); ok && strings.TrimSpace(thumb) != "" {
- return thumb
- }
- if source, ok := asset["source"].(map[string]any); ok {
- if url, ok := source["url"].(string); ok && strings.TrimSpace(url) != "" {
- return url
- }
- }
- return ""
-}
-
-func buildSkippedImageSearchResult(slideIndex int, reason string) *agent.ExecutionResult {
- output, _ := json.Marshal(map[string]interface{}{
- "type": "image_search_slide",
- "slide_index": slideIndex,
- "skipped": true,
- "reason": reason,
- })
- return &agent.ExecutionResult{
- Status: status.StatusCompleted,
- Output: output,
- }
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/image_validate.go b/services/response-api/internal/domain/agent/planners/slide_creator/steps/image_validate.go
deleted file mode 100644
index c35e534c..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/image_validate.go
+++ /dev/null
@@ -1,282 +0,0 @@
-package steps
-
-import (
- "net/url"
- "strings"
-)
-
-// blockedImageDomains contains domains known to block hotlinking or have issues.
-var blockedImageDomains = map[string]bool{
- "facebook.com": true,
- "fbcdn.net": true,
- "instagram.com": true,
- "twitter.com": true,
- "x.com": true,
- "linkedin.com": true,
- "licdn.com": true,
- "pinterest.com": true,
- "pinimg.com": true,
- "tiktok.com": true,
- "snapchat.com": true,
- "reddit.com": true,
- "redd.it": true,
- "discord.com": true,
- "discordapp.com": true,
- "whatsapp.com": true,
- "telegram.org": true,
- "gstatic.com": true, // Google's CDN often has auth issues
- "googleusercontent": true, // Can have short-lived URLs
-}
-
-// ValidImageExtensions contains common image file extensions.
-var validImageExtensions = map[string]bool{
- ".jpg": true,
- ".jpeg": true,
- ".png": true,
- ".gif": true,
- ".webp": true,
- ".svg": true,
- ".bmp": true,
- ".ico": true,
-}
-
-// ImageValidationResult contains the result of image URL validation.
-type ImageValidationResult struct {
- IsValid bool
- URL string
- ErrorReason string
- IsWarning bool
- WarningMsg string
-}
-
-// ValidateImageURL checks if an image URL is valid and usable.
-func ValidateImageURL(imageURL string) ImageValidationResult {
- imageURL = strings.TrimSpace(imageURL)
-
- // Empty URL
- if imageURL == "" {
- return ImageValidationResult{
- IsValid: false,
- ErrorReason: "empty_url",
- }
- }
-
- // Parse URL
- parsed, err := url.Parse(imageURL)
- if err != nil {
- return ImageValidationResult{
- IsValid: false,
- URL: imageURL,
- ErrorReason: "invalid_url_format",
- }
- }
-
- // Must be HTTP or HTTPS
- scheme := strings.ToLower(parsed.Scheme)
- if scheme != "http" && scheme != "https" {
- return ImageValidationResult{
- IsValid: false,
- URL: imageURL,
- ErrorReason: "invalid_scheme",
- }
- }
-
- // Must have a host
- if parsed.Host == "" {
- return ImageValidationResult{
- IsValid: false,
- URL: imageURL,
- ErrorReason: "missing_host",
- }
- }
-
- // Check for blocked domains
- host := strings.ToLower(parsed.Host)
- for blockedDomain := range blockedImageDomains {
- if strings.Contains(host, blockedDomain) {
- return ImageValidationResult{
- IsValid: false,
- URL: imageURL,
- ErrorReason: "blocked_domain",
- }
- }
- }
-
- // Check for data URLs (base64)
- if strings.HasPrefix(strings.ToLower(imageURL), "data:") {
- return ImageValidationResult{
- IsValid: false,
- URL: imageURL,
- ErrorReason: "data_url_not_supported",
- }
- }
-
- // Check URL length (very long URLs are often problematic)
- if len(imageURL) > 2048 {
- return ImageValidationResult{
- IsValid: false,
- URL: imageURL,
- ErrorReason: "url_too_long",
- }
- }
-
- // Check for placeholder or test images
- lowerURL := strings.ToLower(imageURL)
- placeholderPatterns := []string{
- "placeholder",
- "example.com",
- "example.org",
- "test.com",
- "localhost",
- "127.0.0.1",
- "0.0.0.0",
- "1x1",
- "pixel.gif",
- "spacer.gif",
- "blank.gif",
- }
- for _, pattern := range placeholderPatterns {
- if strings.Contains(lowerURL, pattern) {
- return ImageValidationResult{
- IsValid: false,
- URL: imageURL,
- ErrorReason: "placeholder_image",
- }
- }
- }
-
- // Success with optional warnings
- result := ImageValidationResult{
- IsValid: true,
- URL: imageURL,
- }
-
- // Add warning for HTTP (not HTTPS)
- if scheme == "http" {
- result.IsWarning = true
- result.WarningMsg = "http_not_secure"
- }
-
- // Add warning if URL doesn't look like an image path
- path := strings.ToLower(parsed.Path)
- hasImageExtension := false
- for ext := range validImageExtensions {
- if strings.HasSuffix(path, ext) {
- hasImageExtension = true
- break
- }
- }
-
- // Check for common image CDN patterns
- imagePatterns := []string{
- "/image",
- "/img",
- "/photo",
- "/media",
- "/upload",
- "/cdn",
- "/static",
- "/assets",
- }
- looksLikeImage := hasImageExtension
- if !looksLikeImage {
- for _, pattern := range imagePatterns {
- if strings.Contains(path, pattern) {
- looksLikeImage = true
- break
- }
- }
- }
-
- if !looksLikeImage && !result.IsWarning {
- result.IsWarning = true
- result.WarningMsg = "may_not_be_image"
- }
-
- return result
-}
-
-// FilterValidImages filters a list of image assets, keeping only valid ones.
-func FilterValidImages(assets []map[string]any) []map[string]any {
- valid := make([]map[string]any, 0, len(assets))
-
- for _, asset := range assets {
- imageURL := assetImageURL(asset)
- result := ValidateImageURL(imageURL)
- if result.IsValid {
- valid = append(valid, asset)
- }
- }
-
- return valid
-}
-
-// FilterValidSlideImages filters SlideImage list, keeping only valid ones.
-func FilterValidSlideImages(images []SlideImage) []SlideImage {
- valid := make([]SlideImage, 0, len(images))
-
- for _, img := range images {
- result := ValidateImageURL(img.Src)
- if result.IsValid {
- valid = append(valid, img)
- }
- }
-
- return valid
-}
-
-// SanitizeImageURL cleans up an image URL.
-func SanitizeImageURL(imageURL string) string {
- imageURL = strings.TrimSpace(imageURL)
-
- // Remove common tracking parameters
- parsed, err := url.Parse(imageURL)
- if err != nil {
- return imageURL
- }
-
- // Clean up query parameters - remove tracking params
- query := parsed.Query()
- trackingParams := []string{
- "utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content",
- "fbclid", "gclid", "ref", "source", "tracking_id",
- }
- for _, param := range trackingParams {
- query.Del(param)
- }
- parsed.RawQuery = query.Encode()
-
- return parsed.String()
-}
-
-// PreferredImageURL returns the best available image URL from an asset.
-// Prefers full-size imageUrl over thumbnailUrl for final rendering.
-func PreferredImageURL(asset map[string]any) string {
- // For rendering, prefer full-size image
- if img, ok := asset["imageUrl"].(string); ok && strings.TrimSpace(img) != "" {
- result := ValidateImageURL(img)
- if result.IsValid {
- return SanitizeImageURL(img)
- }
- }
-
- // Fall back to thumbnail
- if thumb, ok := asset["thumbnailUrl"].(string); ok && strings.TrimSpace(thumb) != "" {
- result := ValidateImageURL(thumb)
- if result.IsValid {
- return SanitizeImageURL(thumb)
- }
- }
-
- // Try source URL
- if source, ok := asset["source"].(map[string]any); ok {
- if url, ok := source["url"].(string); ok && strings.TrimSpace(url) != "" {
- result := ValidateImageURL(url)
- if result.IsValid {
- return SanitizeImageURL(url)
- }
- }
- }
-
- return ""
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/llm_steps.go b/services/response-api/internal/domain/agent/planners/slide_creator/steps/llm_steps.go
deleted file mode 100644
index 4e66535c..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/llm_steps.go
+++ /dev/null
@@ -1,292 +0,0 @@
-package steps
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "strings"
-
- "jan-server/services/response-api/internal/domain/agent"
- "jan-server/services/response-api/internal/domain/agent/planners/slide_creator/schemas"
- "jan-server/services/response-api/internal/domain/plan"
- "jan-server/services/response-api/internal/domain/status"
-
- "github.com/rs/zerolog/log"
-)
-
-const dataBankPrompt = `
-You are the Data Bank Extractor for a slide-deck generation system.
-Given BRIEF, ASSETS, and RESEARCH, extract concrete facts and chart-ready datasets.
-
-OUTPUT FORMAT (STRICT):
-- Return ONLY valid JSON that matches the provided schema.
-- Do NOT wrap in markdown, code fences, or commentary.
-- Do NOT include any extra keys outside the schema.
-
-RULES:
-- Facts must be atomic, sourced, and include a date when available.
-- Datasets must be ready to use in charts (labels + numeric series).
-- Use ONLY data that appears in the provided research context.
-- If data is missing, leave the dataset list empty instead of inventing values.
-`
-
-const (
- dataBankImageAssetLimit = 2
- dataBankImageAssetLimitSingleSlide = 1
-)
-
-func (e *SlideCreatorExecutor) executeLLMCall(ctx context.Context, step *plan.Step, input agent.ExecutionInput) (*agent.ExecutionResult, error) {
- var params map[string]interface{}
- if err := json.Unmarshal(input.StepParams, ¶ms); err != nil {
- log.Error().Err(err).Msg("[slide_creator] failed to parse LLM call parameters")
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{Message: err.Error(), Severity: status.ErrorSeverityRetryable},
- }, nil
- }
-
- if requiresUser, ok := params["requires_user"].(bool); ok && requiresUser {
- prompt, _ := params["prompt"].(string)
- optionsCount := 0
- if rawCount, ok := params["options_count"].(float64); ok {
- optionsCount = int(rawCount)
- }
-
- options := make([]string, 0, optionsCount)
- for i := 0; i < optionsCount; i++ {
- options = append(options, fmt.Sprintf("option_%d", i+1))
- }
-
- outputBytes, _ := json.Marshal(map[string]interface{}{
- "status": "waiting_for_user",
- "prompt": prompt,
- "options": options,
- "options_count": optionsCount,
- })
-
- return &agent.ExecutionResult{
- Status: status.StatusCompleted,
- Output: outputBytes,
- RequiresUser: true,
- UserPrompt: &prompt,
- }, nil
- }
-
- action, _ := params["action"].(string)
- switch action {
- case "select_templates":
- return e.executeSelectTemplates(ctx, params, input)
- case "deck_theme":
- return e.executeDeckTheme(ctx, params, input)
- case "slide_plan":
- return e.executeSlidePlan(ctx, params, input)
- case "slide_plan_slide":
- return e.executeSlidePlanSlide(ctx, params, input)
- case "reasoning":
- return e.executeOutlineReasoning(ctx, params, input)
- case "data_bank":
- return e.executeDataBank(ctx, params, input)
- default:
- return e.executeOutlineReasoning(ctx, params, input)
- }
-}
-
-func (e *SlideCreatorExecutor) executeOutlineReasoning(ctx context.Context, params map[string]interface{}, input agent.ExecutionInput) (*agent.ExecutionResult, error) {
- description, _ := params["description"].(string)
- brief, _ := params["brief"].(string)
- config, _ := params["config"].(map[string]interface{})
- numSlides, _ := parseIntFromInterface(config["num_slides"])
- contextData := buildAccumulatedContext(input)
- if strings.TrimSpace(contextData) == "" {
- contextData = "[No previous context available]"
- }
- if numSlides == 1 && len(contextData) > slidePlanContextPerSlideLimit {
- contextData = truncateWithSuffix(contextData, slidePlanContextPerSlideLimit)
- }
- singleSlideNote := ""
- if numSlides == 1 {
- singleSlideNote = "\n\nFor single-slide requests, avoid listing full URLs; summarize sources by publisher name only."
- }
- prompt := fmt.Sprintf(
- `You are creating a detailed presentation outline. %s
-
-USER REQUEST:
-%s
-
-RESEARCH DATA:
-%s%s
-
-OUTLINE REQUIREMENTS (CRITICAL - must follow):
-1. RICH DATA: Every slide MUST include specific statistics, numbers, percentages, or metrics. NO vague statements.
- - BAD: "Sales increased significantly"
- - GOOD: "Sales grew 47%% from $2.3M to $3.4M in Q3 2024"
-
-2. DETAILED BULLETS: Each bullet point should be 2-3 sentences with supporting evidence.
- - BAD: "Lions hunt at night"
- - GOOD: "Lions hunt primarily between 8PM-6AM (78%% of kills), using darkness to offset their 30%% slower sprint speed vs prey. Studies show success rates drop to 17%% in daylight vs 32%% at night."
-
-3. DATA VISUALIZATIONS: Include at least 2-3 slides with:
- - Charts: Specify type (bar/line/pie), exact categories and values
- Format: "CHART: [type] - [title] - Categories: [X, Y, Z] - Values: [10, 20, 30]"
- - Tables: Include full data with headers and rows
- Format: "TABLE: [title] | Col1 | Col2 | Col3 | Row1: val1, val2, val3 | Row2: ..."
-
-4. IMAGE SUGGESTIONS: For each slide that needs visuals, suggest:
- - "IMAGE: [description of ideal image, specific subject, composition]"
-
-5. KEY METRICS: Include a "KEY STATS" section on appropriate slides:
- - Format: "STATS: [Metric1: Value1] | [Metric2: Value2] | [Metric3: Value3]"
-
-6. STRUCTURE: For each slide include:
- - Clear title (action-oriented, not generic)
- - 4-6 detailed bullet points with data
- - Visual element suggestion (chart/table/image/stats)
-
-OUTPUT: Plain text outline with slide headers and detailed content. Be comprehensive and data-rich.`,
- description,
- brief,
- contextData,
- singleSlideNote,
- )
-
- log.Debug().
- Str("plan_id", planContextValue(input, "plan_id")).
- Str("prompt", sanitizeForLog(prompt)).
- Msg("[slide_creator] outline prompt")
-
- model := getModelFromContext(input)
- if e.llmProvider == nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "LLM_PROVIDER_MISSING",
- Message: "LLM provider not configured",
- Severity: status.ErrorSeverityFatal,
- },
- }, nil
- }
-
- response, err := e.generateWithModel(ctx, prompt, model, 0.3)
- if err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "LLM_CALL_FAILED",
- Message: fmt.Sprintf("LLM generation failed: %v", err),
- Severity: status.ErrorSeverityRetryable,
- },
- }, nil
- }
-
- output := map[string]interface{}{
- "type": "llm_response",
- "action": "reasoning",
- "description": description,
- "content": response,
- }
- outputBytes, _ := json.Marshal(output)
- log.Debug().
- Int("response_length", len(response)).
- Msg("[slide_creator] reasoning completed")
-
- return &agent.ExecutionResult{
- Status: status.StatusCompleted,
- Output: outputBytes,
- }, nil
-}
-
-func (e *SlideCreatorExecutor) executeDataBank(ctx context.Context, params map[string]interface{}, input agent.ExecutionInput) (*agent.ExecutionResult, error) {
- log.Debug().Msg("[slide_creator] executeDataBank started")
- outlineText := strings.TrimSpace(collectOutlineText(input))
- if outlineText != "" && !outlineNeedsDataBank(outlineText) {
- outputBytes, _ := json.Marshal(map[string]interface{}{
- "type": "data_bank",
- "skipped": true,
- "reason": "outline_no_data_markers",
- })
- return &agent.ExecutionResult{
- Status: status.StatusCompleted,
- Output: outputBytes,
- }, nil
- }
- config, _ := params["config"].(map[string]interface{})
- numSlides, _ := parseIntFromInterface(config["num_slides"])
- contextData := buildAccumulatedContext(input)
- if numSlides == 1 && len(contextData) > slidePlanContextPerSlideLimit {
- contextData = truncateWithSuffix(contextData, slidePlanContextPerSlideLimit)
- }
- brief, _ := params["brief"].(string)
- assetLimit := dataBankImageAssetLimit
- if numSlides == 1 {
- assetLimit = dataBankImageAssetLimitSingleSlide
- }
- assets := limitImageAssets(collectImageAssets(input), assetLimit)
- assetsJSON, _ := json.Marshal(compactImageAssetsForPrompt(assets))
-
- systemPrompt := dataBankPrompt
- userPrompt := fmt.Sprintf("BRIEF:\n%s\n\nRESEARCH:\n%s\n\nASSETS AVAILABLE:\n%s", brief, contextData, string(assetsJSON))
-
- log.Debug().
- Str("plan_id", planContextValue(input, "plan_id")).
- Str("system_prompt", sanitizeForLog(systemPrompt)).
- Str("user_prompt", sanitizeForLog(userPrompt)).
- Msg("[slide_creator] data bank prompt")
-
- model := getModelFromContext(input)
- if e.llmProvider == nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "LLM_PROVIDER_MISSING",
- Message: "LLM provider not configured",
- Severity: status.ErrorSeverityFatal,
- },
- }, nil
- }
-
- schema := schemas.DataBankSchema
-
- var lastErr error
- var dataBank schemas.DataBank
- for attempt := 1; attempt <= 3; attempt++ {
- result, err := e.generateWithStructuredOutput(ctx, systemPrompt, userPrompt, model, schema, 0.1)
- if err != nil {
- lastErr = err
- continue
- }
- if err := json.Unmarshal([]byte(result), &dataBank); err != nil {
- lastErr = err
- continue
- }
- lastErr = nil
- break
- }
-
- if lastErr != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "PARSE_ERROR",
- Message: fmt.Sprintf("Failed to parse data bank after retries: %v", lastErr),
- Severity: status.ErrorSeverityRetryable,
- },
- }, nil
- }
-
- contentBytes, _ := json.Marshal(dataBank)
- output := map[string]interface{}{
- "type": "data_bank",
- "data": dataBank,
- "content": string(contentBytes),
- }
- outputBytes, _ := json.Marshal(output)
- log.Debug().
- Int("facts", len(dataBank.Facts)).
- Int("datasets", len(dataBank.Datasets)).
- Msg("[slide_creator] executeDataBank completed")
-
- return &agent.ExecutionResult{
- Status: status.StatusCompleted,
- Output: outputBytes,
- }, nil
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/log_utils.go b/services/response-api/internal/domain/agent/planners/slide_creator/steps/log_utils.go
deleted file mode 100644
index 254de60c..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/log_utils.go
+++ /dev/null
@@ -1,28 +0,0 @@
-package steps
-
-import "regexp"
-
-var (
- reEmail = regexp.MustCompile(`(?i)[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,}`)
- rePhone = regexp.MustCompile(`\+?\d[\d\s().-]{7,}\d`)
- reBearer = regexp.MustCompile(`(?i)bearer\s+[a-z0-9._\-\~+/=]+`)
- reAuthHeader = regexp.MustCompile(`(?i)authorization\s*[:=]\s*[^\s]+`)
- reKeyValue = regexp.MustCompile(`(?i)\b(api[-_]?key|token|secret|password)\b\s*[:=]\s*[^\s]+`)
- reJSONSecret = regexp.MustCompile(`(?i)"(api[-_]?key|token|secret|password)"\s*:\s*"[^"]+"`)
- reQuerySecret = regexp.MustCompile(`(?i)([?&](?:token|sig|signature|key|auth|expires|x-amz-signature|x-amz-security-token|x-amz-credential|x-amz-date|x-amz-algorithm|x-amz-expires)=)[^&\s]+`)
-)
-
-func sanitizeForLog(text string) string {
- if text == "" {
- return text
- }
- sanitized := text
- sanitized = reBearer.ReplaceAllString(sanitized, "Bearer [REDACTED]")
- sanitized = reAuthHeader.ReplaceAllString(sanitized, "authorization=[REDACTED]")
- sanitized = reKeyValue.ReplaceAllString(sanitized, "$1=[REDACTED]")
- sanitized = reJSONSecret.ReplaceAllString(sanitized, "\"$1\":\"[REDACTED]\"")
- sanitized = reQuerySecret.ReplaceAllString(sanitized, "$1[REDACTED]")
- sanitized = reEmail.ReplaceAllString(sanitized, "[REDACTED_EMAIL]")
- sanitized = rePhone.ReplaceAllString(sanitized, "[REDACTED_PHONE]")
- return sanitized
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/outline_extract.go b/services/response-api/internal/domain/agent/planners/slide_creator/steps/outline_extract.go
deleted file mode 100644
index 87465a96..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/outline_extract.go
+++ /dev/null
@@ -1,561 +0,0 @@
-package steps
-
-import (
- "regexp"
- "strings"
-)
-
-// OutlineSlideContent represents extracted structured content from an outline block.
-type OutlineSlideContent struct {
- Index int
- Title string
- Bullets []string
- TableData *ExtractedTable
- ChartHint *ExtractedChartHint
- ImageHint string
- RawText string
- HasDataNeeds bool
-}
-
-// ExtractedTable represents a table parsed from outline text.
-type ExtractedTable struct {
- Title string
- Headers []string
- Rows [][]string
-}
-
-// ExtractedChartHint captures chart requirements from outline.
-type ExtractedChartHint struct {
- Type string // bar, line, pie
- Title string
- Categories []string
- Values []float64
- YAxisLabel string
- XAxisLabel string
-}
-
-// ExtractedDataPoint represents a single data point from inline data.
-type ExtractedDataPoint struct {
- Label string
- Value float64
-}
-
-var (
- pipeTableRowRE = regexp.MustCompile(`^\s*\|(.+)\|\s*$`)
- chartHintRE = regexp.MustCompile(`(?i)\b(bar|line|pie)\s*(chart|graph)\b`)
- percentageRE = regexp.MustCompile(`(\d+(?:\.\d+)?)\s*%`)
- numberValueRE = regexp.MustCompile(`(\d+(?:,\d{3})*(?:\.\d+)?)\s*(?:M|B|K|T|million|billion|thousand|trillion)?`)
- inlineDataRE = regexp.MustCompile(`(?i)([A-Za-z]+)\s*:\s*\$?([\d.,]+)\s*([MBKT]?)`)
- xAxisRE = regexp.MustCompile(`(?i)x-?\s*axis\s*:\s*(.+)`)
- yAxisRE = regexp.MustCompile(`(?i)y-?\s*axis\s*:\s*(.+)`)
- dataPointsLabelRE = regexp.MustCompile(`(?i)data\s*points?\s*[:\(]`)
-)
-
-// ExtractSlideContent parses an outline block and extracts structured content.
-func ExtractSlideContent(block outlineBlock) OutlineSlideContent {
- content := OutlineSlideContent{
- Index: block.Index,
- Title: block.Title,
- RawText: outlineBlockText(block),
- }
-
- bullets := []string{}
- tableLines := []string{}
- inTable := false
- var chartDataPoints []ExtractedDataPoint
- var xAxisCategories []string
- var yAxisLabel string
-
- for _, line := range block.Lines {
- trimmed := strings.TrimSpace(line)
- if trimmed == "" {
- if inTable && len(tableLines) > 0 {
- inTable = false
- }
- continue
- }
-
- // Check for pipe-delimited table row
- if pipeTableRowRE.MatchString(trimmed) {
- inTable = true
- tableLines = append(tableLines, trimmed)
- continue
- }
-
- // End table if we hit non-table content
- if inTable {
- inTable = false
- }
-
- // Check for X-axis categories
- if matches := xAxisRE.FindStringSubmatch(trimmed); matches != nil {
- xAxisCategories = parseCommaSeparatedValues(matches[1])
- continue
- }
-
- // Check for Y-axis label
- if matches := yAxisRE.FindStringSubmatch(trimmed); matches != nil {
- yAxisLabel = strings.TrimSpace(matches[1])
- continue
- }
-
- // Check for inline data series (e.g., "Jan: $1.7T | Feb: $1.8T")
- if dataPointsLabelRE.MatchString(trimmed) || strings.Contains(trimmed, ": $") || strings.Contains(trimmed, ": 1.") || strings.Contains(trimmed, ": 2.") {
- points := parseInlineDataSeries(trimmed)
- if len(points) > 0 {
- chartDataPoints = append(chartDataPoints, points...)
- continue
- }
- }
-
- // Check for bullet points
- if bullet := parseBulletLine(trimmed); bullet != "" {
- bullets = append(bullets, bullet)
- continue
- }
-
- // Check for chart hints
- if chartHintRE.MatchString(trimmed) && content.ChartHint == nil {
- content.ChartHint = parseChartHint(trimmed)
- }
-
- // Check for image hints
- if outlineImageMarker.MatchString(trimmed) && content.ImageHint == "" {
- content.ImageHint = extractImageHint(trimmed)
- }
- }
-
- content.Bullets = bullets
-
- // Parse table if found
- if len(tableLines) >= 2 {
- content.TableData = parseTableFromLines(tableLines)
- }
-
- // If we found chart data points, add them to the chart hint
- if len(chartDataPoints) > 0 {
- if content.ChartHint == nil {
- content.ChartHint = &ExtractedChartHint{Type: "line"}
- }
- content.ChartHint.Categories = make([]string, len(chartDataPoints))
- content.ChartHint.Values = make([]float64, len(chartDataPoints))
- for i, dp := range chartDataPoints {
- content.ChartHint.Categories[i] = dp.Label
- content.ChartHint.Values[i] = dp.Value
- }
- if len(xAxisCategories) > 0 {
- content.ChartHint.Categories = xAxisCategories
- }
- if yAxisLabel != "" {
- content.ChartHint.YAxisLabel = yAxisLabel
- }
- }
-
- // Determine if data bank is needed
- content.HasDataNeeds = content.TableData != nil || content.ChartHint != nil ||
- outlineBlockNeedsDataBank(block)
-
- return content
-}
-
-// parseBulletLine extracts bullet content from a line.
-func parseBulletLine(line string) string {
- line = strings.TrimSpace(line)
- if line == "" {
- return ""
- }
-
- // Common bullet prefixes
- prefixes := []string{"- ", "* ", "• ", "→ ", "> "}
- for _, prefix := range prefixes {
- if strings.HasPrefix(line, prefix) {
- return strings.TrimSpace(strings.TrimPrefix(line, prefix))
- }
- }
-
- // Numbered bullets: "1. ", "1) "
- if len(line) >= 3 {
- if line[0] >= '0' && line[0] <= '9' {
- for i := 1; i < len(line) && i < 4; i++ {
- if line[i] == '.' || line[i] == ')' {
- if i+1 < len(line) && line[i+1] == ' ' {
- return strings.TrimSpace(line[i+2:])
- }
- }
- if line[i] < '0' || line[i] > '9' {
- break
- }
- }
- }
- }
-
- return ""
-}
-
-// parseTableFromLines converts pipe-delimited lines to a table.
-func parseTableFromLines(lines []string) *ExtractedTable {
- if len(lines) < 2 {
- return nil
- }
-
- table := &ExtractedTable{}
- for i, line := range lines {
- cells := parsePipeRow(line)
- if len(cells) == 0 {
- continue
- }
-
- // Skip separator rows (e.g., |---|---|)
- if isSeparatorRow(cells) {
- continue
- }
-
- if len(table.Headers) == 0 {
- table.Headers = cells
- } else {
- // Normalize row to match header count
- row := make([]string, len(table.Headers))
- for j := 0; j < len(table.Headers); j++ {
- if j < len(cells) {
- row[j] = cells[j]
- }
- }
- table.Rows = append(table.Rows, row)
- }
-
- // Limit rows to prevent oversized tables
- if len(table.Rows) >= 9 {
- break
- }
-
- _ = i
- }
-
- if len(table.Headers) == 0 || len(table.Rows) == 0 {
- return nil
- }
-
- // Limit columns
- if len(table.Headers) > 6 {
- table.Headers = table.Headers[:6]
- for i := range table.Rows {
- if len(table.Rows[i]) > 6 {
- table.Rows[i] = table.Rows[i][:6]
- }
- }
- }
-
- return table
-}
-
-// parsePipeRow splits a pipe-delimited row into cells.
-func parsePipeRow(line string) []string {
- line = strings.TrimSpace(line)
- line = strings.Trim(line, "|")
-
- parts := strings.Split(line, "|")
- cells := make([]string, 0, len(parts))
- for _, part := range parts {
- cell := strings.TrimSpace(part)
- if cell != "" {
- cells = append(cells, cell)
- }
- }
- return cells
-}
-
-// isSeparatorRow checks if all cells are separator patterns (e.g., ---, :--:).
-func isSeparatorRow(cells []string) bool {
- for _, cell := range cells {
- cell = strings.TrimSpace(cell)
- cell = strings.Trim(cell, ":")
- if cell == "" {
- continue
- }
- for _, r := range cell {
- if r != '-' {
- return false
- }
- }
- }
- return true
-}
-
-// parseChartHint extracts chart type and title from a line.
-func parseChartHint(line string) *ExtractedChartHint {
- hint := &ExtractedChartHint{}
-
- lower := strings.ToLower(line)
- if strings.Contains(lower, "bar") {
- hint.Type = "bar"
- } else if strings.Contains(lower, "line") {
- hint.Type = "line"
- } else if strings.Contains(lower, "pie") {
- hint.Type = "pie"
- } else {
- hint.Type = "bar" // default
- }
-
- // Extract title - text before "chart" or "graph"
- chartIdx := strings.Index(lower, "chart")
- if chartIdx < 0 {
- chartIdx = strings.Index(lower, "graph")
- }
- if chartIdx > 0 {
- title := strings.TrimSpace(line[:chartIdx])
- title = strings.TrimSuffix(title, "bar")
- title = strings.TrimSuffix(title, "line")
- title = strings.TrimSuffix(title, "pie")
- hint.Title = strings.TrimSpace(title)
- }
-
- return hint
-}
-
-// extractImageHint extracts image requirement description.
-func extractImageHint(line string) string {
- // Find image-related keywords and extract context
- line = strings.TrimSpace(line)
- if len(line) > 100 {
- return line[:100]
- }
- return line
-}
-
-// FormatSlideContentForPrompt formats extracted content for LLM prompt.
-func FormatSlideContentForPrompt(content OutlineSlideContent) string {
- var sb strings.Builder
-
- if content.Title != "" {
- sb.WriteString("Slide Title: ")
- sb.WriteString(content.Title)
- sb.WriteString("\n\n")
- }
-
- if len(content.Bullets) > 0 {
- sb.WriteString("Key Points:\n")
- for _, bullet := range content.Bullets {
- sb.WriteString("- ")
- sb.WriteString(bullet)
- sb.WriteString("\n")
- }
- sb.WriteString("\n")
- }
-
- if content.TableData != nil {
- sb.WriteString("Table Data:\n")
- sb.WriteString("Headers: ")
- sb.WriteString(strings.Join(content.TableData.Headers, " | "))
- sb.WriteString("\n")
- for _, row := range content.TableData.Rows {
- sb.WriteString("Row: ")
- sb.WriteString(strings.Join(row, " | "))
- sb.WriteString("\n")
- }
- sb.WriteString("\n")
- }
-
- if content.ChartHint != nil {
- sb.WriteString("Chart Required: ")
- sb.WriteString(content.ChartHint.Type)
- if content.ChartHint.Title != "" {
- sb.WriteString(" - ")
- sb.WriteString(content.ChartHint.Title)
- }
- sb.WriteString("\n")
- if content.ChartHint.YAxisLabel != "" {
- sb.WriteString("Y-Axis: ")
- sb.WriteString(content.ChartHint.YAxisLabel)
- sb.WriteString("\n")
- }
- if len(content.ChartHint.Categories) > 0 && len(content.ChartHint.Values) > 0 {
- sb.WriteString("Data Points:\n")
- for i := 0; i < len(content.ChartHint.Categories) && i < len(content.ChartHint.Values); i++ {
- sb.WriteString(" ")
- sb.WriteString(content.ChartHint.Categories[i])
- sb.WriteString(": ")
- sb.WriteString(formatChartValue(content.ChartHint.Values[i]))
- sb.WriteString("\n")
- }
- }
- sb.WriteString("\n")
- }
-
- if content.ImageHint != "" {
- sb.WriteString("Image Note: ")
- sb.WriteString(content.ImageHint)
- sb.WriteString("\n\n")
- }
-
- if content.RawText != "" && sb.Len() < 500 {
- // Include raw text if structured extraction was minimal
- sb.WriteString("Additional Context:\n")
- rawText := content.RawText
- if len(rawText) > 1500 {
- rawText = rawText[:1500] + "..."
- }
- sb.WriteString(rawText)
- }
-
- return strings.TrimSpace(sb.String())
-}
-
-// ConvertExtractedTableToTableData converts an extracted table to the SlidePlan format.
-func ConvertExtractedTableToTableData(ext *ExtractedTable) *TableData {
- if ext == nil || len(ext.Headers) == 0 || len(ext.Rows) == 0 {
- return nil
- }
-
- rows := make([][]any, 0, len(ext.Rows))
- for _, row := range ext.Rows {
- anyRow := make([]any, len(row))
- for i, cell := range row {
- anyRow[i] = cell
- }
- rows = append(rows, anyRow)
- }
-
- return &TableData{
- Title: ext.Title,
- Columns: ext.Headers,
- Rows: rows,
- }
-}
-
-// parseInlineDataSeries parses data series like "Jan: $1.7T | Feb: $1.8T | Mar: $1.9T"
-func parseInlineDataSeries(line string) []ExtractedDataPoint {
- var points []ExtractedDataPoint
-
- // Split by | or ∣ (both pipe characters)
- parts := strings.FieldsFunc(line, func(r rune) bool {
- return r == '|' || r == '∣'
- })
-
- for _, part := range parts {
- part = strings.TrimSpace(part)
- if part == "" {
- continue
- }
-
- // Match patterns like "Jan: $1.7T" or "Jan: 1.7T" or "Jan: 100,000"
- matches := inlineDataRE.FindStringSubmatch(part)
- if matches != nil && len(matches) >= 3 {
- label := strings.TrimSpace(matches[1])
- valueStr := strings.ReplaceAll(matches[2], ",", "")
- multiplier := 1.0
-
- if len(matches) >= 4 {
- switch strings.ToUpper(matches[3]) {
- case "T":
- multiplier = 1e12
- case "B":
- multiplier = 1e9
- case "M":
- multiplier = 1e6
- case "K":
- multiplier = 1e3
- }
- }
-
- value := parseFloatSimple(valueStr)
- if value > 0 {
- points = append(points, ExtractedDataPoint{
- Label: label,
- Value: value * multiplier,
- })
- }
- }
- }
-
- return points
-}
-
-// parseCommaSeparatedValues parses comma-separated values like "Jan, Feb, Mar, ..."
-func parseCommaSeparatedValues(s string) []string {
- parts := strings.Split(s, ",")
- result := make([]string, 0, len(parts))
- for _, part := range parts {
- part = strings.TrimSpace(part)
- if part != "" {
- result = append(result, part)
- }
- }
- return result
-}
-
-// parseFloatSimple parses a simple float from string
-func parseFloatSimple(s string) float64 {
- s = strings.TrimSpace(s)
- if s == "" {
- return 0
- }
-
- var val float64
- var decimal float64 = 0.1
- inDecimal := false
-
- for _, r := range s {
- if r >= '0' && r <= '9' {
- if inDecimal {
- val += float64(r-'0') * decimal
- decimal /= 10
- } else {
- val = val*10 + float64(r-'0')
- }
- } else if r == '.' {
- inDecimal = true
- }
- }
-
- return val
-}
-
-// formatChartValue formats a chart value for display
-func formatChartValue(v float64) string {
- if v >= 1e12 {
- return formatFloat(v/1e12) + "T"
- }
- if v >= 1e9 {
- return formatFloat(v/1e9) + "B"
- }
- if v >= 1e6 {
- return formatFloat(v/1e6) + "M"
- }
- if v >= 1e3 {
- return formatFloat(v/1e3) + "K"
- }
- return formatFloat(v)
-}
-
-// formatFloat formats a float with up to 2 decimal places
-func formatFloat(v float64) string {
- intPart := int(v)
- fracPart := int((v - float64(intPart)) * 100)
- if fracPart == 0 {
- return intToStr(intPart)
- }
- if fracPart%10 == 0 {
- return intToStr(intPart) + "." + intToStr(fracPart/10)
- }
- return intToStr(intPart) + "." + intToStr(fracPart)
-}
-
-// intToStr converts int to string
-func intToStr(n int) string {
- if n == 0 {
- return "0"
- }
- neg := n < 0
- if neg {
- n = -n
- }
- var digits []byte
- for n > 0 {
- digits = append([]byte{byte('0' + n%10)}, digits...)
- n /= 10
- }
- if neg {
- digits = append([]byte{'-'}, digits...)
- }
- return string(digits)
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/outline_fallback.go b/services/response-api/internal/domain/agent/planners/slide_creator/steps/outline_fallback.go
deleted file mode 100644
index 911ee6bc..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/outline_fallback.go
+++ /dev/null
@@ -1,191 +0,0 @@
-package steps
-
-import (
- "bufio"
- "regexp"
- "strconv"
- "strings"
- "unicode/utf8"
-)
-
-type outlineSlide struct {
- Title string
- Bullets []string
-}
-
-var outlineSlideHeader = regexp.MustCompile(`(?i)^slide\s+(\d+)\s*:\s*(.+)$`)
-
-func applyOutlineFallbacks(plan *DeckPlan, outline string) {
- if plan == nil {
- return
- }
- outline = strings.TrimSpace(outline)
- if outline == "" {
- return
- }
- outlineSlides := parseOutlineSlides(outline)
- if len(outlineSlides) == 0 {
- return
- }
-
- // Also parse outline blocks for structured content extraction
- outlineBlocks := parseOutlineBlocks(outline)
- blocksByIndex := make(map[int]outlineBlock)
- for _, block := range outlineBlocks {
- blocksByIndex[block.Index] = block
- }
-
- for i := range plan.Slides {
- slide := &plan.Slides[i]
- outlineSlide, ok := outlineSlides[slide.ID]
- if !ok {
- continue
- }
-
- if shouldReplaceTitle(slide.Title) && outlineSlide.Title != "" {
- slide.Title = trimToRunesNoEllipsis(outlineSlide.Title, 60)
- }
-
- // Extract structured content from outline block
- if block, hasBlock := blocksByIndex[slide.ID]; hasBlock {
- content := ExtractSlideContent(block)
-
- // Apply extracted table if slide doesn't have one
- if slide.Table == nil && content.TableData != nil {
- slide.Table = ConvertExtractedTableToTableData(content.TableData)
- if slide.Table != nil {
- slide.Layout = "table"
- }
- }
-
- // Apply extracted bullets if slide doesn't have content
- if !hasSlideContent(*slide) && len(content.Bullets) > 0 {
- slide.Bullets = clampBullets(content.Bullets, 6)
- }
- }
-
- if !hasSlideContent(*slide) && len(outlineSlide.Bullets) > 0 {
- slide.Bullets = clampBullets(outlineSlide.Bullets, 6)
- }
-
- if len(slide.Bullets) > 0 {
- slide.Bullets = ensureBulletCount(slide.Bullets, 3)
- } else if !hasSlideContent(*slide) {
- slide.Bullets = ensureBulletCount(defaultBulletsForTitle(slide.Title), 3)
- }
- }
-}
-
-func parseOutlineSlides(outline string) map[int]outlineSlide {
- parsed := map[int]outlineSlide{}
- scanner := bufio.NewScanner(strings.NewReader(outline))
- scanner.Buffer(make([]byte, 0, 64*1024), 1024*1024)
-
- current := 0
- for scanner.Scan() {
- line := strings.TrimSpace(scanner.Text())
- if line == "" {
- continue
- }
- if match := outlineSlideHeader.FindStringSubmatch(line); match != nil {
- idx, _ := strconv.Atoi(match[1])
- if idx <= 0 {
- continue
- }
- current = idx
- title := strings.TrimSpace(match[2])
- title = strings.Trim(title, "\"")
- entry := parsed[current]
- entry.Title = title
- parsed[current] = entry
- continue
- }
- if current == 0 {
- continue
- }
- if bullet := parseOutlineBullet(line); bullet != "" {
- entry := parsed[current]
- entry.Bullets = append(entry.Bullets, bullet)
- parsed[current] = entry
- }
- }
-
- return parsed
-}
-
-func parseOutlineBullet(line string) string {
- line = strings.TrimSpace(line)
- if line == "" {
- return ""
- }
- switch {
- case strings.HasPrefix(line, "-"):
- line = strings.TrimSpace(strings.TrimPrefix(line, "-"))
- case strings.HasPrefix(line, "*"):
- line = strings.TrimSpace(strings.TrimPrefix(line, "*"))
- default:
- return ""
- }
- line = strings.Trim(line, "\"")
- return line
-}
-
-func shouldReplaceTitle(title string) bool {
- title = strings.TrimSpace(title)
- if title == "" || title == "..." {
- return true
- }
- lower := strings.ToLower(title)
- if strings.HasPrefix(lower, "slide ") {
- return true
- }
- if utf8.RuneCountInString(title) > 80 {
- return true
- }
- if strings.Contains(lower, "chars max") || strings.Contains(lower, "let me check") {
- return true
- }
- return false
-}
-
-func ensureBulletCount(bullets []string, min int) []string {
- if min <= 0 {
- return bullets
- }
- out := make([]string, 0, 6)
- for _, bullet := range bullets {
- if len(out) >= 6 {
- break
- }
- bullet = strings.TrimSpace(bullet)
- if bullet == "" {
- continue
- }
- out = append(out, trimToRunesNoEllipsis(bullet, 75))
- }
-
- fallbacks := []string{
- "Key signals and market drivers in 2025",
- "Evidence-backed trends and momentum shifts",
- "Implications for strategy and execution",
- }
- for _, fallback := range fallbacks {
- if len(out) >= min || len(out) >= 6 {
- break
- }
- out = append(out, fallback)
- }
- return out
-}
-
-func defaultBulletsForTitle(title string) []string {
- base := strings.TrimSpace(title)
- if base == "" {
- base = "the topic"
- }
- return []string{
- trimToRunesNoEllipsis("Scope and context for "+base, 75),
- "Key signals and market drivers in 2025",
- "Implications for strategy and execution",
- }
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/outline_parse.go b/services/response-api/internal/domain/agent/planners/slide_creator/steps/outline_parse.go
deleted file mode 100644
index 4c621a99..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/outline_parse.go
+++ /dev/null
@@ -1,148 +0,0 @@
-package steps
-
-import (
- "regexp"
- "strings"
-)
-
-type outlineBlock struct {
- Index int
- Title string
- Lines []string
-}
-
-var outlineDataMarker = regexp.MustCompile(`(?i)\b(table|chart|dataset)\b`)
-var outlineImageMarker = regexp.MustCompile(`(?i)\b(image|visual|photo|illustration|diagram|icon|background)\b`)
-var outlineURLMatcher = regexp.MustCompile(`https?://[^\s\])>]+`)
-
-func parseOutlineBlocks(outline string) []outlineBlock {
- outline = strings.TrimSpace(outline)
- if outline == "" {
- return nil
- }
- lines := strings.Split(outline, "\n")
- blocks := []outlineBlock{}
- var current *outlineBlock
- for _, line := range lines {
- trimmed := strings.TrimSpace(line)
- if trimmed == "" {
- continue
- }
- if match := outlineSlideHeader.FindStringSubmatch(trimmed); match != nil {
- block := outlineBlock{
- Index: parseOutlineIndex(match[1]),
- Title: strings.TrimSpace(strings.Trim(match[2], "\"")),
- Lines: []string{},
- }
- if block.Index > 0 {
- blocks = append(blocks, block)
- current = &blocks[len(blocks)-1]
- } else {
- current = nil
- }
- continue
- }
- if current != nil {
- current.Lines = append(current.Lines, strings.TrimRight(line, " \t"))
- }
- }
- return blocks
-}
-
-func outlineBlockForSlide(outline string, slideIndex int) (outlineBlock, bool) {
- if slideIndex <= 0 {
- return outlineBlock{}, false
- }
- for _, block := range parseOutlineBlocks(outline) {
- if block.Index == slideIndex {
- return block, true
- }
- }
- return outlineBlock{}, false
-}
-
-func outlineBlockText(block outlineBlock) string {
- if len(block.Lines) == 0 {
- return ""
- }
- return strings.TrimSpace(strings.Join(block.Lines, "\n"))
-}
-
-func outlineNeedsDataBank(outline string) bool {
- outline = strings.TrimSpace(outline)
- if outline == "" {
- return false
- }
- return outlineDataMarker.MatchString(outline) || strings.Contains(outline, "|")
-}
-
-func outlineBlockNeedsDataBank(block outlineBlock) bool {
- if block.Title != "" && outlineDataMarker.MatchString(block.Title) {
- return true
- }
- for _, line := range block.Lines {
- if outlineDataMarker.MatchString(line) || strings.Contains(line, "|") {
- return true
- }
- }
- return false
-}
-
-func outlineBlockNeedsImage(block outlineBlock) bool {
- if block.Title != "" && outlineImageMarker.MatchString(block.Title) {
- return true
- }
- for _, line := range block.Lines {
- if outlineImageMarker.MatchString(line) {
- return true
- }
- }
- return false
-}
-
-func extractOutlineURLs(text string) []string {
- text = strings.TrimSpace(text)
- if text == "" {
- return nil
- }
- matches := outlineURLMatcher.FindAllString(text, -1)
- if len(matches) == 0 {
- return nil
- }
- seen := map[string]struct{}{}
- out := make([]string, 0, len(matches))
- for _, match := range matches {
- trimmed := strings.TrimRight(match, ".,;:)")
- if trimmed == "" {
- continue
- }
- if _, ok := seen[trimmed]; ok {
- continue
- }
- seen[trimmed] = struct{}{}
- out = append(out, trimmed)
- }
- return out
-}
-
-func fallbackDeckTitle(outline string, brief string) string {
- if outlineBlock, ok := outlineBlockForSlide(outline, 1); ok && outlineBlock.Title != "" {
- return trimToRunesNoEllipsis(outlineBlock.Title, 60)
- }
- return trimToRunesNoEllipsis(strings.TrimSpace(brief), 60)
-}
-
-func parseOutlineIndex(value string) int {
- value = strings.TrimSpace(value)
- if value == "" {
- return 0
- }
- n := 0
- for _, r := range value {
- if r < '0' || r > '9' {
- return 0
- }
- n = n*10 + int(r-'0')
- }
- return n
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/plan_utils.go b/services/response-api/internal/domain/agent/planners/slide_creator/steps/plan_utils.go
deleted file mode 100644
index d403b3d0..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/plan_utils.go
+++ /dev/null
@@ -1,269 +0,0 @@
-package steps
-
-import (
- "encoding/json"
- "fmt"
- "regexp"
- "strings"
- "unicode/utf8"
-)
-
-// normalizeDeckPlan ensures slide count and layout safety.
-func normalizeDeckPlan(plan DeckPlan, wantSlides int) DeckPlan {
- plan.Title = strings.TrimSpace(plan.Title)
- if plan.Title == "" {
- plan.Title = "Untitled Deck"
- }
- plan.Theme = normalizeTheme(plan.Theme)
-
- if wantSlides <= 0 {
- wantSlides = len(plan.Slides)
- }
- if len(plan.Slides) > wantSlides {
- plan.Slides = plan.Slides[:wantSlides]
- }
- for len(plan.Slides) < wantSlides {
- plan.Slides = append(plan.Slides, SlidePlan{ID: len(plan.Slides) + 1, Title: fmt.Sprintf("Slide %d", len(plan.Slides)+1)})
- }
-
- for i := range plan.Slides {
- plan.Slides[i].ID = i + 1
- title := strings.TrimSpace(plan.Slides[i].Title)
- if title == "" {
- plan.Slides[i].Title = fmt.Sprintf("Slide %d", i+1)
- } else {
- if utf8.RuneCountInString(title) > 60 {
- title = trimToRunesNoEllipsis(title, 60)
- }
- plan.Slides[i].Title = title
- }
- plan.Slides[i].Subtitle = strings.TrimSpace(plan.Slides[i].Subtitle)
- plan.Slides[i].Notes = strings.TrimSpace(plan.Slides[i].Notes)
- plan.Slides[i].Bullets = clampBullets(plan.Slides[i].Bullets, 6)
-
- // Validate and filter images
- plan.Slides[i].Images = FilterValidSlideImages(plan.Slides[i].Images)
- if len(plan.Slides[i].Images) > 2 {
- plan.Slides[i].Images = plan.Slides[i].Images[:2]
- }
- for j := range plan.Slides[i].Images {
- plan.Slides[i].Images[j].Src = SanitizeImageURL(plan.Slides[i].Images[j].Src)
- plan.Slides[i].Images[j].Alt = strings.TrimSpace(plan.Slides[i].Images[j].Alt)
- plan.Slides[i].Images[j].Caption = strings.TrimSpace(plan.Slides[i].Images[j].Caption)
- if plan.Slides[i].Images[j].Alt == "" {
- plan.Slides[i].Images[j].Alt = plan.Slides[i].Title
- }
- }
-
- hasImg := len(plan.Slides[i].Images) > 0 && strings.TrimSpace(plan.Slides[i].Images[0].Src) != ""
- hasBul := len(plan.Slides[i].Bullets) > 0
- tableInfo := normalizeTable(plan.Slides[i].Table, 6, 9)
- hasTable := tableInfo.Has
- hasChart := plan.Slides[i].Chart != nil && len(plan.Slides[i].Chart.Series) > 0
-
- layout := strings.ToLower(strings.TrimSpace(plan.Slides[i].Layout))
- valid := map[string]bool{"split": true, "bullets": true, "hero": true, "title": true, "table": true, "chart": true}
- if !valid[layout] {
- layout = ""
- }
- if layout == "hero" && !hasImg {
- layout = ""
- }
- if layout == "split" && !(hasImg && hasBul) {
- layout = ""
- }
- if layout == "bullets" && !hasBul {
- layout = ""
- }
- if layout == "table" && !hasTable {
- layout = ""
- }
- if layout == "chart" && !hasChart {
- layout = ""
- }
- if layout == "title" {
- layout = ""
- }
- if layout == "" {
- layout = chooseLayout(plan.Slides[i])
- }
- plan.Slides[i].Layout = layout
- }
-
- return plan
-}
-
-func validateDeckPlan(plan DeckPlan, wantSlides int) error {
- if wantSlides > 0 && len(plan.Slides) != wantSlides {
- return fmt.Errorf("expected %d slides, got %d", wantSlides, len(plan.Slides))
- }
- for i, slide := range plan.Slides {
- if err := validateSlidePlan(slide); err != nil {
- return fmt.Errorf("slide %d invalid: %v", i+1, err)
- }
- }
- return nil
-}
-
-func hasSlideContent(slide SlidePlan) bool {
- if len(slide.Bullets) > 0 {
- return true
- }
- if slide.Table != nil && len(slide.Table.Columns) > 0 && len(slide.Table.Rows) > 0 {
- return true
- }
- if slide.Chart != nil && len(slide.Chart.Series) > 0 {
- return true
- }
- return false
-}
-
-func validateSlidePlan(slide SlidePlan) error {
- title := strings.TrimSpace(slide.Title)
- if utf8.RuneCountInString(title) < 6 || utf8.RuneCountInString(title) > 60 {
- return fmt.Errorf("title out of range")
- }
- if !hasSlideContent(slide) {
- return fmt.Errorf("missing content")
- }
- return nil
-}
-
-func parseDeckPlan(content string) (DeckPlan, error) {
- var plan DeckPlan
- if err := json.Unmarshal([]byte(content), &plan); err == nil {
- return plan, nil
- }
- if extracted := extractFirstJSONObject(content); extracted != "" {
- if err := json.Unmarshal([]byte(extracted), &plan); err == nil {
- return plan, nil
- }
- }
- return DeckPlan{}, fmt.Errorf("could not parse deck plan JSON")
-}
-
-func extractFirstJSONObject(s string) string {
- s = strings.TrimSpace(s)
- s = strings.TrimPrefix(s, "```json")
- s = strings.TrimPrefix(s, "```")
- s = strings.TrimSuffix(s, "```")
- s = strings.TrimSpace(s)
-
- start := strings.Index(s, "{")
- if start < 0 {
- return ""
- }
- depth := 0
- for i := start; i < len(s); i++ {
- switch s[i] {
- case '{':
- depth++
- case '}':
- depth--
- if depth == 0 {
- return s[start : i+1]
- }
- }
- }
- return ""
-}
-
-func chooseLayout(slide SlidePlan) string {
- hasImg := len(slide.Images) > 0 && strings.TrimSpace(slide.Images[0].Src) != ""
- hasBul := len(slide.Bullets) > 0
- hasTable := slide.Table != nil && len(slide.Table.Columns) > 0 && len(slide.Table.Rows) > 0
- hasChart := slide.Chart != nil && len(slide.Chart.Series) > 0
- if hasChart {
- return "chart"
- }
- if hasTable {
- return "table"
- }
- if hasImg && hasBul {
- return "split"
- }
- if hasImg {
- return "hero"
- }
- if hasBul {
- return "bullets"
- }
- return "bullets"
-}
-
-func clampBullets(in []string, max int) []string {
- out := make([]string, 0, len(in))
- for _, b := range in {
- b = strings.TrimSpace(b)
- b = strings.TrimPrefix(b, "-")
- b = strings.TrimSpace(b)
- if b == "" {
- continue
- }
- out = append(out, b)
- if len(out) >= max {
- break
- }
- }
- return out
-}
-
-func trimToRunesNoEllipsis(s string, maxRunes int) string {
- s = strings.TrimSpace(s)
- if maxRunes <= 0 {
- return ""
- }
- if utf8.RuneCountInString(s) <= maxRunes {
- return s
- }
- out := make([]rune, 0, maxRunes)
- for _, r := range s {
- out = append(out, r)
- if len(out) >= maxRunes {
- break
- }
- }
- return strings.TrimSpace(string(out))
-}
-
-// buildChartsExport writes charts.json for raster overlay or downstream use.
-func buildChartsExport(plan DeckPlan) ChartsExport {
- out := ChartsExport{Slides: []ChartData{}}
- for _, slide := range plan.Slides {
- if slide.Chart == nil {
- continue
- }
- chart := *slide.Chart
- chart.ID = slide.ID
- chart.Position = normalizeChartPosition(chart.Position)
- chartCopy := chart
- chartCopy.Units = strings.TrimSpace(chartCopy.Units)
- out.Slides = append(out.Slides, chartCopy)
- }
- return out
-}
-
-func normalizeChartPosition(pos ChartPosition) ChartPosition {
- if pos.W == 0 {
- pos.W = 11.2
- }
- if pos.H == 0 {
- pos.H = 5.3
- }
- if pos.X == 0 {
- pos.X = 1.1
- }
- if pos.Y == 0 {
- pos.Y = 1.3
- }
- if strings.TrimSpace(pos.Units) == "" {
- pos.Units = "in"
- }
- return pos
-}
-
-var hexColorRE = regexp.MustCompile(`^#[0-9a-fA-F]{6}$`)
-
-func isHexColor(s string) bool {
- return hexColorRE.MatchString(strings.TrimSpace(s))
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/render.go b/services/response-api/internal/domain/agent/planners/slide_creator/steps/render.go
deleted file mode 100644
index 3b0a786b..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/render.go
+++ /dev/null
@@ -1,702 +0,0 @@
-package steps
-
-import (
- "bytes"
- "encoding/json"
- "fmt"
- "html/template"
- "io/fs"
- "math"
- "os"
- "path"
- "path/filepath"
- "strconv"
- "strings"
- "unicode/utf8"
-)
-
-const (
- slideWidth = 1920
- slideHeight = 1080
-)
-
-type SplitTemplateData struct {
- Bullets []string
- BulletFont int
- Label string
- Subtitle string
- Image SlideImage
- ImageAlt string
- ImageCaption string
- HasImage bool
- Stats []StatItem
-}
-
-type StatItem struct {
- Value string
- Label string
-}
-
-type BulletsTemplateData struct {
- Bullets []string
- ItemFont int
- Subtitle string
- Label string
- Stats []StatItem
- Image SlideImage
- ImageAlt string
- ImageCaption string
- HasImage bool
-}
-
-type HeroTemplateData struct {
- Image SlideImage
- ImageAlt string
- ImageCaption string
- Kicker string
- Badge string
-}
-
-type TitleTemplateData struct {
- Notes string
-}
-
-type TemplateData struct {
- SlideW int
- Plan DeckPlan
- Slide SlidePlan
- Index int
- Total int
- Theme Theme
- Muted template.CSS
- Line template.CSS
- CardBorder template.CSS
- Shadow template.CSS
- Background template.CSS
- AccGlow template.CSS
- PriGlow template.CSS
- CardBg template.CSS
- BodyBorder template.CSS
- Split SplitTemplateData
- Bullets BulletsTemplateData
- Table TableTemplateData
- Chart ChartTemplateData
- Hero HeroTemplateData
- Title TitleTemplateData
- BodyHTML template.HTML
-}
-
-type TableTemplateData struct {
- Title string
- Columns []string
- Rows [][]string
- Notes string
- Has bool
-}
-
-type ChartBar struct {
- X float64
- Y float64
- W float64
- H float64
- Value float64
- Color string
- Label string
-}
-
-type ChartPoint struct {
- X float64
- Y float64
- Value float64
-}
-
-type ChartSlice struct {
- Path string
- Color string
- Label string
-}
-
-type ChartTemplateData struct {
- Type string
- Title string
- Categories []string
- Series []ChartSeries
- Bars []ChartBar
- LinePaths []string
- Points [][]ChartPoint
- Slices []ChartSlice
- Colors []string
- Notes string
- Has bool
-}
-
-func buildTemplateData(plan DeckPlan, slide SlidePlan, index, total int, bodyHTML string) TemplateData {
- theme := normalizeTheme(plan.Theme)
- isDark := isDarkColor(theme.BackgroundColor)
- muted := withAlpha(theme.TextColor, 0.86)
- line := safeCSS("rgba(15,23,42,0.10)")
- cardBorder := safeCSS("rgba(15,23,42,0.10)")
- shadow := safeCSS("rgba(15,23,42,0.12)")
- if isDark {
- line = safeCSS("rgba(255,255,255,0.14)")
- cardBorder = safeCSS("rgba(255,255,255,0.14)")
- shadow = safeCSS("rgba(0,0,0,0.35)")
- }
- bg2 := theme.BackgroundColor
- if isDark {
- bg2 = mixHex(theme.BackgroundColor, "#000000", 0.18)
- } else {
- bg2 = mixHex(theme.BackgroundColor, "#FFFFFF", 0.18)
- }
- background := safeCSS(fmt.Sprintf("linear-gradient(135deg, %s 0%%, %s 100%%)", theme.BackgroundColor, bg2))
- accGlow := withAlpha(theme.AccentColor, 0.22)
- priGlow := withAlpha(theme.PrimaryColor, 0.12)
- cardBg := withAlpha("#FFFFFF", 0.92)
- if isDark {
- cardBg = withAlpha("#0B1220", 0.78)
- }
-
- bodyBorder := safeCSS("rgba(148,163,184,0.22)")
- if isDark {
- bodyBorder = safeCSS("rgba(255,255,255,0.18)")
- }
-
- tableInfo := normalizeTable(slide.Table, 6, 9)
- chartInfo := normalizeChart(slide.Chart, theme)
-
- splitImage := SlideImage{}
- if len(slide.Images) > 0 {
- splitImage = slide.Images[0]
- }
-
- splitLabel := strings.TrimSpace(slide.Subtitle)
- if splitLabel == "" && len(slide.Bullets) > 0 {
- splitLabel = slide.Bullets[0]
- }
-
- data := TemplateData{
- SlideW: slideWidth,
- Plan: plan,
- Slide: slide,
- Index: index,
- Total: total,
- Theme: theme,
- Muted: muted,
- Line: line,
- CardBorder: cardBorder,
- Shadow: shadow,
- Background: background,
- AccGlow: accGlow,
- PriGlow: priGlow,
- CardBg: cardBg,
- BodyBorder: bodyBorder,
- Split: SplitTemplateData{
- Bullets: slide.Bullets,
- BulletFont: ternaryInt(len(slide.Bullets) > 4, 20, 22),
- Label: splitLabel,
- Subtitle: slide.Subtitle,
- Image: splitImage,
- ImageAlt: splitImage.Alt,
- ImageCaption: splitImage.Caption,
- HasImage: splitImage.Src != "",
- Stats: extractStats(slide),
- },
- Bullets: BulletsTemplateData{
- Bullets: slide.Bullets,
- ItemFont: ternaryInt(len(slide.Bullets) > 4, 22, 24),
- Subtitle: slide.Subtitle,
- Label: extractBulletsLabel(slide),
- Stats: extractStats(slide),
- Image: splitImage,
- ImageAlt: splitImage.Alt,
- ImageCaption: splitImage.Caption,
- HasImage: splitImage.Src != "",
- },
- Table: tableInfo,
- Chart: chartInfo,
- Hero: HeroTemplateData{
- Image: splitImage,
- ImageAlt: splitImage.Alt,
- ImageCaption: splitImage.Caption,
- Kicker: planSafeDeckTitle(slide),
- Badge: mutedLabel(slide),
- },
- Title: TitleTemplateData{Notes: slide.Notes},
- BodyHTML: template.HTML(bodyHTML),
- }
-
- return data
-}
-
-func renderSlideFromTemplate(layout string, data TemplateData, templateFS fs.FS, templateDir string, fallbackFS fs.FS, fallbackDir string) (string, error) {
- basePath, _, err := resolveTemplatePaths(layout, templateFS, templateDir, fallbackFS, fallbackDir)
- if err != nil {
- return "", err
- }
-
- funcs := template.FuncMap{
- "trimToRunes": trimToRunes,
- "withAlpha": withAlpha,
- "planSafeDeckTitle": planSafeDeckTitle,
- "mutedLabel": mutedLabel,
- }
-
- tmpl, err := template.New("base.html").Funcs(funcs).ParseFS(basePath.fs, basePath.base, basePath.layout)
- if err != nil {
- return "", err
- }
-
- var buf bytes.Buffer
- if err := tmpl.ExecuteTemplate(&buf, "base.html", data); err != nil {
- return "", err
- }
- html := buf.String()
- html = tuneImageOverlays(html, data.Theme)
- return html, nil
-}
-
-func tuneImageOverlays(html string, theme Theme) string {
- if html == "" || isDarkColor(theme.BackgroundColor) {
- return html
- }
- // Lighten image overlays for bright themes to keep text readable.
- replacements := map[string]string{
- "rgba(0,0,0,0.70)": "rgba(0,0,0,0.45)",
- "rgba(0,0,0,0.62)": "rgba(0,0,0,0.40)",
- "rgba(0,0,0,0.30)": "rgba(0,0,0,0.18)",
- "rgba(0,0,0,0.18)": "rgba(0,0,0,0.10)",
- "rgba(0,0,0,0.05)": "rgba(0,0,0,0.02)",
- }
- for oldValue, newValue := range replacements {
- html = strings.ReplaceAll(html, oldValue, newValue)
- }
- return html
-}
-
-type templatePaths struct {
- fs fs.FS
- base string
- layout string
-}
-
-func resolveTemplatePaths(layout string, templateFS fs.FS, templateDir string, fallbackFS fs.FS, fallbackDir string) (*templatePaths, string, error) {
- layout = strings.ToLower(strings.TrimSpace(layout))
- if layout == "" {
- layout = "split"
- }
-
- basePrimary := path.Join(templateDir, "base.html")
- layoutPrimary := path.Join(templateDir, layout+".html")
- if fileExists(templateFS, basePrimary) && fileExists(templateFS, layoutPrimary) {
- return &templatePaths{fs: templateFS, base: basePrimary, layout: layoutPrimary}, layout, nil
- }
-
- baseFallback := path.Join(fallbackDir, "base.html")
- layoutFallback := path.Join(fallbackDir, layout+".html")
- if fileExists(fallbackFS, baseFallback) && fileExists(fallbackFS, layoutFallback) {
- return &templatePaths{fs: fallbackFS, base: baseFallback, layout: layoutFallback}, layout, nil
- }
-
- return nil, "", fmt.Errorf("template files missing for layout %q", layout)
-}
-
-func fileExists(templateFS fs.FS, path string) bool {
- if templateFS == nil {
- return false
- }
- info, err := fs.Stat(templateFS, path)
- if err != nil {
- return false
- }
- return !info.IsDir()
-}
-
-func writeSlideHTML(outDir string, slideID int, html string) error {
- return writeFile(filepath.Join(outDir, fmt.Sprintf("slide-%d.html", slideID)), []byte(html))
-}
-
-func writeIndexHTML(outDir string, plan DeckPlan) error {
- items := make([]string, 0, len(plan.Slides))
- for _, s := range plan.Slides {
- items = append(items, fmt.Sprintf(`Slide %d - %s `, s.ID, s.ID, escapeHTML(s.Title)))
- }
- html := "\n " +
- "" + escapeHTML(plan.Title) + " " +
- "Open each slide HTML to preview before exporting to PPTX.
" +
- "" + strings.Join(items, "") + " " +
- "\n"
- return writeFile(filepath.Join(outDir, "index.html"), []byte(html))
-}
-
-func writeFile(path string, data []byte) error {
- if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
- return err
- }
- return os.WriteFile(path, data, 0644)
-}
-
-func trimToRunes(s string, maxRunes int) string {
- s = strings.TrimSpace(s)
- if maxRunes <= 0 {
- return ""
- }
- if utf8.RuneCountInString(s) <= maxRunes {
- return s
- }
- out := make([]rune, 0, maxRunes)
- for _, r := range s {
- out = append(out, r)
- if len(out) >= maxRunes {
- break
- }
- }
- return strings.TrimSpace(string(out)) + "..."
-}
-
-func planSafeDeckTitle(slide SlidePlan) string {
- _ = slide
- return "Key visual"
-}
-
-func mutedLabel(slide SlidePlan) string {
- if strings.TrimSpace(slide.Subtitle) != "" {
- return slide.Subtitle
- }
- if len(slide.Bullets) > 0 {
- return slide.Bullets[0]
- }
- return slide.Title
-}
-
-func escapeHTML(s string) string {
- replacer := strings.NewReplacer(
- "&", "&",
- "<", "<",
- ">", ">",
- "\"", """,
- "'", "'",
- )
- return replacer.Replace(s)
-}
-
-func ternaryInt(cond bool, a, b int) int {
- if cond {
- return a
- }
- return b
-}
-
-func normalizeTable(table *TableData, maxCols, maxRows int) TableTemplateData {
- if table == nil {
- return TableTemplateData{}
- }
- title := strings.TrimSpace(table.Title)
- notes := strings.TrimSpace(table.Notes)
-
- cols := make([]string, 0, maxCols)
- for _, c := range table.Columns {
- c = strings.TrimSpace(c)
- if c == "" {
- continue
- }
- cols = append(cols, c)
- if len(cols) >= maxCols {
- break
- }
- }
-
- rows := make([][]string, 0, maxRows)
- for _, r := range table.Rows {
- if len(rows) >= maxRows {
- break
- }
- row := make([]string, 0, len(cols))
- for i := 0; i < len(cols); i++ {
- var cell string
- if i < len(r) {
- switch v := r[i].(type) {
- case string:
- cell = strings.TrimSpace(v)
- case float64:
- cell = strings.TrimSpace(strconv.FormatFloat(v, 'f', -1, 64))
- case int:
- cell = strconv.Itoa(v)
- case int64:
- cell = strconv.FormatInt(v, 10)
- case json.Number:
- cell = v.String()
- default:
- if v != nil {
- cell = strings.TrimSpace(fmt.Sprintf("%v", v))
- }
- }
- }
- if cell == "" {
- cell = "-"
- }
- row = append(row, cell)
- }
- if len(row) > 0 {
- rows = append(rows, row)
- }
- }
-
- return TableTemplateData{
- Title: title,
- Columns: cols,
- Rows: rows,
- Notes: notes,
- Has: len(cols) > 0 && len(rows) > 0,
- }
-}
-
-func normalizeChart(chart *ChartData, theme Theme) ChartTemplateData {
- if chart == nil {
- return ChartTemplateData{}
- }
-
- chartType := strings.ToLower(strings.TrimSpace(chart.Type))
- if chartType == "" {
- chartType = "bar"
- }
- if chartType != "bar" && chartType != "line" && chartType != "pie" {
- return ChartTemplateData{}
- }
-
- title := strings.TrimSpace(chart.Title)
- notes := strings.TrimSpace(chart.Notes)
- categories := make([]string, 0, len(chart.Categories))
- for _, c := range chart.Categories {
- c = strings.TrimSpace(c)
- if c != "" {
- categories = append(categories, c)
- }
- }
-
- series := make([]ChartSeries, 0, len(chart.Series))
- maxLen := 0
- for _, s := range chart.Series {
- if len(s.Values) > maxLen {
- maxLen = len(s.Values)
- }
- }
- if len(categories) == 0 && maxLen > 0 {
- for i := 0; i < maxLen; i++ {
- categories = append(categories, fmt.Sprintf("%d", i+1))
- }
- }
- for _, s := range chart.Series {
- values := make([]float64, 0, len(categories))
- for i := 0; i < len(categories); i++ {
- if i < len(s.Values) {
- values = append(values, s.Values[i])
- } else {
- values = append(values, 0)
- }
- }
- series = append(series, ChartSeries{
- Name: strings.TrimSpace(s.Name),
- Values: values,
- })
- }
-
- if len(series) == 0 || len(categories) == 0 {
- return ChartTemplateData{}
- }
-
- colors := []string{theme.AccentColor, theme.PrimaryColor, "#94A3B8", "#38BDF8", "#F59E0B"}
-
- data := ChartTemplateData{
- Type: chartType,
- Title: title,
- Categories: categories,
- Series: series,
- Colors: colors,
- Notes: notes,
- Has: true,
- }
-
- switch chartType {
- case "bar":
- data.Bars = buildBarChart(series, categories, colors)
- case "line":
- data.Points, data.LinePaths = buildLineChart(series, categories)
- case "pie":
- data.Slices = buildPieChart(series, colors)
- }
-
- return data
-}
-
-func buildBarChart(series []ChartSeries, categories []string, colors []string) []ChartBar {
- const (
- w = 1000.0
- h = 420.0
- )
- maxVal := 0.0
- for _, s := range series {
- for _, v := range s.Values {
- if v > maxVal {
- maxVal = v
- }
- }
- }
- if maxVal <= 0 {
- maxVal = 1
- }
-
- groupCount := float64(len(categories))
- seriesCount := float64(len(series))
- groupWidth := w / groupCount
- barWidth := groupWidth / (seriesCount + 1)
-
- var bars []ChartBar
- for i, cat := range categories {
- for j, s := range series {
- value := s.Values[i]
- barHeight := (value / maxVal) * h
- x := (float64(i) * groupWidth) + (float64(j) * barWidth) + (barWidth * 0.2)
- y := h - barHeight
- bars = append(bars, ChartBar{
- X: x,
- Y: y,
- W: barWidth * 0.6,
- H: barHeight,
- Value: value,
- Color: colors[j%len(colors)],
- Label: cat,
- })
- }
- }
- return bars
-}
-
-func buildLineChart(series []ChartSeries, categories []string) ([][]ChartPoint, []string) {
- const (
- w = 1000.0
- h = 420.0
- )
- maxVal := 0.0
- for _, s := range series {
- for _, v := range s.Values {
- if v > maxVal {
- maxVal = v
- }
- }
- }
- if maxVal <= 0 {
- maxVal = 1
- }
- step := 0.0
- if len(categories) > 1 {
- step = w / float64(len(categories)-1)
- }
-
- points := make([][]ChartPoint, 0, len(series))
- paths := make([]string, 0, len(series))
-
- for _, s := range series {
- pts := make([]ChartPoint, 0, len(categories))
- for i := range categories {
- x := float64(i) * step
- y := h - ((s.Values[i] / maxVal) * h)
- pts = append(pts, ChartPoint{X: x, Y: y, Value: s.Values[i]})
- }
- points = append(points, pts)
- path := buildLinePath(pts)
- paths = append(paths, path)
- }
-
- return points, paths
-}
-
-func buildLinePath(points []ChartPoint) string {
- if len(points) == 0 {
- return ""
- }
- var b strings.Builder
- for i, p := range points {
- if i == 0 {
- fmt.Fprintf(&b, "M %.1f %.1f", p.X, p.Y)
- } else {
- fmt.Fprintf(&b, " L %.1f %.1f", p.X, p.Y)
- }
- }
- return b.String()
-}
-
-func buildPieChart(series []ChartSeries, colors []string) []ChartSlice {
- if len(series) == 0 {
- return nil
- }
- values := series[0].Values
- total := 0.0
- for _, v := range values {
- if v > 0 {
- total += v
- }
- }
- if total == 0 {
- total = 1
- }
-
- cx, cy := 240.0, 240.0
- r := 200.0
- start := 0.0
- var slices []ChartSlice
- for i, v := range values {
- angle := (v / total) * 2 * math.Pi
- end := start + angle
- large := 0
- if angle > math.Pi {
- large = 1
- }
- x1 := cx + r*math.Cos(start)
- y1 := cy + r*math.Sin(start)
- x2 := cx + r*math.Cos(end)
- y2 := cy + r*math.Sin(end)
- path := fmt.Sprintf("M %.1f %.1f L %.1f %.1f A %.1f %.1f 0 %d 1 %.1f %.1f Z", cx, cy, x1, y1, r, r, large, x2, y2)
- slices = append(slices, ChartSlice{
- Path: path,
- Color: colors[i%len(colors)],
- Label: fmt.Sprintf("%d", i+1),
- })
- start = end
- }
- return slices
-}
-
-func extractBulletsLabel(slide SlidePlan) string {
- // Try to extract a label from notes or use a default
- if strings.TrimSpace(slide.Notes) != "" {
- // Use first line of notes as label if short enough
- lines := strings.SplitN(slide.Notes, "\n", 2)
- if len(lines[0]) <= 30 {
- return strings.TrimSpace(lines[0])
- }
- }
- return "Overview"
-}
-
-func extractStats(slide SlidePlan) []StatItem {
- // Parse stats from slide data if available
- // Stats can be embedded in slide.Stats field or parsed from notes
- if slide.Stats != nil && len(slide.Stats) > 0 {
- stats := make([]StatItem, 0, len(slide.Stats))
- for _, s := range slide.Stats {
- if s.Value != "" {
- stats = append(stats, StatItem{
- Value: s.Value,
- Label: s.Label,
- })
- }
- }
- if len(stats) > 0 {
- return stats
- }
- }
-
- // Try to extract stats from bullets that look like metrics
- // e.g., "47% growth rate" -> Value: "47%", Label: "growth rate"
- return nil
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/sandbox_export.go b/services/response-api/internal/domain/agent/planners/slide_creator/steps/sandbox_export.go
deleted file mode 100644
index 20400ec3..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/sandbox_export.go
+++ /dev/null
@@ -1,817 +0,0 @@
-package steps
-
-import (
- "context"
- "encoding/base64"
- "encoding/json"
- "fmt"
- "os"
- "path/filepath"
- "sort"
- "strings"
-
- slidecreatorassets "jan-server/services/response-api/assets/slide_creator"
- "jan-server/services/response-api/internal/domain/agent"
- "jan-server/services/response-api/internal/domain/agent/planners"
- "jan-server/services/response-api/internal/domain/status"
- "jan-server/services/response-api/internal/domain/tool"
-
- "github.com/rs/zerolog/log"
-)
-
-// ensurePlaywrightBrowsersMCP installs Playwright browsers via MCP sandbox_shell_exec tool
-// Key fixes: cleans up incomplete installations, copies chrome to headless shell path if missing
-func ensurePlaywrightBrowsersMCP(ctx context.Context, mcpClient planners.MCPClient, cacheDir, conversationID, requestID string) error {
- // cacheDir is relative (e.g., ".cache/pptx_export")
- // Use $HOME for cross-provider compatibility (E2B: /home/user, AIO: /home/gem)
- fullCacheDir := "$HOME/" + cacheDir
- browsersDir := fullCacheDir + "/pw_browsers"
- nodeEnvDir := fullCacheDir + "/node_env"
-
- // Commands to run (using sudo for system deps)
- commands := []struct {
- name string
- cmd string
- }{
- {
- name: "Create cache directories",
- cmd: fmt.Sprintf("mkdir -p %s %s %s/outputs && chmod -R 777 %s 2>/dev/null || true", nodeEnvDir, browsersDir, fullCacheDir, fullCacheDir),
- },
- {
- name: "Initialize npm package",
- cmd: fmt.Sprintf("cd %s && [ -f package.json ] || npm init -y 2>/dev/null", nodeEnvDir),
- },
- {
- name: "Install npm packages",
- cmd: fmt.Sprintf("cd %s && PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm install --no-fund --no-audit playwright pptxgenjs 2>&1", nodeEnvDir),
- },
- {
- name: "Install Playwright system dependencies",
- cmd: fmt.Sprintf("cd %s && sudo npx playwright install-deps 2>&1 || true", nodeEnvDir),
- },
- {
- name: "Clean up incomplete browser installations",
- cmd: fmt.Sprintf(`cd %s && for d in chromium_headless_shell-*; do if [ -d "$d" ]; then exe="$d/chrome-headless-shell-linux64/chrome-headless-shell"; if [ ! -f "$exe" ]; then echo "Removing incomplete: $d"; rm -rf "$d"; fi; fi; done 2>/dev/null; echo "Cleanup done"`, browsersDir),
- },
- {
- name: "Install Playwright browsers",
- cmd: fmt.Sprintf(`cd %s && echo "Playwright version:" && npx playwright --version 2>&1 && echo "Installing browsers..." && PLAYWRIGHT_BROWSERS_PATH=%s npx playwright install chromium 2>&1`, nodeEnvDir, browsersDir),
- },
- {
- name: "Check and fix headless shell",
- cmd: fmt.Sprintf(`cd %s && echo "=== Current browser structure ===" && ls -la 2>&1 && EXPECTED="%s/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell" && if [ -f "$EXPECTED" ]; then echo "Headless shell exists at $EXPECTED"; else echo "Headless shell MISSING at $EXPECTED" && echo "Checking directory structure:" && ls -laR chromium_headless_shell-* 2>&1 | head -30 && CHROME="%s/chromium-1200/chrome-linux64/chrome" && if [ -f "$CHROME" ]; then echo "Chrome found, creating headless shell structure..." && mkdir -p chromium_headless_shell-1200/chrome-headless-shell-linux64 && cp "$CHROME" "$EXPECTED" 2>&1 && chmod +x "$EXPECTED" 2>&1 && echo "Copied chrome to $EXPECTED"; else echo "Chrome also missing at $CHROME"; fi; fi`, browsersDir, browsersDir, browsersDir),
- },
- {
- name: "Verify browser paths",
- cmd: fmt.Sprintf(`echo '=== Browser directories ===' && ls -la %s/ 2>&1 && echo '=== All chrome executables ===' && find %s -type f \( -name 'chrome' -o -name 'chrome-headless-shell' -o -name 'chromium' \) 2>/dev/null && echo '=== Checking headless shell ===' && ls -la %s/chromium_headless_shell-*/chrome-headless-shell-linux64/ 2>&1 || echo 'Headless shell dir not found' && echo '=== Checking regular chromium ===' && ls -la %s/chromium-*/chrome-linux64/ 2>&1 || echo 'Regular chromium dir not found'`, browsersDir, browsersDir, browsersDir, browsersDir),
- },
- }
-
- for _, c := range commands {
- log.Debug().Str("command", c.name).Msg("[slide_creator] Running shell command via MCP")
-
- result, err := mcpClient.CallTool(ctx, tool.CallRequest{
- Name: "sandbox_shell_exec",
- Arguments: map[string]interface{}{
- "command": c.cmd,
- },
- ConversationID: conversationID,
- RequestID: requestID,
- })
- if err != nil {
- return fmt.Errorf("sandbox_shell_exec failed for %s: %w", c.name, err)
- }
-
- if result.IsError {
- return fmt.Errorf("shell exec error for %s: %s", c.name, result.Error)
- }
-
- // Extract output for logging
- output := extractTextContent(result)
- if output != "" {
- lines := strings.Split(output, "\n")
- for i, line := range lines {
- if i < 5 {
- log.Debug().Str("line", line).Msg("[slide_creator] Shell output")
- } else if i == 5 {
- log.Debug().Int("remaining", len(lines)-5).Msg("[slide_creator] ... more lines")
- break
- }
- }
- }
- }
-
- return nil
-}
-
-func (e *SlideCreatorExecutor) executeExportPPTXViaMCP(ctx context.Context, params map[string]interface{}, input agent.ExecutionInput) (*agent.ExecutionResult, error) {
- if e.mcpClient == nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "MCP_NOT_CONFIGURED",
- Message: "MCP client not configured for PPTX export",
- Severity: status.ErrorSeverityFatal,
- },
- }, nil
- }
-
- // Start sandbox automatically before PPTX export (E2B only)
- if e.sandboxHelper != nil {
- opts := agent.StartSandboxOptions{
- Timeout: 1800, // 30 minutes
- }
- if input.PlanContext != nil {
- opts.ConversationID = input.PlanContext.ConversationID
- opts.RequestID = input.PlanContext.ResponseID
- }
- if opts.ConversationID != "" {
- if err := e.sandboxHelper.EnsureSandboxStarted(ctx, opts); err != nil {
- log.Warn().Err(err).Msg("[slide_creator] failed to start sandbox, continuing anyway")
- // Don't fail - sandbox might already be running
- }
- }
- }
-
- outDir := extractOutputDir(input)
- if outDir == "" {
- outDir = outputDirForPlan(input)
- }
- if _, err := os.Stat(outDir); err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "OUTPUT_DIR_ERROR",
- Message: fmt.Sprintf("output directory not found: %v", err),
- Severity: status.ErrorSeverityRetryable,
- },
- }, nil
- }
-
- mode := strings.ToLower(strings.TrimSpace(stringValue(params, "mode")))
- if mode == "" {
- mode = "dom"
- }
-
- payloads, rootName, err := collectInputFiles(outDir)
- if err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "EXPORT_INPUT_ERROR",
- Message: err.Error(),
- Severity: status.ErrorSeverityRetryable,
- },
- }, nil
- }
-
- outputFile := "presentation.pptx"
- // Cache dir is relative to workspace - the JS code will resolve it using process.cwd()
- // e2b-service sets cwd to /home/user/workspace/
- // So ".cache/pptx_export" becomes /home/user/workspace//.cache/pptx_export
- cacheDir := ".cache/pptx_export"
-
- // Extract conversation context for sandbox tool calls
- var conversationID, requestID string
- if input.PlanContext != nil {
- conversationID = input.PlanContext.ConversationID
- requestID = input.PlanContext.ResponseID
- }
-
- // Ensure Playwright browsers are installed via MCP sandbox_shell_exec
- log.Info().Str("cache_dir", cacheDir).Str("conversation_id", conversationID).Msg("[slide_creator] Ensuring Playwright browsers are installed via MCP")
- if err := ensurePlaywrightBrowsersMCP(ctx, e.mcpClient, cacheDir, conversationID, requestID); err != nil {
- log.Warn().Err(err).Msg("[slide_creator] Playwright browser installation may have failed, continuing anyway")
- }
-
- // Build the combined code that will be executed in the sandbox
- inputsJSON, _ := json.Marshal(payloads)
- code := buildSandboxWrapperCode(rootName, outputFile, mode, cacheDir, string(inputsJSON), slidecreatorassets.ExportPPTXFullScript)
-
- log.Debug().Int("code_size", len(code)).Msg("[slide_creator] Executing code via MCP sandbox_code_execute")
-
- // Execute via MCP sandbox_code_execute tool
- result, err := e.mcpClient.CallTool(ctx, tool.CallRequest{
- Name: "sandbox_code_execute",
- Arguments: map[string]interface{}{
- "code": code,
- "language": "nodejs",
- },
- ConversationID: conversationID,
- RequestID: requestID,
- })
- if err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "SANDBOX_EXPORT_FAILED",
- Message: fmt.Sprintf("sandbox_code_execute failed: %v", err),
- Severity: status.ErrorSeverityRetryable,
- },
- }, nil
- }
-
- if result.IsError {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "SANDBOX_EXPORT_ERROR",
- Message: fmt.Sprintf("sandbox execution error: %s", result.Error),
- Severity: status.ErrorSeverityRetryable,
- },
- }, nil
- }
-
- stdout := extractTextContent(result)
-
- log.Debug().Int("output_size", len(stdout)).Msg("[slide_creator] Received output from sandbox")
-
- // Extract PPTX base64
- pptxB64, err := extractBase64FromOutput(stdout)
- if err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "EXPORT_PARSE_ERROR",
- Message: err.Error(),
- Severity: status.ErrorSeverityRetryable,
- },
- }, nil
- }
-
- pptxBytes, err := base64.StdEncoding.DecodeString(pptxB64)
- if err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "EXPORT_DECODE_ERROR",
- Message: fmt.Sprintf("failed to decode PPTX base64: %v", err),
- Severity: status.ErrorSeverityRetryable,
- },
- }, nil
- }
-
- pptxPath := filepath.Join(outDir, outputFile)
- if err := os.WriteFile(pptxPath, pptxBytes, 0644); err != nil {
- return &agent.ExecutionResult{
- Status: status.StatusFailed,
- Error: &agent.ExecutionError{
- Code: "EXPORT_WRITE_ERROR",
- Message: fmt.Sprintf("failed to write PPTX: %v", err),
- Severity: status.ErrorSeverityRetryable,
- },
- }, nil
- }
-
- // Extract slide images from output
- imageNames := []string{}
- images, imgErr := extractImagesFromOutput(stdout)
- if imgErr != nil {
- log.Warn().Err(imgErr).Msg("[slide_creator] failed to parse slide images from export output")
- }
- for name, b64 := range images {
- data, err := base64.StdEncoding.DecodeString(b64)
- if err != nil {
- log.Warn().Err(err).Str("image", name).Msg("[slide_creator] failed to decode slide image")
- continue
- }
- if err := os.WriteFile(filepath.Join(outDir, name), data, 0644); err != nil {
- log.Warn().Err(err).Str("image", name).Msg("[slide_creator] failed to write slide image")
- continue
- }
- imageNames = append(imageNames, name)
- }
- sort.Strings(imageNames)
-
- // If no images were extracted from stdout, try to download from sandbox
- if len(imageNames) == 0 {
- outputDirFromStdout := extractOutputDirFromOutput(stdout)
- if outputDirFromStdout == "" {
- // Fallback: only used when OUTPUT_DIR marker not in stdout (code execution likely crashed)
- // This relative path works for E2B (resolved against workspace) but may fail for AIO
- // depending on Python cwd. Best-effort recovery only.
- outputDirFromStdout = ".outputs"
- log.Warn().Str("fallback_dir", outputDirFromStdout).Msg("[slide_creator] OUTPUT_DIR not found in stdout, using fallback")
- }
- if outputDirFromStdout != "" {
- downloaded, err := downloadSlideImagesMCP(ctx, e.mcpClient, outputDirFromStdout, outDir, conversationID, requestID)
- if err != nil {
- log.Warn().Err(err).Msg("[slide_creator] failed to download slide images from sandbox")
- } else if len(downloaded) > 0 {
- imageNames = append(imageNames, downloaded...)
- sort.Strings(imageNames)
- }
- }
- }
-
- output := map[string]interface{}{
- "type": "pptx_export",
- "output_dir": outDir,
- "pptx_path": pptxPath,
- "pptx_file": outputFile,
- "pptx_size": len(pptxBytes),
- "images": imageNames,
- "image_count": len(imageNames),
- }
- outputBytes, _ := json.Marshal(output)
-
- return &agent.ExecutionResult{
- Status: status.StatusCompleted,
- Output: outputBytes,
- }, nil
-}
-
-// collectInputFiles collects files from output directory for sandbox export
-func collectInputFiles(outDir string) ([]filePayload, string, error) {
- root := filepath.Clean(outDir)
- rootName := filepath.Base(root)
- if rootName == "" || rootName == "." {
- rootName = "slides"
- }
-
- payloads := []filePayload{}
- allowed := map[string]bool{
- ".html": true,
- ".json": true,
- ".css": true,
- ".svg": true,
- ".png": true,
- ".jpg": true,
- ".jpeg": true,
- ".webp": true,
- ".gif": true,
- ".txt": true,
- ".md": true,
- ".woff": true,
- ".woff2": true,
- ".ttf": true,
- ".otf": true,
- }
-
- err := filepath.WalkDir(root, func(path string, d os.DirEntry, err error) error {
- if err != nil {
- return err
- }
- if d.IsDir() {
- return nil
- }
- ext := strings.ToLower(filepath.Ext(path))
- if ext == ".pptx" || ext == ".zip" {
- return nil
- }
- if !allowed[ext] {
- return nil
- }
- rel, err := filepath.Rel(root, path)
- if err != nil {
- return err
- }
- data, err := os.ReadFile(path)
- if err != nil {
- return err
- }
- payloads = append(payloads, filePayload{
- Path: filepath.ToSlash(filepath.Join(rootName, rel)),
- B64: base64.StdEncoding.EncodeToString(data),
- })
- return nil
- })
- if err != nil {
- return nil, "", err
- }
- if len(payloads) == 0 {
- return nil, "", fmt.Errorf("no exportable files found in %s", outDir)
- }
- return payloads, rootName, nil
-}
-
-// buildSandboxWrapperCode builds the NodeJS code to execute in the sandbox
-func buildSandboxWrapperCode(inputDir, outFile, mode, cacheDir, inputsJSON, exportScript string) string {
- // Base64 encode inputs to avoid escaping issues
- inputsB64 := base64.StdEncoding.EncodeToString([]byte(inputsJSON))
- exportScriptB64 := base64.StdEncoding.EncodeToString([]byte(exportScript))
-
- code := fmt.Sprintf(`
-const fs = require("fs");
-const path = require("path");
-const { spawnSync, execSync } = require("child_process");
-
-const workdir = process.cwd();
-const INPUT_DIR = %s;
-const OUT_FILE = %s;
-const MODE = %s;
-// CACHE_DIR uses $HOME for cross-provider compatibility (E2B: /home/user, AIO: /home/gem)
-// Cache can be shared across conversations since it's just browsers/npm packages
-const CACHE_DIR = path.join(process.env.HOME || workdir, %s);
-
-const RUN_ID = String(Date.now());
-// OUTPUT_DIR must be inside workspace for sandbox_file_read compatibility
-// (e2b-service rejects paths that escape workspace)
-const OUTPUT_DIR = path.join(workdir, ".outputs", RUN_ID);
-const OUT_PATH = path.join(OUTPUT_DIR, path.basename(OUT_FILE));
-
-function run(cmd, args, opts) {
- const res = spawnSync(cmd, args, Object.assign({ encoding: "utf8", maxBuffer: 50 * 1024 * 1024 }, opts || {}));
- if (res.stdout) process.stdout.write(res.stdout);
- if (res.stderr) process.stderr.write(res.stderr);
- const code = (typeof res.status === "number") ? res.status : 1;
- return { code };
-}
-
-console.log("[SANDBOX] workdir=" + workdir);
-console.log("[SANDBOX] cache_dir=" + CACHE_DIR);
-
-// Decode base64 inputs
-const inputsB64 = %s;
-const exportScriptB64 = %s;
-const files = JSON.parse(Buffer.from(inputsB64, 'base64').toString('utf8'));
-const exportJs = Buffer.from(exportScriptB64, 'base64').toString('utf8');
-
-// Write input files into temp workdir
-for (const f of files) {
- const fullPath = path.join(workdir, f.path);
- fs.mkdirSync(path.dirname(fullPath), { recursive: true });
- fs.writeFileSync(fullPath, Buffer.from(f.b64, "base64"));
-}
-fs.writeFileSync(path.join(workdir, "export_pptx_full.js"), exportJs);
-console.log("[SANDBOX] wrote " + files.length + " input files + export_pptx_full.js");
-
-// Persistent env dirs
-const nodeEnvDir = path.join(CACHE_DIR, "node_env");
-const browsersDir = path.join(CACHE_DIR, "pw_browsers");
-fs.mkdirSync(nodeEnvDir, { recursive: true });
-fs.mkdirSync(browsersDir, { recursive: true });
-fs.mkdirSync(OUTPUT_DIR, { recursive: true });
-
-const pkgJson = path.join(nodeEnvDir, "package.json");
-if (!fs.existsSync(pkgJson)) {
- fs.writeFileSync(pkgJson, JSON.stringify({ name: "pptx_export_env", private: true }, null, 2));
-}
-
-// Ensure deps
-const nmPlaywright = path.join(nodeEnvDir, "node_modules", "playwright");
-const nmPptx = path.join(nodeEnvDir, "node_modules", "pptxgenjs");
-if (!fs.existsSync(nmPlaywright) || !fs.existsSync(nmPptx)) {
- console.log("[SANDBOX] Installing npm deps (playwright, pptxgenjs) into " + nodeEnvDir);
- const envNpm = Object.assign({}, process.env, {
- PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "1",
- });
- let r = run("npm", ["install", "--no-fund", "--no-audit", "playwright", "pptxgenjs"], { cwd: nodeEnvDir, env: envNpm });
- if (r.code !== 0) {
- console.error("[SANDBOX] ERROR: npm install failed");
- process.exit(2);
- }
-} else {
- console.log("[SANDBOX] npm deps already present in cache");
-}
-
-// Check browser installation
-console.log("[SANDBOX] Checking browser installation in " + browsersDir);
-try {
- const dirs = fs.readdirSync(browsersDir);
- console.log("[SANDBOX] Browser dirs: " + dirs.join(", "));
-} catch (e) {
- console.log("[SANDBOX] Could not list browser dirs: " + e.message);
-}
-
-// Install browsers if needed
-const pwBin = path.join(nodeEnvDir, "node_modules", ".bin", "playwright");
-if (fs.existsSync(pwBin)) {
- console.log("[SANDBOX] Ensuring browsers are installed via " + pwBin);
- const envPwInstall = Object.assign({}, process.env, {
- PLAYWRIGHT_BROWSERS_PATH: browsersDir,
- });
- let r = run(pwBin, ["install", "chromium"], { cwd: nodeEnvDir, env: envPwInstall });
- if (r.code !== 0) {
- console.warn("[SANDBOX] WARNING: playwright install chromium returned " + r.code);
- }
-}
-
-// Find chrome executables
-let chromeExe = "";
-let headlessShellExe = "";
-try {
- const findChrome = execSync("find " + browsersDir + " -type f -name 'chrome' -executable 2>/dev/null | grep -v headless | head -1", { encoding: "utf8" });
- chromeExe = findChrome.trim();
- if (chromeExe) console.log("[SANDBOX] Found chrome: " + chromeExe);
-
- const findHeadless = execSync("find " + browsersDir + " -type f -name 'chrome-headless-shell' -executable 2>/dev/null | head -1", { encoding: "utf8" });
- headlessShellExe = findHeadless.trim();
- if (headlessShellExe) console.log("[SANDBOX] Found headless shell: " + headlessShellExe);
-
- if (!headlessShellExe) {
- const findAny = execSync("find " + browsersDir + "/chromium_headless_shell* -type f -executable 2>/dev/null | head -1", { encoding: "utf8" });
- headlessShellExe = findAny.trim();
- if (headlessShellExe) console.log("[SANDBOX] Found alternative headless: " + headlessShellExe);
- }
-} catch (e) {
- console.log("[SANDBOX] Error finding chrome: " + e.message);
-}
-
-// Copy chrome to headless shell path if missing
-if (!headlessShellExe && chromeExe) {
- console.log("[SANDBOX] Copying chrome to headless shell path...");
- const targetDir = path.join(browsersDir, "chromium_headless_shell-1200", "chrome-headless-shell-linux64");
- const targetFile = path.join(targetDir, "chrome-headless-shell");
- try {
- fs.mkdirSync(targetDir, { recursive: true });
- try { fs.unlinkSync(targetFile); } catch (e) {}
- fs.copyFileSync(chromeExe, targetFile);
- fs.chmodSync(targetFile, 0o755);
- headlessShellExe = targetFile;
- console.log("[SANDBOX] Copied chrome to: " + targetFile);
- } catch (e) {
- console.log("[SANDBOX] Could not copy chrome: " + e.message);
- }
-}
-
-const envRun = Object.assign({}, process.env, {
- NODE_PATH: path.join(nodeEnvDir, "node_modules"),
- AIO_CACHE_DIR: CACHE_DIR,
- PLAYWRIGHT_BROWSERS_PATH: browsersDir,
- PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "0",
-});
-
-if (chromeExe) envRun.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH = chromeExe;
-if (headlessShellExe) envRun.PLAYWRIGHT_CHROMIUM_HEADLESS_SHELL_EXECUTABLE_PATH = headlessShellExe;
-
-const args = [path.join(workdir, "export_pptx_full.js"), "--in", INPUT_DIR, "--out", OUT_PATH, "--mode", MODE];
-console.log("[SANDBOX] Running: node " + args.join(" "));
-const res = spawnSync("node", args, { cwd: workdir, env: envRun, stdio: "inherit", maxBuffer: 50 * 1024 * 1024 });
-if (typeof res.status === "number" && res.status !== 0) process.exit(res.status);
-
-// Return PPTX as base64
-const pptx = fs.readFileSync(OUT_PATH);
-// Output absolute path for cross-provider compatibility:
-// - E2B: e2b-service accepts absolute paths within workspace (passes startswith check)
-// - AIO: Python opens absolute path directly without cwd dependency
-console.log("===OUTPUT_DIR===");
-console.log(OUTPUT_DIR);
-console.log("===OUTPUT_DIR_START===");
-console.log(OUTPUT_DIR);
-console.log("===OUTPUT_DIR_END===");
-console.log("===BASE64_START===");
-console.log(pptx.toString("base64"));
-console.log("===BASE64_END===");
-
-// Get slide images
-let images = {};
-try {
- const imageFiles = fs.readdirSync(OUTPUT_DIR).filter((f) => /^slide-\d+\.png$/i.test(f));
- for (const f of imageFiles) {
- images[f] = fs.readFileSync(path.join(OUTPUT_DIR, f)).toString("base64");
- }
-} catch (e) {
- console.log("[SANDBOX] Could not read slide images: " + e.message);
-}
-console.log("===IMAGES_START===");
-console.log(JSON.stringify(images));
-console.log("===IMAGES_END===");
-`,
- jsQuoteMCP(inputDir),
- jsQuoteMCP(outFile),
- jsQuoteMCP(mode),
- jsQuoteMCP(cacheDir),
- jsQuoteMCP(inputsB64),
- jsQuoteMCP(exportScriptB64),
- )
-
- return strings.TrimSpace(code) + "\n"
-}
-
-func jsQuoteMCP(s string) string {
- encoded, _ := json.Marshal(s)
- return string(encoded)
-}
-
-// extractTextContent extracts text content from MCP result
-// If the content is a JSON object with a "stdout" field, extracts that instead
-func extractTextContent(result *tool.Result) string {
- if result == nil {
- return ""
- }
- for _, content := range result.Content {
- if content.Type == "text" && content.Text != "" {
- text := content.Text
- // Check if this is a JSON response with stdout field (from sandbox_code_execute)
- var codeResult struct {
- Stdout string `json:"stdout"`
- }
- if err := json.Unmarshal([]byte(text), &codeResult); err == nil && codeResult.Stdout != "" {
- return codeResult.Stdout
- }
- return text
- }
- }
- return ""
-}
-
-func extractBase64FromOutput(output string) (string, error) {
- start := strings.Index(output, "===BASE64_START===")
- end := strings.Index(output, "===BASE64_END===")
- if start == -1 || end == -1 || end <= start {
- return "", fmt.Errorf("base64 markers not found in output")
- }
- chunk := strings.TrimSpace(output[start+len("===BASE64_START===") : end])
- if chunk == "" {
- return "", fmt.Errorf("base64 content empty")
- }
- return chunk, nil
-}
-
-func extractImagesFromOutput(output string) (map[string]string, error) {
- start := strings.Index(output, "===IMAGES_START===")
- end := strings.Index(output, "===IMAGES_END===")
- if start == -1 || end == -1 || end <= start {
- return map[string]string{}, nil
- }
- chunk := strings.TrimSpace(output[start+len("===IMAGES_START===") : end])
- if chunk == "" {
- return map[string]string{}, nil
- }
- var decoded map[string]string
- if err := json.Unmarshal([]byte(chunk), &decoded); err != nil {
- return nil, err
- }
- return decoded, nil
-}
-
-func extractOutputDirFromOutput(output string) string {
- singleMarker := "===OUTPUT_DIR==="
- if idx := strings.Index(output, singleMarker); idx != -1 {
- rest := output[idx+len(singleMarker):]
- rest = strings.TrimLeft(rest, "\r\n")
- if rest == "" {
- return ""
- }
- if lineEnd := strings.IndexAny(rest, "\r\n"); lineEnd != -1 {
- rest = rest[:lineEnd]
- }
- return strings.TrimSpace(rest)
- }
- start := strings.Index(output, "===OUTPUT_DIR_START===")
- end := strings.Index(output, "===OUTPUT_DIR_END===")
- if start == -1 || end == -1 || end <= start {
- return ""
- }
- chunk := strings.TrimSpace(output[start+len("===OUTPUT_DIR_START===") : end])
- return chunk
-}
-
-// downloadSlideImagesMCP downloads slide images from sandbox using MCP tools
-func downloadSlideImagesMCP(ctx context.Context, mcpClient planners.MCPClient, outputDir, localDir, conversationID, requestID string) ([]string, error) {
- // List files in sandbox output directory via MCP
- listResult, err := mcpClient.CallTool(ctx, tool.CallRequest{
- Name: "sandbox_file_list",
- Arguments: map[string]interface{}{
- "path": outputDir,
- },
- ConversationID: conversationID,
- RequestID: requestID,
- })
- if err != nil {
- return nil, fmt.Errorf("sandbox_file_list failed: %w", err)
- }
-
- if listResult.IsError {
- return nil, fmt.Errorf("file list error: %s", listResult.Error)
- }
-
- // Parse file list from result
- listOutput := extractTextContent(listResult)
- if listOutput == "" {
- return nil, nil
- }
-
- // Try to parse as JSON array (mcp-tools format: [{"name": "...", "is_dir": false, "size": 123}, ...])
- var fileArray []struct {
- Name string `json:"name"`
- IsDir bool `json:"is_dir"`
- Size int64 `json:"size"`
- }
- if err := json.Unmarshal([]byte(listOutput), &fileArray); err != nil {
- // Try legacy format: {"files": [...]}
- var fileList struct {
- Files []struct {
- Name string `json:"name"`
- Path string `json:"path"`
- } `json:"files"`
- }
- if err := json.Unmarshal([]byte(listOutput), &fileList); err != nil {
- // If not JSON, try line-by-line parsing
- return parseAndDownloadImages(ctx, mcpClient, listOutput, outputDir, localDir, conversationID, requestID)
- }
- // Convert legacy format to array format
- for _, f := range fileList.Files {
- fileArray = append(fileArray, struct {
- Name string `json:"name"`
- IsDir bool `json:"is_dir"`
- Size int64 `json:"size"`
- }{Name: f.Name})
- }
- }
-
- var names []string
- for _, f := range fileArray {
- name := f.Name
- if f.IsDir {
- continue
- }
- if !strings.HasPrefix(strings.ToLower(name), "slide-") || !strings.HasSuffix(strings.ToLower(name), ".png") {
- continue
- }
-
- // Read file from sandbox (path is relative to workspace)
- path := outputDir + "/" + name
-
- readResult, err := mcpClient.CallTool(ctx, tool.CallRequest{
- Name: "sandbox_file_read",
- Arguments: map[string]interface{}{
- "path": path,
- },
- ConversationID: conversationID,
- RequestID: requestID,
- })
- if err != nil {
- log.Warn().Err(err).Str("file", name).Msg("[slide_creator] failed to read image from sandbox")
- continue
- }
-
- if readResult.IsError {
- log.Warn().Str("error", readResult.Error).Str("file", name).Msg("[slide_creator] sandbox file read error")
- continue
- }
-
- content := extractTextContent(readResult)
- if content == "" {
- continue
- }
-
- // Content might be base64 encoded
- var data []byte
- if decoded, err := base64.StdEncoding.DecodeString(content); err == nil {
- data = decoded
- } else {
- data = []byte(content)
- }
-
- localPath := filepath.Join(localDir, name)
- if err := os.WriteFile(localPath, data, 0644); err != nil {
- log.Warn().Err(err).Str("file", name).Msg("[slide_creator] failed to write image")
- continue
- }
- names = append(names, name)
- }
-
- return names, nil
-}
-
-func parseAndDownloadImages(ctx context.Context, mcpClient planners.MCPClient, listOutput, outputDir, localDir, conversationID, requestID string) ([]string, error) {
- var names []string
- lines := strings.Split(listOutput, "\n")
- for _, line := range lines {
- name := strings.TrimSpace(line)
- if name == "" {
- continue
- }
- if !strings.HasPrefix(strings.ToLower(name), "slide-") || !strings.HasSuffix(strings.ToLower(name), ".png") {
- continue
- }
-
- path := outputDir + "/" + name
-
- readResult, err := mcpClient.CallTool(ctx, tool.CallRequest{
- Name: "sandbox_file_read",
- Arguments: map[string]interface{}{
- "path": path,
- },
- ConversationID: conversationID,
- RequestID: requestID,
- })
- if err != nil {
- continue
- }
- if readResult.IsError {
- continue
- }
-
- content := extractTextContent(readResult)
- if content == "" {
- continue
- }
-
- var data []byte
- if decoded, err := base64.StdEncoding.DecodeString(content); err == nil {
- data = decoded
- } else {
- data = []byte(content)
- }
-
- localPath := filepath.Join(localDir, name)
- if err := os.WriteFile(localPath, data, 0644); err != nil {
- continue
- }
- names = append(names, name)
- }
- return names, nil
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/schemas.go b/services/response-api/internal/domain/agent/planners/slide_creator/steps/schemas.go
deleted file mode 100644
index 4bfe66cc..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/schemas.go
+++ /dev/null
@@ -1,167 +0,0 @@
-package steps
-
-// TemplatePickSchema is the JSON schema for template selection.
-var TemplatePickSchema = map[string]any{
- "type": "object",
- "properties": map[string]any{
- "choices": map[string]any{
- "type": "array",
- "items": map[string]any{
- "type": "object",
- "properties": map[string]any{
- "id": map[string]any{
- "type": "integer",
- },
- "reason": map[string]any{
- "type": "string",
- },
- },
- "required": []string{"id", "reason"},
- "additionalProperties": false,
- },
- },
- },
- "required": []string{"choices"},
- "additionalProperties": false,
-}
-
-var slidePlanObjectSchema = map[string]any{
- "type": "object",
- "properties": map[string]any{
- "id": map[string]any{"type": "integer"},
- "layout": map[string]any{"type": "string"},
- "title": map[string]any{"type": "string"},
- "subtitle": map[string]any{"type": "string"},
- "bullets": map[string]any{
- "type": "array",
- "items": map[string]any{"type": "string"},
- },
- "images": map[string]any{
- "type": "array",
- "items": map[string]any{
- "type": "object",
- "properties": map[string]any{
- "src": map[string]any{"type": "string"},
- "alt": map[string]any{"type": "string"},
- "caption": map[string]any{"type": "string"},
- },
- "required": []string{"src", "alt"},
- "additionalProperties": false,
- },
- },
- "table": map[string]any{
- "type": "object",
- "properties": map[string]any{
- "title": map[string]any{"type": "string"},
- "columns": map[string]any{
- "type": "array",
- "items": map[string]any{"type": "string"},
- },
- "rows": map[string]any{
- "type": "array",
- "items": map[string]any{
- "type": "array",
- "items": map[string]any{"type": "string"},
- },
- },
- "notes": map[string]any{"type": "string"},
- },
- "additionalProperties": false,
- },
- "chart": map[string]any{
- "type": "object",
- "properties": map[string]any{
- "type": map[string]any{"type": "string"},
- "title": map[string]any{"type": "string"},
- "categories": map[string]any{
- "type": "array",
- "items": map[string]any{"type": "string"},
- },
- "series": map[string]any{
- "type": "array",
- "items": map[string]any{
- "type": "object",
- "properties": map[string]any{
- "name": map[string]any{"type": "string"},
- "values": map[string]any{
- "type": "array",
- "items": map[string]any{"type": "number"},
- },
- },
- "required": []string{"values"},
- "additionalProperties": false,
- },
- },
- "notes": map[string]any{"type": "string"},
- },
- "additionalProperties": false,
- },
- "notes": map[string]any{"type": "string"},
- },
- "required": []string{"id", "title"},
- "additionalProperties": false,
-}
-
-var deckThemeSchema = map[string]any{
- "type": "object",
- "properties": map[string]any{
- "title": map[string]any{"type": "string"},
- "theme": map[string]any{
- "type": "object",
- "properties": map[string]any{
- "primary_color": map[string]any{"type": "string"},
- "accent_color": map[string]any{"type": "string"},
- "background_color": map[string]any{"type": "string"},
- "text_color": map[string]any{"type": "string"},
- "font_family": map[string]any{"type": "string"},
- },
- "required": []string{"primary_color", "accent_color", "background_color", "text_color", "font_family"},
- "additionalProperties": false,
- },
- },
- "required": []string{"title", "theme"},
- "additionalProperties": false,
-}
-
-// DeckPlanSchema is the JSON schema for HTML slide planning.
-var DeckPlanSchema = map[string]any{
- "type": "object",
- "properties": map[string]any{
- "title": map[string]any{
- "type": "string",
- },
- "theme": map[string]any{
- "type": "object",
- "properties": map[string]any{
- "primary_color": map[string]any{"type": "string"},
- "accent_color": map[string]any{"type": "string"},
- "background_color": map[string]any{"type": "string"},
- "text_color": map[string]any{"type": "string"},
- "font_family": map[string]any{"type": "string"},
- },
- "required": []string{"primary_color", "accent_color", "background_color", "text_color", "font_family"},
- "additionalProperties": false,
- },
- "slides": map[string]any{
- "type": "array",
- "items": slidePlanObjectSchema,
- },
- },
- "required": []string{"title", "theme", "slides"},
- "additionalProperties": false,
-}
-
-// DeckThemeSchema is the JSON schema for deck theme selection.
-var DeckThemeSchema = deckThemeSchema
-
-// SlidePlanSchema is the JSON schema for a single slide plan.
-var SlidePlanSchema = map[string]any{
- "type": "object",
- "properties": map[string]any{
- "slide": slidePlanObjectSchema,
- "image_query": map[string]any{"type": "string"},
- "image_required": map[string]any{"type": "boolean"},
- },
- "required": []string{"slide"},
- "additionalProperties": false,
-}
diff --git a/services/response-api/internal/domain/agent/planners/slide_creator/steps/slide_body.go b/services/response-api/internal/domain/agent/planners/slide_creator/steps/slide_body.go
deleted file mode 100644
index 95d1b776..00000000
--- a/services/response-api/internal/domain/agent/planners/slide_creator/steps/slide_body.go
+++ /dev/null
@@ -1,107 +0,0 @@
-package steps
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "strings"
-
- "jan-server/services/response-api/internal/domain/agent"
-)
-
-func (e *SlideCreatorExecutor) generateSlideBody(ctx context.Context, input agent.ExecutionInput, plan DeckPlan, slide SlidePlan) (string, error) {
- planJSON, _ := json.Marshal(plan.Theme)
- slideJSON, _ := json.Marshal(slide)
- prompt := fmt.Sprintf(`You are generating the BODY HTML for a single slide.
-
-Output: ONLY an HTML fragment for the body area (no , , ,