@olives/devos 2.1.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/.agents/AGENTS.md +316 -0
- package/.agents/README.md +55 -0
- package/.agents/agents/architect.md +18 -0
- package/.agents/agents/dba.md +25 -0
- package/.agents/agents/developer.md +40 -0
- package/.agents/agents/devops.md +18 -0
- package/.agents/agents/memory-manager.md +38 -0
- package/.agents/agents/orchestrator.md +92 -0
- package/.agents/agents/qa.md +53 -0
- package/.agents/agents/release-manager.md +41 -0
- package/.agents/agents/researcher.md +19 -0
- package/.agents/agents/security.md +27 -0
- package/.agents/agents/tester.md +21 -0
- package/.agents/commands/README.md +42 -0
- package/.agents/commands/architect.md +16 -0
- package/.agents/commands/commit.md +15 -0
- package/.agents/commands/deploy.md +18 -0
- package/.agents/commands/fix.md +19 -0
- package/.agents/commands/refactor.md +19 -0
- package/.agents/commands/research.md +19 -0
- package/.agents/commands/review.md +21 -0
- package/.agents/commands/secure.md +23 -0
- package/.agents/commands/status.md +16 -0
- package/.agents/commands/test.md +16 -0
- package/.agents/scripts/commit.sh +73 -0
- package/.agents/scripts/install-hooks.sh +72 -0
- package/.agents/skills/agent-browser/SKILL.md +50 -0
- package/.agents/skills/agent-development/SKILL.md +415 -0
- package/.agents/skills/agent-development/examples/agent-creation-prompt.md +238 -0
- package/.agents/skills/agent-development/examples/complete-agent-examples.md +427 -0
- package/.agents/skills/agent-development/references/agent-creation-system-prompt.md +207 -0
- package/.agents/skills/agent-development/references/system-prompt-design.md +411 -0
- package/.agents/skills/agent-development/references/triggering-examples.md +491 -0
- package/.agents/skills/agent-development/scripts/validate-agent.sh +217 -0
- package/.agents/skills/backend-dev-guidelines/SKILL.md +352 -0
- package/.agents/skills/backend-dev-guidelines/resources/architecture-overview.md +451 -0
- package/.agents/skills/backend-dev-guidelines/resources/async-and-errors.md +307 -0
- package/.agents/skills/backend-dev-guidelines/resources/complete-examples.md +638 -0
- package/.agents/skills/backend-dev-guidelines/resources/configuration.md +275 -0
- package/.agents/skills/backend-dev-guidelines/resources/database-patterns.md +224 -0
- package/.agents/skills/backend-dev-guidelines/resources/middleware-guide.md +213 -0
- package/.agents/skills/backend-dev-guidelines/resources/routing-and-controllers.md +756 -0
- package/.agents/skills/backend-dev-guidelines/resources/sentry-and-monitoring.md +336 -0
- package/.agents/skills/backend-dev-guidelines/resources/services-and-repositories.md +789 -0
- package/.agents/skills/backend-dev-guidelines/resources/testing-guide.md +235 -0
- package/.agents/skills/backend-dev-guidelines/resources/validation-patterns.md +754 -0
- package/.agents/skills/backend-development/SKILL.md +156 -0
- package/.agents/skills/backend-patterns/SKILL.md +562 -0
- package/.agents/skills/brainstorming/SKILL.md +159 -0
- package/.agents/skills/brainstorming/scripts/frame-template.html +213 -0
- package/.agents/skills/brainstorming/scripts/helper.js +167 -0
- package/.agents/skills/brainstorming/scripts/server.cjs +723 -0
- package/.agents/skills/brainstorming/scripts/start-server.sh +209 -0
- package/.agents/skills/brainstorming/scripts/stop-server.sh +120 -0
- package/.agents/skills/brainstorming/spec-document-reviewer-prompt.md +49 -0
- package/.agents/skills/brainstorming/visual-companion.md +291 -0
- package/.agents/skills/code-reviewer/SKILL.md +65 -0
- package/.agents/skills/content-strategy/SKILL.md +365 -0
- package/.agents/skills/content-strategy/evals/evals.json +90 -0
- package/.agents/skills/content-strategy/references/headless-cms.md +194 -0
- package/.agents/skills/deploy-to-vercel/SKILL.md +296 -0
- package/.agents/skills/deploy-to-vercel/resources/deploy-codex.sh +301 -0
- package/.agents/skills/deploy-to-vercel/resources/deploy.sh +301 -0
- package/.agents/skills/deployment-checklist/SKILL.md +119 -0
- package/.agents/skills/design/SKILL.md +170 -0
- package/.agents/skills/design-an-interface/SKILL.md +94 -0
- package/.agents/skills/expose-localhost/SKILL.md +211 -0
- package/.agents/skills/expose-localhost/references/TROUBLESHOOTING.md +27 -0
- package/.agents/skills/find-skills/SKILL.md +142 -0
- package/.agents/skills/frontend-ui-engineering/SKILL.md +328 -0
- package/.agents/skills/git-commit/SKILL.md +124 -0
- package/.agents/skills/git-ops/SKILL.md +53 -0
- package/.agents/skills/git-workflow/SKILL.md +167 -0
- package/.agents/skills/google-agents-cli-adk-code/SKILL.md +72 -0
- package/.agents/skills/google-agents-cli-adk-code/references/adk-python.md +937 -0
- package/.agents/skills/google-agents-cli-adk-code/references/adk-workflows.md +507 -0
- package/.agents/skills/google-agents-cli-workflow/SKILL.md +310 -0
- package/.agents/skills/google-agents-cli-workflow/references/commands.md +12 -0
- package/.agents/skills/google-agents-cli-workflow/references/internals.md +24 -0
- package/.agents/skills/google-agents-cli-workflow/references/samples.md +59 -0
- package/.agents/skills/google-agents-cli-workflow/references/spec-template.md +25 -0
- package/.agents/skills/google-agents-cli-workflow/references/terminology.md +11 -0
- package/.agents/skills/grill-me/SKILL.md +47 -0
- package/.agents/skills/grill-with-docs/SKILL.md +7 -0
- package/.agents/skills/human-checkpoint/SKILL.md +21 -0
- package/.agents/skills/image/SKILL.md +340 -0
- package/.agents/skills/image/evals/evals.json +89 -0
- package/.agents/skills/image/references/ai-image-prompting.md +229 -0
- package/.agents/skills/image-generation/SKILL.md +374 -0
- package/.agents/skills/imagegen/LICENSE.txt +201 -0
- package/.agents/skills/imagegen/SKILL.md +279 -0
- package/.agents/skills/imagegen/agents/openai.yaml +6 -0
- package/.agents/skills/imagegen/assets/imagegen-small.svg +5 -0
- package/.agents/skills/imagegen/assets/imagegen.png +0 -0
- package/.agents/skills/imagegen/references/cli.md +160 -0
- package/.agents/skills/imagegen/references/codex-network.md +33 -0
- package/.agents/skills/imagegen/references/image-api.md +49 -0
- package/.agents/skills/imagegen/references/prompting.md +98 -0
- package/.agents/skills/imagegen/references/sample-prompts.md +376 -0
- package/.agents/skills/imagegen/scripts/image_gen.py +926 -0
- package/.agents/skills/imagegen-frontend-web/SKILL.md +987 -0
- package/.agents/skills/laravel-security/SKILL.md +948 -0
- package/.agents/skills/laravel-specialist/SKILL.md +264 -0
- package/.agents/skills/laravel-specialist/references/eloquent.md +351 -0
- package/.agents/skills/laravel-specialist/references/livewire.md +512 -0
- package/.agents/skills/laravel-specialist/references/queues.md +423 -0
- package/.agents/skills/laravel-specialist/references/routing.md +362 -0
- package/.agents/skills/laravel-specialist/references/testing.md +522 -0
- package/.agents/skills/laravel-tdd/SKILL.md +675 -0
- package/.agents/skills/laravel-verification/SKILL.md +180 -0
- package/.agents/skills/modern-web-guidance/SKILL.md +114 -0
- package/.agents/skills/modern-web-guidance/guides/accessibility/accessibility.md +463 -0
- package/.agents/skills/modern-web-guidance/guides/accessibility/accessible-error-announcement.md +207 -0
- package/.agents/skills/modern-web-guidance/guides/built-in-ai/language-detection.md +89 -0
- package/.agents/skills/modern-web-guidance/guides/built-in-ai/language-model.md +189 -0
- package/.agents/skills/modern-web-guidance/guides/built-in-ai/prompt-api.md +189 -0
- package/.agents/skills/modern-web-guidance/guides/built-in-ai/summarizer.md +154 -0
- package/.agents/skills/modern-web-guidance/guides/built-in-ai/translator.md +162 -0
- package/.agents/skills/modern-web-guidance/guides/css/css.md +527 -0
- package/.agents/skills/modern-web-guidance/guides/css/highlight-text-ranges.md +128 -0
- package/.agents/skills/modern-web-guidance/guides/css-layout/css-layout.md +305 -0
- package/.agents/skills/modern-web-guidance/guides/forms/animated-select-picker.md +178 -0
- package/.agents/skills/modern-web-guidance/guides/forms/autofill-address-form.md +75 -0
- package/.agents/skills/modern-web-guidance/guides/forms/autofill-highlight-inputs.md +45 -0
- package/.agents/skills/modern-web-guidance/guides/forms/autofill-payment-form.md +125 -0
- package/.agents/skills/modern-web-guidance/guides/forms/autofill-sign-in-form.md +135 -0
- package/.agents/skills/modern-web-guidance/guides/forms/autofill-sign-up-form.md +145 -0
- package/.agents/skills/modern-web-guidance/guides/forms/brand-consistent-forms.md +255 -0
- package/.agents/skills/modern-web-guidance/guides/forms/branded-select-styling.md +114 -0
- package/.agents/skills/modern-web-guidance/guides/forms/custom-select-picker-layouts.md +103 -0
- package/.agents/skills/modern-web-guidance/guides/forms/form-fields-automatically-fit-contents.md +121 -0
- package/.agents/skills/modern-web-guidance/guides/forms/forms.md +372 -0
- package/.agents/skills/modern-web-guidance/guides/forms/required-field-feedback.md +214 -0
- package/.agents/skills/modern-web-guidance/guides/forms/rich-media-picker.md +132 -0
- package/.agents/skills/modern-web-guidance/guides/forms/select-menu-interaction.md +180 -0
- package/.agents/skills/modern-web-guidance/guides/forms/validate-input-after-interaction.md +258 -0
- package/.agents/skills/modern-web-guidance/guides/html/html.md +407 -0
- package/.agents/skills/modern-web-guidance/guides/passkeys/passkey-authentication.md +205 -0
- package/.agents/skills/modern-web-guidance/guides/passkeys/passkey-conditional-create.md +134 -0
- package/.agents/skills/modern-web-guidance/guides/passkeys/passkey-management.md +211 -0
- package/.agents/skills/modern-web-guidance/guides/passkeys/passkey-reauthentication.md +128 -0
- package/.agents/skills/modern-web-guidance/guides/passkeys/passkey-registration.md +181 -0
- package/.agents/skills/modern-web-guidance/guides/passkeys/passkeys.md +38 -0
- package/.agents/skills/modern-web-guidance/guides/performance/batch-analytics-events.md +154 -0
- package/.agents/skills/modern-web-guidance/guides/performance/break-up-long-tasks.md +60 -0
- package/.agents/skills/modern-web-guidance/guides/performance/calculate-total-foreground-time.md +69 -0
- package/.agents/skills/modern-web-guidance/guides/performance/conditional-async-dependencies.md +71 -0
- package/.agents/skills/modern-web-guidance/guides/performance/defer-rendering-heavy-content.md +106 -0
- package/.agents/skills/modern-web-guidance/guides/performance/defer-work-until-scroll-ends.md +78 -0
- package/.agents/skills/modern-web-guidance/guides/performance/deprioritize-background-fetches.md +37 -0
- package/.agents/skills/modern-web-guidance/guides/performance/detect-initial-visibility-state.md +99 -0
- package/.agents/skills/modern-web-guidance/guides/performance/efficient-background-processing.md +117 -0
- package/.agents/skills/modern-web-guidance/guides/performance/faster-spa-view-transitions.md +79 -0
- package/.agents/skills/modern-web-guidance/guides/performance/full-session-analytics.md +135 -0
- package/.agents/skills/modern-web-guidance/guides/performance/identify-heavy-scripts.md +69 -0
- package/.agents/skills/modern-web-guidance/guides/performance/identify-inp-causes.md +73 -0
- package/.agents/skills/modern-web-guidance/guides/performance/improve-next-page-load-performance.md +119 -0
- package/.agents/skills/modern-web-guidance/guides/performance/interactions-in-complex-layouts.md +78 -0
- package/.agents/skills/modern-web-guidance/guides/performance/optimize-image-priority.md +61 -0
- package/.agents/skills/modern-web-guidance/guides/performance/optimize-preload-priority.md +41 -0
- package/.agents/skills/modern-web-guidance/guides/performance/optimize-script-priority.md +38 -0
- package/.agents/skills/modern-web-guidance/guides/performance/performance.md +366 -0
- package/.agents/skills/modern-web-guidance/guides/performance/resolution-optimized-pseudo-elements.md +47 -0
- package/.agents/skills/modern-web-guidance/guides/performance/schedule-tasks-by-priority.md +59 -0
- package/.agents/skills/modern-web-guidance/guides/performance/sequence-distributed-events.md +76 -0
- package/.agents/skills/modern-web-guidance/guides/privacy/privacy.md +247 -0
- package/.agents/skills/modern-web-guidance/guides/security/security.md +350 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/adapt-scrollbar-to-contrast-preferences.md +74 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/anchor-positioning-tab-underline.md +95 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/animate-element-entry-exit.md +131 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/animate-to-from-top-layer.md +140 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/animate-to-intrinsic-sizes.md +127 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/apply-webgl-shaders.md +239 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/calculate-event-differentials.md +85 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/calculate-with-intrinsic-sizes.md +196 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/capture-location-agnostic-data.md +63 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/carousel-slide-effects.md +187 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/carousel-snap-highlights.md +136 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/child-state-based-styling.md +101 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/complex-shapes.md +73 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/component-specific-light-dark-theme.md +179 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/consistent-cross-document-transitions.md +226 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/content-based-styling.md +118 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/coordinate-global-events.md +79 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/cross-document-transitions.md +127 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/custom-button-actions.md +173 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/customize-scrollbar-color-and-thickness.md +59 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/dark-mode.md +295 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/declarative-dialog-popover-control.md +238 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/deliver-optimized-decorative-images.md +49 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/design-token-reactivity.md +174 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/directional-navigation-transitions.md +125 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/dynamic-sibling-animations.md +54 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/dynamic-sibling-styling.md +98 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/export-html-media-from-canvas.md +256 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/expose-canvas-content-to-browser-features.md +401 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/flicker-free-client-side-ab-testing.md +168 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/fluid-scaling.md +78 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/format-human-readable-durations.md +87 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/group-element-transitions.md +124 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/improve-text-layout-and-legibility.md +76 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/individual-transform-properties.md +92 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/interactive-content-in-3d-scenes.md +383 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/interactive-content-reveal.md +118 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/interest-triggered-action-previews.md +79 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/interest-triggered-tooltips.md +132 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/light-dismiss-a-dialog.md +84 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/manage-recurring-intervals.md +73 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/model-partial-time-concepts.md +96 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/move-dom-element-without-losing-state.md +57 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/navigation-drawer.md +357 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/overflow-clipping-control.md +180 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/parallax-scroll-effects.md +230 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/persistent-app-tours.md +112 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/persistent-toast-notifications.md +30 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/persistent-top-layer-ui.md +48 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/physics-based-easing.md +118 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/platform-controls-dismiss-dialog.md +38 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/position-aware-tooltips.md +154 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/precise-text-alignment.md +99 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/prevent-text-wrapping.md +62 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/pull-to-reveal.md +83 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/reduce-style-repetition.md +87 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/resilient-context-menus-and-nested-dropdowns.md +102 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/same-document-transitions.md +177 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/scroll-entry-exit-effects.md +173 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/scroll-position-aware-elements.md +128 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/scroll-progress-indicator.md +133 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/scroll-snap-realtime-feedback.md +153 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/scroll-snap-state-sync.md +93 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/scroll-target-on-load.md +56 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/scrollability-affordance-hints.md +124 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/scrollytelling.md +181 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/search-hidden-content.md +136 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/shaped-cutouts.md +146 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/shrinking-header-on-scroll.md +126 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/size-aware-styling.md +104 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/soft-edge-content-fade.md +62 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/stabilize-reactive-state.md +72 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/stack-drill-down.md +680 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/style-parent-with-has.md +199 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/support-global-calendar-systems.md +107 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/swipe-to-remove.md +527 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/visually-stable-font-fallbacks.md +49 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/visually-stable-mixed-fonts.md +61 -0
- package/.agents/skills/modern-web-guidance/guides/user-experience/visually-texture-content.md +76 -0
- package/.agents/skills/modern-web-guidance/guides/webmcp/agentic-forms.md +116 -0
- package/.agents/skills/modern-web-guidance/guides/webmcp/agentic-javascript-tools.md +116 -0
- package/.agents/skills/modern-web-guidance/guides/webmcp/webmcp.md +43 -0
- package/.agents/skills/nextjs-app-router-patterns/SKILL.md +114 -0
- package/.agents/skills/nextjs-app-router-patterns/references/details.md +428 -0
- package/.agents/skills/nextjs-developer/SKILL.md +145 -0
- package/.agents/skills/nextjs-developer/references/app-router.md +311 -0
- package/.agents/skills/nextjs-developer/references/data-fetching.md +482 -0
- package/.agents/skills/nextjs-developer/references/deployment.md +545 -0
- package/.agents/skills/nextjs-developer/references/server-actions.md +462 -0
- package/.agents/skills/nextjs-developer/references/server-components.md +384 -0
- package/.agents/skills/nextjs-supabase-auth/SKILL.md +313 -0
- package/.agents/skills/nodejs-backend-patterns/SKILL.md +45 -0
- package/.agents/skills/nodejs-backend-patterns/references/advanced-patterns.md +430 -0
- package/.agents/skills/nodejs-backend-patterns/references/details.md +599 -0
- package/.agents/skills/performance-engineer/SKILL.md +181 -0
- package/.agents/skills/project-requirements/SKILL.md +43 -0
- package/.agents/skills/qa/SKILL.md +130 -0
- package/.agents/skills/security-review/LICENSE +22 -0
- package/.agents/skills/security-review/SKILL.md +312 -0
- package/.agents/skills/security-review/infrastructure/docker.md +432 -0
- package/.agents/skills/security-review/languages/javascript.md +387 -0
- package/.agents/skills/security-review/languages/python.md +363 -0
- package/.agents/skills/security-review/references/api-security.md +519 -0
- package/.agents/skills/security-review/references/authentication.md +353 -0
- package/.agents/skills/security-review/references/authorization.md +372 -0
- package/.agents/skills/security-review/references/business-logic.md +443 -0
- package/.agents/skills/security-review/references/cryptography.md +329 -0
- package/.agents/skills/security-review/references/csrf.md +398 -0
- package/.agents/skills/security-review/references/data-protection.md +378 -0
- package/.agents/skills/security-review/references/deserialization.md +410 -0
- package/.agents/skills/security-review/references/error-handling.md +436 -0
- package/.agents/skills/security-review/references/file-security.md +457 -0
- package/.agents/skills/security-review/references/injection.md +259 -0
- package/.agents/skills/security-review/references/logging.md +433 -0
- package/.agents/skills/security-review/references/misconfiguration.md +435 -0
- package/.agents/skills/security-review/references/modern-threats.md +475 -0
- package/.agents/skills/security-review/references/ssrf.md +413 -0
- package/.agents/skills/security-review/references/supply-chain.md +405 -0
- package/.agents/skills/security-review/references/xss.md +336 -0
- package/.agents/skills/seo-aeo-best-practices/SKILL.md +37 -0
- package/.agents/skills/seo-aeo-best-practices/references/aeo-considerations.md +159 -0
- package/.agents/skills/seo-aeo-best-practices/references/eeat-principles.md +127 -0
- package/.agents/skills/seo-aeo-best-practices/references/structured-data.md +183 -0
- package/.agents/skills/seo-aeo-best-practices/references/technical-seo.md +188 -0
- package/.agents/skills/seo-geo/.claude-plugin/plugin.json +29 -0
- package/.agents/skills/seo-geo/SKILL.md +250 -0
- package/.agents/skills/seo-geo/examples/opc-skills-case-study.md +330 -0
- package/.agents/skills/seo-geo/references/geo-research.md +319 -0
- package/.agents/skills/seo-geo/references/google-docs-summary.md +65 -0
- package/.agents/skills/seo-geo/references/platform-algorithms.md +354 -0
- package/.agents/skills/seo-geo/references/schema-templates.md +517 -0
- package/.agents/skills/seo-geo/references/seo-checklist.md +249 -0
- package/.agents/skills/seo-geo/references/tools-and-apis.md +313 -0
- package/.agents/skills/seo-geo/scripts/autocomplete_ideas.py +74 -0
- package/.agents/skills/seo-geo/scripts/backlinks.py +37 -0
- package/.agents/skills/seo-geo/scripts/competitor_gap.py +80 -0
- package/.agents/skills/seo-geo/scripts/credential.py +12 -0
- package/.agents/skills/seo-geo/scripts/dataforseo_api.py +104 -0
- package/.agents/skills/seo-geo/scripts/domain_overview.py +44 -0
- package/.agents/skills/seo-geo/scripts/keyword_research.py +38 -0
- package/.agents/skills/seo-geo/scripts/related_keywords.py +84 -0
- package/.agents/skills/seo-geo/scripts/seo_audit.py +151 -0
- package/.agents/skills/seo-geo/scripts/serp_analysis.py +41 -0
- package/.agents/skills/shadcn-ui/README.md +248 -0
- package/.agents/skills/shadcn-ui/SKILL.md +326 -0
- package/.agents/skills/shadcn-ui/examples/auth-layout.tsx +177 -0
- package/.agents/skills/shadcn-ui/examples/data-table.tsx +313 -0
- package/.agents/skills/shadcn-ui/examples/form-pattern.tsx +177 -0
- package/.agents/skills/shadcn-ui/resources/component-catalog.md +481 -0
- package/.agents/skills/shadcn-ui/resources/customization-guide.md +516 -0
- package/.agents/skills/shadcn-ui/resources/migration-guide.md +463 -0
- package/.agents/skills/shadcn-ui/resources/setup-guide.md +412 -0
- package/.agents/skills/shadcn-ui/scripts/verify-setup.sh +134 -0
- package/.agents/skills/skill-creator/LICENSE.txt +202 -0
- package/.agents/skills/skill-creator/SKILL.md +485 -0
- package/.agents/skills/skill-creator/agents/analyzer.md +274 -0
- package/.agents/skills/skill-creator/agents/comparator.md +202 -0
- package/.agents/skills/skill-creator/agents/grader.md +223 -0
- package/.agents/skills/skill-creator/assets/eval_review.html +146 -0
- package/.agents/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/.agents/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/.agents/skills/skill-creator/references/schemas.md +430 -0
- package/.agents/skills/skill-creator/scripts/__init__.py +0 -0
- package/.agents/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/.agents/skills/skill-creator/scripts/generate_report.py +326 -0
- package/.agents/skills/skill-creator/scripts/improve_description.py +247 -0
- package/.agents/skills/skill-creator/scripts/package_skill.py +136 -0
- package/.agents/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/.agents/skills/skill-creator/scripts/run_eval.py +310 -0
- package/.agents/skills/skill-creator/scripts/run_loop.py +328 -0
- package/.agents/skills/skill-creator/scripts/utils.py +47 -0
- package/.agents/skills/stacks/SKILL.md +21 -0
- package/.agents/skills/stacks/django.md +187 -0
- package/.agents/skills/stacks/express.md +16 -0
- package/.agents/skills/stacks/fastapi.md +17 -0
- package/.agents/skills/stacks/laravel.md +18 -0
- package/.agents/skills/stacks/nextjs.md +20 -0
- package/.agents/skills/stacks/react-native.md +170 -0
- package/.agents/skills/supabase/CHANGELOG.md +35 -0
- package/.agents/skills/supabase/SKILL.md +135 -0
- package/.agents/skills/supabase/assets/feedback-issue-template.md +17 -0
- package/.agents/skills/supabase/references/skill-feedback.md +17 -0
- package/.agents/skills/supabase-postgres-best-practices/CHANGELOG.md +29 -0
- package/.agents/skills/supabase-postgres-best-practices/SKILL.md +64 -0
- package/.agents/skills/supabase-postgres-best-practices/references/_contributing.md +170 -0
- package/.agents/skills/supabase-postgres-best-practices/references/_sections.md +39 -0
- package/.agents/skills/supabase-postgres-best-practices/references/_template.md +34 -0
- package/.agents/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -0
- package/.agents/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -0
- package/.agents/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -0
- package/.agents/skills/supabase-postgres-best-practices/references/conn-limits.md +44 -0
- package/.agents/skills/supabase-postgres-best-practices/references/conn-pooling.md +41 -0
- package/.agents/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -0
- package/.agents/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -0
- package/.agents/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -0
- package/.agents/skills/supabase-postgres-best-practices/references/data-pagination.md +50 -0
- package/.agents/skills/supabase-postgres-best-practices/references/data-upsert.md +50 -0
- package/.agents/skills/supabase-postgres-best-practices/references/lock-advisory.md +56 -0
- package/.agents/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -0
- package/.agents/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -0
- package/.agents/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -0
- package/.agents/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -0
- package/.agents/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -0
- package/.agents/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -0
- package/.agents/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -0
- package/.agents/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -0
- package/.agents/skills/supabase-postgres-best-practices/references/query-index-types.md +48 -0
- package/.agents/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -0
- package/.agents/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -0
- package/.agents/skills/supabase-postgres-best-practices/references/schema-constraints.md +80 -0
- package/.agents/skills/supabase-postgres-best-practices/references/schema-data-types.md +46 -0
- package/.agents/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -0
- package/.agents/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -0
- package/.agents/skills/supabase-postgres-best-practices/references/schema-partitioning.md +55 -0
- package/.agents/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -0
- package/.agents/skills/supabase-postgres-best-practices/references/security-privileges.md +54 -0
- package/.agents/skills/supabase-postgres-best-practices/references/security-rls-basics.md +50 -0
- package/.agents/skills/supabase-postgres-best-practices/references/security-rls-performance.md +63 -0
- package/.agents/skills/task-contract/SKILL.md +29 -0
- package/.agents/skills/token-optimization/SKILL.md +40 -0
- package/.agents/skills/ui-designer/SKILL.md +76 -0
- package/.agents/skills/ui-ux-pro-max/SKILL.md +704 -0
- package/.agents/skills/ui-ux-pro-max/data/_sync_all.py +414 -0
- package/.agents/skills/ui-ux-pro-max/data/app-interface.csv +31 -0
- package/.agents/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/.agents/skills/ui-ux-pro-max/data/colors.csv +162 -0
- package/.agents/skills/ui-ux-pro-max/data/design.csv +1776 -0
- package/.agents/skills/ui-ux-pro-max/data/draft.csv +1779 -0
- package/.agents/skills/ui-ux-pro-max/data/google-fonts.csv +1924 -0
- package/.agents/skills/ui-ux-pro-max/data/icons.csv +106 -0
- package/.agents/skills/ui-ux-pro-max/data/landing.csv +35 -0
- package/.agents/skills/ui-ux-pro-max/data/motion.csv +17 -0
- package/.agents/skills/ui-ux-pro-max/data/products.csv +162 -0
- package/.agents/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/angular.csv +51 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/laravel.csv +51 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/threejs.csv +54 -0
- package/.agents/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.agents/skills/ui-ux-pro-max/data/styles.csv +85 -0
- package/.agents/skills/ui-ux-pro-max/data/typography.csv +74 -0
- package/.agents/skills/ui-ux-pro-max/data/ui-reasoning.csv +162 -0
- package/.agents/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.agents/skills/ui-ux-pro-max/scripts/core.py +274 -0
- package/.agents/skills/ui-ux-pro-max/scripts/design_system.py +1329 -0
- package/.agents/skills/ui-ux-pro-max/scripts/search.py +127 -0
- package/.agents/skills/vercel-cli-with-tokens/SKILL.md +353 -0
- package/.agents/skills/vercel-composition-patterns/AGENTS.md +946 -0
- package/.agents/skills/vercel-composition-patterns/README.md +60 -0
- package/.agents/skills/vercel-composition-patterns/SKILL.md +89 -0
- package/.agents/skills/vercel-composition-patterns/metadata.json +11 -0
- package/.agents/skills/vercel-composition-patterns/rules/_sections.md +29 -0
- package/.agents/skills/vercel-composition-patterns/rules/_template.md +24 -0
- package/.agents/skills/vercel-composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
- package/.agents/skills/vercel-composition-patterns/rules/architecture-compound-components.md +112 -0
- package/.agents/skills/vercel-composition-patterns/rules/patterns-children-over-render-props.md +87 -0
- package/.agents/skills/vercel-composition-patterns/rules/patterns-explicit-variants.md +100 -0
- package/.agents/skills/vercel-composition-patterns/rules/react19-no-forwardref.md +42 -0
- package/.agents/skills/vercel-composition-patterns/rules/state-context-interface.md +191 -0
- package/.agents/skills/vercel-composition-patterns/rules/state-decouple-implementation.md +113 -0
- package/.agents/skills/vercel-composition-patterns/rules/state-lift-state.md +125 -0
- package/.agents/skills/vercel-optimize/AGENTS.md +48 -0
- package/.agents/skills/vercel-optimize/CONTRIBUTING.md +41 -0
- package/.agents/skills/vercel-optimize/README.md +91 -0
- package/.agents/skills/vercel-optimize/SKILL.md +322 -0
- package/.agents/skills/vercel-optimize/lib/auth-route.mjs +23 -0
- package/.agents/skills/vercel-optimize/lib/budget-summary.mjs +182 -0
- package/.agents/skills/vercel-optimize/lib/citations.mjs +139 -0
- package/.agents/skills/vercel-optimize/lib/cost-coverage.mjs +143 -0
- package/.agents/skills/vercel-optimize/lib/dedup-recs.mjs +325 -0
- package/.agents/skills/vercel-optimize/lib/deep-dive.mjs +350 -0
- package/.agents/skills/vercel-optimize/lib/display-labels.mjs +185 -0
- package/.agents/skills/vercel-optimize/lib/extract-claims.mjs +550 -0
- package/.agents/skills/vercel-optimize/lib/framework-support.mjs +67 -0
- package/.agents/skills/vercel-optimize/lib/gates/build-minutes-fanout.mjs +69 -0
- package/.agents/skills/vercel-optimize/lib/gates/cold-start.mjs +66 -0
- package/.agents/skills/vercel-optimize/lib/gates/contract.mjs +79 -0
- package/.agents/skills/vercel-optimize/lib/gates/cwv-poor.mjs +87 -0
- package/.agents/skills/vercel-optimize/lib/gates/external-api-slow.mjs +55 -0
- package/.agents/skills/vercel-optimize/lib/gates/hard-gates.mjs +73 -0
- package/.agents/skills/vercel-optimize/lib/gates/index.mjs +45 -0
- package/.agents/skills/vercel-optimize/lib/gates/isr-overrevalidation.mjs +62 -0
- package/.agents/skills/vercel-optimize/lib/gates/middleware-heavy.mjs +51 -0
- package/.agents/skills/vercel-optimize/lib/gates/observability-events-attribution.mjs +56 -0
- package/.agents/skills/vercel-optimize/lib/gates/platform-bot-protection.mjs +115 -0
- package/.agents/skills/vercel-optimize/lib/gates/platform-fluid-compute.mjs +83 -0
- package/.agents/skills/vercel-optimize/lib/gates/region-misconfig.mjs +64 -0
- package/.agents/skills/vercel-optimize/lib/gates/route-errors.mjs +80 -0
- package/.agents/skills/vercel-optimize/lib/gates/scanner-driven.mjs +122 -0
- package/.agents/skills/vercel-optimize/lib/gates/select-candidates.mjs +134 -0
- package/.agents/skills/vercel-optimize/lib/gates/slow-route.mjs +88 -0
- package/.agents/skills/vercel-optimize/lib/gates/types.d.ts +38 -0
- package/.agents/skills/vercel-optimize/lib/gates/uncached-route.mjs +93 -0
- package/.agents/skills/vercel-optimize/lib/gates/usage-spike-triage.mjs +121 -0
- package/.agents/skills/vercel-optimize/lib/grade-recommendation.mjs +155 -0
- package/.agents/skills/vercel-optimize/lib/impact-label.mjs +126 -0
- package/.agents/skills/vercel-optimize/lib/impact-magnitude.mjs +60 -0
- package/.agents/skills/vercel-optimize/lib/investigation-brief.mjs +610 -0
- package/.agents/skills/vercel-optimize/lib/observation-safety.mjs +174 -0
- package/.agents/skills/vercel-optimize/lib/project-facts.mjs +99 -0
- package/.agents/skills/vercel-optimize/lib/queries.mjs +315 -0
- package/.agents/skills/vercel-optimize/lib/reconcile-candidates.mjs +372 -0
- package/.agents/skills/vercel-optimize/lib/render-report.mjs +955 -0
- package/.agents/skills/vercel-optimize/lib/repo-root.mjs +86 -0
- package/.agents/skills/vercel-optimize/lib/route-normalize.mjs +220 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/bot-protection-certainty.mjs +38 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/cache-tag-invalidation-certainty.mjs +30 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/count-correct.mjs +52 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/function-duration-invocations.mjs +38 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/index.mjs +79 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/middleware-conflict.mjs +36 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/missing-citation.mjs +16 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/pre-release.mjs +74 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/rate-limit.mjs +67 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/rendering-mode-mislabel.mjs +38 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/undeclared-dep.mjs +78 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/vercel-directive-strip.mjs +37 -0
- package/.agents/skills/vercel-optimize/lib/sanitizers/window-units.mjs +32 -0
- package/.agents/skills/vercel-optimize/lib/scanners/cache-components-suspense-dedupe.mjs +109 -0
- package/.agents/skills/vercel-optimize/lib/scanners/edge-heavy-import.mjs +94 -0
- package/.agents/skills/vercel-optimize/lib/scanners/force-dynamic.mjs +42 -0
- package/.agents/skills/vercel-optimize/lib/scanners/headers-in-page.mjs +44 -0
- package/.agents/skills/vercel-optimize/lib/scanners/index.mjs +35 -0
- package/.agents/skills/vercel-optimize/lib/scanners/large-static-asset.mjs +92 -0
- package/.agents/skills/vercel-optimize/lib/scanners/max-age-without-s-maxage.mjs +42 -0
- package/.agents/skills/vercel-optimize/lib/scanners/middleware-broad-matcher.mjs +55 -0
- package/.agents/skills/vercel-optimize/lib/scanners/missing-cache-headers.mjs +90 -0
- package/.agents/skills/vercel-optimize/lib/scanners/prisma-include-tree.mjs +42 -0
- package/.agents/skills/vercel-optimize/lib/scanners/region-pin-in-config.mjs +88 -0
- package/.agents/skills/vercel-optimize/lib/scanners/source-maps-production.mjs +36 -0
- package/.agents/skills/vercel-optimize/lib/scanners/sveltekit-prerender-missing.mjs +43 -0
- package/.agents/skills/vercel-optimize/lib/scanners/turbo-force-bypass.mjs +129 -0
- package/.agents/skills/vercel-optimize/lib/scanners/unoptimized-image.mjs +113 -0
- package/.agents/skills/vercel-optimize/lib/scanners/use-cache-date-stamp.mjs +106 -0
- package/.agents/skills/vercel-optimize/lib/support-topics.mjs +355 -0
- package/.agents/skills/vercel-optimize/lib/throttle.mjs +273 -0
- package/.agents/skills/vercel-optimize/lib/util.mjs +17 -0
- package/.agents/skills/vercel-optimize/lib/vercel.mjs +864 -0
- package/.agents/skills/vercel-optimize/lib/verify-claim.mjs +1296 -0
- package/.agents/skills/vercel-optimize/lib/workspace-resolver.mjs +521 -0
- package/.agents/skills/vercel-optimize/metadata.json +14 -0
- package/.agents/skills/vercel-optimize/references/candidates.md +176 -0
- package/.agents/skills/vercel-optimize/references/data-collection.md +218 -0
- package/.agents/skills/vercel-optimize/references/docs-library.json +683 -0
- package/.agents/skills/vercel-optimize/references/doctrine.md +105 -0
- package/.agents/skills/vercel-optimize/references/observability-plus.md +108 -0
- package/.agents/skills/vercel-optimize/references/playbooks/README.md +53 -0
- package/.agents/skills/vercel-optimize/references/playbooks/ai-application.md +32 -0
- package/.agents/skills/vercel-optimize/references/playbooks/api-service.md +30 -0
- package/.agents/skills/vercel-optimize/references/playbooks/content-site.md +30 -0
- package/.agents/skills/vercel-optimize/references/playbooks/ecommerce.md +30 -0
- package/.agents/skills/vercel-optimize/references/playbooks/marketing.md +30 -0
- package/.agents/skills/vercel-optimize/references/playbooks/saas.md +31 -0
- package/.agents/skills/vercel-optimize/references/playbooks/sveltekit.md +75 -0
- package/.agents/skills/vercel-optimize/references/recommendations.md +203 -0
- package/.agents/skills/vercel-optimize/references/scanner-patterns.md +251 -0
- package/.agents/skills/vercel-optimize/references/scoring.md +205 -0
- package/.agents/skills/vercel-optimize/references/support-topics/README.md +46 -0
- package/.agents/skills/vercel-optimize/references/support-topics/astro-edge-middleware-scope.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/astro-output-mode-and-isr.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/auth-preserving-parallelization.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/bot-protection-product-guardrails.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/build-minutes-monorepo-fanout.md +23 -0
- package/.agents/skills/vercel-optimize/references/support-topics/cache-components-static-shell-boundaries.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/cache-components-suspense-dedupe-pitfall.md +23 -0
- package/.agents/skills/vercel-optimize/references/support-topics/cdn-cache-auth-safety.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/cold-start-initialization-bundle.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/core-web-vitals-client-bottlenecks.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/database-egress-pooling-region.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/dynamic-rendering-traps.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/external-api-critical-path-platform.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/external-api-critical-path.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/fast-data-transfer-payloads.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/fluid-compute-caveats.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/function-duration-io-and-after.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/function-invocation-reduction.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/function-region-misconfiguration-ttfb.md +23 -0
- package/.agents/skills/vercel-optimize/references/support-topics/image-optimization-cost-control.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/isr-revalidation-static-generation.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/middleware-proxy-edge-cost.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/next-fetch-revalidate-floor.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/next-font-cls-self-hosting.md +23 -0
- package/.agents/skills/vercel-optimize/references/support-topics/next-heavy-ui-lazy-load-boundaries.md +23 -0
- package/.agents/skills/vercel-optimize/references/support-topics/next-image-lcp-preload-sizes.md +23 -0
- package/.agents/skills/vercel-optimize/references/support-topics/next-route-handler-get-cache-defaults.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/next-script-third-party-strategy.md +23 -0
- package/.agents/skills/vercel-optimize/references/support-topics/nextjs-version-cache-semantics.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/not-found-catchall-request-waste.md +23 -0
- package/.agents/skills/vercel-optimize/references/support-topics/nuxt-route-rules-cache-isr.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/observability-events-cost-attribution.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/post-response-work-waituntil.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/route-error-durable-offload.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/route-error-runtime-limits.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/runtime-cache-reusable-data.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/sveltekit-isr-prerender-safety.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/sveltekit-split-cold-start-tradeoff.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/usage-spike-triage.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/use-cache-date-stamp-isr-write-amplifier.md +23 -0
- package/.agents/skills/vercel-optimize/references/support-topics/use-cache-remote-shared-origin-data.md +22 -0
- package/.agents/skills/vercel-optimize/references/support-topics/workflow-resumable-stream-routes.md +23 -0
- package/.agents/skills/vercel-optimize/references/verification.md +102 -0
- package/.agents/skills/vercel-optimize/references/voice.md +76 -0
- package/.agents/skills/vercel-optimize/scripts/budget-summary.mjs +56 -0
- package/.agents/skills/vercel-optimize/scripts/build-docs.mjs +74 -0
- package/.agents/skills/vercel-optimize/scripts/check-citations.mjs +81 -0
- package/.agents/skills/vercel-optimize/scripts/check-docs-fresh.mjs +93 -0
- package/.agents/skills/vercel-optimize/scripts/collect-signals.mjs +576 -0
- package/.agents/skills/vercel-optimize/scripts/collect-sub-agent-outputs.mjs +296 -0
- package/.agents/skills/vercel-optimize/scripts/deep-dive.mjs +319 -0
- package/.agents/skills/vercel-optimize/scripts/gate-investigations.mjs +166 -0
- package/.agents/skills/vercel-optimize/scripts/merge-signals.mjs +192 -0
- package/.agents/skills/vercel-optimize/scripts/prepare-investigation-brief.mjs +231 -0
- package/.agents/skills/vercel-optimize/scripts/reconcile-candidates.mjs +62 -0
- package/.agents/skills/vercel-optimize/scripts/render-report.mjs +437 -0
- package/.agents/skills/vercel-optimize/scripts/scan-codebase.mjs +313 -0
- package/.agents/skills/vercel-optimize/scripts/verify-and-regen.mjs +346 -0
- package/.agents/skills/vercel-optimize/scripts/verify-finding.mjs +19 -0
- package/.agents/skills/vercel-react-best-practices/AGENTS.md +3810 -0
- package/.agents/skills/vercel-react-best-practices/README.md +123 -0
- package/.agents/skills/vercel-react-best-practices/SKILL.md +149 -0
- package/.agents/skills/vercel-react-best-practices/metadata.json +15 -0
- package/.agents/skills/vercel-react-best-practices/rules/_sections.md +46 -0
- package/.agents/skills/vercel-react-best-practices/rules/_template.md +28 -0
- package/.agents/skills/vercel-react-best-practices/rules/advanced-effect-event-deps.md +56 -0
- package/.agents/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/.agents/skills/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
- package/.agents/skills/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
- package/.agents/skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
- package/.agents/skills/vercel-react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
- package/.agents/skills/vercel-react-best-practices/rules/async-defer-await.md +82 -0
- package/.agents/skills/vercel-react-best-practices/rules/async-dependencies.md +51 -0
- package/.agents/skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
- package/.agents/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/.agents/skills/vercel-react-best-practices/rules/bundle-analyzable-paths.md +63 -0
- package/.agents/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +60 -0
- package/.agents/skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
- package/.agents/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/.agents/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/.agents/skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
- package/.agents/skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
- package/.agents/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/.agents/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/.agents/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-flatmap-filter.md +60 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-request-idle-callback.md +105 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-resource-hints.md +85 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md +68 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-no-inline-components.md +82 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-use-deferred-value.md +59 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-hoist-static-io.md +149 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-no-shared-module-state.md +50 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-parallel-nested-fetching.md +34 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
- package/.agents/skills/vercel-react-native-skills/AGENTS.md +2897 -0
- package/.agents/skills/vercel-react-native-skills/README.md +165 -0
- package/.agents/skills/vercel-react-native-skills/SKILL.md +121 -0
- package/.agents/skills/vercel-react-native-skills/metadata.json +16 -0
- package/.agents/skills/vercel-react-native-skills/rules/_sections.md +86 -0
- package/.agents/skills/vercel-react-native-skills/rules/_template.md +28 -0
- package/.agents/skills/vercel-react-native-skills/rules/animation-derived-value.md +53 -0
- package/.agents/skills/vercel-react-native-skills/rules/animation-gesture-detector-press.md +95 -0
- package/.agents/skills/vercel-react-native-skills/rules/animation-gpu-properties.md +65 -0
- package/.agents/skills/vercel-react-native-skills/rules/design-system-compound-components.md +66 -0
- package/.agents/skills/vercel-react-native-skills/rules/fonts-config-plugin.md +71 -0
- package/.agents/skills/vercel-react-native-skills/rules/imports-design-system-folder.md +68 -0
- package/.agents/skills/vercel-react-native-skills/rules/js-hoist-intl.md +61 -0
- package/.agents/skills/vercel-react-native-skills/rules/list-performance-callbacks.md +44 -0
- package/.agents/skills/vercel-react-native-skills/rules/list-performance-function-references.md +132 -0
- package/.agents/skills/vercel-react-native-skills/rules/list-performance-images.md +53 -0
- package/.agents/skills/vercel-react-native-skills/rules/list-performance-inline-objects.md +97 -0
- package/.agents/skills/vercel-react-native-skills/rules/list-performance-item-expensive.md +94 -0
- package/.agents/skills/vercel-react-native-skills/rules/list-performance-item-memo.md +82 -0
- package/.agents/skills/vercel-react-native-skills/rules/list-performance-item-types.md +104 -0
- package/.agents/skills/vercel-react-native-skills/rules/list-performance-virtualize.md +67 -0
- package/.agents/skills/vercel-react-native-skills/rules/monorepo-native-deps-in-app.md +46 -0
- package/.agents/skills/vercel-react-native-skills/rules/monorepo-single-dependency-versions.md +63 -0
- package/.agents/skills/vercel-react-native-skills/rules/navigation-native-navigators.md +188 -0
- package/.agents/skills/vercel-react-native-skills/rules/react-compiler-destructure-functions.md +50 -0
- package/.agents/skills/vercel-react-native-skills/rules/react-compiler-reanimated-shared-values.md +48 -0
- package/.agents/skills/vercel-react-native-skills/rules/react-state-dispatcher.md +91 -0
- package/.agents/skills/vercel-react-native-skills/rules/react-state-fallback.md +56 -0
- package/.agents/skills/vercel-react-native-skills/rules/react-state-minimize.md +65 -0
- package/.agents/skills/vercel-react-native-skills/rules/rendering-no-falsy-and.md +74 -0
- package/.agents/skills/vercel-react-native-skills/rules/rendering-text-in-text-component.md +36 -0
- package/.agents/skills/vercel-react-native-skills/rules/scroll-position-no-state.md +82 -0
- package/.agents/skills/vercel-react-native-skills/rules/state-ground-truth.md +80 -0
- package/.agents/skills/vercel-react-native-skills/rules/ui-expo-image.md +66 -0
- package/.agents/skills/vercel-react-native-skills/rules/ui-image-gallery.md +104 -0
- package/.agents/skills/vercel-react-native-skills/rules/ui-measure-views.md +78 -0
- package/.agents/skills/vercel-react-native-skills/rules/ui-menus.md +174 -0
- package/.agents/skills/vercel-react-native-skills/rules/ui-native-modals.md +77 -0
- package/.agents/skills/vercel-react-native-skills/rules/ui-pressable.md +61 -0
- package/.agents/skills/vercel-react-native-skills/rules/ui-safe-area-scroll.md +65 -0
- package/.agents/skills/vercel-react-native-skills/rules/ui-scrollview-content-inset.md +45 -0
- package/.agents/skills/vercel-react-native-skills/rules/ui-styling.md +87 -0
- package/.agents/skills/vercel-react-view-transitions/AGENTS.md +955 -0
- package/.agents/skills/vercel-react-view-transitions/README.md +42 -0
- package/.agents/skills/vercel-react-view-transitions/SKILL.md +320 -0
- package/.agents/skills/vercel-react-view-transitions/metadata.json +12 -0
- package/.agents/skills/vercel-react-view-transitions/references/css-recipes.md +242 -0
- package/.agents/skills/vercel-react-view-transitions/references/implementation.md +182 -0
- package/.agents/skills/vercel-react-view-transitions/references/nextjs.md +176 -0
- package/.agents/skills/vercel-react-view-transitions/references/patterns.md +262 -0
- package/.agents/skills/web-design-guidelines/SKILL.md +39 -0
- package/.agents/skills/workflow-metrics/SKILL.md +18 -0
- package/.agents/skills/writing-guidelines/SKILL.md +39 -0
- package/CODING_STANDARDS.md +49 -0
- package/LICENSE +21 -0
- package/README.md +556 -0
- package/VERSION +1 -0
- package/bin/devos.js +893 -0
- package/docs/.gitkeep +0 -0
- package/docs/ARCHITECTURE.md +114 -0
- package/docs/CHANGELOG.md +61 -0
- package/docs/CURRENT_STATE.md +39 -0
- package/docs/FIELD_REPORT_2026-08-20.md +130 -0
- package/docs/GETTING_STARTED.md +130 -0
- package/docs/LESSONS.md +24 -0
- package/docs/PRE_COMMIT_HOOK.md +152 -0
- package/docs/SLASH_COMMANDS.md +116 -0
- package/docs/TUTORIAL.md +75 -0
- package/package.json +54 -0
- package/scripts/smoke-test.js +167 -0
package/.agents/skills/modern-web-guidance/guides/user-experience/scroll-snap-realtime-feedback.md
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
## Overview
|
|
2
|
+
Users expect immediate visual feedback when interacting with UI elements like carousels or galleries. Traditional scroll snap only provides feedback *after* the scroll gesture completes and the element settles. By using Scroll Snap Events, specifically `scrollsnapchanging`, you can provide real-time feedback during the scroll gesture, highlighting the pending snap target before the user releases their touch or mouse.
|
|
3
|
+
|
|
4
|
+
## Implementation
|
|
5
|
+
|
|
6
|
+
### 1. Listen for `scrollsnapchanging`
|
|
7
|
+
Attach an event listener for `scrollsnapchanging` to the scroll container. This event fires when the browser determines a new snap target is likely to be selected.
|
|
8
|
+
|
|
9
|
+
```javascript
|
|
10
|
+
const container = document.querySelector('#gallery');
|
|
11
|
+
const thumbnails = document.querySelectorAll('.thumbnail');
|
|
12
|
+
const items = document.querySelectorAll('.gallery-item');
|
|
13
|
+
|
|
14
|
+
container.addEventListener('scrollsnapchanging', (event) => {
|
|
15
|
+
// Highlight pending snap target during scroll for real-time feedback.
|
|
16
|
+
const pendingTarget = event.snapTargetInline;
|
|
17
|
+
const index = [...items].indexOf(pendingTarget);
|
|
18
|
+
|
|
19
|
+
if (index === -1 || !thumbnails[index]) return;
|
|
20
|
+
|
|
21
|
+
// Use lightweight class toggle to avoid layout thrashing during rapid events.
|
|
22
|
+
// Note: aria-current is NOT toggled here. It tracks the settled "current"
|
|
23
|
+
// item, which is updated in the scrollsnapchange handler below.
|
|
24
|
+
thumbnails.forEach((thumb) => thumb.classList.remove('pending'));
|
|
25
|
+
thumbnails[index].classList.add('pending');
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
This example uses `snapTargetInline` because the gallery scrolls horizontally. If your scroll container scrolls vertically, use `snapTargetBlock` instead.
|
|
30
|
+
|
|
31
|
+
### 2. Listen for `scrollsnapchange`
|
|
32
|
+
To finalize the state when the scroll gesture completes and the element actually snaps, listen for the `scrollsnapchange` event. This is required to establish the final active state.
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
container.addEventListener('scrollsnapchange', (event) => {
|
|
36
|
+
// Promote pending state to active on scroll completion.
|
|
37
|
+
const snappedTarget = event.snapTargetInline;
|
|
38
|
+
const index = [...items].indexOf(snappedTarget);
|
|
39
|
+
|
|
40
|
+
if (index === -1 || !thumbnails[index]) return;
|
|
41
|
+
|
|
42
|
+
// Establish final active state and clean up pending.
|
|
43
|
+
thumbnails.forEach((thumb) => {
|
|
44
|
+
thumb.classList.remove('pending', 'active');
|
|
45
|
+
thumb.removeAttribute('aria-current');
|
|
46
|
+
});
|
|
47
|
+
thumbnails[index].classList.add('active');
|
|
48
|
+
thumbnails[index].setAttribute('aria-current', 'true');
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 3. Sync initial state
|
|
53
|
+
When the page loads, the scroll position might be restored by the browser (e.g., via history traversal or an anchor link). Neither `scrollsnapchange` nor `scroll` events will fire automatically. Run a one-off geometric check to sync the UI with the initial scroll position.
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
// Note: For item.offsetLeft to be relative to the container,
|
|
57
|
+
// the container MUST be the offsetParent (e.g., `position: relative`).
|
|
58
|
+
const findClosestItemIndex = () => {
|
|
59
|
+
// Center-distance assumes scroll-snap-align: center on items.
|
|
60
|
+
// For start-aligned snap, compare scrollLeft to item.offsetLeft directly.
|
|
61
|
+
const containerCenter = container.scrollLeft + container.clientWidth / 2;
|
|
62
|
+
let closestIndex = 0;
|
|
63
|
+
let minDistance = Infinity;
|
|
64
|
+
|
|
65
|
+
items.forEach((item, index) => {
|
|
66
|
+
const itemCenter = item.offsetLeft + item.offsetWidth / 2;
|
|
67
|
+
const distance = Math.abs(containerCenter - itemCenter);
|
|
68
|
+
if (distance < minDistance) {
|
|
69
|
+
minDistance = distance;
|
|
70
|
+
closestIndex = index;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
return closestIndex;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const initActiveItem = () => {
|
|
77
|
+
const closestIndex = findClosestItemIndex();
|
|
78
|
+
if (!thumbnails[closestIndex]) return;
|
|
79
|
+
|
|
80
|
+
thumbnails.forEach((thumb) => {
|
|
81
|
+
thumb.classList.remove('pending', 'active');
|
|
82
|
+
thumb.removeAttribute('aria-current');
|
|
83
|
+
});
|
|
84
|
+
thumbnails[closestIndex].classList.add('active');
|
|
85
|
+
thumbnails[closestIndex].setAttribute('aria-current', 'true');
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
if (document.readyState === 'complete') {
|
|
89
|
+
initActiveItem();
|
|
90
|
+
} else {
|
|
91
|
+
window.addEventListener('load', initActiveItem, { once: true });
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Fallback strategies
|
|
96
|
+
Scroll snap events has limited availability.
|
|
97
|
+
Supported by: Chrome 129 (Sep 2024) and Edge 129 (Sep 2024).
|
|
98
|
+
Unsupported in: Firefox and Safari.
|
|
99
|
+
Baseline status for Scroll snap: Widely available. It's been Baseline since 2020-01-15.
|
|
100
|
+
Supported by: Chrome 69 (Sep 2018), Edge 79 (Jan 2020), Firefox 68 (Jul 2019), and Safari 11 (Sep 2017).
|
|
101
|
+
|
|
102
|
+
For browsers that do not support `scrollsnapchanging`, the UI will not provide eager feedback during the scroll gesture by default, and the linked UI will desynchronize from the content.
|
|
103
|
+
|
|
104
|
+
**MANDATORY:** Provide a fallback for browsers without support, or the linked UI will desynchronize from the content.
|
|
105
|
+
|
|
106
|
+
**DO** simulate the real-time nature of `scrollsnapchanging` with a `scroll` event listener coupled with `requestAnimationFrame` and geometric distance calculations to determine the closest snap target while the user is actively scrolling.
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
if ('onscrollsnapchanging' in Element.prototype) {
|
|
110
|
+
// Use native scroll snap events
|
|
111
|
+
} else {
|
|
112
|
+
// Fallback: use scroll + requestAnimationFrame for eager feedback
|
|
113
|
+
// (assumes the same container, thumbnails, items defined in step 1)
|
|
114
|
+
let scrollTimeout;
|
|
115
|
+
let rafId = null;
|
|
116
|
+
|
|
117
|
+
const promotePendingToActive = () => {
|
|
118
|
+
const closestIndex = findClosestItemIndex();
|
|
119
|
+
if (!thumbnails[closestIndex]) return;
|
|
120
|
+
thumbnails.forEach((thumb) => {
|
|
121
|
+
thumb.classList.remove('pending', 'active');
|
|
122
|
+
thumb.removeAttribute('aria-current');
|
|
123
|
+
});
|
|
124
|
+
thumbnails[closestIndex].classList.add('active');
|
|
125
|
+
thumbnails[closestIndex].setAttribute('aria-current', 'true');
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
container.addEventListener('scroll', () => {
|
|
129
|
+
if (rafId) return;
|
|
130
|
+
rafId = requestAnimationFrame(() => {
|
|
131
|
+
rafId = null;
|
|
132
|
+
const closestIndex = findClosestItemIndex();
|
|
133
|
+
if (!thumbnails[closestIndex]) return;
|
|
134
|
+
|
|
135
|
+
// DO NOT forget to clean up stale pending classes
|
|
136
|
+
thumbnails.forEach((thumb) => thumb.classList.remove('pending'));
|
|
137
|
+
thumbnails[closestIndex].classList.add('pending');
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Debounce fallback for browsers that don't support scrollend
|
|
141
|
+
clearTimeout(scrollTimeout);
|
|
142
|
+
scrollTimeout = setTimeout(promotePendingToActive, 100);
|
|
143
|
+
}, { passive: true });
|
|
144
|
+
|
|
145
|
+
// Fallback: use Baseline `scrollend` event to promote pending to active cleanly where supported
|
|
146
|
+
container.addEventListener('scrollend', () => {
|
|
147
|
+
clearTimeout(scrollTimeout);
|
|
148
|
+
promotePendingToActive();
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
The geometric `scroll` + `requestAnimationFrame` fallback closely emulates the behavior of native snap prediction, including handling programmatic scrolling correctly. Because functions like `scrollIntoView` naturally fire `scroll` events during their execution, the UI will stay smoothly synchronized throughout the scroll animation without requiring additional custom logic.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Synchronizing UI state with a scrollable container's snap position traditionally required complex scroll event listeners, manual calculations of scroll offsets, and intersection observers. The `scrollsnapchange` event provides a native, efficient way to detect when a scroller has settled on a new snap target, making it useful for synchronizing sidebars or highlighting the active section in a table of contents.
|
|
2
|
+
|
|
3
|
+
## Implementation
|
|
4
|
+
|
|
5
|
+
### 1. Configure Scroll Snap in CSS
|
|
6
|
+
The container must have `scroll-snap-type` defined, and have children with `scroll-snap-align` for the browser to track snap targets. In a long article with a table of contents, you can use this to snap section headers to the top of the viewport.
|
|
7
|
+
|
|
8
|
+
```css
|
|
9
|
+
main {
|
|
10
|
+
/* Enable scroll snapping on the container */
|
|
11
|
+
scroll-snap-type: y proximity;
|
|
12
|
+
overflow-y: auto;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
h2 {
|
|
16
|
+
/* Define how headers align when snapped */
|
|
17
|
+
scroll-snap-align: start;
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### 2. Listen for Snap Changes
|
|
22
|
+
Use the `scrollsnapchange` event on the scroll container to react when the user finishes scrolling and the browser snaps to a new element. In our TOC demo, we use this to highlight the active link in the sidebar.
|
|
23
|
+
|
|
24
|
+
```html
|
|
25
|
+
<!-- MANDATORY: Wrap table of contents links inside a proper navigation landmark -->
|
|
26
|
+
<nav aria-label="Table of contents">
|
|
27
|
+
<ul>
|
|
28
|
+
<li><a href="#section-1" aria-current="location">Section 1</a></li>
|
|
29
|
+
<li><a href="#section-2">Section 2</a></li>
|
|
30
|
+
</ul>
|
|
31
|
+
</nav>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
const main = document.getElementById('main');
|
|
36
|
+
const links = document.querySelectorAll('nav a');
|
|
37
|
+
|
|
38
|
+
// The event fires when the scroller settles on a new snap target
|
|
39
|
+
main.addEventListener('scrollsnapchange', (event) => {
|
|
40
|
+
// Use snapTargetBlock for vertical or snapTargetInline for horizontal
|
|
41
|
+
const snappedHeader = event.snapTargetBlock;
|
|
42
|
+
|
|
43
|
+
if (snappedHeader) {
|
|
44
|
+
setSelectedParagraph(snappedHeader.id);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
## Accessibility
|
|
51
|
+
|
|
52
|
+
Caution: While Scroll Snap Events make it possible to visually synchronize other content to the state of the scroller, it does not automatically expose that information programmatically. Relationships between elements, active states, and live content must be reflected in the Accessibility Tree.
|
|
53
|
+
|
|
54
|
+
For a table of contents, ensure the sidebar links use `aria-current="true"` or `aria-current="location"` when they are active.
|
|
55
|
+
|
|
56
|
+
In addition, be careful when using the `mandatory` value for `scroll-snap-type`, as it can cause content in-between snap-points to become inaccessible when longer than the screen.
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
## Fallback strategies
|
|
60
|
+
|
|
61
|
+
Scroll snap events has limited availability.
|
|
62
|
+
Supported by: Chrome 129 (Sep 2024) and Edge 129 (Sep 2024).
|
|
63
|
+
Unsupported in: Firefox and Safari.
|
|
64
|
+
|
|
65
|
+
If `scrollsnapchange` is not supported, use `IntersectionObserver` to detect which element is currently at the top of the scroller. Note this is different behavior than `scrollsnapchange`, as this will trigger while the scroll happens, rather than only when the scroll has settled.
|
|
66
|
+
|
|
67
|
+
```javascript
|
|
68
|
+
// Feature detect support for scroll snap events
|
|
69
|
+
if (!('onscrollsnapchange' in HTMLElement.prototype)) {
|
|
70
|
+
const observer = new IntersectionObserver(
|
|
71
|
+
() => {
|
|
72
|
+
// Each time the set of intersecting headers changes, find the top
|
|
73
|
+
// header that is visible.
|
|
74
|
+
const topEntry = [...headers].reduce((currentTop, header) => {
|
|
75
|
+
// Use the bottom to handle scrolling up, when the top is still offscreen
|
|
76
|
+
const {bottom} = header.getBoundingClientRect();
|
|
77
|
+
// Don't match if the header's bottom is aboce the scrollport
|
|
78
|
+
if (bottom < 0) return;
|
|
79
|
+
if (!currentTop) return header;
|
|
80
|
+
return bottom <
|
|
81
|
+
currentTop.getBoundingClientRect().bottom
|
|
82
|
+
? header
|
|
83
|
+
: currentTop;
|
|
84
|
+
}, undefined);
|
|
85
|
+
if (topEntry) setSelectedParagraph(topEntry.id);
|
|
86
|
+
},
|
|
87
|
+
{ root: main, threshold: 0.9 // Adjust based on your use case },
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
// Observe all snap targets (e.g., section headers)
|
|
91
|
+
document.querySelectorAll('h2').forEach(header => observer.observe(header));
|
|
92
|
+
}
|
|
93
|
+
```
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Set a scroll target for the initial render
|
|
2
|
+
|
|
3
|
+
The CSS property `scroll-initial-target` offers a declarative, CSS-only way to bring a specific descendant element into the visible area of its scroll container as soon as that container is rendered. Previously, developers relied on JavaScript (`Element.scrollIntoView()`) or URL fragment identifiers (`#item-id`), both of which have limitations and are tricky to implement.
|
|
4
|
+
|
|
5
|
+
## How to Implement
|
|
6
|
+
|
|
7
|
+
To implement this successfully:
|
|
8
|
+
|
|
9
|
+
1. **Ensure a scroll container:** The target element must be inside a scroll container (an element with overflow that allows scrolling, such as `overflow: auto`). This can be any ancestor element, including the root `<html>` element.
|
|
10
|
+
2. **Target the Item:** Apply `scroll-initial-target: nearest` to the specific descendant element you want to bring into view.
|
|
11
|
+
|
|
12
|
+
## Example Code: Vertical Media Feed
|
|
13
|
+
|
|
14
|
+
In this example, a feed starts scrolled to a specific "featured" item rather than the very top of the list.
|
|
15
|
+
|
|
16
|
+
```css
|
|
17
|
+
/**
|
|
18
|
+
* TARGET: The item that should be visible on initial load.
|
|
19
|
+
*/
|
|
20
|
+
.item.target {
|
|
21
|
+
scroll-initial-target: nearest;
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Strategic Implementation & Best Practices
|
|
26
|
+
|
|
27
|
+
- **DO** use `scroll-initial-target` for "middle-start" experiences, such as a calendar starting on the current day or a gallery starting on a specific image.
|
|
28
|
+
- **DO NOT** confuse this with accessibility focus. This property only moves the **visual** viewport; it does not move the keyboard focus. You must manually manage `element.focus()` if the target is intended to be the starting point for keyboard users.
|
|
29
|
+
- **DO NOT** use this if you need a smooth "scrolling" animation on load; this property is discrete and sets the position instantly during the layout phase.
|
|
30
|
+
- **DO NOT** set `scroll-initial-target` on multiple elements within the same scrollable container. If multiple elements specify `scroll-initial-target: nearest`, the browser selects the one that appears first in the DOM tree order.
|
|
31
|
+
- **DO** provide dimensions for media. Since the scroll position is calculated during initial layout, ensure images or videos have `aspect-ratio` or fixed `height`/`width` to prevent the target from shifting after the media loads.
|
|
32
|
+
- **DO** account for the **Precedence Hierarchy**: A URL fragment (e.g., `example.com/#top`) and the container-level `scroll-start` property both take precedence over `scroll-initial-target`.
|
|
33
|
+
|
|
34
|
+
## Fallback Strategy
|
|
35
|
+
|
|
36
|
+
scroll-initial-target has limited availability.
|
|
37
|
+
Supported by: Chrome 133 (Feb 2025) and Edge 133 (Feb 2025).
|
|
38
|
+
Unsupported in: Firefox and Safari.
|
|
39
|
+
|
|
40
|
+
For browsers that do not yet support the API, use a JavaScript fallback. Use the `DOMContentLoaded` event to ensure the browser scrolls the element into view as soon as the HTML parsing completes, providing a faster experience than waiting for all images and resources to load. Alternatively, placing the script at the end of the `<body>` element is also acceptable and avoids the need for an event listener.
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
/**
|
|
44
|
+
* Progressive Enhancement Fallback
|
|
45
|
+
*/
|
|
46
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
47
|
+
// Check for native CSS support
|
|
48
|
+
if (!CSS.supports("scroll-initial-target", "nearest")) {
|
|
49
|
+
const feedTarget = document.querySelector(".item.target");
|
|
50
|
+
if (feedTarget) {
|
|
51
|
+
// 'block: center' ensures the featured media is centered in view
|
|
52
|
+
feedTarget.scrollIntoView({ behavior: "instant", block: "center" });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
```
|
package/.agents/skills/modern-web-guidance/guides/user-experience/scrollability-affordance-hints.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
## Overview
|
|
2
|
+
|
|
3
|
+
Visual hints, like shadows or gradients, help users understand that they can scroll to see more content. This guide shows how to build these hints using CSS `container-scroll-state-queries`, which allows styling elements based on the scrollable state of their container without relying on JavaScript scroll listeners or observers.
|
|
4
|
+
|
|
5
|
+
## Implementation
|
|
6
|
+
|
|
7
|
+
### 1. Establish the Scroll Container
|
|
8
|
+
|
|
9
|
+
The scroll container must be declared as a scroll-state query container.
|
|
10
|
+
|
|
11
|
+
```css
|
|
12
|
+
.scroller {
|
|
13
|
+
overflow-y: auto;
|
|
14
|
+
/* Establish this element as a scroll-state query container */
|
|
15
|
+
container-type: scroll-state;
|
|
16
|
+
position: relative;
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### 2. Style the Indicators
|
|
21
|
+
|
|
22
|
+
Place the indicator elements (like shadows, gradients, or arrows) inside the container and style them. By default, they should not be visible. When they are shown, they should not be interactive, by setting `pointer-events: none`.
|
|
23
|
+
|
|
24
|
+
```css
|
|
25
|
+
.indicator-top, .indicator-bottom {
|
|
26
|
+
position: sticky;
|
|
27
|
+
left: 0;
|
|
28
|
+
right: 0;
|
|
29
|
+
height: 20px;
|
|
30
|
+
opacity: 0;
|
|
31
|
+
transition: opacity 0.2s;
|
|
32
|
+
pointer-events: none; /* Let clicks pass through */
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.indicator-top {
|
|
36
|
+
top: 0;
|
|
37
|
+
background: linear-gradient(to bottom, rgba(0,0,0,0.2), transparent); /* Example: Shadow */
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.indicator-bottom {
|
|
41
|
+
bottom: 0;
|
|
42
|
+
background: linear-gradient(to top, rgba(0,0,0,0.2), transparent); /* Example: Shadow */
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 3. Query the Scroll State
|
|
47
|
+
|
|
48
|
+
Use the `@container` rule with the `scroll-state` function. Check if the container is scrollable up or down to show the respective indicator.
|
|
49
|
+
|
|
50
|
+
```css
|
|
51
|
+
/* Show top indicator when the user can scroll up */
|
|
52
|
+
@container scroll-state(scrollable: top) {
|
|
53
|
+
.indicator-top {
|
|
54
|
+
opacity: 1;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* Show bottom indicator when the user can scroll down */
|
|
59
|
+
@container scroll-state(scrollable: bottom) {
|
|
60
|
+
.indicator-bottom {
|
|
61
|
+
opacity: 1;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Fallback strategies
|
|
67
|
+
|
|
68
|
+
Container scroll-state queries has limited availability.
|
|
69
|
+
Supported by: Chrome 133 (Feb 2025) and Edge 133 (Feb 2025).
|
|
70
|
+
Unsupported in: Firefox and Safari.
|
|
71
|
+
|
|
72
|
+
### Basic Fallback
|
|
73
|
+
If the feature is not supported, the indicators will remain invisible. Since these are hints and not critical for functionality, it is acceptable to omit them in unsupported browsers.
|
|
74
|
+
|
|
75
|
+
### Advanced Fallback (Intersection Observer)
|
|
76
|
+
If the hints are required, use an `IntersectionObserver` to toggle classes when sentinel elements at the top and bottom of the scroller move in and out of the scrollport.
|
|
77
|
+
|
|
78
|
+
```html
|
|
79
|
+
<!-- Sentinel elements placed at the ends of the scroller -->
|
|
80
|
+
<div class="sentinel-top"></div>
|
|
81
|
+
<!-- Content goes here -->
|
|
82
|
+
<div class="sentinel-bottom"></div>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
```css
|
|
86
|
+
/* Marker styling to ensure it does not affect layout */
|
|
87
|
+
.sentinel-top, .sentinel-bottom {
|
|
88
|
+
height: 0;
|
|
89
|
+
width: 0;
|
|
90
|
+
visibility: hidden;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.scroller.scrolled-down .indicator-top {
|
|
94
|
+
opacity: 1;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.scroller.can-scroll-down .indicator-bottom {
|
|
98
|
+
opacity: 1;
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
if (!CSS.supports('container-type', 'scroll-state')) {
|
|
104
|
+
const topSentinel = document.querySelector('.sentinel-top');
|
|
105
|
+
const bottomSentinel = document.querySelector('.sentinel-bottom');
|
|
106
|
+
const scroller = document.querySelector('.scroller');
|
|
107
|
+
|
|
108
|
+
const observer = new IntersectionObserver((entries) => {
|
|
109
|
+
entries.forEach(entry => {
|
|
110
|
+
if (entry.target === topSentinel) {
|
|
111
|
+
// If top sentinel is not intersecting, we have scrolled down
|
|
112
|
+
scroller.classList.toggle('scrolled-down', !entry.isIntersecting);
|
|
113
|
+
}
|
|
114
|
+
if (entry.target === bottomSentinel) {
|
|
115
|
+
// If bottom sentinel is intersecting, we reached the bottom
|
|
116
|
+
scroller.classList.toggle('can-scroll-down', !entry.isIntersecting);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}, { root: scroller });
|
|
120
|
+
|
|
121
|
+
observer.observe(topSentinel);
|
|
122
|
+
observer.observe(bottomSentinel);
|
|
123
|
+
}
|
|
124
|
+
```
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# Scrollytelling
|
|
2
|
+
|
|
3
|
+
Scrollytelling is a popular technique used to create engaging and immersive web experiences. It involves animating elements on a page as the user scrolls, effectively telling a story or guiding the user through a narrative. With CSS Scroll-Driven Animations, you can create these effects directly in CSS, without needing to rely on JavaScript. The animations are controlled by the scroll position, not a time-based clock, which ensures they are always in sync with the user's scroll.
|
|
4
|
+
|
|
5
|
+
## How to implement
|
|
6
|
+
|
|
7
|
+
To create a scrollytelling experience, you need two sets of elements: one to track the scroll position and another to be animated.
|
|
8
|
+
|
|
9
|
+
First, define a named `view-timeline` on the elements you want to track. These will act as the drivers for your animations.
|
|
10
|
+
|
|
11
|
+
```css
|
|
12
|
+
#tracked {
|
|
13
|
+
section:nth-child(1){ view-timeline: --tl-1 block; }
|
|
14
|
+
section:nth-child(2){ view-timeline: --tl-2 block; }
|
|
15
|
+
section:nth-child(3){ view-timeline: --tl-3 block; }
|
|
16
|
+
section:nth-child(4){ view-timeline: --tl-4 block; }
|
|
17
|
+
section:nth-child(5){ view-timeline: --tl-5 block; }
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Next, apply animations to the elements you want to animate and link them to the timelines you just created using the `animation-timeline` property.
|
|
22
|
+
|
|
23
|
+
```css
|
|
24
|
+
#animated {
|
|
25
|
+
section {
|
|
26
|
+
animation: animate-in auto linear both, animate-out auto linear forwards;
|
|
27
|
+
animation-range: entry 25% cover 50%, exit 50% exit 75%;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
section:nth-child(1){ animation-timeline: --tl-1; }
|
|
31
|
+
section:nth-child(2){ animation-timeline: --tl-2; }
|
|
32
|
+
section:nth-child(3){ animation-timeline: --tl-3; }
|
|
33
|
+
section:nth-child(4){ animation-timeline: --tl-4; }
|
|
34
|
+
section:nth-child(5){ animation-timeline: --tl-5; }
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
For the `animation-timeline` to be able to reference the named timelines, they need to be in the same scope. You can use the `timeline-scope` property on a common ancestor to make the timelines available to all the elements that need them. The `:root` element is often a good choice for this.
|
|
39
|
+
|
|
40
|
+
```css
|
|
41
|
+
html {
|
|
42
|
+
timeline-scope: --tl-1, --tl-2, --tl-3, --tl-4, --tl-5;
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Finally, you can use the `animation-range` property to specify the exact range of the timeline during which the animation should run. This gives you fine-grained control over when the animations are triggered and how they progress.
|
|
47
|
+
|
|
48
|
+
```css
|
|
49
|
+
#animated section {
|
|
50
|
+
animation-range: entry 25% cover 50%, exit 50% exit 75%;
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Example code
|
|
55
|
+
|
|
56
|
+
```css
|
|
57
|
+
html {
|
|
58
|
+
timeline-scope: --tl-1, --tl-2, --tl-3, --tl-4, --tl-5;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
#tracked {
|
|
62
|
+
section:nth-child(1){ view-timeline: --tl-1 block; }
|
|
63
|
+
section:nth-child(2){ view-timeline: --tl-2 block; }
|
|
64
|
+
section:nth-child(3){ view-timeline: --tl-3 block; }
|
|
65
|
+
section:nth-child(4){ view-timeline: --tl-4 block; }
|
|
66
|
+
section:nth-child(5){ view-timeline: --tl-5 block; }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@keyframes animate-in {
|
|
70
|
+
from { scale: 0.5; opacity: 0; transform: rotateY(-180deg); }
|
|
71
|
+
to { transform: rotateY(0deg); }
|
|
72
|
+
}
|
|
73
|
+
@keyframes animate-out {
|
|
74
|
+
to { translate: 100% 0; opacity: 0; }
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
#animated {
|
|
78
|
+
section {
|
|
79
|
+
animation: animate-in auto linear both, animate-out auto linear forwards;
|
|
80
|
+
animation-range: entry 25% cover 50%, exit 50% exit 75%;
|
|
81
|
+
backface-visibility: hidden;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
section:nth-child(1){ animation-timeline: --tl-1; }
|
|
85
|
+
section:nth-child(2){ animation-timeline: --tl-2; }
|
|
86
|
+
section:nth-child(3){ animation-timeline: --tl-3; }
|
|
87
|
+
section:nth-child(4){ animation-timeline: --tl-4; }
|
|
88
|
+
section:nth-child(5){ animation-timeline: --tl-5; }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* MANDATORY Copy-Paste Safety: Disable continuous storytelling motion for sensitive users */
|
|
92
|
+
@media (prefers-reduced-motion: reduce) {
|
|
93
|
+
#animated section {
|
|
94
|
+
animation: none !important;
|
|
95
|
+
opacity: 1 !important;
|
|
96
|
+
transform: none !important;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Best Practices
|
|
102
|
+
|
|
103
|
+
When using scroll-driven animations, it's important to follow a few best practices to ensure a smooth and accessible experience:
|
|
104
|
+
|
|
105
|
+
- **DO** include feature detection: Not all browsers support scroll-driven animations. Use `@supports ((animation-timeline: scroll()) and (animation-range: 0% 100%))` to check for support and provide a fallback for browsers that don't support it.
|
|
106
|
+
- The `(animation-range: 0% 100%)` check **MUST** be included here, to filter out browsers with only partial support.
|
|
107
|
+
- **DO NOT** use the `scroll-timeline-polyfill` package for the fallback strategy as it is not feature complete and has a lot of known issues.
|
|
108
|
+
- If the animation is only considered to be decorative, opt for Progressive Enhancement and **DO NOT** provide a fallback.
|
|
109
|
+
- **DO** respect user preferences: Some users prefer to have less motion on the web. Use the `prefers-reduced-motion` media query to disable or reduce your animations for these users.
|
|
110
|
+
- **DO** try to animate only performant CSS properties: For the smoothest animations, stick to animating properties that can be handled by the browser's compositor thread, such as `transform` and `opacity`. Animating other properties like `width` or `height` can lead to performance issues.
|
|
111
|
+
- **DO** use the correct declaration order: When using the `animation` shorthand property, declare `animation-timeline` and `animation-range` *after* it to prevent the shorthand from resetting the timeline.
|
|
112
|
+
|
|
113
|
+
When using the `view-timeline` property to create a scroll-driven animation:
|
|
114
|
+
|
|
115
|
+
- **DO** use a CSS `<dashed-ident>` for the name.
|
|
116
|
+
- **OPTIONAL** be explicit about the axis to track: When not targeting the default `block` axis (such as in a horizontal scroller), be explicit about which axis to track with `view-timeline-axis`.
|
|
117
|
+
- **DO** make sure the scope of the lookup works: When the element that is declaring the `view-timeline` is not a flat tree ancestor of the animated element, hoist up the visibility of the `view-timeline`’s name by using `timeline-scope` on a shared ancestor.
|
|
118
|
+
|
|
119
|
+
## Fallback strategies
|
|
120
|
+
|
|
121
|
+
Scroll-driven animations has limited availability.
|
|
122
|
+
Supported by: Chrome 115 (Jul 2023), Edge 115 (Jul 2023), and Safari 26 (Sep 2025).
|
|
123
|
+
Unsupported in: Firefox.
|
|
124
|
+
|
|
125
|
+
For browsers that do not support scroll-driven animations, you can use a fallback to recreate the visual effects. The fallbacks are typically built with either a scroll listener (for ScrollTimeline effects) or the IntersectionObserver API (for ViewTimeline effects).
|
|
126
|
+
|
|
127
|
+
In browsers with built-in support for scroll-driven animations, ALWAYS use the native CSS implementation as those are more performant.
|
|
128
|
+
|
|
129
|
+
Note that not every effect can be recreated using the fallbacks approach.
|
|
130
|
+
|
|
131
|
+
For this use-case specifically, the following script applies the fallback for browsers that do not support scroll-driven animations. It uses an `IntersectionObserver` to track the visibility of each `#tracked section` element and updates the `transform` property of the corresponding `#animated section` accordingly.
|
|
132
|
+
|
|
133
|
+
```js
|
|
134
|
+
const animatedSections = document.querySelectorAll('#animated section');
|
|
135
|
+
|
|
136
|
+
const observer = new IntersectionObserver((entries) => {
|
|
137
|
+
entries.forEach(entry => {
|
|
138
|
+
const sectionIndex = Array.from(document.querySelectorAll('#tracked section')).indexOf(entry.target);
|
|
139
|
+
if (sectionIndex !== -1) {
|
|
140
|
+
const animatedSection = animatedSections[sectionIndex];
|
|
141
|
+
const ratio = entry.intersectionRatio;
|
|
142
|
+
|
|
143
|
+
// Animate-in
|
|
144
|
+
animatedSection.style.opacity = ratio;
|
|
145
|
+
animatedSection.style.transform = `scale(${0.5 + ratio * 0.5}) rotateY(${-180 + ratio * 180}deg)`;
|
|
146
|
+
|
|
147
|
+
// Animate-out
|
|
148
|
+
if (ratio < 0.5) {
|
|
149
|
+
animatedSection.style.translate = `${(0.5 - ratio) * 2 * 100}% 0`;
|
|
150
|
+
} else {
|
|
151
|
+
animatedSection.style.translate = '0 0';
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}, { threshold: Array.from({length: 101}, (_, i) => i / 100) });
|
|
156
|
+
|
|
157
|
+
document.querySelectorAll('#tracked section').forEach(section => {
|
|
158
|
+
observer.observe(section);
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
And the accompanying CSS:
|
|
163
|
+
|
|
164
|
+
```css
|
|
165
|
+
#animated section {
|
|
166
|
+
opacity: 0;
|
|
167
|
+
transform: scale(0.5) rotateY(-180deg);
|
|
168
|
+
backface-visibility: hidden;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/* MANDATORY Copy-Paste Safety: Ensure content remains fully visible and legible for assistive technologies or users with motion sensitivities */
|
|
172
|
+
@media (prefers-reduced-motion: reduce) {
|
|
173
|
+
#animated section {
|
|
174
|
+
opacity: 1 !important;
|
|
175
|
+
transform: none !important;
|
|
176
|
+
translate: 0 0 !important;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
This fallback provides a more accurate, scroll-driven animation for browsers that do not support the native CSS feature, ensuring a more consistent experience for all users. By using a series of thresholds for the `IntersectionObserver`, we can track the scroll position with more precision and create a smoother animation.
|