@wix/agent-skills 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/LICENSE +21 -0
- package/README.md +111 -0
- package/package.json +29 -0
- package/skills/wix-app/SKILL.md +344 -0
- package/skills/wix-app/references/APP_IDENTIFIERS.md +35 -0
- package/skills/wix-app/references/APP_MARKET_REVIEW.md +311 -0
- package/skills/wix-app/references/APP_VALIDATION.md +171 -0
- package/skills/wix-app/references/BACKEND_API.md +233 -0
- package/skills/wix-app/references/BACKEND_EVENT.md +116 -0
- package/skills/wix-app/references/CODE_QUALITY.md +33 -0
- package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +587 -0
- package/skills/wix-app/references/DASHBOARD_MENU_PLUGIN.md +157 -0
- package/skills/wix-app/references/DASHBOARD_MODAL.md +283 -0
- package/skills/wix-app/references/DASHBOARD_PAGE.md +403 -0
- package/skills/wix-app/references/DASHBOARD_PLUGIN.md +205 -0
- package/skills/wix-app/references/DATA_COLLECTION.md +451 -0
- package/skills/wix-app/references/DOCUMENTATION.md +42 -0
- package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +65 -0
- package/skills/wix-app/references/EMBEDDED_SCRIPT.md +468 -0
- package/skills/wix-app/references/EXTENSION_REGISTRATION.md +96 -0
- package/skills/wix-app/references/SERVICE_PLUGIN.md +235 -0
- package/skills/wix-app/references/SITE_PLUGIN.md +436 -0
- package/skills/wix-app/references/STORES_VERSIONING.md +334 -0
- package/skills/wix-app/references/backend-event/COMMON-EVENTS.md +84 -0
- package/skills/wix-app/references/custom-element-widget/SETTINGS_PANEL.md +345 -0
- package/skills/wix-app/references/dashboard-menu-plugin/blog-slots.md +71 -0
- package/skills/wix-app/references/dashboard-menu-plugin/bookings-slots.md +58 -0
- package/skills/wix-app/references/dashboard-menu-plugin/crm-slots.md +8 -0
- package/skills/wix-app/references/dashboard-menu-plugin/ecommerce-slots.md +17 -0
- package/skills/wix-app/references/dashboard-menu-plugin/events-slots.md +29 -0
- package/skills/wix-app/references/dashboard-menu-plugin/restaurants-slots.md +27 -0
- package/skills/wix-app/references/dashboard-menu-plugin/stores-slots.md +35 -0
- package/skills/wix-app/references/dashboard-page/API_SPEC.md +138 -0
- package/skills/wix-app/references/dashboard-page/DASHBOARD_API.md +573 -0
- package/skills/wix-app/references/dashboard-page/DYNAMIC_PARAMETERS.md +269 -0
- package/skills/wix-app/references/dashboard-page/ECOM_NAVIGATION.md +164 -0
- package/skills/wix-app/references/dashboard-plugin/SLOTS.md +294 -0
- package/skills/wix-app/references/data-collection/WIX_DATA.md +270 -0
- package/skills/wix-app/references/data-collection/extension-template.ts +107 -0
- package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +138 -0
- package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +454 -0
- package/skills/wix-app/references/editor-react-component/COMPONENT-CONFIGURATION.md +165 -0
- package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +576 -0
- package/skills/wix-app/references/editor-react-component/DIRECTIONALITY.md +170 -0
- package/skills/wix-app/references/editor-react-component/EDIT-FLOW.md +6 -0
- package/skills/wix-app/references/editor-react-component/PARTS.md +25 -0
- package/skills/wix-app/references/editor-react-component/PROPS-VS-CSS.md +203 -0
- package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +167 -0
- package/skills/wix-app/references/editor-react-component/REACT-PATTERNS.md +137 -0
- package/skills/wix-app/references/service-plugin/ADDITIONAL-FEES.md +112 -0
- package/skills/wix-app/references/service-plugin/BOOKINGS-STAFF-SORTING.md +118 -0
- package/skills/wix-app/references/service-plugin/DISCOUNT-TRIGGERS.md +87 -0
- package/skills/wix-app/references/service-plugin/GIFT-CARDS.md +86 -0
- package/skills/wix-app/references/service-plugin/PAYMENT-SETTINGS.md +135 -0
- package/skills/wix-app/references/service-plugin/SHIPPING-RATES.md +79 -0
- package/skills/wix-app/references/service-plugin/VALIDATIONS.md +68 -0
- package/skills/wix-app/references/site-plugin/EXAMPLES.md +311 -0
- package/skills/wix-app/references/site-plugin/SLOTS.md +263 -0
- package/skills/wix-design-system/SKILL.md +129 -0
- package/skills/wix-design-system/references/file-structure.md +56 -0
- package/skills/wix-design-system/scripts/wds.cjs +531 -0
- package/skills/wix-headless/SKILL.md +418 -0
- package/skills/wix-headless/references/DISCOVERY.md +332 -0
- package/skills/wix-headless/references/ORCHESTRATION.md +269 -0
- package/skills/wix-headless/references/SETUP.md +154 -0
- package/skills/wix-headless/references/blog/BLOG_CONTENT.md +152 -0
- package/skills/wix-headless/references/blog/BLOG_PAGES.md +299 -0
- package/skills/wix-headless/references/blog/BLOG_SETUP.md +218 -0
- package/skills/wix-headless/references/blog/INSTRUCTIONS.md +32 -0
- package/skills/wix-headless/references/cms/CMS_FOUNDATIONS.md +373 -0
- package/skills/wix-headless/references/cms/FAQ_KNOWLEDGE_BASE.md +229 -0
- package/skills/wix-headless/references/cms/INSTRUCTIONS.md +40 -0
- package/skills/wix-headless/references/cms/PORTFOLIO.md +454 -0
- package/skills/wix-headless/references/cms/RESOURCE_LIBRARY.md +356 -0
- package/skills/wix-headless/references/cms/TEAM_DIRECTORY.md +299 -0
- package/skills/wix-headless/references/commands/install-app.md +42 -0
- package/skills/wix-headless/references/commands/known-apps.json +5 -0
- package/skills/wix-headless/references/commands/mcp-bootstrap.md +28 -0
- package/skills/wix-headless/references/designer/INSTRUCTIONS.md +828 -0
- package/skills/wix-headless/references/ecom/CART_PAGES.md +120 -0
- package/skills/wix-headless/references/ecom/CART_WIRING.md +103 -0
- package/skills/wix-headless/references/ecom/COMPONENTS_CSS.md +132 -0
- package/skills/wix-headless/references/ecom/INSTRUCTIONS.md +59 -0
- package/skills/wix-headless/references/forms/CONTACT_FORM.md +477 -0
- package/skills/wix-headless/references/forms/INSTRUCTIONS.md +43 -0
- package/skills/wix-headless/references/gift-cards/COMPONENTS.md +119 -0
- package/skills/wix-headless/references/gift-cards/INSTRUCTIONS.md +51 -0
- package/skills/wix-headless/references/gift-cards/PAGES.md +129 -0
- package/skills/wix-headless/references/images/INSTRUCTIONS.md +359 -0
- package/skills/wix-headless/references/shared/BUILD_NOISE.md +8 -0
- package/skills/wix-headless/references/shared/IMAGE_GENERATION.md +185 -0
- package/skills/wix-headless/references/shared/IMPLEMENTER.md +155 -0
- package/skills/wix-headless/references/shared/MCP_PREFIX.md +105 -0
- package/skills/wix-headless/references/shared/PRODUCTION_SHARP_EDGES.md +97 -0
- package/skills/wix-headless/references/shared/RETURN_CONTRACT.md +423 -0
- package/skills/wix-headless/references/shared/STYLING.md +117 -0
- package/skills/wix-headless/references/stores/BACK_IN_STOCK.md +178 -0
- package/skills/wix-headless/references/stores/CATEGORY_PAGES.md +86 -0
- package/skills/wix-headless/references/stores/COMPONENTS_CSS.md +129 -0
- package/skills/wix-headless/references/stores/HOME_AND_NAV.md +227 -0
- package/skills/wix-headless/references/stores/INSTRUCTIONS.md +96 -0
- package/skills/wix-headless/references/stores/PRODUCT_CATALOG_DATA.md +249 -0
- package/skills/wix-headless/references/stores/PRODUCT_PAGES.md +213 -0
- package/skills/wix-headless/references/stores/SHARED_WIRING.md +164 -0
- package/skills/wix-headless/references/verticals/_schema.json +160 -0
- package/skills/wix-headless/references/verticals/_schema.md +185 -0
- package/skills/wix-headless/references/verticals/blog.md +125 -0
- package/skills/wix-headless/references/verticals/cms.md +121 -0
- package/skills/wix-headless/references/verticals/ecom.md +96 -0
- package/skills/wix-headless/references/verticals/forms.md +106 -0
- package/skills/wix-headless/references/verticals/gift-cards.md +121 -0
- package/skills/wix-headless/references/verticals/stores.md +167 -0
- package/skills/wix-headless/scripts/check-manifest.mjs +198 -0
- package/skills/wix-headless/scripts/copy-utility-templates.mjs +153 -0
- package/skills/wix-headless/scripts/emit-design-tokens.mjs +77 -0
- package/skills/wix-headless/scripts/finalize-run-json.mjs +141 -0
- package/skills/wix-headless/scripts/init-site-json.mjs +63 -0
- package/skills/wix-headless/scripts/patch-decorative-slots.mjs +124 -0
- package/skills/wix-headless/scripts/plan-entity-image-waves.mjs +190 -0
- package/skills/wix-headless/scripts/preview.sh +45 -0
- package/skills/wix-headless/scripts/release.sh +73 -0
- package/skills/wix-headless/scripts/scaffold.sh +53 -0
- package/skills/wix-headless/scripts/seed-utilities.sh +55 -0
- package/skills/wix-headless/shared-utilities/analytics.ts +40 -0
- package/skills/wix-headless/shared-utilities/ricos.ts +179 -0
- package/skills/wix-headless/shared-utilities/wix-image.ts +72 -0
- package/skills/wix-headless/templates/ecom/CartBadge.tsx +84 -0
- package/skills/wix-headless/templates/ecom/CartView.tsx +543 -0
- package/skills/wix-headless/templates/ecom/cart.astro +13 -0
- package/skills/wix-headless/templates/ecom/components-ecom.css +215 -0
- package/skills/wix-headless/templates/ecom/discounts.ts +71 -0
- package/skills/wix-headless/templates/ecom/thank-you.astro +24 -0
- package/skills/wix-headless/templates/gift-cards/GiftCardPurchase.tsx +172 -0
- package/skills/wix-headless/templates/gift-cards/_home-teaser-snippet.astro +42 -0
- package/skills/wix-headless/templates/gift-cards/_nav-snippet.astro +11 -0
- package/skills/wix-headless/templates/gift-cards/components-gift-cards.css +219 -0
- package/skills/wix-headless/templates/gift-cards/gift-cards.astro +51 -0
- package/skills/wix-headless/templates/gift-cards/gift-cards.ts +75 -0
- package/skills/wix-headless/templates/stores/AddToCartButton.tsx +77 -0
- package/skills/wix-headless/templates/stores/BackInStockForm.tsx +176 -0
- package/skills/wix-headless/templates/stores/CategoryRail.astro +69 -0
- package/skills/wix-headless/templates/stores/ProductCard.astro +79 -0
- package/skills/wix-headless/templates/stores/ProductPurchase.tsx +397 -0
- package/skills/wix-headless/templates/stores/SeoTags.astro +21 -0
- package/skills/wix-headless/templates/stores/back-in-stock.ts +67 -0
- package/skills/wix-headless/templates/stores/categories.ts +155 -0
- package/skills/wix-headless/templates/stores/category/[slug].astro +130 -0
- package/skills/wix-headless/templates/stores/components-stores.css +295 -0
- package/skills/wix-headless/templates/stores/products/[slug].astro +128 -0
- package/skills/wix-headless/templates/stores/products/index.astro +101 -0
- package/skills/wix-manage/SKILL.md +280 -0
- package/skills/wix-manage/references/app-installation/install-wix-apps.md +155 -0
- package/skills/wix-manage/references/app-installation/list-installed-apps.md +124 -0
- package/skills/wix-manage/references/blog/how-to-create-blog-posts.md +226 -0
- package/skills/wix-manage/references/bookings/booking-service-policy-setup.md +95 -0
- package/skills/wix-manage/references/bookings/booking-system-integration-gaps.md +416 -0
- package/skills/wix-manage/references/bookings/bookings-staff-setup.md +255 -0
- package/skills/wix-manage/references/bookings/create-and-update-booking-services.md +462 -0
- package/skills/wix-manage/references/bookings/end-to-end-booking-flow.md +278 -0
- package/skills/wix-manage/references/bookings/external-calendar-integration.md +258 -0
- package/skills/wix-manage/references/bookings/multi-resource-service-creation.md +231 -0
- package/skills/wix-manage/references/calendar/configure-default-business-hours.md +226 -0
- package/skills/wix-manage/references/cms/cms-data-items-crud.md +422 -0
- package/skills/wix-manage/references/cms/cms-data-operations-extended.md +263 -0
- package/skills/wix-manage/references/cms/cms-ecommerce-catalog-integration.md +136 -0
- package/skills/wix-manage/references/cms/cms-references-and-relationships.md +160 -0
- package/skills/wix-manage/references/cms/cms-schema-management.md +143 -0
- package/skills/wix-manage/references/contacts/bulk-delete-contacts.md +73 -0
- package/skills/wix-manage/references/contacts/bulk-label-and-unlabel-contacts.md +67 -0
- package/skills/wix-manage/references/domains/domain-search-and-purchase.md +434 -0
- package/skills/wix-manage/references/ecommerce/api-recommendation-tracking.md +420 -0
- package/skills/wix-manage/references/ecommerce/flow-add-free-shipping.md +267 -0
- package/skills/wix-manage/references/ecommerce/flow-bundle-and-save.md +290 -0
- package/skills/wix-manage/references/ecommerce/flow-fix-coverage-gaps.md +300 -0
- package/skills/wix-manage/references/ecommerce/flow-optimize-shipping-rates.md +364 -0
- package/skills/wix-manage/references/ecommerce/flow-seasonal-promotion.md +315 -0
- package/skills/wix-manage/references/ecommerce/flow-stock-mover.md +308 -0
- package/skills/wix-manage/references/ecommerce/flow-upsell-boost.md +271 -0
- package/skills/wix-manage/references/ecommerce/goal-clear-inventory.md +118 -0
- package/skills/wix-manage/references/ecommerce/goal-drive-cross-sells.md +122 -0
- package/skills/wix-manage/references/ecommerce/goal-increase-aov.md +132 -0
- package/skills/wix-manage/references/ecommerce/goal-reduce-cart-abandonment.md +148 -0
- package/skills/wix-manage/references/ecommerce/goal-seasonal-revenue.md +146 -0
- package/skills/wix-manage/references/ecommerce/guardrail-discount-conflicts.md +118 -0
- package/skills/wix-manage/references/ecommerce/guardrail-margin-protection.md +88 -0
- package/skills/wix-manage/references/ecommerce/guardrail-rate-pricing-sanity.md +108 -0
- package/skills/wix-manage/references/ecommerce/guardrail-shipping-health.md +124 -0
- package/skills/wix-manage/references/ecommerce/recipe-apply-shipping-recommendations.md +299 -0
- package/skills/wix-manage/references/ecommerce/recommend-ecommerce-strategy.md +582 -0
- package/skills/wix-manage/references/ecommerce/setup-coupons.md +338 -0
- package/skills/wix-manage/references/ecommerce/setup-discount-rules.md +444 -0
- package/skills/wix-manage/references/ecommerce/setup-shipping-rates.md +86 -0
- package/skills/wix-manage/references/ecommerce/setup-shipping-regions.md +56 -0
- package/skills/wix-manage/references/ecommerce/setup-store-pickup-location.md +209 -0
- package/skills/wix-manage/references/ecommerce/skill-graph.md +139 -0
- package/skills/wix-manage/references/ecommerce/troubleshoot-checkout-delivery-dropoff.md +124 -0
- package/skills/wix-manage/references/ecommerce/troubleshoot-discount-not-applying.md +95 -0
- package/skills/wix-manage/references/events/list-events.md +203 -0
- package/skills/wix-manage/references/forms/create-form.md +260 -0
- package/skills/wix-manage/references/get-paid/create-payment-links.md +212 -0
- package/skills/wix-manage/references/get-paid/how-to-setup-wix-payments.md +57 -0
- package/skills/wix-manage/references/get-paid/payment-links-for-bookings.md +101 -0
- package/skills/wix-manage/references/media/upload-media-to-wix.md +216 -0
- package/skills/wix-manage/references/pricing-plans/create-and-update-pricing-plans.md +77 -0
- package/skills/wix-manage/references/pricing-plans/pricing-plans-bookings-integration.md +166 -0
- package/skills/wix-manage/references/restaurants/wix-restaurants-setup.md +336 -0
- package/skills/wix-manage/references/rich-content/ricos-converter-service.md +295 -0
- package/skills/wix-manage/references/site-properties/change-payment-currency-site-properties.md +59 -0
- package/skills/wix-manage/references/sites/create-site-from-template.md +183 -0
- package/skills/wix-manage/references/sites/query-sites.md +125 -0
- package/skills/wix-manage/references/stores/add-store-pages-to-site.md +57 -0
- package/skills/wix-manage/references/stores/bulk-create-products-with-options.md +1041 -0
- package/skills/wix-manage/references/stores/create-product-catalog-v1.md +125 -0
- package/skills/wix-manage/references/stores/create-product-from-image.md +824 -0
- package/skills/wix-manage/references/stores/create-product-with-options-catalog-v3.md +566 -0
- package/skills/wix-manage/references/stores/find-products-query-and-search-catalog-v3.md +194 -0
- package/skills/wix-manage/references/stores/query-products-catalog-v1.md +80 -0
- package/skills/wix-manage/references/stores/setup-online-store-catalog-v3.md +99 -0
- package/skills/wix-manage/references/stores/update-product-pre-order.md +213 -0
- package/skills/wix-manage/references/stores/update-product-with-options.md +318 -0
|
@@ -0,0 +1,576 @@
|
|
|
1
|
+
# CSS guidelines
|
|
2
|
+
|
|
3
|
+
These rules govern the CSS authored for each generated site
|
|
4
|
+
component. The rules exist so the rendered component is editable in
|
|
5
|
+
the Wix visual editor, fits any user-resizable container, and can be
|
|
6
|
+
parsed by zeroConfig to produce a correct manifest. Each rule states
|
|
7
|
+
_why_; when an edge case isn't covered literally, follow the intent.
|
|
8
|
+
|
|
9
|
+
## Naming and class application
|
|
10
|
+
|
|
11
|
+
### Apply classes via the `classnames` helper; merge `className` on the root
|
|
12
|
+
|
|
13
|
+
All CSS lives in a single CSS module file imported as `import styles from './[ComponentName].module.css';`. There is no separate global CSS import.
|
|
14
|
+
|
|
15
|
+
There are two kinds of classes, determined by whether the element is a named part:
|
|
16
|
+
|
|
17
|
+
| Element type | className | Why |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| Named part | `classNames('heading', styles.heading)` | Global string → zeroConfig creates an editor element; module class → applies the component's own CSS |
|
|
20
|
+
| Non-part (layout/structural) | `styles.contentWrapper` | Module class only — invisible to zeroConfig, no spurious editor element created |
|
|
21
|
+
|
|
22
|
+
**Named parts** get both a global plain string and a module class. The global string (`'<component-name>'` for root, `'<part-name>'` for inner parts — kebab-case) is what zeroConfig scans. The module class is what carries the component's structural CSS for that element.
|
|
23
|
+
|
|
24
|
+
**Non-part elements** (layout wrappers, grouping containers, structural helpers) get only a module class. CSS module classes are mangled and invisible to zeroConfig.
|
|
25
|
+
|
|
26
|
+
The root also merges the consumer-provided `className` prop via the `classnames` helper.
|
|
27
|
+
|
|
28
|
+
**Why:** zeroConfig creates one editor element per global class. A global class on a non-part produces a spurious editor element with no meaningful surface.
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
import classNames from 'classnames';
|
|
32
|
+
import styles from './ProfileCard.module.css';
|
|
33
|
+
|
|
34
|
+
// ✅ Root: global string + module class + consumer className
|
|
35
|
+
<div className={classNames(className, 'profile-card', styles.root)} id={id}>
|
|
36
|
+
|
|
37
|
+
{/* ✅ Named part: global string + module class */}
|
|
38
|
+
<h2 className={classNames('heading', styles.heading)}>{heading}</h2>
|
|
39
|
+
|
|
40
|
+
{/* ✅ Non-part layout wrapper: module class only */}
|
|
41
|
+
<div className={styles.contentWrapper}>
|
|
42
|
+
<span className={classNames('label', styles.label)}>{label}</span>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
// ✅ Internal sub-components — same pattern on part slots
|
|
47
|
+
<CardHeader className={classNames('header', styles.header)}>
|
|
48
|
+
<CardTitle className={classNames('title', styles.title)}>{title}</CardTitle>
|
|
49
|
+
</CardHeader>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Use single-class selectors
|
|
53
|
+
|
|
54
|
+
Every selector is exactly one class, written as a flat top-level
|
|
55
|
+
rule. Compound selectors (`.a.b`), descendant
|
|
56
|
+
selectors (`.a .b`), child combinators (`.a > .b`), sibling
|
|
57
|
+
combinators (`.a + .b`), tag selectors, and CSS nesting (the `&`
|
|
58
|
+
syntax) are not permitted in component CSS.
|
|
59
|
+
|
|
60
|
+
**Why:** zeroConfig pairs each editor element with the single CSS
|
|
61
|
+
rule keyed on its class. A compound or relational selector means
|
|
62
|
+
either two elements share a rule or one element's appearance depends
|
|
63
|
+
on context — either way the editor cannot decide which rule to
|
|
64
|
+
modify when a user changes a property. CSS nesting compiles to
|
|
65
|
+
descendant selectors and has the same effect.
|
|
66
|
+
|
|
67
|
+
```css
|
|
68
|
+
/* ✅ Do: Single-class selector — unambiguous mapping to an editor control */
|
|
69
|
+
.profile-card {
|
|
70
|
+
}
|
|
71
|
+
.title {
|
|
72
|
+
}
|
|
73
|
+
.content {
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* ❌ Compound selector — rule applies only when both classes match the same element */
|
|
77
|
+
.profile-card.featured {
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* ❌ Descendant selector — rule depends on ancestor structure */
|
|
81
|
+
.profile-card .title {
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* ❌ Child combinator — rule depends on direct parent */
|
|
85
|
+
.profile-card > .content {
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* ❌ Sibling combinator — rule depends on a sibling element */
|
|
89
|
+
.title + .subtitle {
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* ❌ CSS nesting — compiles to a descendant selector */
|
|
93
|
+
.profile-card {
|
|
94
|
+
& .title {
|
|
95
|
+
color: black;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Layout and responsiveness
|
|
101
|
+
|
|
102
|
+
### Root fills its container
|
|
103
|
+
|
|
104
|
+
The root element sets `width: 100%`, `height: 100%`, and
|
|
105
|
+
`box-sizing: border-box`. The component never assumes a specific
|
|
106
|
+
pixel size for its outer box.
|
|
107
|
+
|
|
108
|
+
**Why:** Wix users place components in resizable slots whose
|
|
109
|
+
dimensions aren't known at authoring time. A root with hardcoded
|
|
110
|
+
width or height overflows or leaves gaps inside its slot.
|
|
111
|
+
|
|
112
|
+
```css
|
|
113
|
+
/* ✅ Do: Root fills any slot the user creates */
|
|
114
|
+
.profile-card {
|
|
115
|
+
width: 100%;
|
|
116
|
+
height: 100%;
|
|
117
|
+
box-sizing: border-box;
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Pipe sizing through every layer below the root
|
|
122
|
+
|
|
123
|
+
Every element between the platform-sized root and the leaf content
|
|
124
|
+
must explicitly participate in the sizing chain — one unsized
|
|
125
|
+
wrapper collapses the entire subtree to intrinsic size.
|
|
126
|
+
|
|
127
|
+
Use `flex: 1; min-width: 0` (or `min-height: 0` on the block axis)
|
|
128
|
+
on children that should grow, and `flex: 0 0 auto` on children that
|
|
129
|
+
should stay fixed-size.
|
|
130
|
+
|
|
131
|
+
**Why:** flex/grid children default to `auto` sizing and shrink to
|
|
132
|
+
content. A wrapper `<div>` without explicit sizing breaks the chain
|
|
133
|
+
even when the root fills its slot correctly.
|
|
134
|
+
|
|
135
|
+
```css
|
|
136
|
+
/* ✅ Do: grower fills remaining space */
|
|
137
|
+
.wrapper {
|
|
138
|
+
display: flex;
|
|
139
|
+
flex: 1;
|
|
140
|
+
min-width: 0;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* ✅ Do: fixed child keeps intrinsic size */
|
|
144
|
+
.control {
|
|
145
|
+
flex: 0 0 auto;
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Set `box-sizing: border-box` on every selector
|
|
150
|
+
|
|
151
|
+
Apply `box-sizing: border-box` to every class in component CSS, not
|
|
152
|
+
just the root. The default `content-box` is never wanted in this
|
|
153
|
+
codebase.
|
|
154
|
+
|
|
155
|
+
**Why:** the editor exposes padding and border-width as live
|
|
156
|
+
controls. With `content-box`, increasing either grows the element's
|
|
157
|
+
outer box, which makes neighbouring elements visibly shift while the
|
|
158
|
+
user is dragging a slider — the component "shakes" in the editor.
|
|
159
|
+
`border-box` keeps the outer dimension stable; padding and border
|
|
160
|
+
eat into the existing box instead, so the layout stays still while
|
|
161
|
+
the user tunes values.
|
|
162
|
+
|
|
163
|
+
```css
|
|
164
|
+
/* ✅ Do: border-box — outer size stays stable while the editor tunes padding and border */
|
|
165
|
+
.profile-card,
|
|
166
|
+
.title,
|
|
167
|
+
.button {
|
|
168
|
+
box-sizing: border-box;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/* ❌ content-box — outer size grows when the editor adjusts padding or border */
|
|
172
|
+
.profile-card {
|
|
173
|
+
box-sizing: content-box; /* the default — don't rely on it */
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Adapt to container size, not viewport
|
|
178
|
+
|
|
179
|
+
Layout responds to the size of the component's parent, not to the
|
|
180
|
+
browser viewport. Use intrinsic flex/grid sizing (`auto-fit`,
|
|
181
|
+
`minmax(...)`, `1fr`) and `clamp()` for fluid scaling. `@media`
|
|
182
|
+
queries keyed on viewport dimensions (`width`, `height`,
|
|
183
|
+
`orientation`) are not permitted in component CSS.
|
|
184
|
+
|
|
185
|
+
**Why:** the Wix editor owns viewport-level breakpoints. A component
|
|
186
|
+
that branches on viewport width competes with the editor's
|
|
187
|
+
responsiveness model and renders the same container size differently
|
|
188
|
+
across viewports, breaking the editor's WYSIWYG contract.
|
|
189
|
+
|
|
190
|
+
```css
|
|
191
|
+
/* ✅ Do: Container-driven sizing — adapts to the slot, not the viewport */
|
|
192
|
+
.card-grid {
|
|
193
|
+
display: grid;
|
|
194
|
+
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
|
195
|
+
gap: clamp(1rem, 2.5vw, 2rem);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/* ❌ Viewport breakpoint — fights the editor's responsiveness model */
|
|
199
|
+
@media (max-width: 768px) {
|
|
200
|
+
.card-grid {
|
|
201
|
+
grid-template-columns: 1fr;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Use logical properties on the inline axis
|
|
207
|
+
|
|
208
|
+
For any property that should flip between LTR and RTL — horizontal
|
|
209
|
+
margin, padding, border, positional offset — use logical properties
|
|
210
|
+
keyed on the inline axis: `margin-inline`, `margin-inline-start`,
|
|
211
|
+
`margin-inline-end`, `padding-inline`, `padding-inline-start`,
|
|
212
|
+
`padding-inline-end`, `border-inline-start`, `border-inline-end`,
|
|
213
|
+
`inset-inline-start`, `inset-inline-end`. Do not use `margin-left` /
|
|
214
|
+
`margin-right`, `padding-left` / `padding-right`, `border-left` /
|
|
215
|
+
`border-right`, `left`, or `right`.
|
|
216
|
+
|
|
217
|
+
Block-axis properties (`margin-top`, `margin-bottom`, `padding-top`,
|
|
218
|
+
`padding-bottom`, `border-top`, `border-bottom`, `top`, `bottom`)
|
|
219
|
+
stay as physical properties — they don't flip with text direction
|
|
220
|
+
in horizontal writing modes, which is what site components ship in.
|
|
221
|
+
|
|
222
|
+
**Why:** the Wix editor lets the site owner switch a site's text
|
|
223
|
+
direction between LTR and RTL. Logical inline properties flip
|
|
224
|
+
automatically with `direction: rtl` set by an ancestor, so one CSS
|
|
225
|
+
file produces correct layouts in both directions. Physical
|
|
226
|
+
left/right properties stay locked regardless of direction, which
|
|
227
|
+
breaks RTL layouts (icons end up on the wrong side of text, padding
|
|
228
|
+
piles up on the wrong edge, sticky offsets point the wrong way).
|
|
229
|
+
|
|
230
|
+
```css
|
|
231
|
+
/* ✅ Do: Inline logical properties — flip automatically in RTL */
|
|
232
|
+
.profile-card {
|
|
233
|
+
padding-inline: 24px;
|
|
234
|
+
margin-inline-start: 8px;
|
|
235
|
+
border-inline-start: 4px solid currentColor;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/* ❌ Don't: Physical left/right — stays locked in RTL and breaks the layout */
|
|
239
|
+
.profile-card {
|
|
240
|
+
padding-left: 24px;
|
|
241
|
+
padding-right: 24px;
|
|
242
|
+
margin-left: 8px;
|
|
243
|
+
border-left: 4px solid currentColor;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/* ✅ Do: Block axis stays physical — top/bottom don't flip with direction */
|
|
247
|
+
.banner {
|
|
248
|
+
position: sticky;
|
|
249
|
+
top: 0;
|
|
250
|
+
padding-block: 12px;
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Set the root layout via `--display`, never `display`
|
|
255
|
+
|
|
256
|
+
The root rule declares `--display: <value>` and does not set
|
|
257
|
+
`display` itself. The platform reads `--display` and applies the
|
|
258
|
+
resolved `display` value at runtime. This rule applies to the root
|
|
259
|
+
selector only — inner element classes set `display` directly as
|
|
260
|
+
normal.
|
|
261
|
+
|
|
262
|
+
**Why:** the editor toggles a component's visibility (and other
|
|
263
|
+
display modes) by overriding the `--display` custom property on the
|
|
264
|
+
root. If the root rule also sets `display` directly, that
|
|
265
|
+
declaration wins over the platform's override and the editor has to
|
|
266
|
+
rewrite the rule to take effect, which is fragile. Inner elements
|
|
267
|
+
aren't toggled this way, so they use `display` normally.
|
|
268
|
+
|
|
269
|
+
```css
|
|
270
|
+
/* ✅ Do: Root declares --display only — platform applies it, editor can override */
|
|
271
|
+
.profile-card {
|
|
272
|
+
--display: flex;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/* ❌ Don't: Root sets display directly — competes with the platform override */
|
|
276
|
+
.profile-card {
|
|
277
|
+
--display: flex;
|
|
278
|
+
display: var(--display);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/* ✅ Do: Inner elements set display normally — the --display rule is root-only */
|
|
282
|
+
.header {
|
|
283
|
+
display: flex;
|
|
284
|
+
align-items: center;
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Choose one of four layout shapes for the component root
|
|
289
|
+
|
|
290
|
+
A component's root layout typically fits one of four shapes — reach
|
|
291
|
+
for the simplest one that satisfies the design.
|
|
292
|
+
|
|
293
|
+
**Why:** a small, shared vocabulary of layouts produces predictable
|
|
294
|
+
manifests and predictable editor behavior. The editor's
|
|
295
|
+
auto-generated controls (gap, padding, alignment) are tuned for
|
|
296
|
+
these shapes.
|
|
297
|
+
|
|
298
|
+
```css
|
|
299
|
+
/* ✅ Do: Single column — stacked content (profile card, pricing card, CTA block) */
|
|
300
|
+
.profile-card {
|
|
301
|
+
--display: flex;
|
|
302
|
+
flex-direction: column;
|
|
303
|
+
align-items: center;
|
|
304
|
+
text-align: center;
|
|
305
|
+
gap: 1rem;
|
|
306
|
+
padding: clamp(1rem, 3vw, 2rem);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/* ✅ Do: Two-column split — media + text pair (testimonial, feature row, media card) */
|
|
310
|
+
.media-card {
|
|
311
|
+
--display: grid;
|
|
312
|
+
grid-template-columns: 1fr 1fr;
|
|
313
|
+
gap: clamp(1rem, 3vw, 2rem);
|
|
314
|
+
align-items: center;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/* ✅ Do: Multi-column grid — list of children (product list, testimonial list, gallery) */
|
|
318
|
+
.testimonial-list {
|
|
319
|
+
--display: grid;
|
|
320
|
+
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
|
321
|
+
gap: clamp(1rem, 2.5vw, 2rem);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/* ✅ Do: Inline row — fixed controls on edges, growing center
|
|
325
|
+
(numeric stepper, search bar, toolbar, split button, pagination).
|
|
326
|
+
Pair with stretch-chain rules: controls flex: 0 0 auto,
|
|
327
|
+
center area flex: 1; min-width: 0. */
|
|
328
|
+
.numeric-stepper {
|
|
329
|
+
--display: flex;
|
|
330
|
+
flex-direction: row;
|
|
331
|
+
align-items: center;
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## CSS variables and props
|
|
336
|
+
|
|
337
|
+
### Use literal CSS values; introduce a variable only when interpolation requires it
|
|
338
|
+
|
|
339
|
+
Write CSS values as literals. Introduce a CSS custom property _only_
|
|
340
|
+
when the value is consumed inside a CSS function or compound
|
|
341
|
+
expression that cannot be written as a plain value — for example
|
|
342
|
+
inside `repeat()`, `calc()`, `min()`, `max()`, or `clamp()`. Do not
|
|
343
|
+
add a React prop for a value the user wouldn't meaningfully tune.
|
|
344
|
+
|
|
345
|
+
**Why:** every CSS variable that crosses into a React prop becomes a
|
|
346
|
+
control in the editor. Exposing routine values like `gap` or
|
|
347
|
+
`padding` as props clutters the editor UI, and the editor already
|
|
348
|
+
auto-surfaces those properties from the CSS rule itself —
|
|
349
|
+
duplicating them as props gives the user two competing controls for
|
|
350
|
+
the same thing.
|
|
351
|
+
|
|
352
|
+
```css
|
|
353
|
+
/* ❌ Don't: Unnecessary variable — value isn't interpolated anywhere */
|
|
354
|
+
.profile-card {
|
|
355
|
+
--gap: 16px;
|
|
356
|
+
gap: var(--gap);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/* ✅ Do: Literal value — nothing to interpolate */
|
|
360
|
+
.profile-card {
|
|
361
|
+
gap: 16px;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/* ✅ Do: Variable required — value is consumed inside repeat() */
|
|
365
|
+
.card-grid {
|
|
366
|
+
--columns: 3;
|
|
367
|
+
grid-template-columns: repeat(var(--columns), 1fr);
|
|
368
|
+
}
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## Other rules
|
|
372
|
+
|
|
373
|
+
### Keep all styling in CSS
|
|
374
|
+
|
|
375
|
+
Static styling lives in the component's CSS. Do not use the JSX
|
|
376
|
+
`style={{ ... }}` attribute on rendered elements. Dynamic values
|
|
377
|
+
that genuinely vary per instance go through CSS custom properties
|
|
378
|
+
(see the rule above), still set in CSS.
|
|
379
|
+
|
|
380
|
+
**Why:** zeroConfig reads CSS rules to derive the editor's control
|
|
381
|
+
surface. An inline `style` attribute is invisible to the extractor,
|
|
382
|
+
so any value baked into JSX cannot be edited in the visual editor —
|
|
383
|
+
the user sees no control for it.
|
|
384
|
+
|
|
385
|
+
```tsx
|
|
386
|
+
// ❌ Inline style — invisible to zeroConfig, no editor control
|
|
387
|
+
<div className="profile-card" style={{ padding: 20, borderRadius: 8 }} />
|
|
388
|
+
|
|
389
|
+
// ✅ Do: Defaults in CSS — surfaced to the editor as controls
|
|
390
|
+
<div className="profile-card" />
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
```css
|
|
394
|
+
/* ✅ Do: Defaults belong in CSS so the editor can surface them */
|
|
395
|
+
.profile-card {
|
|
396
|
+
padding: 20px;
|
|
397
|
+
border-radius: 8px;
|
|
398
|
+
background: #ffffff; /* Use `background`, never `background-color` — the schema key is "background"; zeroConfig can't match "background-color" so the default is lost in the design panel */
|
|
399
|
+
}
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
### Default aesthetic: polished and generous
|
|
403
|
+
|
|
404
|
+
When the user does not specify a visual style, default to a polished,
|
|
405
|
+
modern look. The editor lets the user override every value, so a
|
|
406
|
+
refined default costs nothing.
|
|
407
|
+
|
|
408
|
+
| Property | Guidance |
|
|
409
|
+
|---|---|
|
|
410
|
+
| `border-radius` | 8–12 px containers, `50%` for controls and interactive groups (buttons, pills, input rows) |
|
|
411
|
+
| `box-shadow` | Prefer soft, diffused shadows over hard borders (e.g. `0 2px 8px rgba(0,0,0,0.06), 0 0 1px rgba(0,0,0,0.08)`) |
|
|
412
|
+
| Spacing | 8–16 px inside controls, 16–32 px for containers. Avoid cramped layouts |
|
|
413
|
+
| Typography | Body ≥ 16 px, labels ≥ 14 px, headings larger. `font-weight: 500`–`600` |
|
|
414
|
+
| Palette | Root background transparent (blends with page). Use subtle fills (`#f1f5f9`/`#e2e8f0`) on *inner controls* only (buttons, input areas, pill containers). Text `#1e293b`/`#334155`, borders `#e2e8f0`. `#475569` for large/secondary text only |
|
|
415
|
+
| Accent | Use a muted accent color (e.g. `#6366f1`, `#7c83db`) sparingly on interactive icons, active indicators, and primary actions — just enough to signal interactivity without dominating |
|
|
416
|
+
| Contrast | WCAG AA minimum: 4.5:1 body text, 3:1 large text / UI controls |
|
|
417
|
+
| Hierarchy | Interactive elements visually distinct from static via weight, fill, or elevation |
|
|
418
|
+
| Touch targets | Interactive elements ≥ 44×44 px |
|
|
419
|
+
|
|
420
|
+
### Don't author state styles (`:hover`, `:focus`, `:disabled`, `[data-state]`)
|
|
421
|
+
|
|
422
|
+
State pseudo-classes and state attribute selectors are not allowed
|
|
423
|
+
in component CSS. That includes `:hover`, `:focus`, `:focus-visible`,
|
|
424
|
+
`:active`, `:disabled`, and attribute selectors like
|
|
425
|
+
`[data-state='open']` or `[aria-selected='true']`.
|
|
426
|
+
|
|
427
|
+
**Why:** the editor owns state styling. Hover, focus, disabled, and
|
|
428
|
+
similar interaction states are exposed to the site owner as
|
|
429
|
+
editable visual states — the platform writes those rules itself
|
|
430
|
+
based on what the user configures. State styles authored in the
|
|
431
|
+
component compete with the platform's rules and produce two
|
|
432
|
+
sources of truth for the same state.
|
|
433
|
+
|
|
434
|
+
```css
|
|
435
|
+
/* ❌ Don't: hover/focus/disabled state — platform owns these */
|
|
436
|
+
.button:hover {
|
|
437
|
+
background-color: #f0f0f0;
|
|
438
|
+
}
|
|
439
|
+
.button:focus {
|
|
440
|
+
outline: 2px solid blue;
|
|
441
|
+
}
|
|
442
|
+
.button:disabled {
|
|
443
|
+
opacity: 0.5;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/* ❌ Don't: state attribute selectors — same problem */
|
|
447
|
+
.panel[data-state='open'] {
|
|
448
|
+
background-color: #fafafa;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/* ✅ Do: Style the resting state only — platform layers state styling on top */
|
|
452
|
+
.button {
|
|
453
|
+
background-color: #ffffff;
|
|
454
|
+
color: #111;
|
|
455
|
+
}
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
### Express selection / mode variants with JS-toggled modifier classes
|
|
459
|
+
|
|
460
|
+
The previous rule banned **interaction states** (`:hover`, `:focus`,
|
|
461
|
+
`:focus-visible`, `:active`, `:disabled`, `[data-state]`,
|
|
462
|
+
`[aria-selected]`) — those are user-controlled and platform-owned.
|
|
463
|
+
**Selection / mode variants** (`selected`, `active`, `current`,
|
|
464
|
+
`open`, `expanded`) are different: they are part of the component's
|
|
465
|
+
own data model and the component owns their styling.
|
|
466
|
+
|
|
467
|
+
Express each variant as a **JS-toggled modifier class**, applied
|
|
468
|
+
alongside the base class via `classNames`. Each class — base and
|
|
469
|
+
modifier — is its own **single-class** CSS rule. The decision of
|
|
470
|
+
which class applies is made in JSX from props/state, not by a CSS
|
|
471
|
+
selector.
|
|
472
|
+
|
|
473
|
+
**Why:** the modifier class is decided in JSX, not in CSS. zeroConfig
|
|
474
|
+
still sees one selector per rule (both classes are single-class
|
|
475
|
+
rules), so the editor's mapping stays unambiguous. `PARTS.md`
|
|
476
|
+
excludes "state or variant" from the named-parts taxonomy — the
|
|
477
|
+
modifier is CSS-only, not a part.
|
|
478
|
+
|
|
479
|
+
```tsx
|
|
480
|
+
/* ✅ Do: JS-toggled modifier class, applied alongside the base */
|
|
481
|
+
<button
|
|
482
|
+
className={classNames(
|
|
483
|
+
styles.toggleSegment,
|
|
484
|
+
isSelected && styles.toggleSegmentSelected,
|
|
485
|
+
)}
|
|
486
|
+
/>
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
```css
|
|
490
|
+
/* ✅ Do: each class is its own single-class rule */
|
|
491
|
+
.toggleSegment {
|
|
492
|
+
background: transparent;
|
|
493
|
+
color: #475569;
|
|
494
|
+
font-weight: 500;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
.toggleSegmentSelected {
|
|
498
|
+
background: #ffffff;
|
|
499
|
+
color: #0f172a;
|
|
500
|
+
font-weight: 600;
|
|
501
|
+
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06), 0 1px 3px rgba(15, 23, 42, 0.1);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/* ❌ Don't: compound selector — banned by the single-class-selector rule */
|
|
505
|
+
.toggleSegment.selected {
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/* ❌ Don't: attribute selector keyed on ARIA — banned by the no-state-CSS rule */
|
|
509
|
+
.toggleSegment[aria-selected='true'] {
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/* ❌ Don't: pseudo-class — that's an interaction state, platform-owned */
|
|
513
|
+
.toggleSegment:checked {
|
|
514
|
+
}
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
### Don't add transitions or animations unless functionally required
|
|
518
|
+
|
|
519
|
+
Component CSS does not declare `transition` or `animation` for
|
|
520
|
+
decorative purposes. Use them only when the motion is part of the
|
|
521
|
+
component's behavior (e.g. an accordion panel sliding open, a
|
|
522
|
+
carousel translating between slides). When transitions are required,
|
|
523
|
+
list the specific properties — never `transition: all`,
|
|
524
|
+
`transition-property: all`, or the implicit `all` of a duration-only
|
|
525
|
+
shorthand (`transition: 0.2s ease`).
|
|
526
|
+
|
|
527
|
+
**Why:** the editor mutates many CSS properties live as the user
|
|
528
|
+
configures the component — colors, font, padding, border width,
|
|
529
|
+
even layout properties on parent classes. Animating those mutations
|
|
530
|
+
makes the editor visibly laggy: values meant to update instantly
|
|
531
|
+
slide instead. State transitions like hover and focus are owned by
|
|
532
|
+
the platform (see the rule above), so the component shouldn't
|
|
533
|
+
author them either.
|
|
534
|
+
|
|
535
|
+
```css
|
|
536
|
+
/* ❌ Don't: decorative transition with no functional reason */
|
|
537
|
+
.button {
|
|
538
|
+
transition: background-color 0.2s ease;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/* ❌ Don't: transition: all — animates every property the editor touches */
|
|
542
|
+
.button {
|
|
543
|
+
transition: all 0.2s ease;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/* ❌ Don't: implicit all — duration-only shorthand resolves to transition-property: all */
|
|
547
|
+
.button {
|
|
548
|
+
transition: 0.2s ease;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/* ✅ Do: Functional transition with specific properties named (e.g. accordion expand) */
|
|
552
|
+
.panel {
|
|
553
|
+
transition: height 0.2s ease;
|
|
554
|
+
}
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
### Set `pointer-events: auto` on the root and every interactive element
|
|
558
|
+
|
|
559
|
+
The root selector and every nested class that the user can click,
|
|
560
|
+
hover, or focus (links, buttons, controls) explicitly set
|
|
561
|
+
`pointer-events: auto`.
|
|
562
|
+
|
|
563
|
+
**Why:** the editor renders components inside wrappers that disable
|
|
564
|
+
pointer events at the wrapper level so the editor itself can capture
|
|
565
|
+
clicks for selection. Explicit `auto` on the component's own
|
|
566
|
+
elements ensures interaction reaches them at runtime on the
|
|
567
|
+
published site, where the wrapper is gone.
|
|
568
|
+
|
|
569
|
+
```css
|
|
570
|
+
/* ✅ Do: pointer-events: auto — interaction reaches component elements through the editor wrapper */
|
|
571
|
+
.profile-card,
|
|
572
|
+
.title,
|
|
573
|
+
.button {
|
|
574
|
+
pointer-events: auto;
|
|
575
|
+
}
|
|
576
|
+
```
|