DEV Community

Keo Fung | FormLM
Keo Fung | FormLM

Posted on

[5/10]Generating AI-Driven Cover Pages and Visual Styles That Don't Look Generic

Series: Building a Modular Assessment Engine (5/10)

The connect module configures what users actually see: the cover page, the form-filling experience, and the final page. It also drives the visual style — colors, backgrounds, layout. This is where "functional" meets "doesn't look like a government form from 2003."

Three Pages, Three Jobs

Every assessment app has three page types:

[Cover Page] → [Main Page (form)] → [Final Page]
Enter fullscreen mode Exit fullscreen mode
  • Cover page: The hook. Why should the user spend 5 minutes on this?
  • Main page: The actual form. Can be one long page (form mode), one question per screen (field mode), or card-swipe style (card mode).
  • Final page: The payoff. Download a PDF report, chat with an AI expert, or a simple thank-you.

The Cover Page Conversion Formula

Most cover pages fail because they say "Welcome to our assessment." Nobody cares. The cover page needs to answer one question: why should I spend my time on this?

The SKILL.md enforces a four-element formula:

assess connect cover-page add --id cover_main \
  --name "Workplace Stress Assessment" \
  --description "<p>73% of high-pressure workers don't realize their stress exceeds healthy levels.</p>
    <p>This assessment covers Workload, Role Stress, and Social Support. 5 minutes. Personalized report.</p>" \
  --format rich-text \
  --enable-title-writer true \
  --enable-split-screen true
Enter fullscreen mode Exit fullscreen mode

The four elements:

  1. Hook sentence — a counter-intuitive fact or surprising number from the knowledge base (NOT "welcome")
  2. Benefit statement — what the user gets out of it (one sentence)
  3. Time estimate — "5 minutes" (honest, not "quick")
  4. Dimension preview — 2-4 keywords showing what's covered

The Fabricated Statistics Problem

The hardest rule to enforce: statistics in the hook must come from the knowledge base, not the AI's imagination.

The AI would write things like "Studies show 87% of workers experience burnout." That number sounds credible. It's made up. On a public platform, fabricated statistics are a credibility disaster.

The fix: the SKILL.md explicitly states "statistics must come from knowledge base original text, AI fabrication forbidden. The --kbText contract from the form module ensures the source material is available.

The Main Page Format Decision

Three formats, each suited to different scenarios:

Format UX When to Use
form All questions on one page Surveys, data collection, short forms
field One question per screen Assessments, exams, consultations
card Card carousel within a container Medium-length assessments

The decision is driven by the plan type:

survey → form (mandatory)
assessment/consultation/exam → field or card
learn → field
Enter fullscreen mode Exit fullscreen mode

Why does survey mandate form? Because surveys are often filled on desktop, and one-page-per-question for a 20-question survey feels like a dark pattern. Users want to see the full scope before committing.

Why does assessment prefer field? Because one-question-per-screen creates focus. The user isn't overwhelmed by seeing 15 Likert scales at once. It also enables progress indicators and per-question context.

The Style System

Visual style is applied through a separate AI call — style apply:

assess connect style apply \
  --theme Noir \
  --look "workplace stress assessment, psychological evaluation, dark professional, deep blue with silver accents" \
  --layout stack
Enter fullscreen mode Exit fullscreen mode

This generates CSS that's applied to all pages. The --look parameter is natural language — the AI translates it into actual color values, background gradients, and typography.

Theme Presets

12 preset themes map to color palettes:

Light Themes Dark Themes
Minimal (light purple-gray) Earthy (deep forest green)
Fresh (blue-green) Soft (deep rose)
Clean (green-white) Vibrant (dark orange)
Warm (amber) Noir (deep indigo)
Airy (sky blue) Classic (deep blue)
Retro (warm rose) Mystic (dark purple)

The AI picks a theme based on the assessment topic. Psychological assessments tend toward dark themes (Noir, Mystic). Health surveys lean light (Fresh, Clean). The --look parameter adds nuance — "warm and supportive" modifies how the theme is applied.

The apply-all Optimization

Initially, style apply was called once per page type (cover, main, final). Each call triggered a separate AI call to generate CSS. Three AI calls for styling alone.

The fix: style apply-all:

assess connect style apply-all \
  --theme Noir \
  --look "dark professional, deep blue with silver accents" \
  --layout stack
Enter fullscreen mode Exit fullscreen mode

One AI call generates the style once, then applies it to all pages. This cut styling time from ~15 seconds to ~5 seconds.

The SVG Illustration System

The connect module supports optional SVG illustrations for field-level context. When the user asks for "scene illustrations," each assessment question gets a small SVG above it:

assess connect main-page set --field X4 \
  --description "<div><svg viewBox='0 0 280 64' width='100%' height='64'>
    <defs><linearGradient id='gd' x1='0' y1='0' x2='1' y2='0'>
      <stop offset='0%' stop-color='#818CF8' stop-opacity='0.3'/>
      <stop offset='100%' stop-color='#818CF8' stop-opacity='1'/>
    </linearGradient></defs>
    <!-- gauge, ticks, pointer -->
  </svg></div>"
Enter fullscreen mode Exit fullscreen mode

Five standard illustration patterns cover most assessment question types:

Pattern Visual When
A. Layer deconstruction Nested rounded boxes Concept understanding
B. Path nodes Bezier-connected circles Process/methodology
C. Dual-scene contrast Dashed divider, left dim/right bright Comparison/contrast
D. Scale pointer Gradient track + glowing dot Frequency/degree scales
E. Scene narrative Two figures + transformation arrow Application/scenario

SVG Rules That Prevent Bugs

SVGs in this system have strict rules — not for aesthetics, but because they're later rendered to PDF by Batik, and Batik is picky:

  1. Transparent background — no <rect> background. Batik renders it as opaque black in PDF.
  2. fill='none' or low opacity — no large solid color blocks. They look terrible in print.
  3. viewBox must be explicit — without it, Batik uses default dimensions and the SVG renders at wrong size in PDF.
  4. <path> d attribute must start with M — Batik rejects paths that don't start with a move-to command.
  5. Gradient IDs must be unique per page — duplicate IDs cause the first gradient to be used everywhere.
  6. No <script>, <use>, or <image> — Batik doesn't execute scripts or fetch external resources.

These rules exist because each one was a bug report. The <path> starting with L instead of M? That crashed the PDF renderer for an entire week before I found it.

The Final Page: Where Conversion Happens

The final page is where the user gets their reward. Four formats:

Format Content When
report-pdf Display + download PDF report Assessment, exam, report
expert Enter AI expert chat Consultation
rich-text Thank-you page Survey, learn
url Redirect to external link Special cases

The final page must answer: "I just spent 5 minutes. What did I get?"

The SKILL.md enforces a three-element structure:

  1. Congratulations — acknowledge completion
  2. Value statement — "Your personalized report shows..."
  3. Share prompt — "Found this useful? Share with a friend"

The share prompt matters more than you'd think. It's the viral coefficient. Apps without a share prompt have ~2% share rates. Apps with a natural share prompt hit ~8%.

The --type vs --page-id Confusion

One more CLI gotcha. The style set command can target pages by type or by ID:

# By type — works for cover/main/final
assess connect style set --type main --submit-label "Submit"

# By ID — needed for specific page overrides
assess connect style set --id cover_main --writer-speed 80
Enter fullscreen mode Exit fullscreen mode

The rule: --type is for type-level settings (submit button text, main page config). --id is for page-specific overrides (typewriter speed on a specific cover page). Using --type cover when you meant --id cover_main silently applies to all cover pages, which is usually not what you want.

The exception: --submit-label is the only parameter allowed with --type main. Everything else requires --id.

Lessons Learned

  1. The cover page is a conversion problem, not a design problem. Hook > benefit > time > preview. "Welcome" is not a hook.

  2. Fabricated statistics are a credibility bomb. If the number isn't in the source material, it doesn't go in the cover page. Period.

  3. SVG rules are PDF renderer rules. What looks fine in a browser can crash Batik. Define the constraints at generation time, not at render time.

  4. Style generation should be one AI call, not N. apply-all isn't just an optimization — it ensures visual consistency across pages.

  5. The final page is where virality lives. A good share prompt is worth more than a beautiful cover page.


Next: [Report Module — Page-templated PDF generation]

Top comments (0)