ima2-gen 2.0.15 → 2.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/README.md +30 -0
  2. package/bin/commands/skill.js +336 -17
  3. package/bin/ima2.js +22 -2
  4. package/bin/lib/doctor-checks.js +6 -4
  5. package/config.js +1 -0
  6. package/docs/CLI.md +25 -3
  7. package/docs/PROMPT_STUDIO.ko.md +29 -0
  8. package/docs/PROMPT_STUDIO.md +31 -0
  9. package/docs/migration/runtime-test-inventory.md +7 -1
  10. package/lib/agentImageVideoGen.js +8 -0
  11. package/lib/agentQueueStore.js +36 -10
  12. package/lib/agentQueueWorker.js +79 -7
  13. package/lib/agentRuntime.js +2 -0
  14. package/lib/assetLifecycle.js +40 -8
  15. package/lib/canvasVersionStore.js +86 -0
  16. package/lib/cardNewsGenerator.js +37 -3
  17. package/lib/cardNewsJobStore.js +10 -0
  18. package/lib/cardNewsManifestStore.js +6 -12
  19. package/lib/cardNewsPath.js +25 -0
  20. package/lib/db.js +2 -0
  21. package/lib/generatePipeline.js +474 -0
  22. package/lib/generationInputValidation.js +32 -0
  23. package/lib/grokImageCore.js +18 -1
  24. package/lib/historyIndex.js +11 -4
  25. package/lib/historyList.js +3 -0
  26. package/lib/imageMetadata.js +3 -0
  27. package/lib/inflight.js +30 -3
  28. package/lib/multimodePipeline.js +462 -0
  29. package/lib/nodeGeneration.js +440 -0
  30. package/lib/nodeValidation.js +23 -0
  31. package/lib/oauthProxy/generators.js +3 -246
  32. package/lib/oauthProxy/multimodeGenerators.js +251 -0
  33. package/lib/routeHelpers.js +9 -2
  34. package/package.json +2 -2
  35. package/routes/agent.js +4 -4
  36. package/routes/canvasVersions.js +21 -1
  37. package/routes/cardNews.js +2 -1
  38. package/routes/edit.js +25 -9
  39. package/routes/events.js +5 -1
  40. package/routes/generate.js +2 -481
  41. package/routes/keys.js +31 -39
  42. package/routes/multimode.js +2 -502
  43. package/routes/nodes.js +3 -448
  44. package/routes/video.js +12 -3
  45. package/routes/videoExtended.js +19 -4
  46. package/server.js +53 -1
  47. package/skills/ima2/SKILL.md +204 -0
  48. package/skills/ima2-front/SKILL.md +611 -0
  49. package/skills/ima2-front/references/a11y-patterns.md +134 -0
  50. package/skills/ima2-front/references/aesthetics.md +327 -0
  51. package/skills/ima2-front/references/anti-slop.md +241 -0
  52. package/skills/ima2-front/references/asset-requirements.md +431 -0
  53. package/skills/ima2-front/references/brand-asset-sourcing.md +122 -0
  54. package/skills/ima2-front/references/color-system.md +132 -0
  55. package/skills/ima2-front/references/consistency-locks.md +20 -0
  56. package/skills/ima2-front/references/crud-ui.md +53 -0
  57. package/skills/ima2-front/references/dropdown-layer.md +110 -0
  58. package/skills/ima2-front/references/i18n-global.md +104 -0
  59. package/skills/ima2-front/references/iterative-design.md +90 -0
  60. package/skills/ima2-front/references/korea-2026.md +174 -0
  61. package/skills/ima2-front/references/layout-discipline.md +161 -0
  62. package/skills/ima2-front/references/liquid-glass.md +181 -0
  63. package/skills/ima2-front/references/logo-sections.md +194 -0
  64. package/skills/ima2-front/references/mobile-ux.md +144 -0
  65. package/skills/ima2-front/references/performance-budget.md +106 -0
  66. package/skills/ima2-front/references/preflight-full.md +58 -0
  67. package/skills/ima2-front/references/product-density.md +53 -0
  68. package/skills/ima2-front/references/prototype-variants.md +54 -0
  69. package/skills/ima2-front/references/reference-capture.md +120 -0
  70. package/skills/ima2-front/references/responsive-viewport.md +139 -0
  71. package/skills/ima2-front/references/seo-baseline.md +123 -0
  72. package/skills/ima2-front/references/soft-3d-asset-gates.md +70 -0
  73. package/skills/ima2-front/references/stacks/astro.md +204 -0
  74. package/skills/ima2-front/references/stacks/mobile-native.md +281 -0
  75. package/skills/ima2-front/references/stacks/nextjs.md +219 -0
  76. package/skills/ima2-front/references/stacks/react.md +264 -0
  77. package/skills/ima2-front/references/stacks/svelte.md +235 -0
  78. package/skills/ima2-front/references/stacks/vanilla.md +226 -0
  79. package/skills/ima2-front/references/theme-switching.md +82 -0
  80. package/skills/ima2-front/references/top-bar.md +126 -0
  81. package/skills/ima2-front/references/typography-wrapping.md +270 -0
  82. package/skills/ima2-front/references/ux-writing-ko.md +62 -0
  83. package/skills/ima2-front/references/visual-verification.md +102 -0
  84. package/skills/ima2-uiux/SKILL.md +477 -0
  85. package/skills/ima2-uiux/references/anti-slop-judgment.md +39 -0
  86. package/skills/ima2-uiux/references/color-system.md +80 -0
  87. package/skills/ima2-uiux/references/design-isms.md +194 -0
  88. package/skills/ima2-uiux/references/design-read-example.md +33 -0
  89. package/skills/ima2-uiux/references/design-system-bootstrap.md +133 -0
  90. package/skills/ima2-uiux/references/favicon-logo.md +355 -0
  91. package/skills/ima2-uiux/references/form-patterns.md +118 -0
  92. package/skills/ima2-uiux/references/intent-discovery-ladder.md +86 -0
  93. package/skills/ima2-uiux/references/korean-design-vocabulary.md +52 -0
  94. package/skills/ima2-uiux/references/layout-macrostructures.md +54 -0
  95. package/skills/ima2-uiux/references/logo-trust-sections.md +96 -0
  96. package/skills/ima2-uiux/references/mobile-native-ux.md +207 -0
  97. package/skills/ima2-uiux/references/product-personalities.md +118 -0
  98. package/skills/ima2-uiux/references/responsive-nav.md +66 -0
  99. package/skills/ima2-uiux/references/typography-line-breaks.md +193 -0
  100. package/skills/ima2-uiux/references/ux-preflight.md +65 -0
  101. package/skills/ima2-uiux/references/ux-states.md +197 -0
  102. package/skills/ima2-uiux/references/visual-hierarchy.md +115 -0
  103. package/ui/dist/.vite/manifest.json +13 -13
  104. package/ui/dist/assets/AgentWorkspace-CtYt4SF5.js +3 -0
  105. package/ui/dist/assets/{CardNewsWorkspace-Cdxn1ohU.js → CardNewsWorkspace-DN5cVqG5.js} +1 -1
  106. package/ui/dist/assets/GenerationRequestLogPanel-DnmUQdKR.js +1 -0
  107. package/ui/dist/assets/{NodeCanvas-C67sLboA.js → NodeCanvas-CxpfIBI0.js} +1 -1
  108. package/ui/dist/assets/PromptBuilderPanel-C2R3ObtR.js +2 -0
  109. package/ui/dist/assets/{PromptImportDialog-DeQXsEEv.js → PromptImportDialog-BIxz_yEx.js} +2 -2
  110. package/ui/dist/assets/PromptImportDiscoverySection-BQTlPMME.js +1 -0
  111. package/ui/dist/assets/PromptImportFolderSection-Ds_Th9O3.js +1 -0
  112. package/ui/dist/assets/{PromptLibraryPanel-Db3xEPM_.js → PromptLibraryPanel-Rs4l45pV.js} +2 -2
  113. package/ui/dist/assets/{SettingsWorkspace-BDk_1W-V.js → SettingsWorkspace-p1AZ6uT9.js} +1 -1
  114. package/ui/dist/assets/index-0-_vgFGs.js +4 -0
  115. package/ui/dist/assets/index-Dm3pFxV4.js +23 -0
  116. package/ui/dist/assets/index-J8yDF3Ch.css +1 -0
  117. package/ui/dist/index.html +2 -2
  118. package/ui/dist/assets/AgentWorkspace-DAg_7zpY.js +0 -3
  119. package/ui/dist/assets/GenerationRequestLogPanel-C_qvEUi2.js +0 -1
  120. package/ui/dist/assets/PromptBuilderPanel-DjvVdAie.js +0 -2
  121. package/ui/dist/assets/PromptImportDiscoverySection-CrwyUKYI.js +0 -1
  122. package/ui/dist/assets/PromptImportFolderSection-CToGMqYE.js +0 -1
  123. package/ui/dist/assets/index-2oG6in1i.css +0 -1
  124. package/ui/dist/assets/index-CoxMOXAU.js +0 -23
  125. package/ui/dist/assets/index-p8egnGHk.js +0 -4
@@ -0,0 +1,120 @@
1
+ # Reference Capture
2
+
3
+ Capture reference sites only to learn structure, ground visual judgment, and
4
+ provide reference material for concept mockups. Captures are analysis inputs,
5
+ not project assets.
6
+
7
+ Use this workflow when a page, component, brand system, or visual interaction
8
+ needs source-grounded study before design synthesis or `ima2 --ref` mockups.
9
+
10
+ ---
11
+
12
+ ## Purpose
13
+
14
+ ### Analysis-Only Capture (FE-CAPTURE-01, STRICT)
15
+
16
+ Captured third-party HTML, CSS, images, videos, logos, and font references are
17
+ analysis-only. They may be used to:
18
+
19
+ - study layout structure, density, hierarchy, spacing, and interaction shape
20
+ - compare DOM/component composition against a target pattern
21
+ - ground an `ima2 --ref` concept mockup or style exploration
22
+ - document observed behavior in a devlog unit
23
+
24
+ They must not be copied into shipped source, public assets, production
25
+ bundles, marketing exports, or final deliverables.
26
+
27
+ ---
28
+
29
+ ## Mechanics
30
+
31
+ ### Capture Channels (FE-CAPTURE-02, DEFAULT)
32
+
33
+ Use the least invasive public capture method that gives enough evidence.
34
+
35
+ | Channel | Use |
36
+ | --- | --- |
37
+ | In-app browser `pageAssets` capability | List and bundle observed page assets from the rendered page |
38
+ | `curl` / `wget` | Fetch public HTML, CSS, JSON, images, or videos needed for analysis |
39
+ | DOM snapshot | Record structure, landmarks, role patterns, component nesting, and text density |
40
+ | Screenshot | Capture visual state, responsive breakpoints, hover/open states, and motion posters |
41
+
42
+ Do not bypass auth, paywalls, robots restrictions, private CDNs, signed URLs,
43
+ or technical access controls.
44
+
45
+ ### Storage Location (FE-CAPTURE-03, STRICT)
46
+
47
+ Store captures under the active devlog unit, never under shipped project asset
48
+ directories such as `public/`, `assets/`, `images/`, `src/assets/`, or app
49
+ static folders.
50
+
51
+ Recommended shape: `devlog/<active-unit>/captures/manifest.md` plus one
52
+ folder per source with captured DOM, CSS, screenshots, and notes.
53
+
54
+ ---
55
+
56
+ ## Legal Boundary
57
+
58
+ ### Never-Ship Rule (FE-CAPTURE-04, STRICT)
59
+
60
+ Captured third-party assets never ship. This includes copied photographs,
61
+ illustrations, videos, icons, logos, CSS artwork, SVGs, and bundled media.
62
+
63
+ Webfont binaries are never copied. Treat webfonts as license-restricted by
64
+ default even when they are publicly downloadable. You may record the font name,
65
+ CSS stack, metrics observations, and usage notes for analysis.
66
+
67
+ Photography, illustrations, videos, and logos are analysis-only unless they are
68
+ independently re-sourced through shippable channels. Shippable brand assets
69
+ come only from `brand-asset-sourcing.md` channels such as official press kits,
70
+ Simple Icons, SVGL, theSVG, or other explicit licensed libraries.
71
+
72
+ ### Mockup Reference Boundary (FE-CAPTURE-05, DEFAULT)
73
+
74
+ Captured material may be passed to `ima2 --ref` to ground composition, density,
75
+ palette, or material exploration. The generated concept mockup remains an
76
+ exploration artifact unless all shipped pixels are recreated or sourced through
77
+ legal build-asset channels.
78
+
79
+ Do not crop a captured logo, photo, illustration, or UI region out of a
80
+ reference and place it into the build.
81
+
82
+ ---
83
+
84
+ ## Provenance Manifest
85
+
86
+ ### Manifest Required (FE-CAPTURE-06, STRICT)
87
+
88
+ Every capture set needs a manifest stored next to the captured files, usually
89
+ `captures/manifest.md` or `captures/manifest.json` inside the active devlog
90
+ unit.
91
+
92
+ Each capture record must include:
93
+
94
+ | Field | Required Value |
95
+ | --- | --- |
96
+ | `source_url` | Original page or asset URL |
97
+ | `capture_date` | Date captured, preferably ISO `YYYY-MM-DD` |
98
+ | `license_status` | Known license, or `unknown - assume restricted` |
99
+ | `intended_use` | `analysis` or `mockup-ref` |
100
+ | `storage_path` | Path to the local captured file or folder |
101
+
102
+ Optional fields: viewport, interaction state, tool used, notes, and
103
+ replacement plan for any shippable equivalent.
104
+
105
+ ---
106
+
107
+ ## Ship Gate
108
+
109
+ ### Captured Asset Preflight (FE-CAPTURE-07, STRICT)
110
+
111
+ Before shipping, verify that no captured third-party asset appears in the
112
+ shipped build. The same row belongs in `preflight-full.md`:
113
+
114
+ ```text
115
+ No captured third-party asset in the shipped build; capture manifest present
116
+ for any reference captures.
117
+ ```
118
+
119
+ If a captured reference inspired the final design, document the shippable
120
+ replacement source or confirm the final pixels were recreated from scratch.
@@ -0,0 +1,139 @@
1
+ # Responsive & Viewport Rules (MANDATORY)
2
+
3
+ Every multi-column layout, every full-height section, every image-heavy page MUST follow these rules. "It works at 1440px" is not responsive.
4
+
5
+ ---
6
+
7
+ ## Canonical Breakpoint Tiers
8
+
9
+ | Tier | Breakpoint | Name | Tailwind | Devices |
10
+ |------|-----------|------|----------|---------|
11
+ | T1 | < 640px | Mobile | default | Phone portrait/landscape |
12
+ | T2 | ≥ 640px | Large Mobile | `sm:` | Landscape phones, small tablets |
13
+ | T3 | ≥ 768px | Tablet | `md:` | iPad portrait, desktop half-screen (1440px split) |
14
+ | T4 | ≥ 1024px | Small Desktop | `lg:` | iPad landscape, laptop, desktop half-screen (1920px split) |
15
+ | T5 | ≥ 1280px | Desktop | `xl:` | Standard desktop monitors |
16
+ | T5+ | ≥ 1536px | Large Desktop | `2xl:` | Ultra-wide, large monitors |
17
+
18
+ Use these tiers consistently. Do not invent ad-hoc `@media` breakpoints. Container query breakpoints are based on container width (not viewport tiers) — custom values like 400px or 900px are fine there.
19
+
20
+ ## Page Containment (MANDATORY)
21
+
22
+ Every page layout MUST have a max-width wrapper:
23
+ ```css
24
+ max-w-[1400px] mx-auto px-4 sm:px-6 lg:px-8
25
+ ```
26
+
27
+ Without containment, text lines stretch to 200+ characters on wide monitors — unreadable.
28
+ Full-bleed sections (hero images, color blocks) break out of containment with negative margins or `w-screen`.
29
+
30
+ ## Viewport Units
31
+
32
+ - `min-h-[100dvh]` — ALWAYS. Accounts for mobile browser chrome (iOS Safari address bar).
33
+ - `h-screen` / `100vh` — BANNED for full-height sections. These cause layout jump on mobile.
34
+ - `svh` — use for "minimum guaranteed visible height" (rare).
35
+ - `lvh` — use for background sizing where slight overflow is acceptable.
36
+
37
+ ## Container Queries (default for components)
38
+
39
+ Prefer `@container` over `@media` for any reusable component. Components should adapt to their parent's width, not the viewport — this is what makes the same component work in a sidebar, modal, full-width layout, AND split-screen.
40
+
41
+ ```css
42
+ .card-grid { container-type: inline-size; }
43
+
44
+ @container (min-width: 600px) {
45
+ .card-grid { grid-template-columns: repeat(2, 1fr); }
46
+ }
47
+ @container (min-width: 900px) {
48
+ .card-grid { grid-template-columns: repeat(3, 1fr); }
49
+ }
50
+ ```
51
+
52
+ Reserve `@media` for page-level layout shifts (sidebar show/hide, nav mode switch, page grid columns).
53
+
54
+ ## Split-Screen / Half-Window (the neglected viewport)
55
+
56
+ macOS split-view on a 1440px display gives each app ~640-720px. Windows snap on 1440px gives ~720px. On 1920px displays, each half is ~960px.
57
+
58
+ This range (640-1024px) falls between "mobile collapse" and "full desktop." Most pages break here because rules only exist for < 768px and ≥ 1280px.
59
+
60
+ Rules:
61
+ - At 640-767px (T2): 2-column grids reduce to 1-column. Side-by-side hero stacks. Padding tightens.
62
+ - At 768-1023px (T3): 3-column grids reduce to 2-column. Hero can remain side-by-side if text-heavy. Bento reduces to 2-column.
63
+ - Test at 768px AND 1024px in addition to mobile and desktop widths.
64
+
65
+ ## Responsive Spacing Scale
66
+
67
+ Section padding scales with viewport tier:
68
+
69
+ | Element | Mobile (<640px) | Tablet (640-1023px) | Desktop (≥1024px) |
70
+ |---------|-----------------|---------------------|--------------------|
71
+ | Section vertical padding | `py-12` (3rem) | `py-16` (4rem) | `py-20` to `py-24` (5-6rem) |
72
+ | Section horizontal padding | `px-4` (1rem) | `px-6` (1.5rem) | `px-8` (2rem) |
73
+ | Inter-section gap | `gap-12` | `gap-16` | `gap-20` |
74
+ | Card grid gap | `gap-4` | `gap-5` | `gap-6` |
75
+ | Content max-width | `max-w-full` | `max-w-2xl` | `max-w-[1400px]` |
76
+
77
+ ## Responsive Images (MANDATORY for image-heavy pages)
78
+
79
+ ### srcset / sizes
80
+ Above-fold / LCP images use `loading="eager"` (or omit — eager is the default) + `fetchpriority="high"`. Below-fold images use `loading="lazy"`. Example (above-fold hero):
81
+ ```html
82
+ <img
83
+ src="hero-800.webp"
84
+ srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w"
85
+ sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 800px"
86
+ alt="..."
87
+ loading="eager"
88
+ fetchpriority="high"
89
+ decoding="async"
90
+ />
91
+ ```
92
+
93
+ ### Art Direction (picture element)
94
+ When the image crop must change between viewports (landscape hero → portrait on mobile):
95
+ ```html
96
+ <picture>
97
+ <source media="(max-width: 639px)" srcset="hero-portrait.webp" />
98
+ <source media="(max-width: 1023px)" srcset="hero-square.webp" />
99
+ <img src="hero-landscape.webp" alt="..." />
100
+ </picture>
101
+ ```
102
+
103
+ ### Aspect Ratio
104
+ Lock aspect ratios to prevent layout shift:
105
+ ```css
106
+ .hero-image { aspect-ratio: 16/9; object-fit: cover; }
107
+ @media (max-width: 767px) { .hero-image { aspect-ratio: 4/5; } }
108
+ ```
109
+
110
+ ## Safe Area / Notch (MANDATORY for mobile)
111
+
112
+ Modern phones have notches, dynamic islands, and home indicators. Content MUST not hide behind them:
113
+
114
+ Apply safe-area insets selectively, not as blanket body padding (top inset on `body` conflicts with fixed navigation bars):
115
+
116
+ ```css
117
+ /* Fixed bottom elements (sticky CTA, tab bar) */
118
+ .sticky-bottom {
119
+ padding-bottom: calc(0.75rem + env(safe-area-inset-bottom));
120
+ }
121
+
122
+ /* Horizontal safe area for landscape notch devices */
123
+ .page-wrapper {
124
+ padding-left: env(safe-area-inset-left);
125
+ padding-right: env(safe-area-inset-right);
126
+ }
127
+ ```
128
+
129
+ Add `viewport-fit=cover` to the meta viewport tag:
130
+ ```html
131
+ <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
132
+ ```
133
+
134
+ ## Nav Height Cap
135
+
136
+ - Desktop nav: 64-72px default, 80px absolute max
137
+ - Mobile nav: 56-64px
138
+ - Nav must not consume >10% of viewport height
139
+ - On scroll, nav can compact to 48px with `transition-all duration-200`
@@ -0,0 +1,123 @@
1
+ # SEO, GEO & Social Sharing
2
+
3
+ ## Technical SEO
4
+
5
+ ### Required Meta Tags
6
+
7
+ ```html
8
+ <html lang="ko">
9
+ <head>
10
+ <meta charset="utf-8">
11
+ <meta name="viewport" content="width=device-width, initial-scale=1">
12
+ <title>{Page Title} — {Site Name}</title> <!-- ≤60 chars -->
13
+ <meta name="description" content="..."> <!-- ≤160 chars -->
14
+ <link rel="canonical" href="https://..."> <!-- absolute URL -->
15
+ </head>
16
+ ```
17
+
18
+ - One `<title>` per page, unique across the site
19
+ - Description: complete sentence, not keyword stuffing
20
+ - Canonical URL resolves www/non-www and trailing slash consistently
21
+ - `lang` attribute must match page content language
22
+
23
+ ### Heading Hierarchy
24
+
25
+ - `<h1>`: one per page, contains primary keyword naturally
26
+ - `<h2>`: section headings, each a distinct topic
27
+ - `<h3>`: subsections within h2. No skipping (h2 → h4 is invalid)
28
+ - Never use heading tags for visual sizing — use CSS classes
29
+
30
+ ### Semantic HTML
31
+
32
+ Use `<header>`, `<main>` (one per page), `<article>`, `<section>`, `<aside>`, `<footer>`, `<nav>`. Every `<img>` needs `alt` text. Every `<a>` needs discernible text. Use `<time datetime="...">` for dates.
33
+
34
+ ### Structured Data (JSON-LD)
35
+
36
+ Always JSON-LD in `<head>`, never Microdata or RDFa.
37
+
38
+ | Page Type | Schema | Required Fields |
39
+ |-----------|--------|-----------------|
40
+ | Landing/Home | `WebPage` + `Organization` | name, url, logo, description |
41
+ | Product | `Product` | name, description, offers |
42
+ | Blog post | `BlogPosting` | headline, datePublished, dateModified, author, image |
43
+ | FAQ | `FAQPage` + `Question`/`Answer` | each Q&A pair |
44
+ | Service | `Service` | name, description, provider, areaServed |
45
+ | Breadcrumbs | `BreadcrumbList` | itemListElement with position + name + URL |
46
+
47
+ - Schema MUST match visible page content — mismatched schema is penalized
48
+ - Include `dateModified` on content pages
49
+ - FAQPage schema has the highest AI citation lift
50
+ - Test with Google Rich Results Test before shipping
51
+
52
+ ### Robots & Sitemap
53
+
54
+ ```
55
+ User-agent: *
56
+ Allow: /
57
+ Sitemap: https://example.com/sitemap.xml
58
+
59
+ User-agent: GPTBot
60
+ Allow: /
61
+ User-agent: ChatGPT-User
62
+ Allow: /
63
+ User-agent: anthropic-ai
64
+ Allow: /
65
+ User-agent: PerplexityBot
66
+ Allow: /
67
+ User-agent: Google-Extended
68
+ Allow: /
69
+ ```
70
+
71
+ - XML sitemap with `<lastmod>`, `<changefreq>`, `<priority>`
72
+ - Allow AI crawlers by default — GEO requires it
73
+
74
+ ## GEO (Generative Engine Optimization)
75
+
76
+ Optimizing content so AI answer engines (ChatGPT, Perplexity, Gemini, Claude) retrieve and cite your content. GEO is a layer ON TOP of SEO, not a replacement.
77
+
78
+ ### Strategies
79
+
80
+ 1. **Quotable content** — clear factual statements, TL;DR summaries, data tables an LLM can extract verbatim. Primary value proposition in the first 200 words.
81
+ 2. **FAQPage schema** — highest AI citation lift. Use whenever the page addresses common questions.
82
+ 3. **Content freshness** — visible "Last updated: YYYY-MM-DD" timestamp.
83
+ 4. **Authority signals** — original data, proprietary research, expert commentary.
84
+ 5. **Performance** — faster FCP strongly correlates with higher AI citation likelihood.
85
+ 6. **AI-generated pages** — always SSR/SSG. Never gate critical text behind client-side JS.
86
+
87
+ ## Social Sharing
88
+
89
+ ### Open Graph (Required)
90
+
91
+ ```html
92
+ <meta property="og:title" content="Page Title"> <!-- ≤60 chars -->
93
+ <meta property="og:description" content="..."> <!-- ≤160 chars -->
94
+ <meta property="og:image" content="https://.../og.png"> <!-- 1200x630px -->
95
+ <meta property="og:url" content="https://...">
96
+ <meta property="og:type" content="website">
97
+ <meta property="og:site_name" content="Site Name">
98
+ <meta property="og:locale" content="ko_KR">
99
+ ```
100
+
101
+ ### Twitter Cards
102
+
103
+ ```html
104
+ <meta name="twitter:card" content="summary_large_image">
105
+ <meta name="twitter:title" content="Page Title">
106
+ <meta name="twitter:description" content="...">
107
+ <meta name="twitter:image" content="https://.../og.png">
108
+ ```
109
+
110
+ - OG image: 1200x630px, PNG or JPG, < 1MB, no text smaller than 24px
111
+ - For dynamic pages, generate OG images via edge function (Vercel OG, Satori)
112
+ - Test with Twitter Card Validator, Facebook Debugger
113
+
114
+ ## Pre-flight
115
+
116
+ - [ ] `<title>` unique and ≤ 60 chars
117
+ - [ ] `<meta name="description">` present and ≤ 160 chars
118
+ - [ ] `<link rel="canonical">` with absolute URL
119
+ - [ ] `<html lang="...">` matches content language
120
+ - [ ] JSON-LD structured data matches page type
121
+ - [ ] OG tags present (title, description, image, url)
122
+ - [ ] `<h1>` unique, one per page, no skipped levels
123
+ - [ ] "Last updated" date visible on content pages
@@ -0,0 +1,70 @@
1
+ # Soft 3D / Character-Like Asset Gates
2
+
3
+ Use this when a design includes soft 3D miniatures, toy-like objects, mascot/character illustrations, chibi proportions, rounded pastel 3D graphics, or tactile product metaphors.
4
+
5
+ ## Definition
6
+
7
+ "Cute" in this context means visual assets, not Korean copy:
8
+
9
+ - soft 3D miniature objects
10
+ - toy-like product metaphors
11
+ - character or mascot-like illustrations
12
+ - rounded pastel tactile graphics
13
+ - chibi/miniature proportions
14
+ - finance/education/commerce concepts made into friendly objects
15
+
16
+ It does not mean:
17
+
18
+ - aegyo labels
19
+ - childish error messages
20
+ - excessive exclamation marks
21
+ - fake friendliness in high-trust flows
22
+
23
+ ## Domain Gate
24
+
25
+ | Domain | Gate |
26
+ | --- | --- |
27
+ | Kids / education | Allowed when it guides learning |
28
+ | Community / casual commerce | Allowed when local, friendly, and restrained |
29
+ | Consumer onboarding | Allowed when it reduces anxiety |
30
+ | Fintech | Allowed only as premium semantic support, Toss-style; text and trust stay primary |
31
+ | Government / public service | Avoid by default |
32
+ | B2B / admin / ops | Avoid by default |
33
+ | Developer tools | Avoid by default |
34
+ | Auth / security / payment | Avoid unless it clarifies state without reducing trust |
35
+
36
+ ## Premium vs Slop
37
+
38
+ Premium:
39
+
40
+ - custom or brand-consistent asset system
41
+ - semantic product metaphor
42
+ - consistent lighting, material, perspective, and palette
43
+ - one core graphic or clear hierarchy
44
+ - subordinate to headline, CTA, and state
45
+ - optimized and performant
46
+ - works across supported themes
47
+
48
+ Slop:
49
+
50
+ - generic public 3D icon pack
51
+ - random cute object unrelated to the page
52
+ - inconsistent lighting/materials
53
+ - low-polish AI output
54
+ - decorative overload
55
+ - asset competes with text or CTA
56
+ - heavy 3D scene with no product value
57
+
58
+ ## Toss-Style Exception
59
+
60
+ Soft 3D can work in Korean fintech when it behaves like Toss:
61
+
62
+ - blue/white restrained palette
63
+ - finance-related object metaphors
64
+ - high production value
65
+ - text-first hierarchy
66
+ - simple clean digital style
67
+ - no obstruction of key information
68
+
69
+ Do not copy Toss assets. Extract the rule: premium, semantic, restrained, and brand-consistent.
70
+
@@ -0,0 +1,204 @@
1
+ # Astro Stack
2
+
3
+ Last reviewed: 2026-06-16
4
+ Applies to: Astro 5.x
5
+ When to read: Building or modifying Astro projects
6
+ Canonical owner: dev-frontend
7
+
8
+ Read `core/aesthetics.md` + `core/anti-slop.md` first.
9
+
10
+ ## 1. Islands Architecture
11
+
12
+ Astro ships zero JavaScript by default. Interactive components are explicit **islands** that hydrate independently:
13
+
14
+ ```astro
15
+ ---
16
+ // Static by default — no JS shipped
17
+ import Header from '../components/Header.astro';
18
+ import Counter from '../components/Counter.tsx'; // React island
19
+ import Newsletter from '../components/Newsletter.svelte'; // Svelte island
20
+ ---
21
+
22
+ <Header />
23
+
24
+ <!-- Interactive islands — each hydrates independently -->
25
+ <Counter client:load />
26
+ <Newsletter client:visible />
27
+ ```
28
+
29
+ | Directive | When JS Loads | Use Case |
30
+ |-----------|--------------|----------|
31
+ | `client:load` | Immediately on page load | Above-fold interactive elements (nav, search, auth) |
32
+ | `client:idle` | After page is idle (`requestIdleCallback`) | Below-fold interactive elements, analytics |
33
+ | `client:visible` | When element enters viewport | Comments, newsletter forms, lazy widgets |
34
+ | `client:media` | When media query matches | Mobile-only interactive elements |
35
+ | `client:only="react"` | Immediately, no SSR | Components that cannot SSR (canvas, WebGL, browser APIs) |
36
+ | _(none)_ | Never — static HTML only | Content display, navigation, layout |
37
+
38
+ Rules:
39
+ - Default to no `client:*` directive — components are static HTML unless interaction is required.
40
+ - Use `client:visible` for anything below the fold — saves initial bundle size.
41
+ - Use `client:only` only when SSR genuinely fails (browser APIs, canvas) — it sends no HTML.
42
+ - Every `client:*` directive adds a framework runtime to the page bundle — minimize island count.
43
+ - Astro components (`.astro`) are always static — they cannot be islands. Use React/Svelte/Vue for interactive islands.
44
+
45
+ ## 2. Multi-Framework Shell
46
+
47
+ Astro uniquely supports mixing frameworks in one project:
48
+
49
+ | Framework | File Extension | Island Support | When to Use |
50
+ |-----------|---------------|---------------|-------------|
51
+ | React | `.tsx` / `.jsx` | Yes | Existing React component library, complex interactive UI |
52
+ | Svelte | `.svelte` | Yes | Lightweight interactivity, transitions, form handling |
53
+ | Vue | `.vue` | Yes | Existing Vue codebase, directive-heavy UI |
54
+ | Solid | `.tsx` (with Solid plugin) | Yes | Performance-critical islands, fine-grained reactivity |
55
+ | Preact | `.tsx` (with Preact plugin) | Yes | Smaller React-compatible islands |
56
+
57
+ ```javascript
58
+ // astro.config.mjs
59
+ import { defineConfig } from 'astro/config';
60
+ import react from '@astrojs/react';
61
+ import svelte from '@astrojs/svelte';
62
+
63
+ export default defineConfig({
64
+ integrations: [
65
+ react({ include: ['**/react/*'] }),
66
+ svelte(),
67
+ ],
68
+ });
69
+ ```
70
+
71
+ Rules:
72
+ - Keep to **one primary framework** per project — multi-framework is for migration or specialized components, not default practice.
73
+ - Organize framework-specific components in separate directories (`components/react/`, `components/svelte/`).
74
+ - Shared state between different framework islands requires a framework-agnostic store (nanostores, signals).
75
+ - Do not pass complex objects as island props — islands serialize props through HTML attributes. Use primitive types or simple objects.
76
+
77
+ ```typescript
78
+ // Shared state across frameworks with nanostores
79
+ // src/stores/cart.ts
80
+ import { atom, map } from 'nanostores';
81
+
82
+ export const cartItems = map<Record<string, CartItem>>({});
83
+ export const cartCount = atom(0);
84
+ ```
85
+
86
+ ## 3. Content Collections
87
+
88
+ Type-safe content management for Markdown, MDX, YAML, and JSON:
89
+
90
+ ```typescript
91
+ // src/content.config.ts (Astro 5 — file-based content config)
92
+ import { defineCollection, z } from 'astro:content';
93
+ import { glob } from 'astro/loaders';
94
+
95
+ const blog = defineCollection({
96
+ loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/blog' }),
97
+ schema: z.object({
98
+ title: z.string(),
99
+ description: z.string(),
100
+ pubDate: z.coerce.date(),
101
+ tags: z.array(z.string()).default([]),
102
+ draft: z.boolean().default(false),
103
+ }),
104
+ });
105
+
106
+ export const collections = { blog };
107
+ ```
108
+
109
+ ```astro
110
+ ---
111
+ // src/pages/blog/[slug].astro
112
+ import { getCollection, render } from 'astro:content';
113
+
114
+ export async function getStaticPaths() {
115
+ const posts = await getCollection('blog', ({ data }) => !data.draft);
116
+ return posts.map(post => ({
117
+ params: { slug: post.id },
118
+ props: { post },
119
+ }));
120
+ }
121
+
122
+ const { post } = Astro.props;
123
+ const { Content } = await render(post);
124
+ ---
125
+
126
+ <article>
127
+ <h1>{post.data.title}</h1>
128
+ <time>{post.data.pubDate.toLocaleDateString()}</time>
129
+ <Content />
130
+ </article>
131
+ ```
132
+
133
+ Rules:
134
+ - Define schemas for all content collections — untyped content defeats the purpose.
135
+ - Use `z.coerce.date()` for dates — Markdown frontmatter dates are strings.
136
+ - Filter drafts in `getCollection()` calls, not in templates.
137
+ - Use Astro 5's `content.config.ts` (replaces `config.ts` in `src/content/`).
138
+
139
+ ## 4. Rendering Modes: SSG / SSR / Hybrid
140
+
141
+ | Mode | Config | When to Use |
142
+ |------|--------|-------------|
143
+ | **SSG** (default) | `output: 'static'` | Blog, docs, marketing — content changes infrequently |
144
+ | **SSR** | `output: 'server'` | Auth-gated, personalized, real-time — every request is dynamic |
145
+ | **Hybrid** | `output: 'static'` + per-page `export const prerender = false` | Mostly static site with a few dynamic pages |
146
+
147
+ ```astro
148
+ ---
149
+ // src/pages/dashboard.astro — dynamic page in hybrid mode
150
+ export const prerender = false;
151
+
152
+ const user = await getUser(Astro.cookies.get('session'));
153
+ if (!user) return Astro.redirect('/login');
154
+ ---
155
+
156
+ <h1>Welcome, {user.name}</h1>
157
+ ```
158
+
159
+ Rules:
160
+ - Default to SSG — ship HTML, not a server.
161
+ - Use hybrid mode before full SSR — mark only dynamic pages with `prerender = false`.
162
+ - SSR requires a deployment adapter (`@astrojs/node`, `@astrojs/vercel`, `@astrojs/cloudflare`).
163
+ - Do not use SSR for content that can be statically generated — it adds latency and server cost.
164
+ - Cache SSR responses at the CDN edge when content is user-independent.
165
+
166
+ ### Deployment Adapters
167
+
168
+ | Adapter | Target | Install |
169
+ |---------|--------|---------|
170
+ | `@astrojs/node` | Node.js server (Docker, VPS) | `npx astro add node` |
171
+ | `@astrojs/vercel` | Vercel (edge/serverless) | `npx astro add vercel` |
172
+ | `@astrojs/cloudflare` | Cloudflare Workers/Pages | `npx astro add cloudflare` |
173
+ | `@astrojs/netlify` | Netlify Functions | `npx astro add netlify` |
174
+ | _(none)_ | Static output (default) | No adapter needed for SSG |
175
+
176
+ ### Performance Characteristics
177
+
178
+ | Metric | Astro 5 | Next.js 16 | SvelteKit 2 |
179
+ |--------|---------|------------|-------------|
180
+ | Default JS shipped | 0 KB (static pages) | Framework runtime (~80 KB) | ~2 KB (compiled) |
181
+ | Hydration model | Islands (opt-in per component) | Full page (RSC partial) | Full page |
182
+ | Multi-framework | Yes (React + Svelte + Vue) | React only | Svelte only |
183
+ | Content layer | Built-in Collections + Zod | MDX (plugin) | mdsvex (plugin) |
184
+ | Build tool | Vite | Turbopack/Webpack | Vite |
185
+ | Best for | Content-heavy, docs, marketing | Full-stack apps | Interactive apps |
186
+
187
+ ## 5. Anti-Patterns
188
+
189
+ | Banned | Symptom | Fix |
190
+ |--------|---------|-----|
191
+ | `client:load` on everything | Full React/Vue/Svelte runtime shipped on every page | Use `client:visible` or `client:idle`; most components need no JS |
192
+ | Multiple frameworks without justification | Bundle bloat — each framework adds its runtime | One primary framework; multi-framework only for migration |
193
+ | Complex objects as island props | Serialization errors, silent data loss | Use primitives or simple objects; fetch data inside the island |
194
+ | SSR for static content | Unnecessary server cost and latency | Use SSG or hybrid mode (§4) |
195
+ | Skipping content collection schemas | Untyped frontmatter, runtime errors on missing fields | Always define Zod schemas for collections (§3) |
196
+
197
+ ## Pre-flight
198
+
199
+ - [ ] Default rendering is SSG unless dynamic pages are explicitly marked
200
+ - [ ] Islands use appropriate `client:*` directives — no unnecessary `client:load`
201
+ - [ ] Single primary framework chosen; multi-framework justified if present
202
+ - [ ] Content collections have Zod schemas defined
203
+ - [ ] Island prop types are serialization-safe (no functions, classes, or complex objects)
204
+ - [ ] Shared cross-framework state uses nanostores or equivalent