@hortonstudio/main 1.9.10 → 1.9.20

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.
Files changed (124) hide show
  1. package/.prettierrc +8 -0
  2. package/README.md +146 -0
  3. package/eslint.config.js +32 -0
  4. package/index.ts +275 -0
  5. package/package.json +19 -2
  6. package/public/bootstrap.js +16 -0
  7. package/src/animations/animations.ts +93 -0
  8. package/src/animations/functions/counter/counter.ts +137 -0
  9. package/src/config.json +570 -0
  10. package/src/config.ts +105 -0
  11. package/src/modules/default/README.md +167 -0
  12. package/src/modules/default/default.ts +71 -0
  13. package/{autoInit → src/modules/default/functions}/accessibility/README.md +44 -12
  14. package/src/modules/default/functions/accessibility/accessibility.ts +54 -0
  15. package/src/modules/default/functions/accordion/README.md +451 -0
  16. package/src/modules/default/functions/accordion/accordion.ts +189 -0
  17. package/src/modules/default/functions/comparison/comparison.ts +424 -0
  18. package/src/modules/default/functions/marquee/marquee.ts +206 -0
  19. package/src/modules/default/functions/navbar/README.md +393 -0
  20. package/src/modules/default/functions/navbar/functions/arrow-navigation/arrow-navigation.ts +183 -0
  21. package/src/modules/default/functions/navbar/functions/dropdown/dropdown.ts +313 -0
  22. package/src/modules/default/functions/navbar/functions/menu/menu.ts +315 -0
  23. package/src/modules/default/functions/navbar/navbar.ts +51 -0
  24. package/{autoInit → src/modules/default/functions}/smooth-scroll/README.md +45 -14
  25. package/{autoInit/smooth-scroll/smooth-scroll.js → src/modules/default/functions/smooth-scroll/smooth-scroll.ts} +33 -38
  26. package/{autoInit → src/modules/default/functions}/transition/README.md +59 -32
  27. package/src/modules/default/functions/transition/transition.ts +290 -0
  28. package/src/modules/normalize/README.md +172 -0
  29. package/src/modules/normalize/functions/clickable/README.md +84 -0
  30. package/src/modules/normalize/functions/clickable/clickable.ts +43 -0
  31. package/src/modules/normalize/functions/clickable/functions/normalize/README.md +213 -0
  32. package/src/modules/normalize/functions/clickable/functions/normalize/normalize.ts +68 -0
  33. package/src/modules/normalize/functions/dupe/README.md +405 -0
  34. package/src/modules/normalize/functions/dupe/dupe.ts +197 -0
  35. package/src/modules/normalize/functions/sync/sync.ts +378 -0
  36. package/src/modules/normalize/normalize.ts +58 -0
  37. package/src/modules/structure/README.md +190 -0
  38. package/src/modules/structure/functions/form/README.md +94 -0
  39. package/src/modules/structure/functions/form/form.ts +54 -0
  40. package/src/modules/structure/functions/form/functions/honeypot/README.md +77 -0
  41. package/src/modules/structure/functions/form/functions/honeypot/honeypot.ts +37 -0
  42. package/src/modules/structure/functions/form/functions/range/README.md +410 -0
  43. package/src/modules/structure/functions/form/functions/range/range.ts +92 -0
  44. package/src/modules/structure/functions/form/functions/select/README.md +393 -0
  45. package/src/modules/structure/functions/form/functions/select/functions/custom-select/custom-select.ts +637 -0
  46. package/src/modules/structure/functions/form/functions/select/functions/states/states.ts +118 -0
  47. package/src/modules/structure/functions/form/functions/select/select.ts +48 -0
  48. package/src/modules/structure/functions/form/functions/test/test.ts +132 -0
  49. package/src/modules/structure/functions/pagination/README.md +527 -0
  50. package/src/modules/structure/functions/pagination/pagination.ts +493 -0
  51. package/src/modules/structure/functions/site-settings/README.md +395 -0
  52. package/src/modules/structure/functions/site-settings/site-settings.ts +158 -0
  53. package/{autoInit/accessibility → src/modules/structure}/functions/toc/README.md +18 -15
  54. package/{autoInit/accessibility/functions/toc/toc.js → src/modules/structure/functions/toc/functions/heading-links/heading-links.ts} +43 -63
  55. package/src/modules/structure/functions/toc/functions/progress-bar/progress-bar.ts +101 -0
  56. package/src/modules/structure/functions/toc/toc.ts +35 -0
  57. package/{autoInit/accessibility → src/modules/structure}/functions/year-replacement/README.md +7 -6
  58. package/src/modules/structure/functions/year-replacement/year-replacement.ts +59 -0
  59. package/src/modules/structure/structure.ts +59 -0
  60. package/src/utils/attributeSelector.ts +78 -0
  61. package/src/utils/cssVariables.ts +24 -0
  62. package/src/utils/gsap.ts +198 -0
  63. package/src/utils/heightAnimator.ts +130 -0
  64. package/src/utils/modalManager.ts +150 -0
  65. package/src/utils.ts +54 -0
  66. package/tsconfig.json +24 -0
  67. package/vite.config.js +45 -0
  68. package/.claude/settings.local.json +0 -70
  69. package/archive/hero.js +0 -794
  70. package/archive/modal.js +0 -80
  71. package/archive/text.js +0 -628
  72. package/autoInit/accessibility/accessibility.js +0 -53
  73. package/autoInit/accessibility/functions/blog-remover/README.md +0 -61
  74. package/autoInit/accessibility/functions/blog-remover/blog-remover.js +0 -31
  75. package/autoInit/accessibility/functions/click-forwarding/README.md +0 -60
  76. package/autoInit/accessibility/functions/click-forwarding/click-forwarding.js +0 -82
  77. package/autoInit/accessibility/functions/dropdown/README.md +0 -212
  78. package/autoInit/accessibility/functions/dropdown/dropdown.js +0 -167
  79. package/autoInit/accessibility/functions/list-accessibility/README.md +0 -56
  80. package/autoInit/accessibility/functions/list-accessibility/list-accessibility.js +0 -23
  81. package/autoInit/accessibility/functions/pagination/README.md +0 -428
  82. package/autoInit/accessibility/functions/pagination/pagination.js +0 -359
  83. package/autoInit/accessibility/functions/text-synchronization/README.md +0 -62
  84. package/autoInit/accessibility/functions/text-synchronization/text-synchronization.js +0 -101
  85. package/autoInit/accessibility/functions/year-replacement/year-replacement.js +0 -43
  86. package/autoInit/button/README.md +0 -122
  87. package/autoInit/button/button.js +0 -51
  88. package/autoInit/counter/README.md +0 -274
  89. package/autoInit/counter/counter.js +0 -185
  90. package/autoInit/form/README.md +0 -338
  91. package/autoInit/form/form.js +0 -374
  92. package/autoInit/navbar/README.md +0 -366
  93. package/autoInit/navbar/navbar.js +0 -786
  94. package/autoInit/site-settings/README.md +0 -218
  95. package/autoInit/site-settings/site-settings.js +0 -134
  96. package/autoInit/transition/transition.js +0 -116
  97. package/index.js +0 -305
  98. package/utils/before-after/README.md +0 -520
  99. package/utils/before-after/before-after.js +0 -653
  100. package/utils/css-animations/buttons/main/bgbasic/btn-main-bgbasic.html +0 -10
  101. package/utils/css-animations/buttons/main/bgfill/btn-main-bgfill.html +0 -29
  102. package/utils/css-animations/buttons/navbar/bgbasic/navbar-main-bgbasic.html +0 -17
  103. package/utils/css-animations/buttons/navbar/bgbasic/navbar-menu-bgbasic.html +0 -16
  104. package/utils/css-animations/buttons/navbar/bgfill/navbar-main-bgfill.html +0 -46
  105. package/utils/css-animations/buttons/navbar/bgfill/navbar-menu-bgfill.html +0 -39
  106. package/utils/css-animations/buttons/navbar/color/navbar-announce-color.html +0 -5
  107. package/utils/css-animations/buttons/navbar/color/navbar-main-color.html +0 -7
  108. package/utils/css-animations/buttons/navbar/color/navbar-menu-color.html +0 -7
  109. package/utils/css-animations/buttons/navbar/double-slide/navbar-announce-double-slide.html +0 -40
  110. package/utils/css-animations/buttons/navbar/double-slide/navbar-main-double-slide.html +0 -77
  111. package/utils/css-animations/buttons/navbar/scale/navbar-announce-scale.html +0 -6
  112. package/utils/css-animations/buttons/navbar/scale/navbar-main-scale.html +0 -9
  113. package/utils/css-animations/buttons/navbar/scale/navbar-menu-scale.html +0 -8
  114. package/utils/css-animations/buttons/navbar/underline/navbar-announce-underline.html +0 -32
  115. package/utils/css-animations/buttons/navbar/underline/navbar-main-underline.html +0 -56
  116. package/utils/css-animations/buttons/text/color/text-footer-color.html +0 -5
  117. package/utils/css-animations/buttons/text/color/text-main-color.html +0 -5
  118. package/utils/css-animations/buttons/text/double-slide/text-main-double-slide.html +0 -56
  119. package/utils/css-animations/buttons/text/scale/text-footer-scale.html +0 -6
  120. package/utils/css-animations/buttons/text/scale/text-main-scale.html +0 -6
  121. package/utils/css-animations/buttons/text/underline/text-footer-underline.html +0 -45
  122. package/utils/css-animations/buttons/text/underline/text-main-underline.html +0 -58
  123. package/utils/css-animations/cards/card-clickable.html +0 -11
  124. package/utils/css-animations/defaults.html +0 -69
@@ -13,12 +13,15 @@ The smooth scroll system provides GSAP-powered smooth scrolling for anchor links
13
13
  ### **Required Dependencies**
14
14
 
15
15
  **GSAP Core**
16
- * Must be loaded before this script
16
+
17
+ - Must be loaded before this script
17
18
 
18
19
  **GSAP ScrollToPlugin**
19
- * Required for smooth scrolling functionality
20
+
21
+ - Required for smooth scrolling functionality
20
22
 
21
23
  **Typical setup:**
24
+
22
25
  ```html
23
26
  <script src="https://cdn.jsdelivr.net/npm/gsap@3/dist/gsap.min.js"></script>
24
27
  <script src="https://cdn.jsdelivr.net/npm/gsap@3/dist/ScrollToPlugin.min.js"></script>
@@ -39,9 +42,9 @@ The smooth scroll system provides GSAP-powered smooth scrolling for anchor links
39
42
 
40
43
  ### **When It Runs**
41
44
 
42
- * Auto-initializes on page load
43
- * Runs on every page in a multi-page site
44
- * Listed in `autoInitModules` in index.js
45
+ - Auto-initializes on page load
46
+ - Runs on every page in a multi-page site
47
+ - Listed in `autoInitModules` in index.js
45
48
 
46
49
  ---
47
50
 
@@ -88,6 +91,7 @@ Any link with `href` starting with `#`:
88
91
  ```
89
92
 
90
93
  **Requirements:**
94
+
91
95
  - Must have `href` attribute starting with `#`
92
96
  - Target element must have matching `id` attribute
93
97
  - Cannot be just `#` (empty hash)
@@ -105,6 +109,7 @@ Any link with `href` starting with `#`:
105
109
  ```
106
110
 
107
111
  **Requirements:**
112
+
108
113
  - Must have `id` attribute matching the anchor's `href` (without `#`)
109
114
 
110
115
  ---
@@ -128,7 +133,7 @@ gsap.to(window, {
128
133
  y: target,
129
134
  offsetY: offset,
130
135
  },
131
- ease: "power2.out"
136
+ ease: 'power2.out',
132
137
  });
133
138
  ```
134
139
 
@@ -141,6 +146,7 @@ gsap.to(window, {
141
146
  ### **What It Does**
142
147
 
143
148
  If user has `prefers-reduced-motion: reduce` enabled:
149
+
144
150
  - Skips GSAP animation entirely
145
151
  - Uses instant scroll with `window.scrollTo()`
146
152
  - Still respects scroll offset
@@ -149,7 +155,7 @@ If user has `prefers-reduced-motion: reduce` enabled:
149
155
  ### **Detection**
150
156
 
151
157
  ```javascript
152
- window.matchMedia("(prefers-reduced-motion: reduce)").matches
158
+ window.matchMedia('(prefers-reduced-motion: reduce)').matches;
153
159
  ```
154
160
 
155
161
  **Result:** Users with motion sensitivity get instant, non-animated scrolling while maintaining all functionality.
@@ -161,6 +167,7 @@ window.matchMedia("(prefers-reduced-motion: reduce)").matches
161
167
  ### **Automatic Focus**
162
168
 
163
169
  After scrolling to target element:
170
+
164
171
  1. Sets `tabindex="-1"` on target (makes it focusable without adding to tab order)
165
172
  2. Calls `focus({ preventScroll: true })` on target
166
173
  3. Announces target to screen readers
@@ -174,6 +181,7 @@ After scrolling to target element:
174
181
  ### **What It Does**
175
182
 
176
183
  On page load, performs a quick scroll:
184
+
177
185
  1. Scrolls to `1px`
178
186
  2. Immediately scrolls back to `0px`
179
187
 
@@ -188,11 +196,13 @@ On page load, performs a quick scroll:
188
196
  ## **URL Hash Updates**
189
197
 
190
198
  When clicking an anchor link:
199
+
191
200
  1. Prevents default browser behavior
192
201
  2. Updates URL hash using `history.replaceState()`
193
202
  3. Scrolls to target
194
203
 
195
204
  **Example:**
205
+
196
206
  - Click `<a href="#about">`
197
207
  - URL changes from `example.com` to `example.com#about`
198
208
  - Page smoothly scrolls to `#about` element
@@ -206,8 +216,9 @@ When clicking an anchor link:
206
216
  ### **Supported Keys**
207
217
 
208
218
  When an anchor link is focused:
209
- - **Enter** � Triggers smooth scroll to target
210
- - **Space** � Triggers smooth scroll to target
219
+
220
+ - **Enter** � Triggers smooth scroll to target
221
+ - **Space** � Triggers smooth scroll to target
211
222
 
212
223
  **Implementation:** Keyboard events are handled the same as clicks, providing consistent behavior.
213
224
 
@@ -296,6 +307,7 @@ When an anchor link is focused:
296
307
  ### **Disables Webflow's Default Behavior**
297
308
 
298
309
  This script automatically disables:
310
+
299
311
  1. **jQuery scroll handler** - Removes `click.wf-scroll` event listener
300
312
  2. **CSS smooth scrolling** - Sets `scroll-behavior: auto`
301
313
 
@@ -309,10 +321,10 @@ This script automatically disables:
309
321
 
310
322
  This module doesn't require any data attributes - it works automatically with standard HTML anchor links.
311
323
 
312
- | Element | Requirement |
313
- | ----- | ----- |
314
- | Anchor link | `href="#target-id"` |
315
- | Target element | `id="target-id"` |
324
+ | Element | Requirement |
325
+ | -------------- | ------------------- |
326
+ | Anchor link | `href="#target-id"` |
327
+ | Target element | `id="target-id"` |
316
328
 
317
329
  ---
318
330
 
@@ -335,6 +347,25 @@ This module has no public API methods. It runs automatically and handles all anc
335
347
 
336
348
  ---
337
349
 
350
+ ## **v2.0.0 Improvements**
351
+
352
+ ### **JSON Config System**
353
+
354
+ - Added config.js with module metadata
355
+ - Future-proof: Ready for configuration options if needed
356
+ - Note: This module auto-detects anchor links and requires no data attributes
357
+
358
+ ### **Barba.js / SPA Compatibility**
359
+
360
+ The smooth-scroll system is fully compatible with Barba.js and other SPA frameworks:
361
+
362
+ - Proper cleanup on destroy (removes event listeners, restores CSS scroll behavior)
363
+ - Fresh initialization on reinitialize
364
+ - Works on all anchor links on new pages
365
+ - Works like fresh page load on new DOM
366
+
367
+ ---
368
+
338
369
  ## **Common Issues**
339
370
 
340
371
  **Smooth scroll not working:**
@@ -368,7 +399,7 @@ This module has no public API methods. It runs automatically and handles all anc
368
399
  **Reduced motion not instant:**
369
400
 
370
401
  1. Check browser/OS motion settings
371
- 2. Test with DevTools: Rendering � Emulate CSS media `prefers-reduced-motion: reduce`
402
+ 2. Test with DevTools: Rendering � Emulate CSS media `prefers-reduced-motion: reduce`
372
403
  3. Verify scroll is instant (no animation)
373
404
 
374
405
  **URL hash not updating:**
@@ -1,30 +1,23 @@
1
- const API_NAME = "hsmain";
1
+ import { getGsap, prefersReducedMotion } from '@utils';
2
2
 
3
3
  export async function init() {
4
- const api = window[API_NAME];
5
-
6
4
  // Store event handlers for cleanup
7
5
  let clickHandler = null;
8
6
  let keydownHandler = null;
9
7
 
10
- api.afterWebflowReady(() => {
11
- if (typeof $ !== "undefined") {
12
- $(document).off("click.wf-scroll");
13
- }
14
- });
8
+ // Disable Webflow's native scroll behavior (jQuery-based)
9
+ // This runs immediately since default module already waits for IX3
10
+ if (typeof $ !== 'undefined') {
11
+ $(document).off('click.wf-scroll');
12
+ }
15
13
 
16
14
  // Disable CSS smooth scrolling
17
- document.documentElement.style.scrollBehavior = "auto";
18
- document.body.style.scrollBehavior = "auto";
19
-
20
- // Check if user prefers reduced motion
21
- function prefersReducedMotion() {
22
- return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
23
- }
15
+ document.documentElement.style.scrollBehavior = 'auto';
16
+ document.body.style.scrollBehavior = 'auto';
24
17
 
25
18
  function getScrollOffset() {
26
19
  const offsetValue = getComputedStyle(document.documentElement)
27
- .getPropertyValue("--misc--scroll-offset")
20
+ .getPropertyValue('--misc--scroll-offset')
28
21
  .trim();
29
22
  return parseInt(offsetValue) || 0;
30
23
  }
@@ -33,25 +26,26 @@ export async function init() {
33
26
  function scrollToElement(target, offset = 0) {
34
27
  if (!target) return;
35
28
 
36
- // Skip animation if user prefers reduced motion
37
- if (prefersReducedMotion()) {
38
- const targetPosition =
39
- target.getBoundingClientRect().top + window.scrollY - offset;
29
+ const gsapLib = getGsap('smooth-scroll', false);
30
+
31
+ // Skip animation if user prefers reduced motion or GSAP not available
32
+ if (prefersReducedMotion() || !gsapLib) {
33
+ const targetPosition = target.getBoundingClientRect().top + window.scrollY - offset;
40
34
  window.scrollTo(0, targetPosition);
41
- target.setAttribute("tabindex", "-1");
35
+ target.setAttribute('tabindex', '-1');
42
36
  target.focus({ preventScroll: true });
43
37
  return;
44
38
  }
45
39
 
46
- gsap.to(window, {
40
+ gsapLib.gsap.to(window, {
47
41
  duration: 1,
48
42
  scrollTo: {
49
43
  y: target,
50
44
  offsetY: offset,
51
45
  },
52
- ease: "power2.out",
46
+ ease: 'power2.out',
53
47
  onComplete: function () {
54
- target.setAttribute("tabindex", "-1");
48
+ target.setAttribute('tabindex', '-1');
55
49
  target.focus({ preventScroll: true });
56
50
  },
57
51
  });
@@ -61,8 +55,8 @@ export async function init() {
61
55
  const link = e.target.closest('a[href^="#"]');
62
56
  if (!link) return;
63
57
 
64
- const href = link.getAttribute("href");
65
- if (!href || href === "#") return;
58
+ const href = link.getAttribute('href');
59
+ if (!href || href === '#') return;
66
60
 
67
61
  const targetId = href.substring(1);
68
62
  const targetElement = document.getElementById(targetId);
@@ -81,40 +75,41 @@ export async function init() {
81
75
  function handleAnchorClicks() {
82
76
  clickHandler = handleAnchorActivation;
83
77
  keydownHandler = function (e) {
84
- if (e.key === "Enter" || e.key === " ") {
78
+ if (e.key === 'Enter' || e.key === ' ') {
85
79
  handleAnchorActivation(e);
86
80
  }
87
81
  };
88
82
 
89
- document.addEventListener("click", clickHandler);
90
- document.addEventListener("keydown", keydownHandler);
83
+ document.addEventListener('click', clickHandler);
84
+ document.addEventListener('keydown', keydownHandler);
91
85
  }
92
86
 
93
87
  // Initialize anchor link handling
94
88
  handleAnchorClicks();
95
89
 
96
90
  // Mock scroll to trigger scroll-based animations
97
- if (document.body.scrollHeight > window.innerHeight) {
98
- gsap.set(window, { scrollTo: 1 });
99
- gsap.set(window, { scrollTo: 0 });
91
+ const gsapLib = getGsap('smooth-scroll', false);
92
+ if (gsapLib && document.body.scrollHeight > window.innerHeight) {
93
+ gsapLib.gsap.set(window, { scrollTo: 1 });
94
+ gsapLib.gsap.set(window, { scrollTo: 0 });
100
95
  }
101
96
 
102
97
  return {
103
- result: "autoInit-smooth-scroll initialized",
98
+ result: 'autoInit-smooth-scroll initialized',
104
99
  destroy: () => {
105
100
  // Remove event listeners
106
101
  if (clickHandler) {
107
- document.removeEventListener("click", clickHandler);
102
+ document.removeEventListener('click', clickHandler);
108
103
  clickHandler = null;
109
104
  }
110
105
  if (keydownHandler) {
111
- document.removeEventListener("keydown", keydownHandler);
106
+ document.removeEventListener('keydown', keydownHandler);
112
107
  keydownHandler = null;
113
108
  }
114
109
 
115
110
  // Re-enable CSS smooth scrolling
116
- document.documentElement.style.scrollBehavior = "";
117
- document.body.style.scrollBehavior = "";
118
- }
111
+ document.documentElement.style.scrollBehavior = '';
112
+ document.body.style.scrollBehavior = '';
113
+ },
119
114
  };
120
115
  }
@@ -12,29 +12,29 @@ The page transition system provides smooth animated transitions between pages in
12
12
 
13
13
  ### **Required Elements**
14
14
 
15
- **Transition Trigger** *(invisible element that triggers Webflow IX animation)*
15
+ **Transition Trigger** _(invisible element that triggers Webflow IX animation)_
16
16
 
17
- * data-hs-transition="trigger"
18
- * Webflow IX interaction attached (entrance and exit animations)
17
+ - data-hs-transition="trigger"
18
+ - Webflow IX interaction attached (entrance and exit animations)
19
19
 
20
- **Transition Element** *(visual overlay that covers the page during transition)*
20
+ **Transition Element** _(visual overlay that covers the page during transition)_
21
21
 
22
- * data-hs-transition="element"
23
- * Should cover entire viewport
24
- * Contains visual transition effect (fade, slide, etc.)
22
+ - data-hs-transition="element"
23
+ - Should cover entire viewport
24
+ - Contains visual transition effect (fade, slide, etc.)
25
25
 
26
- **Exit Time** *(optional attribute on transition element)*
26
+ **Exit Time** _(optional attribute on transition element)_
27
27
 
28
- * data-hs-exit-time="0.5"
29
- * Time in seconds to wait before navigating to new page
30
- * Should match your Webflow exit animation duration
28
+ - data-hs-exit-time="0.5"
29
+ - Time in seconds to wait before navigating to new page
30
+ - Should match your Webflow exit animation duration
31
31
 
32
- **Entrance Delay** *(optional attribute on transition element)*
32
+ **Entrance Delay** _(optional attribute on transition element)_
33
33
 
34
- * data-hs-delay="0.3"
35
- * Delay in seconds before triggering entrance animation on FIRST page load only
36
- * Subsequent page loads trigger instantly (no delay)
37
- * Default: 0 (instant trigger)
34
+ - data-hs-delay="0.3"
35
+ - Delay in seconds before triggering entrance animation on FIRST page load only
36
+ - Subsequent page loads trigger instantly (no delay)
37
+ - Default: 0 (instant trigger)
38
38
 
39
39
  **Typical element layout:**
40
40
 
@@ -58,10 +58,10 @@ The page transition system provides smooth animated transitions between pages in
58
58
 
59
59
  ### **When It Runs**
60
60
 
61
- * Auto-initializes on page load (unless `no-transition` attribute is present)
62
- * Waits for Webflow to be ready (`afterWebflowReady()`)
63
- * Adds 50ms delay after Webflow ready to ensure IX is fully loaded
64
- * Runs on every page in a multi-page site
61
+ - Auto-initializes on page load (unless `no-transition` attribute is present)
62
+ - Waits for Webflow to be ready (`afterWebflowReady()`)
63
+ - Adds 50ms delay after Webflow ready to ensure IX is fully loaded
64
+ - Runs on every page in a multi-page site
65
65
 
66
66
  ---
67
67
 
@@ -72,10 +72,15 @@ The page transition system provides smooth animated transitions between pages in
72
72
  Add `no-transition` attribute to the script tag to disable page transitions:
73
73
 
74
74
  ```html
75
- <script type="module" src="https://cdn.jsdelivr.net/npm/@hortonstudio/main@latest" no-transition></script>
75
+ <script
76
+ type="module"
77
+ src="https://cdn.jsdelivr.net/npm/@hortonstudio/main@latest"
78
+ no-transition
79
+ ></script>
76
80
  ```
77
81
 
78
82
  **When to use:**
83
+
79
84
  - During development/testing
80
85
  - On sites where transitions cause issues
81
86
  - For specific pages where you don't want transitions
@@ -135,12 +140,19 @@ Add this script to your site's `<head>` BEFORE the main script to prevent transi
135
140
 
136
141
  ```html
137
142
  <script>
138
- // Prevent transition if codebase hasn't loaded
139
- new MutationObserver((m,o)=>{if(document.documentElement.classList.contains('w-mod-ix3')){if(!document.documentElement.classList.contains('hs-main'))document.querySelectorAll('[data-hs-transition="element"]').forEach(el=>el.remove());o.disconnect()}}).observe(document.documentElement,{attributes:true,attributeFilter:['class']})
143
+ // Prevent transition if codebase hasn't loaded
144
+ new MutationObserver((m, o) => {
145
+ if (document.documentElement.classList.contains('w-mod-ix3')) {
146
+ if (!document.documentElement.classList.contains('hs-main'))
147
+ document.querySelectorAll('[data-hs-transition="element"]').forEach((el) => el.remove());
148
+ o.disconnect();
149
+ }
150
+ }).observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
140
151
  </script>
141
152
  ```
142
153
 
143
154
  **What it does:**
155
+
144
156
  1. Waits for Webflow IX to load (`w-mod-ix3` class)
145
157
  2. Checks if main codebase loaded (`hs-main` class)
146
158
  3. If main codebase didn't load, removes all transition elements
@@ -157,7 +169,13 @@ new MutationObserver((m,o)=>{if(document.documentElement.classList.contains('w-m
157
169
  ```html
158
170
  <!-- Fallback script in <head> -->
159
171
  <script>
160
- new MutationObserver((m,o)=>{if(document.documentElement.classList.contains('w-mod-ix3')){if(!document.documentElement.classList.contains('hs-main'))document.querySelectorAll('[data-hs-transition="element"]').forEach(el=>el.remove());o.disconnect()}}).observe(document.documentElement,{attributes:true,attributeFilter:['class']})
172
+ new MutationObserver((m, o) => {
173
+ if (document.documentElement.classList.contains('w-mod-ix3')) {
174
+ if (!document.documentElement.classList.contains('hs-main'))
175
+ document.querySelectorAll('[data-hs-transition="element"]').forEach((el) => el.remove());
176
+ o.disconnect();
177
+ }
178
+ }).observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
161
179
  </script>
162
180
 
163
181
  <!-- Main script -->
@@ -169,7 +187,11 @@ new MutationObserver((m,o)=>{if(document.documentElement.classList.contains('w-m
169
187
  <div data-hs-transition="trigger" style="width: 0; height: 0; opacity: 0;"></div>
170
188
 
171
189
  <!-- Visual overlay with 0.5s exit time -->
172
- <div data-hs-transition="element" data-hs-exit-time="0.5" style="position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: black; z-index: 9999;">
190
+ <div
191
+ data-hs-transition="element"
192
+ data-hs-exit-time="0.5"
193
+ style="position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: black; z-index: 9999;"
194
+ >
173
195
  <!-- Optional loading animation or logo -->
174
196
  </div>
175
197
  </div>
@@ -195,6 +217,7 @@ new MutationObserver((m,o)=>{if(document.documentElement.classList.contains('w-m
195
217
  ```
196
218
 
197
219
  **Result:**
220
+
198
221
  - First visit to site: Waits 300ms, then triggers entrance animation
199
222
  - Navigating to other pages: Triggers entrance animation immediately
200
223
 
@@ -208,6 +231,7 @@ The system uses `sessionStorage` to track the first page load:
208
231
  **Value:** `'true'`
209
232
 
210
233
  **Purpose:** Differentiates between initial site visit and subsequent page navigations. Used to determine whether to apply the entrance delay (`data-hs-delay`):
234
+
211
235
  - **First load:** Delay is applied before entrance animation
212
236
  - **Subsequent loads:** No delay, entrance animation triggers immediately
213
237
 
@@ -216,6 +240,7 @@ The system uses `sessionStorage` to track the first page load:
216
240
  ## **Resize Handling**
217
241
 
218
242
  When the browser window is resized:
243
+
219
244
  - The transition element is hidden (`display: none`)
220
245
  - Prevents visual bugs with fixed positioning during resize
221
246
  - Transition will work again on next navigation
@@ -225,6 +250,7 @@ When the browser window is resized:
225
250
  ## **Back Button Behavior**
226
251
 
227
252
  When using the browser back button:
253
+
228
254
  - Page is fully reloaded (not cached)
229
255
  - Ensures transition animations play correctly
230
256
  - Uses `window.onpageshow` event with `persisted` check
@@ -233,13 +259,13 @@ When using the browser back button:
233
259
 
234
260
  ## **Key Attributes Summary**
235
261
 
236
- | Attribute | Purpose | Required On |
237
- | ----- | ----- | ----- |
238
- | `data-hs-transition="trigger"` | Animation trigger | Hidden trigger element |
239
- | `data-hs-transition="element"` | Visual transition overlay | Transition element |
240
- | `data-hs-exit-time="0.5"` | Exit duration in seconds | Transition element (optional) |
241
- | `data-hs-delay="0.3"` | First load entrance delay in seconds | Transition element (optional) |
242
- | `no-transition` | Disable transitions | Script tag (optional) |
262
+ | Attribute | Purpose | Required On |
263
+ | ------------------------------ | ------------------------------------ | ----------------------------- |
264
+ | `data-hs-transition="trigger"` | Animation trigger | Hidden trigger element |
265
+ | `data-hs-transition="element"` | Visual transition overlay | Transition element |
266
+ | `data-hs-exit-time="0.5"` | Exit duration in seconds | Transition element (optional) |
267
+ | `data-hs-delay="0.3"` | First load entrance delay in seconds | Transition element (optional) |
268
+ | `no-transition` | Disable transitions | Script tag (optional) |
243
269
 
244
270
  ---
245
271
 
@@ -252,6 +278,7 @@ When using the browser back button:
252
278
  5. **Session tracking** - Uses sessionStorage to track first load
253
279
  6. **Back button reloads** - Forces full page reload on back navigation
254
280
  7. **Resize hides transition** - Prevents visual bugs during window resize
281
+ 8. **v2.0.0 improvements** - Enhanced Barba.js/SPA compatibility with proper timeout cleanup
255
282
 
256
283
  ---
257
284