rebly-sections 1.3.0 → 1.4.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.
@@ -0,0 +1,29 @@
1
+ name,category,css_keyframes,easing,duration,trigger,shopify_compatible,reduced_motion_fallback,use_case,keywords
2
+ fade-in,entrance,@keyframes fadeIn { from { opacity: 0 } to { opacity: 1 } },ease-out,0.6s,load/scroll,yes,opacity:1,Hero sections appearing on load or scroll,fade enter appear reveal
3
+ slide-up,entrance,@keyframes slideUp { from { transform: translateY(30px); opacity: 0 } to { transform: translateY(0); opacity: 1 } },cubic-bezier(0.4 0 0.2 1),0.6s,scroll,yes,no transform,Cards and text blocks sliding into view,slide up enter reveal
4
+ slide-in-left,entrance,@keyframes slideInLeft { from { transform: translateX(-30px); opacity: 0 } to { transform: translateX(0); opacity: 1 } },ease-out,0.5s,scroll,yes,no transform,Image with text sections entering from left,slide left enter reveal
5
+ slide-in-right,entrance,@keyframes slideInRight { from { transform: translateX(30px); opacity: 0 } to { transform: translateX(0); opacity: 1 } },ease-out,0.5s,scroll,yes,no transform,Alternating layouts entering from right,slide right enter reveal
6
+ scale-in,entrance,@keyframes scaleIn { from { transform: scale(0.95); opacity: 0 } to { transform: scale(1); opacity: 1 } },ease-out,0.4s,scroll,yes,opacity:1,Cards and images scaling into view,scale zoom grow enter reveal
7
+ stagger-children,entrance,animation-delay increments of 0.1s per child element via CSS custom property --stagger-index,ease-out,0.5s,scroll,yes,no delay,Grids lists and feature item sequences,stagger cascade sequential children delay
8
+ blur-in,entrance,@keyframes blurIn { from { filter: blur(10px); opacity: 0 } to { filter: blur(0); opacity: 1 } },ease-out,0.8s,scroll,yes,opacity:1,Hero backgrounds and overlay elements,blur focus enter reveal
9
+ clip-reveal,entrance,@keyframes clipReveal { from { clip-path: inset(0 100% 0 0) } to { clip-path: inset(0 0% 0 0) } },cubic-bezier(0.77 0 0.175 1),0.8s,scroll,yes,opacity:1,Text headings and premium content reveals,clip mask reveal wipe text premium
10
+ button-hover-lift,micro-interaction,transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0 0 0 / 0.15),ease,0.2s,hover,yes,no transform,Buttons and CTA elements on hover,button hover lift shadow cta
11
+ card-hover-lift,micro-interaction,transform: translateY(-4px); box-shadow: 0 8px 24px rgba(0 0 0 / 0.12),cubic-bezier(0.4 0 0.2 1),0.3s,hover,yes,box-shadow only,Product cards and feature cards on hover,card hover lift shadow product
12
+ image-zoom,micro-interaction,transform: scale(1.05),ease,0.4s,hover,yes,no transform,Gallery images and product images on hover,image zoom scale hover gallery product
13
+ underline-slide,micro-interaction,background-size: 0% 2px to 100% 2px using background-image: linear-gradient(currentColor currentColor),ease-out,0.3s,hover,yes,text-decoration underline,Links and navigation items on hover,underline slide link navigation hover
14
+ icon-bounce,micro-interaction,@keyframes iconBounce { 0% 100% { transform: translateY(0) } 50% { transform: translateY(-4px) } },ease-in-out,0.4s,hover,yes,no animation,Icons and social link elements on hover,icon bounce hover social
15
+ color-shift,micro-interaction,background-color transition or gradient background-position shift,ease,0.3s,hover,yes,instant change,Buttons tags and badges on hover,color transition shift hover button badge
16
+ border-draw,micro-interaction,box-shadow inset 0 0 0 2px var(--color-primary) transition,ease-out,0.4s,hover/focus,yes,solid border,Input fields and card borders on focus or hover,border draw outline focus input
17
+ pulse-glow,micro-interaction,@keyframes pulseGlow { 0% 100% { box-shadow: 0 0 0 0 rgba(var(--color-primary-rgb) / 0.4) } 50% { box-shadow: 0 0 0 8px rgba(var(--color-primary-rgb) / 0) } },ease-in-out,2s,attention,yes,static shadow,Sale badges and notification indicators,pulse glow attention badge notification
18
+ parallax-bg,scroll-triggered,transform: translateY(calc(var(--scroll-offset) * 0.3)) updated via JS scroll listener on requestAnimationFrame,linear,continuous,scroll,yes (JS required),static background position,Hero backgrounds with depth effect,parallax depth scroll background hero
19
+ reveal-on-scroll,scroll-triggered,Intersection Observer adds .is-visible class which triggers CSS transition opacity and transform,ease-out,0.6s,scroll,yes,visible immediately,Any section or element revealed on scroll,scroll reveal intersect observe visible
20
+ counter-up,scroll-triggered,JS counting animation incrementing from 0 to target number via requestAnimationFrame,ease-out,2s,scroll-visible,yes (JS required),show final number,Stats sections and achievement numbers,counter number count up stats
21
+ progress-bar,scroll-triggered,width: 0% transitioning to target percentage when element enters viewport,ease-out,1.5s,scroll-visible,yes,show full width,Skills bars loading indicators and stat displays,progress bar fill width scroll
22
+ stagger-grid,scroll-triggered,Grid items gain .is-visible class sequentially via Intersection Observer with index-based animation-delay,ease-out,0.4s per item,scroll,yes,all visible,Product grids and image galleries,grid stagger appear sequential scroll
23
+ text-split-reveal,scroll-triggered,Each line or word revealed sequentially via clip-path: inset(100% 0 0 0) to inset(0) with staggered delay,cubic-bezier(0.77 0 0.175 1),0.6s per line,scroll,yes (JS required),all visible,Headlines and testimonial text,text split word reveal line headline
24
+ scroll-snap,scroll-triggered,CSS scroll-snap-type: x mandatory on container with scroll-snap-align: start on children,ease,native,scroll,yes,normal scroll,Carousels and testimonial sliders,snap carousel swipe slider scroll
25
+ fade-slide-section,scroll-triggered,@keyframes fadeSectionIn { from { opacity: 0; transform: translateY(20px) } to { opacity: 1; transform: translateY(0) } } triggered by Intersection Observer,ease-out,0.8s,scroll,yes,visible,Full page sections fading and sliding on scroll enter,section fade slide enter scroll reveal
26
+ gpu-accelerated,performance,will-change: transform opacity; transform: translateZ(0) applied to animated elements,n/a,n/a,n/a,yes,remove will-change after animation,All animated elements requiring smooth GPU-composited rendering,gpu accelerate performance smooth compositing
27
+ reduced-motion-reset,performance,@media (prefers-reduced-motion: reduce) { * *::before *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } },n/a,n/a,always,yes,n/a,Global accessibility reset for users who prefer reduced motion,reduced motion accessibility a11y prefers-reduced-motion
28
+ intersection-observer-base,performance,const observer = new IntersectionObserver((entries) => { entries.forEach(e => { if (e.isIntersecting) { e.target.classList.add('is-visible'); observer.unobserve(e.target); } }); }{ threshold: 0.15 });,n/a,n/a,scroll,yes,n/a,Base scroll trigger utility for all scroll-triggered animations,observer intersect scroll trigger utility base
29
+ loading-skeleton,performance,@keyframes shimmer { 0% { background-position: -200% 0 } 100% { background-position: 200% 0 } } with linear-gradient background,ease-in-out,1.5s infinite,load,yes,static background color,Loading state placeholders for images and content blocks,skeleton shimmer loading placeholder
@@ -1,12 +1,23 @@
1
- {%- comment -%} rebly-sections: Features Grid | Category: content | OS2.0 {%- endcomment -%}
1
+ {%- comment -%} rebly-sections: Features Grid | Category: content | OS2.0 | Stagger-reveal + icon animations {%- endcomment -%}
2
+ {%- assign font = section.settings.heading_font -%}
3
+ {%- assign heading_tag = section.settings.heading_tag -%}
2
4
 
3
- <section id="section-{{ section.id }}" class="features-grid">
4
- <div class="features-grid__container">
5
+ {{ font | font_face: font_display: 'swap' }}
6
+
7
+ <section id="section-{{ section.id }}" class="features-grid color-{{ section.settings.color_scheme }}">
8
+ <div class="features-grid__container" style="
9
+ --pt: {{ section.settings.padding_top }}px;
10
+ --pb: {{ section.settings.padding_bottom }}px;
11
+ --heading-size: {{ section.settings.heading_font_size }}px;
12
+ --heading-font: {{ font.family }}, {{ font.fallback_families }};
13
+ --heading-weight: {{ font.weight }};
14
+ --cols: {{ section.settings.columns_per_row }};
15
+ ">
5
16
 
6
17
  {%- if section.settings.heading != blank or section.settings.subheading != blank -%}
7
18
  <div class="features-grid__header">
8
19
  {%- if section.settings.heading != blank -%}
9
- <h2 class="features-grid__heading">{{ section.settings.heading | escape }}</h2>
20
+ <{{ heading_tag }} class="features-grid__heading">{{ section.settings.heading | escape }}</{{ heading_tag }}>
10
21
  {%- endif -%}
11
22
  {%- if section.settings.subheading != blank -%}
12
23
  <p class="features-grid__subheading">{{ section.settings.subheading | escape }}</p>
@@ -14,21 +25,44 @@
14
25
  </div>
15
26
  {%- endif -%}
16
27
 
17
- <div class="features-grid__items" style="--cols: {{ section.settings.columns_per_row }};">
28
+ <div class="features-grid__items">
18
29
  {%- for block in section.blocks -%}
19
30
  {%- if block.type == 'feature' -%}
20
- <div class="features-grid__item" {{ block.shopify_attributes }}>
31
+ <div class="features-grid__item feat-reveal" {{ block.shopify_attributes }}>
32
+ {%- comment -%} Icon wrapper — bounce/scale animation on hover {%- endcomment -%}
21
33
  {%- if block.settings.icon_image != blank -%}
22
- <div class="features-grid__icon">
23
- {{- block.settings.icon_image | image_url: width: 80 | image_tag: loading: 'lazy' -}}
34
+ <div class="features-grid__icon-wrap" aria-hidden="true">
35
+ <div class="features-grid__icon">
36
+ <img
37
+ src="{{ block.settings.icon_image | image_url: width: 80 }}"
38
+ srcset="{{ block.settings.icon_image | image_url: width: 80 }} 1x, {{ block.settings.icon_image | image_url: width: 160 }} 2x"
39
+ loading="lazy"
40
+ alt=""
41
+ width="64"
42
+ height="64"
43
+ >
44
+ </div>
45
+ </div>
46
+ {%- elsif block.settings.icon_emoji != blank -%}
47
+ <div class="features-grid__icon-wrap" aria-hidden="true">
48
+ <div class="features-grid__icon features-grid__icon--emoji">
49
+ {{ block.settings.icon_emoji }}
50
+ </div>
24
51
  </div>
25
52
  {%- endif -%}
53
+
26
54
  {%- if block.settings.heading != blank -%}
27
55
  <h3 class="features-grid__item-heading">{{ block.settings.heading | escape }}</h3>
28
56
  {%- endif -%}
29
57
  {%- if block.settings.text != blank -%}
30
58
  <p class="features-grid__item-text">{{ block.settings.text | escape }}</p>
31
59
  {%- endif -%}
60
+ {%- if block.settings.link_label != blank -%}
61
+ <a href="{{ block.settings.link_url }}" class="features-grid__link">
62
+ {{ block.settings.link_label | escape }}
63
+ <span class="features-grid__link-arrow" aria-hidden="true">&#8594;</span>
64
+ </a>
65
+ {%- endif -%}
32
66
  </div>
33
67
  {%- endif -%}
34
68
  {%- endfor -%}
@@ -38,37 +72,136 @@
38
72
  </section>
39
73
 
40
74
  <style>
41
- #section-{{ section.id }} .features-grid__container { max-width: 1200px; margin: 0 auto; padding: 4rem 2rem; }
42
- #section-{{ section.id }} .features-grid__header { text-align: center; margin-bottom: 3rem; }
43
- #section-{{ section.id }} .features-grid__heading { font-size: 2rem; margin: 0 0 0.75rem; color: inherit; }
44
- #section-{{ section.id }} .features-grid__subheading { font-size: 1.125rem; opacity: 0.75; margin: 0; color: inherit; }
75
+ /* ── Layout ── */
76
+ #section-{{ section.id }} .features-grid__container {
77
+ max-width: 1200px; margin: 0 auto;
78
+ padding: var(--pt, 80px) 2rem var(--pb, 80px);
79
+ }
80
+ #section-{{ section.id }} .features-grid__header { text-align: center; margin-bottom: 3.5rem; }
81
+ #section-{{ section.id }} .features-grid__heading {
82
+ font-family: var(--heading-font); font-weight: var(--heading-weight);
83
+ font-size: clamp(1.75rem, 3vw, var(--heading-size, 2.5rem));
84
+ margin: 0 0 0.75rem; color: rgb(var(--color-foreground));
85
+ }
86
+ #section-{{ section.id }} .features-grid__subheading {
87
+ font-size: clamp(1rem, 1.5vw, 1.125rem); opacity: 0.7; max-width: 640px;
88
+ margin: 0 auto; color: rgb(var(--color-foreground)); line-height: 1.6;
89
+ }
90
+ /* ── Grid: 1 → 2 → N cols ── */
45
91
  #section-{{ section.id }} .features-grid__items {
46
92
  display: grid;
47
93
  grid-template-columns: repeat(var(--cols, 3), 1fr);
48
94
  gap: 2rem;
49
95
  }
50
- #section-{{ section.id }} .features-grid__item { text-align: center; padding: 1.5rem; }
51
- #section-{{ section.id }} .features-grid__icon { margin: 0 auto 1rem; width: 60px; height: 60px; }
52
- #section-{{ section.id }} .features-grid__icon img { width: 100%; height: 100%; object-fit: contain; }
53
- #section-{{ section.id }} .features-grid__item-heading { font-size: 1.25rem; margin: 0 0 0.5rem; color: inherit; }
54
- #section-{{ section.id }} .features-grid__item-text { line-height: 1.6; opacity: 0.8; margin: 0; color: inherit; }
96
+ /* ── Card: lift + border reveal on hover ── */
97
+ #section-{{ section.id }} .features-grid__item {
98
+ padding: 2rem 1.75rem; border-radius: 12px; text-align: center;
99
+ background: rgb(var(--color-background));
100
+ border: 1px solid rgba(var(--color-foreground), 0.08);
101
+ transition: transform 0.35s cubic-bezier(0.22,1,0.36,1),
102
+ box-shadow 0.35s ease,
103
+ border-color 0.35s ease;
104
+ will-change: transform;
105
+ }
106
+ #section-{{ section.id }} .features-grid__item:hover {
107
+ transform: translateY(-8px);
108
+ box-shadow: 0 20px 60px rgba(var(--color-foreground), 0.1);
109
+ border-color: rgba(var(--color-button), 0.4);
110
+ }
111
+ /* ── Icon: bounce-scale animation on hover ── */
112
+ #section-{{ section.id }} .features-grid__icon-wrap { margin: 0 auto 1.25rem; }
113
+ #section-{{ section.id }} .features-grid__icon {
114
+ width: 72px; height: 72px; margin: 0 auto;
115
+ display: grid; place-items: center;
116
+ background: rgba(var(--color-button), 0.1); border-radius: 50%;
117
+ transition: transform 0.4s cubic-bezier(0.34,1.56,0.64,1);
118
+ will-change: transform;
119
+ }
120
+ #section-{{ section.id }} .features-grid__icon img { width: 40px; height: 40px; object-fit: contain; }
121
+ #section-{{ section.id }} .features-grid__icon--emoji { font-size: 2rem; background: rgba(var(--color-button), 0.08); }
122
+ #section-{{ section.id }} .features-grid__item:hover .features-grid__icon {
123
+ transform: scale(1.2) rotate(-5deg);
124
+ }
125
+ /* ── Text ── */
126
+ #section-{{ section.id }} .features-grid__item-heading {
127
+ font-size: 1.125rem; font-weight: 700; margin: 0 0 0.625rem;
128
+ color: rgb(var(--color-foreground));
129
+ }
130
+ #section-{{ section.id }} .features-grid__item-text {
131
+ font-size: 0.9375rem; line-height: 1.65; opacity: 0.75; margin: 0 0 1rem;
132
+ color: rgb(var(--color-foreground));
133
+ }
134
+ #section-{{ section.id }} .features-grid__link {
135
+ font-size: 0.875rem; font-weight: 600; color: rgb(var(--color-button));
136
+ text-decoration: none; display: inline-flex; align-items: center; gap: 0.3rem;
137
+ }
138
+ #section-{{ section.id }} .features-grid__link-arrow {
139
+ display: inline-block;
140
+ transition: transform 0.2s ease;
141
+ }
142
+ #section-{{ section.id }} .features-grid__link:hover .features-grid__link-arrow { transform: translateX(4px); }
143
+ /* ── Scroll-reveal ── */
144
+ #section-{{ section.id }} .feat-reveal {
145
+ opacity: 0; transform: translateY(30px);
146
+ transition: opacity 0.6s ease, transform 0.6s cubic-bezier(0.22,1,0.36,1);
147
+ }
148
+ #section-{{ section.id }} .feat-reveal.is-visible { opacity: 1; transform: translateY(0); }
149
+ /* ── Reduced motion ── */
150
+ @media (prefers-reduced-motion: reduce) {
151
+ #section-{{ section.id }} .feat-reveal { opacity: 1; transform: none; transition: none; }
152
+ #section-{{ section.id }} .features-grid__item { transition: none; }
153
+ #section-{{ section.id }} .features-grid__icon { transition: none; }
154
+ #section-{{ section.id }} .features-grid__link-arrow { transition: none; }
155
+ }
156
+ /* ── Responsive ── */
55
157
  @media (max-width: 989px) {
56
158
  #section-{{ section.id }} .features-grid__items { grid-template-columns: repeat(2, 1fr); }
57
159
  }
58
160
  @media (max-width: 749px) {
59
- #section-{{ section.id }} .features-grid__items { grid-template-columns: 1fr; }
161
+ #section-{{ section.id }} .features-grid__items { grid-template-columns: 1fr; gap: 1.25rem; }
162
+ #section-{{ section.id }} .features-grid__item { padding: 1.5rem 1.25rem; }
60
163
  }
61
164
  </style>
62
165
 
166
+ <script>
167
+ /* Stagger reveal — Intersection Observer with per-item delay */
168
+ (function() {
169
+ var items = document.querySelectorAll('#section-{{ section.id }} .feat-reveal');
170
+ if (!items.length) return;
171
+ if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
172
+ items.forEach(function(el) { el.classList.add('is-visible'); });
173
+ return;
174
+ }
175
+ var observer = new IntersectionObserver(function(entries) {
176
+ entries.forEach(function(entry, i) {
177
+ if (entry.isIntersecting) {
178
+ setTimeout(function() { entry.target.classList.add('is-visible'); }, i * 90);
179
+ observer.unobserve(entry.target);
180
+ }
181
+ });
182
+ }, { threshold: 0.1 });
183
+ items.forEach(function(el) { observer.observe(el); });
184
+ })();
185
+ </script>
186
+
63
187
  {% schema %}
64
188
  {
65
189
  "name": "Features Grid",
66
190
  "tag": "section",
67
191
  "class": "section-features-grid",
68
192
  "settings": [
193
+ { "type": "color_scheme", "id": "color_scheme", "label": "Color Scheme", "default": "scheme-1" },
194
+ { "type": "font_picker", "id": "heading_font", "label": "Heading Font", "default": "helvetica_n4" },
195
+ { "type": "range", "id": "heading_font_size", "label": "Heading Size (px)", "min": 20, "max": 56, "step": 2, "default": 40 },
196
+ { "type": "select", "id": "heading_tag", "label": "Heading Tag", "options": [
197
+ { "value": "h1", "label": "H1" }, { "value": "h2", "label": "H2" },
198
+ { "value": "h3", "label": "H3" }, { "value": "h4", "label": "H4" }
199
+ ], "default": "h2" },
69
200
  { "type": "text", "id": "heading", "label": "Heading", "default": "Why choose us" },
70
- { "type": "text", "id": "subheading", "label": "Subheading" },
71
- { "type": "range", "id": "columns_per_row", "label": "Columns", "min": 2, "max": 4, "step": 1, "default": 3 }
201
+ { "type": "text", "id": "subheading", "label": "Subheading", "default": "Everything you need to succeed." },
202
+ { "type": "range", "id": "columns_per_row", "label": "Columns (desktop)", "min": 2, "max": 4, "step": 1, "default": 3 },
203
+ { "type": "range", "id": "padding_top", "label": "Padding Top (px)", "min": 0, "max": 160, "step": 8, "default": 80 },
204
+ { "type": "range", "id": "padding_bottom", "label": "Padding Bottom (px)", "min": 0, "max": 160, "step": 8, "default": 80 }
72
205
  ],
73
206
  "blocks": [
74
207
  {
@@ -76,8 +209,11 @@
76
209
  "name": "Feature",
77
210
  "settings": [
78
211
  { "type": "image_picker", "id": "icon_image", "label": "Icon Image" },
79
- { "type": "text", "id": "heading", "label": "Heading", "default": "Feature title" },
80
- { "type": "text", "id": "text", "label": "Description", "default": "Describe your feature here." }
212
+ { "type": "text", "id": "icon_emoji", "label": "Icon Emoji (fallback)", "default": "" },
213
+ { "type": "text", "id": "heading", "label": "Heading", "default": "Feature Title" },
214
+ { "type": "textarea", "id": "text", "label": "Description", "default": "Describe this feature in a sentence or two that highlights the value." },
215
+ { "type": "text", "id": "link_label", "label": "Link Label" },
216
+ { "type": "url", "id": "link_url", "label": "Link URL" }
81
217
  ]
82
218
  },
83
219
  { "type": "@app" }
@@ -85,9 +221,7 @@
85
221
  "presets": [{
86
222
  "name": "Features Grid",
87
223
  "blocks": [
88
- { "type": "feature" },
89
- { "type": "feature" },
90
- { "type": "feature" }
224
+ { "type": "feature" }, { "type": "feature" }, { "type": "feature" }
91
225
  ]
92
226
  }]
93
227
  }
@@ -1,102 +1,215 @@
1
- {%- comment -%} rebly-sections: Hero Banner | Category: hero | OS2.0 {%- endcomment -%}
1
+ {%- comment -%} rebly-sections: Hero Banner | Category: hero | OS2.0 | Awwwards-level {%- endcomment -%}
2
+ {%- assign font = section.settings.heading_font -%}
3
+ {%- assign heading_tag = section.settings.heading_tag -%}
2
4
 
3
- <section id="section-{{ section.id }}" class="hero-banner">
4
- <div class="hero-banner__inner"
5
- style="
6
- --overlay-opacity: {{ section.settings.overlay_opacity | divided_by: 100.0 }};
7
- --text-color: {{ section.settings.text_color }};
8
- --min-height: {{ section.settings.min_height }}px;
9
- ">
5
+ {{ font | font_face: font_display: 'swap' }}
6
+
7
+ <section id="section-{{ section.id }}" class="hero-banner color-{{ section.settings.color_scheme }}">
8
+ <div class="hero-banner__inner" style="
9
+ --overlay-opacity: {{ section.settings.overlay_opacity | divided_by: 100.0 }};
10
+ --min-height: {{ section.settings.min_height }}px;
11
+ --pt: {{ section.settings.padding_top }}px;
12
+ --pb: {{ section.settings.padding_bottom }}px;
13
+ --heading-size: {{ section.settings.heading_font_size }}px;
14
+ --heading-font: {{ font.family }}, {{ font.fallback_families }};
15
+ --heading-weight: {{ font.weight }};
16
+ ">
10
17
 
11
18
  {%- if section.settings.image != blank -%}
12
- <div class="hero-banner__bg">
13
- {{- section.settings.image | image_url: width: 1920 | image_tag: loading: 'eager', fetchpriority: 'high', class: 'hero-banner__img' -}}
19
+ {%- comment -%} Parallax container — JS nudges translateY on scroll {%- endcomment -%}
20
+ <div class="hero-banner__parallax" aria-hidden="true">
21
+ <img
22
+ src="{{ section.settings.image | image_url: width: 1920 }}"
23
+ srcset="
24
+ {{ section.settings.image | image_url: width: 750 }} 750w,
25
+ {{ section.settings.image | image_url: width: 1200 }} 1200w,
26
+ {{ section.settings.image | image_url: width: 1920 }} 1920w"
27
+ sizes="100vw"
28
+ loading="eager"
29
+ fetchpriority="high"
30
+ alt="{{ section.settings.image.alt | escape }}"
31
+ class="hero-banner__img"
32
+ width="{{ section.settings.image.width }}"
33
+ height="{{ section.settings.image.height }}"
34
+ >
14
35
  </div>
15
36
  {%- endif -%}
16
37
 
17
- <div class="hero-banner__overlay"></div>
38
+ {%- comment -%} Glassmorphism overlay — conditionally applied {%- endcomment -%}
39
+ <div class="hero-banner__overlay{% if section.settings.glass_overlay %} hero-banner__overlay--glass{% endif %}"></div>
18
40
 
19
41
  {%- for block in section.blocks -%}
20
42
  <div {{ block.shopify_attributes }}></div>
21
43
  {%- endfor -%}
22
44
 
23
45
  <div class="hero-banner__content hero-banner__content--{{ section.settings.content_position }}">
46
+ {%- if section.settings.eyebrow != blank -%}
47
+ <p class="hero-banner__eyebrow hero-anim hero-anim--1">{{ section.settings.eyebrow | escape }}</p>
48
+ {%- endif -%}
24
49
  {%- if section.settings.heading != blank -%}
25
- <h1 class="hero-banner__heading">{{ section.settings.heading | escape }}</h1>
50
+ <{{ heading_tag }} class="hero-banner__heading hero-anim hero-anim--2">
51
+ {{ section.settings.heading | escape }}
52
+ </{{ heading_tag }}>
26
53
  {%- endif -%}
27
54
  {%- if section.settings.subtext != blank -%}
28
- <p class="hero-banner__subtext">{{ section.settings.subtext | escape }}</p>
29
- {%- endif -%}
30
- {%- if section.settings.button_label != blank -%}
31
- <a href="{{ section.settings.button_link }}" class="hero-banner__btn btn">
32
- {{ section.settings.button_label | escape }}
33
- </a>
55
+ <p class="hero-banner__subtext hero-anim hero-anim--3">{{ section.settings.subtext | escape }}</p>
34
56
  {%- endif -%}
57
+ <div class="hero-banner__actions hero-anim hero-anim--4">
58
+ {%- if section.settings.button_label != blank -%}
59
+ <a href="{{ section.settings.button_link }}" class="hero-banner__btn hero-banner__btn--primary">
60
+ {{ section.settings.button_label | escape }}
61
+ </a>
62
+ {%- endif -%}
63
+ {%- if section.settings.button_label_2 != blank -%}
64
+ <a href="{{ section.settings.button_link_2 }}" class="hero-banner__btn hero-banner__btn--secondary">
65
+ {{ section.settings.button_label_2 | escape }}
66
+ </a>
67
+ {%- endif -%}
68
+ </div>
35
69
  </div>
36
70
 
37
71
  </div>
38
72
  </section>
39
73
 
40
74
  <style>
75
+ /* ── Base ── */
41
76
  #section-{{ section.id }} .hero-banner__inner {
42
- position: relative;
43
- display: grid;
44
- place-items: center;
45
- min-height: var(--min-height, 500px);
46
- overflow: hidden;
47
- color: var(--text-color, #ffffff);
48
- }
49
- #section-{{ section.id }} .hero-banner__bg,
77
+ position: relative; display: grid; place-items: center;
78
+ min-height: var(--min-height, 600px); overflow: hidden;
79
+ padding-top: var(--pt, 80px); padding-bottom: var(--pb, 80px);
80
+ }
81
+ /* ── Parallax bg — GPU-only transforms ── */
82
+ #section-{{ section.id }} .hero-banner__parallax {
83
+ position: absolute; inset: -15% 0; will-change: transform;
84
+ }
50
85
  #section-{{ section.id }} .hero-banner__img {
51
- position: absolute;
52
- inset: 0;
53
- width: 100%;
54
- height: 100%;
55
- object-fit: cover;
86
+ width: 100%; height: 100%; object-fit: cover; display: block;
56
87
  }
88
+ /* ── Overlay: standard + glassmorphism variant ── */
57
89
  #section-{{ section.id }} .hero-banner__overlay {
58
- position: absolute;
59
- inset: 0;
60
- background: rgba(0,0,0, var(--overlay-opacity, 0.4));
90
+ position: absolute; inset: 0;
91
+ background: rgba(var(--color-overlay-rgb, 0,0,0), var(--overlay-opacity, 0.45));
92
+ }
93
+ #section-{{ section.id }} .hero-banner__overlay--glass {
94
+ backdrop-filter: blur(4px) saturate(1.4);
95
+ -webkit-backdrop-filter: blur(4px) saturate(1.4);
61
96
  }
97
+ /* ── Content ── */
62
98
  #section-{{ section.id }} .hero-banner__content {
63
- position: relative;
64
- z-index: 1;
65
- padding: 2rem;
66
- max-width: 800px;
67
- text-align: center;
99
+ position: relative; z-index: 1; padding: 2rem;
100
+ max-width: 860px; text-align: center; width: 100%;
101
+ color: rgb(var(--color-foreground));
68
102
  }
69
- #section-{{ section.id }} .hero-banner__content--left { text-align: left; justify-self: start; }
103
+ #section-{{ section.id }} .hero-banner__content--left { text-align: left; justify-self: start; }
70
104
  #section-{{ section.id }} .hero-banner__content--right { text-align: right; justify-self: end; }
71
- #section-{{ section.id }} .hero-banner__heading { font-size: clamp(2rem, 5vw, 4rem); margin: 0 0 1rem; color: var(--text-color, #ffffff); }
72
- #section-{{ section.id }} .hero-banner__subtext { font-size: 1.125rem; margin: 0 0 1.5rem; opacity: 0.9; color: var(--text-color, #ffffff); }
73
- #section-{{ section.id }} .hero-banner__btn { display: inline-block; padding: 0.75rem 2rem; background: #fff; color: #000; text-decoration: none; border-radius: 4px; font-weight: 600; }
105
+ #section-{{ section.id }} .hero-banner__eyebrow {
106
+ font-size: 0.8125rem; letter-spacing: 0.15em; text-transform: uppercase;
107
+ opacity: 0.8; margin: 0 0 0.75rem;
108
+ }
109
+ #section-{{ section.id }} .hero-banner__heading {
110
+ font-family: var(--heading-font); font-weight: var(--heading-weight);
111
+ font-size: clamp(2rem, 5vw, var(--heading-size, 4rem));
112
+ line-height: 1.1; margin: 0 0 1rem;
113
+ }
114
+ #section-{{ section.id }} .hero-banner__subtext {
115
+ font-size: clamp(1rem, 2vw, 1.25rem); opacity: 0.9;
116
+ max-width: 600px; margin: 0 auto 1.75rem; line-height: 1.65;
117
+ }
118
+ #section-{{ section.id }} .hero-banner__content--left .hero-banner__subtext,
119
+ #section-{{ section.id }} .hero-banner__content--right .hero-banner__subtext { margin-left: 0; margin-right: 0; }
120
+ #section-{{ section.id }} .hero-banner__actions { display: flex; gap: 1rem; flex-wrap: wrap; justify-content: center; }
121
+ #section-{{ section.id }} .hero-banner__content--left .hero-banner__actions { justify-content: flex-start; }
122
+ #section-{{ section.id }} .hero-banner__content--right .hero-banner__actions { justify-content: flex-end; }
123
+ #section-{{ section.id }} .hero-banner__btn {
124
+ display: inline-flex; align-items: center; padding: 0.875rem 2.25rem;
125
+ border-radius: 4px; font-weight: 600; text-decoration: none; font-size: 0.9375rem;
126
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
127
+ }
128
+ #section-{{ section.id }} .hero-banner__btn--primary {
129
+ background: rgb(var(--color-button)); color: rgb(var(--color-button-text));
130
+ box-shadow: 0 4px 16px rgba(0,0,0,0.2);
131
+ }
132
+ #section-{{ section.id }} .hero-banner__btn--secondary {
133
+ background: transparent; color: rgb(var(--color-foreground));
134
+ border: 2px solid rgba(var(--color-foreground), 0.7);
135
+ }
136
+ #section-{{ section.id }} .hero-banner__btn:hover {
137
+ transform: translateY(-2px); box-shadow: 0 8px 24px rgba(0,0,0,0.25);
138
+ }
139
+ /* ── Stagger entrance animations ── */
140
+ #section-{{ section.id }} .hero-anim {
141
+ opacity: 0; transform: translateY(24px);
142
+ animation: heroFadeUp 0.7s cubic-bezier(0.22,1,0.36,1) forwards;
143
+ }
144
+ #section-{{ section.id }} .hero-anim--1 { animation-delay: 0.1s; }
145
+ #section-{{ section.id }} .hero-anim--2 { animation-delay: 0.25s; }
146
+ #section-{{ section.id }} .hero-anim--3 { animation-delay: 0.4s; }
147
+ #section-{{ section.id }} .hero-anim--4 { animation-delay: 0.55s; }
148
+ @keyframes heroFadeUp {
149
+ to { opacity: 1; transform: translateY(0); }
150
+ }
151
+ /* ── Reduced motion: skip animations ── */
152
+ @media (prefers-reduced-motion: reduce) {
153
+ #section-{{ section.id }} .hero-anim { animation: none; opacity: 1; transform: none; }
154
+ #section-{{ section.id }} .hero-banner__parallax { position: absolute; inset: 0; }
155
+ }
156
+ /* ── Responsive ── */
74
157
  @media (max-width: 749px) {
75
158
  #section-{{ section.id }} .hero-banner__content { padding: 1.5rem; }
76
159
  #section-{{ section.id }} .hero-banner__content--left,
77
160
  #section-{{ section.id }} .hero-banner__content--right { text-align: center; justify-self: center; }
161
+ #section-{{ section.id }} .hero-banner__content--left .hero-banner__actions,
162
+ #section-{{ section.id }} .hero-banner__content--right .hero-banner__actions { justify-content: center; }
163
+ }
164
+ @media (min-width: 750px) and (max-width: 989px) {
165
+ #section-{{ section.id }} .hero-banner__content { max-width: 680px; }
78
166
  }
79
167
  </style>
80
168
 
169
+ <script>
170
+ /* Parallax — GPU-accelerated translateY, respects reduced-motion */
171
+ (function() {
172
+ if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
173
+ var el = document.querySelector('#section-{{ section.id }} .hero-banner__parallax');
174
+ if (!el) return;
175
+ function onScroll() {
176
+ var rect = el.closest('section').getBoundingClientRect();
177
+ var progress = -rect.top / (window.innerHeight + rect.height);
178
+ el.style.transform = 'translateY(' + (progress * 80).toFixed(2) + 'px)';
179
+ }
180
+ window.addEventListener('scroll', onScroll, { passive: true });
181
+ })();
182
+ </script>
183
+
81
184
  {% schema %}
82
185
  {
83
186
  "name": "Hero Banner",
84
187
  "tag": "section",
85
188
  "class": "section-hero-banner",
86
189
  "settings": [
190
+ { "type": "color_scheme", "id": "color_scheme", "label": "Color Scheme", "default": "scheme-1" },
87
191
  { "type": "image_picker", "id": "image", "label": "Background Image" },
192
+ { "type": "font_picker", "id": "heading_font", "label": "Heading Font", "default": "helvetica_n4" },
193
+ { "type": "range", "id": "heading_font_size", "label": "Heading Size (px)", "min": 28, "max": 96, "step": 4, "default": 64 },
194
+ { "type": "select", "id": "heading_tag", "label": "Heading Tag", "options": [
195
+ { "value": "h1", "label": "H1" }, { "value": "h2", "label": "H2" },
196
+ { "value": "h3", "label": "H3" }, { "value": "h4", "label": "H4" }
197
+ ], "default": "h1" },
198
+ { "type": "text", "id": "eyebrow", "label": "Eyebrow Text" },
88
199
  { "type": "text", "id": "heading", "label": "Heading", "default": "Welcome to our store" },
89
- { "type": "text", "id": "subtext", "label": "Subtext", "default": "Discover our collection" },
90
- { "type": "text", "id": "button_label", "label": "Button Label", "default": "Shop Now" },
91
- { "type": "url", "id": "button_link", "label": "Button Link" },
92
- { "type": "range", "id": "overlay_opacity", "label": "Overlay Opacity", "min": 0, "max": 80, "step": 5, "default": 40 },
93
- { "type": "range", "id": "min_height", "label": "Min Height (px)", "min": 300, "max": 900, "step": 50, "default": 500 },
94
- { "type": "color", "id": "text_color", "label": "Text Color", "default": "#ffffff" },
200
+ { "type": "textarea", "id": "subtext", "label": "Subtext", "default": "Discover our curated collection of premium products." },
201
+ { "type": "text", "id": "button_label", "label": "Primary Button Label", "default": "Shop Now" },
202
+ { "type": "url", "id": "button_link", "label": "Primary Button Link" },
203
+ { "type": "text", "id": "button_label_2", "label": "Secondary Button Label" },
204
+ { "type": "url", "id": "button_link_2", "label": "Secondary Button Link" },
205
+ { "type": "range", "id": "overlay_opacity", "label": "Overlay Opacity %", "min": 0, "max": 80, "step": 5, "default": 40 },
206
+ { "type": "checkbox", "id": "glass_overlay", "label": "Glassmorphism Overlay", "default": false },
207
+ { "type": "range", "id": "min_height", "label": "Min Height (px)", "min": 300, "max": 900, "step": 50, "default": 600 },
95
208
  { "type": "select", "id": "content_position", "label": "Content Position", "options": [
96
- { "value": "left", "label": "Left" },
97
- { "value": "center", "label": "Center" },
98
- { "value": "right", "label": "Right" }
99
- ], "default": "center" }
209
+ { "value": "left", "label": "Left" }, { "value": "center", "label": "Center" }, { "value": "right", "label": "Right" }
210
+ ], "default": "center" },
211
+ { "type": "range", "id": "padding_top", "label": "Padding Top (px)", "min": 0, "max": 160, "step": 8, "default": 80 },
212
+ { "type": "range", "id": "padding_bottom", "label": "Padding Bottom (px)", "min": 0, "max": 160, "step": 8, "default": 80 }
100
213
  ],
101
214
  "blocks": [{ "type": "@app" }],
102
215
  "presets": [{ "name": "Hero Banner" }]