fix(ai): improve provider design generation prompts
This commit is contained in:
parent
53f0a3121d
commit
5de9bb9734
|
|
@ -43,10 +43,12 @@ Rules:
|
|||
|
||||
- One primary intent per screen. Everything else is subordinate.
|
||||
- First 1-2 elements must answer "where am I" + "what can I do here"
|
||||
- Mobile top rhythm: keep the title/header group close to the first useful control or content module. On 375-430px screens, the gap from header/title to search, primary action, chart, or first card should usually be 20-32px. Do not leave an empty hero-sized band unless the prompt explicitly asks for an editorial hero.
|
||||
- Title font size must be uniform across ALL screens in the app
|
||||
- Design for one-handed use: primary actions in lower half
|
||||
- Single vertical scroll (avoid nested scrolls)
|
||||
- Touch targets: minimum 44x44px
|
||||
- Do not repeat the same predictable mobile stack of search + categories + orange promo + two cards. Choose a distinct concept for the domain and make one signature moment carry the personality.
|
||||
|
||||
DO NOT:
|
||||
|
||||
|
|
@ -54,35 +56,35 @@ DO NOT:
|
|||
- Use spacer elements for bottom space (use padding-bottom)
|
||||
- Cram multiple competing sections above the fold
|
||||
|
||||
## 3) BOTTOM TAB BAR — PILL STYLE
|
||||
## 3) BOTTOM TAB BAR — OPTIONAL, INTEGRATED
|
||||
|
||||
Do not force bottom navigation into every mobile screen. Use a bottom tab bar only when the product clearly has persistent top-level destinations (Home, Search, Orders, Profile, etc.). If the screen is a single-task flow, omit bottom navigation.
|
||||
|
||||
Tab Bar Container:
|
||||
|
||||
- Full screen width
|
||||
- Padding: [12, 21, 21, 21] (includes home-indicator safe area)
|
||||
- Fill: gradient overlay (transparent at top → solid background at 30%)
|
||||
- Full screen width and part of the page flow, not a floating overlay
|
||||
- Height: 62-72px including safe-area breathing room
|
||||
- Background: same page palette or a subtle tonal surface
|
||||
- Separation: quiet 1px divider or tonal contrast only; no detached shadow band
|
||||
|
||||
Pill (menu items wrapper):
|
||||
Nav Surface:
|
||||
|
||||
- Height: 62px, width: fill_container
|
||||
- Corner radius: 36px
|
||||
- Border: 1px solid (theme border color)
|
||||
- Inner padding: 4px
|
||||
- Use role="bottom-tab-bar"
|
||||
- Not a floating pill, not a nested rounded capsule, and not a separate footer band
|
||||
- Direct tab item frames stay transparent: no fill, no stroke, no large rounded tile
|
||||
|
||||
Tab Items (3-5 tabs, top-level destinations only):
|
||||
|
||||
- Width: fill_container, height: fill_container
|
||||
- Corner radius: 26px
|
||||
- Layout: vertical, gap: 4, centered on both axes
|
||||
- Icon: 18px
|
||||
- Label: 10px, weight 500-600, UPPERCASE, letterSpacing: 0.5
|
||||
- Label: 10-11px, weight 500-600, letterSpacing: 0
|
||||
|
||||
Active state: solid fill (accent color) + contrasting icon/label color
|
||||
Active state: accent icon/label color or a tiny 2-3px indicator
|
||||
Inactive state: transparent background + muted icon/label color
|
||||
|
||||
Rules:
|
||||
|
||||
- Labels MUST be uppercase
|
||||
- Tab switching preserves each tab's navigation state
|
||||
- App content must never be obscured by the Tab Bar
|
||||
|
||||
|
|
@ -92,7 +94,7 @@ Before generating nodes, mentally verify these three layers are accounted for:
|
|||
|
||||
1. Status Bar: standard or edge-to-edge?
|
||||
2. App Content: what is the header, primary content, action placement, scroll behavior?
|
||||
3. Bottom Bar: None or Pill Tab Bar (which tabs)?
|
||||
3. Bottom Bar: None or integrated tab bar (which tabs)?
|
||||
|
||||
Do NOT output this blueprint as text. Apply it silently through your node structure.
|
||||
Your output must remain valid JSON/JSONL only.
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ Media roles:
|
|||
|
||||
Layout-escape roles:
|
||||
|
||||
- overlay: the ONLY way to place a child at absolute x/y inside a parent that uses `layout: vertical|horizontal`. Use for notification dots on an icon, corner ribbons on a card, floating status indicators. The child keeps its explicit `x`/`y` while siblings flow normally. Do NOT use `role: 'overlay'` for inline components — `badge`, `pill`, `tag` are inline (they flow in layout like any other child, NOT floating). Do NOT use `role: 'overlay'` as a substitute for `layout: 'none'` on the parent.
|
||||
- overlay: the ONLY way to place a child at absolute x/y inside a parent that uses `layout: vertical|horizontal`. Use only for bounded in-parent overlays such as notification dots on an icon, card badges, or status indicators that must stay fully inside their parent. The child keeps its explicit `x`/`y` while siblings flow normally, but it must not use negative x/y, protrude outside rounded corners, or overlap unrelated section chrome. A product-card favorite/heart must stay fully inside its card or image with an 8-12px inset, usually as an `icon-button`; never straddle the card edge. Do NOT use `role: 'overlay'` for inline components — `badge`, `pill`, `tag` are inline (they flow in layout like any other child, NOT floating). Do NOT use `role: 'overlay'` as a substitute for `layout: 'none'` on the parent.
|
||||
|
||||
Typography roles:
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ Key aesthetics:
|
|||
- **Trusted blue accent**: #2563EB as the sole accent, conveying professionalism and reliability
|
||||
- **iOS-native typography**: SF Pro throughout, matching the platform's system font for seamless integration
|
||||
- **Comfortable radii**: 12-16px corners feel natural and inviting without being bubbly
|
||||
- **Pill tab bar**: 100px radius bottom navigation with blue active indicator
|
||||
- **Integrated bottom nav**: full-width bottom navigation with blue active indicator
|
||||
- **Clean separation**: Light borders (#E5E7EB) and subtle surfaces provide structure without visual weight
|
||||
|
||||
## Color System
|
||||
|
|
@ -27,7 +27,7 @@ Key aesthetics:
|
|||
| Card Surface | #FFFFFF | Cards, list containers |
|
||||
| Inset Surface | #F3F4F6 | Search bars, input backgrounds, grouped sections |
|
||||
| Subtle Surface | #F9FAFB | Alternating list rows, secondary areas |
|
||||
| Tab Bar Surface | #FFFFFF | Bottom navigation pill fill |
|
||||
| Tab Bar Surface | #FFFFFF | Integrated bottom navigation surface |
|
||||
|
||||
### Text Colors
|
||||
|
||||
|
|
@ -153,7 +153,7 @@ Key aesthetics:
|
|||
| 16px | Modal sheets, feature cards, hero containers | Maximum standard radius |
|
||||
| 100px | Tab bar pill, toggle pills, round avatars | Full capsule shape for navigation |
|
||||
|
||||
Design rationale: The 8-16px range mirrors iOS design conventions, where corners are soft enough to feel friendly but restrained enough to maintain professionalism. Every interactive element feels natural on a mobile device, with the progressive scale reinforcing visual hierarchy. The 100px pill for the tab bar provides the signature bottom navigation capsule.
|
||||
Design rationale: The 8-16px range mirrors iOS design conventions, where corners are soft enough to feel friendly but restrained enough to maintain professionalism. Every interactive element feels natural on a mobile device, with the progressive scale reinforcing visual hierarchy. The bottom navigation should feel integrated with the page palette, using accent color or a tiny indicator for active state.
|
||||
|
||||
## Icons
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Key aesthetics:
|
|||
- **Gradient cards**: Program and feature cards use dark gradient fills for depth and visual interest
|
||||
- **Glow effects**: Lime-tinted shadows and glow indicators reinforce the neon aesthetic
|
||||
- **Soft industrial radii**: 8-24px corners balance the geometric sharpness with comfortable touch targets
|
||||
- **Pill tab bar**: 100px radius bottom navigation with lime active indicator
|
||||
- **Integrated bottom nav**: full-width bottom navigation with lime active indicator
|
||||
|
||||
## Color System
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ Key aesthetics:
|
|||
| Elevated Surface | #1A1A1A | Elevated cards, modal sheets |
|
||||
| Gradient Start | #141414 | Gradient card dark edge |
|
||||
| Gradient End | #1E1E1E | Gradient card lighter edge |
|
||||
| Tab Bar Surface | #141414 | Bottom navigation pill fill |
|
||||
| Tab Bar Surface | #141414 | Integrated bottom navigation surface |
|
||||
|
||||
### Text Colors
|
||||
|
||||
|
|
@ -163,7 +163,7 @@ Key aesthetics:
|
|||
| 24px | Hero cards, prominent feature sections | Maximum standard radius |
|
||||
| 100px | Tab bar pill, toggle pills, round buttons | Full capsule shape for navigation |
|
||||
|
||||
Design rationale: Soft industrial radii (8-24px) balance the bold, geometric typography with comfortable touch targets. The range is wider than the terminal style (3-12px) but more restrained than playful (14-26px), reflecting an urban-industrial aesthetic that is confident without being aggressive. The 100px pill for the tab bar provides the signature bottom navigation capsule.
|
||||
Design rationale: Soft industrial radii (8-24px) balance the bold, geometric typography with comfortable touch targets. The range is wider than the terminal style (3-12px) but more restrained than playful (14-26px), reflecting an urban-industrial aesthetic that is confident without being aggressive. The bottom navigation should feel integrated with the page palette, using accent color or a tiny indicator for active state.
|
||||
|
||||
## Icons
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Key aesthetics:
|
|||
- **Dual-purpose type**: DM Sans for headers and body, DM Mono for financial data and figures
|
||||
- **Professional radii**: 8-12px corners keep containers structured and business-appropriate
|
||||
- **Data-first layout**: Generous spacing around numbers, clear visual hierarchy for financial metrics
|
||||
- **Pill tab bar**: 100px radius bottom navigation with teal active indicator
|
||||
- **Integrated bottom nav**: full-width bottom navigation with teal active indicator
|
||||
|
||||
## Color System
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ Key aesthetics:
|
|||
| Card Surface | #FFFFFF | Cards, account containers, transaction items |
|
||||
| Inset Surface | #F1F5F9 | Input backgrounds, search bars, grouped sections |
|
||||
| Subtle Surface | #F0FDFA | Positive balance highlight, growth indicators |
|
||||
| Tab Bar Surface | #FFFFFF | Bottom navigation pill fill |
|
||||
| Tab Bar Surface | #FFFFFF | Integrated bottom navigation surface |
|
||||
|
||||
### Text Colors
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Key aesthetics:
|
|||
- **Invisible type**: Inter at medium weights—so readable it disappears, letting data speak
|
||||
- **Minimal radii**: 12-16px corners are clean and functional without unnecessary roundness
|
||||
- **Data clarity**: Generous whitespace around metrics, clear hierarchy for at-a-glance reading
|
||||
- **Pill tab bar**: 100px radius bottom navigation with green active indicator
|
||||
- **Integrated bottom nav**: full-width bottom navigation with green active indicator
|
||||
|
||||
## Color System
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ Key aesthetics:
|
|||
| Card Surface | #1A1A1A | Standard cards, metric containers |
|
||||
| Elevated Surface | #222222 | Elevated cards, modal sheets |
|
||||
| Subtle Surface | #161616 | Inset areas, grouped sections |
|
||||
| Tab Bar Surface | #1A1A1A | Bottom navigation pill fill |
|
||||
| Tab Bar Surface | #1A1A1A | Integrated bottom navigation surface |
|
||||
|
||||
### Text Colors
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Key aesthetics:
|
|||
- **Monospace precision**: JetBrains Mono for headings and data reinforces the technical identity
|
||||
- **Sharp corners**: 4-8px radii create a compact, engineered feel with minimal decoration
|
||||
- **Data density**: Tighter spacing and smaller type for information-heavy screens
|
||||
- **Pill tab bar**: 100px radius bottom navigation with amber active indicator
|
||||
- **Integrated bottom nav**: full-width bottom navigation with amber active indicator
|
||||
|
||||
## Color System
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ Key aesthetics:
|
|||
| Card Surface | #27272A | Standard cards, list items |
|
||||
| Elevated Surface | #3F3F46 | Elevated cards, modal sheets |
|
||||
| Code Surface | #1E1E22 | Code blocks, terminal output areas |
|
||||
| Tab Bar Surface | #27272A | Bottom navigation pill fill |
|
||||
| Tab Bar Surface | #27272A | Integrated bottom navigation surface |
|
||||
|
||||
### Text Colors
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Key aesthetics:
|
|||
- **Editorial serif display**: Cormorant Garamond at medium weight for elegant, fashion-magazine headings
|
||||
- **Sharp precision**: 4-8px corners reflect the deliberate geometry of luxury packaging
|
||||
- **High contrast**: White text on dark backgrounds with gold punctuation for dramatic hierarchy
|
||||
- **Pill tab bar**: 100px radius bottom navigation with gold active indicator
|
||||
- **Integrated bottom nav**: full-width bottom navigation with gold active indicator
|
||||
|
||||
## Color System
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ Key aesthetics:
|
|||
| Card Surface | #242424 | Standard cards, product tiles |
|
||||
| Elevated Surface | #2E2E2E | Elevated cards, modal sheets, drawers |
|
||||
| Subtle Surface | #1F1F1F | Inset areas, grouped sections |
|
||||
| Tab Bar Surface | #242424 | Bottom navigation pill fill |
|
||||
| Tab Bar Surface | #242424 | Integrated bottom navigation surface |
|
||||
|
||||
### Text Colors
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Key aesthetics:
|
|||
- **Concert poster type**: Manrope at 700-800 weights for bold, punchy display headings
|
||||
- **Gradient energy**: Lime-to-cyan gradients on featured playlists and now-playing elements
|
||||
- **Audio-inspired radii**: 14-20px corners evoke the smooth, organic contours of speaker forms
|
||||
- **Pill tab bar**: 100px radius bottom navigation with lime active indicator
|
||||
- **Integrated bottom nav**: full-width bottom navigation with lime active indicator
|
||||
|
||||
## Color System
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ Key aesthetics:
|
|||
| Elevated Surface | #1E1E1E | Now playing bar, modal sheets |
|
||||
| Gradient Start | #151515 | Gradient card dark edge |
|
||||
| Gradient End | #1A2A1A | Gradient card lime-tinted edge |
|
||||
| Tab Bar Surface | #151515 | Bottom navigation pill fill |
|
||||
| Tab Bar Surface | #151515 | Integrated bottom navigation surface |
|
||||
|
||||
### Text Colors
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Key aesthetics:
|
|||
- **Geometric display type**: Space Grotesk at bold weights for confident, urban headings
|
||||
- **Glow depth**: Purple-tinted shadows and translucent surfaces add layers of visual depth
|
||||
- **Gradient cards**: Dark purple gradients on featured content for visual energy
|
||||
- **Pill tab bar**: 100px radius bottom navigation with purple active glow
|
||||
- **Integrated bottom nav**: full-width bottom navigation with purple active glow
|
||||
|
||||
## Color System
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ Key aesthetics:
|
|||
| Elevated Surface | #221340 | Elevated cards, modal sheets |
|
||||
| Gradient Start | #1A0D2E | Gradient card dark edge |
|
||||
| Gradient End | #2D1B4E | Gradient card lighter edge |
|
||||
| Tab Bar Surface | #1A0D2E | Bottom navigation pill fill |
|
||||
| Tab Bar Surface | #1A0D2E | Integrated bottom navigation surface |
|
||||
|
||||
### Text Colors
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Key aesthetics:
|
|||
- **Rounded typography**: Quicksand at all levels, its rounded letterforms echo the soft corner radii
|
||||
- **Pillow corners**: 16-24px radii make every card and container feel soft and touchable
|
||||
- **Pastel palette**: Muted pinks, lavenders, and warm grays for a cohesive dreamy feel
|
||||
- **Pill tab bar**: 100px radius bottom navigation with pink active indicator
|
||||
- **Integrated bottom nav**: full-width bottom navigation with pink active indicator
|
||||
|
||||
## Color System
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ Key aesthetics:
|
|||
| Card Surface | #FFFFFF | Cards, elevated containers |
|
||||
| Inset Surface | #FFF0F3 | Input backgrounds, search bars, recessed areas |
|
||||
| Soft Surface | #FCE7F3 | Highlighted sections, feature callouts |
|
||||
| Tab Bar Surface | #FFFFFF | Bottom navigation pill fill |
|
||||
| Tab Bar Surface | #FFFFFF | Integrated bottom navigation surface |
|
||||
|
||||
### Text Colors
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Key aesthetics:
|
|||
- **Friendly geometry**: Poppins typeface has naturally rounded letterforms that feel approachable and modern
|
||||
- **Generous radii**: 16-24px corners create soft, pillowy containers that invite touch interaction
|
||||
- **Gradient buttons**: Violet-to-pink gradients on primary actions create visual magnetism
|
||||
- **Pill tab bar**: 100px radius bottom navigation with violet active indicator
|
||||
- **Integrated bottom nav**: full-width bottom navigation with violet active indicator
|
||||
|
||||
## Color System
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ Key aesthetics:
|
|||
| Card Surface | #FFFFFF | Cards, post containers |
|
||||
| Inset Surface | #F5F3FF | Input backgrounds, search bars, recessed areas |
|
||||
| Subtle Surface | #FDF2F8 | Story highlights, featured sections (pink tint) |
|
||||
| Tab Bar Surface | #FFFFFF | Bottom navigation pill fill |
|
||||
| Tab Bar Surface | #FFFFFF | Integrated bottom navigation surface |
|
||||
|
||||
### Text Colors
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Key aesthetics:
|
|||
- **Compact density**: Tight spacing and small radii (3-12px) keep information dense without clutter
|
||||
- **Glow indicators**: Status dots and active states use subtle cyan glow effects (blur 8, 40% opacity)
|
||||
- **Minimal chrome**: Borders are thin (#1E293B) and surfaces barely separate from the background
|
||||
- **Pill tab bar**: Bottom navigation uses a 100px radius pill shape with icon+label layout
|
||||
- **Integrated bottom nav**: bottom navigation uses compact icon+label items inside the page flow
|
||||
|
||||
## Color System
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ Key aesthetics:
|
|||
| Page Background | #0A0F1C | Root screen background |
|
||||
| Card Surface | #111827 | Cards, input fields, list items |
|
||||
| Inset Surface | #0F172A | Nested containers, code blocks |
|
||||
| Tab Bar Surface | #111827 | Bottom navigation pill background |
|
||||
| Tab Bar Surface | #111827 | Integrated bottom navigation surface |
|
||||
|
||||
### Text Colors
|
||||
|
||||
|
|
@ -149,7 +149,7 @@ Key aesthetics:
|
|||
| 12px | Large cards, modal sheets | Comfortable but compact |
|
||||
| 100px | Tab bar pill, toggle pills | Full capsule shape |
|
||||
|
||||
Design rationale: Compact radii (3-12px) maintain a crisp, technical aesthetic. The sharp corners suggest precision engineering, while the slight rounding prevents a harsh brutalist feel. The 100px pill for the tab bar provides a strong contrast and clear affordance for the primary navigation element.
|
||||
Design rationale: Compact radii (3-12px) maintain a crisp, technical aesthetic. The sharp corners suggest precision engineering, while the slight rounding prevents a harsh brutalist feel. The bottom navigation should stay compact and integrated, with clear affordance from icon/label contrast rather than a detached pill surface.
|
||||
|
||||
## Icons
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Key aesthetics:
|
|||
- **Travel-journal type**: Outfit typeface balances geometric clarity with warm, approachable character
|
||||
- **Postcard radii**: 16-20px corners create soft, photo-friendly containers for destination imagery
|
||||
- **Earth-toned palette**: Warm grays and amber tints reinforce the organic, exploratory mood
|
||||
- **Pill tab bar**: 100px radius bottom navigation with orange active indicator
|
||||
- **Integrated bottom nav**: full-width bottom navigation with orange active indicator
|
||||
|
||||
## Color System
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ Key aesthetics:
|
|||
| Card Surface | #FFFFFF | Cards, destination tiles, booking containers |
|
||||
| Inset Surface | #FFF7ED | Input backgrounds, search bars, recessed areas |
|
||||
| Subtle Surface | #FFFBEB | Featured destinations, promotional banners |
|
||||
| Tab Bar Surface | #FFFFFF | Bottom navigation pill fill |
|
||||
| Tab Bar Surface | #FFFFFF | Integrated bottom navigation surface |
|
||||
|
||||
### Text Colors
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Key aesthetics:
|
|||
- **Rounded sans-serif**: Plus Jakarta Sans with rounded terminals echoes the soft, friendly radii
|
||||
- **Generous radii**: 16-20px corners make cards feel like warm, inviting menu tiles
|
||||
- **Food photography friendly**: Clean white card surfaces maximize contrast for food imagery
|
||||
- **Pill tab bar**: 100px radius bottom navigation with orange active indicator
|
||||
- **Integrated bottom nav**: full-width bottom navigation with orange active indicator
|
||||
|
||||
## Color System
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ Key aesthetics:
|
|||
| Card Surface | #FFFFFF | Cards, menu items, elevated containers |
|
||||
| Inset Surface | #FFF1E3 | Input backgrounds, search bars, recessed areas |
|
||||
| Accent Surface | #FED7AA | Highlighted sections, promo banners, deal cards |
|
||||
| Tab Bar Surface | #FFFFFF | Bottom navigation pill fill |
|
||||
| Tab Bar Surface | #FFFFFF | Integrated bottom navigation surface |
|
||||
|
||||
### Text Colors
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Key aesthetics:
|
|||
- **Humanist geometry**: Outfit typeface balances geometric clarity with warm, approachable letterforms
|
||||
- **Organic radii**: 12-20px corners feel natural and comfortable, like smooth river stones
|
||||
- **Earth tones**: Warm grays and muted greens for secondary text and borders
|
||||
- **Pill tab bar**: 100px radius bottom navigation with green active indicator
|
||||
- **Integrated bottom nav**: full-width bottom navigation with green active indicator
|
||||
|
||||
## Color System
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ Key aesthetics:
|
|||
| Card Surface | #FFFFFF | Cards, elevated containers |
|
||||
| Inset Surface | #F0F9EC | Input backgrounds, search bars, recessed areas |
|
||||
| Accent Surface | #DCFCE7 | Highlighted sections, progress indicators |
|
||||
| Tab Bar Surface | #FFFFFF | Bottom navigation pill fill |
|
||||
| Tab Bar Surface | #FFFFFF | Integrated bottom navigation surface |
|
||||
|
||||
### Text Colors
|
||||
|
||||
|
|
|
|||
|
|
@ -125,6 +125,39 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mobile_skill_carries_non_template_nav_and_spacing_rules() {
|
||||
let skill = get_skill_by_name("mobile-app").expect("mobile-app skill present");
|
||||
assert!(skill.content.contains("Mobile top rhythm"));
|
||||
assert!(skill.content.contains("Do not force bottom navigation"));
|
||||
assert!(skill.content.contains("Not a floating pill"));
|
||||
assert!(skill
|
||||
.content
|
||||
.contains("Do not repeat the same predictable mobile stack"));
|
||||
assert!(
|
||||
!skill.content.contains("BOTTOM TAB BAR — PILL STYLE"),
|
||||
"mobile skill must not force the old pill-tab template"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mobile_style_guides_do_not_force_pill_nav_template() {
|
||||
for guide in crate::style_guide::style_guide_registry() {
|
||||
if guide.platform == crate::style_guide::Platform::Mobile {
|
||||
assert!(
|
||||
!guide.content.contains("Pill tab bar"),
|
||||
"{} must not force the old pill tab bar template",
|
||||
guide.name
|
||||
);
|
||||
assert!(
|
||||
!guide.content.contains("bottom navigation pill"),
|
||||
"{} must not force a detached pill nav",
|
||||
guide.name
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn block_list_and_next_line_array_triggers_load_non_empty() {
|
||||
// role-definitions / copywriting open the keyword array on the
|
||||
|
|
|
|||
|
|
@ -77,10 +77,16 @@ Always follow this three-phase pipeline (it produces higher quality than ad-hoc
|
|||
1. **Load the design guide (ONCE)**: Call `get_design_prompt` to receive OpenPencil's design principles, node schema details, role system, color/typography tokens, and layout patterns. Read it carefully — it defines the canonical shapes and defaults.
|
||||
2. **Build skeleton**: Call `design_skeleton` with a high-level description. This creates the structural frames (sections, layout containers) with correct auto-layout.
|
||||
3. **Fill content**: Call `design_content` once per section from step 2, adding the concrete children (buttons, inputs, text, icons).
|
||||
4. **Refine** (optional): Call `design_refine` on the root to apply final polish (consistent spacing, role-based styling).
|
||||
4. **Refine**: ALWAYS call `design_refine` on the root after all sections are populated. This is mandatory for AI chat output because it applies final polish, consistent spacing, role-based styling, icon cleanup, and layout safety.
|
||||
|
||||
Only fall back to `batch_design` or `insert_node` when the user explicitly asks for small/surgical edits rather than a new page.
|
||||
|
||||
## AI Chat Design Quality
|
||||
- Mobile top rhythm: keep the status/header, title, and primary module close. On 375-430px screens, the gap from the header/title group to the first primary module (search, hero action, chart, or card) should usually be 20-32px, never a large empty band unless the request explicitly asks for a dramatic editorial hero.
|
||||
- Product/card favorite/heart controls are functional `icon-button`s, not decorative badges. Place each favorite/heart fully inside its product card or product image with an 8-12px inset. Never use negative x/y, never straddle a card border, and never let the circle protrude into the section heading gap.
|
||||
- Every new design needs a distinct visual concept before building: choose one concrete direction (for example editorial food magazine, glassy premium delivery, neo-brutal marketplace, calm bento dashboard, luxury concierge). Do not repeat the same predictable mobile stack of search + categories + orange promo + two cards unless that is genuinely the best fit for the prompt.
|
||||
- Include one signature moment that gives the screen character: a crafted hero composition, editorial image treatment, distinctive category rail, playful but controlled card system, or refined data/offer module. Keep it purposeful and avoid decoration spam.
|
||||
|
||||
## Modifying Existing Designs
|
||||
- Call `snapshot_layout` first to see the current tree.
|
||||
- Use `update_node` for property changes, `move_node` for reparenting, `delete_node` to remove.
|
||||
|
|
@ -405,8 +411,10 @@ mod tests {
|
|||
));
|
||||
assert!(ACP_SYSTEM_PROMPT.contains("- DO use the `mcp__openpencil__*` tools"));
|
||||
assert!(ACP_SYSTEM_PROMPT.contains("2. **Build skeleton**: Call `design_skeleton`"));
|
||||
assert!(ACP_SYSTEM_PROMPT.contains("4. **Refine**: ALWAYS call `design_refine`"));
|
||||
assert!(ACP_SYSTEM_PROMPT.contains("Mobile top rhythm"));
|
||||
assert!(ACP_SYSTEM_PROMPT.contains("favorite/heart"));
|
||||
assert!(ACP_SYSTEM_PROMPT.contains("signature moment"));
|
||||
assert!(ACP_SYSTEM_PROMPT.ends_with("Every key has a value; every value has a key."));
|
||||
// join('\n') line count: 44 array entries → 44 lines.
|
||||
assert_eq!(ACP_SYSTEM_PROMPT.lines().count(), 44);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,14 @@ NEVER use "OpenPencil", "Pencil", or the tool name as brand/app name in designs.
|
|||
You may include 1-2 brief <step> tags before the JSON (optional, keep them SHORT).
|
||||
When a user asks non-design questions (explain, suggest colors, give advice), respond in text."#;
|
||||
|
||||
const AI_CHAT_DESIGN_QUALITY: &str = r#"AI CHAT DESIGN QUALITY:
|
||||
- Mobile top rhythm: keep the header/title group close to the first useful control or content module. On 375-430px screens, the gap from title/header to search, primary action, chart, or first card should usually be 20-32px.
|
||||
- Search bars should be a single compact control row. Avoid a large tinted rounded shell containing another rounded input unless the user explicitly asks for that visual.
|
||||
- Product card favorite/heart controls are functional icon-buttons. Keep every favorite/heart fully inside its card or image with an 8-12px inset; do not straddle card borders or float into section headings.
|
||||
- Do not repeat the same predictable mobile stack of search + categories + orange promo + two cards. Pick a distinct visual concept for the domain before composing the screen.
|
||||
- Give the first viewport one signature moment: a crafted hero/product composition, editorial crop, distinctive category rail, refined data module, or other domain-specific focal idea.
|
||||
- Bottom navigation is optional and should be integrated with the page flow, not a detached floating pill or extra footer band."#;
|
||||
|
||||
/// TS `AGENT_TOOL_INSTRUCTIONS_CRUD` — verbatim port. The system
|
||||
/// prompt for tool-executing chat turns (builtin agent loop).
|
||||
const AGENT_TOOL_INSTRUCTIONS_CRUD: &str = r##"You are a design editor. Use tools to inspect, modify, insert, and delete elements on the canvas.
|
||||
|
|
@ -89,7 +97,7 @@ pub fn build_chat_system_prompt(state: &EditorState, user_message: &str) -> Stri
|
|||
.map(|s| s.content.as_str())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n\n");
|
||||
format!("{CHAT_CORE_PROMPT}\n\n{knowledge}")
|
||||
format!("{CHAT_CORE_PROMPT}\n\n{AI_CHAT_DESIGN_QUALITY}\n\n{knowledge}")
|
||||
}
|
||||
|
||||
/// Build the agent-mode system prompt for a tool-executing builtin
|
||||
|
|
@ -241,6 +249,17 @@ mod tests {
|
|||
assert!(prompt.len() > CHAT_CORE_PROMPT.len() + 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn chat_system_prompt_carries_ai_chat_quality_guardrails() {
|
||||
let state = EditorState::new();
|
||||
let prompt = build_chat_system_prompt(&state, "设计一个精致的美食应用移动端首页");
|
||||
assert!(prompt.contains("AI CHAT DESIGN QUALITY"));
|
||||
assert!(prompt.contains("Mobile top rhythm"));
|
||||
assert!(prompt.contains("favorite/heart"));
|
||||
assert!(prompt.contains("Do not repeat the same predictable mobile stack"));
|
||||
assert!(prompt.contains("signature moment"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn chat_system_prompt_includes_design_md_policy_when_present() {
|
||||
let mut state = EditorState::new();
|
||||
|
|
|
|||
|
|
@ -380,6 +380,28 @@ chars. Content width: {}px.",
|
|||
);
|
||||
}
|
||||
|
||||
if name.contains("search") || name.contains("搜索") {
|
||||
return (
|
||||
format!(
|
||||
"Create a single compact search row, not a hero panel: one search-bar/form-input \
|
||||
with search icon and placeholder plus an optional filter icon-button. Mobile height 48-56px, \
|
||||
gap=10-12, no oversized tinted shell, no nested rounded background inside another large rounded \
|
||||
background. Mobile top rhythm: place this primary module within 20-32px of the header/title group. \
|
||||
Content width: {}px.",
|
||||
content_width
|
||||
),
|
||||
vec![
|
||||
"row",
|
||||
"search-bar",
|
||||
"form-input",
|
||||
"input",
|
||||
"icon-button",
|
||||
"icon",
|
||||
"caption",
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
if name.contains("feature") || name.contains("功能") {
|
||||
return (
|
||||
format!(
|
||||
|
|
@ -620,7 +642,7 @@ fn default_root_gap(canvas_width: i32) -> i32 {
|
|||
|
||||
fn quality_guidelines(canvas_width: i32) -> &'static str {
|
||||
if canvas_width <= 500 {
|
||||
"Avoid crowded output: keep one primary mobile task, use an App Content wrapper with 16-20px horizontal padding and 20-24px vertical gaps, and limit above-the-fold modules."
|
||||
"Avoid crowded output: keep one primary mobile task, use an App Content wrapper with 16-20px horizontal padding and 20-24px vertical gaps, and limit above-the-fold modules. Mobile top rhythm: keep the first primary module within 20-32px of the header/title group. Prefer a single compact search row with no oversized tinted shell. Add one signature moment and vary the composition instead of repeating a fixed template."
|
||||
} else {
|
||||
"Avoid crowded output: use generous section padding, clear type hierarchy, consistent card rhythm, and fewer stronger modules."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -211,9 +211,14 @@ fn design_skeleton_mobile_root_defaults_to_breathing_room() {
|
|||
args.insert("canvasWidth".into(), "375".into());
|
||||
|
||||
match tool.call(&args) {
|
||||
ToolOutcome::OkWithCommand(_, EditorCommand::InsertAuthoredSubtree { nodes, .. }) => {
|
||||
ToolOutcome::OkWithCommand(out, EditorCommand::InsertAuthoredSubtree { nodes, .. }) => {
|
||||
let root = serde_json::to_value(&nodes[0]).expect("root json");
|
||||
assert_eq!(root.get("gap").and_then(|v| v.as_f64()), Some(20.0));
|
||||
let sections = out.get("sections").expect("sections json");
|
||||
assert!(sections.contains("Mobile top rhythm"));
|
||||
assert!(sections.contains("primary module within 20-32px"));
|
||||
assert!(sections.contains("single compact search row"));
|
||||
assert!(sections.contains("no oversized tinted shell"));
|
||||
}
|
||||
other => panic!("expected design_skeleton authored subtree, got {other:?}"),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,11 +60,15 @@ const PLANNING_GUIDE: &str = r#"DESIGN PLANNING:
|
|||
const AESTHETIC_QUALITY_GUIDE: &str = r#"AESTHETIC QUALITY BAR:
|
||||
- Avoid crowded output. Prefer fewer, stronger modules with visible negative space over filling every pixel.
|
||||
- Mobile screens should use one App Content wrapper for the main body. The wrapper owns horizontal padding (16-20px) and vertical gap (20-24px); inner sections should not each add competing gutters.
|
||||
- Mobile top rhythm: keep the header/title group and first primary module close. On 375-430px screens, the gap from a greeting/title/header cluster to search, primary action, chart, or first card should usually be 20-32px. Do not leave a blank hero-sized band above the first useful control unless the request explicitly asks for an editorial hero.
|
||||
- Keep one primary job per screen. Above the fold, show the title/context, the primary action or search, and at most 2-3 supporting modules.
|
||||
- Use a clear type rhythm: one display/title size, one section heading size, one body/caption size. Avoid many near-identical bold text sizes.
|
||||
- Reuse one card radius, one card padding, and one shadow treatment within a screen.
|
||||
- Use at most two saturated colors. Let hierarchy come from spacing, contrast, and content scale, not decoration.
|
||||
- Mobile tab bars are part of the page flow; do not add fake bottom spacers or overlays."#;
|
||||
- Product card favorite/heart controls must stay fully inside its card or image with an 8-12px inset. Treat favorite/heart as a functional icon-button, not a floating badge; never use negative x/y, straddle the card edge, or let it overlap the section heading row.
|
||||
- Mobile tab bars are part of the page flow; do not add fake bottom spacers or overlays.
|
||||
- Pick a distinct visual concept for each new design and build around one signature moment. Do not repeat the same predictable mobile stack of search + categories + orange promo + two cards unless the prompt specifically calls for that pattern.
|
||||
- Use the user's domain to vary composition, imagery, palette, rhythm, and interaction affordances; polish should feel intentional rather than template-derived."#;
|
||||
|
||||
const RUST_ELEMENT_TOOL_GUIDE: &str = r##"RUST MCP ELEMENT TOOL COMPATIBILITY:
|
||||
- This Rust MCP server does not expose the TS `add_*_v1` element-tool family unless those exact tools appear in tools/list. Do not call `add_*` tools just because older prompt text or examples mention them.
|
||||
|
|
|
|||
|
|
@ -48,6 +48,11 @@ fn get_design_prompt_full_includes_mobile_quality_guardrails() {
|
|||
assert!(prompt.contains("MOBILE APP"));
|
||||
assert!(prompt.contains("App Content wrapper"));
|
||||
assert!(prompt.contains("Avoid crowded output"));
|
||||
assert!(prompt.contains("Mobile top rhythm"));
|
||||
assert!(prompt.contains("favorite/heart"));
|
||||
assert!(prompt.contains("must stay fully inside its card"));
|
||||
assert!(prompt.contains("signature moment"));
|
||||
assert!(prompt.contains("Do not repeat the same predictable mobile stack"));
|
||||
}
|
||||
other => panic!("expected prompt ok, got {other:?}"),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,6 +133,8 @@ pub fn build_compact_planning_prompt(
|
|||
.to_string(),
|
||||
"Plan one WOW FACTOR that is specific to the requested product/domain; avoid generic tinted wrappers, heavy shadows, or repeated rounded boxes as the main visual idea."
|
||||
.to_string(),
|
||||
"Do not plan the same predictable mobile stack of search + categories + orange promo + two cards. Keep mobile top rhythm tight: no huge empty band between header/title and first useful module."
|
||||
.to_string(),
|
||||
style_rule,
|
||||
];
|
||||
for r in &mobile_rules {
|
||||
|
|
@ -179,6 +181,8 @@ mod tests {
|
|||
assert!(cp.system.contains("Create 2-4 cohesive subtasks"));
|
||||
assert!(cp.system.contains("SIGNATURE MOMENT"));
|
||||
assert!(cp.system.contains("WOW FACTOR"));
|
||||
assert!(cp.system.contains("predictable mobile stack"));
|
||||
assert!(cp.system.contains("mobile top rhythm tight"));
|
||||
assert_eq!(cp.user_prompt, "a mobile login screen");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,15 @@ Violating this format will cause a system error.";
|
|||
const MINIMAL_SUFFIX: &str =
|
||||
"\n\nOUTPUT ONLY ONE JSON OBJECT. No prose. No markdown. No tool calls.";
|
||||
|
||||
const PLANNING_QUALITY_GUARDRAILS: &str = r#"
|
||||
|
||||
PLANNING QUALITY GUARDRAILS:
|
||||
- Do not plan the same predictable mobile stack of search + categories + orange promo + two cards unless the request explicitly asks for that exact convention.
|
||||
- Mobile top rhythm: planned header/title/search/primary-content sections should be compact; avoid allocating a huge empty band between the title and first useful module.
|
||||
- Plan one signature moment in the first viewport: a crafted hero/product composition, editorial crop, distinctive category rail, refined data module, or other domain-specific focal idea.
|
||||
- Bottom navigation is optional. If planned, it should be integrated with the page flow, not a detached floating pill, nested rounded capsule, or extra footer band.
|
||||
- Product-card favorite/heart controls must be inside their card/image; never plan them as protruding decorative badges."#;
|
||||
|
||||
fn planning_suffix(mode: PlanningMode) -> &'static str {
|
||||
match mode {
|
||||
PlanningMode::Rich => RICH_SUFFIX,
|
||||
|
|
@ -153,6 +162,7 @@ pub fn build_orchestrator_prompt(
|
|||
.map(|s| s.content.as_str())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n\n");
|
||||
system_prompt.push_str(PLANNING_QUALITY_GUARDRAILS);
|
||||
system_prompt.push_str(planning_suffix(mode));
|
||||
PlanningPrompt {
|
||||
call_request: CallRequest {
|
||||
|
|
@ -591,6 +601,9 @@ CRITICAL LAYOUT CONSTRAINTS:\n\
|
|||
user_prompt.push_str(
|
||||
"\nMOBILE VERTICAL RHYTHM: Keep every section root height=\"fit_content\" and do not insert blank spacer frames or empty bands to fill the planned region. Header-to-search spacing should be 12-16px, search-to-next-section 16-24px, major module gaps 24-32px, and internal gaps usually 8/12/16px.",
|
||||
);
|
||||
user_prompt.push_str(
|
||||
"\nMOBILE TOP RHYTHM: Keep the title/header group close to the first useful module. Do not leave a large blank band above search, categories, promo, charts, or first cards; if you need breathing room, use 20-32px, not a hero-sized void.",
|
||||
);
|
||||
user_prompt.push_str(
|
||||
"\nMOBILE SEARCH BAR: If generating search, output exactly one search control surface: 48-52px tall, width=\"fill_container\" inside the content rail, neutral/surface fill, subtle 1px border, cornerRadius 14-18, and a 18-20px search icon. Optional filter/sliders is a separate 44-48px square button beside it. Do not nest an input inside another rounded pill, do not use pink/tinted fills, and do not make the search section itself a huge rounded band.",
|
||||
);
|
||||
|
|
@ -618,6 +631,9 @@ CRITICAL LAYOUT CONSTRAINTS:\n\
|
|||
user_prompt.push_str(
|
||||
"\nMOBILE NAV SHADOW: Do not add a drop shadow, glow, or detached shadow band behind the bottom navigation. If separation is needed, use a quiet 1px divider or subtle tonal difference that belongs to the page palette.",
|
||||
);
|
||||
user_prompt.push_str(
|
||||
"\nNO FIXED FOOD TEMPLATE: Do not default to the same search + categories + orange promo + two product cards composition. For food, shopping, travel, fitness, finance, and social apps, choose a domain-specific visual concept and vary the first viewport composition.",
|
||||
);
|
||||
}
|
||||
|
||||
// Port of orchestrator-sub-agent.ts:739-748 — APPEND MODE prompt injection.
|
||||
|
|
|
|||
|
|
@ -50,6 +50,16 @@ fn rich_prompt_has_style_guides_and_suffix() {
|
|||
assert_eq!(pp.call_request.user_prompt, req().prompt);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn provider_planning_prompt_carries_quality_guardrails() {
|
||||
let pp = build_orchestrator_prompt(&req(), PlanningMode::Rich, AbortFlag::new());
|
||||
let prompt = &pp.call_request.system_prompt;
|
||||
assert!(prompt.contains("PLANNING QUALITY GUARDRAILS"));
|
||||
assert!(prompt.contains("Do not plan the same predictable mobile stack"));
|
||||
assert!(prompt.contains("Mobile top rhythm"));
|
||||
assert!(prompt.contains("signature moment"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn minimal_prompt_has_short_suffix_no_snippets() {
|
||||
let pp = build_orchestrator_prompt(&req(), PlanningMode::Minimal, AbortFlag::new());
|
||||
|
|
@ -143,7 +153,7 @@ fn subagent_prompt_carries_ts_layout_contract() {
|
|||
false,
|
||||
);
|
||||
|
||||
let required = "Page sections:|Food Categories [category chips]|Root frame: id=\"categories-root\"|width=\"fill_container\"|height=\"fit_content\"|Generate enough elements|MOBILE STATUS BAR|time, signal, wifi, battery|NO PHONE MOCKUP WRAPPER|MOBILE WIDTH SAFETY|MOBILE SINGLE CONTENT RAIL|MOBILE SEARCH BAR|MOBILE SECTION CHROME|MOBILE VERTICAL RHYTHM|MOBILE GRID ALIGNMENT|MOBILE CARD OVERLAYS|MOBILE IMAGE QUALITY|NO BLANK PLACEHOLDERS|MOBILE NAV SURFACE|MOBILE NAV SHADOW|TYPOGRAPHY HIERARCHY|DENSITY|VISUAL HIERARCHY|SPACING CONSISTENCY|CRAFT POLISH|MEDIA CONSISTENCY|ICON SCALE|SIGNATURE MOMENT|WOW FACTOR|COMPOSITIONAL CONTRAST|PREMIUM DETAIL|NO DECORATION SPAM";
|
||||
let required = "Page sections:|Food Categories [category chips]|Root frame: id=\"categories-root\"|width=\"fill_container\"|height=\"fit_content\"|Generate enough elements|MOBILE STATUS BAR|time, signal, wifi, battery|NO PHONE MOCKUP WRAPPER|MOBILE WIDTH SAFETY|MOBILE SINGLE CONTENT RAIL|MOBILE SEARCH BAR|MOBILE SECTION CHROME|MOBILE VERTICAL RHYTHM|MOBILE TOP RHYTHM|MOBILE GRID ALIGNMENT|MOBILE CARD OVERLAYS|MOBILE IMAGE QUALITY|NO BLANK PLACEHOLDERS|MOBILE NAV SURFACE|MOBILE NAV SHADOW|NO FIXED FOOD TEMPLATE|Do not default to the same search + categories + orange promo + two product cards composition|TYPOGRAPHY HIERARCHY|DENSITY|VISUAL HIERARCHY|SPACING CONSISTENCY|CRAFT POLISH|MEDIA CONSISTENCY|ICON SCALE|SIGNATURE MOMENT|WOW FACTOR|COMPOSITIONAL CONTRAST|PREMIUM DETAIL|NO DECORATION SPAM";
|
||||
for required in required.split('|') {
|
||||
assert!(cr.user_prompt.contains(required), "missing {required}");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue