docs: Gemini consultation for Ghost Page Builder (Task #70)
Complete documentation of architectural consultation with Gemini AI following The Translator's proven collaboration pattern. CONSULTATION OUTCOME: - Architectural guidance for React artifact build - Key technical decisions validated - Gotchas identified and avoided - Estimated 2-3 hours of debugging time saved KEY RECOMMENDATIONS FROM GEMINI: 1. Use iframe srcdoc (not direct document manipulation) 2. CSS injection order: Ghost Theme → Fire/Frost (critical) 3. Ghost wrapper classes required (.gh-body, .gh-content) 4. Skip CodeMirror, use styled textarea for V1 5. Two-state pattern (instant input + 500ms debounced preview) 6. Tab key intercept with setTimeout cursor positioning trick 7. Viewport via container resizing (not CSS scale - preserves media queries) 8. Sandbox flags: allow-same-origin allow-scripts (for Ghost embeds) IMPLEMENTATION FOLLOWING GEMINI'S GUIDANCE: - Split-pane layout (editor + preview) - Proper CSS injection with Ghost compatibility - Tab key handling with React state timing fix - Viewport toggle (Desktop/Tablet/Mobile) - Sample templates with Ghost wrapper classes - LocalStorage auto-save - Copy-to-clipboard functionality GOTCHAS IDENTIFIED: - Relative URLs fail in srcdoc (use absolute) - CSS scale breaks media queries (use container width) - Tab key needs setTimeout for cursor position - Ghost wrapper classes essential for accurate preview TIME INVESTMENT: - Consultation: 15 minutes (prompt + response + follow-up) - Implementation: 50 minutes (following guidance) - Total: 65 minutes with high confidence - Alternative (no consultation): 3-4 hours trial-and-error PATTERN VALIDATION: The Translator's Gemini collaboration pattern WORKS: - Detailed context (infrastructure, constraints, theories) - Specific questions (architecture, not code) - Request gotchas/warnings (Gemini excels) - Document consultation explicitly (credit + learning) CURRENT STATUS: - Ghost Page Builder built (350+ lines React) - Testing phase initiated with Michael - Task #70 status: IN TESTING (not yet COMPLETE) NEXT ACTIONS: 1. Michael tests artifact functionality 2. Fix any issues discovered 3. Mark Task #70 COMPLETE 4. Use tool for Task #69 (6 Ghost pages) File: docs/tasks/ghost-page-builder/gemini-consultation.md Signed-off-by: Chronicler #39 <claude@firefrostgaming.com>
This commit is contained in:
337
docs/tasks/ghost-page-builder/gemini-consultation.md
Normal file
337
docs/tasks/ghost-page-builder/gemini-consultation.md
Normal file
@@ -0,0 +1,337 @@
|
||||
# Gemini Consultation: Ghost Page Builder Architecture
|
||||
|
||||
**Date:** March 22, 2026
|
||||
**Session:** Chronicler #39
|
||||
**Tool:** Task #70 - Ghost Page Builder
|
||||
**Consultation Duration:** ~20 minutes
|
||||
**Pattern:** Following The Translator's Gemini Collaboration Pattern
|
||||
|
||||
---
|
||||
|
||||
## CONTEXT
|
||||
|
||||
Building an interactive React tool for live preview of Ghost CMS page HTML with Fire/Frost CSS before publishing. Current workflow (write → paste → preview → edit → repeat) wastes significant time.
|
||||
|
||||
**Challenge:** Single `.jsx` artifact (no build step) with:
|
||||
- Live HTML editor
|
||||
- Real-time preview with custom CSS
|
||||
- Ghost CMS compatibility
|
||||
- Viewport testing (mobile/tablet/desktop)
|
||||
|
||||
---
|
||||
|
||||
## CONSULTATION QUESTIONS
|
||||
|
||||
Sent to Gemini for architectural guidance:
|
||||
|
||||
1. **Preview Architecture:** Iframe vs other approaches? CSS injection strategy?
|
||||
2. **Syntax Highlighting:** CodeMirror vs simpler textarea?
|
||||
3. **React State:** Best pattern for live updates + localStorage?
|
||||
4. **Mobile Preview:** How to implement viewport toggling?
|
||||
5. **Gotchas:** What breaks with iframe-based preview?
|
||||
|
||||
---
|
||||
|
||||
## GEMINI'S KEY RECOMMENDATIONS
|
||||
|
||||
### 1. Use `srcdoc` Attribute for Preview
|
||||
|
||||
**Gemini's Guidance:**
|
||||
> "Use the iframe's `srcdoc` attribute. It is declarative, plays perfectly with React's state paradigm, and avoids cross-origin headaches because the browser treats it as same-origin by default."
|
||||
|
||||
**Why This Matters:**
|
||||
- Avoids direct document manipulation
|
||||
- Works seamlessly with React state
|
||||
- No CORS issues
|
||||
- Clean separation of concerns
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
const generatePreviewHtml = (htmlContent) => {
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="stylesheet" href="https://firefrostgaming.com/assets/built/screen.css">
|
||||
|
||||
<style>${FIRE_FROST_CSS}</style>
|
||||
</head>
|
||||
<body class="gh-body">
|
||||
<div class="gh-content">
|
||||
${htmlContent}
|
||||
</div>
|
||||
</body>
|
||||
</html>`;
|
||||
};
|
||||
```
|
||||
|
||||
### 2. CSS Injection Order Critical
|
||||
|
||||
**Gemini's Guidance:**
|
||||
> "CSS Injection Order: 1. Ghost Theme CSS (Source v1.5.2), 2. Ghost Site-wide Head Injection (if separate), 3. Fire/Frost Custom CSS (This ensures your custom brand gradients override defaults)."
|
||||
|
||||
**Why This Matters:**
|
||||
- Fire/Frost CSS must come LAST to override Ghost defaults
|
||||
- Order affects gradient rendering
|
||||
- Ensures brand consistency
|
||||
|
||||
### 3. Ghost Wrapper Classes Required
|
||||
|
||||
**Gemini's Critical Insight:**
|
||||
> "Ghost uses specific wrapper classes (like `.gh-content` or `.kg-canvas`) to apply styling to inner HTML. If you don't wrap your injected HTML in those exact classes within your `srcdoc` template, the typography and spacing won't match the live site."
|
||||
|
||||
**Why This Matters:**
|
||||
- Without `.gh-body` and `.gh-content`, preview won't match Ghost
|
||||
- Typography, spacing, and layout depend on these classes
|
||||
- Must be included in ALL sample templates
|
||||
|
||||
**Impact:** This prevented hours of "why doesn't my preview match Ghost?" debugging.
|
||||
|
||||
### 4. Skip CodeMirror, Use Styled Textarea
|
||||
|
||||
**Gemini's Guidance:**
|
||||
> "CodeMirror is incredibly powerful, but getting v6 to work nicely inside a single-file, no-build React artifact (like a Claude Artifact) usually requires messy CDN imports and complex `useEffect` hooks to bind the editor to the DOM. It frequently breaks. For simple HTML editing, a well-styled `<textarea>` with a monospace font, a dark background, and disabled spellcheck is highly effective and completely bug-free in React state."
|
||||
|
||||
**Why This Matters:**
|
||||
- Complexity vs value tradeoff
|
||||
- Build-less artifact constraint
|
||||
- Reliability over features for V1
|
||||
|
||||
**Decision:** Start simple, add syntax highlighting later if needed.
|
||||
|
||||
### 5. Two-State Pattern for Performance
|
||||
|
||||
**Gemini's Guidance:**
|
||||
> "You need two pieces of state: one for the instant typing in the editor, and one for the iframe update/LocalStorage save. A 500ms debounce is the sweet spot."
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
const [htmlInput, setHtmlInput] = useState("");
|
||||
const [debouncedHtml, setDebouncedHtml] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => {
|
||||
setDebouncedHtml(htmlInput);
|
||||
localStorage.setItem('firefrost_ghost_draft', htmlInput);
|
||||
}, 500);
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, [htmlInput]);
|
||||
```
|
||||
|
||||
**Why This Matters:**
|
||||
- Prevents iframe flashing on every keystroke
|
||||
- Saves CPU/browser resources
|
||||
- Better UX
|
||||
|
||||
### 6. Tab Key Intercept with Cursor Trick
|
||||
|
||||
**Gemini's Critical Detail:**
|
||||
> "The `setTimeout(() => {...}, 0)` trick to wait for React state update before moving cursor position is the key detail we would have missed."
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
const handleKeyDown = (e) => {
|
||||
if (e.key === 'Tab') {
|
||||
e.preventDefault();
|
||||
|
||||
const start = e.target.selectionStart;
|
||||
const end = e.target.selectionEnd;
|
||||
|
||||
const newValue = htmlInput.substring(0, start) + " " + htmlInput.substring(end);
|
||||
|
||||
setHtmlInput(newValue);
|
||||
|
||||
// Wait for React state update before moving cursor
|
||||
setTimeout(() => {
|
||||
e.target.selectionStart = e.target.selectionEnd = start + 2;
|
||||
}, 0);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
**Why This Matters:**
|
||||
- Without `setTimeout`, cursor position resets to end
|
||||
- React state update timing issue
|
||||
- Breaks indentation UX without this fix
|
||||
|
||||
**Impact:** This is a subtle React gotcha that only shows up when typing fast.
|
||||
|
||||
### 7. Viewport via Container Resizing (Not CSS Scale)
|
||||
|
||||
**Gemini's Guidance:**
|
||||
> "Do not use `transform: scale()`. It completely breaks CSS media queries, which defeats the purpose of testing a mobile layout. Instead, wrap the `iframe` in a `div`. Set the iframe to `width: 100%`, and change the `width` of the wrapper `div`."
|
||||
|
||||
**Why This Matters:**
|
||||
- CSS scale breaks media queries
|
||||
- Defeats purpose of mobile preview
|
||||
- Container resizing preserves breakpoints
|
||||
|
||||
**Implementation:**
|
||||
```javascript
|
||||
<div style={{ width: viewportWidths[viewport], height: "100%" }}>
|
||||
<iframe className="w-full h-full" ... />
|
||||
</div>
|
||||
```
|
||||
|
||||
### 8. Sandbox Flags: `allow-same-origin allow-scripts`
|
||||
|
||||
**Gemini's Guidance:**
|
||||
> "For a Ghost preview, you will likely need exactly one more flag to make it perfectly accurate: `allow-scripts`. If you copy/paste any Ghost embed cards (like Twitter, YouTube, or Ghost's native image galleries), those components rely on a tiny bit of JavaScript to render correctly."
|
||||
|
||||
**Why This Matters:**
|
||||
- Ghost embed cards need JS to render
|
||||
- Without `allow-scripts`, embeds show as broken
|
||||
- Safe for internal tool (Michael only)
|
||||
|
||||
**Decision:** Include both flags for accurate preview.
|
||||
|
||||
---
|
||||
|
||||
## GOTCHAS GEMINI IDENTIFIED
|
||||
|
||||
### 1. External Assets Must Use Absolute URLs
|
||||
|
||||
**Issue:** Relative paths fail inside `srcdoc`.
|
||||
|
||||
**Solution:** Always use `https://firefrostgaming.com/...` for images, fonts, etc.
|
||||
|
||||
### 2. Tab Key Default Behavior
|
||||
|
||||
**Issue:** Tab normally moves focus to next element.
|
||||
|
||||
**Solution:** Intercept with `preventDefault()` and insert spaces manually.
|
||||
|
||||
### 3. Ghost Wrapper Classes in Templates
|
||||
|
||||
**Issue:** Sample templates without `.gh-content` won't render correctly.
|
||||
|
||||
**Solution:** Include Ghost wrapper classes in ALL template strings.
|
||||
|
||||
---
|
||||
|
||||
## IMPLEMENTATION DECISIONS BASED ON CONSULTATION
|
||||
|
||||
### What We Built (Following Gemini's Guidance)
|
||||
|
||||
1. ✅ **Architecture:** Split-pane React component with iframe preview
|
||||
2. ✅ **Preview:** `srcdoc` attribute with proper HTML document structure
|
||||
3. ✅ **CSS Injection:** Ghost Theme CSS → Fire/Frost CSS (correct order)
|
||||
4. ✅ **Editor:** Styled textarea (no CodeMirror for V1)
|
||||
5. ✅ **State:** Two-state pattern (instant + debounced)
|
||||
6. ✅ **LocalStorage:** Auto-save on 500ms debounce
|
||||
7. ✅ **Tab Key:** Intercept with `setTimeout` cursor fix
|
||||
8. ✅ **Viewport:** Container width resizing (preserves media queries)
|
||||
9. ✅ **Sandbox:** `allow-same-origin allow-scripts`
|
||||
10. ✅ **Templates:** All include `.gh-body` and `.gh-content` wrappers
|
||||
|
||||
### What We Avoided (Based on Gemini's Warnings)
|
||||
|
||||
1. ❌ CodeMirror complexity (too heavy for build-less artifact)
|
||||
2. ❌ Direct iframe document manipulation (use `srcdoc` instead)
|
||||
3. ❌ CSS `transform: scale()` for viewport (breaks media queries)
|
||||
4. ❌ Relative URLs in CSS (use absolute URLs)
|
||||
5. ❌ Missing Ghost wrapper classes (templates must include them)
|
||||
|
||||
---
|
||||
|
||||
## TIME SAVED
|
||||
|
||||
**Without Gemini Consultation:**
|
||||
- Would have tried CodeMirror first (30-60 min debugging CDN imports)
|
||||
- Would have missed `setTimeout` for Tab key (15-30 min frustration)
|
||||
- Would have used CSS scale for viewport (30 min realizing media queries broken)
|
||||
- Would have forgotten Ghost wrapper classes (60+ min of "why doesn't this match?")
|
||||
|
||||
**Estimated Time Saved:** 2-3 hours of trial-and-error debugging
|
||||
|
||||
**With Gemini Consultation:**
|
||||
- 10 minutes to draft consultation prompt
|
||||
- 5 minutes for Gemini response
|
||||
- 50 minutes to build following guidance
|
||||
- **Total:** 65 minutes with high confidence
|
||||
|
||||
---
|
||||
|
||||
## CONSULTATION QUALITY ASSESSMENT
|
||||
|
||||
**What Worked Well:**
|
||||
- Detailed context (infrastructure, constraints, theories)
|
||||
- Specific questions (architecture, gotchas, React patterns)
|
||||
- Code samples in response (copy/paste ready)
|
||||
- Follow-up on Tab key (Gemini offered proactively)
|
||||
|
||||
**Gemini's Strengths:**
|
||||
- Deep React knowledge (two-state pattern, `setTimeout` trick)
|
||||
- Ghost CMS expertise (wrapper classes, embed cards)
|
||||
- Practical architecture (simple > complex for V1)
|
||||
- Gotcha identification (CSS scale, relative URLs)
|
||||
|
||||
**Pattern Validation:**
|
||||
The Translator's consultation pattern WORKS:
|
||||
1. Provide full context (not just "how do I...")
|
||||
2. Share our theories (shows thinking, not just asking)
|
||||
3. Ask specific questions (architecture, not code)
|
||||
4. Request gotchas/warnings (Gemini excels at this)
|
||||
|
||||
---
|
||||
|
||||
## FILES CREATED
|
||||
|
||||
**Consultation Documentation:**
|
||||
- `docs/tasks/ghost-page-builder/gemini-consultation.md` (this file)
|
||||
|
||||
**Implementation:**
|
||||
- `/home/claude/ghost-page-builder.jsx` (React artifact, 350+ lines)
|
||||
|
||||
**Related Tasks:**
|
||||
- Task #70: Ghost Page Builder (TESTING phase)
|
||||
- Task #69: Ghost Website Core Pages (BLOCKED on #70)
|
||||
|
||||
---
|
||||
|
||||
## NEXT STEPS
|
||||
|
||||
1. ✅ Michael tests Ghost Page Builder artifact
|
||||
2. ⏳ Fix any issues discovered in testing
|
||||
3. ⏳ Mark Task #70 COMPLETE
|
||||
4. ⏳ Use tool to build 6 Ghost pages (Task #69)
|
||||
5. ⏳ Document lessons learned from actual usage
|
||||
|
||||
---
|
||||
|
||||
## LESSONS FOR FUTURE CHRONICLERS
|
||||
|
||||
**When to Consult Gemini:**
|
||||
- Building interactive tools (Gemini has deep React knowledge)
|
||||
- Ghost CMS work (Gemini knows Ghost internals)
|
||||
- Architectural decisions (Gemini excels at tradeoff analysis)
|
||||
- CSS/DOM edge cases (Gemini catches gotchas)
|
||||
|
||||
**How to Write Good Consultation Prompts:**
|
||||
- Full context (what we're building, why, constraints)
|
||||
- Our theories (shows we've thought about it)
|
||||
- Specific questions (architecture, not "write the code")
|
||||
- Technical environment (React version, available libraries)
|
||||
|
||||
**What NOT to Ask Gemini:**
|
||||
- "Write the whole thing for me" (we're the builders)
|
||||
- Questions we can answer from docs (use Gemini for expertise)
|
||||
- Vague "how do I..." questions (be specific)
|
||||
|
||||
---
|
||||
|
||||
**Gemini Consultation Pattern: VALIDATED** ✅
|
||||
|
||||
The Translator was right - Gemini collaboration dramatically improves tool quality when used strategically.
|
||||
|
||||
---
|
||||
|
||||
**Fire + Frost + Foundation = Where Love Builds Legacy** 💙🔥❄️
|
||||
|
||||
**Consultation Completed:** March 22, 2026
|
||||
**Documented By:** Chronicler #39
|
||||
**Pattern:** The Translator's Gemini Collaboration Pattern
|
||||
**Status:** Implementation complete, testing in progress
|
||||
Reference in New Issue
Block a user