@pen.dev/cli 0.3.2 → 0.3.4

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 (82) hide show
  1. package/README.md +18 -12
  2. package/dist/anthropic-messages-COZrsSdY.mjs +40 -0
  3. package/dist/azure-openai-responses-Dmf1EaVz.mjs +2 -0
  4. package/dist/browserAll-BZYrVO32.mjs +2 -0
  5. package/dist/{dist-BEo0Z8Vf.mjs → dist-D9ROAuw3.mjs} +348 -319
  6. package/dist/{dist-BY6vOcMF.mjs → dist-DGrygXHh.mjs} +2 -2
  7. package/dist/{error-body-D2Mrqb4g.mjs → error-body-BBlqjbe7.mjs} +1 -1
  8. package/dist/google-generative-ai-BMEzR_34.mjs +2 -0
  9. package/dist/google-shared-DXgnvvDU.mjs +318 -0
  10. package/dist/google-vertex-In7qdx36.mjs +2 -0
  11. package/dist/index.mjs +2 -2
  12. package/dist/mistral-conversations-DdYjdrRy.mjs +5 -0
  13. package/dist/models-BBd5zwn6.mjs +2 -0
  14. package/dist/{multipart-parser-DX5ZDxQv.mjs → multipart-parser-BdmM0fdd.mjs} +1 -1
  15. package/dist/node_modules/@highagency/pencil-wasm/package.json +1 -1
  16. package/dist/node_modules/@highagency/pencil-wasm/pencil.d.ts +3 -0
  17. package/dist/node_modules/@highagency/pencil-wasm/pencil.js +1 -1
  18. package/dist/node_modules/@highagency/pencil-wasm/pencil.wasm +0 -0
  19. package/dist/openai-CbFQ5q5I.mjs +18 -0
  20. package/dist/openai-codex-responses-CD-2hfWB.mjs +8 -0
  21. package/dist/openai-completions-DamtYjy7.mjs +6 -0
  22. package/dist/openai-responses-DgeWdtm-.mjs +2 -0
  23. package/dist/openai-responses-shared-DKseiGAg.mjs +11 -0
  24. package/dist/{openrouter-images-BbBWg9zF.mjs → openrouter-images-gArAwqnL.mjs} +1 -1
  25. package/dist/out/mcp-server-darwin-arm64 +0 -0
  26. package/dist/out/mcp-server-darwin-x64 +0 -0
  27. package/dist/out/mcp-server-linux-arm64 +0 -0
  28. package/dist/out/mcp-server-linux-x64 +0 -0
  29. package/dist/out/mcp-server-windows-arm64.exe +0 -0
  30. package/dist/out/mcp-server-windows-x64.exe +0 -0
  31. package/dist/out/skills/pen-dev/SKILL.md +204 -0
  32. package/dist/out/skills/pen-dev/execute.md +364 -0
  33. package/dist/out/skills/pen-dev/guide/code.md +198 -0
  34. package/dist/out/skills/pen-dev/guide/components.md +45 -0
  35. package/dist/out/skills/pen-dev/guide/design-system.md +556 -0
  36. package/dist/out/skills/pen-dev/guide/landing-page.md +31 -0
  37. package/dist/out/skills/pen-dev/guide/mobile-app.md +31 -0
  38. package/dist/out/skills/pen-dev/guide/slides.md +222 -0
  39. package/dist/out/skills/pen-dev/guide/table.md +37 -0
  40. package/dist/out/skills/pen-dev/guide/tailwind.md +328 -0
  41. package/dist/out/skills/pen-dev/guide/web-app.md +245 -0
  42. package/dist/out/skills/pen-dev/pen-schema.md +202 -0
  43. package/dist/out/skills/pen-dev/scripts-and-shaders.md +94 -0
  44. package/dist/pi-user-agent-m9a4CjJo.mjs +2 -0
  45. package/dist/{src-B_lvnEtX.mjs → src-KoDMTA_Q.mjs} +1 -1
  46. package/dist/transform-messages-BHnJzowk.mjs +2 -0
  47. package/dist/webworkerAll-CB00nbs9.mjs +2 -0
  48. package/package.json +5 -4
  49. package/dist/anthropic-messages-Bf-fvkNu.mjs +0 -40
  50. package/dist/azure-openai-responses-CzgVqECr.mjs +0 -2
  51. package/dist/browserAll-8jKh1NRi.mjs +0 -2
  52. package/dist/completionchunk-BQtPqA8U.mjs +0 -28
  53. package/dist/google-generative-ai-DSOqI0LF.mjs +0 -2
  54. package/dist/google-shared-CetPT_Vt.mjs +0 -318
  55. package/dist/google-vertex-CPtOc5oU.mjs +0 -2
  56. package/dist/mistral-conversations-CUsdbDQ8.mjs +0 -10
  57. package/dist/models-CwK5xZH9.mjs +0 -2
  58. package/dist/openai-Brr_V-tF.mjs +0 -17
  59. package/dist/openai-codex-responses-Cb5pfH5S.mjs +0 -8
  60. package/dist/openai-completions-BvTlcCeP.mjs +0 -6
  61. package/dist/openai-responses-IuaLTEHh.mjs +0 -2
  62. package/dist/openai-responses-shared-D4d0NbBE.mjs +0 -11
  63. package/dist/otel-CaADOqYZ.mjs +0 -4
  64. package/dist/transform-messages-CSBQpmXO.mjs +0 -2
  65. package/dist/webworkerAll-BD-7VH16.mjs +0 -2
  66. /package/dist/{dist-BnoSGZKP.mjs → dist-D8tvRm1b.mjs} +0 -0
  67. /package/dist/{emscripten-module.browser-F76W5DM6-CNibWX-6.mjs → emscripten-module.browser-F76W5DM6-DWhj_jYh.mjs} +0 -0
  68. /package/dist/{emscripten-module.browser-XIKQQPVU-BNfdGnMe.mjs → emscripten-module.browser-XIKQQPVU-Dmh4no3c.mjs} +0 -0
  69. /package/dist/{ffi-C5tLdQO9.mjs → ffi-BroAqW9B.mjs} +0 -0
  70. /package/dist/{ffi-BuJ13coi.mjs → ffi-DwdyvnFx.mjs} +0 -0
  71. /package/dist/{from-py2TfO8m.mjs → from-Choxbpmr.mjs} +0 -0
  72. /package/dist/{github-copilot-headers-DZOfokGy.mjs → github-copilot-headers-DCj7hJoC.mjs} +0 -0
  73. /package/dist/{hash-Kp92CI9R.mjs → hash-DNYCELl4.mjs} +0 -0
  74. /package/dist/{html-GGJ1fTRB.mjs → html-DEPARSNH.mjs} +0 -0
  75. /package/dist/{init-B9LSomNH.mjs → init-DwIpBeuP.mjs} +0 -0
  76. /package/dist/{module-ES6BEMUI-DwQ9nTMF.mjs → module-ES6BEMUI-DUGQwtIb.mjs} +0 -0
  77. /package/dist/{module-asyncify-2EFITU5U-B54Mkt6K.mjs → module-asyncify-2EFITU5U-U7fqmMTF.mjs} +0 -0
  78. /package/dist/{openai-prompt-cache-t4kk9puG.mjs → openai-prompt-cache-tVHrB8oW.mjs} +0 -0
  79. /package/dist/{photon_rs-BySSRmP5.mjs → photon_rs-o0nbTM4F.mjs} +0 -0
  80. /package/dist/{provider-retry-BM3ArvaW.mjs → provider-retry-wOYAq0sa.mjs} +0 -0
  81. /package/dist/{sanitize-unicode-CHjuq5rK.mjs → sanitize-unicode-Byz9nlLd.mjs} +0 -0
  82. /package/dist/{standalone-DYT2Zg6I.mjs → standalone-DwaYVpTH.mjs} +0 -0
@@ -0,0 +1,222 @@
1
+ ROLE: You are a professional slide deck designer.
2
+ GOAL: Produce slides that are readable in real conditions (projector, Zoom, mobile).
3
+ PRIORITY: Clarity > Readability > Hierarchy > Simplicity.
4
+
5
+
6
+ CRITICAL — FIRST PRIORITY
7
+ INPUT: Brand guidelines will be given but are NOT slide-optimized.
8
+ RULE: Always adapt brand for slides (bigger fonts, more spacing, change more if needed). Never sacrifice readability.
9
+
10
+ CORE RULES:
11
+ - One idea per slide.
12
+ - Slides are visual aids, not documents.
13
+ - If content doesn’t fit at required sizes: split or remove. Never shrink fonts.
14
+ - Consistency > creativity. Reduce cognitive load.
15
+
16
+ CRITICAL – TYPOGRAPHY:
17
+ - Max 2 font families.
18
+ - Body >=24px (prefer 28–32).
19
+ - Titles >=40px.
20
+ - Key numbers can be larger.
21
+ - Use weight, not many sizes.
22
+ - Avoid ALL CAPS except labels.
23
+ - Line-height ~1.1–1.2.
24
+ - High contrast always.
25
+
26
+ LAYOUT & SPACING:
27
+ - Use grid. Align everything.
28
+ - Generous whitespace.
29
+ - No clutter.
30
+ - Apply CRAP: Contrast, Repetition, Alignment, Proximity.
31
+
32
+ COLOR:
33
+ - 2–3 core colors + neutrals.
34
+ - High contrast text/bg mandatory.
35
+ - Accent only for emphasis.
36
+ - Body text neutral.
37
+ - Colorblind-safe if possible.
38
+
39
+ VISUALS & DATA:
40
+ - Visuals support meaning, not decoration.
41
+ - Prefer custom visuals to stock.
42
+ - Charts > text for data.
43
+ - One insight per chart.
44
+ - Simplify charts (no junk).
45
+ - Highlight key datapoint.
46
+ - Icons consistent style/size.
47
+
48
+ FORMAT:
49
+ - 16:9, 1920x1080.
50
+ - Keep content >=100px from edges.
51
+
52
+ CONTENT DENSITY:
53
+ - One message per slide.
54
+ - Short phrases > sentences.
55
+ - No paragraphs.
56
+ - Title states takeaway.
57
+ - Details go to notes/appendix.
58
+
59
+ CONTEXT:
60
+ - Corp=structured.
61
+ - Startup=minimal, bold.
62
+ - Marketing=benefit-driven.
63
+ - Internal=slightly denser.
64
+ - Keynote=very visual.
65
+ (Rules above always apply.)
66
+
67
+ LAYOUT CONTRACTS (use IDs, follow strictly):
68
+
69
+ L01:
70
+ Intent=Cover
71
+ Grid=CenterStack
72
+ Content=Title(48-64,Bold); Subtitle(28-32); Meta(20-24)
73
+ Rules=CenterXY; PlentySpace; NoExtras
74
+
75
+ L02:
76
+ Intent=BoldCover
77
+ Grid=LeftBlock
78
+ Content=Title(56-72,Max2Lines); Subtitle(28); Meta
79
+ Rules=LeftMargin~120; Logo=BR; NoClutter
80
+
81
+ L03:
82
+ Intent=SectionBreak
83
+ Grid=Center
84
+ Content=Label(24,Muted); Title(48-56)
85
+ Rules=OnlyThese2; MaxWhitespace
86
+
87
+ L04:
88
+ Intent=KeyStatement
89
+ Grid=Center
90
+ Content=Statement(36-48,Max2Lines); OptionalAttribution(24)
91
+ Rules=Only1Message
92
+
93
+ L05:
94
+ Intent=Concept+Visual
95
+ Grid=2col(50/50)
96
+ Left=Title(36-40)+Body(24-28,Max4Lines)
97
+ Right=Image
98
+ Rules=Gap>=40; CenterY; NoOverflow
99
+
100
+ L06:
101
+ Intent=Concept+Visual
102
+ Grid=2col(50/50)
103
+ Left=Image
104
+ Right=Title(36-40)+Body(24-28,Max4Lines)
105
+ Rules=Mirror(L05)
106
+
107
+ L07:
108
+ Intent=3Pillars
109
+ Grid=3col
110
+ Each=Visual+Label(28)+Desc(20,Max2Lines)
111
+ Rules=EqualWidth; SameTopY; Gap=30-50
112
+
113
+ L08:
114
+ Intent=Compare2
115
+ Grid=2col
116
+ Each=Heading(28-32)+Points(24,2-4)
117
+ Rules=BalancedContent; Gap=40-60
118
+
119
+ L09:
120
+ Intent=SingleKPI
121
+ Grid=CenterStack
122
+ Content=Label(24,Muted); Number(120-200); Context(24-28)
123
+ Rules=NumberIsHero; NothingCompetes
124
+
125
+ L10:
126
+ Intent=TwoKPIs
127
+ Grid=2col
128
+ Each=Number(80-120)+Label(24)
129
+ Rules=EqualWeight
130
+
131
+ L11:
132
+ Intent=ThreeKPIs
133
+ Grid=3col
134
+ Each=Number(64-80)+Label(24)
135
+ Rules=SameBaseline
136
+
137
+ L12:
138
+ Intent=Quote
139
+ Grid=CenterStack
140
+ Content=Quote(28-36,Max3Lines); Attribution(20-24)
141
+ Rules=GenerousPadding
142
+
143
+ L13:
144
+ Intent=Process
145
+ Grid=Row(3-5Steps)
146
+ Each=Icon/Number+Label(28)+Desc(20,1Line)
147
+ Rules=EqualSpacing; SameBaseline
148
+
149
+ L14:
150
+ Intent=HeroImage
151
+ Grid=FullBleed
152
+ Content=OverlayTitle(40-56)+Subtitle(24-28)
153
+ Rules=DarkOverlay; HighContrast
154
+
155
+ L15:
156
+ Intent=Matrix4
157
+ Grid=2x2
158
+ Each=Heading(28)+Desc(20)
159
+ Rules=EqualCards; Gap=20-30
160
+
161
+ L16:
162
+ Intent=IconRow
163
+ Grid=Row(3-4)
164
+ Each=Icon+Label(28)+Desc(20,1-2Lines)
165
+ Rules=SameIconSize; AlignBaselines
166
+
167
+ L17:
168
+ Intent=Data+Insight
169
+ Grid=Stack
170
+ Content=Chart(~60%H); Insight(24-28,Bold)
171
+ Rules=1Highlight; NoChartJunk
172
+
173
+ L18:
174
+ Intent=BeforeAfter
175
+ Grid=2col+Arrow
176
+ Left=Before(Muted)
177
+ Right=After(Strong)
178
+ Rules=ClearContrast
179
+
180
+ L19:
181
+ Intent=List
182
+ Grid=Stack
183
+ Content=Title(40); Items(28,3-5)
184
+ Rules=NoWrap; LargeGaps
185
+
186
+ L20:
187
+ Intent=Closing
188
+ Grid=CenterStack
189
+ Content=Headline(48-56); Sub(24-28); Contact(24)
190
+ Rules=Clean; FinalImpression
191
+
192
+ OPENING & CLOSING SLIDES:
193
+ - First and last slides are STATEMENTS — emotional, not informational.
194
+ - Combine a strong visual with powerful words. Image + text working together.
195
+ - These set the tone (opening) and leave the lasting impression (closing).
196
+ - Aim for feeling, not facts.
197
+
198
+ TEXT-ONLY SLIDES:
199
+ - When a slide has no visual, let typography do the emotional heavy lifting.
200
+ - Be courageous: oversized type, unexpected alignment, asymmetric layout.
201
+ - Break the grid if it serves the message. Unusual ≠ unreadable.
202
+ - The text IS the visual — treat it as such.
203
+
204
+ SELECTION:
205
+ - Opening: L01,L02 (emotional statement + visual)
206
+ - Section: L03
207
+ - Statement/Quote: L04,L12
208
+ - Concept+Visual: L05,L06,L14
209
+ - Features: L07,L16
210
+ - Compare: L08,L18
211
+ - KPI: L09,L10,L11
212
+ - Process: L13
213
+ - Matrix: L15
214
+ - Data: L17
215
+ - List: L19
216
+ - Closing: L20 (emotional statement + visual)
217
+
218
+ OUTPUT RULES:
219
+ - Be concrete.
220
+ - No theory, no filler.
221
+ - Use sizes, spacing, alignment explicitly.
222
+ - If unclear: ask <=3 questions OR list <=5 assumptions.
@@ -0,0 +1,37 @@
1
+ # Table
2
+
3
+ - Tables follow strict hierarchy: **Table (frame) → Table Row (frame) → Table Cell (frame) → Table Cell Content**
4
+ - Use the following rules **only when there is no predefined Table component or Table frame** in the design system or document.
5
+ - Table responsive multi screen design: Unless specifically defined, when converting a wide multi-column table to a mobile version, consider using cards instead of table
6
+ - Tables need to use flex box layout.
7
+ - CRITICAL: Each cell is represented as a **frame** node and contains a cell content, which is usually text, label, button or instance of a component.
8
+ - **Antipattern** – Do NOT put content directly in the row, skipping the cell frame:
9
+
10
+ ```js
11
+ tableRowId=Insert("kdl58",{type:"frame",layout:"horizontal"})
12
+ Insert(tableRowId,{type:"text",content:"John Doe"})
13
+ Insert(tableRowId,{type:"text",content:"joe.doe@example.com"})
14
+ ```
15
+
16
+
17
+ ## Table Hierarchy
18
+ ```
19
+ Table (frame, vertical layout)
20
+ ├── Header Row (frame, horizontal, width: fill_container, height: fixed)
21
+ │ ├── Cell (frame, width: fixed, height: fill_container)
22
+ │ │ └── Text (text, bold, textGrowth: fixed-width)
23
+ │ ├── Cell (frame, width: fixed, height: fill_container)
24
+ │ │ └── Text (text, bold, textGrowth: fixed-width)
25
+ │ └── ...
26
+ ├── Data Row (frame, horizontal, width: fill_container, height: fixed)
27
+ │ ├── Cell (frame, width: fixed, height: fill_container)
28
+ │ │ └── Text (text, textGrowth: fixed-width)
29
+ │ ├── Cell (frame, width: fixed, height: fill_container)
30
+ │ │ └── Text (text, textGrowth: fixed-width)
31
+ │ └── ...
32
+ ├── Data Row ...
33
+ └── ...
34
+ ```
35
+
36
+ - If the user does not specify data, generate **dummy placeholder values** for each cell.
37
+ - Cells may contain other components (e.g., label, button) instead of text if explicitly requested.
@@ -0,0 +1,328 @@
1
+ # Tailwind v4 Implementation Guidelines
2
+
3
+ This document provides Tailwind v4 specific guidelines for implementing .pen designs in code.
4
+
5
+ **NOTE**: These guidelines are specific to Tailwind v4. If you are deliberately using an older version of Tailwind (v3 or earlier), you may bypass the v4-specific syntax rules (such as `@import "tailwindcss";` vs `@tailwind` directives) and adapt accordingly.
6
+
7
+ ## Core Principle
8
+
9
+ **Use Tailwind classes exclusively throughout - NEVER use inline styles for any property (sizing, colors, spacing, typography, etc.).**
10
+
11
+ ## CSS Variables Setup
12
+
13
+ ### Structure of globals.css
14
+
15
+ Your `globals.css` should follow this structure:
16
+
17
+ ```css
18
+ @import "tailwindcss";
19
+
20
+ :root {
21
+ /* Design variables from .pen file - ONLY single values */
22
+ --color-primary: #3b82f6;
23
+ --color-secondary: #8b5cf6;
24
+ --spacing-base: 16px;
25
+ /* DO NOT store font stacks here */
26
+ }
27
+
28
+ @layer base {
29
+ html, body {
30
+ height: 100%;
31
+ }
32
+
33
+ /* Font family utilities - Define font stacks directly here */
34
+ .font-primary {
35
+ font-family: "Inter", sans-serif;
36
+ }
37
+
38
+ .font-secondary {
39
+ font-family: "JetBrains Mono", monospace;
40
+ }
41
+ }
42
+ ```
43
+
44
+ ### Guidelines
45
+
46
+ - Read design variables using `Print(GetVariables())` in `execute`
47
+ - Convert to CSS custom properties in `:root` block for single values only (colors, numbers, keywords)
48
+ - Map all design variables using exact names from design file
49
+ - **IMPORTANT**: Use `:root` block for design variables (NOT `@theme` - Tailwind v4's `@theme` only supports custom properties and `@keyframes`)
50
+ - **DO NOT add manual resets** - `@import "tailwindcss";` includes Preflight automatically
51
+ - **CRITICAL for Next.js projects**: If using `next/font` loaders, DO NOT re-wrap their CSS variables (like `--font-geist`) in your `:root` block. Instead, reference them directly in `@layer base` utility classes (see Font Loading section)
52
+
53
+ ## Font Implementation
54
+
55
+ ### Core Rules
56
+
57
+ **CSS variables work for single values only** (colors, numbers, keywords). **DO NOT use them for font stacks.**
58
+
59
+ ❌ **WRONG**:
60
+ ```css
61
+ :root {
62
+ --font-primary: "JetBrains Mono", monospace; /* Breaks with comma-separated values */
63
+ }
64
+ ```
65
+
66
+ ✅ **CORRECT**: Define fonts in `@layer base` utility classes:
67
+ ```css
68
+ @layer base {
69
+ .font-primary {
70
+ font-family: "JetBrains Mono", monospace;
71
+ }
72
+
73
+ .font-secondary {
74
+ font-family: "Inter", sans-serif;
75
+ }
76
+ }
77
+ ```
78
+
79
+ ### Next.js Font Loaders
80
+
81
+ When using `next/font/google` or `next/font/local`:
82
+
83
+ ❌ **NEVER wrap Next.js font variables in `:root`**:
84
+ ```css
85
+ /* WRONG - nested var() references break */
86
+ :root {
87
+ --font-primary: var(--font-geist);
88
+ }
89
+ ```
90
+
91
+ ✅ **DO reference them directly in utility classes**:
92
+ ```css
93
+ @layer base {
94
+ .font-primary {
95
+ font-family: var(--font-jetbrains-mono), "JetBrains Mono", monospace;
96
+ }
97
+ }
98
+ ```
99
+
100
+ ### Implementation Workflow
101
+
102
+ 1. Read font names from design using `Print(GetVariables())` in `execute`
103
+ 2. Load fonts via `<link>` tags OR Next.js font loaders in layout.tsx
104
+ 3. Create utility classes in `@layer base` (`.font-primary`, `.font-secondary`)
105
+ 4. Use classes in components: `className="font-primary"`
106
+ 5. **NEVER use** `font-[var(--font-name)]` or inline styles for fonts
107
+
108
+ ## Font Loading
109
+
110
+ ### Tailwind v4 Requirements
111
+
112
+ ❌ **NEVER in Tailwind v4**:
113
+ - `@import url()` in CSS files
114
+ - `font-[family-name:var(...)]` syntax
115
+ - `--turbopack` flag
116
+
117
+ ✅ **Load fonts via**:
118
+ - `<link>` tags in layout.tsx `<head>`, OR
119
+ - Next.js font loaders (`next/font/google`, `next/font/local`)
120
+
121
+ ### Examples
122
+
123
+ **Option 1: Manual loading**
124
+ ```tsx
125
+ // layout.tsx
126
+ <head>
127
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet" />
128
+ </head>
129
+ ```
130
+
131
+ **Option 2: Next.js font loaders**
132
+ ```tsx
133
+ // layout.tsx
134
+ import { JetBrains_Mono } from "next/font/google";
135
+
136
+ const jetbrainsMono = JetBrains_Mono({
137
+ variable: "--font-jetbrains-mono",
138
+ subsets: ["latin"],
139
+ });
140
+
141
+ export default function RootLayout({ children }) {
142
+ return (
143
+ <html>
144
+ <body className={jetbrainsMono.variable}>
145
+ {children}
146
+ </body>
147
+ </html>
148
+ );
149
+ }
150
+ ```
151
+
152
+ ```css
153
+ /* globals.css */
154
+ @layer base {
155
+ .font-primary {
156
+ font-family: var(--font-jetbrains-mono), "JetBrains Mono", monospace;
157
+ }
158
+ }
159
+ ```
160
+
161
+ ## Icon Font Setup
162
+
163
+ - **If design uses `icon` nodes**:
164
+ 1. Add Google Fonts link in layout.tsx `<head>` (following the Font Loading Rules above)
165
+ 2. Add utility class in `@layer base` section of globals.css with appropriate font-feature-settings
166
+ 3. Render as `<span>` elements with icon name as text content
167
+ 4. Use inline styles for font-weight if needed (e.g., `style={{ fontWeight: 100 }}`)
168
+ 5. **NEVER use `@font-face`** - Always use CDN links
169
+
170
+ ## Viewport Setup
171
+
172
+ - Add `height: 100%` to `html` and `body` in `@layer base` section of globals.css (as shown in CSS Variables Setup example)
173
+ - Add `h-full` class to `<html>` and `<body>` in layout.tsx
174
+ - Ensures viewport-relative sizing works throughout app
175
+ - Design dimensions are specifications, not fixed constraints
176
+ - **DO NOT use wildcard selectors** - use the `@layer base` approach shown above
177
+
178
+ ## Tailwind v4 Import and Preflight
179
+
180
+ ### Correct Import Syntax
181
+
182
+ **Tailwind v4 uses a simplified import syntax** in `globals.css`:
183
+
184
+ ```css
185
+ @import "tailwindcss";
186
+ ```
187
+
188
+ This single import automatically includes:
189
+ - Base styles (Preflight reset)
190
+ - Component classes
191
+ - Utility classes
192
+
193
+ **DO NOT use the old v3 syntax**:
194
+ ```css
195
+ /* ❌ WRONG - This is v3 syntax */
196
+ @tailwind base;
197
+ @tailwind components;
198
+ @tailwind utilities;
199
+ ```
200
+
201
+ ### Preflight Reset Behavior
202
+
203
+ The `@import "tailwindcss";` automatically includes Preflight, which:
204
+ - Removes margins and padding from all elements
205
+ - Sets `box-sizing: border-box` on all elements
206
+ - Resets headings and lists (they inherit font properties)
207
+ - Makes images block-level with responsive sizing
208
+
209
+ ### Critical Rules
210
+
211
+ - **NEVER manually add global resets** - Preflight handles everything
212
+ - **NEVER use wildcard selectors** like `* { margin: 0; padding: 0; }` in globals.css
213
+ - **DO NOT duplicate Preflight functionality** - it's already included
214
+ - Use `@layer base { ... }` ONLY for additional custom base styles that don't conflict with Preflight
215
+
216
+ ## Layout Conversion
217
+
218
+ ### Container Sizing
219
+
220
+ - Root containers: `h-full w-full` or `h-screen w-screen` (NOT fixed dimensions)
221
+ - Fixed dimensions only for specific elements (e.g., sidebar: `w-[280px]`)
222
+
223
+ ### fill_container Translation
224
+
225
+ - In flex containers: use `flex-1`
226
+ - For explicit sizing: `w-full` (width), `h-full` (height)
227
+ - **IMPORTANT**: `h-full` requires parent chain has height set
228
+ - For scrollable containers: `flex-1 overflow-auto`
229
+ - **NEVER use inline styles** for sizing
230
+ - **Multiple fill_container Children**:
231
+ * In flex containers, multiple children with `fill_container` → each needs `flex-1`
232
+ * Applies to both horizontal and vertical flex layouts
233
+ * Distributes space equally among children
234
+ - **Height fill_container**:
235
+ * ANY component with `height: "fill_container"` MUST have `h-full` class
236
+ * Applies universally regardless of component type or parent layout
237
+ * Verify every `fill_container` height has corresponding `h-full` class
238
+
239
+ ### fit_content Translation
240
+
241
+ - Use `w-fit` (width), `h-fit` (height)
242
+ - NEVER use inline styles
243
+
244
+ ### Flex Context
245
+
246
+ - Parent must be flex container for `flex-1` to work
247
+ - Use `min-h-0` on flex children that need to shrink below content size
248
+ - Scrollable flex children: `flex-1 overflow-auto`
249
+
250
+ ### Verification
251
+
252
+ - Check ALL `fill_container`/`fit_content` converted to Tailwind classes
253
+ - Ensure NO inline styles for width/height
254
+
255
+ ## Style Implementation
256
+
257
+ Use **Tailwind classes exclusively** (NO inline styles) for all styling:
258
+
259
+ ### 1. Layout
260
+
261
+ - Position: `relative`, `absolute`, `fixed`, `sticky`
262
+ - Display: `flex`, `flex-col`, `grid`, `block`, `inline-block`
263
+ - Alignment: `items-center`, `justify-between`, etc.
264
+ - Gap: `gap-4`, `gap-[16px]` (match design exactly)
265
+
266
+ ### 2. Spacing
267
+
268
+ Match design values exactly:
269
+ - Padding: `p-4`, `px-6`, `pt-[12px]`, etc.
270
+ - Margin: `m-4`, `mx-auto`, `mt-[8px]`, etc.
271
+ - Use arbitrary values `[Npx]` when needed
272
+
273
+ ### 3. Dimensions
274
+
275
+ - Width: `w-[280px]` (fixed), `w-full` or `flex-1` (fill_container), `w-fit` (fit_content)
276
+ - Height: `h-[48px]` (fixed), `h-full` or `flex-1` (fill_container), `h-fit` (fit_content)
277
+ - Min/max: `min-w-[200px]`, `max-h-[600px]`
278
+ - **CRITICAL**: Never use inline styles for dimensions
279
+
280
+ ### 4. Colors and Borders
281
+
282
+ - Background: `bg-[var(--color-name)]` - NO hardcoded hex values
283
+ - Border: `border`, `border-2`, `border-[var(--color-border)]`
284
+ - Border radius: `rounded`, `rounded-lg`, `rounded-[12px]`
285
+ - Text: `text-[var(--color-text)]`
286
+ - Shadows: `shadow-sm`, `shadow-[custom]`
287
+
288
+ ### 5. Typography
289
+
290
+ - **Font family**: Use utility classes defined in `@layer base` (see "CSS Custom Properties and Font Stacks" section above)
291
+ - ✅ Correct: `className="font-primary"`
292
+ - ❌ NEVER: `font-[var(--font-primary)]` (arbitrary value syntax doesn't work with CSS variables)
293
+ - ❌ NEVER: `style={{ fontFamily: 'var(--font-primary)' }}` (avoid inline styles unless necessary)
294
+ - For Next.js font loaders: Create utility classes that reference the Next.js variables, then use those classes
295
+ - Font size: `text-sm`, `text-[14px]`
296
+ - Font weight: `font-medium`, `font-[500]`
297
+ - Line height: `leading-normal`, `leading-[24px]`
298
+ - Letter spacing: `tracking-normal`, `tracking-[0.02em]`
299
+
300
+ ### 6. Interactive States
301
+
302
+ - Hover: `hover:bg-[var(--color-hover)]`, `hover:opacity-80`
303
+ - Active: `active:scale-95`
304
+ - Disabled: `disabled:opacity-50`, `disabled:cursor-not-allowed`
305
+ - Focus: `focus:outline-none`, `focus:ring-2`
306
+
307
+ ## SVG Styling
308
+
309
+ For SVG path extraction and implementation workflow, see code.md "SVG Path Implementation" section.
310
+
311
+ ### Tailwind-Specific SVG Styling
312
+
313
+ When styling SVG elements with Tailwind:
314
+
315
+ - **Fill colors**: Use `fill-[var(--color-name)]` with CSS variables
316
+ - Example: `fill-[var(--primary)]`
317
+ - **Stroke colors**: Use `stroke-[var(--color-name)]`
318
+ - Example: `stroke-[var(--border)]`
319
+ - **Stroke width**: Use `stroke-[2]` or arbitrary values `stroke-[1.5px]`
320
+ - **SVG sizing**: Use standard sizing classes `w-6 h-6` or arbitrary `w-[24px] h-[24px]`
321
+ - **NEVER use inline styles** - always use Tailwind classes or className with CSS variables
322
+
323
+ Example:
324
+ ```tsx
325
+ <svg className="w-6 h-6 fill-[var(--icon-primary)]" viewBox="0 0 24 24">
326
+ <path d="M12 2L2 7l10 5 10-5-10-5z" />
327
+ </svg>
328
+ ```