@aexol/spectral 0.9.230 → 0.9.231
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.
- package/CHANGELOG.md +2 -0
- package/dist/designer/data/skills/blog-post.d.ts +3 -0
- package/dist/designer/data/skills/blog-post.d.ts.map +1 -0
- package/dist/designer/data/skills/blog-post.js +84 -0
- package/dist/designer/data/skills/blog-post.ts +87 -0
- package/dist/designer/data/skills/critique.d.ts +3 -0
- package/dist/designer/data/skills/critique.d.ts.map +1 -0
- package/dist/designer/data/skills/critique.js +109 -0
- package/dist/designer/data/skills/critique.ts +112 -0
- package/dist/designer/data/skills/dashboard.d.ts +3 -0
- package/dist/designer/data/skills/dashboard.d.ts.map +1 -0
- package/dist/designer/data/skills/dashboard.js +165 -0
- package/dist/designer/data/skills/dashboard.ts +168 -0
- package/dist/designer/data/skills/design-brief.d.ts +3 -0
- package/dist/designer/data/skills/design-brief.d.ts.map +1 -0
- package/dist/designer/data/skills/design-brief.js +141 -0
- package/dist/designer/data/skills/design-brief.ts +144 -0
- package/dist/designer/data/skills/design-skill.d.ts +10 -0
- package/dist/designer/data/skills/design-skill.d.ts.map +1 -0
- package/dist/designer/data/skills/design-skill.js +1 -0
- package/dist/designer/data/skills/design-skill.ts +9 -0
- package/dist/designer/data/skills/docs-page.d.ts +3 -0
- package/dist/designer/data/skills/docs-page.d.ts.map +1 -0
- package/dist/designer/data/skills/docs-page.js +68 -0
- package/dist/designer/data/skills/docs-page.ts +71 -0
- package/dist/designer/data/skills/index.d.ts +3 -0
- package/dist/designer/data/skills/index.d.ts.map +1 -0
- package/dist/designer/data/skills/index.js +28 -0
- package/dist/designer/data/skills/index.ts +30 -0
- package/dist/designer/data/skills/magazine-poster.d.ts +3 -0
- package/dist/designer/data/skills/magazine-poster.d.ts.map +1 -0
- package/dist/designer/data/skills/magazine-poster.js +70 -0
- package/dist/designer/data/skills/magazine-poster.ts +73 -0
- package/dist/designer/data/skills/mobile-app.d.ts +3 -0
- package/dist/designer/data/skills/mobile-app.d.ts.map +1 -0
- package/dist/designer/data/skills/mobile-app.js +229 -0
- package/dist/designer/data/skills/mobile-app.ts +232 -0
- package/dist/designer/data/skills/motion-frames.d.ts +3 -0
- package/dist/designer/data/skills/motion-frames.d.ts.map +1 -0
- package/dist/designer/data/skills/motion-frames.js +121 -0
- package/dist/designer/data/skills/motion-frames.ts +124 -0
- package/dist/designer/data/skills/pricing-page.d.ts +3 -0
- package/dist/designer/data/skills/pricing-page.d.ts.map +1 -0
- package/dist/designer/data/skills/pricing-page.js +76 -0
- package/dist/designer/data/skills/pricing-page.ts +79 -0
- package/dist/designer/data/skills/saas-landing.d.ts +3 -0
- package/dist/designer/data/skills/saas-landing.d.ts.map +1 -0
- package/dist/designer/data/skills/saas-landing.js +71 -0
- package/dist/designer/data/skills/saas-landing.ts +74 -0
- package/dist/designer/data/skills/slide-deck.d.ts +3 -0
- package/dist/designer/data/skills/slide-deck.d.ts.map +1 -0
- package/dist/designer/data/skills/slide-deck.js +213 -0
- package/dist/designer/data/skills/slide-deck.ts +216 -0
- package/dist/designer/data/skills/social-carousel.d.ts +3 -0
- package/dist/designer/data/skills/social-carousel.d.ts.map +1 -0
- package/dist/designer/data/skills/social-carousel.js +135 -0
- package/dist/designer/data/skills/social-carousel.ts +138 -0
- package/dist/designer/data/skills/web-prototype.d.ts +3 -0
- package/dist/designer/data/skills/web-prototype.d.ts.map +1 -0
- package/dist/designer/data/skills/web-prototype.js +159 -0
- package/dist/designer/data/skills/web-prototype.ts +162 -0
- package/dist/designer/skills.d.ts +4 -10
- package/dist/designer/skills.d.ts.map +1 -1
- package/dist/designer/skills.js +2 -1643
- package/dist/extensions/wizard/index.js +9 -1
- package/dist/generated/parser/ast/nodes.d.ts +115 -0
- package/dist/generated/parser/ast/nodes.d.ts.map +1 -0
- package/dist/generated/parser/ast/nodes.js +8 -0
- package/dist/generated/parser/lexer/lexer.d.ts +28 -0
- package/dist/generated/parser/lexer/lexer.d.ts.map +1 -0
- package/dist/generated/parser/{lexer.js → lexer/lexer.js} +1 -180
- package/dist/generated/parser/{lexer.d.ts → lexer/tokens.d.ts} +5 -24
- package/dist/generated/parser/lexer/tokens.d.ts.map +1 -0
- package/dist/generated/parser/lexer/tokens.js +187 -0
- package/dist/generated/parser/mod.d.ts +5 -7
- package/dist/generated/parser/mod.d.ts.map +1 -1
- package/dist/generated/parser/mod.js +2 -1
- package/dist/generated/parser/parser/cursor.d.ts +47 -0
- package/dist/generated/parser/parser/cursor.d.ts.map +1 -0
- package/dist/generated/parser/parser/cursor.js +12 -0
- package/dist/generated/parser/parser/definitions.d.ts +16 -0
- package/dist/generated/parser/parser/definitions.d.ts.map +1 -0
- package/dist/generated/parser/parser/definitions.js +353 -0
- package/dist/generated/parser/parser/expressions.d.ts +17 -0
- package/dist/generated/parser/parser/expressions.d.ts.map +1 -0
- package/dist/generated/parser/parser/expressions.js +165 -0
- package/dist/generated/parser/parser.d.ts +18 -133
- package/dist/generated/parser/parser.d.ts.map +1 -1
- package/dist/generated/parser/parser.js +9 -505
- package/dist/generated/parser/tokenizer.d.ts +1 -2
- package/dist/generated/parser/tokenizer.d.ts.map +1 -1
- package/dist/generated/parser/tokenizer.js +2 -1
- package/dist/generated/parser/validator.d.ts +1 -1
- package/dist/generated/parser/validator.d.ts.map +1 -1
- package/dist/mcp/glimpse-ui.js +9 -1
- package/dist/relay/dispatcher.d.ts +11 -104
- package/dist/relay/dispatcher.d.ts.map +1 -1
- package/dist/relay/dispatcher.js +10 -1130
- package/dist/relay/rest.d.ts +31 -0
- package/dist/relay/rest.d.ts.map +1 -0
- package/dist/relay/rest.js +85 -0
- package/dist/relay/routing.d.ts +109 -0
- package/dist/relay/routing.d.ts.map +1 -0
- package/dist/relay/routing.js +669 -0
- package/dist/relay/wizard-login.d.ts +17 -0
- package/dist/relay/wizard-login.d.ts.map +1 -0
- package/dist/relay/wizard-login.js +419 -0
- package/dist/sdk/agent-core/agent-loop.d.ts +2 -9
- package/dist/sdk/agent-core/agent-loop.d.ts.map +1 -1
- package/dist/sdk/agent-core/agent-loop.js +4 -288
- package/dist/sdk/agent-core/tool-execution.d.ts +33 -0
- package/dist/sdk/agent-core/tool-execution.d.ts.map +1 -0
- package/dist/sdk/agent-core/tool-execution.js +300 -0
- package/dist/sdk/ai/env-api-keys.js +9 -1
- package/dist/sdk/ai/providers/openai/reasoning-replay.d.ts +48 -0
- package/dist/sdk/ai/providers/openai/reasoning-replay.d.ts.map +1 -0
- package/dist/sdk/ai/providers/openai/reasoning-replay.js +209 -0
- package/dist/sdk/ai/providers/openai-completions.d.ts.map +1 -1
- package/dist/sdk/ai/providers/openai-completions.js +1 -203
- package/dist/sdk/coding-agent/core/compaction/compaction.d.ts +6 -118
- package/dist/sdk/coding-agent/core/compaction/compaction.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/compaction/compaction.js +11 -733
- package/dist/sdk/coding-agent/core/compaction/cut-points.d.ts +58 -0
- package/dist/sdk/coding-agent/core/compaction/cut-points.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/compaction/cut-points.js +191 -0
- package/dist/sdk/coding-agent/core/compaction/dedupe.d.ts +28 -0
- package/dist/sdk/coding-agent/core/compaction/dedupe.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/compaction/dedupe.js +156 -0
- package/dist/sdk/coding-agent/core/compaction/summarize.d.ts +21 -0
- package/dist/sdk/coding-agent/core/compaction/summarize.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/compaction/summarize.js +181 -0
- package/dist/sdk/coding-agent/core/compaction/tokens.d.ts +47 -0
- package/dist/sdk/coding-agent/core/compaction/tokens.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/compaction/tokens.js +224 -0
- package/dist/sdk/coding-agent/core/extensions/session-events.d.ts +157 -0
- package/dist/sdk/coding-agent/core/extensions/session-events.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/extensions/session-events.js +13 -0
- package/dist/sdk/coding-agent/core/extensions/types.d.ts +6 -365
- package/dist/sdk/coding-agent/core/extensions/types.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/extensions/types.js +2 -10
- package/dist/sdk/coding-agent/core/extensions/ui-types.d.ts +219 -0
- package/dist/sdk/coding-agent/core/extensions/ui-types.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/extensions/ui-types.js +4 -0
- package/dist/sdk/coding-agent/core/package/default-package-manager.d.ts +115 -0
- package/dist/sdk/coding-agent/core/package/default-package-manager.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/package/default-package-manager.js +1184 -0
- package/dist/sdk/coding-agent/core/package/discovery.d.ts +20 -0
- package/dist/sdk/coding-agent/core/package/discovery.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/package/discovery.js +283 -0
- package/dist/sdk/coding-agent/core/package/ignore.d.ts +29 -0
- package/dist/sdk/coding-agent/core/package/ignore.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/package/ignore.js +235 -0
- package/dist/sdk/coding-agent/core/package/types.d.ts +128 -0
- package/dist/sdk/coding-agent/core/package/types.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/package/types.js +18 -0
- package/dist/sdk/coding-agent/core/package/update-check.d.ts +43 -0
- package/dist/sdk/coding-agent/core/package/update-check.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/package/update-check.js +253 -0
- package/dist/sdk/coding-agent/core/package-manager.d.ts +2 -188
- package/dist/sdk/coding-agent/core/package-manager.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/package-manager.js +1 -1940
- package/dist/sdk/coding-agent/core/session/migrate.d.ts +18 -0
- package/dist/sdk/coding-agent/core/session/migrate.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/session/migrate.js +78 -0
- package/dist/sdk/coding-agent/core/session/types.d.ts +165 -0
- package/dist/sdk/coding-agent/core/session/types.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/session/types.js +4 -0
- package/dist/sdk/coding-agent/core/session-manager.d.ts +3 -161
- package/dist/sdk/coding-agent/core/session-manager.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/session-manager.js +4 -72
- package/package.json +2 -2
- package/dist/generated/parser/lexer.d.ts.map +0 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { blogPost } from "./blog-post.js";
|
|
2
|
+
import { critique } from "./critique.js";
|
|
3
|
+
import { dashboard } from "./dashboard.js";
|
|
4
|
+
import { designBrief } from "./design-brief.js";
|
|
5
|
+
import { docsPage } from "./docs-page.js";
|
|
6
|
+
import { magazinePoster } from "./magazine-poster.js";
|
|
7
|
+
import { mobileApp } from "./mobile-app.js";
|
|
8
|
+
import { motionFrames } from "./motion-frames.js";
|
|
9
|
+
import { pricingPage } from "./pricing-page.js";
|
|
10
|
+
import { saasLanding } from "./saas-landing.js";
|
|
11
|
+
import { slideDeck } from "./slide-deck.js";
|
|
12
|
+
import { socialCarousel } from "./social-carousel.js";
|
|
13
|
+
import { webPrototype } from "./web-prototype.js";
|
|
14
|
+
export const DESIGN_SKILLS = [
|
|
15
|
+
webPrototype,
|
|
16
|
+
saasLanding,
|
|
17
|
+
slideDeck,
|
|
18
|
+
mobileApp,
|
|
19
|
+
dashboard,
|
|
20
|
+
socialCarousel,
|
|
21
|
+
designBrief,
|
|
22
|
+
critique,
|
|
23
|
+
pricingPage,
|
|
24
|
+
docsPage,
|
|
25
|
+
blogPost,
|
|
26
|
+
magazinePoster,
|
|
27
|
+
motionFrames,
|
|
28
|
+
];
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { DesignSkill } from "./design-skill.js";
|
|
2
|
+
import { blogPost } from "./blog-post.js";
|
|
3
|
+
import { critique } from "./critique.js";
|
|
4
|
+
import { dashboard } from "./dashboard.js";
|
|
5
|
+
import { designBrief } from "./design-brief.js";
|
|
6
|
+
import { docsPage } from "./docs-page.js";
|
|
7
|
+
import { magazinePoster } from "./magazine-poster.js";
|
|
8
|
+
import { mobileApp } from "./mobile-app.js";
|
|
9
|
+
import { motionFrames } from "./motion-frames.js";
|
|
10
|
+
import { pricingPage } from "./pricing-page.js";
|
|
11
|
+
import { saasLanding } from "./saas-landing.js";
|
|
12
|
+
import { slideDeck } from "./slide-deck.js";
|
|
13
|
+
import { socialCarousel } from "./social-carousel.js";
|
|
14
|
+
import { webPrototype } from "./web-prototype.js";
|
|
15
|
+
|
|
16
|
+
export const DESIGN_SKILLS: DesignSkill[] = [
|
|
17
|
+
webPrototype,
|
|
18
|
+
saasLanding,
|
|
19
|
+
slideDeck,
|
|
20
|
+
mobileApp,
|
|
21
|
+
dashboard,
|
|
22
|
+
socialCarousel,
|
|
23
|
+
designBrief,
|
|
24
|
+
critique,
|
|
25
|
+
pricingPage,
|
|
26
|
+
docsPage,
|
|
27
|
+
blogPost,
|
|
28
|
+
magazinePoster,
|
|
29
|
+
motionFrames,
|
|
30
|
+
];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"magazine-poster.d.ts","sourceRoot":"","sources":["../../../../src/designer/data/skills/magazine-poster.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,eAAO,MAAM,cAAc,EAAE,WAsE1B,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export const magazinePoster = {
|
|
2
|
+
name: "magazine-poster",
|
|
3
|
+
scenario: "creative",
|
|
4
|
+
description: "Editorial magazine poster or spread — bold typography, large-scale display font, dramatic image/color blocking. Magazine-cover aesthetic with strong visual hierarchy.",
|
|
5
|
+
outputKind: "html",
|
|
6
|
+
workflow: `# Magazine Poster Skill
|
|
7
|
+
|
|
8
|
+
Produce an editorial magazine poster or spread. Bold typography, large-scale display font, dramatic layout — the kind of image that could be a magazine cover or poster.
|
|
9
|
+
|
|
10
|
+
## Phase 1 — Determine Format
|
|
11
|
+
|
|
12
|
+
- **Poster** (A3-ish: 960×1358px or similar portrait ratio) — single bold composition
|
|
13
|
+
- **Magazine spread** (landscape: 1440×960px or similar) — two-page feel with gutter
|
|
14
|
+
- **Social cover** (square: 1080×1080px) — optimized for social sharing
|
|
15
|
+
|
|
16
|
+
## Phase 2 — Composition Modes
|
|
17
|
+
|
|
18
|
+
### Mode A: Typography-first
|
|
19
|
+
Big display text dominates. Color block background, minimal elements. Font scale carries the energy.
|
|
20
|
+
\`\`\`css
|
|
21
|
+
.poster { width: 960px; height: 1358px; background: var(--bg); display: flex; flex-direction: column; justify-content: center; padding: 80px; position: relative; overflow: hidden; }
|
|
22
|
+
.poster-eyebrow { font-size: 14px; text-transform: uppercase; letter-spacing: 0.15em; color: var(--muted); margin-bottom: 24px; }
|
|
23
|
+
.poster-headline { font-family: var(--font-display, var(--font-body)); font-size: 96px; font-weight: 800; line-height: 1.05; letter-spacing: -0.03em; }
|
|
24
|
+
.poster-subhead { font-size: 24px; color: var(--muted); margin-top: 32px; max-width: 600px; line-height: 1.5; }
|
|
25
|
+
.poster-issue { position: absolute; bottom: 60px; left: 80px; font-size: 14px; color: var(--muted); }
|
|
26
|
+
\`\`\`
|
|
27
|
+
|
|
28
|
+
### Mode B: Image-first
|
|
29
|
+
Large image dominates 70% of the canvas, typography overlays or sits below.
|
|
30
|
+
\`\`\`css
|
|
31
|
+
.poster-image-first { width: 960px; height: 1358px; display: grid; grid-template-rows: 1fr auto; background: var(--bg); }
|
|
32
|
+
.poster-image { width: 100%; height: 100%; object-fit: cover; background: linear-gradient(135deg, var(--accent), var(--surface)); }
|
|
33
|
+
.poster-text-block { padding: 48px 64px; }
|
|
34
|
+
\`\`\`
|
|
35
|
+
|
|
36
|
+
### Mode C: Split-screen
|
|
37
|
+
Two-panel composition — color block left, image right (or vice versa).
|
|
38
|
+
\`\`\`css
|
|
39
|
+
.poster-split { width: 1440px; height: 960px; display: grid; grid-template-columns: 1fr 1fr; }
|
|
40
|
+
.poster-split-panel { display: flex; flex-direction: column; justify-content: center; padding: 80px; }
|
|
41
|
+
.poster-split-panel.left { background: var(--accent); color: var(--accent-on, white); }
|
|
42
|
+
.poster-split-panel.right { background: var(--bg); }
|
|
43
|
+
\`\`\`
|
|
44
|
+
|
|
45
|
+
## Phase 3 — Typography Scale
|
|
46
|
+
|
|
47
|
+
\`\`\`css
|
|
48
|
+
/* Magazine typography is dramatic — go big */
|
|
49
|
+
.display-xxl { font-size: 120px; font-weight: 800; line-height: 0.95; letter-spacing: -0.04em; }
|
|
50
|
+
.display-xl { font-size: 80px; font-weight: 800; line-height: 1.0; letter-spacing: -0.03em; }
|
|
51
|
+
.display-lg { font-size: 56px; font-weight: 700; line-height: 1.1; }
|
|
52
|
+
.poster-body { font-size: 18px; line-height: 1.6; }
|
|
53
|
+
.poster-meta { font-size: 12px; text-transform: uppercase; letter-spacing: 0.12em; }
|
|
54
|
+
\`\`\`
|
|
55
|
+
|
|
56
|
+
## Phase 4 — Design Elements
|
|
57
|
+
|
|
58
|
+
- **Accent shapes**: Use ::before/::after pseudo-elements for geometric accents (circles, lines, color blocks)
|
|
59
|
+
- **Photo treatment**: Use mix-blend-mode on images over color backgrounds
|
|
60
|
+
- **Grid lines**: Thin horizontal/vertical rules as structural elements
|
|
61
|
+
- **Page numbers**: ALWAYS include an issue/volume/page-number block
|
|
62
|
+
- **Date line**: MONTH YYYY format in the masthead area
|
|
63
|
+
|
|
64
|
+
## Phase 5 — Anti-Kitsch Rules
|
|
65
|
+
- No emoji in editorial design
|
|
66
|
+
- Use the design system's display font at scale — not a safe web font
|
|
67
|
+
- Headline should create tension: unexpected word break, dramatic line split, or bold claim
|
|
68
|
+
- One focal point per poster — don't make everything compete
|
|
69
|
+
- white-space is intentional, not leftover`,
|
|
70
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { DesignSkill } from "./design-skill.js";
|
|
2
|
+
|
|
3
|
+
export const magazinePoster: DesignSkill = {
|
|
4
|
+
name: "magazine-poster",
|
|
5
|
+
scenario: "creative",
|
|
6
|
+
description:
|
|
7
|
+
"Editorial magazine poster or spread — bold typography, large-scale display font, dramatic image/color blocking. Magazine-cover aesthetic with strong visual hierarchy.",
|
|
8
|
+
outputKind: "html",
|
|
9
|
+
workflow: `# Magazine Poster Skill
|
|
10
|
+
|
|
11
|
+
Produce an editorial magazine poster or spread. Bold typography, large-scale display font, dramatic layout — the kind of image that could be a magazine cover or poster.
|
|
12
|
+
|
|
13
|
+
## Phase 1 — Determine Format
|
|
14
|
+
|
|
15
|
+
- **Poster** (A3-ish: 960×1358px or similar portrait ratio) — single bold composition
|
|
16
|
+
- **Magazine spread** (landscape: 1440×960px or similar) — two-page feel with gutter
|
|
17
|
+
- **Social cover** (square: 1080×1080px) — optimized for social sharing
|
|
18
|
+
|
|
19
|
+
## Phase 2 — Composition Modes
|
|
20
|
+
|
|
21
|
+
### Mode A: Typography-first
|
|
22
|
+
Big display text dominates. Color block background, minimal elements. Font scale carries the energy.
|
|
23
|
+
\`\`\`css
|
|
24
|
+
.poster { width: 960px; height: 1358px; background: var(--bg); display: flex; flex-direction: column; justify-content: center; padding: 80px; position: relative; overflow: hidden; }
|
|
25
|
+
.poster-eyebrow { font-size: 14px; text-transform: uppercase; letter-spacing: 0.15em; color: var(--muted); margin-bottom: 24px; }
|
|
26
|
+
.poster-headline { font-family: var(--font-display, var(--font-body)); font-size: 96px; font-weight: 800; line-height: 1.05; letter-spacing: -0.03em; }
|
|
27
|
+
.poster-subhead { font-size: 24px; color: var(--muted); margin-top: 32px; max-width: 600px; line-height: 1.5; }
|
|
28
|
+
.poster-issue { position: absolute; bottom: 60px; left: 80px; font-size: 14px; color: var(--muted); }
|
|
29
|
+
\`\`\`
|
|
30
|
+
|
|
31
|
+
### Mode B: Image-first
|
|
32
|
+
Large image dominates 70% of the canvas, typography overlays or sits below.
|
|
33
|
+
\`\`\`css
|
|
34
|
+
.poster-image-first { width: 960px; height: 1358px; display: grid; grid-template-rows: 1fr auto; background: var(--bg); }
|
|
35
|
+
.poster-image { width: 100%; height: 100%; object-fit: cover; background: linear-gradient(135deg, var(--accent), var(--surface)); }
|
|
36
|
+
.poster-text-block { padding: 48px 64px; }
|
|
37
|
+
\`\`\`
|
|
38
|
+
|
|
39
|
+
### Mode C: Split-screen
|
|
40
|
+
Two-panel composition — color block left, image right (or vice versa).
|
|
41
|
+
\`\`\`css
|
|
42
|
+
.poster-split { width: 1440px; height: 960px; display: grid; grid-template-columns: 1fr 1fr; }
|
|
43
|
+
.poster-split-panel { display: flex; flex-direction: column; justify-content: center; padding: 80px; }
|
|
44
|
+
.poster-split-panel.left { background: var(--accent); color: var(--accent-on, white); }
|
|
45
|
+
.poster-split-panel.right { background: var(--bg); }
|
|
46
|
+
\`\`\`
|
|
47
|
+
|
|
48
|
+
## Phase 3 — Typography Scale
|
|
49
|
+
|
|
50
|
+
\`\`\`css
|
|
51
|
+
/* Magazine typography is dramatic — go big */
|
|
52
|
+
.display-xxl { font-size: 120px; font-weight: 800; line-height: 0.95; letter-spacing: -0.04em; }
|
|
53
|
+
.display-xl { font-size: 80px; font-weight: 800; line-height: 1.0; letter-spacing: -0.03em; }
|
|
54
|
+
.display-lg { font-size: 56px; font-weight: 700; line-height: 1.1; }
|
|
55
|
+
.poster-body { font-size: 18px; line-height: 1.6; }
|
|
56
|
+
.poster-meta { font-size: 12px; text-transform: uppercase; letter-spacing: 0.12em; }
|
|
57
|
+
\`\`\`
|
|
58
|
+
|
|
59
|
+
## Phase 4 — Design Elements
|
|
60
|
+
|
|
61
|
+
- **Accent shapes**: Use ::before/::after pseudo-elements for geometric accents (circles, lines, color blocks)
|
|
62
|
+
- **Photo treatment**: Use mix-blend-mode on images over color backgrounds
|
|
63
|
+
- **Grid lines**: Thin horizontal/vertical rules as structural elements
|
|
64
|
+
- **Page numbers**: ALWAYS include an issue/volume/page-number block
|
|
65
|
+
- **Date line**: MONTH YYYY format in the masthead area
|
|
66
|
+
|
|
67
|
+
## Phase 5 — Anti-Kitsch Rules
|
|
68
|
+
- No emoji in editorial design
|
|
69
|
+
- Use the design system's display font at scale — not a safe web font
|
|
70
|
+
- Headline should create tension: unexpected word break, dramatic line split, or bold claim
|
|
71
|
+
- One focal point per poster — don't make everything compete
|
|
72
|
+
- white-space is intentional, not leftover`,
|
|
73
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mobile-app.d.ts","sourceRoot":"","sources":["../../../../src/designer/data/skills/mobile-app.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,eAAO,MAAM,SAAS,EAAE,WAqOrB,CAAC"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
export const mobileApp = {
|
|
2
|
+
name: "mobile-app",
|
|
3
|
+
scenario: "design",
|
|
4
|
+
description: "Mobile app prototype. Phone-frame-contained HTML with iOS/Android patterns, touch targets, and native-feel interactions.",
|
|
5
|
+
outputKind: "html",
|
|
6
|
+
workflow: `# Mobile App Prototype Skill
|
|
7
|
+
|
|
8
|
+
Produce a mobile app prototype as a single HTML file. Phone-frame contained, touch-friendly, native-feel interactions.
|
|
9
|
+
|
|
10
|
+
## Phase 0 — Pre-flight
|
|
11
|
+
|
|
12
|
+
1. Read the design system for color tokens.
|
|
13
|
+
2. Determine: app name, screens needed (2-5), platform style (iOS or Material).
|
|
14
|
+
3. Vocalize: "I'll build [app name] with [N] screens: [screen names]. [iOS/Material] patterns."
|
|
15
|
+
|
|
16
|
+
## Phase 1 — Shell with Phone Frame
|
|
17
|
+
|
|
18
|
+
Create \`app.html\` with a phone frame wrapper:
|
|
19
|
+
|
|
20
|
+
\`\`\`html
|
|
21
|
+
<!doctype html>
|
|
22
|
+
<html lang="en">
|
|
23
|
+
<head>
|
|
24
|
+
<meta charset="utf-8">
|
|
25
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
26
|
+
<title>App Name</title>
|
|
27
|
+
<style>
|
|
28
|
+
*, *::before, *::after { box-sizing: border-box; margin: 0; }
|
|
29
|
+
|
|
30
|
+
:root {
|
|
31
|
+
--phone-w: 390px;
|
|
32
|
+
--phone-h: 844px;
|
|
33
|
+
--phone-radius: 44px;
|
|
34
|
+
--safe-top: 54px;
|
|
35
|
+
--safe-bottom: 34px;
|
|
36
|
+
/* Design system tokens */
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
body {
|
|
40
|
+
display: flex;
|
|
41
|
+
justify-content: center;
|
|
42
|
+
align-items: center;
|
|
43
|
+
min-height: 100vh;
|
|
44
|
+
background: #f0f0f0;
|
|
45
|
+
font-family: -apple-system, "SF Pro Text", "Inter", sans-serif;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.phone-frame {
|
|
49
|
+
width: var(--phone-w);
|
|
50
|
+
height: var(--phone-h);
|
|
51
|
+
background: var(--color-bg-primary);
|
|
52
|
+
border-radius: var(--phone-radius);
|
|
53
|
+
overflow: hidden;
|
|
54
|
+
position: relative;
|
|
55
|
+
box-shadow: 0 0 0 8px #1a1a1a, 0 0 0 10px #333, 0 20px 60px rgba(0,0,0,0.3);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.status-bar {
|
|
59
|
+
height: var(--safe-top);
|
|
60
|
+
display: flex;
|
|
61
|
+
justify-content: space-between;
|
|
62
|
+
align-items: center;
|
|
63
|
+
padding: 0 24px;
|
|
64
|
+
font-size: 14px;
|
|
65
|
+
font-weight: 600;
|
|
66
|
+
background: var(--color-bg-primary);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.screen {
|
|
70
|
+
position: absolute;
|
|
71
|
+
top: var(--safe-top);
|
|
72
|
+
left: 0;
|
|
73
|
+
right: 0;
|
|
74
|
+
bottom: var(--safe-bottom);
|
|
75
|
+
display: none;
|
|
76
|
+
flex-direction: column;
|
|
77
|
+
overflow-y: auto;
|
|
78
|
+
-webkit-overflow-scrolling: touch;
|
|
79
|
+
}
|
|
80
|
+
.screen.active { display: flex; }
|
|
81
|
+
|
|
82
|
+
.bottom-nav {
|
|
83
|
+
position: absolute;
|
|
84
|
+
bottom: 0;
|
|
85
|
+
left: 0;
|
|
86
|
+
right: 0;
|
|
87
|
+
height: var(--safe-bottom);
|
|
88
|
+
display: flex;
|
|
89
|
+
border-top: 1px solid var(--color-border);
|
|
90
|
+
background: var(--color-bg-surface, var(--color-bg-primary));
|
|
91
|
+
}
|
|
92
|
+
.nav-item {
|
|
93
|
+
flex: 1;
|
|
94
|
+
display: flex;
|
|
95
|
+
flex-direction: column;
|
|
96
|
+
align-items: center;
|
|
97
|
+
justify-content: center;
|
|
98
|
+
gap: 2px;
|
|
99
|
+
font-size: 10px;
|
|
100
|
+
color: var(--color-text-secondary);
|
|
101
|
+
cursor: pointer;
|
|
102
|
+
user-select: none;
|
|
103
|
+
}
|
|
104
|
+
.nav-item.active { color: var(--color-accent); }
|
|
105
|
+
.nav-icon { font-size: 22px; line-height: 1; }
|
|
106
|
+
</style>
|
|
107
|
+
</head>
|
|
108
|
+
<body>
|
|
109
|
+
<div class="phone-frame">
|
|
110
|
+
<div class="status-bar">
|
|
111
|
+
<span>9:41</span>
|
|
112
|
+
<span>●●●○ WiFi ▮▮▮</span>
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
<div class="screen active" id="screen-home"><!-- Home content --></div>
|
|
116
|
+
<div class="screen" id="screen-detail"><!-- Detail content --></div>
|
|
117
|
+
<div class="screen" id="screen-settings"><!-- Settings content --></div>
|
|
118
|
+
|
|
119
|
+
<div class="bottom-nav">
|
|
120
|
+
<div class="nav-item active" onclick="showScreen('home')">
|
|
121
|
+
<span class="nav-icon">🏠</span>Home
|
|
122
|
+
</div>
|
|
123
|
+
<div class="nav-item" onclick="showScreen('detail')">
|
|
124
|
+
<span class="nav-icon">🔍</span>Search
|
|
125
|
+
</div>
|
|
126
|
+
<div class="nav-item" onclick="showScreen('settings')">
|
|
127
|
+
<span class="nav-icon">👤</span>Profile
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
|
|
132
|
+
<script>
|
|
133
|
+
function showScreen(id) {
|
|
134
|
+
document.querySelectorAll('.screen').forEach(s => s.classList.remove('active'));
|
|
135
|
+
document.getElementById('screen-' + id).classList.add('active');
|
|
136
|
+
document.querySelectorAll('.nav-item').forEach((n, i) => {
|
|
137
|
+
n.classList.toggle('active', n.textContent.trim().toLowerCase().includes(id));
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
</script>
|
|
141
|
+
</body>
|
|
142
|
+
</html>
|
|
143
|
+
\`\`\`
|
|
144
|
+
|
|
145
|
+
## Phase 2 — Component Patterns
|
|
146
|
+
|
|
147
|
+
### List Item (44px minimum tap target)
|
|
148
|
+
\`\`\`css
|
|
149
|
+
.list-item {
|
|
150
|
+
display: flex;
|
|
151
|
+
align-items: center;
|
|
152
|
+
padding: 12px 16px;
|
|
153
|
+
min-height: 44px;
|
|
154
|
+
gap: 12px;
|
|
155
|
+
border-bottom: 0.5px solid var(--color-border);
|
|
156
|
+
cursor: pointer;
|
|
157
|
+
}
|
|
158
|
+
.list-item:active { background: var(--color-bg-hover, rgba(0,0,0,0.04)); }
|
|
159
|
+
.list-item-icon { width: 40px; height: 40px; border-radius: 10px; background: var(--color-accent); display: flex; align-items: center; justify-content: center; color: white; font-size: 18px; }
|
|
160
|
+
.list-item-content { flex: 1; }
|
|
161
|
+
.list-item-title { font-size: 16px; font-weight: 500; }
|
|
162
|
+
.list-item-subtitle { font-size: 14px; color: var(--color-text-secondary); margin-top: 2px; }
|
|
163
|
+
.list-item-trailing { color: var(--color-text-secondary); font-size: 14px; }
|
|
164
|
+
\`\`\`
|
|
165
|
+
|
|
166
|
+
### Card
|
|
167
|
+
\`\`\`css
|
|
168
|
+
.card {
|
|
169
|
+
background: var(--color-bg-surface, #fff);
|
|
170
|
+
border-radius: 16px;
|
|
171
|
+
padding: 16px;
|
|
172
|
+
margin: 8px 16px;
|
|
173
|
+
box-shadow: 0 1px 3px rgba(0,0,0,0.08);
|
|
174
|
+
}
|
|
175
|
+
.card-image { width: 100%; height: 180px; border-radius: 12px; object-fit: cover; background: var(--color-bg-secondary); }
|
|
176
|
+
.card-title { font-size: 17px; font-weight: 600; margin: 12px 0 4px; }
|
|
177
|
+
.card-subtitle { font-size: 14px; color: var(--color-text-secondary); }
|
|
178
|
+
\`\`\`
|
|
179
|
+
|
|
180
|
+
### Input Field
|
|
181
|
+
\`\`\`css
|
|
182
|
+
.input-group { padding: 8px 16px; }
|
|
183
|
+
.input-label { font-size: 13px; color: var(--color-text-secondary); margin-bottom: 4px; display: block; }
|
|
184
|
+
.input-field {
|
|
185
|
+
width: 100%;
|
|
186
|
+
height: 44px;
|
|
187
|
+
padding: 0 12px;
|
|
188
|
+
border: 1px solid var(--color-border);
|
|
189
|
+
border-radius: 10px;
|
|
190
|
+
font-size: 16px;
|
|
191
|
+
background: var(--color-bg-secondary, #f5f5f5);
|
|
192
|
+
outline: none;
|
|
193
|
+
}
|
|
194
|
+
.input-field:focus { border-color: var(--color-accent); }
|
|
195
|
+
\`\`\`
|
|
196
|
+
|
|
197
|
+
### Button
|
|
198
|
+
\`\`\`css
|
|
199
|
+
.btn {
|
|
200
|
+
display: flex;
|
|
201
|
+
align-items: center;
|
|
202
|
+
justify-content: center;
|
|
203
|
+
height: 50px;
|
|
204
|
+
padding: 0 24px;
|
|
205
|
+
border-radius: 14px;
|
|
206
|
+
font-size: 17px;
|
|
207
|
+
font-weight: 600;
|
|
208
|
+
border: none;
|
|
209
|
+
cursor: pointer;
|
|
210
|
+
margin: 8px 16px;
|
|
211
|
+
user-select: none;
|
|
212
|
+
}
|
|
213
|
+
.btn-primary { background: var(--color-accent); color: #fff; }
|
|
214
|
+
.btn-secondary { background: var(--color-bg-secondary, #f0f0f0); color: var(--color-text-primary); }
|
|
215
|
+
.btn:active { opacity: 0.8; transform: scale(0.98); }
|
|
216
|
+
\`\`\`
|
|
217
|
+
|
|
218
|
+
## Phase 3 — Mobile-Specific Rules
|
|
219
|
+
|
|
220
|
+
- Minimum touch target: 44×44px
|
|
221
|
+
- Font sizes: 13px (captions), 15px (body), 17px (headlines), 22px (titles), 28px (hero)
|
|
222
|
+
- Padding: 16px horizontal standard, 8-16px card margins
|
|
223
|
+
- Never use hover effects — use :active for tap feedback
|
|
224
|
+
- Scrollable content uses \`overflow-y: auto; -webkit-overflow-scrolling: touch;\`
|
|
225
|
+
- Status bar: 54px height standard, dark or light based on design system
|
|
226
|
+
- Bottom safe area: 34px for home indicator
|
|
227
|
+
- Images: use \`object-fit: cover\` with fixed aspect ratios, gradient placeholders
|
|
228
|
+
- No hamburger menus — use tab bar navigation (3-5 items)`,
|
|
229
|
+
};
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import type { DesignSkill } from "./design-skill.js";
|
|
2
|
+
|
|
3
|
+
export const mobileApp: DesignSkill = {
|
|
4
|
+
name: "mobile-app",
|
|
5
|
+
scenario: "design",
|
|
6
|
+
description:
|
|
7
|
+
"Mobile app prototype. Phone-frame-contained HTML with iOS/Android patterns, touch targets, and native-feel interactions.",
|
|
8
|
+
outputKind: "html",
|
|
9
|
+
workflow: `# Mobile App Prototype Skill
|
|
10
|
+
|
|
11
|
+
Produce a mobile app prototype as a single HTML file. Phone-frame contained, touch-friendly, native-feel interactions.
|
|
12
|
+
|
|
13
|
+
## Phase 0 — Pre-flight
|
|
14
|
+
|
|
15
|
+
1. Read the design system for color tokens.
|
|
16
|
+
2. Determine: app name, screens needed (2-5), platform style (iOS or Material).
|
|
17
|
+
3. Vocalize: "I'll build [app name] with [N] screens: [screen names]. [iOS/Material] patterns."
|
|
18
|
+
|
|
19
|
+
## Phase 1 — Shell with Phone Frame
|
|
20
|
+
|
|
21
|
+
Create \`app.html\` with a phone frame wrapper:
|
|
22
|
+
|
|
23
|
+
\`\`\`html
|
|
24
|
+
<!doctype html>
|
|
25
|
+
<html lang="en">
|
|
26
|
+
<head>
|
|
27
|
+
<meta charset="utf-8">
|
|
28
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
29
|
+
<title>App Name</title>
|
|
30
|
+
<style>
|
|
31
|
+
*, *::before, *::after { box-sizing: border-box; margin: 0; }
|
|
32
|
+
|
|
33
|
+
:root {
|
|
34
|
+
--phone-w: 390px;
|
|
35
|
+
--phone-h: 844px;
|
|
36
|
+
--phone-radius: 44px;
|
|
37
|
+
--safe-top: 54px;
|
|
38
|
+
--safe-bottom: 34px;
|
|
39
|
+
/* Design system tokens */
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
body {
|
|
43
|
+
display: flex;
|
|
44
|
+
justify-content: center;
|
|
45
|
+
align-items: center;
|
|
46
|
+
min-height: 100vh;
|
|
47
|
+
background: #f0f0f0;
|
|
48
|
+
font-family: -apple-system, "SF Pro Text", "Inter", sans-serif;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.phone-frame {
|
|
52
|
+
width: var(--phone-w);
|
|
53
|
+
height: var(--phone-h);
|
|
54
|
+
background: var(--color-bg-primary);
|
|
55
|
+
border-radius: var(--phone-radius);
|
|
56
|
+
overflow: hidden;
|
|
57
|
+
position: relative;
|
|
58
|
+
box-shadow: 0 0 0 8px #1a1a1a, 0 0 0 10px #333, 0 20px 60px rgba(0,0,0,0.3);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.status-bar {
|
|
62
|
+
height: var(--safe-top);
|
|
63
|
+
display: flex;
|
|
64
|
+
justify-content: space-between;
|
|
65
|
+
align-items: center;
|
|
66
|
+
padding: 0 24px;
|
|
67
|
+
font-size: 14px;
|
|
68
|
+
font-weight: 600;
|
|
69
|
+
background: var(--color-bg-primary);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.screen {
|
|
73
|
+
position: absolute;
|
|
74
|
+
top: var(--safe-top);
|
|
75
|
+
left: 0;
|
|
76
|
+
right: 0;
|
|
77
|
+
bottom: var(--safe-bottom);
|
|
78
|
+
display: none;
|
|
79
|
+
flex-direction: column;
|
|
80
|
+
overflow-y: auto;
|
|
81
|
+
-webkit-overflow-scrolling: touch;
|
|
82
|
+
}
|
|
83
|
+
.screen.active { display: flex; }
|
|
84
|
+
|
|
85
|
+
.bottom-nav {
|
|
86
|
+
position: absolute;
|
|
87
|
+
bottom: 0;
|
|
88
|
+
left: 0;
|
|
89
|
+
right: 0;
|
|
90
|
+
height: var(--safe-bottom);
|
|
91
|
+
display: flex;
|
|
92
|
+
border-top: 1px solid var(--color-border);
|
|
93
|
+
background: var(--color-bg-surface, var(--color-bg-primary));
|
|
94
|
+
}
|
|
95
|
+
.nav-item {
|
|
96
|
+
flex: 1;
|
|
97
|
+
display: flex;
|
|
98
|
+
flex-direction: column;
|
|
99
|
+
align-items: center;
|
|
100
|
+
justify-content: center;
|
|
101
|
+
gap: 2px;
|
|
102
|
+
font-size: 10px;
|
|
103
|
+
color: var(--color-text-secondary);
|
|
104
|
+
cursor: pointer;
|
|
105
|
+
user-select: none;
|
|
106
|
+
}
|
|
107
|
+
.nav-item.active { color: var(--color-accent); }
|
|
108
|
+
.nav-icon { font-size: 22px; line-height: 1; }
|
|
109
|
+
</style>
|
|
110
|
+
</head>
|
|
111
|
+
<body>
|
|
112
|
+
<div class="phone-frame">
|
|
113
|
+
<div class="status-bar">
|
|
114
|
+
<span>9:41</span>
|
|
115
|
+
<span>●●●○ WiFi ▮▮▮</span>
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
<div class="screen active" id="screen-home"><!-- Home content --></div>
|
|
119
|
+
<div class="screen" id="screen-detail"><!-- Detail content --></div>
|
|
120
|
+
<div class="screen" id="screen-settings"><!-- Settings content --></div>
|
|
121
|
+
|
|
122
|
+
<div class="bottom-nav">
|
|
123
|
+
<div class="nav-item active" onclick="showScreen('home')">
|
|
124
|
+
<span class="nav-icon">🏠</span>Home
|
|
125
|
+
</div>
|
|
126
|
+
<div class="nav-item" onclick="showScreen('detail')">
|
|
127
|
+
<span class="nav-icon">🔍</span>Search
|
|
128
|
+
</div>
|
|
129
|
+
<div class="nav-item" onclick="showScreen('settings')">
|
|
130
|
+
<span class="nav-icon">👤</span>Profile
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
|
|
135
|
+
<script>
|
|
136
|
+
function showScreen(id) {
|
|
137
|
+
document.querySelectorAll('.screen').forEach(s => s.classList.remove('active'));
|
|
138
|
+
document.getElementById('screen-' + id).classList.add('active');
|
|
139
|
+
document.querySelectorAll('.nav-item').forEach((n, i) => {
|
|
140
|
+
n.classList.toggle('active', n.textContent.trim().toLowerCase().includes(id));
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
</script>
|
|
144
|
+
</body>
|
|
145
|
+
</html>
|
|
146
|
+
\`\`\`
|
|
147
|
+
|
|
148
|
+
## Phase 2 — Component Patterns
|
|
149
|
+
|
|
150
|
+
### List Item (44px minimum tap target)
|
|
151
|
+
\`\`\`css
|
|
152
|
+
.list-item {
|
|
153
|
+
display: flex;
|
|
154
|
+
align-items: center;
|
|
155
|
+
padding: 12px 16px;
|
|
156
|
+
min-height: 44px;
|
|
157
|
+
gap: 12px;
|
|
158
|
+
border-bottom: 0.5px solid var(--color-border);
|
|
159
|
+
cursor: pointer;
|
|
160
|
+
}
|
|
161
|
+
.list-item:active { background: var(--color-bg-hover, rgba(0,0,0,0.04)); }
|
|
162
|
+
.list-item-icon { width: 40px; height: 40px; border-radius: 10px; background: var(--color-accent); display: flex; align-items: center; justify-content: center; color: white; font-size: 18px; }
|
|
163
|
+
.list-item-content { flex: 1; }
|
|
164
|
+
.list-item-title { font-size: 16px; font-weight: 500; }
|
|
165
|
+
.list-item-subtitle { font-size: 14px; color: var(--color-text-secondary); margin-top: 2px; }
|
|
166
|
+
.list-item-trailing { color: var(--color-text-secondary); font-size: 14px; }
|
|
167
|
+
\`\`\`
|
|
168
|
+
|
|
169
|
+
### Card
|
|
170
|
+
\`\`\`css
|
|
171
|
+
.card {
|
|
172
|
+
background: var(--color-bg-surface, #fff);
|
|
173
|
+
border-radius: 16px;
|
|
174
|
+
padding: 16px;
|
|
175
|
+
margin: 8px 16px;
|
|
176
|
+
box-shadow: 0 1px 3px rgba(0,0,0,0.08);
|
|
177
|
+
}
|
|
178
|
+
.card-image { width: 100%; height: 180px; border-radius: 12px; object-fit: cover; background: var(--color-bg-secondary); }
|
|
179
|
+
.card-title { font-size: 17px; font-weight: 600; margin: 12px 0 4px; }
|
|
180
|
+
.card-subtitle { font-size: 14px; color: var(--color-text-secondary); }
|
|
181
|
+
\`\`\`
|
|
182
|
+
|
|
183
|
+
### Input Field
|
|
184
|
+
\`\`\`css
|
|
185
|
+
.input-group { padding: 8px 16px; }
|
|
186
|
+
.input-label { font-size: 13px; color: var(--color-text-secondary); margin-bottom: 4px; display: block; }
|
|
187
|
+
.input-field {
|
|
188
|
+
width: 100%;
|
|
189
|
+
height: 44px;
|
|
190
|
+
padding: 0 12px;
|
|
191
|
+
border: 1px solid var(--color-border);
|
|
192
|
+
border-radius: 10px;
|
|
193
|
+
font-size: 16px;
|
|
194
|
+
background: var(--color-bg-secondary, #f5f5f5);
|
|
195
|
+
outline: none;
|
|
196
|
+
}
|
|
197
|
+
.input-field:focus { border-color: var(--color-accent); }
|
|
198
|
+
\`\`\`
|
|
199
|
+
|
|
200
|
+
### Button
|
|
201
|
+
\`\`\`css
|
|
202
|
+
.btn {
|
|
203
|
+
display: flex;
|
|
204
|
+
align-items: center;
|
|
205
|
+
justify-content: center;
|
|
206
|
+
height: 50px;
|
|
207
|
+
padding: 0 24px;
|
|
208
|
+
border-radius: 14px;
|
|
209
|
+
font-size: 17px;
|
|
210
|
+
font-weight: 600;
|
|
211
|
+
border: none;
|
|
212
|
+
cursor: pointer;
|
|
213
|
+
margin: 8px 16px;
|
|
214
|
+
user-select: none;
|
|
215
|
+
}
|
|
216
|
+
.btn-primary { background: var(--color-accent); color: #fff; }
|
|
217
|
+
.btn-secondary { background: var(--color-bg-secondary, #f0f0f0); color: var(--color-text-primary); }
|
|
218
|
+
.btn:active { opacity: 0.8; transform: scale(0.98); }
|
|
219
|
+
\`\`\`
|
|
220
|
+
|
|
221
|
+
## Phase 3 — Mobile-Specific Rules
|
|
222
|
+
|
|
223
|
+
- Minimum touch target: 44×44px
|
|
224
|
+
- Font sizes: 13px (captions), 15px (body), 17px (headlines), 22px (titles), 28px (hero)
|
|
225
|
+
- Padding: 16px horizontal standard, 8-16px card margins
|
|
226
|
+
- Never use hover effects — use :active for tap feedback
|
|
227
|
+
- Scrollable content uses \`overflow-y: auto; -webkit-overflow-scrolling: touch;\`
|
|
228
|
+
- Status bar: 54px height standard, dark or light based on design system
|
|
229
|
+
- Bottom safe area: 34px for home indicator
|
|
230
|
+
- Images: use \`object-fit: cover\` with fixed aspect ratios, gradient placeholders
|
|
231
|
+
- No hamburger menus — use tab bar navigation (3-5 items)`,
|
|
232
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"motion-frames.d.ts","sourceRoot":"","sources":["../../../../src/designer/data/skills/motion-frames.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,eAAO,MAAM,YAAY,EAAE,WAyHxB,CAAC"}
|