Files
firefrost-operations-manual/docs/archive/retired-tasks/ghost-page-builder/gemini-consultation.md
Claude 256f3a35ac Cleanup: Archive retired tasks, remove duplicate templates
Archived to docs/archive/retired-tasks/:
- Ghost CMS tasks (6 folders) - retired April 2, 2026
- Paymenter tasks (2 folders) - retired April 3, 2026
- Ghost website pages

Removed duplicate templates:
- MEMORIAL-TEMPLATE.md (keeping lowercase version)
- PORTRAIT-PROMPT-TEMPLATE.md (keeping lowercase version)
- SESSION-REPORT-TEMPLATE.md (keeping lowercase version)
- OPENER-TEMPLATE.md

Chronicler #66
2026-04-07 17:47:29 +00:00

11 KiB

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:

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:

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:

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:

<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