Skip to content

Commit f1c9ed0

Browse files
feat: add transitions.dev plugin
Package the transitions-dev and transitions-polish skills as a standalone official plugin with upstream attribution and marketplace registration. Co-Authored-By: DotCraft <273930855+dotcraft-ai@users.noreply.github.com>
1 parent 7a48050 commit f1c9ed0

30 files changed

Lines changed: 3322 additions & 0 deletions

.craft/plugins/marketplace.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,18 @@
6464
},
6565
"category": "Design"
6666
},
67+
{
68+
"name": "transitions-dev",
69+
"source": {
70+
"source": "local",
71+
"path": "./plugins/transitions-dev"
72+
},
73+
"policy": {
74+
"installation": "AVAILABLE",
75+
"authentication": "ON_INSTALL"
76+
},
77+
"category": "Design"
78+
},
6779
{
6880
"name": "grill-me",
6981
"source": {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"schemaVersion": 1,
3+
"id": "transitions-dev",
4+
"version": "0.1.0",
5+
"displayName": "Transitions.dev",
6+
"description": "Production-ready CSS transitions and motion-polish guidance for web interfaces.",
7+
"capabilities": ["skill"],
8+
"skills": "./skills/",
9+
"author": {
10+
"name": "Jakub Antalik",
11+
"url": "https://github.com/Jakubantalik"
12+
},
13+
"homepage": "https://transitions.dev/",
14+
"repository": "https://github.com/Jakubantalik/transitions.dev",
15+
"keywords": [
16+
"transitions",
17+
"css",
18+
"motion",
19+
"animation",
20+
"frontend",
21+
"design"
22+
],
23+
"interface": {
24+
"displayName": "Transitions.dev",
25+
"shortDescription": "Add and polish production-ready web transitions.",
26+
"longDescription": "Transitions.dev provides portable CSS transition recipes for common interface patterns plus motion-token guidance for reviewing and polishing existing animations.",
27+
"developerName": "Jakub Antalik",
28+
"category": "Design",
29+
"capabilities": ["Skill", "Design", "Frontend", "Motion"],
30+
"defaultPrompt": "Use Transitions.dev to add the best-fit transition or polish the motion in this interface.",
31+
"websiteUrl": "https://transitions.dev/",
32+
"brandColor": "#FFFFFF",
33+
"composerIcon": "./assets/transitions-dev.png",
34+
"logo": "./assets/transitions-dev.png"
35+
}
36+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Transitions.dev
2+
3+
- Author: Jakub Antalik
4+
- Source: https://github.com/Jakubantalik/transitions.dev
5+
- Website: https://transitions.dev/
6+
- Imported revision: `5ad812dbbe1009ff51d1137dbea5d577f9135814`
3.49 KB
Loading
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Card resize
2+
3+
## When to use
4+
5+
Tweening a container's width or height when its layout state changes (compact ↔ expanded card, collapsing panel, list row toggling extra detail). Pure CSS — no JS required beyond the class toggle that drives the size change.
6+
7+
## HTML usage
8+
9+
```html
10+
<div class="t-resize">…</div>
11+
```
12+
13+
Put `.t-resize` on any element and change its width/height
14+
(directly, or via a state class such as `.is-small`). The
15+
transition will tween the two sizes.
16+
17+
## Tunable variables
18+
19+
| Variable | Default | Notes |
20+
| --- | --- | --- |
21+
| `--resize-dur` | `300ms` | sourced from `--p4-dur` |
22+
| `--resize-ease` | `cubic-bezier(0.22, 1, 0.36, 1)` | sourced from `--p4-ease` |
23+
24+
The `:root` defaults below match the live tuning on [transitions.dev](https://transitions.dev). Drop them into your global stylesheet once — every transition in this skill reads from semantic names like these, so multiple transitions can share a single `:root` block.
25+
26+
```css
27+
:root {
28+
--resize-dur: 300ms;
29+
--resize-ease: cubic-bezier(0.22, 1, 0.36, 1);
30+
}
31+
```
32+
33+
## CSS
34+
35+
```css
36+
.t-resize {
37+
transition:
38+
width var(--resize-dur) var(--resize-ease),
39+
height var(--resize-dur) var(--resize-ease);
40+
will-change: width, height;
41+
}
42+
43+
@media (prefers-reduced-motion: reduce) {
44+
.t-resize { transition: none !important; }
45+
}
46+
```
47+
48+
The `@media (prefers-reduced-motion: reduce)` guard at the bottom of the snippet is required — keep it. It zeroes the transition for users who have asked for less motion at the OS level.
49+
50+
## JavaScript orchestration
51+
52+
None — pure CSS. Toggle the documented HTML attributes or class names from whatever already drives state in your app.
53+
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# Number pop-in
2+
3+
## When to use
4+
5+
Counters, prices, balances, or any number that updates and should re-enter from a direction with blur. Each character animates independently and the last two digits stagger so decimals feel alive without looking chaotic.
6+
7+
## HTML usage
8+
9+
```html
10+
<span class="t-digit-group is-animating">
11+
<span class="t-digit">1</span>
12+
<span class="t-digit">2</span>
13+
<span class="t-digit" data-stagger="1">.</span>
14+
<span class="t-digit" data-stagger="2">3</span>
15+
</span>
16+
```
17+
18+
Replay:
19+
- Remove `.is-animating`, re-render digits (or swap text),
20+
force a reflow, then re-add `.is-animating`.
21+
- Use data-stagger="1", "2", … to delay individual
22+
digits by `n * var(--digit-stagger)`.
23+
24+
Direction:
25+
--digit-dir-x / --digit-dir-y are unit-less multipliers
26+
(e.g. 1, -1, 0) applied to --digit-distance.
27+
28+
## Tunable variables
29+
30+
| Variable | Default | Notes |
31+
| --- | --- | --- |
32+
| `--digit-dur` | `500ms` | sourced from `--p9-dur` |
33+
| `--digit-distance` | `8px` | sourced from `--p9-distance` |
34+
| `--digit-stagger` | `70ms` | sourced from `--p9-stagger` |
35+
| `--digit-blur` | `2px` | sourced from `--p9-blur` |
36+
| `--digit-ease` | `cubic-bezier(0.34, 1.45, 0.64, 1)` | sourced from `--p9-ease` |
37+
| `--digit-dir-x` | `0` | sourced from `--p9-dir-x` |
38+
| `--digit-dir-y` | `1` | sourced from `--p9-dir-y` |
39+
40+
The `:root` defaults below match the live tuning on [transitions.dev](https://transitions.dev). Drop them into your global stylesheet once — every transition in this skill reads from semantic names like these, so multiple transitions can share a single `:root` block.
41+
42+
```css
43+
:root {
44+
--digit-dur: 500ms;
45+
--digit-distance: 8px;
46+
--digit-stagger: 70ms;
47+
--digit-blur: 2px;
48+
--digit-ease: cubic-bezier(0.34, 1.45, 0.64, 1);
49+
--digit-dir-x: 0;
50+
--digit-dir-y: 1;
51+
}
52+
```
53+
54+
## CSS
55+
56+
```css
57+
@keyframes t-digit-pop-in {
58+
0% {
59+
transform: translate(
60+
calc(var(--digit-distance) * var(--digit-dir-x)),
61+
calc(var(--digit-distance) * var(--digit-dir-y))
62+
);
63+
opacity: 0;
64+
filter: blur(var(--digit-blur));
65+
}
66+
100% { transform: translate(0, 0); opacity: 1; filter: blur(0); }
67+
}
68+
69+
.t-digit-group {
70+
display: inline-flex;
71+
align-items: baseline;
72+
}
73+
.t-digit {
74+
display: inline-block;
75+
will-change: transform, opacity, filter;
76+
}
77+
.t-digit-group.is-animating .t-digit {
78+
animation: t-digit-pop-in var(--digit-dur) var(--digit-ease) both;
79+
}
80+
.t-digit-group.is-animating .t-digit[data-stagger="1"] {
81+
animation-delay: var(--digit-stagger);
82+
}
83+
.t-digit-group.is-animating .t-digit[data-stagger="2"] {
84+
animation-delay: calc(var(--digit-stagger) * 2);
85+
}
86+
87+
@media (prefers-reduced-motion: reduce) {
88+
.t-digit-group .t-digit { animation: none !important; }
89+
}
90+
```
91+
92+
The `@media (prefers-reduced-motion: reduce)` guard at the bottom of the snippet is required — keep it. It zeroes the transition for users who have asked for less motion at the OS level.
93+
94+
## JavaScript orchestration
95+
96+
```js
97+
// Replay the digit pop-in: remove .is-animating, swap the digit spans,
98+
// force a reflow, then re-add .is-animating. Mark the last two digits
99+
// with data-stagger="1" / "2" so they ride in 1× / 2× --digit-stagger
100+
// behind the leading digits.
101+
const group = document.querySelector(".t-digit-group");
102+
103+
function setDigits(str) {
104+
group.classList.remove("is-animating");
105+
group.replaceChildren();
106+
const chars = str.split("");
107+
chars.forEach((ch, i) => {
108+
const span = document.createElement("span");
109+
span.className = "t-digit";
110+
span.textContent = ch;
111+
if (i === chars.length - 2) span.dataset.stagger = "1";
112+
else if (i === chars.length - 1) span.dataset.stagger = "2";
113+
group.appendChild(span);
114+
});
115+
void group.offsetHeight; // force reflow
116+
group.classList.add("is-animating");
117+
}
118+
```
119+
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# Notification badge
2+
3+
## When to use
4+
5+
A small badge appearing on top of a trigger (bell, inbox, button). Slides in diagonally and pops the dot independently of the trigger so the trigger itself never moves.
6+
7+
## HTML usage
8+
9+
```html
10+
<!-- Place .t-badge inside your trigger (bell icon, button, etc.). -->
11+
<!-- The trigger must be position: relative so .t-badge can anchor to it. -->
12+
<button class="your-trigger" style="position: relative">
13+
<!-- your icon / trigger contents -->
14+
<span class="t-badge" data-open="false">
15+
<span class="t-badge-dot">1</span>
16+
</span>
17+
</button>
18+
```
19+
20+
State: toggle data-open="true" / "false" on .t-badge.
21+
Only the badge slides + pops — the trigger itself stays put.
22+
23+
## Tunable variables
24+
25+
| Variable | Default | Notes |
26+
| --- | --- | --- |
27+
| `--badge-slide-dur` | `260ms` | sourced from `--p1-pos-open-dur` |
28+
| `--badge-pop-dur` | `500ms` | sourced from `--p1-scale-open-dur` |
29+
| `--badge-pop-close-dur` | `180ms` | sourced from `--p1-scale-close-dur` |
30+
| `--badge-fade-dur` | `400ms` | sourced from `--p1-opacity-open-dur` |
31+
| `--badge-fade-close-dur` | `180ms` | sourced from `--p1-opacity-close-dur` |
32+
| `--badge-blur` | `2px` | sourced from `--p1-blur` |
33+
| `--badge-offset-x` | `-8.2px` | sourced from `--p1-distance-x` |
34+
| `--badge-offset-y` | `12.4px` | sourced from `--p1-distance-y` |
35+
| `--badge-slide-ease` | `cubic-bezier(0.22, 1, 0.36, 1)` | sourced from `--p1-ease-pos-open` |
36+
| `--badge-pop-ease` | `cubic-bezier(0.34, 1.36, 0.64, 1)` | sourced from `--p1-ease-scale-open` |
37+
| `--badge-close-ease` | `cubic-bezier(0.4, 0, 0.2, 1)` | sourced from `--p1-ease-close` |
38+
39+
The `:root` defaults below match the live tuning on [transitions.dev](https://transitions.dev). Drop them into your global stylesheet once — every transition in this skill reads from semantic names like these, so multiple transitions can share a single `:root` block.
40+
41+
```css
42+
:root {
43+
--badge-slide-dur: 260ms;
44+
--badge-pop-dur: 500ms;
45+
--badge-pop-close-dur: 180ms;
46+
--badge-fade-dur: 400ms;
47+
--badge-fade-close-dur: 180ms;
48+
--badge-blur: 2px;
49+
--badge-offset-x: -8.2px;
50+
--badge-offset-y: 12.4px;
51+
--badge-slide-ease: cubic-bezier(0.22, 1, 0.36, 1);
52+
--badge-pop-ease: cubic-bezier(0.34, 1.36, 0.64, 1);
53+
--badge-close-ease: cubic-bezier(0.4, 0, 0.2, 1);
54+
}
55+
```
56+
57+
## CSS
58+
59+
```css
60+
@keyframes t-badge-slide-in {
61+
from { transform: translate(var(--badge-offset-x), var(--badge-offset-y)); }
62+
to { transform: translate(0, 0); }
63+
}
64+
65+
/* .t-badge is the absolutely-positioned wrapper for the dot.
66+
Adjust top/right (or left/bottom) to anchor it on your trigger. */
67+
.t-badge {
68+
position: absolute;
69+
top: -6px;
70+
right: -8px;
71+
pointer-events: none;
72+
will-change: transform;
73+
}
74+
.t-badge[data-open="true"] {
75+
animation: t-badge-slide-in var(--badge-slide-dur) var(--badge-slide-ease);
76+
}
77+
78+
.t-badge-dot {
79+
display: block;
80+
transform-origin: center;
81+
transform: scale(1);
82+
opacity: 1;
83+
filter: blur(0);
84+
transition:
85+
transform var(--badge-pop-dur) var(--badge-pop-ease),
86+
opacity var(--badge-fade-dur) var(--badge-pop-ease),
87+
filter var(--badge-pop-dur) var(--badge-pop-ease);
88+
will-change: transform, opacity, filter;
89+
}
90+
.t-badge[data-open="false"] .t-badge-dot {
91+
transform: scale(0);
92+
opacity: 0;
93+
filter: blur(var(--badge-blur));
94+
transition:
95+
transform var(--badge-pop-close-dur) var(--badge-close-ease),
96+
opacity var(--badge-fade-close-dur) var(--badge-close-ease),
97+
filter var(--badge-pop-close-dur) var(--badge-close-ease);
98+
}
99+
100+
@media (prefers-reduced-motion: reduce) {
101+
.t-badge, .t-badge-dot { animation: none !important; transition: none !important; }
102+
}
103+
```
104+
105+
The `@media (prefers-reduced-motion: reduce)` guard at the bottom of the snippet is required — keep it. It zeroes the transition for users who have asked for less motion at the OS level.
106+
107+
## JavaScript orchestration
108+
109+
None — pure CSS. Toggle the documented HTML attributes or class names from whatever already drives state in your app.
110+

0 commit comments

Comments
 (0)