clipper-css 0.1.2 → 0.2.0
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/README.md +2 -2
- package/bin/cli.js +54 -21
- package/clipper/clipper.css +1 -1
- package/clipper.instructions.md +183 -0
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ The best way to install clipper is to run it in a freshly installed framework pr
|
|
|
10
10
|
|
|
11
11
|
### Astro
|
|
12
12
|
|
|
13
|
-
- [How to install Astro](https://docs.astro.build/en/
|
|
13
|
+
- [How to install Astro](https://docs.astro.build/en/install-and-setup/)
|
|
14
14
|
- [How to install Tailwind for Astro](https://docs.astro.build/en/guides/styling/#tailwind)
|
|
15
15
|
|
|
16
16
|
### SvelteKit
|
|
@@ -151,4 +151,4 @@ Clipper is intentionally small and unobtrusive. Use Tailwind classes or a UI com
|
|
|
151
151
|
|
|
152
152
|
## Get in touch
|
|
153
153
|
|
|
154
|
-
Please suggest fixes etc on Github. Improvements can surely be made.
|
|
154
|
+
Please suggest fixes etc on [Github](https://github.com/ciscoheat/clipper-css/issues). Improvements can surely be made.
|
package/bin/cli.js
CHANGED
|
@@ -133,8 +133,9 @@ async function main() {
|
|
|
133
133
|
// --- FLOW 1: NOT FOUND ---
|
|
134
134
|
log(`\n✨ New setup detected`, c.cyan);
|
|
135
135
|
|
|
136
|
-
// Gather files
|
|
137
|
-
const
|
|
136
|
+
// Gather potential files
|
|
137
|
+
const allCoreFiles = [];
|
|
138
|
+
const allTemplateFiles = [];
|
|
138
139
|
|
|
139
140
|
// Core Clipper Files
|
|
140
141
|
if (await exists(clipperSourceDir)) {
|
|
@@ -143,11 +144,16 @@ async function main() {
|
|
|
143
144
|
...(devMode ? { ignore: ["node_modules/**"] } : { gitignore: true }),
|
|
144
145
|
});
|
|
145
146
|
for (const f of coreFiles) {
|
|
146
|
-
|
|
147
|
+
allCoreFiles.push({
|
|
147
148
|
src: path.join(clipperSourceDir, f),
|
|
148
149
|
dest: path.join(selectedConfig.clipperDest, f),
|
|
149
150
|
});
|
|
150
151
|
}
|
|
152
|
+
// Instructions file
|
|
153
|
+
allCoreFiles.push({
|
|
154
|
+
src: path.join(__dirname, "..", "clipper.instructions.md"),
|
|
155
|
+
dest: path.join(".github", "instructions", "clipper.instructions.md"),
|
|
156
|
+
});
|
|
151
157
|
}
|
|
152
158
|
|
|
153
159
|
// Framework Template Files
|
|
@@ -157,37 +163,64 @@ async function main() {
|
|
|
157
163
|
...(devMode ? { ignore: ["node_modules/**"] } : { gitignore: true }),
|
|
158
164
|
});
|
|
159
165
|
for (const f of templFiles) {
|
|
160
|
-
|
|
166
|
+
allTemplateFiles.push({
|
|
161
167
|
src: path.join(templateSourceDir, f),
|
|
162
168
|
dest: f, // relative to root
|
|
163
169
|
});
|
|
164
170
|
}
|
|
165
171
|
}
|
|
166
172
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
173
|
+
const filesToCopy = [];
|
|
174
|
+
|
|
175
|
+
// Question 1: Core Files
|
|
176
|
+
let copyCore = autoYes;
|
|
177
|
+
if (allCoreFiles.length > 0) {
|
|
178
|
+
log(`\nClipper CSS Core Files:`, c.gray);
|
|
179
|
+
allCoreFiles.forEach((f) => log(` + ${f.dest}`, c.cyan));
|
|
180
|
+
|
|
181
|
+
if (!autoYes) {
|
|
182
|
+
const response = await prompts({
|
|
183
|
+
type: "confirm",
|
|
184
|
+
name: "copyCore",
|
|
185
|
+
message: "Install Clipper CSS core files?",
|
|
186
|
+
initial: true,
|
|
187
|
+
});
|
|
188
|
+
copyCore = response.copyCore;
|
|
189
|
+
}
|
|
170
190
|
}
|
|
171
191
|
|
|
172
|
-
|
|
173
|
-
|
|
192
|
+
if (copyCore) {
|
|
193
|
+
filesToCopy.push(...allCoreFiles);
|
|
194
|
+
}
|
|
174
195
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
196
|
+
// Question 2: Template Files
|
|
197
|
+
let copyTemplate = autoYes;
|
|
198
|
+
if (allTemplateFiles.length > 0) {
|
|
199
|
+
log(`\nTemplate Files:`, c.gray);
|
|
200
|
+
allTemplateFiles.forEach((f) => log(` + ${f.dest}`, c.cyan));
|
|
201
|
+
|
|
202
|
+
if (!autoYes) {
|
|
203
|
+
const response = await prompts({
|
|
204
|
+
type: "confirm",
|
|
205
|
+
name: "copyTemplate",
|
|
206
|
+
message: "Install template files?",
|
|
207
|
+
initial: true,
|
|
208
|
+
});
|
|
209
|
+
copyTemplate = response.copyTemplate;
|
|
210
|
+
}
|
|
184
211
|
}
|
|
185
212
|
|
|
186
|
-
if (
|
|
187
|
-
|
|
213
|
+
if (copyTemplate) {
|
|
214
|
+
filesToCopy.push(...allTemplateFiles);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (filesToCopy.length === 0) {
|
|
218
|
+
log(`No files selected to install.`, c.gray);
|
|
188
219
|
process.exit(0);
|
|
189
220
|
}
|
|
190
221
|
|
|
222
|
+
log(`\nInstalling selected files...`, c.gray);
|
|
223
|
+
|
|
191
224
|
// Perform Copy
|
|
192
225
|
for (const f of filesToCopy) {
|
|
193
226
|
const absDest = path.join(cwd, f.dest);
|
|
@@ -278,7 +311,7 @@ async function injectImport(cwd, clipperDestRelative, devMode) {
|
|
|
278
311
|
|
|
279
312
|
if (!patched) {
|
|
280
313
|
log(
|
|
281
|
-
`ℹ️ Could not automatically inject CSS import
|
|
314
|
+
`ℹ️ Could not automatically inject CSS import. Is Tailwind installed?\n Please import ${clipperDestRelative}/clipper.css manually.`,
|
|
282
315
|
c.gray,
|
|
283
316
|
);
|
|
284
317
|
}
|
package/clipper/clipper.css
CHANGED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "Clipper CSS"
|
|
3
|
+
applyTo: "**/*.html,**/*.astro,**/*.svelte,**/*.css,**/*.scss"
|
|
4
|
+
description: "Instructions for working with Clipper, the CSS framework for Tailwind."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Working in Clipper - The CSS framework for Tailwind
|
|
8
|
+
|
|
9
|
+
This guide is for agents making changes to codebases where Clipper is used as the CSS framework.
|
|
10
|
+
|
|
11
|
+
**Goal:** Make safe, minimal, maintainable changes that align with Clipper's philosophy: "If you can express it semantically, do that first. If you need control, use tokens/utilities. If it repeats, make it a component."
|
|
12
|
+
|
|
13
|
+
## Scope
|
|
14
|
+
|
|
15
|
+
This guide applies to:
|
|
16
|
+
|
|
17
|
+
- New sections/pages
|
|
18
|
+
- Refactors and cleanup
|
|
19
|
+
- Bug fixes
|
|
20
|
+
- Styling and theming changes
|
|
21
|
+
- Layout/header/footer/navigation changes
|
|
22
|
+
|
|
23
|
+
## Core principles
|
|
24
|
+
|
|
25
|
+
- **Semantic first** — Use semantic HTML and preserve accessibility
|
|
26
|
+
- **Minimal changes** — Change as few lines as possible to achieve the goal
|
|
27
|
+
- **Token-driven** — Use design tokens from `variables.css`, not arbitrary values
|
|
28
|
+
- **Utility-first** — Use Tailwind utilities for page-specific styling
|
|
29
|
+
- **Component when it repeats** — Only extract reusable primitives to `components.css`
|
|
30
|
+
|
|
31
|
+
## Project architecture
|
|
32
|
+
|
|
33
|
+
### File structure
|
|
34
|
+
|
|
35
|
+
- `src/styles/variables.css` → design tokens (color, spacing, typography) + Tailwind v4 `@theme` exports
|
|
36
|
+
- `src/styles/components.css` → reusable component primitives (`.btn`, `.card`, `.badge`)
|
|
37
|
+
- `src/styles/clipper.css` → framework foundations - no need to change this file unless explicitly asked
|
|
38
|
+
|
|
39
|
+
## Styling rules
|
|
40
|
+
|
|
41
|
+
### Utility-first approach
|
|
42
|
+
|
|
43
|
+
- Use Tailwind utilities directly in markup for page-specific styling
|
|
44
|
+
- Keep utility strings in the `class` attribute (don't extract as constants)
|
|
45
|
+
- Only add to `components.css` if the pattern repeats across pages
|
|
46
|
+
|
|
47
|
+
### Components in `components.css`
|
|
48
|
+
|
|
49
|
+
**NOTE:** If another UI framework is being used (e.g. Material UI, Radix, Daisy UI), do not use `components.css` - stick to that framework's components.
|
|
50
|
+
|
|
51
|
+
**Allowed** — Generic, reusable primitives:
|
|
52
|
+
|
|
53
|
+
- `.btn`
|
|
54
|
+
- `.card`
|
|
55
|
+
- `.badge`
|
|
56
|
+
- `.btn .btn-outline`
|
|
57
|
+
|
|
58
|
+
**Avoid** — Page/section-scoped classes:
|
|
59
|
+
|
|
60
|
+
- Page-scoped: `.page-*`, `.home-*`
|
|
61
|
+
- Section-scoped: `.hero-*`, `.footer-*`
|
|
62
|
+
- One-off namespaces: `.cs-*`
|
|
63
|
+
|
|
64
|
+
If it's one-off, keep it as utilities in markup.
|
|
65
|
+
|
|
66
|
+
## Tokens and spacing
|
|
67
|
+
|
|
68
|
+
### Color tokens
|
|
69
|
+
|
|
70
|
+
Use semantic tokens from `variables.css`:
|
|
71
|
+
|
|
72
|
+
**Base colors:**
|
|
73
|
+
|
|
74
|
+
- `background`, `foreground`
|
|
75
|
+
- `accent`, `accent-foreground`
|
|
76
|
+
- `muted`, `muted-foreground`
|
|
77
|
+
|
|
78
|
+
**Primary colors:**
|
|
79
|
+
|
|
80
|
+
- `primary` (500 is usually the base color, with the other 50-900 shades)
|
|
81
|
+
- `primary-foreground`
|
|
82
|
+
- `primary-hover`
|
|
83
|
+
- `primary-muted`
|
|
84
|
+
|
|
85
|
+
Same goes for `secondary` and `tertiary` if they exist in the project.
|
|
86
|
+
|
|
87
|
+
**Other:**
|
|
88
|
+
|
|
89
|
+
- `link`, `link-hover`
|
|
90
|
+
- `link-underline`, `link-underline-hover`
|
|
91
|
+
- `border`
|
|
92
|
+
|
|
93
|
+
### Spacing utilities
|
|
94
|
+
|
|
95
|
+
**Always use Clipper's fluid spacing scale:**
|
|
96
|
+
|
|
97
|
+
- `4xs`, `3xs`, `2xs`, `xs`, `sm`, `base`, `lg`, `xl`, `2xl`, `3xl`, `4xl`
|
|
98
|
+
|
|
99
|
+
Examples: `gap-sm`, `pb-xl`.
|
|
100
|
+
|
|
101
|
+
**Note** that `base` is the default spacing unit for all elements except `section`, and should not be added explicitly to keep the markup clean.
|
|
102
|
+
|
|
103
|
+
**Never use** Tailwind's numeric scale (`gap-1`, `gap-2`, `gap-4`, etc.) — it bypasses the fluid spacing system.
|
|
104
|
+
|
|
105
|
+
## Typography
|
|
106
|
+
|
|
107
|
+
### Headings
|
|
108
|
+
|
|
109
|
+
- Semantic first: `<h1>`, `<h2>`, `<h3>`, `<h4>`, `<h5>`
|
|
110
|
+
- Visual flexibility: Apply display classes to change size
|
|
111
|
+
|
|
112
|
+
```astro
|
|
113
|
+
<h3 class="h2">Semantically h3, visually h2</h3>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Body text
|
|
117
|
+
|
|
118
|
+
Body text stays stable while heading sizes scale fluidly via `clamp()`.
|
|
119
|
+
|
|
120
|
+
## Utility classes
|
|
121
|
+
|
|
122
|
+
| Class | Function |
|
|
123
|
+
| --------------- | ------------------------------------- |
|
|
124
|
+
| `row` | `flex-row` with sensible defaults |
|
|
125
|
+
| `readable` | Max-width for readable text |
|
|
126
|
+
| `full-width` | Break children out of `page-width` |
|
|
127
|
+
| `page-width` | Restore `page-width` to inner content |
|
|
128
|
+
| `header-sticky` | Simple sticky header |
|
|
129
|
+
|
|
130
|
+
## Data modeling
|
|
131
|
+
|
|
132
|
+
- Define page data in the top script block as arrays/objects
|
|
133
|
+
- Structure mock data like real data (stable keys, realistic types)
|
|
134
|
+
- Keep rendering logic in templates, data in the script block
|
|
135
|
+
- When real data arrives (CMS/API), swap the source with minimal template changes
|
|
136
|
+
|
|
137
|
+
## Accessibility checklist
|
|
138
|
+
|
|
139
|
+
- Use correct landmarks and `aria-label` where needed
|
|
140
|
+
- Keep heading hierarchy logical (`h1` once per page)
|
|
141
|
+
- Ensure focus-visible states remain clear
|
|
142
|
+
- Use real links/buttons for interaction
|
|
143
|
+
|
|
144
|
+
## Implementation workflow
|
|
145
|
+
|
|
146
|
+
When working from a design/screenshot:
|
|
147
|
+
|
|
148
|
+
- Extract semantic structure (`header`, `main`, `section`, `footer`)
|
|
149
|
+
- Implement with minimal wrappers
|
|
150
|
+
- Map visual decisions to existing tokens
|
|
151
|
+
- Use utilities for page-specific layout/spacing/typography
|
|
152
|
+
- Add to `components.css` only if the pattern truly repeats
|
|
153
|
+
- Validate desktop/mobile + dark mode
|
|
154
|
+
- Run `pnpm build` to verify
|
|
155
|
+
|
|
156
|
+
## Definition of done
|
|
157
|
+
|
|
158
|
+
- [ ] Requested outcome is implemented
|
|
159
|
+
- [ ] Page-specific styling uses utilities in markup, as few as possible and primarily the clipper utilities
|
|
160
|
+
- [ ] Mock data is defined in script block, structured for real data
|
|
161
|
+
- [ ] `components.css` contains only generic reusable primitives
|
|
162
|
+
- [ ] Tokens are used consistently (no arbitrary colors)
|
|
163
|
+
- [ ] Dark mode remains intentional/readable
|
|
164
|
+
- [ ] `pnpm build` passes
|
|
165
|
+
|
|
166
|
+
## Quick reference: Do / Don't
|
|
167
|
+
|
|
168
|
+
### Do
|
|
169
|
+
|
|
170
|
+
- Reuse existing primitives first
|
|
171
|
+
- Keep markup semantic and lean - don't add utilities unless required
|
|
172
|
+
- Use Clipper's spacing utilities (`gap-sm`, `mb-xl` etc.)
|
|
173
|
+
- Use utilities for page styling
|
|
174
|
+
- Centralize colors in tokens
|
|
175
|
+
|
|
176
|
+
### Don't
|
|
177
|
+
|
|
178
|
+
- Add one-off classes to `components.css`
|
|
179
|
+
- Duplicate Header/Footer across pages
|
|
180
|
+
- Hardcode colors when tokens exist
|
|
181
|
+
- Use Tailwind's numeric gap utilities (`gap-1`, `gap-2`, etc.)
|
|
182
|
+
- Add unrelated features beyond the request
|
|
183
|
+
- Use inline styles or arbitrary values instead of tokens/utilities
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clipper-css",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Clipper is a simple Tailwind framework for building pages without fighting CSS and drowning in utility classes.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "bin/cli.js",
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"clipper",
|
|
27
27
|
"templates",
|
|
28
28
|
"README.md",
|
|
29
|
-
"LICENSE"
|
|
29
|
+
"LICENSE",
|
|
30
|
+
"clipper.instructions.md"
|
|
30
31
|
],
|
|
31
32
|
"dependencies": {
|
|
32
33
|
"globby": "^16.1.1",
|
|
@@ -35,8 +36,8 @@
|
|
|
35
36
|
"scripts": {
|
|
36
37
|
"clean": "node scripts/utils.js clean",
|
|
37
38
|
"build": "node scripts/utils.js update-version",
|
|
38
|
-
"test:astro": "cd tests/astro && node ../../bin/cli.js
|
|
39
|
-
"test:sveltekit": "cd tests/sveltekit && node ../../bin/cli.js
|
|
39
|
+
"test:astro": "cd tests/astro && node ../../bin/cli.js",
|
|
40
|
+
"test:sveltekit": "cd tests/sveltekit && node ../../bin/cli.js",
|
|
40
41
|
"version": "npm run build && git add clipper/clipper.css"
|
|
41
42
|
}
|
|
42
43
|
}
|