@convertex/skill 1.0.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/cli.mjs +103 -0
- package/package.json +29 -0
- package/skills/convertex/SKILL.md +330 -0
- package/skills/convertex/client-first/css/rules.md +102 -0
- package/skills/convertex/client-first/naming/conventions.md +92 -0
- package/skills/convertex/client-first/structure/page-skeleton.md +154 -0
- package/skills/convertex/client-first/utilities/buttons.md +170 -0
- package/skills/convertex/client-first/utilities/layout.md +89 -0
- package/skills/convertex/client-first/utilities/spacing.md +81 -0
- package/skills/convertex/client-first/utilities/typography.md +86 -0
- package/skills/convertex/css/best-practices.md +190 -0
- package/skills/convertex/elements/background-video.md +62 -0
- package/skills/convertex/elements/dropdown.md +49 -0
- package/skills/convertex/elements/forms.md +170 -0
- package/skills/convertex/elements/images.md +90 -0
- package/skills/convertex/elements/lightbox.md +61 -0
- package/skills/convertex/elements/links-buttons.md +96 -0
- package/skills/convertex/elements/navbar.md +100 -0
- package/skills/convertex/elements/slider.md +81 -0
- package/skills/convertex/elements/tabs.md +63 -0
- package/skills/convertex/patterns/ghost-blocks.md +94 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Links & Buttons
|
|
2
|
+
|
|
3
|
+
## The 3 Clickable Types in Webflow
|
|
4
|
+
|
|
5
|
+
| You want | Use this HTML | Result in Webflow |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| **Button** | `<button class="button">Click me</button>` | Button element (text only, no children) |
|
|
8
|
+
| **Link Block** (link with nested elements) | `<a href="/page" class="card">...<div>...</div>...</a>` | Link Block |
|
|
9
|
+
| **Text Link** (simple text link) | `<a href="/page" class="text-link">Click here</a>` | Text Link |
|
|
10
|
+
|
|
11
|
+
## How Tags Determine the Type
|
|
12
|
+
|
|
13
|
+
Detection is **tag-based**:
|
|
14
|
+
|
|
15
|
+
- `<button>` (without `type="submit"`) → **Button**
|
|
16
|
+
- `<a>` with child elements inside → **Link Block**
|
|
17
|
+
- `<a>` with text only → **Text Link**
|
|
18
|
+
|
|
19
|
+
**Key rule:** `<a class="button">` produces a **Link**, NOT a Button. To get a Webflow Button, use `<button>`.
|
|
20
|
+
|
|
21
|
+
## Button Patterns
|
|
22
|
+
|
|
23
|
+
**CRITICAL: `<button>` in Webflow is an atomic element — it CANNOT have children.** It only contains plain text. If you need a button with an icon or multiple child elements, use `<a>` (Link Block) instead.
|
|
24
|
+
|
|
25
|
+
### Standard button (text only)
|
|
26
|
+
```html
|
|
27
|
+
<button class="button">Get started</button>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Button with icon — use `<a>` Link Block
|
|
31
|
+
```html
|
|
32
|
+
<a href="/page" class="button">
|
|
33
|
+
<div class="button_text">Explore</div>
|
|
34
|
+
<div class="w-embed">
|
|
35
|
+
<svg class="button_icon" width="10" height="10" viewBox="0 0 10 10" fill="none" aria-hidden="true">
|
|
36
|
+
<path d="M1 5h8M5 1l4 4-4 4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
37
|
+
</svg>
|
|
38
|
+
</div>
|
|
39
|
+
</a>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Form submit (special case)
|
|
43
|
+
```html
|
|
44
|
+
<button type="submit" class="submit-button">Send</button>
|
|
45
|
+
<!-- or -->
|
|
46
|
+
<input type="submit" value="Send" class="submit-button" />
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`type="submit"` makes it a Form Button, not a regular Button.
|
|
50
|
+
|
|
51
|
+
## Link Block Patterns
|
|
52
|
+
|
|
53
|
+
### Card as link
|
|
54
|
+
```html
|
|
55
|
+
<a href="/project" class="project_card">
|
|
56
|
+
<img src="thumb.jpg" alt="Project" class="project_image" />
|
|
57
|
+
<h3 class="project_title">Project Name</h3>
|
|
58
|
+
<p class="project_desc">Brief description</p>
|
|
59
|
+
</a>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Link with icon
|
|
63
|
+
```html
|
|
64
|
+
<a href="/page" class="nav_link">
|
|
65
|
+
<div class="nav_link-text">About</div>
|
|
66
|
+
<div class="w-embed">
|
|
67
|
+
<svg class="nav_link-arrow" width="10" height="10" viewBox="0 0 10 10" fill="none" aria-hidden="true">
|
|
68
|
+
<path d="M1 5h8M5 1l4 4-4 4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
69
|
+
</svg>
|
|
70
|
+
</div>
|
|
71
|
+
</a>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Text Link Patterns
|
|
75
|
+
|
|
76
|
+
```html
|
|
77
|
+
<a href="/terms" class="text-link">Terms of service</a>
|
|
78
|
+
<a href="/privacy" class="footer_link">Privacy policy</a>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Best Practices
|
|
82
|
+
|
|
83
|
+
1. **Prefer Link Blocks over text links** when you need styling flexibility — a `<div>` child gives you independent control over text styling, padding, and icon placement.
|
|
84
|
+
|
|
85
|
+
2. **Always set `href`** on `<a>` elements — even `href="#"` is better than no href.
|
|
86
|
+
|
|
87
|
+
3. **`<button>` = text only, no children.** If you need an icon or nested elements, use `<a>` (Link Block) instead. `<button>` in Webflow is atomic.
|
|
88
|
+
|
|
89
|
+
4. **Link with text + icon** — always use `<div>` children, never `<span>`. Text in a `<div>`, icon SVG in a `<div class="w-embed">`:
|
|
90
|
+
```html
|
|
91
|
+
<a href="/page" class="button">
|
|
92
|
+
<div class="button_text">Download</div>
|
|
93
|
+
<div class="w-embed"><svg>...</svg></div>
|
|
94
|
+
</a>
|
|
95
|
+
```
|
|
96
|
+
**NEVER** place text directly inside `<a>` alongside a `w-embed`. **NEVER** use `<span>` inside links — always `<div>`. **NEVER** put children inside `<button>`.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Navbar
|
|
2
|
+
|
|
3
|
+
## Required Structure
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<div class="w-nav navbar"
|
|
7
|
+
data-animation="default"
|
|
8
|
+
data-collapse="medium"
|
|
9
|
+
data-duration="400"
|
|
10
|
+
data-easing="ease"
|
|
11
|
+
data-easing2="ease">
|
|
12
|
+
<div class="w-container nav-container">
|
|
13
|
+
<a href="/" class="w-nav-brand"><img src="logo.svg" alt="Logo" /></a>
|
|
14
|
+
<nav class="w-nav-menu nav-menu">
|
|
15
|
+
<a href="/about" class="w-nav-link nav-link">About</a>
|
|
16
|
+
<a href="/contact" class="w-nav-link nav-link">Contact</a>
|
|
17
|
+
</nav>
|
|
18
|
+
<div class="w-nav-button menu-button">
|
|
19
|
+
<div class="w-icon-nav-menu"></div>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Data Attributes
|
|
26
|
+
|
|
27
|
+
| Attribute | Default | Description |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| `data-animation` | `"default"` | Menu open/close animation type |
|
|
30
|
+
| `data-collapse` | `"none"` | Breakpoint where menu collapses to burger (`"medium"` = tablet) |
|
|
31
|
+
| `data-duration` | `400` | Animation duration (ms) |
|
|
32
|
+
| `data-easing` | `"ease"` | Open easing |
|
|
33
|
+
| `data-easing2` | `"ease"` | Close easing |
|
|
34
|
+
|
|
35
|
+
## Required Elements
|
|
36
|
+
|
|
37
|
+
### Root — `div.w-nav`
|
|
38
|
+
The outermost navbar wrapper. Must have the `w-nav` class.
|
|
39
|
+
|
|
40
|
+
### Container — `div.w-container`
|
|
41
|
+
Wraps all navbar content. Use `w-container` inside the navbar for proper layout.
|
|
42
|
+
|
|
43
|
+
### Brand — `a.w-nav-brand`
|
|
44
|
+
Logo/brand link. Typically contains an `<img>` or text.
|
|
45
|
+
|
|
46
|
+
```html
|
|
47
|
+
<a href="/" class="w-nav-brand">
|
|
48
|
+
<img src="logo.svg" alt="Company" class="brand-logo" />
|
|
49
|
+
</a>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Menu — `nav.w-nav-menu`
|
|
53
|
+
Contains all navigation links. Collapses into burger on mobile.
|
|
54
|
+
|
|
55
|
+
```html
|
|
56
|
+
<nav class="w-nav-menu nav-menu">
|
|
57
|
+
<a href="/about" class="w-nav-link">About</a>
|
|
58
|
+
<a href="/services" class="w-nav-link">Services</a>
|
|
59
|
+
</nav>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Nav Links — `a.w-nav-link`
|
|
63
|
+
Individual navigation links inside the menu. The active link gets the `w--current` class:
|
|
64
|
+
|
|
65
|
+
```html
|
|
66
|
+
<a href="/about" class="w-nav-link nav-link w--current">About</a>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Menu Button — `div.w-nav-button`
|
|
70
|
+
The hamburger/burger button for mobile. Contains the menu icon.
|
|
71
|
+
|
|
72
|
+
```html
|
|
73
|
+
<div class="w-nav-button menu-button">
|
|
74
|
+
<div class="w-icon-nav-menu"></div>
|
|
75
|
+
</div>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Menu Icon — `div.w-icon-nav-menu`
|
|
79
|
+
The hamburger icon inside the menu button. Renders Webflow's default burger icon.
|
|
80
|
+
|
|
81
|
+
## Dropdown Inside Navbar
|
|
82
|
+
|
|
83
|
+
Dropdowns are fully supported inside the navbar menu. See `elements/dropdown.md` for the structure.
|
|
84
|
+
|
|
85
|
+
```html
|
|
86
|
+
<nav class="w-nav-menu nav-menu">
|
|
87
|
+
<a href="/about" class="w-nav-link">About</a>
|
|
88
|
+
<div class="w-dropdown" data-hover="true" data-delay="0">
|
|
89
|
+
<div class="w-dropdown-toggle">
|
|
90
|
+
<div class="w-icon-dropdown-toggle"></div>
|
|
91
|
+
<div>Services</div>
|
|
92
|
+
</div>
|
|
93
|
+
<nav class="w-dropdown-list">
|
|
94
|
+
<a href="/web" class="w-dropdown-link">Web Design</a>
|
|
95
|
+
<a href="/app" class="w-dropdown-link">App Dev</a>
|
|
96
|
+
</nav>
|
|
97
|
+
</div>
|
|
98
|
+
<a href="/contact" class="w-nav-link">Contact</a>
|
|
99
|
+
</nav>
|
|
100
|
+
```
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Slider
|
|
2
|
+
|
|
3
|
+
## Required Structure
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<div class="w-slider hero-slider"
|
|
7
|
+
data-animation="slide"
|
|
8
|
+
data-duration="500"
|
|
9
|
+
data-infinite="true"
|
|
10
|
+
data-easing="ease"
|
|
11
|
+
data-autoplay="false"
|
|
12
|
+
data-delay="4000"
|
|
13
|
+
data-hide-arrows="false">
|
|
14
|
+
<div class="w-slider-mask">
|
|
15
|
+
<div class="w-slide slide-1">Slide 1 content</div>
|
|
16
|
+
<div class="w-slide slide-2">Slide 2 content</div>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="w-slider-arrow-left"><div class="w-icon-slider-left"></div></div>
|
|
19
|
+
<div class="w-slider-arrow-right"><div class="w-icon-slider-right"></div></div>
|
|
20
|
+
<div class="w-slider-nav"></div>
|
|
21
|
+
</div>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Data Attributes
|
|
25
|
+
|
|
26
|
+
| Attribute | Default | Description |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| `data-animation` | `"slide"` | Animation type |
|
|
29
|
+
| `data-duration` | `500` | Transition duration (ms) |
|
|
30
|
+
| `data-infinite` | `"true"` | Loop slides |
|
|
31
|
+
| `data-easing` | `"ease"` | Easing function |
|
|
32
|
+
| `data-disable-swipe` | `"false"` | Disable touch swipe |
|
|
33
|
+
| `data-autoplay` | `"false"` | Auto-advance slides |
|
|
34
|
+
| `data-delay` | `4000` | Autoplay delay (ms) |
|
|
35
|
+
| `data-autoplay-limit` | `0` | Max autoplay cycles (0 = infinite) |
|
|
36
|
+
| `data-hide-arrows` | `"false"` | Hide navigation arrows |
|
|
37
|
+
| `data-nav-spacing` | `3` | Dot nav spacing (px) |
|
|
38
|
+
|
|
39
|
+
## Required Elements
|
|
40
|
+
|
|
41
|
+
### Wrapper — `div.w-slider`
|
|
42
|
+
Root element with all data attributes.
|
|
43
|
+
|
|
44
|
+
### Mask — `div.w-slider-mask`
|
|
45
|
+
Contains all slides. Only children with `w-slide` class are treated as slides.
|
|
46
|
+
|
|
47
|
+
### Slide — `div.w-slide`
|
|
48
|
+
Individual slides. Put any content inside.
|
|
49
|
+
|
|
50
|
+
### Arrows — `div.w-slider-arrow-left` / `div.w-slider-arrow-right`
|
|
51
|
+
Navigation arrows. Each contains an icon element:
|
|
52
|
+
|
|
53
|
+
```html
|
|
54
|
+
<div class="w-slider-arrow-left"><div class="w-icon-slider-left"></div></div>
|
|
55
|
+
<div class="w-slider-arrow-right"><div class="w-icon-slider-right"></div></div>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Dot Nav — `div.w-slider-nav`
|
|
59
|
+
Dot-style pagination. Empty element — dots are auto-generated.
|
|
60
|
+
|
|
61
|
+
## Minimal Example
|
|
62
|
+
|
|
63
|
+
If default data attributes are fine, you can simplify:
|
|
64
|
+
|
|
65
|
+
```html
|
|
66
|
+
<div class="w-slider hero-slider">
|
|
67
|
+
<div class="w-slider-mask">
|
|
68
|
+
<div class="w-slide">
|
|
69
|
+
<h2>First Slide</h2>
|
|
70
|
+
<p>Description here</p>
|
|
71
|
+
</div>
|
|
72
|
+
<div class="w-slide">
|
|
73
|
+
<h2>Second Slide</h2>
|
|
74
|
+
<p>Another slide</p>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
<div class="w-slider-arrow-left"><div class="w-icon-slider-left"></div></div>
|
|
78
|
+
<div class="w-slider-arrow-right"><div class="w-icon-slider-right"></div></div>
|
|
79
|
+
<div class="w-slider-nav"></div>
|
|
80
|
+
</div>
|
|
81
|
+
```
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Tabs
|
|
2
|
+
|
|
3
|
+
## Required Structure
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<div class="w-tabs" data-current="Tab 1" data-duration-in="300" data-duration-out="100" data-easing="">
|
|
7
|
+
<div class="w-tab-menu">
|
|
8
|
+
<a class="w-tab-link w--current" data-w-tab="Tab 1">Tab 1</a>
|
|
9
|
+
<a class="w-tab-link" data-w-tab="Tab 2">Tab 2</a>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="w-tab-content">
|
|
12
|
+
<div class="w-tab-pane w--tab-active" data-w-tab="Tab 1">Content 1</div>
|
|
13
|
+
<div class="w-tab-pane" data-w-tab="Tab 2">Content 2</div>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Data Attributes
|
|
19
|
+
|
|
20
|
+
| Attribute | Default | Description |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| `data-current` | `""` | Name of the active tab (must match a `data-w-tab` value) |
|
|
23
|
+
| `data-easing` | `""` | Easing function (`"ease"`, `"ease-in"`, `"ease-out"`, `"ease-in-out"`) |
|
|
24
|
+
| `data-duration-in` | `300` | Fade-in duration (ms) |
|
|
25
|
+
| `data-duration-out` | `100` | Fade-out duration (ms) |
|
|
26
|
+
|
|
27
|
+
## Required Elements
|
|
28
|
+
|
|
29
|
+
### Wrapper — `div.w-tabs`
|
|
30
|
+
Root element with data attributes.
|
|
31
|
+
|
|
32
|
+
### Menu — `div.w-tab-menu`
|
|
33
|
+
Contains the tab triggers.
|
|
34
|
+
|
|
35
|
+
### Tab Link — `a.w-tab-link`
|
|
36
|
+
Individual tab trigger. **Must have `data-w-tab` matching its corresponding pane.**
|
|
37
|
+
|
|
38
|
+
The active tab link gets the `w--current` class.
|
|
39
|
+
|
|
40
|
+
### Content — `div.w-tab-content`
|
|
41
|
+
Contains all tab panes.
|
|
42
|
+
|
|
43
|
+
### Tab Pane — `div.w-tab-pane`
|
|
44
|
+
Individual tab content. **Must have `data-w-tab` matching its corresponding link.**
|
|
45
|
+
|
|
46
|
+
The active pane gets the `w--tab-active` class.
|
|
47
|
+
|
|
48
|
+
## Critical: Matching Rule
|
|
49
|
+
|
|
50
|
+
`data-w-tab` on the link **must exactly match** `data-w-tab` on the pane:
|
|
51
|
+
|
|
52
|
+
```html
|
|
53
|
+
<a class="w-tab-link" data-w-tab="Pricing">Pricing</a>
|
|
54
|
+
<!-- ... -->
|
|
55
|
+
<div class="w-tab-pane" data-w-tab="Pricing">Pricing content here</div>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Active State Classes
|
|
59
|
+
|
|
60
|
+
- `w--current` on the active tab link
|
|
61
|
+
- `w--tab-active` on the active tab pane
|
|
62
|
+
|
|
63
|
+
These are Webflow system classes. Only one tab should be active at a time.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Ghost Blocks — Dynamic States & Custom Code
|
|
2
|
+
|
|
3
|
+
## What Are Ghost Blocks?
|
|
4
|
+
|
|
5
|
+
Ghost blocks are `<div class="w-embed">` elements containing `<style>` tags for CSS that Webflow doesn't support natively (pseudo-elements, descendant selectors, keyframes). They're also used for raw HTML/SVG embeds.
|
|
6
|
+
|
|
7
|
+
## Dynamic Combo Classes
|
|
8
|
+
|
|
9
|
+
Define combo class styles in CSS to control element states. The base class must exist on an element in the HTML:
|
|
10
|
+
|
|
11
|
+
```css
|
|
12
|
+
/* Base: fully visible (editable in Webflow Designer) */
|
|
13
|
+
.modal_overlay {
|
|
14
|
+
position: fixed;
|
|
15
|
+
top: 0;
|
|
16
|
+
left: 0;
|
|
17
|
+
width: 100%;
|
|
18
|
+
height: 100%;
|
|
19
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
20
|
+
transition: opacity 0.3s ease, visibility 0.3s ease;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/* Combo: active state (toggled by JS) */
|
|
24
|
+
.modal_overlay.is-active {
|
|
25
|
+
opacity: 1;
|
|
26
|
+
visibility: visible;
|
|
27
|
+
pointer-events: auto;
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## CRITICAL: Initial Hidden States in JS, NOT CSS
|
|
32
|
+
|
|
33
|
+
All elements must be visible by default in Webflow Designer. This is essential for editing.
|
|
34
|
+
|
|
35
|
+
**NEVER set these in base CSS:**
|
|
36
|
+
- `display: none`
|
|
37
|
+
- `opacity: 0`
|
|
38
|
+
- `visibility: hidden`
|
|
39
|
+
- `height: 0`
|
|
40
|
+
|
|
41
|
+
**ALWAYS set initial hidden states via JavaScript:**
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
45
|
+
document.querySelectorAll('.modal_overlay').forEach(function(el) {
|
|
46
|
+
el.style.opacity = '0';
|
|
47
|
+
el.style.visibility = 'hidden';
|
|
48
|
+
el.style.pointerEvents = 'none';
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## CSS Transitions over JS Animations
|
|
54
|
+
|
|
55
|
+
Use CSS `transition` on the base class. JavaScript only toggles the class:
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
trigger.addEventListener('click', function() {
|
|
59
|
+
menu.classList.toggle('is-open');
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Only use JS animation libraries (GSAP) for: staggered animations, scroll-triggered effects, complex timelines, physics-based motion.
|
|
64
|
+
|
|
65
|
+
## Ghost Block for Unsupported CSS
|
|
66
|
+
|
|
67
|
+
When you need CSS that Webflow doesn't support natively (nth-child, keyframes), add a ghost block embed in the HTML.
|
|
68
|
+
|
|
69
|
+
**FORBIDDEN:** `::before` and `::after` are **never allowed**, even in ghost blocks. They are poorly supported by Webflow and not manageable in the Designer. Always use a real HTML element instead (e.g. a `<div>` with a class for decorative elements, underlines, icons, or separators).
|
|
70
|
+
|
|
71
|
+
```html
|
|
72
|
+
<!-- Ghost block for keyframe animation -->
|
|
73
|
+
<div class="w-embed">
|
|
74
|
+
<style>
|
|
75
|
+
@keyframes pulse {
|
|
76
|
+
0%, 100% { opacity: 1; }
|
|
77
|
+
50% { opacity: 0.5; }
|
|
78
|
+
}
|
|
79
|
+
.status_dot { animation: pulse 2s ease-in-out infinite; }
|
|
80
|
+
</style>
|
|
81
|
+
</div>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Common Use Cases
|
|
85
|
+
|
|
86
|
+
| Pattern | Approach |
|
|
87
|
+
|---|---|
|
|
88
|
+
| Modal / dialog | Base visible, JS hides on load, `.is-open` combo shows |
|
|
89
|
+
| Mobile menu | Same pattern as modal |
|
|
90
|
+
| Dropdown mega menu | `.is-open` combo on the menu panel |
|
|
91
|
+
| Accordion | `.is-open` combo on the content panel |
|
|
92
|
+
| Toast notifications | JS creates and adds `.is-visible` combo |
|
|
93
|
+
| Tab underline animation | CSS transition on position/width with combo class |
|
|
94
|
+
| Hover card effects | `:hover` pseudo (natively supported) + `transition` |
|