@andersseen/skills 0.0.1

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.
@@ -0,0 +1,124 @@
1
+ ---
2
+ name: andersseen-icon
3
+ description:
4
+ 'Register and render SVG icons with @andersseen/icon. Load when using
5
+ registerIcons / registerAllIcons / getIcon / COMPONENT_ICONS, wiring the
6
+ and-icon element, or resolving "icon not showing" issues. COMPONENT_ICONS must
7
+ be registered whenever @andersseen/web-components is used. Trigger phrases:
8
+ icon, svg, registerIcons, and-icon, icon registry, icon not rendering.'
9
+ ---
10
+
11
+ # @andersseen/icon — SVG icon registry
12
+
13
+ Framework-agnostic SVG string registry: tree-shakable icon constants + runtime
14
+ registration functions. Used internally by `and-icon` in
15
+ `@andersseen/web-components`, and consumable standalone to render SVGs in any
16
+ framework.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ npm i @andersseen/icon
22
+ ```
23
+
24
+ ## Core API
25
+
26
+ ```ts
27
+ import {
28
+ registerIcons,
29
+ registerAllIcons,
30
+ getIcon,
31
+ hasIcon,
32
+ getRegisteredIconNames,
33
+ getRegisteredIconCount,
34
+ } from '@andersseen/icon';
35
+ ```
36
+
37
+ Verified behavior:
38
+
39
+ - The registry is global (`window`/`globalThis`) under `__AND_ICONS_REGISTRY__`.
40
+ - `registerIcons` merges entries into that global Map.
41
+ - `getIcon(name)` returns an SVG string or `undefined` if not registered.
42
+
43
+ ## Setup options
44
+
45
+ ### Option A — register all icons (prototyping / small apps)
46
+
47
+ ```ts
48
+ import { registerAllIcons } from '@andersseen/icon';
49
+ registerAllIcons();
50
+ ```
51
+
52
+ ### Option B — tree-shakable selective registration (production recommended)
53
+
54
+ ```ts
55
+ import {
56
+ registerIcons,
57
+ HOME,
58
+ CLOSE,
59
+ SEARCH,
60
+ COMPONENT_ICONS,
61
+ } from '@andersseen/icon';
62
+
63
+ // Icons required by and-* components — ALWAYS register when using web-components
64
+ registerIcons(COMPONENT_ICONS);
65
+
66
+ // Additional icons your app needs
67
+ registerIcons({ home: HOME, close: CLOSE, search: SEARCH });
68
+ ```
69
+
70
+ ### COMPONENT_ICONS
71
+
72
+ A pre-built record containing every icon that `@andersseen/web-components` uses
73
+ internally (chevron, close, check, spinner, …). Always include it when using the
74
+ web-components package.
75
+
76
+ ## Using registered icons
77
+
78
+ ```ts
79
+ const svg = getIcon('home'); // SVG string or undefined
80
+
81
+ if (!hasIcon('home')) {
82
+ console.warn('Icon "home" is not registered');
83
+ }
84
+
85
+ console.log(getRegisteredIconNames());
86
+ console.log(getRegisteredIconCount());
87
+
88
+ // Render inline in a framework
89
+ // Angular: <span [innerHTML]="getIcon('home')"></span>
90
+ // Pure HTML: element.innerHTML = getIcon('home') ?? '';
91
+ ```
92
+
93
+ ## With and-icon (web component)
94
+
95
+ After registration, use the icon by name via the `name` prop:
96
+
97
+ ```html
98
+ <and-icon name="home" size="20"></and-icon>
99
+ <and-icon name="sparkles" size="16" color="hsl(var(--primary))"></and-icon>
100
+ <and-icon name="arrow-right" size="24" stroke-width="1.5"></and-icon>
101
+ ```
102
+
103
+ ## Naming convention
104
+
105
+ Exported constants use `SCREAMING_SNAKE_CASE`; registration keys (and `name`
106
+ prop values) use `kebab-case`.
107
+
108
+ ```ts
109
+ import { ARROW_RIGHT, CHECK_CIRCLE, LOADING_SPINNER } from '@andersseen/icon';
110
+ registerIcons({
111
+ 'arrow-right': ARROW_RIGHT,
112
+ 'check-circle': CHECK_CIRCLE,
113
+ 'loading-spinner': LOADING_SPINNER,
114
+ });
115
+ ```
116
+
117
+ ## Rules
118
+
119
+ - Always register icons before rendering `and-icon` or calling `getIcon`.
120
+ - In production prefer selective registration; avoid `registerAllIcons` outside
121
+ demos/prototypes.
122
+ - Keep `and-icon name` exactly aligned with registry keys.
123
+ - Do not inline random SVG literals when the registry can be used.
124
+ - Register `COMPONENT_ICONS` whenever `@andersseen/web-components` is used.
@@ -0,0 +1,198 @@
1
+ ---
2
+ name: andersseen-layout
3
+ description:
4
+ 'Compose layout and typography with @andersseen/layout — a pure-CSS,
5
+ attribute-driven system using and-layout and and-text with @breakpoint
6
+ responsive modifiers. Load when building responsive page shells, grids, flex
7
+ layouts, spacing, or type scales without a utility framework. Trigger phrases:
8
+ and-layout, and-text, responsive grid, flex layout, spacing scale, typography,
9
+ cols, gap, and-layout attributes.'
10
+ ---
11
+
12
+ # @andersseen/layout — attribute-driven layout & typography
13
+
14
+ Pure CSS library — **no JavaScript runtime**. Attribute-driven layout
15
+ composition and typography, framework-agnostic and mobile-first. HTML attributes
16
+ are the single source of truth for layout.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ npm i @andersseen/layout
22
+ ```
23
+
24
+ ## Setup
25
+
26
+ ```ts
27
+ import '@andersseen/layout/dist/layout.css';
28
+ ```
29
+
30
+ ## Breakpoints (mobile-first, min-width)
31
+
32
+ | Name | Min-width |
33
+ | ---- | --------- |
34
+ | sm | 640px |
35
+ | md | 768px |
36
+ | lg | 1024px |
37
+ | xl | 1280px |
38
+ | 2xl | 1536px |
39
+
40
+ ## Responsive syntax
41
+
42
+ Every modifier supports responsive variants using `@breakpoint`:
43
+
44
+ ```html
45
+ <div and-layout="vertical vertical@sm horizontal@md gap:sm gap@lg:xl"></div>
46
+ <p and-text="p-sm align:center align@md:left"></p>
47
+ ```
48
+
49
+ Spacing scale: `none · xxxs · xxs · xs · sm · md · lg · xl · xxl · xxxl · auto`.
50
+
51
+ ## `and-layout`
52
+
53
+ ### Display / direction
54
+
55
+ ```html
56
+ <div and-layout="horizontal"><!-- flex row --></div>
57
+ <div and-layout="vertical"><!-- flex column --></div>
58
+ <div and-layout="grid"><!-- display:grid --></div>
59
+ ```
60
+
61
+ Both `horizontal` and `vertical` are responsive: `horizontal@md`, `vertical@lg`.
62
+
63
+ ### Flex alignment
64
+
65
+ ```
66
+ align:start | end | center | baseline | stretch
67
+ justify:start | end | center | between | around | evenly
68
+ wrap:nowrap | wrap | wrap-reverse
69
+ ```
70
+
71
+ ### Gap
72
+
73
+ ```
74
+ gap:{spacing} gap-x:{spacing} gap-y:{spacing}
75
+ ```
76
+
77
+ ### Grid columns
78
+
79
+ Generates `repeat(N, minmax(0, 1fr))` for N in 1–12.
80
+
81
+ ```html
82
+ <div and-layout="grid cols:1 cols@sm:2 cols@lg:3 gap:lg"></div>
83
+ ```
84
+
85
+ ### Grid column span
86
+
87
+ Values 1–12 + `full` (span all columns).
88
+
89
+ ```html
90
+ <div and-layout="grid cols:12">
91
+ <header and-layout="span:full">...</header>
92
+ <main and-layout="span:8 span@lg:9">...</main>
93
+ <aside and-layout="span:4 span@lg:3">...</aside>
94
+ </div>
95
+ ```
96
+
97
+ ### Grid start/end
98
+
99
+ `col-start:1`–`col-start:13`, `col-start:auto`; `col-end:1`–`col-end:13`,
100
+ `col-end:auto`.
101
+
102
+ ### Padding / margin
103
+
104
+ ```
105
+ p:{s} p-t p-b p-l p-r p-x p-y : {s}
106
+ m:{s} m-t m-b m-l m-r m-x m-y : {s}
107
+ ```
108
+
109
+ ### Spacing scale
110
+
111
+ | Token | Value | | Token | Value |
112
+ | ----- | -------- | --- | ----- | ------ |
113
+ | none | 0 | | md | 1rem |
114
+ | xxxs | 0.125rem | | lg | 1.5rem |
115
+ | xxs | 0.25rem | | xl | 2rem |
116
+ | xs | 0.5rem | | xxl | 3rem |
117
+ | sm | 0.75rem | | xxxl | 4rem |
118
+ | | | | auto | auto |
119
+
120
+ ## `and-text` — typography
121
+
122
+ ### Semantic scale
123
+
124
+ `h1 · h2 · h3 · h4 · h5 · h6 · p · p-sm · p-xs · caption`
125
+
126
+ | Token | Font size | Weight | Line-height |
127
+ | ------- | --------- | ------ | ----------- |
128
+ | h1 | 3.75rem | 700 | 1.1 |
129
+ | h2 | 3rem | 700 | 1.1 |
130
+ | h3 | 2.25rem | 600 | 1.2 |
131
+ | h4 | 1.875rem | 600 | 1.2 |
132
+ | h5 | 1.5rem | 500 | 1.3 |
133
+ | h6 | 1.25rem | 500 | 1.3 |
134
+ | p | 1rem | 400 | 1.5 |
135
+ | p-sm | 0.875rem | 400 | 1.5 |
136
+ | p-xs | 0.75rem | 400 | 1.5 |
137
+ | caption | 0.75rem | 400 | — (muted) |
138
+
139
+ ### Alignment · weight · color (all responsive)
140
+
141
+ ```
142
+ align:left | center | right | justify
143
+ weight:thin | light | normal | medium | semibold | bold | extrabold | black
144
+ color:primary | secondary | accent | muted | destructive | foreground | background
145
+ ```
146
+
147
+ Color tokens map to CSS variables: `var(--color-primary)`,
148
+ `var(--color-foreground)`, …
149
+
150
+ ## Usage examples
151
+
152
+ ### Responsive page shell
153
+
154
+ ```html
155
+ <body and-layout="vertical gap:none">
156
+ <nav and-layout="horizontal justify:between align:center p-x:lg p-y:md">
157
+ <a and-text="h6 weight:bold">Logo</a>
158
+ <div and-layout="horizontal gap:sm">
159
+ <a and-text="p-sm">Home</a>
160
+ <a and-text="p-sm">Docs</a>
161
+ </div>
162
+ </nav>
163
+ <main and-layout="vertical gap:xl p:lg p@md:xxl">
164
+ <section and-layout="vertical gap:md">
165
+ <h1 and-text="h1 align:center align@md:left color:foreground">
166
+ Hero Title
167
+ </h1>
168
+ <p and-text="p align:center align@md:left color:muted">Subtitle text</p>
169
+ </section>
170
+ <div and-layout="grid cols:1 cols@sm:2 cols@lg:3 gap:lg">
171
+ <article and-layout="vertical gap:sm p:md">
172
+ <h2 and-text="h5 color:foreground">Card Title</h2>
173
+ <p and-text="p-sm color:muted">Card description</p>
174
+ </article>
175
+ </div>
176
+ </main>
177
+ </body>
178
+ ```
179
+
180
+ ### 12-column grid
181
+
182
+ ```html
183
+ <section and-layout="grid cols:12 gap:md">
184
+ <div and-layout="span:12 span@md:8">Main content</div>
185
+ <div and-layout="span:12 span@md:4">Sidebar</div>
186
+ </section>
187
+ ```
188
+
189
+ ## Rules
190
+
191
+ - Use `and-layout` and `and-text` as the primary composition mechanism.
192
+ - Do not mix a utility CSS framework (Tailwind, Bootstrap) with `and-layout`
193
+ tokens on the same element.
194
+ - Responsive tokens use the `@breakpoint` suffix: `cols@md:2`, `align@lg:left`.
195
+ - Color tokens map to CSS custom properties — do not override with hardcoded
196
+ values.
197
+ - `caption` already applies a muted color — do not combine with
198
+ `color:foreground`.
@@ -0,0 +1,166 @@
1
+ ---
2
+ name: andersseen-motion
3
+ description:
4
+ 'Add attribute-driven animations with @andersseen/motion — scroll/enter,
5
+ hover, and tap triggers via and-motion HTML attributes plus
6
+ initMotion/MotionController. Load when animating element entrances, hover/tap
7
+ feedback, staggered lists, or configuring duration/delay/easing. Respects
8
+ prefers-reduced-motion. Trigger phrases: animation, motion, and-motion,
9
+ fade-up, scroll animation, initMotion, entrance animation.'
10
+ ---
11
+
12
+ # @andersseen/motion — attribute-driven animation engine
13
+
14
+ Animate the web with HTML attributes + CSS keyframes and a lightweight JS
15
+ controller. Triggers: `enter` (IntersectionObserver), `hover`, `tap`. Respects
16
+ `prefers-reduced-motion` in both CSS and JS.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ npm i @andersseen/motion
22
+ ```
23
+
24
+ ## Setup
25
+
26
+ ```ts
27
+ import { initMotion } from '@andersseen/motion';
28
+ import '@andersseen/motion/style.css';
29
+
30
+ // Creates a MotionController + scans the root. Returns a cleanup function.
31
+ const cleanup = initMotion();
32
+
33
+ // Optional options:
34
+ const cleanupWithOpts = initMotion({
35
+ root: document.getElementById('page'),
36
+ threshold: 0.15,
37
+ rootMargin: '0px',
38
+ once: true,
39
+ });
40
+
41
+ // On SPA route change / component destroy:
42
+ cleanup();
43
+ ```
44
+
45
+ ## Advanced: MotionController class
46
+
47
+ ```ts
48
+ import { MotionController } from '@andersseen/motion';
49
+
50
+ const mc = new MotionController({
51
+ root: document.body,
52
+ threshold: 0.1,
53
+ once: true,
54
+ });
55
+ mc.scan(); // re-scan root (call after dynamic content is added)
56
+ mc.destroy(); // remove all observers and event listeners
57
+ ```
58
+
59
+ Verified options: `root?` (default `document.body`), `threshold?` (default
60
+ `0.1`), `rootMargin?` (default `'0px'`), `once?` (default `true`).
61
+
62
+ ## Attribute reference
63
+
64
+ | Attribute | Values | Notes |
65
+ | --------------------- | -------------------------- | ---------------------------------------------------- |
66
+ | `and-motion` | animation name (required) | Marks the element and sets which animation runs |
67
+ | `and-motion-trigger` | `enter` · `hover` · `tap` | Default `enter`; names ending `-in` also infer enter |
68
+ | `and-motion-duration` | CSS time (`500ms`, `1.2s`) | Sets `--and-motion-duration` on the element |
69
+ | `and-motion-delay` | CSS time (`200ms`) | Sets `--and-motion-delay` on the element |
70
+ | `and-motion-easing` | CSS easing string | Sets `--and-motion-easing` on the element |
71
+ | `and-motion-once` | `true` · `false` | Per-element override of the controller-level `once` |
72
+
73
+ Controller runtime attribute: `and-motion-state=active` is toggled internally
74
+ while an animation is active.
75
+
76
+ ## CSS custom properties (global, overridable)
77
+
78
+ ```
79
+ --and-motion-duration: 500ms
80
+ --and-motion-delay: 0ms
81
+ --and-motion-easing: cubic-bezier(0.16, 1, 0.3, 1) /* expo-out */
82
+ --and-motion-easing-enter: cubic-bezier(0.16, 1, 0.3, 1)
83
+ --and-motion-easing-exit: cubic-bezier(0.7, 0, 0.84, 0)
84
+ --and-motion-easing-spring: cubic-bezier(0.34, 1.56, 0.64, 1)
85
+ --and-motion-easing-smooth: cubic-bezier(0.25, 0.1, 0.25, 1)
86
+ --and-motion-easing-bounce: cubic-bezier(0.175, 0.885, 0.32, 1.275)
87
+ --and-motion-distance: 20px
88
+ --and-motion-distance-big: 150px
89
+ ```
90
+
91
+ ## Animation names
92
+
93
+ - **Fading** (enter by default): `fade`, `fade-up`, `fade-down`, `fade-left`,
94
+ `fade-right` (+ `-big` and corner variants). Explicit: `fade-in`,
95
+ `fade-in-up`, …; exit: `fade-out`, `fade-out-up`, …
96
+ - **Sliding**: `slide-up/down/left/right` (+ `slide-in-*` / `slide-out-*`).
97
+ - **Zooming**: `zoom`, `zoom-up/down/left/right` (+ `zoom-in-*` / `zoom-out-*`).
98
+ - **Bouncing**: `bounce-up/down/left/right` (+ `bounce-in-*` / `bounce-out-*`);
99
+ `bounce-in`, `bounce-out` (750ms).
100
+ - **Flipping**: `flip`, `flip-x`, `flip-y` (+ `flip-in-x/y`, `flip-out-x/y`).
101
+ - **Rotating**: `rotate`, `rotate-down-left/right`, `rotate-up-left/right` (+
102
+ `rotate-in-*` / `rotate-out-*`).
103
+ - **Light speed**: `light-speed-right/left` (+ `light-speed-in/out-*`).
104
+ - **Back** (overshoot from off-screen): `back-down/left/right/up` (+ `back-in-*`
105
+ / `back-out-*`).
106
+ - **Attention seekers** (use `trigger="hover"` or `trigger="tap"`): `pulse`,
107
+ `rubber-band`, `shake-x`, `shake-y`, `head-shake`, `swing`, `tada`, `wobble`,
108
+ `jello`, `heart-beat`, `flash`, `bounce`, `scale-up`, `scale-down`.
109
+ - **Specials**: `hinge` (2s, origin top-left), `jack-in-the-box`, `roll`,
110
+ `roll-in`, `roll-out`.
111
+
112
+ ## Usage examples
113
+
114
+ ```html
115
+ <!-- Scroll-triggered fade-up (once) -->
116
+ <section
117
+ and-motion="fade-up"
118
+ and-motion-duration="700ms"
119
+ and-motion-delay="100ms"
120
+ >
121
+ <h2>Section title</h2>
122
+ </section>
123
+
124
+ <!-- Hover rubber-band attention seeker -->
125
+ <button and-motion="rubber-band" and-motion-trigger="hover">Click me</button>
126
+
127
+ <!-- Tap scale with spring easing -->
128
+ <div
129
+ and-motion="scale-up"
130
+ and-motion-trigger="tap"
131
+ and-motion-easing="cubic-bezier(0.34, 1.56, 0.64, 1)"
132
+ >
133
+ Card
134
+ </div>
135
+
136
+ <!-- Staggered list via delay -->
137
+ <ul>
138
+ <li and-motion="fade-in-up" and-motion-delay="0ms">Item 1</li>
139
+ <li and-motion="fade-in-up" and-motion-delay="100ms">Item 2</li>
140
+ <li and-motion="fade-in-up" and-motion-delay="200ms">Item 3</li>
141
+ </ul>
142
+ ```
143
+
144
+ ## Angular usage
145
+
146
+ ```ts
147
+ // app.config.ts or main.ts
148
+ import { initMotion } from '@andersseen/motion';
149
+ import '@andersseen/motion/style.css';
150
+
151
+ initMotion();
152
+ ```
153
+
154
+ For OnPush components with dynamic content, call `mc.scan()` after content
155
+ renders.
156
+
157
+ ## Rules
158
+
159
+ - Use `and-motion` attributes directly in HTML — no JS required for basic
160
+ animations.
161
+ - Use motion for meaningful feedback (entrance, hover affordance, tap
162
+ confirmation); avoid constant looping animations that distract from content.
163
+ - The experience must be usable without animation (reduced motion is handled
164
+ automatically).
165
+ - Call `cleanup()` / `destroy()` when unmounting SPA views to avoid listener
166
+ leaks.