├── sections ├── cart-drawer.liquid ├── cart-notification-button.liquid ├── cart-live-region-text.liquid ├── cart-icon-bubble.liquid ├── main-404.liquid ├── apps.liquid ├── main-page.liquid ├── cart-notification-product.liquid ├── custom-liquid.liquid ├── predictive-search.liquid ├── announcement-bar.liquid ├── pickup-availability.liquid ├── main-collection-banner.liquid ├── page.liquid ├── main-blog.liquid └── main-list-collections.liquid ├── .DS_Store ├── .gitattributes ├── templates ├── 404.json ├── customers │ ├── login.json │ ├── order.json │ ├── account.json │ ├── register.json │ ├── addresses.json │ ├── activate_account.json │ └── reset_password.json ├── page.json ├── list-collections.json ├── blog.json ├── page.contact.json ├── search.json ├── collection.json ├── article.json ├── password.json └── cart.json ├── assets ├── component-show-more.css ├── password-modal.js ├── section-product-recommendations.css ├── section-main-page.css ├── component-list-payment.css ├── component-list-social.css ├── component-totals.css ├── component-list-menu.css ├── component-discounts.css ├── section-contact-form.css ├── component-search.css ├── video-section.css ├── theme-editor.js ├── show-more.js ├── component-product-model.css ├── newsletter-section.css ├── product-modal.js ├── component-rating.css ├── section-collection-list.css ├── component-accordion.css ├── disclosure.css ├── component-loading-overlay.css ├── component-rte.css ├── product-model.js ├── component-model-viewer-ui.css ├── component-newsletter.css ├── component-pagination.css ├── section-rich-text.css ├── section-featured-product.css ├── template-collection.css ├── details-disclosure.js ├── section-featured-blog.css ├── details-modal.js ├── component-price.css ├── share.js ├── component-mega-menu.css ├── component-modal-video.css ├── section-main-blog.css ├── cart-notification.js ├── transitions.js ├── component-deferred-media.css ├── component-collection-hero.css ├── component-cart-notification.css ├── section-email-signup-banner.css ├── component-article-card.css ├── collapsible-content.css ├── customer.js ├── product-form.js ├── quick-add.js ├── pickup-availability.js ├── section-blog-post.css ├── component-pickup-availability.css ├── component-cart.css ├── cart-drawer.js ├── media-gallery.js ├── quick-add.css └── component-predictive-search.css ├── snippets ├── icon-minus.liquid ├── icon-caret.liquid ├── icon-tumblr.liquid ├── icon-tiktok.liquid ├── icon-plus.liquid ├── icon-discount.liquid ├── icon-hamburger.liquid ├── icon-tick.liquid ├── icon-arrow.liquid ├── icon-clipboard.liquid ├── icon-youtube.liquid ├── icon-close.liquid ├── icon-checkmark.liquid ├── icon-play.liquid ├── icon-close-small.liquid ├── icon-unavailable.liquid ├── icon-cart-empty.liquid ├── icon-success.liquid ├── icon-facebook.liquid ├── icon-account.liquid ├── icon-pause.liquid ├── icon-vimeo.liquid ├── icon-cart.liquid ├── icon-filter.liquid ├── icon-padlock.liquid ├── icon-remove.liquid ├── icon-twitter.liquid ├── icon-error.liquid ├── icon-pinterest.liquid ├── icon-share.liquid ├── icon-3d-model.liquid ├── icon-instagram.liquid ├── icon-zoom.liquid ├── cart-notification.liquid ├── meta-tags.liquid ├── icon-snapchat.liquid ├── pagination.liquid ├── email-signup-banner-background-mobile.liquid ├── price.liquid └── email-signup-banner-background.liquid ├── README.md ├── translation.yml ├── LICENSE.md └── release-notes.md /sections/cart-drawer.liquid: -------------------------------------------------------------------------------- 1 | {%- render 'cart-drawer' -%} 2 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SidNewman/shopify-transitions/HEAD/.DS_Store -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /sections/cart-notification-button.liquid: -------------------------------------------------------------------------------- 1 | {{ 'general.cart.view' | t: count: cart.item_count }} 2 | -------------------------------------------------------------------------------- /sections/cart-live-region-text.liquid: -------------------------------------------------------------------------------- 1 | {{ 'sections.cart.new_subtotal' | t }}: {{ cart.total_price | money_with_currency }} 2 | -------------------------------------------------------------------------------- /templates/404.json: -------------------------------------------------------------------------------- 1 | { 2 | "sections": { 3 | "main": { 4 | "type": "main-404" 5 | } 6 | }, 7 | "order": [ 8 | "main" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /templates/customers/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "sections": { 3 | "main": { 4 | "type": "main-login" 5 | } 6 | }, 7 | "order": [ 8 | "main" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /templates/customers/order.json: -------------------------------------------------------------------------------- 1 | { 2 | "sections": { 3 | "main": { 4 | "type": "main-order" 5 | } 6 | }, 7 | "order": [ 8 | "main" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /templates/customers/account.json: -------------------------------------------------------------------------------- 1 | { 2 | "sections": { 3 | "main": { 4 | "type": "main-account" 5 | } 6 | }, 7 | "order": [ 8 | "main" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /templates/customers/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "sections": { 3 | "main": { 4 | "type": "main-register" 5 | } 6 | }, 7 | "order": [ 8 | "main" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /templates/customers/addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "sections": { 3 | "main": { 4 | "type": "main-addresses" 5 | } 6 | }, 7 | "order": [ 8 | "main" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /templates/customers/activate_account.json: -------------------------------------------------------------------------------- 1 | { 2 | "sections": { 3 | "main": { 4 | "type": "main-activate-account" 5 | } 6 | }, 7 | "order": [ 8 | "main" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /templates/customers/reset_password.json: -------------------------------------------------------------------------------- 1 | { 2 | "sections": { 3 | "main": { 4 | "type": "main-reset-password" 5 | } 6 | }, 7 | "order": [ 8 | "main" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /assets/component-show-more.css: -------------------------------------------------------------------------------- 1 | 2 | .button-show-more { 3 | padding-left: 0; 4 | justify-content: flex-start; 5 | padding-bottom: 1.1rem; 6 | } 7 | 8 | .button-show-more, 9 | .button-show-less { 10 | margin-top: 1.5rem; 11 | } 12 | -------------------------------------------------------------------------------- /templates/page.json: -------------------------------------------------------------------------------- 1 | { 2 | "sections": { 3 | "main": { 4 | "type": "main-page", 5 | "settings": { 6 | "padding_top": 28, 7 | "padding_bottom": 28 8 | } 9 | } 10 | }, 11 | "order": [ 12 | "main" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /assets/password-modal.js: -------------------------------------------------------------------------------- 1 | class PasswordModal extends DetailsModal { 2 | constructor() { 3 | super(); 4 | 5 | if (this.querySelector('input[aria-invalid="true"]')) this.open({target: this.querySelector('details')}); 6 | } 7 | } 8 | 9 | customElements.define('password-modal', PasswordModal); 10 | -------------------------------------------------------------------------------- /snippets/icon-minus.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /assets/section-product-recommendations.css: -------------------------------------------------------------------------------- 1 | .product-recommendations { 2 | display: block; 3 | } 4 | 5 | .product-recommendations:not(.product-recommendations--loaded) { 6 | padding: 0; 7 | margin: 0; 8 | } 9 | 10 | .product-recommendations__heading { 11 | margin: 0; 12 | margin-bottom: 3rem; 13 | } 14 | -------------------------------------------------------------------------------- /snippets/icon-caret.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /snippets/icon-tumblr.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /templates/list-collections.json: -------------------------------------------------------------------------------- 1 | { 2 | "sections": { 3 | "main": { 4 | "type": "main-list-collections", 5 | "settings": { 6 | "title": "Collections", 7 | "sort": "alphabetical", 8 | "image_ratio": "square" 9 | } 10 | } 11 | }, 12 | "order": [ 13 | "main" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /snippets/icon-tiktok.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /snippets/icon-plus.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /snippets/icon-discount.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /snippets/icon-hamburger.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /snippets/icon-tick.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /snippets/icon-arrow.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /snippets/icon-clipboard.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /snippets/icon-youtube.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /snippets/icon-close.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /snippets/icon-checkmark.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /snippets/icon-play.liquid: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /templates/blog.json: -------------------------------------------------------------------------------- 1 | { 2 | "sections": { 3 | "main": { 4 | "type": "main-blog", 5 | "settings": { 6 | "layout": "collage", 7 | "show_image": true, 8 | "image_height": "medium", 9 | "show_date": true, 10 | "show_author": false, 11 | "padding_top": 36, 12 | "padding_bottom": 36 13 | } 14 | } 15 | }, 16 | "order": [ 17 | "main" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /assets/section-main-page.css: -------------------------------------------------------------------------------- 1 | .page-title { 2 | margin-top: 0; 3 | } 4 | 5 | .main-page-title { 6 | margin-bottom: 3rem; 7 | } 8 | 9 | @media screen and (min-width: 750px) { 10 | .main-page-title { 11 | margin-bottom: 4rem; 12 | } 13 | } 14 | 15 | .page-placeholder-wrapper { 16 | display: flex; 17 | justify-content: center; 18 | } 19 | 20 | .page-placeholder { 21 | width: 52.5rem; 22 | height: 52.5rem; 23 | } 24 | -------------------------------------------------------------------------------- /snippets/icon-close-small.liquid: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /snippets/icon-unavailable.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /snippets/icon-cart-empty.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /assets/component-list-payment.css: -------------------------------------------------------------------------------- 1 | .list-payment { 2 | display: flex; 3 | flex-wrap: wrap; 4 | justify-content: center; 5 | margin: -0.5rem 0; 6 | padding-top: 1rem; 7 | padding-left: 0; 8 | } 9 | 10 | @media screen and (min-width: 750px) { 11 | .list-payment { 12 | justify-content: flex-end; 13 | margin: -0.5rem; 14 | padding-top: 0; 15 | } 16 | } 17 | 18 | .list-payment__item { 19 | align-items: center; 20 | display: flex; 21 | padding: 0.5rem; 22 | } 23 | -------------------------------------------------------------------------------- /snippets/icon-success.liquid: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Slick & smooth page transitions for any shopify theme :point_down: :fire: :heart_eyes: 2 | ## Currently re working this to be much more robust! so bare with me im a busy boi 3 | 4 | 5 | ### A simple fade 6 | 7 | https://user-images.githubusercontent.com/104797880/186023261-43f22cb1-c7d7-46ce-87c0-08fe72bed80b.mov 8 | 9 | ### Or using anything you can imagine in the DOM 10 | 11 | https://user-images.githubusercontent.com/104797880/186023352-de0038a1-de4b-4b3d-bd77-a17f866197c1.mov 12 | -------------------------------------------------------------------------------- /snippets/icon-facebook.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /snippets/icon-account.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /templates/page.contact.json: -------------------------------------------------------------------------------- 1 | { 2 | "sections": { 3 | "main": { 4 | "type": "main-page", 5 | "settings": { 6 | "padding_top": 36, 7 | "padding_bottom": 36 8 | } 9 | }, 10 | "form": { 11 | "type": "contact-form", 12 | "settings": { 13 | "heading": "", 14 | "heading_size": "h1", 15 | "color_scheme": "background-1", 16 | "padding_top": 36, 17 | "padding_bottom": 36 18 | } 19 | } 20 | }, 21 | "order": [ 22 | "main", 23 | "form" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /snippets/icon-pause.liquid: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /snippets/icon-vimeo.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /snippets/icon-cart.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /sections/cart-icon-bubble.liquid: -------------------------------------------------------------------------------- 1 | {%- liquid 2 | if cart == empty 3 | render 'icon-cart-empty' 4 | else 5 | render 'icon-cart' 6 | endif 7 | -%} 8 | {{ 'templates.cart.cart' | t }} 9 | {%- if cart != empty -%} 10 |
11 | {%- if cart.item_count < 100 -%} 12 | 13 | {%- endif -%} 14 | {{ 'sections.header.cart_count' | t: count: cart.item_count }} 15 |
16 | {%- endif -%} 17 | -------------------------------------------------------------------------------- /assets/component-list-social.css: -------------------------------------------------------------------------------- 1 | .list-social { 2 | display: flex; 3 | flex-wrap: wrap; 4 | justify-content: flex-end; 5 | } 6 | 7 | @media only screen and (max-width: 749px) { 8 | .list-social { 9 | justify-content: center; 10 | } 11 | } 12 | 13 | .list-social__item .icon { 14 | height: 1.8rem; 15 | width: 1.8rem; 16 | } 17 | 18 | .list-social__link { 19 | align-items: center; 20 | display: flex; 21 | padding: 1.3rem; 22 | color: rgb(var(--color-foreground)); 23 | } 24 | 25 | .list-social__link:hover .icon { 26 | transform: scale(1.07); 27 | } 28 | -------------------------------------------------------------------------------- /snippets/icon-filter.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /sections/main-404.liquid: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 |

15 | {{ 'templates.404.subtext' | t }} 16 |

17 |

18 | {{ 'templates.404.title' | t }} 19 |

20 | 21 | {{ 'general.continue_shopping' | t }} 22 | 23 |
24 | -------------------------------------------------------------------------------- /snippets/icon-padlock.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /templates/search.json: -------------------------------------------------------------------------------- 1 | { 2 | "sections": { 3 | "main": { 4 | "type": "main-search", 5 | "settings": { 6 | "columns_desktop": 4, 7 | "image_ratio": "adapt", 8 | "show_secondary_image": false, 9 | "show_vendor": false, 10 | "show_rating": false, 11 | "enable_filtering": true, 12 | "enable_sorting": true, 13 | "article_show_date": true, 14 | "article_show_author": false, 15 | "columns_mobile": "2", 16 | "padding_top": 36, 17 | "padding_bottom": 36 18 | } 19 | } 20 | }, 21 | "order": [ 22 | "main" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /assets/component-totals.css: -------------------------------------------------------------------------------- 1 | .totals { 2 | display: flex; 3 | justify-content: center; 4 | align-items: flex-end; 5 | } 6 | 7 | .totals > * { 8 | font-size: 1.6rem; 9 | margin: 0; 10 | } 11 | 12 | .totals > h2 { 13 | font-size: calc(var(--font-heading-scale) * 1.6rem); 14 | } 15 | 16 | .totals * { 17 | line-height: 1; 18 | } 19 | 20 | .totals > * + * { 21 | margin-left: 2rem; 22 | } 23 | 24 | .totals__subtotal-value { 25 | font-size: 1.8rem; 26 | } 27 | 28 | .cart__ctas + .totals { 29 | margin-top: 2rem; 30 | } 31 | 32 | @media all and (min-width: 750px) { 33 | .totals { 34 | justify-content: flex-end; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /snippets/icon-remove.liquid: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /assets/component-list-menu.css: -------------------------------------------------------------------------------- 1 | .list-menu--right { 2 | right: 0; 3 | } 4 | 5 | .list-menu--disclosure { 6 | position: absolute; 7 | min-width: 100%; 8 | width: 20rem; 9 | border: 1px solid rgba(var(--color-foreground), 0.2); 10 | } 11 | 12 | .list-menu--disclosure:focus { 13 | outline: none; 14 | } 15 | 16 | .list-menu__item--active { 17 | text-decoration: underline; 18 | text-underline-offset: 0.3rem; 19 | } 20 | 21 | .list-menu__item--active:hover { 22 | text-decoration-thickness: 0.2rem; 23 | } 24 | 25 | .list-menu--disclosure.localization-selector { 26 | max-height: 18rem; 27 | overflow: auto; 28 | width: 10rem; 29 | padding: 0.5rem; 30 | } 31 | -------------------------------------------------------------------------------- /assets/component-discounts.css: -------------------------------------------------------------------------------- 1 | .discounts { 2 | font-size: 1.2rem; 3 | } 4 | 5 | .discounts__discount { 6 | display: flex; 7 | align-items: center; 8 | line-height: calc(1 + 0.5 / var(--font-body-scale)); 9 | } 10 | 11 | .discounts__discount svg { 12 | color: rgba(var(--color-button), var(--alpha-button-background)); 13 | } 14 | 15 | .discounts__discount--position { 16 | justify-content: center; 17 | } 18 | 19 | @media screen and (min-width: 750px) { 20 | .discounts__discount--position { 21 | justify-content: flex-end; 22 | } 23 | } 24 | 25 | .discounts__discount > .icon { 26 | color: rgb(var(--color-foreground)); 27 | width: 1.2rem; 28 | height: 1.2rem; 29 | margin-right: 0.7rem; 30 | } 31 | -------------------------------------------------------------------------------- /sections/apps.liquid: -------------------------------------------------------------------------------- 1 |
2 | {%- for block in section.blocks -%} 3 | {% render block %} 4 | {%- endfor -%} 5 |
6 | 7 | {% schema %} 8 | { 9 | "name": "t:sections.apps.name", 10 | "tag": "section", 11 | "class": "section", 12 | "settings": [ 13 | { 14 | "type": "checkbox", 15 | "id": "include_margins", 16 | "default": true, 17 | "label": "t:sections.apps.settings.include_margins.label" 18 | } 19 | ], 20 | "blocks": [ 21 | { 22 | "type": "@app" 23 | } 24 | ], 25 | "presets": [ 26 | { 27 | "name": "t:sections.apps.presets.name" 28 | } 29 | ] 30 | } 31 | {% endschema %} 32 | -------------------------------------------------------------------------------- /snippets/icon-twitter.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /translation.yml: -------------------------------------------------------------------------------- 1 | source_language: en 2 | target_languages: [bg-BG, cs, da, de, el, es, fi, fr, hr-HR, hu, id, it, ja, ko, lt-LT, nb, nl, pl, pt-BR, pt-PT, ro-RO, ru, sk-SK, sl-SI, sv, th, tr, vi, zh-CN, zh-TW] 3 | non_blocking_languages: [] 4 | components: 5 | - name: buyer 6 | audience: buyer 7 | scheme: 'online-store-theme' 8 | owners: ['@Shopify/themes-translations'] 9 | paths: 10 | - locales/{{language}}.json 11 | - name: merchant 12 | target_languages: [cs, da, de, es, fi, fr, it, ja, ko, nb, nl, pl, pt-BR, pt-PT, sv, th, tr, vi, zh-CN, zh-TW] 13 | audience: merchant 14 | scheme: 'online-store-theme' 15 | owners: ['@Shopify/themes-translations'] 16 | paths: 17 | - locales/{{language}}.schema.json 18 | -------------------------------------------------------------------------------- /assets/section-contact-form.css: -------------------------------------------------------------------------------- 1 | .contact img { 2 | max-width: 100%; 3 | } 4 | 5 | .contact .form__message { 6 | align-items: flex-start; 7 | } 8 | 9 | .contact .icon-success { 10 | margin-top: 0.2rem; 11 | } 12 | 13 | .contact .field { 14 | margin-bottom: 1.5rem; 15 | } 16 | 17 | @media screen and (min-width: 750px) { 18 | .contact .field { 19 | margin-bottom: 2rem; 20 | } 21 | } 22 | 23 | .contact__button { 24 | margin-top: 3rem; 25 | } 26 | 27 | @media screen and (min-width: 750px) { 28 | .contact__button { 29 | margin-top: 4rem; 30 | } 31 | } 32 | 33 | @media screen and (min-width: 750px) { 34 | .contact__fields { 35 | display: grid; 36 | grid-template-columns: repeat(2, 1fr); 37 | grid-column-gap: 2rem; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /assets/component-search.css: -------------------------------------------------------------------------------- 1 | .search__input.field__input { 2 | padding-right: 5rem; 3 | } 4 | 5 | .search__button { 6 | right: var(--inputs-border-width); 7 | top: var(--inputs-border-width); 8 | } 9 | 10 | .search__button:focus-visible { 11 | background-color: rgb(var(--color-background)); 12 | z-index: 2; 13 | } 14 | 15 | .search__button:focus { 16 | background-color: rgb(var(--color-background)); 17 | z-index: 2; 18 | } 19 | 20 | .search__button:not(:focus-visible):not(.focused){ 21 | box-shadow: inherit; 22 | background-color: inherit; 23 | } 24 | 25 | .search__button .icon { 26 | height: 1.8rem; 27 | width: 1.8rem; 28 | } 29 | 30 | /* Remove extra spacing for search inputs in Safari */ 31 | input::-webkit-search-decoration { 32 | -webkit-appearance: none; 33 | } 34 | -------------------------------------------------------------------------------- /assets/video-section.css: -------------------------------------------------------------------------------- 1 | .video-section__media { 2 | position: relative; 3 | padding-bottom: 56.25%; 4 | } 5 | 6 | .video-section__media.deferred-media { 7 | box-shadow: var(--media-shadow-horizontal-offset) var(--media-shadow-vertical-offset) var(--media-shadow-blur-radius) rgba(var(--color-shadow), var(--media-shadow-opacity)); 8 | } 9 | 10 | .video-section__media.deferred-media:after { 11 | content: none; 12 | } 13 | 14 | .video-section__poster.deferred-media__poster:focus { 15 | outline-offset: 0.3rem; 16 | } 17 | 18 | .video-section__media iframe { 19 | background-color: rgba(var(--color-foreground), 0.03); 20 | border: 0; 21 | } 22 | 23 | .video-section__poster, 24 | .video-section__media iframe { 25 | position: absolute; 26 | width: 100%; 27 | height: 100%; 28 | } 29 | -------------------------------------------------------------------------------- /templates/collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "sections": { 3 | "banner": { 4 | "type": "main-collection-banner", 5 | "settings": { 6 | "show_collection_description": true, 7 | "show_collection_image": false, 8 | "color_scheme": "background-1" 9 | } 10 | }, 11 | "product-grid": { 12 | "type": "main-collection-product-grid", 13 | "settings": { 14 | "products_per_page": 16, 15 | "columns_desktop": 4, 16 | "image_ratio": "adapt", 17 | "show_secondary_image": false, 18 | "show_vendor": false, 19 | "show_rating": false, 20 | "enable_filtering": true, 21 | "enable_sorting": true, 22 | "columns_mobile": "2", 23 | "padding_top": 36, 24 | "padding_bottom": 36 25 | } 26 | } 27 | }, 28 | "order": [ 29 | "banner", 30 | "product-grid" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /assets/theme-editor.js: -------------------------------------------------------------------------------- 1 | document.addEventListener('shopify:block:select', function(event) { 2 | const blockSelectedIsSlide = event.target.classList.contains('slideshow__slide'); 3 | if (!blockSelectedIsSlide) return; 4 | 5 | const parentSlideshowComponent = event.target.closest('slideshow-component'); 6 | parentSlideshowComponent.pause(); 7 | 8 | setTimeout(function() { 9 | parentSlideshowComponent.slider.scrollTo({ 10 | left: event.target.offsetLeft 11 | }); 12 | }, 200); 13 | }); 14 | 15 | document.addEventListener('shopify:block:deselect', function(event) { 16 | const blockDeselectedIsSlide = event.target.classList.contains('slideshow__slide'); 17 | if (!blockDeselectedIsSlide) return; 18 | const parentSlideshowComponent = event.target.closest('slideshow-component'); 19 | if (parentSlideshowComponent.autoplayButtonIsSetToPlay) parentSlideshowComponent.play(); 20 | }); 21 | -------------------------------------------------------------------------------- /templates/article.json: -------------------------------------------------------------------------------- 1 | { 2 | "sections": { 3 | "main": { 4 | "type": "main-article", 5 | "blocks": { 6 | "featured_image": { 7 | "type": "featured_image", 8 | "settings": { 9 | "image_height": "adapt" 10 | } 11 | }, 12 | "title": { 13 | "type": "title", 14 | "settings": { 15 | "blog_show_date": true, 16 | "blog_show_author": false 17 | } 18 | }, 19 | "share": { 20 | "type": "share", 21 | "settings": { 22 | "share_label": "Share" 23 | } 24 | }, 25 | "content": { 26 | "type": "content" 27 | } 28 | }, 29 | "block_order": [ 30 | "featured_image", 31 | "title", 32 | "share", 33 | "content" 34 | ] 35 | } 36 | }, 37 | "order": [ 38 | "main" 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /snippets/icon-error.liquid: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /assets/show-more.js: -------------------------------------------------------------------------------- 1 | class ShowMoreButton extends HTMLElement { 2 | constructor() { 3 | super(); 4 | const button = this.querySelector('button'); 5 | button.addEventListener('click', (event) => { 6 | this.expandShowMore(event); 7 | const nextElementToFocus = event.target.closest('.parent-display').querySelector('.show-more-item') 8 | if (nextElementToFocus && !nextElementToFocus.classList.contains('hidden')) { 9 | nextElementToFocus.querySelector('input').focus() 10 | } 11 | }); 12 | } 13 | expandShowMore(event) { 14 | const parentDisplay = event.target.closest('[id^="Show-More-"]').closest('.parent-display'); 15 | const parentWrap = parentDisplay.querySelector('.parent-wrap'); 16 | this.querySelectorAll('.label-text').forEach(element => element.classList.toggle('hidden')); 17 | parentDisplay.querySelectorAll('.show-more-item').forEach(item => item.classList.toggle('hidden')) 18 | } 19 | } 20 | 21 | customElements.define('show-more-button', ShowMoreButton); 22 | 23 | -------------------------------------------------------------------------------- /assets/component-product-model.css: -------------------------------------------------------------------------------- 1 | .product__xr-button { 2 | background: rgba(var(--color-foreground), 0.08); 3 | color: rgb(var(--color-foreground)); 4 | margin: 1rem auto; 5 | box-shadow: none; 6 | display: flex; 7 | } 8 | 9 | .button.product__xr-button:hover { 10 | box-shadow: none; 11 | } 12 | 13 | .product__xr-button[data-shopify-xr-hidden] { 14 | visibility: hidden; 15 | } 16 | 17 | .shopify-design-mode .product__xr-button[data-shopify-xr-hidden] { 18 | display: none; 19 | } 20 | 21 | @media screen and (max-width: 749px) { 22 | slider-component .product__xr-button { 23 | display: none; 24 | } 25 | 26 | .active .product__xr-button:not([data-shopify-xr-hidden]) { 27 | display: block; 28 | } 29 | } 30 | 31 | @media screen and (min-width: 750px) { 32 | slider-component + .button.product__xr-button { 33 | display: none; 34 | } 35 | 36 | .product__xr-button[data-shopify-xr-hidden] { 37 | display: none; 38 | } 39 | } 40 | 41 | .product__xr-button .icon { 42 | width: 1.4rem; 43 | margin-right: 1rem; 44 | } 45 | -------------------------------------------------------------------------------- /snippets/icon-pinterest.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /snippets/icon-share.liquid: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /assets/newsletter-section.css: -------------------------------------------------------------------------------- 1 | .newsletter__wrapper { 2 | padding-right: calc(4rem / var(--font-body-scale)); 3 | padding-left: calc(4rem / var(--font-body-scale)); 4 | } 5 | 6 | @media screen and (min-width: 750px) { 7 | .newsletter__wrapper { 8 | padding-right: 9rem; 9 | padding-left: 9rem; 10 | } 11 | } 12 | 13 | .newsletter__wrapper > * { 14 | margin-top: 0; 15 | margin-bottom: 0; 16 | } 17 | 18 | .newsletter__wrapper > * + * { 19 | margin-top: 2rem; 20 | } 21 | 22 | .newsletter__wrapper > * + .newsletter-form { 23 | margin-top: 3rem; 24 | } 25 | 26 | .newsletter__subheading { 27 | max-width: 70rem; 28 | margin-left: auto; 29 | margin-right: auto; 30 | } 31 | 32 | .newsletter__wrapper .newsletter-form__field-wrapper { 33 | max-width: 36rem; 34 | } 35 | 36 | .newsletter-form__field-wrapper .newsletter-form__message { 37 | margin-top: 1.5rem; 38 | } 39 | 40 | .newsletter__button { 41 | margin-top: 3rem; 42 | width: fit-content; 43 | } 44 | 45 | @media screen and (min-width: 750px) { 46 | .newsletter__button { 47 | flex-shrink: 0; 48 | margin: 0 0 0 1rem; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /templates/password.json: -------------------------------------------------------------------------------- 1 | { 2 | "layout": "password", 3 | "sections": { 4 | "main": { 5 | "type": "email-signup-banner", 6 | "blocks": { 7 | "heading": { 8 | "type": "heading", 9 | "settings": { 10 | "heading": "Opening soon", 11 | "heading_size": "h1" 12 | } 13 | }, 14 | "paragraph": { 15 | "type": "paragraph", 16 | "settings": { 17 | "text": "

Be the first to know when we launch.<\/p>", 18 | "text_style": "body" 19 | } 20 | }, 21 | "email_form": { 22 | "type": "email_form" 23 | } 24 | }, 25 | "block_order": [ 26 | "heading", 27 | "paragraph", 28 | "email_form" 29 | ], 30 | "settings": { 31 | "image_overlay_opacity": 0, 32 | "show_background_image": true, 33 | "image_height": "medium", 34 | "desktop_content_position": "middle-center", 35 | "show_text_box": true, 36 | "desktop_content_alignment": "center", 37 | "color_scheme": "background-1", 38 | "mobile_content_alignment": "center", 39 | "show_text_below": true 40 | } 41 | } 42 | }, 43 | "order": [ 44 | "main" 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /assets/product-modal.js: -------------------------------------------------------------------------------- 1 | if (!customElements.get('product-modal')) { 2 | customElements.define('product-modal', class ProductModal extends ModalDialog { 3 | constructor() { 4 | super(); 5 | } 6 | 7 | hide() { 8 | super.hide(); 9 | } 10 | 11 | show(opener) { 12 | super.show(opener); 13 | this.showActiveMedia(); 14 | } 15 | 16 | showActiveMedia() { 17 | this.querySelectorAll(`[data-media-id]:not([data-media-id="${this.openedBy.getAttribute("data-media-id")}"])`).forEach((element) => { 18 | element.classList.remove('active'); 19 | } 20 | ) 21 | const activeMedia = this.querySelector(`[data-media-id="${this.openedBy.getAttribute("data-media-id")}"]`); 22 | const activeMediaTemplate = activeMedia.querySelector('template'); 23 | const activeMediaContent = activeMediaTemplate ? activeMediaTemplate.content : null; 24 | activeMedia.classList.add('active'); 25 | activeMedia.scrollIntoView(); 26 | 27 | const container = this.querySelector('[role="document"]'); 28 | container.scrollLeft = (activeMedia.width - container.clientWidth) / 2; 29 | 30 | if (activeMedia.nodeName == 'DEFERRED-MEDIA' && activeMediaContent && activeMediaContent.querySelector('.js-youtube')) 31 | activeMedia.loadContent(); 32 | } 33 | }); 34 | } 35 | -------------------------------------------------------------------------------- /assets/component-rating.css: -------------------------------------------------------------------------------- 1 | .rating { 2 | display: inline-block; 3 | margin: 0; 4 | } 5 | 6 | .product .rating-star { 7 | --letter-spacing: 0.8; 8 | --font-size: 1.7; 9 | } 10 | 11 | .card-wrapper .rating-star { 12 | --letter-spacing: 0.7; 13 | --font-size: 1.4; 14 | } 15 | 16 | .rating-star { 17 | --percent: calc( 18 | ( 19 | var(--rating) / var(--rating-max) + var(--rating-decimal) * 20 | var(--font-size) / 21 | (var(--rating-max) * (var(--letter-spacing) + var(--font-size))) 22 | ) * 100% 23 | ); 24 | letter-spacing: calc(var(--letter-spacing) * 1rem); 25 | font-size: calc(var(--font-size) * 1rem); 26 | line-height: 1; 27 | display: inline-block; 28 | font-family: Times; 29 | margin: 0; 30 | } 31 | 32 | .rating-star::before { 33 | content: '★★★★★'; 34 | background: linear-gradient( 35 | 90deg, 36 | var(--color-icon) var(--percent), 37 | rgba(var(--color-foreground), 0.15) var(--percent) 38 | ); 39 | -webkit-background-clip: text; 40 | -webkit-text-fill-color: transparent; 41 | } 42 | 43 | .rating-text { 44 | display: none; 45 | } 46 | 47 | .rating-count { 48 | display: inline-block; 49 | margin: 0; 50 | } 51 | 52 | @media (forced-colors: active) { 53 | .rating { 54 | display: none; 55 | } 56 | 57 | .rating-text { 58 | display: block; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /snippets/icon-3d-model.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /snippets/icon-instagram.liquid: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /assets/section-collection-list.css: -------------------------------------------------------------------------------- 1 | .collection-list { 2 | margin-top: 0; 3 | margin-bottom: 0; 4 | } 5 | 6 | .collection-list-title { 7 | margin: 0; 8 | } 9 | 10 | @media screen and (max-width: 749px) { 11 | .collection-list:not(.slider) { 12 | padding-left: 0; 13 | padding-right: 0; 14 | } 15 | 16 | .section-collection-list .page-width { 17 | padding-left: 0; 18 | padding-right: 0; 19 | } 20 | 21 | .section-collection-list .collection-list:not(.slider) { 22 | padding-left: 1.5rem; 23 | padding-right: 1.5rem; 24 | } 25 | } 26 | 27 | .collection-list__item:only-child { 28 | max-width: 100%; 29 | width: 100%; 30 | } 31 | 32 | @media screen and (max-width: 749px) { 33 | .slider.collection-list--1-items { 34 | padding-bottom: 0; 35 | } 36 | } 37 | 38 | @media screen and (min-width: 750px) and (max-width: 989px) { 39 | .slider.collection-list--1-items, 40 | .slider.collection-list--2-items, 41 | .slider.collection-list--3-items, 42 | .slider.collection-list--4-items { 43 | padding-bottom: 0; 44 | } 45 | } 46 | 47 | @media screen and (min-width: 750px) { 48 | .collection-list__item a:hover { 49 | box-shadow: none; 50 | } 51 | } 52 | 53 | @media screen and (max-width: 989px) { 54 | .collection-list.slider .collection-list__item { 55 | max-width: 100%; 56 | } 57 | } 58 | 59 | .collection-list-view-all { 60 | margin-top: 2rem; 61 | } 62 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021-present Shopify Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, sell and/or create derivative works of the Software or any part thereof, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The rights granted above may only be exercised to develop themes that integrate or interoperate with Shopify software or services, and, if applicable, to distribute, offer for sale or otherwise make available any such themes via the Shopify Theme Store. All other uses of the Software are strictly prohibited. 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /assets/component-accordion.css: -------------------------------------------------------------------------------- 1 | .accordion summary { 2 | display: flex; 3 | position: relative; 4 | line-height: 1; 5 | padding: 1.5rem 0; 6 | } 7 | 8 | .accordion .summary__title { 9 | display: flex; 10 | flex: 1; 11 | } 12 | 13 | .accordion .summary__title + .icon-caret { 14 | height: calc(var(--font-heading-scale) * 0.6rem); 15 | } 16 | 17 | .accordion + .accordion { 18 | margin-top: 0; 19 | border-top: none; 20 | } 21 | 22 | .accordion { 23 | margin-top: 2.5rem; 24 | margin-bottom: 0; 25 | border-top: 0.1rem solid rgba(var(--color-foreground), 0.08); 26 | border-bottom: 0.1rem solid rgba(var(--color-foreground), 0.08); 27 | } 28 | 29 | .accordion__title { 30 | display: inline-block; 31 | max-width: calc(100% - 6rem); 32 | min-height: 1.6rem; 33 | margin: 0; 34 | word-break: break-word; 35 | } 36 | 37 | .accordion .icon-accordion { 38 | align-self: center; 39 | fill: rgb(var(--color-foreground)); 40 | height: calc(var(--font-heading-scale) * 2rem); 41 | margin-right: calc(var(--font-heading-scale) * 1rem); 42 | width: calc(var(--font-heading-scale) * 2rem); 43 | } 44 | 45 | .accordion details[open] > summary .icon-caret { 46 | transform: rotate(180deg); 47 | } 48 | 49 | .accordion__content { 50 | margin-bottom: 1.5rem; 51 | word-break: break-word; 52 | overflow-x: auto; 53 | padding: 0 0.6rem; 54 | } 55 | 56 | .accordion__content img { 57 | max-width: 100%; 58 | } 59 | -------------------------------------------------------------------------------- /templates/cart.json: -------------------------------------------------------------------------------- 1 | { 2 | "sections": { 3 | "cart-items": { 4 | "type": "main-cart-items", 5 | "settings": { 6 | "padding_top": 36, 7 | "padding_bottom": 36 8 | } 9 | }, 10 | "cart-footer": { 11 | "type": "main-cart-footer", 12 | "blocks": { 13 | "subtotal": { 14 | "type": "subtotal", 15 | "settings": { 16 | } 17 | }, 18 | "buttons": { 19 | "type": "buttons", 20 | "settings": { 21 | } 22 | } 23 | }, 24 | "block_order": [ 25 | "subtotal", 26 | "buttons" 27 | ] 28 | }, 29 | "featured-collection": { 30 | "type": "featured-collection", 31 | "settings": { 32 | "title": "Featured collection", 33 | "heading_size": "h2", 34 | "collection": "all", 35 | "products_to_show": 4, 36 | "columns_desktop": 4, 37 | "color_scheme": "background-1", 38 | "show_view_all": true, 39 | "swipe_on_mobile": false, 40 | "image_ratio": "square", 41 | "show_secondary_image": false, 42 | "show_vendor": false, 43 | "show_rating": false, 44 | "columns_mobile": "2", 45 | "padding_top": 36, 46 | "padding_bottom": 36 47 | } 48 | } 49 | }, 50 | "order": [ 51 | "cart-items", 52 | "cart-footer", 53 | "featured-collection" 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /snippets/icon-zoom.liquid: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /assets/disclosure.css: -------------------------------------------------------------------------------- 1 | .disclosure { 2 | position: relative; 3 | } 4 | 5 | .disclosure__button { 6 | align-items: center; 7 | cursor: pointer; 8 | display: flex; 9 | height: 4rem; 10 | padding: 0 1.5rem 0 1.5rem; 11 | font-size: 1.3rem; 12 | background-color: transparent; 13 | } 14 | 15 | .disclosure__list-wrapper { 16 | border-width: var(--popup-border-width); 17 | border-style: solid; 18 | border-color: rgba(var(--color-foreground), var(--popup-border-opacity)); 19 | overflow: hidden; 20 | position: absolute; 21 | bottom: 100%; 22 | transform: translateY(-1rem); 23 | z-index: 2; 24 | background-color: rgb(var(--color-background)); 25 | border-radius: var(--popup-corner-radius); 26 | box-shadow: var(--popup-shadow-horizontal-offset) var(--popup-shadow-vertical-offset) var(--popup-shadow-blur-radius) rgba(var(--color-shadow), var(--popup-shadow-opacity)); 27 | } 28 | 29 | .disclosure__list { 30 | position: relative; 31 | overflow-y: auto; 32 | font-size: 1.4rem; 33 | padding-bottom: 0.5rem; 34 | padding-top: 0.5rem; 35 | scroll-padding: 0.5rem 0; 36 | min-height: 8.2rem; 37 | max-height: 19rem; 38 | max-width: 22rem; 39 | min-width: 12rem; 40 | width: max-content; 41 | } 42 | 43 | .disclosure__item { 44 | position: relative; 45 | } 46 | 47 | .disclosure__link { 48 | display: block; 49 | padding: 0.5rem 2.2rem; 50 | text-decoration: none; 51 | line-height: calc(1 + 0.8 / var(--font-body-scale)); 52 | } 53 | -------------------------------------------------------------------------------- /assets/component-loading-overlay.css: -------------------------------------------------------------------------------- 1 | .loading-overlay { 2 | position: absolute; 3 | z-index: 1; 4 | width: 1.8rem; 5 | } 6 | 7 | @media screen and (max-width: 749px) { 8 | .loading-overlay { 9 | top: 0; 10 | right: 0; 11 | } 12 | } 13 | 14 | @media screen and (min-width: 750px) { 15 | .loading-overlay { 16 | left: 0; 17 | } 18 | } 19 | 20 | .loading-overlay__spinner { 21 | width: 1.8rem; 22 | display: inline-block; 23 | } 24 | 25 | .spinner { 26 | animation: rotator 1.4s linear infinite; 27 | } 28 | 29 | @keyframes rotator { 30 | 0% { 31 | transform: rotate(0deg); 32 | } 33 | 100% { 34 | transform: rotate(270deg); 35 | } 36 | } 37 | 38 | .path { 39 | stroke-dasharray: 280; 40 | stroke-dashoffset: 0; 41 | transform-origin: center; 42 | stroke: rgb(var(--color-foreground)); 43 | animation: dash 1.4s ease-in-out infinite; 44 | } 45 | 46 | @media screen and (forced-colors: active) { 47 | .path{ 48 | stroke: CanvasText; 49 | } 50 | } 51 | 52 | @keyframes dash { 53 | 0% { 54 | stroke-dashoffset: 280; 55 | } 56 | 50% { 57 | stroke-dashoffset: 75; 58 | transform: rotate(135deg); 59 | } 60 | 100% { 61 | stroke-dashoffset: 280; 62 | transform: rotate(450deg); 63 | } 64 | } 65 | 66 | .loading-overlay:not(.hidden) + .cart-item__price-wrapper, 67 | .loading-overlay:not(.hidden) ~ cart-remove-button { 68 | opacity: 50%; 69 | } 70 | 71 | .loading-overlay:not(.hidden) ~ cart-remove-button { 72 | pointer-events: none; 73 | cursor: default; 74 | } 75 | -------------------------------------------------------------------------------- /assets/component-rte.css: -------------------------------------------------------------------------------- 1 | .rte:after { 2 | clear: both; 3 | content: ''; 4 | display: block; 5 | } 6 | 7 | .rte > p:first-child { 8 | margin-top: 0; 9 | } 10 | 11 | .rte > p:last-child { 12 | margin-bottom: 0; 13 | } 14 | 15 | .rte table { 16 | table-layout: fixed; 17 | } 18 | 19 | @media screen and (min-width: 750px) { 20 | .rte table td { 21 | padding-left: 1.2rem; 22 | padding-right: 1.2rem; 23 | } 24 | } 25 | 26 | .rte img { 27 | height: auto; 28 | max-width: 100%; 29 | border: var(--media-border-width) solid rgba(var(--color-foreground), var(--media-border-opacity)); 30 | border-radius: var(--media-radius); 31 | box-shadow: var(--media-shadow-horizontal-offset) var(--media-shadow-vertical-offset) var(--media-shadow-blur-radius) rgba(var(--color-shadow), var(--media-shadow-opacity)); 32 | margin-bottom: var(--media-shadow-vertical-offset); 33 | } 34 | 35 | .rte ul { 36 | padding-left: 2rem; 37 | } 38 | 39 | .rte li { 40 | list-style: inherit; 41 | } 42 | 43 | .rte li:last-child { 44 | margin-bottom: 0; 45 | } 46 | 47 | .rte a { 48 | color: rgba(var(--color-link), var(--alpha-link)); 49 | text-underline-offset: 0.3rem; 50 | text-decoration-thickness: 0.1rem; 51 | transition: text-decoration-thickness var(--duration-short) ease; 52 | } 53 | 54 | .rte a:hover { 55 | color: rgb(var(--color-link)); 56 | text-decoration-thickness: 0.2rem; 57 | } 58 | 59 | .rte blockquote { 60 | display: inline-flex; 61 | } 62 | 63 | .rte blockquote > * { 64 | margin: -0.5rem 0 -0.5rem 0; 65 | } 66 | -------------------------------------------------------------------------------- /assets/product-model.js: -------------------------------------------------------------------------------- 1 | if (!customElements.get('product-model')) { 2 | customElements.define('product-model', class ProductModel extends DeferredMedia { 3 | constructor() { 4 | super(); 5 | } 6 | 7 | loadContent() { 8 | super.loadContent(); 9 | 10 | Shopify.loadFeatures([ 11 | { 12 | name: 'model-viewer-ui', 13 | version: '1.0', 14 | onLoad: this.setupModelViewerUI.bind(this), 15 | }, 16 | ]); 17 | } 18 | 19 | setupModelViewerUI(errors) { 20 | if (errors) return; 21 | 22 | this.modelViewerUI = new Shopify.ModelViewerUI(this.querySelector('model-viewer')); 23 | } 24 | }); 25 | } 26 | 27 | window.ProductModel = { 28 | loadShopifyXR() { 29 | Shopify.loadFeatures([ 30 | { 31 | name: 'shopify-xr', 32 | version: '1.0', 33 | onLoad: this.setupShopifyXR.bind(this), 34 | }, 35 | ]); 36 | }, 37 | 38 | setupShopifyXR(errors) { 39 | if (errors) return; 40 | 41 | if (!window.ShopifyXR) { 42 | document.addEventListener('shopify_xr_initialized', () => 43 | this.setupShopifyXR() 44 | ); 45 | return; 46 | } 47 | 48 | document.querySelectorAll('[id^="ProductJSON-"]').forEach((modelJSON) => { 49 | window.ShopifyXR.addModels(JSON.parse(modelJSON.textContent)); 50 | modelJSON.remove(); 51 | }); 52 | window.ShopifyXR.setupXRElements(); 53 | }, 54 | }; 55 | 56 | window.addEventListener('DOMContentLoaded', () => { 57 | if (window.ProductModel) window.ProductModel.loadShopifyXR(); 58 | }); 59 | -------------------------------------------------------------------------------- /assets/component-model-viewer-ui.css: -------------------------------------------------------------------------------- 1 | .shopify-model-viewer-ui .shopify-model-viewer-ui__controls-area { 2 | background: rgb(var(--color-background)); 3 | border-color: rgba(var(--color-foreground), 0.04); 4 | } 5 | 6 | .shopify-model-viewer-ui .shopify-model-viewer-ui__button { 7 | color: rgba(var(--color-foreground), 0.75); 8 | } 9 | 10 | .shopify-model-viewer-ui .shopify-model-viewer-ui__button--control:hover { 11 | color: rgba(var(--color-foreground), 0.55); 12 | } 13 | 14 | .shopify-model-viewer-ui .shopify-model-viewer-ui__button--control:active, 15 | .shopify-model-viewer-ui .shopify-model-viewer-ui__button--control.focus-visible:focus { 16 | color: rgba(var(--color-foreground), 0.55); 17 | background: rgba(var(--color-foreground), 0.04); 18 | } 19 | 20 | .shopify-model-viewer-ui .shopify-model-viewer-ui__button--control:not(:last-child):after { 21 | border-color: rgba(var(--color-foreground), 0.04); 22 | } 23 | 24 | .shopify-model-viewer-ui .shopify-model-viewer-ui__button--poster { 25 | border-radius: 50%; 26 | color: rgb(var(--color-foreground)); 27 | background: rgb(var(--color-background)); 28 | border-color: rgba(var(--color-foreground), 0.1); 29 | transform: translate(-50%, -50%) scale(1); 30 | transition: transform var(--duration-short) ease, color var(--duration-short) ease; 31 | } 32 | 33 | .shopify-model-viewer-ui .shopify-model-viewer-ui__poster-control-icon { 34 | width: 4.8rem; 35 | height: 4.8rem; 36 | margin-top: .3rem; 37 | } 38 | 39 | .shopify-model-viewer-ui .shopify-model-viewer-ui__button--poster:hover, 40 | .shopify-model-viewer-ui .shopify-model-viewer-ui__button--poster:focus { 41 | transform: translate(-50%, -50%) scale(1.1); 42 | } 43 | 44 | -------------------------------------------------------------------------------- /assets/component-newsletter.css: -------------------------------------------------------------------------------- 1 | .newsletter-form { 2 | display: flex; 3 | flex-direction: column; 4 | justify-content: center; 5 | align-items: center; 6 | width: 100%; 7 | position: relative; 8 | } 9 | 10 | @media screen and (min-width: 750px) { 11 | .newsletter-form { 12 | align-items: flex-start; 13 | margin: 0 auto; 14 | max-width: 36rem; 15 | } 16 | } 17 | 18 | .newsletter-form__field-wrapper { 19 | width: 100%; 20 | } 21 | 22 | .newsletter-form__field-wrapper .field__input { 23 | padding-right: 5rem; 24 | } 25 | 26 | .newsletter-form__field-wrapper .field { 27 | z-index: 0; 28 | } 29 | 30 | .newsletter-form__message { 31 | justify-content: center; 32 | margin-bottom: 0; 33 | } 34 | 35 | .newsletter-form__message--success { 36 | margin-top: 2rem; 37 | } 38 | 39 | @media screen and (min-width: 750px) { 40 | .newsletter-form__message { 41 | justify-content: flex-start; 42 | } 43 | } 44 | 45 | .newsletter-form__button { 46 | width: 4.4rem; 47 | margin: 0; 48 | right: var(--inputs-border-width); 49 | top: 0; 50 | height: 100%; 51 | z-index: 2; 52 | } 53 | 54 | .newsletter-form__button:focus-visible { 55 | box-shadow: 0 0 0 .3rem rgb(var(--color-background)),0 0 0 .4rem rgba(var(--color-foreground)); 56 | background-color: rgb(var(--color-background)); 57 | } 58 | 59 | .newsletter-form__button:focus { 60 | box-shadow: 0 0 0 .3rem rgb(var(--color-background)),0 0 0 .4rem rgba(var(--color-foreground)); 61 | background-color: rgb(var(--color-background)); 62 | } 63 | 64 | .newsletter-form__button:not(:focus-visible):not(.focused) { 65 | box-shadow: inherit; 66 | background-color: inherit; 67 | } 68 | 69 | .newsletter-form__button .icon { 70 | width: 1.5rem; 71 | } 72 | -------------------------------------------------------------------------------- /assets/component-pagination.css: -------------------------------------------------------------------------------- 1 | .pagination-wrapper { 2 | margin-top: 4rem; 3 | } 4 | 5 | @media screen and (min-width: 990px) { 6 | .pagination-wrapper { 7 | margin-top: 5rem; 8 | } 9 | } 10 | 11 | .pagination__list { 12 | display: flex; 13 | flex-wrap: wrap; 14 | justify-content: center; 15 | } 16 | 17 | .pagination__list > li { 18 | flex: 1 0 4.4rem; 19 | max-width: 4.4rem; 20 | } 21 | 22 | .pagination__list > li:not(:last-child) { 23 | margin-right: 1rem; 24 | } 25 | 26 | .pagination__item { 27 | color: rgb(var(--color-foreground)); 28 | display: inline-flex; 29 | justify-content: center; 30 | align-items: center; 31 | position: relative; 32 | height: 4.4rem; 33 | width: 100%; 34 | padding: 0; 35 | text-decoration: none; 36 | } 37 | 38 | a.pagination__item:hover::after { 39 | height: 0.1rem; 40 | } 41 | 42 | .pagination__item .icon-caret { 43 | height: 0.6rem; 44 | } 45 | 46 | .pagination__item--current::after { 47 | height: 0.1rem; 48 | } 49 | 50 | .pagination__item--current::after, 51 | .pagination__item:hover::after { 52 | content: ''; 53 | display: block; 54 | width: 2rem; 55 | position: absolute; 56 | bottom: 8px; 57 | left: 50%; 58 | transform: translateX(-50%); 59 | background-color: currentColor; 60 | } 61 | 62 | .pagination__item--next .icon { 63 | margin-left: -0.2rem; 64 | transform: rotate(90deg); 65 | } 66 | 67 | .pagination__item--next:hover .icon { 68 | transform: rotate(90deg) scale(1.07); 69 | } 70 | 71 | .pagination__item--prev .icon { 72 | margin-right: -0.2rem; 73 | transform: rotate(-90deg); 74 | } 75 | 76 | .pagination__item--prev:hover .icon { 77 | transform: rotate(-90deg) scale(1.07); 78 | } 79 | 80 | .pagination__item-arrow:hover::after { 81 | display: none; 82 | } 83 | -------------------------------------------------------------------------------- /assets/section-rich-text.css: -------------------------------------------------------------------------------- 1 | .rich-text { 2 | z-index: 1; 3 | } 4 | 5 | .rich-text__wrapper { 6 | display: flex; 7 | justify-content: center; 8 | width: calc(100% - 4rem / var(--font-body-scale)); 9 | } 10 | 11 | .rich-text:not(.rich-text--full-width) .rich-text__wrapper { 12 | margin: auto; 13 | width: calc(100% - 8rem / var(--font-body-scale)); 14 | } 15 | 16 | .rich-text__blocks { 17 | width: 100%; 18 | } 19 | 20 | @media screen and (min-width: 750px) { 21 | .rich-text__wrapper { 22 | width: 100%; 23 | } 24 | 25 | .rich-text__wrapper--left { 26 | justify-content: flex-start; 27 | } 28 | 29 | .rich-text__wrapper--right { 30 | justify-content: flex-end; 31 | } 32 | 33 | .rich-text__blocks { 34 | max-width: 50rem; 35 | } 36 | } 37 | 38 | @media screen and (min-width: 990px) { 39 | .rich-text__blocks { 40 | max-width: 78rem; 41 | } 42 | } 43 | 44 | .rich-text__blocks * { 45 | overflow-wrap: break-word; 46 | } 47 | 48 | .rich-text__blocks > * { 49 | margin-top: 0; 50 | margin-bottom: 0; 51 | } 52 | 53 | .rich-text__blocks > * + * { 54 | margin-top: 2rem; 55 | } 56 | 57 | .rich-text__blocks > * + a { 58 | margin-top: 3rem; 59 | } 60 | 61 | .rich-text__buttons { 62 | display: inline-flex; 63 | justify-content: center; 64 | flex-wrap: wrap; 65 | gap: 1rem; 66 | width: 100%; 67 | max-width: 45rem; 68 | word-break: break-word; 69 | } 70 | 71 | .rich-text__buttons--multiple > * { 72 | flex-grow: 1; 73 | min-width: 22rem; 74 | } 75 | 76 | .rich-text__buttons + .rich-text__buttons { 77 | margin-top: 1rem; 78 | } 79 | 80 | .rich-text__blocks.left .rich-text__buttons { 81 | justify-content: flex-start; 82 | } 83 | 84 | .rich-text__blocks.right .rich-text__buttons { 85 | justify-content: flex-end; 86 | } 87 | -------------------------------------------------------------------------------- /assets/section-featured-product.css: -------------------------------------------------------------------------------- 1 | .featured-product .product__media-list { 2 | width: 100%; 3 | margin: 0; 4 | padding-bottom: 0; 5 | } 6 | 7 | .featured-product .global-media-settings:after { 8 | z-index: 0; 9 | } 10 | 11 | .featured-product .product__modal-opener { 12 | margin-bottom: var(--media-shadow-vertical-offset); 13 | } 14 | 15 | .featured-product .product__media-item { 16 | padding-left: 0; 17 | width: 100%; 18 | } 19 | 20 | .featured-product .product__media-item:not(:first-child) { 21 | display: none; 22 | } 23 | 24 | .background-secondary .featured-product { 25 | padding: 2.5rem; 26 | } 27 | 28 | .featured-product .share-button:nth-last-child(2) { 29 | display: inline-flex; 30 | } 31 | 32 | .share-button + .product__view-details { 33 | display: inline-flex; 34 | float: right; 35 | align-items: center; 36 | } 37 | 38 | .share-button + .product__view-details::after { 39 | content: ""; 40 | clear: both; 41 | display: table; 42 | } 43 | 44 | @media screen and (min-width: 750px) { 45 | .featured-product .product__media-item { 46 | padding-bottom: 0; 47 | } 48 | 49 | .background-secondary .featured-product { 50 | padding: 5rem; 51 | } 52 | } 53 | 54 | @media screen and (min-width: 990px) { 55 | .background-secondary .featured-product:not(.product--no-media) > .product__info-wrapper { 56 | padding: 0 0 0 5rem; 57 | } 58 | 59 | .background-secondary .featured-product:not(.product--no-media).product--right > .product__info-wrapper { 60 | padding: 0 5rem 0 0; 61 | } 62 | 63 | .featured-product:not(.product--no-media) > .product__info-wrapper { 64 | padding: 0 7rem; 65 | } 66 | 67 | .background-secondary .featured-product { 68 | padding: 6rem 7rem; 69 | position: relative; 70 | z-index: 1; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /assets/template-collection.css: -------------------------------------------------------------------------------- 1 | @media screen and (max-width: 749px) { 2 | .collection .grid__item:only-child { 3 | flex: 0 0 100%; 4 | max-width: 100%; 5 | } 6 | } 7 | 8 | @media screen and (max-width: 989px) { 9 | .collection .slider.slider--tablet { 10 | margin-bottom: 1.5rem; 11 | } 12 | } 13 | 14 | .collection .loading-overlay { 15 | top: 0; 16 | right: 0; 17 | bottom: 0; 18 | left: 0; 19 | display: none; 20 | width: 100%; 21 | padding: 0 1.5rem; 22 | opacity: 0.7; 23 | } 24 | 25 | @media screen and (min-width: 750px) { 26 | .collection .loading-overlay { 27 | padding-left: 5rem; 28 | padding-right: 5rem; 29 | } 30 | } 31 | 32 | .collection.loading .loading-overlay { 33 | display: block; 34 | } 35 | 36 | .collection--empty .title-wrapper { 37 | margin-top: 10rem; 38 | margin-bottom: 15rem; 39 | } 40 | 41 | @media screen and (max-width: 989px) { 42 | .collection .slider--tablet.product-grid { 43 | scroll-padding-left: 1.5rem; 44 | } 45 | } 46 | 47 | .collection__description > * { 48 | margin: 0; 49 | } 50 | 51 | .collection__title.title-wrapper { 52 | margin-bottom: 2.5rem; 53 | } 54 | 55 | .collection__title .title:not(:only-child) { 56 | margin-bottom: 1rem; 57 | } 58 | 59 | @media screen and (min-width: 990px) { 60 | .collection__title--desktop-slider .title { 61 | margin-bottom: 2.5rem; 62 | } 63 | 64 | .collection__title.title-wrapper--self-padded-tablet-down { 65 | padding: 0 5rem; 66 | } 67 | 68 | .collection slider-component:not(.page-width-desktop) { 69 | padding: 0; 70 | } 71 | 72 | .collection--full-width slider-component:not(.slider-component-desktop) { 73 | padding: 0 1.5rem; 74 | max-width: none; 75 | } 76 | } 77 | 78 | .collection__view-all a:not(.link) { 79 | margin-top: 1rem; 80 | } 81 | -------------------------------------------------------------------------------- /assets/details-disclosure.js: -------------------------------------------------------------------------------- 1 | class DetailsDisclosure extends HTMLElement { 2 | constructor() { 3 | super(); 4 | this.mainDetailsToggle = this.querySelector('details'); 5 | this.content = this.mainDetailsToggle.querySelector('summary').nextElementSibling; 6 | 7 | this.mainDetailsToggle.addEventListener('focusout', this.onFocusOut.bind(this)); 8 | this.mainDetailsToggle.addEventListener('toggle', this.onToggle.bind(this)); 9 | } 10 | 11 | onFocusOut() { 12 | setTimeout(() => { 13 | if (!this.contains(document.activeElement)) this.close(); 14 | }) 15 | } 16 | 17 | onToggle() { 18 | if (!this.animations) this.animations = this.content.getAnimations(); 19 | 20 | if (this.mainDetailsToggle.hasAttribute('open')) { 21 | this.animations.forEach(animation => animation.play()); 22 | } else { 23 | this.animations.forEach(animation => animation.cancel()); 24 | } 25 | } 26 | 27 | close() { 28 | this.mainDetailsToggle.removeAttribute('open'); 29 | this.mainDetailsToggle.querySelector('summary').setAttribute('aria-expanded', false); 30 | } 31 | } 32 | 33 | customElements.define('details-disclosure', DetailsDisclosure); 34 | 35 | class HeaderMenu extends DetailsDisclosure { 36 | constructor() { 37 | super(); 38 | this.header = document.querySelector('.header-wrapper'); 39 | } 40 | 41 | onToggle() { 42 | if (!this.header) return; 43 | this.header.preventHide = this.mainDetailsToggle.open; 44 | 45 | if (document.documentElement.style.getPropertyValue('--header-bottom-position-desktop') !== '') return; 46 | document.documentElement.style.setProperty('--header-bottom-position-desktop', `${Math.floor(this.header.getBoundingClientRect().bottom)}px`); 47 | } 48 | } 49 | 50 | customElements.define('header-menu', HeaderMenu); 51 | -------------------------------------------------------------------------------- /snippets/cart-notification.liquid: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Renders cart notification 3 | 4 | Accepts: 5 | - color_scheme: {String} sets the color scheme of the notification (optional) 6 | 7 | Usage: 8 | {% render 'cart-notification' %} 9 | {% endcomment %} 10 | 11 | 12 |

13 | 29 |
30 | 31 | {% style %} 32 | .cart-notification { 33 | display: none; 34 | } 35 | {% endstyle %} 36 | -------------------------------------------------------------------------------- /snippets/meta-tags.liquid: -------------------------------------------------------------------------------- 1 | {%- liquid 2 | assign og_title = page_title | default: shop.name 3 | assign og_url = canonical_url | default: request.origin 4 | assign og_type = 'website' 5 | assign og_description = page_description | default: shop.description | default: shop.name 6 | 7 | if request.page_type == 'product' 8 | assign og_type = 'product' 9 | elsif request.page_type == 'article' 10 | assign og_type = 'article' 11 | elsif request.page_type == 'password' 12 | assign og_url = request.origin 13 | endif 14 | %} 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | {%- if page_image -%} 23 | 24 | 25 | 26 | 27 | {%- endif -%} 28 | 29 | {%- if request.page_type == 'product' -%} 30 | 31 | 32 | {%- endif -%} 33 | 34 | {%- if settings.social_twitter_link != blank -%} 35 | 36 | {%- endif -%} 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /assets/section-featured-blog.css: -------------------------------------------------------------------------------- 1 | .blog-placeholder { 2 | margin: 0 1.5rem; 3 | background: rgb(var(--color-background)); 4 | } 5 | 6 | @media screen and (min-width: 750px) { 7 | .blog-placeholder { 8 | text-align: center; 9 | width: 50%; 10 | margin: 0; 11 | } 12 | } 13 | 14 | .blog-placeholder__content { 15 | padding: 3rem; 16 | background: rgba(var(--color-foreground), 0.04); 17 | } 18 | 19 | .blog-placeholder .placeholder { 20 | position: relative; 21 | } 22 | 23 | .blog-placeholder h2 { 24 | margin: 0; 25 | } 26 | 27 | .blog-placeholder .rte-width { 28 | margin-top: 1.2rem; 29 | color: rgba(var(--color-foreground), 0.75); 30 | } 31 | 32 | @media screen and (min-width: 990px) { 33 | .grid--1-col-desktop .article-card .card__content { 34 | text-align: center; 35 | } 36 | } 37 | 38 | .blog__title { 39 | margin: 0; 40 | } 41 | 42 | .blog__posts.articles-wrapper { 43 | margin-bottom: 1rem; 44 | } 45 | 46 | @media screen and (min-width: 990px) { 47 | .blog__posts.articles-wrapper { 48 | margin-bottom: 0; 49 | } 50 | } 51 | 52 | .blog__posts.articles-wrapper .article { 53 | scroll-snap-align: start; 54 | } 55 | 56 | @media screen and (max-width: 749px) { 57 | .blog__post.article { 58 | width: calc(100% - 3rem); 59 | } 60 | } 61 | 62 | .background-secondary .blog-placeholder__content { 63 | background-color: rgb(var(--color-background)); 64 | } 65 | 66 | .blog__posts .card-wrapper { 67 | width: 100%; 68 | } 69 | 70 | .blog__button { 71 | margin-top: 3rem; 72 | } 73 | 74 | @media screen and (min-width: 750px) { 75 | .blog__button { 76 | margin-top: 5rem; 77 | } 78 | } 79 | 80 | /* check for flexbox gap in older Safari versions */ 81 | @supports not (inset: 10px) { 82 | @media screen and (min-width: 750px) { 83 | .blog__posts .article + .article { 84 | margin-left: var(--grid-desktop-horizontal-spacing); 85 | } 86 | } 87 | } 88 | 89 | -------------------------------------------------------------------------------- /snippets/icon-snapchat.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /sections/main-page.liquid: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {%- style -%} 8 | .section-{{ section.id }}-padding { 9 | padding-top: {{ section.settings.padding_top | times: 0.75 | round: 0 }}px; 10 | padding-bottom: {{ section.settings.padding_bottom | times: 0.75 | round: 0 }}px; 11 | } 12 | 13 | @media screen and (min-width: 750px) { 14 | .section-{{ section.id }}-padding { 15 | padding-top: {{ section.settings.padding_top }}px; 16 | padding-bottom: {{ section.settings.padding_bottom }}px; 17 | } 18 | } 19 | {%- endstyle -%} 20 | 21 |
22 |

23 | {{ page.title | escape }} 24 |

25 |
26 | {{ page.content }} 27 |
28 |
29 | 30 | {% schema %} 31 | { 32 | "name": "t:sections.main-page.name", 33 | "tag": "section", 34 | "class": "section", 35 | "settings": [ 36 | { 37 | "type": "header", 38 | "content": "t:sections.all.padding.section_padding_heading" 39 | }, 40 | { 41 | "type": "range", 42 | "id": "padding_top", 43 | "min": 0, 44 | "max": 100, 45 | "step": 4, 46 | "unit": "px", 47 | "label": "t:sections.all.padding.padding_top", 48 | "default": 36 49 | }, 50 | { 51 | "type": "range", 52 | "id": "padding_bottom", 53 | "min": 0, 54 | "max": 100, 55 | "step": 4, 56 | "unit": "px", 57 | "label": "t:sections.all.padding.padding_bottom", 58 | "default": 36 59 | } 60 | ] 61 | } 62 | {% endschema %} 63 | -------------------------------------------------------------------------------- /assets/details-modal.js: -------------------------------------------------------------------------------- 1 | class DetailsModal extends HTMLElement { 2 | constructor() { 3 | super(); 4 | this.detailsContainer = this.querySelector('details'); 5 | this.summaryToggle = this.querySelector('summary'); 6 | 7 | this.detailsContainer.addEventListener( 8 | 'keyup', 9 | (event) => event.code.toUpperCase() === 'ESCAPE' && this.close() 10 | ); 11 | this.summaryToggle.addEventListener( 12 | 'click', 13 | this.onSummaryClick.bind(this) 14 | ); 15 | this.querySelector('button[type="button"]').addEventListener( 16 | 'click', 17 | this.close.bind(this) 18 | ); 19 | 20 | this.summaryToggle.setAttribute('role', 'button'); 21 | } 22 | 23 | isOpen() { 24 | return this.detailsContainer.hasAttribute('open'); 25 | } 26 | 27 | onSummaryClick(event) { 28 | event.preventDefault(); 29 | event.target.closest('details').hasAttribute('open') 30 | ? this.close() 31 | : this.open(event); 32 | } 33 | 34 | onBodyClick(event) { 35 | if (!this.contains(event.target) || event.target.classList.contains('modal-overlay')) this.close(false); 36 | } 37 | 38 | open(event) { 39 | this.onBodyClickEvent = 40 | this.onBodyClickEvent || this.onBodyClick.bind(this); 41 | event.target.closest('details').setAttribute('open', true); 42 | document.body.addEventListener('click', this.onBodyClickEvent); 43 | document.body.classList.add('overflow-hidden'); 44 | 45 | trapFocus( 46 | this.detailsContainer.querySelector('[tabindex="-1"]'), 47 | this.detailsContainer.querySelector('input:not([type="hidden"])') 48 | ); 49 | } 50 | 51 | close(focusToggle = true) { 52 | removeTrapFocus(focusToggle ? this.summaryToggle : null); 53 | this.detailsContainer.removeAttribute('open'); 54 | document.body.removeEventListener('click', this.onBodyClickEvent); 55 | document.body.classList.remove('overflow-hidden'); 56 | } 57 | } 58 | 59 | customElements.define('details-modal', DetailsModal); 60 | -------------------------------------------------------------------------------- /assets/component-price.css: -------------------------------------------------------------------------------- 1 | .price { 2 | font-size: 1.6rem; 3 | letter-spacing: 0.1rem; 4 | line-height: calc(1 + 0.5 / var(--font-body-scale)); 5 | color: rgb(var(--color-foreground)); 6 | } 7 | 8 | .price > * { 9 | display: inline-block; 10 | vertical-align: top; 11 | } 12 | 13 | .price.price--unavailable { 14 | visibility: hidden; 15 | } 16 | 17 | .price--end { 18 | text-align: right; 19 | } 20 | 21 | .price .price-item { 22 | margin: 0 1rem 0 0; 23 | } 24 | 25 | .price__regular .price-item--regular { 26 | margin-right: 0; 27 | } 28 | 29 | .price:not(.price--show-badge) .price-item--last:last-of-type { 30 | margin: 0; 31 | } 32 | 33 | @media screen and (min-width: 750px) { 34 | .price { 35 | margin-bottom: 0; 36 | } 37 | } 38 | 39 | .price--large { 40 | font-size: 1.6rem; 41 | line-height: calc(1 + 0.5 / var(--font-body-scale)); 42 | letter-spacing: 0.13rem; 43 | } 44 | 45 | @media screen and (min-width: 750px) { 46 | .price--large { 47 | font-size: 1.8rem; 48 | } 49 | } 50 | 51 | .price--sold-out .price__availability, 52 | .price__regular { 53 | display: block; 54 | } 55 | 56 | .price__sale, 57 | .price__availability, 58 | .price .price__badge-sale, 59 | .price .price__badge-sold-out, 60 | .price--on-sale .price__regular, 61 | .price--on-sale .price__availability { 62 | display: none; 63 | } 64 | 65 | .price--sold-out .price__badge-sold-out, 66 | .price--on-sale .price__badge-sale { 67 | display: inline-block; 68 | } 69 | 70 | .price--on-sale .price__sale { 71 | display: initial; 72 | flex-direction: row; 73 | flex-wrap: wrap; 74 | } 75 | 76 | .price--center { 77 | display: initial; 78 | justify-content: center; 79 | } 80 | 81 | .price--on-sale .price-item--regular { 82 | text-decoration: line-through; 83 | color: rgba(var(--color-foreground), 0.75); 84 | font-size: 1.3rem; 85 | } 86 | 87 | .unit-price { 88 | display: block; 89 | font-size: 1.1rem; 90 | letter-spacing: 0.04rem; 91 | line-height: calc(1 + 0.2 / var(--font-body-scale)); 92 | margin-top: 0.2rem; 93 | text-transform: uppercase; 94 | color: rgba(var(--color-foreground), 0.7); 95 | } 96 | -------------------------------------------------------------------------------- /release-notes.md: -------------------------------------------------------------------------------- 1 | Dawn 6.0.2 introduces a new cart drawer feature, additional customization options on the rich text section, and various fixes and enhancements. 2 | 3 | ### Added 4 | - Important: We introduced new settings to the header section to control top and bottom section padding. This update may cause a visual change to your header. This can be modified by adjusting the bottom padding value. 5 | - We introduced a new theme setting that allows you to control what happens when an item is added to cart. Choose between a cart drawer, a pop-up notification, or linking directly to the cart page. 6 | - The rich text section is now more flexible. You can now customize the desktop content position, the content alignment, the size and formatting of headings, and the number of blocks added to the section. 7 | 8 | ### Changed 9 | 10 | - Important: We moved “Show vendor” and “Enable cart note” checkboxes from the cart template to the theme settings under the heading “Cart”. This update may cause a visual change to your cart. This can be modified by adjusting the checkboxes in the theme settings. 11 | 12 | ### Fixes and improvements 13 | 14 | - On larger screen sizes, the quick add modal included unnecessary empty space. This is now fixed. 15 | - We fixed an issue where the product media gallery sometimes hid the subsequent media when larger values of horizontal grid space were used. 16 | - The product media gallery included unnecessary empty space between the product media and the gallery controls. This is now fixed. 17 | - We fixed an issue where the collapsible row blocks in the collapsible content section were missing padding. 18 | - We fixed an issue where hiding the background of the content container on the slideshow section would not work if a gradient was set as the background color. 19 | - The recaptcha badge was not visible on the contact form. This is now fixed. 20 | - We fixed an issue where adding a menu block to the footer required a heading to display. 21 | - The experience of navigating paginated pages when using a screen reader or keyboard is improved. 22 | - We added a warning to the password footer link opening in a new tab, improving its accessibility. 23 | -------------------------------------------------------------------------------- /assets/share.js: -------------------------------------------------------------------------------- 1 | if (!customElements.get('share-button')) { 2 | customElements.define('share-button', class ShareButton extends DetailsDisclosure { 3 | constructor() { 4 | super(); 5 | 6 | this.elements = { 7 | shareButton: this.querySelector('button'), 8 | shareSummary: this.querySelector('summary'), 9 | closeButton: this.querySelector('.share-button__close'), 10 | successMessage: this.querySelector('[id^="ShareMessage"]'), 11 | urlInput: this.querySelector('input') 12 | } 13 | this.urlToShare = this.elements.urlInput ? this.elements.urlInput.value : document.location.href; 14 | 15 | if (navigator.share) { 16 | this.mainDetailsToggle.setAttribute('hidden', ''); 17 | this.elements.shareButton.classList.remove('hidden'); 18 | this.elements.shareButton.addEventListener('click', () => { navigator.share({ url: this.urlToShare, title: document.title }) }); 19 | } else { 20 | this.mainDetailsToggle.addEventListener('toggle', this.toggleDetails.bind(this)); 21 | this.mainDetailsToggle.querySelector('.share-button__copy').addEventListener('click', this.copyToClipboard.bind(this)); 22 | this.mainDetailsToggle.querySelector('.share-button__close').addEventListener('click', this.close.bind(this)); 23 | } 24 | } 25 | 26 | toggleDetails() { 27 | if (!this.mainDetailsToggle.open) { 28 | this.elements.successMessage.classList.add('hidden'); 29 | this.elements.successMessage.textContent = ''; 30 | this.elements.closeButton.classList.add('hidden'); 31 | this.elements.shareSummary.focus(); 32 | } 33 | } 34 | 35 | copyToClipboard() { 36 | navigator.clipboard.writeText(this.elements.urlInput.value).then(() => { 37 | this.elements.successMessage.classList.remove('hidden'); 38 | this.elements.successMessage.textContent = window.accessibilityStrings.shareSuccess; 39 | this.elements.closeButton.classList.remove('hidden'); 40 | this.elements.closeButton.focus(); 41 | }); 42 | } 43 | 44 | updateUrl(url) { 45 | this.urlToShare = url; 46 | this.elements.urlInput.value = url; 47 | } 48 | }); 49 | } 50 | -------------------------------------------------------------------------------- /assets/component-mega-menu.css: -------------------------------------------------------------------------------- 1 | .mega-menu { 2 | position: static; 3 | } 4 | 5 | .mega-menu__content { 6 | background-color: rgb(var(--color-background)); 7 | border-left: 0; 8 | border-radius: 0; 9 | border-right: 0; 10 | left: 0; 11 | overflow-y: auto; 12 | padding-bottom: 2.4rem; 13 | padding-top: 2.4rem; 14 | position: absolute; 15 | right: 0; 16 | top: 100%; 17 | z-index: -1; 18 | } 19 | 20 | .shopify-section-header-sticky .mega-menu__content { 21 | max-height: calc(100vh - var(--header-bottom-position-desktop, 20rem) - 4rem); 22 | } 23 | 24 | .header-wrapper--border-bottom .mega-menu__content { 25 | border-top: 0; 26 | } 27 | 28 | .js .mega-menu__content { 29 | opacity: 0; 30 | transform: translateY(-1.5rem); 31 | } 32 | 33 | .mega-menu[open] .mega-menu__content { 34 | opacity: 1; 35 | transform: translateY(0); 36 | } 37 | 38 | .mega-menu__list { 39 | display: grid; 40 | gap: 2.4rem 4rem; 41 | grid-template-columns: repeat(6, minmax(0, 1fr)); 42 | list-style: none; 43 | } 44 | 45 | .mega-menu__link { 46 | color: rgba(var(--color-foreground), 0.75); 47 | display: block; 48 | font-size: 1.3rem; 49 | line-height: calc(1 + 0.3 / var(--font-body-scale)); 50 | padding-bottom: 0.6rem; 51 | padding-top: 0.6rem; 52 | text-decoration: none; 53 | transition: text-decoration var(--duration-short) ease; 54 | word-wrap: break-word; 55 | } 56 | 57 | .mega-menu__link--level-2 { 58 | font-size: 1.4rem; 59 | } 60 | 61 | .mega-menu__link--level-2:not(:only-child) { 62 | margin-bottom: 0.8rem; 63 | } 64 | 65 | .header--top-center .mega-menu__list { 66 | display: flex; 67 | justify-content: center; 68 | flex-wrap: wrap; 69 | column-gap: 0; 70 | } 71 | 72 | .header--top-center .mega-menu__list > li { 73 | width: 16%; 74 | padding-right: 2.4rem; 75 | } 76 | 77 | .mega-menu__link:hover, 78 | .mega-menu__link--active { 79 | color: rgb(var(--color-foreground)); 80 | text-decoration: underline; 81 | } 82 | 83 | .mega-menu__link--active:hover { 84 | text-decoration-thickness: 0.2rem; 85 | } 86 | 87 | .mega-menu .mega-menu__list--condensed { 88 | display: block; 89 | } 90 | 91 | .mega-menu__list--condensed .mega-menu__link { 92 | font-weight: normal; 93 | } 94 | -------------------------------------------------------------------------------- /sections/cart-notification-product.liquid: -------------------------------------------------------------------------------- 1 | {%- if cart != empty -%} 2 | {%- for item in cart.items -%} 3 |
4 | {%- if item.image -%} 5 |
6 | {{ item.image.alt | escape }} 13 |
14 | {%- endif -%} 15 |
16 | {%- if settings.show_vendor -%} 17 |

{{ item.product.vendor }}

18 | {%- endif -%} 19 |

{{ item.product.title | escape }}

20 |
21 | {%- unless item.product.has_only_default_variant -%} 22 | {%- for option in item.options_with_values -%} 23 |
24 |
{{ option.name }}:
25 |
{{ option.value }}
26 |
27 | {%- endfor -%} 28 | {%- endunless -%} 29 | {%- for property in item.properties -%} 30 | {%- assign property_first_char = property.first | slice: 0 -%} 31 | {%- if property.last != blank and property_first_char != '_' -%} 32 |
33 |
{{ property.first }}:
34 |
35 | {%- if property.last contains '/uploads/' -%} 36 | 37 | {{ property.last | split: '/' | last }} 38 | 39 | {%- else -%} 40 | {{ property.last }} 41 | {%- endif -%} 42 |
43 |
44 | {%- endif -%} 45 | {%- endfor -%} 46 |
47 | {%- if item.selling_plan_allocation != nil -%} 48 |

{{ item.selling_plan_allocation.selling_plan.name }}

49 | {%- endif -%} 50 |
51 |
52 | {%- endfor -%} 53 | {%- endif -%} 54 | -------------------------------------------------------------------------------- /assets/component-modal-video.css: -------------------------------------------------------------------------------- 1 | .modal-video { 2 | background: rgba(var(--color-foreground), 0.2); 3 | box-sizing: border-box; 4 | height: 100%; 5 | left: 0; 6 | margin: 0 auto; 7 | opacity: 0; 8 | overflow: auto; 9 | position: fixed; 10 | top: 0; 11 | visibility: hidden; 12 | width: 100%; 13 | z-index: -1; 14 | } 15 | 16 | .modal-video[open] { 17 | opacity: 1; 18 | visibility: visible; 19 | z-index: 101; 20 | } 21 | 22 | .modal-video__content { 23 | background-color: rgb(var(--color-background)); 24 | height: 100%; 25 | margin: 0; 26 | overflow: auto; 27 | padding: 0; 28 | position: absolute; 29 | width: 100%; 30 | } 31 | 32 | .modal-video__toggle { 33 | align-items: center; 34 | background-color: rgb(var(--color-background)); 35 | border-radius: 50%; 36 | border: 0.1rem solid rgba(var(--color-foreground), 0.1); 37 | color: rgba(var(--color-foreground), 0.55); 38 | cursor: pointer; 39 | display: flex; 40 | justify-content: center; 41 | margin: 0 0 0 auto; 42 | padding: 1.2rem; 43 | position: fixed; 44 | right: 0.5rem; 45 | top: 2rem; 46 | width: 4rem; 47 | z-index: 2; 48 | } 49 | 50 | @media screen and (min-width: 750px) { 51 | .modal-video__toggle { 52 | right: 4.8rem; 53 | top: 3.5rem; 54 | } 55 | } 56 | 57 | @media screen and (min-width: 990px) { 58 | .modal-video__toggle { 59 | right: 4.3rem; 60 | top: 3rem; 61 | } 62 | } 63 | 64 | .modal-video__toggle .icon { 65 | height: auto; 66 | margin: 0; 67 | width: 2.2rem; 68 | } 69 | 70 | .modal-video__content-info { 71 | height: calc(100% - 6rem); 72 | margin: 0 auto; 73 | padding-top: 8rem; 74 | width: calc(100% - 1rem); 75 | } 76 | 77 | @media screen and (min-width: 750px) { 78 | .modal-video__content-info { 79 | height: calc(100% - 7.5rem); 80 | padding-top: 9.5rem; 81 | width: calc(100% - 9.6rem); 82 | } 83 | } 84 | 85 | @media screen and (min-width: 990px) { 86 | .modal-video__content-info { 87 | height: calc(100% - 7rem); 88 | padding-top: 9rem; 89 | width: calc(100% - 8.6rem); 90 | } 91 | } 92 | 93 | .modal-video__video, 94 | .modal-video__video iframe { 95 | height: 100%; 96 | width: 100%; 97 | } 98 | 99 | .modal-video__video iframe { 100 | position: static; 101 | border: 0; 102 | } 103 | -------------------------------------------------------------------------------- /assets/section-main-blog.css: -------------------------------------------------------------------------------- 1 | .blog-articles { 2 | display: grid; 3 | grid-gap: 1rem; 4 | column-gap: var(--grid-mobile-horizontal-spacing); 5 | row-gap: var(--grid-mobile-vertical-spacing); 6 | } 7 | 8 | .blog-articles .card-wrapper { 9 | width: 100%; 10 | } 11 | 12 | @media screen and (min-width: 750px) { 13 | .blog-articles { 14 | grid-template-columns: 1fr 1fr; 15 | column-gap: var(--grid-desktop-horizontal-spacing); 16 | row-gap: var(--grid-desktop-vertical-spacing); 17 | } 18 | 19 | .blog-articles--collage > *:nth-child(3n + 1), 20 | .blog-articles--collage > *:nth-child(3n + 2):last-child { 21 | grid-column: span 2; 22 | text-align: center; 23 | } 24 | 25 | .blog-articles--collage > *:nth-child(3n + 1) .card, 26 | .blog-articles--collage > *:nth-child(3n + 2):last-child .card { 27 | text-align: center; 28 | } 29 | 30 | .blog-articles--collage > *:nth-child(3n + 1) .article-card__image--small .ratio::before, 31 | .blog-articles--collage > *:nth-child(3n + 2):last-child .article-card__image--small .ratio::before { 32 | padding-bottom: 22rem; 33 | } 34 | 35 | .blog-articles--collage > *:nth-child(3n + 1) .article-card__image--medium .ratio::before, 36 | .blog-articles--collage > *:nth-child(3n + 2):last-child .article-card__image--medium .ratio::before { 37 | padding-bottom: 44rem; 38 | } 39 | 40 | .blog-articles--collage > *:nth-child(3n + 1) .article-card__image--large .ratio::before, 41 | .blog-articles--collage > *:nth-child(3n + 2):last-child .article-card__image--large .ratio::before { 42 | padding-bottom: 66rem; 43 | } 44 | } 45 | 46 | @media screen and (min-width: 990px) { 47 | .blog-articles--collage > *:nth-child(3n + 1) .article-card__image--small .ratio .ratio::before, 48 | .blog-articles--collage > *:nth-child(3n + 2):last-child .article-card__image--small .ratio .ratio::before { 49 | padding-bottom: 27.5rem; 50 | } 51 | 52 | .blog-articles--collage > *:nth-child(3n + 1) .article-card__image--medium .ratio::before, 53 | .blog-articles--collage > *:nth-child(3n + 2):last-child .article-card__image--medium .ratio::before { 54 | padding-bottom: 55rem; 55 | } 56 | 57 | .blog-articles--collage > *:nth-child(3n + 1) .article-card__image--large .ratio::before, 58 | .blog-articles--collage > *:nth-child(3n + 2):last-child .article-card__image--large .ratio::before { 59 | padding-bottom: 82.5rem; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /snippets/pagination.liquid: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Renders a set of links for paginated results. Must be used within paginate tags. 3 | 4 | Usage: 5 | {% paginate results by 2 %} 6 | {% render 'pagination', paginate: paginate, anchor: '#yourID' %} 7 | {% endpaginate %} 8 | 9 | Accepts: 10 | - paginate: {Object} 11 | - anchor: {String} (optional) This can be added so that on page reload it takes you to wherever you've placed your anchor tag. 12 | {% endcomment %} 13 | 14 | 15 | 16 | 17 | {%- if paginate.parts.size > 0 -%} 18 |
19 | 52 |
53 | {%- endif -%} 54 | -------------------------------------------------------------------------------- /assets/cart-notification.js: -------------------------------------------------------------------------------- 1 | class CartNotification extends HTMLElement { 2 | constructor() { 3 | super(); 4 | 5 | this.notification = document.getElementById('cart-notification'); 6 | this.header = document.querySelector('sticky-header'); 7 | this.onBodyClick = this.handleBodyClick.bind(this); 8 | 9 | this.notification.addEventListener('keyup', (evt) => evt.code === 'Escape' && this.close()); 10 | this.querySelectorAll('button[type="button"]').forEach((closeButton) => 11 | closeButton.addEventListener('click', this.close.bind(this)) 12 | ); 13 | } 14 | 15 | open() { 16 | this.notification.classList.add('animate', 'active'); 17 | 18 | this.notification.addEventListener('transitionend', () => { 19 | this.notification.focus(); 20 | trapFocus(this.notification); 21 | }, { once: true }); 22 | 23 | document.body.addEventListener('click', this.onBodyClick); 24 | } 25 | 26 | close() { 27 | this.notification.classList.remove('active'); 28 | 29 | document.body.removeEventListener('click', this.onBodyClick); 30 | 31 | removeTrapFocus(this.activeElement); 32 | } 33 | 34 | renderContents(parsedState) { 35 | this.cartItemKey = parsedState.key; 36 | this.getSectionsToRender().forEach((section => { 37 | document.getElementById(section.id).innerHTML = 38 | this.getSectionInnerHTML(parsedState.sections[section.id], section.selector); 39 | })); 40 | 41 | if (this.header) this.header.reveal(); 42 | this.open(); 43 | } 44 | 45 | getSectionsToRender() { 46 | return [ 47 | { 48 | id: 'cart-notification-product', 49 | selector: `[id="cart-notification-product-${this.cartItemKey}"]`, 50 | }, 51 | { 52 | id: 'cart-notification-button' 53 | }, 54 | { 55 | id: 'cart-icon-bubble' 56 | } 57 | ]; 58 | } 59 | 60 | getSectionInnerHTML(html, selector = '.shopify-section') { 61 | return new DOMParser() 62 | .parseFromString(html, 'text/html') 63 | .querySelector(selector).innerHTML; 64 | } 65 | 66 | handleBodyClick(evt) { 67 | const target = evt.target; 68 | if (target !== this.notification && !target.closest('cart-notification')) { 69 | const disclosure = target.closest('details-disclosure, header-menu'); 70 | this.activeElement = disclosure ? disclosure.querySelector('summary') : null; 71 | this.close(); 72 | } 73 | } 74 | 75 | setActiveElement(element) { 76 | this.activeElement = element; 77 | } 78 | } 79 | 80 | customElements.define('cart-notification', CartNotification); 81 | -------------------------------------------------------------------------------- /assets/transitions.js: -------------------------------------------------------------------------------- 1 | !function(){ 2 | const activeTrans = document.querySelector('body').dataset.trans; 3 | barba.init({ 4 | sync: true, 5 | debug: true, 6 | // prevent: ({ el }) => el.classList && el.classList.contains('full-unstyled-link'), 7 | views: [{ 8 | namespace: 'home', 9 | beforeEnter(data) { 10 | 11 | }, 12 | enter(data) { 13 | 14 | }, 15 | once(data) { 16 | 17 | }, 18 | afterLeave(data) { 19 | } 20 | }, 21 | { 22 | namespace: 'pdp', 23 | async beforeEnter(data){ 24 | console.log('pdp'); 25 | } 26 | } 27 | ], 28 | transitions: [{ 29 | async leave() { 30 | let done = this.async(); 31 | pageTrans(); 32 | pageOut(); 33 | await delay(500); 34 | done(); 35 | }, 36 | async enter() { 37 | pageIn(); 38 | }, 39 | async once() { 40 | pageIn(); 41 | } 42 | }] 43 | }) 44 | 45 | barba.hooks.enter(function () { 46 | window.scrollTo(0, 0); 47 | }); 48 | barba.hooks.leave(function () { 49 | window.scrollTo(0, 0); 50 | }); 51 | if (window.document.documentMode){ 52 | barba.destroy(); 53 | } 54 | }(); 55 | 56 | 57 | const delay = (t) => { 58 | t = t || 1000; 59 | return new Promise(function(done){ 60 | setTimeout(function() { 61 | done(); 62 | }, t); 63 | }); 64 | } 65 | 66 | const pageIn = (e) => { 67 | const tl = new TimelineMax({ 68 | ease: Expo.easeInOut 69 | }); 70 | tl.set(".content", { 71 | opacity: 1, 72 | }) 73 | .to(".content", .5, { 74 | opacity: 1, 75 | }, .1) 76 | } 77 | 78 | const pageTrans = (e) => { 79 | const tl = new TimelineMax(); 80 | tl.set('.trans-pane', { 81 | x: '-100%', 82 | display: 'block' 83 | }) 84 | .staggerTo('.trans-pane', .3, { 85 | x: 0, 86 | }, .1) 87 | .staggerTo('.trans-pane', .3, { 88 | x: '100%', 89 | }, .1) 90 | .set('.trans-pane', { display: 'none' }) 91 | } 92 | 93 | const pageOut = (e) => { 94 | const tl = new TimelineMax({ 95 | ease: Expo.easeInOut 96 | }); 97 | tl.to(".content", .5, { 98 | opacity: 0 99 | }) 100 | } -------------------------------------------------------------------------------- /sections/custom-liquid.liquid: -------------------------------------------------------------------------------- 1 | {%- style -%} 2 | .section-{{ section.id }}-padding { 3 | padding-top: calc({{ section.settings.padding_top }}px * 0.75); 4 | padding-bottom: calc({{ section.settings.padding_bottom }}px * 0.75); 5 | } 6 | 7 | @media screen and (min-width: 750px) { 8 | .section-{{ section.id }}-padding { 9 | padding-top: {{ section.settings.padding_top }}px; 10 | padding-bottom: {{ section.settings.padding_bottom }}px; 11 | } 12 | } 13 | {%- endstyle -%} 14 |
15 |
16 | {{ section.settings.custom_liquid }} 17 |
18 |
19 | 20 | {% schema %} 21 | { 22 | "name": "t:sections.custom-liquid.name", 23 | "tag": "section", 24 | "class": "section", 25 | "settings": [ 26 | { 27 | "type": "liquid", 28 | "id": "custom_liquid", 29 | "label": "t:sections.custom-liquid.settings.custom_liquid.label", 30 | "info": "t:sections.custom-liquid.settings.custom_liquid.info" 31 | }, 32 | { 33 | "type": "select", 34 | "id": "color_scheme", 35 | "options": [ 36 | { 37 | "value": "accent-1", 38 | "label": "t:sections.all.colors.accent_1.label" 39 | }, 40 | { 41 | "value": "accent-2", 42 | "label": "t:sections.all.colors.accent_2.label" 43 | }, 44 | { 45 | "value": "background-1", 46 | "label": "t:sections.all.colors.background_1.label" 47 | }, 48 | { 49 | "value": "background-2", 50 | "label": "t:sections.all.colors.background_2.label" 51 | }, 52 | { 53 | "value": "inverse", 54 | "label": "t:sections.all.colors.inverse.label" 55 | } 56 | ], 57 | "default": "background-1", 58 | "label": "t:sections.all.colors.label" 59 | }, 60 | { 61 | "type": "header", 62 | "content": "t:sections.all.padding.section_padding_heading" 63 | }, 64 | { 65 | "type": "range", 66 | "id": "padding_top", 67 | "min": 0, 68 | "max": 100, 69 | "step": 4, 70 | "unit": "px", 71 | "label": "t:sections.all.padding.padding_top", 72 | "default": 40 73 | }, 74 | { 75 | "type": "range", 76 | "id": "padding_bottom", 77 | "min": 0, 78 | "max": 100, 79 | "step": 4, 80 | "unit": "px", 81 | "label": "t:sections.all.padding.padding_bottom", 82 | "default": 52 83 | } 84 | ], 85 | "presets": [ 86 | { 87 | "name": "t:sections.custom-liquid.presets.name" 88 | } 89 | ] 90 | } 91 | {% endschema %} 92 | -------------------------------------------------------------------------------- /assets/component-deferred-media.css: -------------------------------------------------------------------------------- 1 | .deferred-media__poster { 2 | background-color: transparent; 3 | border: none; 4 | cursor: pointer; 5 | margin: 0; 6 | padding: 0; 7 | height: 100%; 8 | width: 100%; 9 | overflow: hidden; 10 | } 11 | 12 | .media > .deferred-media__poster { 13 | display: flex; 14 | align-items: center; 15 | justify-content: center; 16 | } 17 | 18 | .deferred-media__poster img { 19 | width: auto; 20 | max-width: 100%; 21 | height: 100%; 22 | } 23 | 24 | .deferred-media { 25 | overflow: hidden; 26 | } 27 | 28 | .deferred-media:not([loaded]) template { 29 | z-index: -1; 30 | } 31 | 32 | .deferred-media[loaded] > .deferred-media__poster { 33 | display: none; 34 | } 35 | 36 | .deferred-media__poster:focus-visible { 37 | outline: none; 38 | box-shadow: 0 0 0 var(--media-border-width) rgba(var(--color-foreground), var(--media-border-opacity)), 0 0 0 calc(var(--media-border-width) + 0.3rem) rgb(var(--color-background)),0 0 0 calc(var(--media-border-width) + 0.5rem) rgba(var(--color-foreground),.5); 39 | border-radius: calc(var(--media-radius) - var(--media-border-width)); 40 | } 41 | 42 | .deferred-media__poster:focus { 43 | outline: none; 44 | box-shadow: 0 0 0 var(--media-border-width) rgba(var(--color-foreground), var(--media-border-opacity)), 0 0 0 calc(var(--media-border-width) + 0.3rem) rgb(var(--color-background)),0 0 0 calc(var(--media-border-width) + 0.5rem) rgba(var(--color-foreground),.5); 45 | border-radius: calc(var(--media-radius) - var(--media-border-width)); 46 | } 47 | 48 | /* outline styling for Windows High Contrast Mode */ 49 | @media (forced-colors: active) { 50 | .deferred-media__poster:focus { 51 | outline: transparent solid 1px; 52 | } 53 | } 54 | .deferred-media__poster:focus:not(:focus-visible) { 55 | outline: 0; 56 | box-shadow: none; 57 | } 58 | 59 | .deferred-media__poster-button { 60 | background-color: rgb(var(--color-background)); 61 | border: 0.1rem solid rgba(var(--color-foreground), 0.1); 62 | border-radius: 50%; 63 | color: rgb(var(--color-foreground)); 64 | display: flex; 65 | align-items: center; 66 | justify-content: center; 67 | height: 6.2rem; 68 | width: 6.2rem; 69 | position: absolute; 70 | left: 50%; 71 | top: 50%; 72 | transform: translate(-50%, -50%) scale(1); 73 | transition: transform var(--duration-short) ease, color var(--duration-short) ease; 74 | z-index: 1; 75 | } 76 | 77 | .deferred-media__poster-button:hover { 78 | transform: translate(-50%, -50%) scale(1.1); 79 | } 80 | 81 | .deferred-media__poster-button .icon { 82 | width: 2rem; 83 | height: 2rem; 84 | } 85 | 86 | .deferred-media__poster-button .icon-play { 87 | margin-left: 0.2rem; 88 | } 89 | 90 | -------------------------------------------------------------------------------- /assets/component-collection-hero.css: -------------------------------------------------------------------------------- 1 | .collection-hero__inner { 2 | display: flex; 3 | flex-direction: column; 4 | } 5 | 6 | .collection-hero--with-image .collection-hero__inner { 7 | margin-bottom: 0; 8 | padding-bottom: 2rem; 9 | } 10 | 11 | @media screen and (min-width: 750px) { 12 | .collection-hero.collection-hero--with-image { 13 | padding: calc(4rem + var(--page-width-margin)) 0 14 | calc(4rem + var(--page-width-margin)); 15 | overflow: hidden; 16 | } 17 | 18 | .collection-hero--with-image .collection-hero__inner { 19 | padding-bottom: 0; 20 | } 21 | } 22 | 23 | .collection-hero__text-wrapper { 24 | flex-basis: 100%; 25 | } 26 | 27 | @media screen and (min-width: 750px) { 28 | .collection-hero { 29 | padding: 0; 30 | } 31 | 32 | .collection-hero__inner { 33 | align-items: center; 34 | flex-direction: row; 35 | padding-bottom: 0; 36 | } 37 | } 38 | 39 | .collection-hero__title { 40 | margin: 2.5rem 0; 41 | } 42 | 43 | .collection-hero__title + .collection-hero__description { 44 | margin-top: 1.5rem; 45 | margin-bottom: 1.5rem; 46 | font-size: 1.6rem; 47 | line-height: calc(1 + 0.5 / var(--font-body-scale)); 48 | } 49 | 50 | @media screen and (min-width: 750px) { 51 | .collection-hero__title + .collection-hero__description { 52 | font-size: 1.8rem; 53 | margin-top: 2rem; 54 | margin-bottom: 2rem; 55 | } 56 | 57 | .collection-hero__description { 58 | max-width: 66.67%; 59 | } 60 | 61 | .collection-hero--with-image .collection-hero__description { 62 | max-width: 100%; 63 | } 64 | } 65 | 66 | .collection-hero--with-image .collection-hero__title { 67 | margin: 0; 68 | } 69 | 70 | .collection-hero--with-image .collection-hero__text-wrapper { 71 | padding: 5rem 0 4rem; 72 | } 73 | 74 | .collection-hero__image-container { 75 | border: var(--media-border-width) solid rgba(var(--color-foreground), var(--media-border-opacity)); 76 | border-radius: var(--media-radius); 77 | box-shadow: var(--media-shadow-horizontal-offset) 78 | var(--media-shadow-vertical-offset) 79 | var(--media-shadow-blur-radius) 80 | rgba(var(--color-shadow), var(--media-shadow-opacity)); 81 | } 82 | 83 | @media screen and (max-width: 749px) { 84 | .collection-hero__image-container { 85 | height: 20rem; 86 | } 87 | } 88 | 89 | @media screen and (min-width: 750px) { 90 | .collection-hero--with-image .collection-hero__text-wrapper { 91 | padding: 4rem 2rem 4rem 0; 92 | flex-basis: 50%; 93 | } 94 | 95 | .collection-hero__image-container { 96 | align-self: stretch; 97 | flex: 1 0 50%; 98 | margin-left: 3rem; 99 | min-height: 20rem; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /assets/component-cart-notification.css: -------------------------------------------------------------------------------- 1 | .cart-notification-wrapper { 2 | position: relative; 3 | } 4 | 5 | .cart-notification-wrapper .cart-notification { 6 | display: block; 7 | } 8 | 9 | .cart-notification { 10 | border-bottom-right-radius: var(--popup-corner-radius); 11 | border-bottom-left-radius: var(--popup-corner-radius); 12 | border-color: rgba(var(--color-foreground), var(--popup-border-opacity)); 13 | border-style: solid; 14 | border-width: 0 0 var(--popup-border-width); 15 | padding: 2.5rem 3.5rem; 16 | position: absolute; 17 | right: 0; 18 | transform: translateY(-100%); 19 | visibility: hidden; 20 | width: 100%; 21 | z-index: -1; 22 | filter: drop-shadow( 23 | var(--popup-shadow-horizontal-offset) 24 | var(--popup-shadow-vertical-offset) 25 | var(--popup-shadow-blur-radius) 26 | rgba(var(--color-shadow), var(--popup-shadow-opacity)) 27 | ); 28 | } 29 | 30 | @media screen and (min-width: 750px) { 31 | .header-wrapper:not(.header-wrapper--border-bottom) + cart-notification .cart-notification { 32 | border-top-width: var(--popup-border-width); 33 | } 34 | 35 | .cart-notification { 36 | border-width: 0 var(--popup-border-width) var(--popup-border-width); 37 | max-width: 36.8rem; 38 | right: 4rem; 39 | } 40 | } 41 | 42 | .cart-notification.animate { 43 | transition: transform var(--duration-short) ease, 44 | visibility 0s var(--duration-short) ease; 45 | } 46 | 47 | .cart-notification.active { 48 | transform: translateY(0); 49 | transition: transform var(--duration-default) ease, visibility 0s; 50 | visibility: visible; 51 | } 52 | 53 | .cart-notification__header { 54 | align-items: flex-start; 55 | display: flex; 56 | } 57 | 58 | .cart-notification__heading { 59 | align-items: center; 60 | display: flex; 61 | flex-grow: 1; 62 | margin-bottom: 0; 63 | margin-top: 0; 64 | } 65 | 66 | .cart-notification__heading .icon-checkmark { 67 | color: rgb(var(--color-foreground)); 68 | margin-right: 1rem; 69 | width: 1.3rem; 70 | } 71 | 72 | .cart-notification__close { 73 | margin-top: -2rem; 74 | margin-right: -3rem; 75 | } 76 | 77 | .cart-notification__links { 78 | text-align: center; 79 | } 80 | 81 | .cart-notification__links > * { 82 | margin-top: 1rem; 83 | } 84 | 85 | .cart-notification-product { 86 | align-items: flex-start; 87 | display: flex; 88 | padding-bottom: 3rem; 89 | padding-top: 2rem; 90 | } 91 | 92 | .cart-notification-product dl { 93 | margin-bottom: 0; 94 | margin-top: 0; 95 | } 96 | 97 | .cart-notification-product__image { 98 | display: inline-flex; 99 | margin-right: 1.5rem; 100 | margin-top: 0.5rem; 101 | } 102 | 103 | .cart-notification-product__image:after { 104 | content: none; 105 | } 106 | 107 | .cart-notification-product__name { 108 | margin-bottom: 0.5rem; 109 | margin-top: 0; 110 | } 111 | -------------------------------------------------------------------------------- /assets/section-email-signup-banner.css: -------------------------------------------------------------------------------- 1 | .email-signup-banner .newsletter-form, 2 | .email-signup-banner .newsletter-form__field-wrapper { 3 | display: inline-block; 4 | } 5 | 6 | @media only screen and (min-width: 750px) { 7 | .email-signup-banner:not(.banner--desktop-transparent) .email-signup-banner__box { 8 | width: 100%; 9 | } 10 | } 11 | 12 | .email-signup-banner__box .email-signup-banner__heading { 13 | margin-bottom: 0; 14 | } 15 | 16 | .email-signup-banner__box > * + .newsletter__subheading { 17 | margin-top: 2rem; 18 | } 19 | 20 | .email-signup-banner__box .newsletter__subheading p { 21 | margin: 0; 22 | } 23 | 24 | .email-signup-banner-background { 25 | width: 100%; 26 | height: 100%; 27 | position: relative; 28 | left: 50%; 29 | transform: translateX(-50%); 30 | } 31 | 32 | @media screen and (max-width: 749px) { 33 | .email-signup-banner:not(.banner--mobile-bottom) .banner__box:not(.email-signup-banner__box--no-image) { 34 | background-color: transparent; 35 | --color-foreground: 255, 255, 255; 36 | --color-button: 255, 255, 255; 37 | --color-button-text: 0, 0, 0; 38 | } 39 | } 40 | 41 | @media only screen and (min-width: 750px) { 42 | .banner--desktop-transparent .email-signup-banner__box--no-image * { 43 | color: rgb(var(--color-base-text)); 44 | } 45 | 46 | .banner--desktop-transparent .email-signup-banner__box .field__input { 47 | background-color: transparent; 48 | } 49 | 50 | .banner--desktop-transparent .email-signup-banner__box--no-image .field__input { 51 | box-shadow: 0 0 0 0.1rem rgba(var(--color-base-text), 0.55); 52 | } 53 | 54 | .banner--desktop-transparent .email-signup-banner__box--no-image .field__input:focus { 55 | box-shadow: 0 0 0 0.2rem rgba(var(--color-base-text), 0.75); 56 | } 57 | 58 | .banner--desktop-transparent .email-signup-banner__box--no-image .field__button:focus-visible { 59 | outline: 0.2rem solid rgba(var(--color-base-text), 0.5); 60 | box-shadow: 0 0 0 0.3rem rgb(var(--color-background)), 61 | 0 0 0.5rem 0.4rem rgba(var(--color-base-text), 0.3); 62 | } 63 | } 64 | 65 | @media only screen and (min-width: 750px) { 66 | .email-signup-banner-background-mobile { 67 | display: none; 68 | } 69 | } 70 | 71 | @media only screen and (max-width: 749px) { 72 | .email-signup-banner-background:not(.email-signup-banner-background-mobile) { 73 | display: none; 74 | } 75 | } 76 | 77 | .email-signup-banner .banner__media { 78 | overflow: hidden; 79 | } 80 | 81 | @media screen and (max-width: 749px) { 82 | .banner--mobile-content-align-left .newsletter-form__message { 83 | justify-content: flex-start; 84 | } 85 | 86 | .banner--mobile-content-align-right .newsletter-form__message { 87 | justify-content: right; 88 | } 89 | } 90 | 91 | @media screen and (min-width: 750px) { 92 | .banner--content-align-center .newsletter-form__message { 93 | justify-content: center; 94 | } 95 | 96 | .banner--content-align-right .newsletter-form__message { 97 | justify-content: right; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /assets/component-article-card.css: -------------------------------------------------------------------------------- 1 | @media screen and (max-width: 749px) { 2 | .articles-wrapper .article { 3 | width: 100%; 4 | } 5 | } 6 | 7 | .article { 8 | display: flex; 9 | align-items: center; 10 | } 11 | 12 | .article.grid__item { 13 | padding: 0; 14 | } 15 | 16 | .grid--peek .article-card { 17 | box-sizing: border-box; 18 | } 19 | 20 | .article-card__image-wrapper > a { 21 | display: block; 22 | } 23 | 24 | .article-card__title { 25 | text-decoration: none; 26 | word-break: break-word; 27 | } 28 | 29 | .article-card__title a:after { 30 | bottom: 0; 31 | content: ""; 32 | height: 100%; 33 | left: 0; 34 | position: absolute; 35 | right: 0; 36 | top: 0; 37 | width: 100%; 38 | z-index: 1; 39 | } 40 | 41 | .article-card__link.link { 42 | padding: 0; 43 | } 44 | 45 | .article-card__link { 46 | text-underline-offset: 0.3rem; 47 | } 48 | 49 | .article-card .card__heading { 50 | margin-bottom: 0.6rem; 51 | } 52 | 53 | .blog-articles .article-card .card__information, 54 | .blog__posts .article-card .card__information { 55 | padding-left: 2rem; 56 | padding-right: 2rem; 57 | } 58 | 59 | .article-card__info { 60 | padding-top: 0.4rem; 61 | } 62 | 63 | .article-card__footer { 64 | letter-spacing: 0.1rem; 65 | font-size: 1.4rem; 66 | } 67 | 68 | .article-card__footer:not(:last-child) { 69 | margin-bottom: 1rem; 70 | } 71 | 72 | .article-card__footer:last-child { 73 | margin-top: auto; 74 | } 75 | 76 | .article-card__excerpt { 77 | width: 100%; 78 | margin-top: 1.2rem; 79 | } 80 | 81 | .article-card__link:not(:only-child) { 82 | margin-right: 3rem; 83 | } 84 | 85 | @media screen and (min-width: 990px) { 86 | .article-card__link:not(:only-child) { 87 | margin-right: 4rem; 88 | } 89 | } 90 | 91 | .article-card__image--small .ratio::before { 92 | padding-bottom: 11rem; 93 | } 94 | 95 | .article-card__image--medium .ratio::before { 96 | padding-bottom: 22rem; 97 | } 98 | 99 | .article-card__image--large .ratio::before { 100 | padding-bottom: 33rem; 101 | } 102 | 103 | @media screen and (min-width: 750px) { 104 | .article-card__image--small .ratio::before { 105 | padding-bottom: 14.3rem; 106 | } 107 | 108 | .article-card__image--medium .ratio::before { 109 | padding-bottom: 21.9rem; 110 | } 111 | 112 | .article-card__image--large .ratio::before { 113 | padding-bottom: 27.5rem; 114 | } 115 | } 116 | 117 | @media screen and (min-width: 990px) { 118 | .article-card__image--small .ratio::before { 119 | padding-bottom: 17.7rem; 120 | } 121 | 122 | .article-card__image--medium .ratio::before { 123 | padding-bottom: 30.7rem; 124 | } 125 | 126 | .article-card__image--large .ratio::before { 127 | padding-bottom: 40.7rem; 128 | } 129 | } 130 | 131 | /* check for flexbox gap in older Safari versions */ 132 | @supports not (inset: 10px) { 133 | .articles-wrapper.grid { 134 | margin: 0 0 5rem 0; 135 | } 136 | 137 | @media screen and (min-width: 750px) { 138 | .articles-wrapper.grid { 139 | margin-bottom: 7rem; 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /assets/collapsible-content.css: -------------------------------------------------------------------------------- 1 | .collapsible-content { 2 | position: relative; 3 | z-index: 0; 4 | } 5 | 6 | .collapsible-section-layout { 7 | padding-bottom: 5rem; 8 | padding-top: 5rem; 9 | } 10 | 11 | @media screen and (min-width: 750px) { 12 | .collapsible-section-layout { 13 | padding-bottom: 7rem; 14 | padding-top: 7rem; 15 | } 16 | } 17 | 18 | .collapsible-content__media--small { 19 | height: 19.4rem; 20 | } 21 | 22 | .collapsible-content__media--large { 23 | height: 43.5rem; 24 | } 25 | 26 | @media screen and (min-width: 750px) { 27 | .collapsible-content__media--small { 28 | height: 31.4rem; 29 | } 30 | 31 | .collapsible-content__media--large { 32 | height: 69.5rem; 33 | } 34 | } 35 | 36 | @media screen and (min-width: 750px) { 37 | .collapsible-content__grid--reverse { 38 | flex-direction: row-reverse; 39 | } 40 | } 41 | 42 | .collapsible-content-wrapper-narrow { 43 | margin: 0 auto; 44 | padding-right: 1.5rem; 45 | padding-left: 1.5rem; 46 | max-width: 73.4rem; 47 | } 48 | 49 | .collapsible-content__header { 50 | word-break: break-word; 51 | } 52 | 53 | .collapsible-content__heading { 54 | margin-bottom: 2rem; 55 | margin-top: 0; 56 | } 57 | 58 | @media screen and (min-width: 750px) { 59 | .collapsible-content__heading { 60 | margin-bottom: 3rem; 61 | } 62 | } 63 | 64 | .collapsible-none-layout .accordion + .accordion { 65 | border-top: 0; 66 | } 67 | 68 | .collapsible-row-layout .accordion:not(:first-child):not(.color-background-1) { 69 | margin-top: 1rem; 70 | } 71 | 72 | .caption-with-letter-spacing + h2 { 73 | margin-top: 1rem; 74 | } 75 | 76 | @media screen and (min-width: 750px) { 77 | .collapsible-content .accordion { 78 | margin-top: 0; 79 | } 80 | } 81 | 82 | .collapsible-row-layout .accordion { 83 | border: var(--text-boxes-border-width) solid rgba(var(--color-foreground),var(--text-boxes-border-opacity)); 84 | margin-bottom: 1.5rem; 85 | } 86 | 87 | .collapsible-row-layout .accordion summary, 88 | .collapsible-row-layout .accordion .accordion__content { 89 | padding: 1.5rem; 90 | } 91 | 92 | .collapsible-row-layout .accordion .accordion__content { 93 | padding-top: 0; 94 | } 95 | 96 | .collapsible-content summary:hover { 97 | background: rgba(var(--color-foreground), 0.04); 98 | } 99 | 100 | .collapsible-content summary:hover .accordion__title { 101 | text-decoration: underline; 102 | text-underline-offset: 0.3rem; 103 | } 104 | 105 | /* check for flexbox gap in older Safari versions */ 106 | @supports not (inset: 10px) { 107 | @media screen and (min-width: 750px) { 108 | .collapsible-content__grid:not(.collapsible-content__grid--reverse) .grid__item:last-child, 109 | .collapsible-content__grid--reverse .collapsible-content__grid-item { 110 | padding-left: 5rem; 111 | padding-right: 0; 112 | } 113 | } 114 | 115 | @media screen and (min-width: 990px) { 116 | .collapsible-content__grid:not(.collapsible-content__grid--reverse) .grid__item:last-child, 117 | .collapsible-content__grid--reverse .collapsible-content__grid-item { 118 | padding-left: 7rem; 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /snippets/email-signup-banner-background-mobile.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/customer.js: -------------------------------------------------------------------------------- 1 | const selectors = { 2 | customerAddresses: '[data-customer-addresses]', 3 | addressCountrySelect: '[data-address-country-select]', 4 | addressContainer: '[data-address]', 5 | toggleAddressButton: 'button[aria-expanded]', 6 | cancelAddressButton: 'button[type="reset"]', 7 | deleteAddressButton: 'button[data-confirm-message]' 8 | }; 9 | 10 | const attributes = { 11 | expanded: 'aria-expanded', 12 | confirmMessage: 'data-confirm-message' 13 | }; 14 | 15 | class CustomerAddresses { 16 | constructor() { 17 | this.elements = this._getElements(); 18 | if (Object.keys(this.elements).length === 0) return; 19 | this._setupCountries(); 20 | this._setupEventListeners(); 21 | } 22 | 23 | _getElements() { 24 | const container = document.querySelector(selectors.customerAddresses); 25 | return container ? { 26 | container, 27 | addressContainer: container.querySelector(selectors.addressContainer), 28 | toggleButtons: document.querySelectorAll(selectors.toggleAddressButton), 29 | cancelButtons: container.querySelectorAll(selectors.cancelAddressButton), 30 | deleteButtons: container.querySelectorAll(selectors.deleteAddressButton), 31 | countrySelects: container.querySelectorAll(selectors.addressCountrySelect) 32 | } : {}; 33 | } 34 | 35 | _setupCountries() { 36 | if (Shopify && Shopify.CountryProvinceSelector) { 37 | // eslint-disable-next-line no-new 38 | new Shopify.CountryProvinceSelector('AddressCountryNew', 'AddressProvinceNew', { 39 | hideElement: 'AddressProvinceContainerNew' 40 | }); 41 | this.elements.countrySelects.forEach((select) => { 42 | const formId = select.dataset.formId; 43 | // eslint-disable-next-line no-new 44 | new Shopify.CountryProvinceSelector(`AddressCountry_${formId}`, `AddressProvince_${formId}`, { 45 | hideElement: `AddressProvinceContainer_${formId}` 46 | }); 47 | }); 48 | } 49 | } 50 | 51 | _setupEventListeners() { 52 | this.elements.toggleButtons.forEach((element) => { 53 | element.addEventListener('click', this._handleAddEditButtonClick); 54 | }); 55 | this.elements.cancelButtons.forEach((element) => { 56 | element.addEventListener('click', this._handleCancelButtonClick); 57 | }); 58 | this.elements.deleteButtons.forEach((element) => { 59 | element.addEventListener('click', this._handleDeleteButtonClick); 60 | }); 61 | } 62 | 63 | _toggleExpanded(target) { 64 | target.setAttribute( 65 | attributes.expanded, 66 | (target.getAttribute(attributes.expanded) === 'false').toString() 67 | ); 68 | } 69 | 70 | _handleAddEditButtonClick = ({ currentTarget }) => { 71 | this._toggleExpanded(currentTarget); 72 | } 73 | 74 | _handleCancelButtonClick = ({ currentTarget }) => { 75 | this._toggleExpanded( 76 | currentTarget 77 | .closest(selectors.addressContainer) 78 | .querySelector(`[${attributes.expanded}]`) 79 | ) 80 | } 81 | 82 | _handleDeleteButtonClick = ({ currentTarget }) => { 83 | // eslint-disable-next-line no-alert 84 | if (confirm(currentTarget.getAttribute(attributes.confirmMessage))) { 85 | Shopify.postLink(currentTarget.dataset.target, { 86 | parameters: { _method: 'delete' }, 87 | }); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /sections/predictive-search.liquid: -------------------------------------------------------------------------------- 1 | {% comment %}theme-check-disable ImgLazyLoading{% endcomment %} 2 | {%- if predictive_search.performed -%} 3 |
4 | {%- if predictive_search.resources.products.size > 0 -%} 5 |

6 | {{ 'templates.search.products' | t }} 7 | 8 | 11 |

12 | {%- endif -%} 13 | 44 | 45 | 50 |
51 | 52 | 59 | {%- endif -%} 60 | -------------------------------------------------------------------------------- /assets/product-form.js: -------------------------------------------------------------------------------- 1 | if (!customElements.get('product-form')) { 2 | customElements.define('product-form', class ProductForm extends HTMLElement { 3 | constructor() { 4 | super(); 5 | 6 | this.form = this.querySelector('form'); 7 | this.form.querySelector('[name=id]').disabled = false; 8 | this.form.addEventListener('submit', this.onSubmitHandler.bind(this)); 9 | this.cart = document.querySelector('cart-notification') || document.querySelector('cart-drawer'); 10 | this.submitButton = this.querySelector('[type="submit"]'); 11 | if (document.querySelector('cart-drawer')) this.submitButton.setAttribute('aria-haspopup', 'dialog'); 12 | } 13 | 14 | onSubmitHandler(evt) { 15 | evt.preventDefault(); 16 | if (this.submitButton.getAttribute('aria-disabled') === 'true') return; 17 | 18 | this.handleErrorMessage(); 19 | 20 | this.submitButton.setAttribute('aria-disabled', true); 21 | this.submitButton.classList.add('loading'); 22 | this.querySelector('.loading-overlay__spinner').classList.remove('hidden'); 23 | 24 | const config = fetchConfig('javascript'); 25 | config.headers['X-Requested-With'] = 'XMLHttpRequest'; 26 | delete config.headers['Content-Type']; 27 | 28 | const formData = new FormData(this.form); 29 | if (this.cart) { 30 | formData.append('sections', this.cart.getSectionsToRender().map((section) => section.id)); 31 | formData.append('sections_url', window.location.pathname); 32 | this.cart.setActiveElement(document.activeElement); 33 | } 34 | config.body = formData; 35 | 36 | fetch(`${routes.cart_add_url}`, config) 37 | .then((response) => response.json()) 38 | .then((response) => { 39 | if (response.status) { 40 | this.handleErrorMessage(response.description); 41 | 42 | const soldOutMessage = this.submitButton.querySelector('.sold-out-message'); 43 | if (!soldOutMessage) return; 44 | this.submitButton.setAttribute('aria-disabled', true); 45 | this.submitButton.querySelector('span').classList.add('hidden'); 46 | soldOutMessage.classList.remove('hidden'); 47 | this.error = true; 48 | return; 49 | } else if (!this.cart) { 50 | window.location = window.routes.cart_url; 51 | return; 52 | } 53 | 54 | this.error = false; 55 | const quickAddModal = this.closest('quick-add-modal'); 56 | if (quickAddModal) { 57 | document.body.addEventListener('modalClosed', () => { 58 | setTimeout(() => { this.cart.renderContents(response) }); 59 | }, { once: true }); 60 | quickAddModal.hide(true); 61 | } else { 62 | this.cart.renderContents(response); 63 | } 64 | }) 65 | .catch((e) => { 66 | console.error(e); 67 | }) 68 | .finally(() => { 69 | this.submitButton.classList.remove('loading'); 70 | if (this.cart && this.cart.classList.contains('is-empty')) this.cart.classList.remove('is-empty'); 71 | if (!this.error) this.submitButton.removeAttribute('aria-disabled'); 72 | this.querySelector('.loading-overlay__spinner').classList.add('hidden'); 73 | }); 74 | } 75 | 76 | handleErrorMessage(errorMessage = false) { 77 | this.errorMessageWrapper = this.errorMessageWrapper || this.querySelector('.product-form__error-message-wrapper'); 78 | if (!this.errorMessageWrapper) return; 79 | this.errorMessage = this.errorMessage || this.errorMessageWrapper.querySelector('.product-form__error-message'); 80 | 81 | this.errorMessageWrapper.toggleAttribute('hidden', !errorMessage); 82 | 83 | if (errorMessage) { 84 | this.errorMessage.textContent = errorMessage; 85 | } 86 | } 87 | }); 88 | } 89 | -------------------------------------------------------------------------------- /sections/announcement-bar.liquid: -------------------------------------------------------------------------------- 1 | {%- for block in section.blocks -%} 2 | {%- case block.type -%} 3 | {%- when 'announcement' -%} 4 |
5 | {%- if block.settings.text != blank -%} 6 | {%- if block.settings.link != blank -%} 7 | 8 | {%- endif -%} 9 |
10 |

11 | {{ block.settings.text | escape }} 12 | {%- if block.settings.link != blank -%} 13 | {% render 'icon-arrow' %} 14 | {%- endif -%} 15 |

16 |
17 | {%- if block.settings.link != blank -%} 18 |
19 | {%- endif -%} 20 | {%- endif -%} 21 |
22 | {%- endcase -%} 23 | {%- endfor -%} 24 | 25 | {% schema %} 26 | { 27 | "name": "t:sections.announcement-bar.name", 28 | "max_blocks": 12, 29 | "blocks": [ 30 | { 31 | "type": "announcement", 32 | "name": "t:sections.announcement-bar.blocks.announcement.name", 33 | "settings": [ 34 | { 35 | "type": "text", 36 | "id": "text", 37 | "default": "Welcome to our store", 38 | "label": "t:sections.announcement-bar.blocks.announcement.settings.text.label" 39 | }, 40 | { 41 | "type": "select", 42 | "id": "text_alignment", 43 | "options": [ 44 | { 45 | "value": "left", 46 | "label": "t:sections.announcement-bar.blocks.announcement.settings.text_alignment.options__1.label" 47 | }, 48 | { 49 | "value": "center", 50 | "label": "t:sections.announcement-bar.blocks.announcement.settings.text_alignment.options__2.label" 51 | }, 52 | { 53 | "value": "right", 54 | "label": "t:sections.announcement-bar.blocks.announcement.settings.text_alignment.options__3.label" 55 | } 56 | ], 57 | "default": "center", 58 | "label": "t:sections.announcement-bar.blocks.announcement.settings.text_alignment.label" 59 | }, 60 | { 61 | "type": "select", 62 | "id": "color_scheme", 63 | "options": [ 64 | { 65 | "value": "accent-1", 66 | "label": "t:sections.all.colors.accent_1.label" 67 | }, 68 | { 69 | "value": "accent-2", 70 | "label": "t:sections.all.colors.accent_2.label" 71 | }, 72 | { 73 | "value": "background-1", 74 | "label": "t:sections.all.colors.background_1.label" 75 | }, 76 | { 77 | "value": "background-2", 78 | "label": "t:sections.all.colors.background_2.label" 79 | }, 80 | { 81 | "value": "inverse", 82 | "label": "t:sections.all.colors.inverse.label" 83 | } 84 | ], 85 | "default": "accent-1", 86 | "label": "t:sections.all.colors.label" 87 | }, 88 | { 89 | "type": "url", 90 | "id": "link", 91 | "label": "t:sections.announcement-bar.blocks.announcement.settings.link.label" 92 | } 93 | ] 94 | } 95 | ], 96 | "default": { 97 | "blocks": [ 98 | { 99 | "type": "announcement" 100 | } 101 | ] 102 | } 103 | } 104 | {% endschema %} 105 | -------------------------------------------------------------------------------- /assets/quick-add.js: -------------------------------------------------------------------------------- 1 | if (!customElements.get('quick-add-modal')) { 2 | customElements.define('quick-add-modal', class QuickAddModal extends ModalDialog { 3 | constructor() { 4 | super(); 5 | this.modalContent = this.querySelector('[id^="QuickAddInfo-"]'); 6 | } 7 | 8 | hide(preventFocus = false) { 9 | const cartNotification = document.querySelector('cart-notification') || document.querySelector('cart-drawer'); 10 | if (cartNotification) cartNotification.setActiveElement(this.openedBy); 11 | this.modalContent.innerHTML = ''; 12 | 13 | if (preventFocus) this.openedBy = null; 14 | super.hide(); 15 | } 16 | 17 | show(opener) { 18 | opener.setAttribute('aria-disabled', true); 19 | opener.classList.add('loading'); 20 | opener.querySelector('.loading-overlay__spinner').classList.remove('hidden'); 21 | 22 | fetch(opener.getAttribute('data-product-url')) 23 | .then((response) => response.text()) 24 | .then((responseText) => { 25 | const responseHTML = new DOMParser().parseFromString(responseText, 'text/html'); 26 | this.productElement = responseHTML.querySelector('section[id^="MainProduct-"]'); 27 | this.preventDuplicatedIDs(); 28 | this.removeDOMElements(); 29 | this.setInnerHTML(this.modalContent, this.productElement.innerHTML); 30 | 31 | if (window.Shopify && Shopify.PaymentButton) { 32 | Shopify.PaymentButton.init(); 33 | } 34 | 35 | if (window.ProductModel) window.ProductModel.loadShopifyXR(); 36 | 37 | this.removeGalleryListSemantic(); 38 | this.preventVariantURLSwitching(); 39 | super.show(opener); 40 | }) 41 | .finally(() => { 42 | opener.removeAttribute('aria-disabled'); 43 | opener.classList.remove('loading'); 44 | opener.querySelector('.loading-overlay__spinner').classList.add('hidden'); 45 | }); 46 | } 47 | 48 | setInnerHTML(element, html) { 49 | element.innerHTML = html; 50 | 51 | // Reinjects the script tags to allow execution. By default, scripts are disabled when using element.innerHTML. 52 | element.querySelectorAll('script').forEach(oldScriptTag => { 53 | const newScriptTag = document.createElement('script'); 54 | Array.from(oldScriptTag.attributes).forEach(attribute => { 55 | newScriptTag.setAttribute(attribute.name, attribute.value) 56 | }); 57 | newScriptTag.appendChild(document.createTextNode(oldScriptTag.innerHTML)); 58 | oldScriptTag.parentNode.replaceChild(newScriptTag, oldScriptTag); 59 | }); 60 | } 61 | 62 | preventVariantURLSwitching() { 63 | this.modalContent.querySelector('variant-radios,variant-selects').setAttribute('data-update-url', 'false'); 64 | } 65 | 66 | removeDOMElements() { 67 | const pickupAvailability = this.productElement.querySelector('pickup-availability'); 68 | if (pickupAvailability) pickupAvailability.remove(); 69 | 70 | const productModal = this.productElement.querySelector('product-modal'); 71 | if (productModal) productModal.remove(); 72 | } 73 | 74 | preventDuplicatedIDs() { 75 | const sectionId = this.productElement.dataset.section; 76 | this.productElement.innerHTML = this.productElement.innerHTML.replaceAll(sectionId, `quickadd-${ sectionId }`); 77 | this.productElement.querySelectorAll('variant-selects, variant-radios').forEach((variantSelect) => { 78 | variantSelect.dataset.originalSection = sectionId; 79 | }); 80 | } 81 | 82 | removeGalleryListSemantic() { 83 | const galleryList = this.modalContent.querySelector('[id^="Slider-Gallery"]'); 84 | if (!galleryList) return; 85 | 86 | galleryList.setAttribute('role', 'presentation'); 87 | galleryList.querySelectorAll('[id^="Slide-"]').forEach(li => li.setAttribute('role', 'presentation')); 88 | } 89 | }); 90 | } 91 | -------------------------------------------------------------------------------- /assets/pickup-availability.js: -------------------------------------------------------------------------------- 1 | if (!customElements.get('pickup-availability')) { 2 | customElements.define('pickup-availability', class PickupAvailability extends HTMLElement { 3 | constructor() { 4 | super(); 5 | 6 | if(!this.hasAttribute('available')) return; 7 | 8 | this.errorHtml = this.querySelector('template').content.firstElementChild.cloneNode(true); 9 | this.onClickRefreshList = this.onClickRefreshList.bind(this); 10 | this.fetchAvailability(this.dataset.variantId); 11 | } 12 | 13 | fetchAvailability(variantId) { 14 | let rootUrl = this.dataset.rootUrl; 15 | if (!rootUrl.endsWith("/")) { 16 | rootUrl = rootUrl + "/"; 17 | } 18 | const variantSectionUrl = `${rootUrl}variants/${variantId}/?section_id=pickup-availability`; 19 | 20 | fetch(variantSectionUrl) 21 | .then(response => response.text()) 22 | .then(text => { 23 | const sectionInnerHTML = new DOMParser() 24 | .parseFromString(text, 'text/html') 25 | .querySelector('.shopify-section'); 26 | this.renderPreview(sectionInnerHTML); 27 | }) 28 | .catch(e => { 29 | const button = this.querySelector('button'); 30 | if (button) button.removeEventListener('click', this.onClickRefreshList); 31 | this.renderError(); 32 | }); 33 | } 34 | 35 | onClickRefreshList(evt) { 36 | this.fetchAvailability(this.dataset.variantId); 37 | } 38 | 39 | renderError() { 40 | this.innerHTML = ''; 41 | this.appendChild(this.errorHtml); 42 | 43 | this.querySelector('button').addEventListener('click', this.onClickRefreshList); 44 | } 45 | 46 | renderPreview(sectionInnerHTML) { 47 | const drawer = document.querySelector('pickup-availability-drawer'); 48 | if (drawer) drawer.remove(); 49 | if (!sectionInnerHTML.querySelector('pickup-availability-preview')) { 50 | this.innerHTML = ""; 51 | this.removeAttribute('available'); 52 | return; 53 | } 54 | 55 | this.innerHTML = sectionInnerHTML.querySelector('pickup-availability-preview').outerHTML; 56 | this.setAttribute('available', ''); 57 | 58 | document.body.appendChild(sectionInnerHTML.querySelector('pickup-availability-drawer')); 59 | 60 | const button = this.querySelector('button'); 61 | if (button) button.addEventListener('click', (evt) => { 62 | document.querySelector('pickup-availability-drawer').show(evt.target); 63 | }); 64 | } 65 | }); 66 | } 67 | 68 | if (!customElements.get('pickup-availability-drawer')) { 69 | customElements.define('pickup-availability-drawer', class PickupAvailabilityDrawer extends HTMLElement { 70 | constructor() { 71 | super(); 72 | 73 | this.onBodyClick = this.handleBodyClick.bind(this); 74 | 75 | this.querySelector('button').addEventListener('click', () => { 76 | this.hide(); 77 | }); 78 | 79 | this.addEventListener('keyup', (event) => { 80 | if(event.code.toUpperCase() === 'ESCAPE') this.hide(); 81 | }); 82 | } 83 | 84 | handleBodyClick(evt) { 85 | const target = evt.target; 86 | if (target != this && !target.closest('pickup-availability-drawer') && target.id != 'ShowPickupAvailabilityDrawer') { 87 | this.hide(); 88 | } 89 | } 90 | 91 | hide() { 92 | this.removeAttribute('open'); 93 | document.body.removeEventListener('click', this.onBodyClick); 94 | document.body.classList.remove('overflow-hidden'); 95 | removeTrapFocus(this.focusElement); 96 | } 97 | 98 | show(focusElement) { 99 | this.focusElement = focusElement; 100 | this.setAttribute('open', ''); 101 | document.body.addEventListener('click', this.onBodyClick); 102 | document.body.classList.add('overflow-hidden'); 103 | trapFocus(this); 104 | } 105 | }); 106 | } 107 | -------------------------------------------------------------------------------- /sections/pickup-availability.liquid: -------------------------------------------------------------------------------- 1 | {% comment %}theme-check-disable UndefinedObject{% endcomment %} 2 | {%- assign pick_up_availabilities = product_variant.store_availabilities | where: 'pick_up_enabled', true -%} 3 | 4 | {%- if pick_up_availabilities.size > 0 -%} 5 | 6 | {%- liquid 7 | assign closest_location = pick_up_availabilities.first 8 | 9 | if closest_location.available 10 | render 'icon-tick' 11 | endif 12 | -%} 13 | 14 |
15 | {%- if closest_location.available -%} 16 |

{{ 'products.product.pickup_availability.pick_up_available_at_html' | t: location_name: closest_location.location.name }}

17 |

{{ closest_location.pick_up_time }}

18 | 25 | {%- else -%} 26 |

{{ 'products.product.pickup_availability.pick_up_unavailable_at_html' | t: location_name: closest_location.location.name }}

27 | {%- if pick_up_availabilities.size > 1 -%} 28 | 29 | {%- endif -%} 30 | {%- endif -%} 31 |
32 |
33 | 34 | 35 |
36 |

{{ product_variant.product.title | escape }}

37 | 38 |
39 | 40 | {%- unless product_variant.product.has_only_default_variant -%} 41 |

42 | {%- for product_option in product_variant.product.options_with_values -%} 43 | {{ product_option.name | escape }}:  44 | {%- for value in product_option.values -%} 45 | {%- if product_option.selected_value == value -%} 46 | {{ value | escape }} 47 | {%- endif -%} 48 | {%- endfor -%} 49 | {%- unless forloop.last -%}, {%- endunless forloop.last -%} 50 | {%- endfor -%} 51 |

52 | {%- endunless -%} 53 | 54 | 75 |
76 | {%- endif -%} 77 | -------------------------------------------------------------------------------- /assets/section-blog-post.css: -------------------------------------------------------------------------------- 1 | .article-template > *:first-child:not(.article-template__hero-container) { 2 | margin-top: 5rem; 3 | } 4 | 5 | @media screen and (min-width: 750px) { 6 | .article-template > *:first-child:not(.article-template__hero-container) { 7 | margin-top: calc(5rem + var(--page-width-margin)); 8 | } 9 | } 10 | 11 | .article-template__hero-container { 12 | max-width: 130rem; 13 | margin: 0 auto; 14 | } 15 | 16 | .article-template__hero-small { 17 | height: 11rem; 18 | } 19 | 20 | .article-template__hero-medium { 21 | height: 22rem; 22 | } 23 | 24 | .article-template__hero-large { 25 | height: 33rem; 26 | } 27 | 28 | @media screen and (min-width: 750px) and (max-width: 989px) { 29 | .article-template__hero-small { 30 | height: 22rem; 31 | } 32 | 33 | .article-template__hero-medium { 34 | height: 44rem; 35 | } 36 | 37 | .article-template__hero-large { 38 | height: 66rem; 39 | } 40 | } 41 | 42 | @media screen and (min-width: 990px) { 43 | .article-template__hero-small { 44 | height: 27.5rem; 45 | } 46 | 47 | .article-template__hero-medium { 48 | height: 55rem; 49 | } 50 | 51 | .article-template__hero-large { 52 | height: 82.5rem; 53 | } 54 | } 55 | 56 | .article-template header { 57 | margin-top: 4.4rem; 58 | margin-bottom: 2rem; 59 | line-height: calc(0.8 / var(--font-body-scale)); 60 | } 61 | 62 | @media screen and (min-width: 750px) { 63 | .article-template header { 64 | margin-top: 5rem; 65 | } 66 | } 67 | 68 | .article-template__title { 69 | margin: 0; 70 | } 71 | 72 | .article-template__title:not(:only-child) { 73 | margin-bottom: 1rem; 74 | } 75 | 76 | .article-template__link { 77 | font-size: 1.8rem; 78 | display: flex; 79 | justify-content: center; 80 | align-items: center; 81 | text-decoration: none; 82 | } 83 | 84 | .article-template__link .icon-wrap { 85 | display: flex; 86 | margin-right: 1rem; 87 | transform: rotate(180deg); 88 | } 89 | 90 | .article-template__content { 91 | margin-top: 3rem; 92 | margin-bottom: 3rem; 93 | } 94 | 95 | .article-template__social-sharing { 96 | margin-top: 3rem; 97 | } 98 | 99 | .article-template__social-sharing + header, 100 | .article-template__social-sharing + .article-template__content { 101 | margin-top: 1.5rem; 102 | } 103 | 104 | .article-template__comment-wrapper { 105 | margin-top: 5rem; 106 | padding: 2.7rem 0; 107 | } 108 | 109 | @media screen and (min-width: 750px) { 110 | .article-template__comment-wrapper { 111 | margin-top: 6rem; 112 | padding: 3.6rem 0; 113 | } 114 | } 115 | 116 | .article-template__comment-wrapper h2 { 117 | margin-top: 0; 118 | } 119 | 120 | .article-template__comments { 121 | margin-bottom: 5rem; 122 | } 123 | 124 | @media screen and (min-width: 750px) { 125 | .article-template__comments { 126 | margin-bottom: 7rem; 127 | } 128 | } 129 | 130 | .article-template__comments-fields { 131 | margin-bottom: 4rem; 132 | } 133 | 134 | .article-template__comments-comment { 135 | color: rgba(var(--color-foreground), 0.75); 136 | background-color: rgb(var(--color-background)); 137 | margin-bottom: 1.5rem; 138 | padding: 2rem 2rem 1.5rem; 139 | } 140 | 141 | @media screen and (min-width: 750px) { 142 | .article-template__comments-comment { 143 | padding: 2rem 2.5rem; 144 | } 145 | } 146 | 147 | .article-template__comments-comment p { 148 | margin: 0 0 1rem; 149 | } 150 | 151 | .article-template__comment-fields > * { 152 | margin-bottom: 3rem; 153 | } 154 | 155 | @media screen and (min-width: 750px) { 156 | .article-template__comment-fields { 157 | display: grid; 158 | grid-template-columns: repeat(2, 1fr); 159 | grid-column-gap: 4rem; 160 | } 161 | } 162 | 163 | .article-template__comment-warning { 164 | margin: 2rem 0 2.5rem; 165 | } 166 | 167 | @media screen and (min-width: 990px) { 168 | .article-template__comments .pagination-wrapper { 169 | margin: 5rem 0 8rem; 170 | } 171 | } 172 | 173 | .article-template__back:last-child { 174 | margin-bottom: 3.2rem; 175 | } 176 | -------------------------------------------------------------------------------- /sections/main-collection-banner.liquid: -------------------------------------------------------------------------------- 1 | {% comment %}theme-check-disable ImgLazyLoading{% endcomment %} 2 | {{ 'component-collection-hero.css' | asset_url | stylesheet_tag }} 3 | 4 | {%- style -%} 5 | @media screen and (max-width: 749px) { 6 | .collection-hero--with-image .collection-hero__inner { 7 | padding-bottom: calc({{ settings.media_shadow_vertical_offset | at_least: 0 }}px + 2rem); 8 | } 9 | } 10 | {%- endstyle -%} 11 | 12 |
13 |
14 |
15 |

16 | {{ 'sections.collection_template.title' | t }}: 17 | {{- collection.title | escape -}} 18 |

19 | 20 | {%- if section.settings.show_collection_description -%} 21 |
{{ collection.description }}
22 | {%- endif -%} 23 |
24 | 25 | {%- if section.settings.show_collection_image and collection.image -%} 26 |
27 | 41 |
42 | {%- endif -%} 43 |
44 |
45 | 46 | {% schema %} 47 | { 48 | "name": "t:sections.main-collection-banner.name", 49 | "class": "section", 50 | "settings": [ 51 | { 52 | "type": "paragraph", 53 | "content": "t:sections.main-collection-banner.settings.paragraph.content" 54 | }, 55 | { 56 | "type": "checkbox", 57 | "id": "show_collection_description", 58 | "default": true, 59 | "label": "t:sections.main-collection-banner.settings.show_collection_description.label" 60 | }, 61 | { 62 | "type": "checkbox", 63 | "id": "show_collection_image", 64 | "default": false, 65 | "label": "t:sections.main-collection-banner.settings.show_collection_image.label", 66 | "info": "t:sections.main-collection-banner.settings.show_collection_image.info" 67 | }, 68 | { 69 | "type": "select", 70 | "id": "color_scheme", 71 | "options": [ 72 | { 73 | "value": "accent-1", 74 | "label": "t:sections.all.colors.accent_1.label" 75 | }, 76 | { 77 | "value": "accent-2", 78 | "label": "t:sections.all.colors.accent_2.label" 79 | }, 80 | { 81 | "value": "background-1", 82 | "label": "t:sections.all.colors.background_1.label" 83 | }, 84 | { 85 | "value": "background-2", 86 | "label": "t:sections.all.colors.background_2.label" 87 | }, 88 | { 89 | "value": "inverse", 90 | "label": "t:sections.all.colors.inverse.label" 91 | } 92 | ], 93 | "default": "background-1", 94 | "label": "t:sections.all.colors.label" 95 | } 96 | ] 97 | } 98 | {% endschema %} 99 | -------------------------------------------------------------------------------- /sections/page.liquid: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {%- style -%} 8 | .section-{{ section.id }}-padding { 9 | padding-top: {{ section.settings.padding_top | times: 0.75 | round: 0 }}px; 10 | padding-bottom: {{ section.settings.padding_bottom | times: 0.75 | round: 0 }}px; 11 | } 12 | 13 | @media screen and (min-width: 750px) { 14 | .section-{{ section.id }}-padding { 15 | padding-top: {{ section.settings.padding_top }}px; 16 | padding-bottom: {{ section.settings.padding_bottom }}px; 17 | } 18 | } 19 | {%- endstyle -%} 20 | 21 |
22 |
23 |

24 | {%- if section.settings.page.title != blank -%} 25 | {{ section.settings.page.title | escape }} 26 | {%- else -%} 27 | {{ 'sections.page.title' | t }} 28 | {%- endif -%} 29 |

30 |
31 | {%- if section.settings.page.content != blank -%} 32 | {{ section.settings.page.content }} 33 | {%- else -%} 34 |
35 | {{ 'page' | placeholder_svg_tag: 'page-placeholder' }} 36 |
37 | {%- endif -%} 38 |
39 |
40 |
41 | 42 | {% schema %} 43 | { 44 | "name": "t:sections.page.name", 45 | "tag": "section", 46 | "class": "section", 47 | "settings": [ 48 | { 49 | "type": "page", 50 | "id": "page", 51 | "label": "t:sections.page.settings.page.label" 52 | }, 53 | { 54 | "type": "select", 55 | "id": "heading_size", 56 | "options": [ 57 | { 58 | "value": "h2", 59 | "label": "t:sections.all.heading_size.options__1.label" 60 | }, 61 | { 62 | "value": "h1", 63 | "label": "t:sections.all.heading_size.options__2.label" 64 | }, 65 | { 66 | "value": "h0", 67 | "label": "t:sections.all.heading_size.options__3.label" 68 | } 69 | ], 70 | "default": "h1", 71 | "label": "t:sections.all.heading_size.label" 72 | }, 73 | { 74 | "type": "select", 75 | "id": "color_scheme", 76 | "options": [ 77 | { 78 | "value": "accent-1", 79 | "label": "t:sections.all.colors.accent_1.label" 80 | }, 81 | { 82 | "value": "accent-2", 83 | "label": "t:sections.all.colors.accent_2.label" 84 | }, 85 | { 86 | "value": "background-1", 87 | "label": "t:sections.all.colors.background_1.label" 88 | }, 89 | { 90 | "value": "background-2", 91 | "label": "t:sections.all.colors.background_2.label" 92 | }, 93 | { 94 | "value": "inverse", 95 | "label": "t:sections.all.colors.inverse.label" 96 | } 97 | ], 98 | "default": "background-1", 99 | "label": "t:sections.all.colors.label" 100 | }, 101 | { 102 | "type": "header", 103 | "content": "t:sections.all.padding.section_padding_heading" 104 | }, 105 | { 106 | "type": "range", 107 | "id": "padding_top", 108 | "min": 0, 109 | "max": 100, 110 | "step": 4, 111 | "unit": "px", 112 | "label": "t:sections.all.padding.padding_top", 113 | "default": 36 114 | }, 115 | { 116 | "type": "range", 117 | "id": "padding_bottom", 118 | "min": 0, 119 | "max": 100, 120 | "step": 4, 121 | "unit": "px", 122 | "label": "t:sections.all.padding.padding_bottom", 123 | "default": 36 124 | } 125 | ], 126 | "presets": [ 127 | { 128 | "name": "t:sections.page.presets.name" 129 | } 130 | ] 131 | } 132 | {% endschema %} 133 | -------------------------------------------------------------------------------- /snippets/price.liquid: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Renders a list of product's price (regular, sale) 3 | 4 | Accepts: 5 | - product: {Object} Product Liquid object (optional) 6 | - use_variant: {Boolean} Renders selected or first variant price instead of overall product pricing (optional) 7 | - show_badges: {Boolean} Renders 'Sale' and 'Sold Out' tags if the product matches the condition (optional) 8 | - price_class: {String} Adds a price class to the price element (optional) 9 | 10 | Usage: 11 | {% render 'price', product: product %} 12 | {% endcomment %} 13 | {%- liquid 14 | if use_variant 15 | assign target = product.selected_or_first_available_variant 16 | else 17 | assign target = product 18 | endif 19 | 20 | assign compare_at_price = target.compare_at_price 21 | assign price = target.price | default: 1999 22 | assign available = target.available | default: false 23 | assign money_price = price | money 24 | if settings.currency_code_enabled 25 | assign money_price = price | money_with_currency 26 | endif 27 | 28 | if target == product and product.price_varies 29 | assign money_price = 'products.product.price.from_price_html' | t: price: money_price 30 | endif 31 | -%} 32 | 33 |
39 |
40 | {%- comment -%} 41 | Explanation of description list: 42 | - div.price__regular: Displayed when there are no variants on sale 43 | - div.price__sale: Displayed when a variant is a sale 44 | {%- endcomment -%} 45 |
46 | {{ 'products.product.price.regular_price' | t }} 47 | 48 | {{ money_price }} 49 | 50 |
51 |
52 | {%- unless product.price_varies == false and product.compare_at_price_varies %} 53 | {{ 'products.product.price.regular_price' | t }} 54 | 55 | 56 | {% if settings.currency_code_enabled %} 57 | {{ compare_at_price | money_with_currency }} 58 | {% else %} 59 | {{ compare_at_price | money }} 60 | {% endif %} 61 | 62 | 63 | {%- endunless -%} 64 | {{ 'products.product.price.sale_price' | t }} 65 | 66 | {{ money_price }} 67 | 68 |
69 | 70 | {{ 'products.product.price.unit_price' | t }} 71 | 72 | {{- product.selected_or_first_available_variant.unit_price | money -}} 73 | 74 |  {{ 'accessibility.unit_price_separator' | t }}  75 | 76 | {%- if product.selected_or_first_available_variant.unit_price_measurement.reference_value != 1 -%} 77 | {{- product.selected_or_first_available_variant.unit_price_measurement.reference_value -}} 78 | {%- endif -%} 79 | {{ product.selected_or_first_available_variant.unit_price_measurement.reference_unit }} 80 | 81 | 82 | 83 |
84 | {%- if show_badges -%} 85 | 86 | {{ 'products.product.on_sale' | t }} 87 | 88 | 89 | 90 | {{ 'products.product.sold_out' | t }} 91 | 92 | {%- endif -%} 93 |
94 | -------------------------------------------------------------------------------- /snippets/email-signup-banner-background.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/component-pickup-availability.css: -------------------------------------------------------------------------------- 1 | pickup-availability { 2 | display: block; 3 | } 4 | 5 | pickup-availability[available] { 6 | min-height: 8rem; 7 | } 8 | 9 | .pickup-availability-preview { 10 | align-items: flex-start; 11 | display: flex; 12 | gap: 0.2rem; 13 | padding: 1rem 2rem 0 0; 14 | } 15 | 16 | .pickup-availability-preview .icon { 17 | flex-shrink: 0; 18 | height: 1.8rem; 19 | } 20 | 21 | .pickup-availability-preview .icon-unavailable { 22 | height: 1.6rem; 23 | margin-top: 0.1rem; 24 | } 25 | 26 | .pickup-availability-button { 27 | background-color: transparent; 28 | color: rgba(var(--color-foreground), 0.75); 29 | letter-spacing: 0.06rem; 30 | padding: 0 0 0.2rem; 31 | text-align: left; 32 | text-decoration: underline; 33 | } 34 | 35 | .pickup-availability-button:hover { 36 | color: rgb(var(--color-foreground)); 37 | } 38 | 39 | .pickup-availability-info * { 40 | margin: 0 0 0.6rem; 41 | } 42 | 43 | pickup-availability-drawer { 44 | background-color: rgb(var(--color-background)); 45 | height: 100%; 46 | opacity: 0; 47 | overflow-y: auto; 48 | padding: 2rem; 49 | position: fixed; 50 | top: 0; 51 | right: 0; 52 | z-index: 4; 53 | transition: opacity var(--duration-default) ease, 54 | transform var(--duration-default) ease; 55 | transform: translateX(100%); 56 | width: 100%; 57 | border-width: 0 0 0 var(--drawer-border-width); 58 | border-color: rgba(var(--color-foreground), var(--drawer-border-opacity)); 59 | border-style: solid; 60 | filter: drop-shadow( 61 | var(--drawer-shadow-horizontal-offset) 62 | var(--drawer-shadow-vertical-offset) 63 | var(--drawer-shadow-blur-radius) 64 | rgba(var(--color-shadow), var(--drawer-shadow-opacity)) 65 | ); 66 | } 67 | 68 | pickup-availability-drawer[open] { 69 | transform: translateX(0); 70 | opacity: 1; 71 | } 72 | 73 | @media screen and (min-width: 750px) { 74 | pickup-availability-drawer { 75 | transform: translateX(100%); 76 | width: 37.5rem; 77 | } 78 | 79 | pickup-availability-drawer[open] { 80 | opacity: 1; 81 | transform: translateX(0); 82 | animation: animateDrawerOpen var(--duration-default) ease; 83 | } 84 | } 85 | 86 | .pickup-availability-header { 87 | align-items: flex-start; 88 | display: flex; 89 | justify-content: space-between; 90 | margin-bottom: 1.2rem; 91 | } 92 | 93 | .pickup-availability-drawer-title { 94 | margin: 0.5rem 0 0; 95 | } 96 | 97 | .pickup-availability-header .icon { 98 | width: 2rem; 99 | } 100 | 101 | .pickup-availability-drawer-button { 102 | background-color: transparent; 103 | border: none; 104 | color: rgb(var(--color-foreground)); 105 | cursor: pointer; 106 | display: block; 107 | height: 4.4rem; 108 | padding: 1.2rem; 109 | width: 4.4rem; 110 | } 111 | 112 | .pickup-availability-drawer-button:hover { 113 | color: rgba(var(--color-foreground), 0.75); 114 | } 115 | 116 | .pickup-availability-variant { 117 | font-size: 1.3rem; 118 | line-height: calc(1 + 0.2 / var(--font-body-scale)); 119 | margin: 0 0 1.2rem; 120 | text-transform: capitalize; 121 | } 122 | 123 | .pickup-availability-variant > * + strong { 124 | margin-left: 1rem; 125 | } 126 | 127 | .pickup-availability-list__item { 128 | border-bottom: 0.1rem solid rgba(var(--color-foreground), 0.08); 129 | padding: 2rem 0; 130 | } 131 | 132 | .pickup-availability-list__item:first-child { 133 | border-top: 0.1rem solid rgba(var(--color-foreground), 0.08); 134 | } 135 | 136 | .pickup-availability-list__item > * { 137 | margin: 0; 138 | } 139 | 140 | .pickup-availability-list__item > * + * { 141 | margin-top: 1rem; 142 | } 143 | 144 | .pickup-availability-address { 145 | font-style: normal; 146 | font-size: 1.2rem; 147 | line-height: calc(1 + 0.5 / var(--font-body-scale)); 148 | } 149 | 150 | .pickup-availability-address p { 151 | margin: 0; 152 | } 153 | 154 | @keyframes animateDrawerOpen { 155 | @media screen and (max-width: 749px) { 156 | 0% { 157 | opacity: 0; 158 | transform: translateX(100%); 159 | } 160 | 161 | 100% { 162 | opacity: 1; 163 | transform: translateX(0); 164 | } 165 | } 166 | 167 | @media screen and (min-width: 750px) { 168 | 0% { 169 | opacity: 0; 170 | transform: translateX(100%); 171 | } 172 | 173 | 100% { 174 | opacity: 1; 175 | transform: translateX(0); 176 | } 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /assets/component-cart.css: -------------------------------------------------------------------------------- 1 | .cart { 2 | position: relative; 3 | display: block; 4 | } 5 | 6 | .cart__empty-text, 7 | .is-empty .cart__contents, 8 | cart-items.is-empty .title-wrapper-with-link, 9 | .is-empty .cart__footer { 10 | display: none; 11 | } 12 | 13 | .is-empty .cart__empty-text, 14 | .is-empty .cart__warnings { 15 | display: block; 16 | } 17 | 18 | .cart__warnings { 19 | display: none; 20 | text-align: center; 21 | padding: 3rem 0 1rem; 22 | } 23 | 24 | .cart__empty-text { 25 | margin: 4.5rem 0 2rem; 26 | } 27 | 28 | .cart__contents > * + * { 29 | margin-top: 2.5rem; 30 | } 31 | 32 | .cart__login-title { 33 | margin: 5.5rem 0 0.5rem; 34 | } 35 | 36 | .cart__login-paragraph { 37 | margin-top: 0.8rem; 38 | } 39 | 40 | .cart__login-paragraph a { 41 | font-size: inherit; 42 | } 43 | 44 | @media screen and (min-width: 990px) { 45 | .cart__warnings { 46 | padding: 7rem 0 1rem; 47 | } 48 | 49 | .cart__empty-text { 50 | margin: 0 0 3rem; 51 | } 52 | } 53 | 54 | cart-items { 55 | display: block; 56 | } 57 | 58 | .cart__items { 59 | position: relative; 60 | padding-bottom: 3rem; 61 | border-bottom: 0.1rem solid rgba(var(--color-foreground), 0.08); 62 | } 63 | 64 | .cart__items--disabled { 65 | pointer-events: none; 66 | } 67 | 68 | .cart__footer { 69 | padding: 4rem 0 0; 70 | } 71 | 72 | .cart__footer-wrapper:last-child .cart__footer { 73 | padding-bottom: 5rem; 74 | } 75 | 76 | .cart__footer > div:only-child { 77 | margin-left: auto; 78 | } 79 | 80 | .cart__footer > * + * { 81 | margin-top: 4rem; 82 | } 83 | 84 | .cart__footer .discounts { 85 | margin-top: 1rem; 86 | } 87 | 88 | .cart__note { 89 | height: fit-content; 90 | } 91 | 92 | .cart__note label { 93 | display: flex; 94 | align-items: flex-end; 95 | position: absolute; 96 | line-height: 1; 97 | height: 1.8rem; 98 | top: -3rem; 99 | color: rgba(var(--color-foreground), 0.75); 100 | } 101 | 102 | .cart__note .field__input { 103 | height: 100%; 104 | position: relative; 105 | border-radius: var(--inputs-radius); 106 | padding: 1rem 2rem; 107 | } 108 | 109 | .cart__note .text-area { 110 | resize: vertical; 111 | } 112 | 113 | .cart__note:after, .cart__note:hover.cart__note:after, 114 | .cart__note:before, .cart__note:hover.cart__note:before, 115 | .cart__note .field__input:focus, 116 | .cart__note .field__input { 117 | border-bottom-right-radius: 0; 118 | } 119 | 120 | @media screen and (min-width: 750px) { 121 | .cart__items { 122 | grid-column-start: 1; 123 | grid-column-end: 3; 124 | padding-bottom: 4rem; 125 | } 126 | 127 | .cart__contents > * + * { 128 | margin-top: 0; 129 | } 130 | 131 | .cart__items + .cart__footer { 132 | grid-column: 2; 133 | } 134 | 135 | .cart__footer { 136 | display: flex; 137 | justify-content: space-between; 138 | border: 0; 139 | } 140 | 141 | .cart__footer-wrapper:last-child { 142 | padding-top: 0; 143 | } 144 | 145 | .cart__footer > * { 146 | width: 35rem; 147 | } 148 | 149 | .cart__footer > * + * { 150 | margin-left: 4rem; 151 | margin-top: 0; 152 | } 153 | } 154 | 155 | .cart__ctas button { 156 | width: 100%; 157 | } 158 | 159 | .cart__ctas > *:not(noscript:first-child) + * { 160 | margin-top: 1rem; 161 | } 162 | 163 | .cart__update-button { 164 | margin-bottom: 1rem; 165 | } 166 | 167 | .cart__dynamic-checkout-buttons { 168 | max-width: 36rem; 169 | margin: 0 auto; 170 | } 171 | 172 | .cart__blocks > * + * { 173 | margin-top: 1rem; 174 | } 175 | 176 | .cart__dynamic-checkout-buttons div[role='button'] { 177 | border-radius: var(--buttons-radius-outset) !important; 178 | } 179 | 180 | .cart-note__label { 181 | display: inline-block; 182 | margin-bottom: 1rem; 183 | line-height: calc(1 + 1 / var(--font-body-scale)); 184 | } 185 | 186 | .tax-note { 187 | margin: 2.2rem 0 1.6rem auto; 188 | text-align: center; 189 | display: block; 190 | } 191 | 192 | .cart__checkout-button { 193 | max-width: 36rem; 194 | } 195 | 196 | .cart__ctas { 197 | text-align: center; 198 | } 199 | 200 | @media screen and (min-width: 750px) { 201 | .cart-note { 202 | max-width: 35rem; 203 | } 204 | 205 | .cart__update-button { 206 | margin-bottom: 0; 207 | margin-right: 0.8rem; 208 | } 209 | 210 | .tax-note { 211 | margin-bottom: 2.2rem; 212 | text-align: right; 213 | } 214 | 215 | [data-shopify-buttoncontainer] { 216 | justify-content: flex-end; 217 | } 218 | 219 | .cart__ctas { 220 | display: flex; 221 | gap: 1rem; 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /assets/cart-drawer.js: -------------------------------------------------------------------------------- 1 | class CartDrawer extends HTMLElement { 2 | constructor() { 3 | super(); 4 | 5 | this.addEventListener('keyup', (evt) => evt.code === 'Escape' && this.close()); 6 | this.querySelector('#CartDrawer-Overlay').addEventListener('click', this.close.bind(this)); 7 | this.setHeaderCartIconAccessibility(); 8 | } 9 | 10 | setHeaderCartIconAccessibility() { 11 | const cartLink = document.querySelector('#cart-icon-bubble'); 12 | cartLink.setAttribute('role', 'button'); 13 | cartLink.setAttribute('aria-haspopup', 'dialog'); 14 | cartLink.addEventListener('click', (event) => { 15 | event.preventDefault(); 16 | this.open(cartLink) 17 | }); 18 | cartLink.addEventListener('keydown', (event) => { 19 | if (event.code.toUpperCase() === 'SPACE') { 20 | event.preventDefault(); 21 | this.open(cartLink); 22 | } 23 | }); 24 | } 25 | 26 | open(triggeredBy) { 27 | if (triggeredBy) this.setActiveElement(triggeredBy); 28 | const cartDrawerNote = this.querySelector('[id^="Details-"] summary'); 29 | if (cartDrawerNote && !cartDrawerNote.hasAttribute('role')) this.setSummaryAccessibility(cartDrawerNote); 30 | // here the animation doesn't seem to always get triggered. A timeout seem to help 31 | setTimeout(() => {this.classList.add('animate', 'active')}); 32 | 33 | this.addEventListener('transitionend', () => { 34 | const containerToTrapFocusOn = this.classList.contains('is-empty') ? this.querySelector('.drawer__inner-empty') : document.getElementById('CartDrawer'); 35 | const focusElement = this.querySelector('.drawer__inner') || this.querySelector('.drawer__close'); 36 | trapFocus(containerToTrapFocusOn, focusElement); 37 | }, { once: true }); 38 | 39 | document.body.classList.add('overflow-hidden'); 40 | } 41 | 42 | close() { 43 | this.classList.remove('active'); 44 | removeTrapFocus(this.activeElement); 45 | document.body.classList.remove('overflow-hidden'); 46 | } 47 | 48 | setSummaryAccessibility(cartDrawerNote) { 49 | cartDrawerNote.setAttribute('role', 'button'); 50 | cartDrawerNote.setAttribute('aria-expanded', 'false'); 51 | 52 | if(cartDrawerNote.nextElementSibling.getAttribute('id')) { 53 | cartDrawerNote.setAttribute('aria-controls', cartDrawerNote.nextElementSibling.id); 54 | } 55 | 56 | cartDrawerNote.addEventListener('click', (event) => { 57 | event.currentTarget.setAttribute('aria-expanded', !event.currentTarget.closest('details').hasAttribute('open')); 58 | }); 59 | 60 | cartDrawerNote.parentElement.addEventListener('keyup', onKeyUpEscape); 61 | } 62 | 63 | renderContents(parsedState) { 64 | this.querySelector('.drawer__inner').classList.contains('is-empty') && this.querySelector('.drawer__inner').classList.remove('is-empty'); 65 | this.productId = parsedState.id; 66 | this.getSectionsToRender().forEach((section => { 67 | const sectionElement = section.selector ? document.querySelector(section.selector) : document.getElementById(section.id); 68 | sectionElement.innerHTML = 69 | this.getSectionInnerHTML(parsedState.sections[section.id], section.selector); 70 | })); 71 | 72 | setTimeout(() => { 73 | this.querySelector('#CartDrawer-Overlay').addEventListener('click', this.close.bind(this)); 74 | this.open(); 75 | }); 76 | } 77 | 78 | getSectionInnerHTML(html, selector = '.shopify-section') { 79 | return new DOMParser() 80 | .parseFromString(html, 'text/html') 81 | .querySelector(selector).innerHTML; 82 | } 83 | 84 | getSectionsToRender() { 85 | return [ 86 | { 87 | id: 'cart-drawer', 88 | selector: '#CartDrawer' 89 | }, 90 | { 91 | id: 'cart-icon-bubble' 92 | } 93 | ]; 94 | } 95 | 96 | getSectionDOM(html, selector = '.shopify-section') { 97 | return new DOMParser() 98 | .parseFromString(html, 'text/html') 99 | .querySelector(selector); 100 | } 101 | 102 | setActiveElement(element) { 103 | this.activeElement = element; 104 | } 105 | } 106 | 107 | customElements.define('cart-drawer', CartDrawer); 108 | 109 | class CartDrawerItems extends CartItems { 110 | getSectionsToRender() { 111 | return [ 112 | { 113 | id: 'CartDrawer', 114 | section: 'cart-drawer', 115 | selector: '.drawer__inner' 116 | }, 117 | { 118 | id: 'cart-icon-bubble', 119 | section: 'cart-icon-bubble', 120 | selector: '.shopify-section' 121 | } 122 | ]; 123 | } 124 | } 125 | 126 | customElements.define('cart-drawer-items', CartDrawerItems); 127 | -------------------------------------------------------------------------------- /assets/media-gallery.js: -------------------------------------------------------------------------------- 1 | if (!customElements.get('media-gallery')) { 2 | customElements.define('media-gallery', class MediaGallery extends HTMLElement { 3 | constructor() { 4 | super(); 5 | this.elements = { 6 | liveRegion: this.querySelector('[id^="GalleryStatus"]'), 7 | viewer: this.querySelector('[id^="GalleryViewer"]'), 8 | thumbnails: this.querySelector('[id^="GalleryThumbnails"]') 9 | } 10 | this.mql = window.matchMedia('(min-width: 750px)'); 11 | if (!this.elements.thumbnails) return; 12 | 13 | this.elements.viewer.addEventListener('slideChanged', debounce(this.onSlideChanged.bind(this), 500)); 14 | this.elements.thumbnails.querySelectorAll('[data-target]').forEach((mediaToSwitch) => { 15 | mediaToSwitch.querySelector('button').addEventListener('click', this.setActiveMedia.bind(this, mediaToSwitch.dataset.target, false)); 16 | }); 17 | if (this.dataset.desktopLayout !== 'stacked' && this.mql.matches) this.removeListSemantic(); 18 | } 19 | 20 | onSlideChanged(event) { 21 | const thumbnail = this.elements.thumbnails.querySelector(`[data-target="${ event.detail.currentElement.dataset.mediaId }"]`); 22 | this.setActiveThumbnail(thumbnail); 23 | } 24 | 25 | setActiveMedia(mediaId, prepend) { 26 | const activeMedia = this.elements.viewer.querySelector(`[data-media-id="${ mediaId }"]`); 27 | this.elements.viewer.querySelectorAll('[data-media-id]').forEach((element) => { 28 | element.classList.remove('is-active'); 29 | }); 30 | activeMedia.classList.add('is-active'); 31 | 32 | if (prepend) { 33 | activeMedia.parentElement.prepend(activeMedia); 34 | if (this.elements.thumbnails) { 35 | const activeThumbnail = this.elements.thumbnails.querySelector(`[data-target="${ mediaId }"]`); 36 | activeThumbnail.parentElement.prepend(activeThumbnail); 37 | } 38 | if (this.elements.viewer.slider) this.elements.viewer.resetPages(); 39 | } 40 | 41 | this.preventStickyHeader(); 42 | window.setTimeout(() => { 43 | if (this.elements.thumbnails) { 44 | activeMedia.parentElement.scrollTo({ left: activeMedia.offsetLeft }); 45 | } 46 | if (!this.elements.thumbnails || this.dataset.desktopLayout === 'stacked') { 47 | activeMedia.scrollIntoView({behavior: 'smooth'}); 48 | } 49 | }); 50 | this.playActiveMedia(activeMedia); 51 | 52 | if (!this.elements.thumbnails) return; 53 | const activeThumbnail = this.elements.thumbnails.querySelector(`[data-target="${ mediaId }"]`); 54 | this.setActiveThumbnail(activeThumbnail); 55 | this.announceLiveRegion(activeMedia, activeThumbnail.dataset.mediaPosition); 56 | } 57 | 58 | setActiveThumbnail(thumbnail) { 59 | if (!this.elements.thumbnails || !thumbnail) return; 60 | 61 | this.elements.thumbnails.querySelectorAll('button').forEach((element) => element.removeAttribute('aria-current')); 62 | thumbnail.querySelector('button').setAttribute('aria-current', true); 63 | if (this.elements.thumbnails.isSlideVisible(thumbnail, 10)) return; 64 | 65 | this.elements.thumbnails.slider.scrollTo({ left: thumbnail.offsetLeft }); 66 | } 67 | 68 | announceLiveRegion(activeItem, position) { 69 | const image = activeItem.querySelector('.product__modal-opener--image img'); 70 | if (!image) return; 71 | image.onload = () => { 72 | this.elements.liveRegion.setAttribute('aria-hidden', false); 73 | this.elements.liveRegion.innerHTML = window.accessibilityStrings.imageAvailable.replace( 74 | '[index]', 75 | position 76 | ); 77 | setTimeout(() => { 78 | this.elements.liveRegion.setAttribute('aria-hidden', true); 79 | }, 2000); 80 | }; 81 | image.src = image.src; 82 | } 83 | 84 | playActiveMedia(activeItem) { 85 | window.pauseAllMedia(); 86 | const deferredMedia = activeItem.querySelector('.deferred-media'); 87 | if (deferredMedia) deferredMedia.loadContent(false); 88 | } 89 | 90 | preventStickyHeader() { 91 | this.stickyHeader = this.stickyHeader || document.querySelector('sticky-header'); 92 | if (!this.stickyHeader) return; 93 | this.stickyHeader.dispatchEvent(new Event('preventHeaderReveal')); 94 | } 95 | 96 | removeListSemantic() { 97 | if (!this.elements.viewer.slider) return; 98 | this.elements.viewer.slider.setAttribute('role', 'presentation'); 99 | this.elements.viewer.sliderItems.forEach(slide => slide.setAttribute('role', 'presentation')); 100 | } 101 | }); 102 | } 103 | -------------------------------------------------------------------------------- /sections/main-blog.liquid: -------------------------------------------------------------------------------- 1 | {{ 'component-article-card.css' | asset_url | stylesheet_tag }} 2 | {{ 'component-card.css' | asset_url | stylesheet_tag }} 3 | {{ 'section-main-blog.css' | asset_url | stylesheet_tag }} 4 | 5 | {%- style -%} 6 | .section-{{ section.id }}-padding { 7 | padding-top: {{ section.settings.padding_top | times: 0.75 | round: 0 }}px; 8 | padding-bottom: {{ section.settings.padding_bottom | times: 0.75 | round: 0 }}px; 9 | } 10 | 11 | @media screen and (min-width: 750px) { 12 | .section-{{ section.id }}-padding { 13 | padding-top: {{ section.settings.padding_top }}px; 14 | padding-bottom: {{ section.settings.padding_bottom }}px; 15 | } 16 | } 17 | {%- endstyle -%} 18 | 19 | {%- paginate blog.articles by 6 -%} 20 |
21 |

{{ blog.title | escape }}

22 | 23 |
24 | {%- for article in blog.articles -%} 25 |
26 | {%- render 'article-card', 27 | article: article, 28 | media_height: section.settings.image_height, 29 | media_aspect_ratio: article.image.aspect_ratio, 30 | show_image: section.settings.show_image, 31 | show_date: section.settings.show_date, 32 | show_author: section.settings.show_author, 33 | show_excerpt: true 34 | -%} 35 |
36 | {%- endfor -%} 37 |
38 | 39 | {%- if paginate.pages > 1 -%} 40 | {%- render 'pagination', paginate: paginate -%} 41 | {%- endif -%} 42 |
43 | {%- endpaginate -%} 44 | 45 | {% schema %} 46 | { 47 | "name": "t:sections.main-blog.name", 48 | "tag": "section", 49 | "class": "section", 50 | "settings": [ 51 | { 52 | "type": "header", 53 | "content": "t:sections.main-blog.settings.header.content" 54 | }, 55 | { 56 | "type": "select", 57 | "id": "layout", 58 | "options": [ 59 | { 60 | "value": "grid", 61 | "label": "t:sections.main-blog.settings.layout.options__1.label" 62 | }, 63 | { 64 | "value": "collage", 65 | "label": "t:sections.main-blog.settings.layout.options__2.label" 66 | } 67 | ], 68 | "default": "collage", 69 | "label": "t:sections.main-blog.settings.layout.label", 70 | "info": "t:sections.main-blog.settings.layout.info" 71 | }, 72 | { 73 | "type": "checkbox", 74 | "id": "show_image", 75 | "default": true, 76 | "label": "t:sections.main-blog.settings.show_image.label" 77 | }, 78 | { 79 | "type": "select", 80 | "id": "image_height", 81 | "options": [ 82 | { 83 | "value": "adapt", 84 | "label": "t:sections.main-blog.settings.image_height.options__1.label" 85 | }, 86 | { 87 | "value": "small", 88 | "label": "t:sections.main-blog.settings.image_height.options__2.label" 89 | }, 90 | { 91 | "value": "medium", 92 | "label": "t:sections.main-blog.settings.image_height.options__3.label" 93 | }, 94 | { 95 | "value": "large", 96 | "label": "t:sections.main-blog.settings.image_height.options__4.label" 97 | } 98 | ], 99 | "default": "medium", 100 | "label": "t:sections.main-blog.settings.image_height.label", 101 | "info": "t:sections.main-blog.settings.image_height.info" 102 | }, 103 | { 104 | "type": "checkbox", 105 | "id": "show_date", 106 | "default": true, 107 | "label": "t:sections.main-blog.settings.show_date.label" 108 | }, 109 | { 110 | "type": "checkbox", 111 | "id": "show_author", 112 | "default": false, 113 | "label": "t:sections.main-blog.settings.show_author.label" 114 | }, 115 | { 116 | "type": "paragraph", 117 | "content": "t:sections.main-blog.settings.paragraph.content" 118 | }, 119 | { 120 | "type": "header", 121 | "content": "t:sections.all.padding.section_padding_heading" 122 | }, 123 | { 124 | "type": "range", 125 | "id": "padding_top", 126 | "min": 0, 127 | "max": 100, 128 | "step": 4, 129 | "unit": "px", 130 | "label": "t:sections.all.padding.padding_top", 131 | "default": 36 132 | }, 133 | { 134 | "type": "range", 135 | "id": "padding_bottom", 136 | "min": 0, 137 | "max": 100, 138 | "step": 4, 139 | "unit": "px", 140 | "label": "t:sections.all.padding.padding_bottom", 141 | "default": 36 142 | } 143 | ] 144 | } 145 | {% endschema %} 146 | -------------------------------------------------------------------------------- /sections/main-list-collections.liquid: -------------------------------------------------------------------------------- 1 | {{ 'component-card.css' | asset_url | stylesheet_tag }} 2 | {{ 'section-collection-list.css' | asset_url | stylesheet_tag }} 3 | 4 |
5 |

{{ section.settings.title | escape }}

6 | {%- liquid 7 | case section.settings.sort 8 | when 'products_high' or 'products_low' 9 | assign collections = collections | sort: 'all_products_count' 10 | when 'date' or 'date_reversed' 11 | assign collections = collections | sort: 'published_at' 12 | endcase 13 | 14 | if section.settings.sort == 'products_high' or section.settings.sort == 'date_reversed' or section.settings.sort == 'alphabetical_reversed' 15 | assign collections = collections | reverse 16 | endif 17 | 18 | assign moduloResult = 28 | modulo: section.settings.columns_desktop 19 | assign paginate_by = 30 20 | if moduloResult == 0 21 | assign paginate_by = 28 22 | endif 23 | -%} 24 | {%- paginate collections by paginate_by -%} 25 | 32 | {% render 'pagination', paginate: paginate %} 33 | {%- endpaginate -%} 34 |
35 | {% schema %} 36 | { 37 | "name": "t:sections.main-list-collections.name", 38 | "class": "section", 39 | "settings": [ 40 | { 41 | "type": "text", 42 | "id": "title", 43 | "label": "t:sections.main-list-collections.settings.title.label", 44 | "default": "Collections" 45 | }, 46 | { 47 | "type": "select", 48 | "id": "sort", 49 | "options": [ 50 | { 51 | "value": "alphabetical", 52 | "label": "t:sections.main-list-collections.settings.sort.options__1.label" 53 | }, 54 | { 55 | "value": "alphabetical_reversed", 56 | "label": "t:sections.main-list-collections.settings.sort.options__2.label" 57 | }, 58 | { 59 | "value": "date_reversed", 60 | "label": "t:sections.main-list-collections.settings.sort.options__3.label" 61 | }, 62 | { 63 | "value": "date", 64 | "label": "t:sections.main-list-collections.settings.sort.options__4.label" 65 | }, 66 | { 67 | "value": "products_high", 68 | "label": "t:sections.main-list-collections.settings.sort.options__5.label" 69 | }, 70 | { 71 | "value": "products_low", 72 | "label": "t:sections.main-list-collections.settings.sort.options__6.label" 73 | } 74 | ], 75 | "default": "alphabetical", 76 | "label": "t:sections.main-list-collections.settings.sort.label" 77 | }, 78 | { 79 | "type": "select", 80 | "id": "image_ratio", 81 | "options": [ 82 | { 83 | "value": "adapt", 84 | "label": "t:sections.main-list-collections.settings.image_ratio.options__1.label" 85 | }, 86 | { 87 | "value": "portrait", 88 | "label": "t:sections.main-list-collections.settings.image_ratio.options__2.label" 89 | }, 90 | { 91 | "value": "square", 92 | "label": "t:sections.main-list-collections.settings.image_ratio.options__3.label" 93 | } 94 | ], 95 | "default": "adapt", 96 | "label": "t:sections.main-list-collections.settings.image_ratio.label", 97 | "info": "t:sections.main-list-collections.settings.image_ratio.info" 98 | }, 99 | { 100 | "type": "range", 101 | "id": "columns_desktop", 102 | "min": 1, 103 | "max": 5, 104 | "step": 1, 105 | "default": 3, 106 | "label": "t:sections.main-list-collections.settings.columns_desktop.label" 107 | }, 108 | { 109 | "type": "header", 110 | "content": "t:sections.main-list-collections.settings.header_mobile.content" 111 | }, 112 | { 113 | "type": "select", 114 | "id": "columns_mobile", 115 | "options": [ 116 | { 117 | "value": "1", 118 | "label": "t:sections.main-list-collections.settings.columns_mobile.options__1.label" 119 | }, 120 | { 121 | "value": "2", 122 | "label": "t:sections.main-list-collections.settings.columns_mobile.options__2.label" 123 | } 124 | ], 125 | "default": "2", 126 | "label": "t:sections.main-list-collections.settings.columns_mobile.label" 127 | } 128 | ] 129 | } 130 | {% endschema %} 131 | -------------------------------------------------------------------------------- /assets/quick-add.css: -------------------------------------------------------------------------------- 1 | .quick-add { 2 | position: relative; 3 | grid-row-start: 4; 4 | margin: 0 0 1rem; 5 | z-index: 1; 6 | } 7 | 8 | .card--card .quick-add { 9 | margin: 0 1.3rem 1rem; 10 | } 11 | 12 | .quick-add-modal { 13 | box-sizing: border-box; 14 | opacity: 0; 15 | position: fixed; 16 | visibility: hidden; 17 | z-index: -1; 18 | margin: 0 auto; 19 | top: 0; 20 | left: 0; 21 | width: 100%; 22 | background: rgba(var(--color-foreground), 0.2); 23 | height: 100%; 24 | } 25 | 26 | .quick-add-modal[open] { 27 | opacity: 1; 28 | visibility: visible; 29 | z-index: 101; 30 | } 31 | 32 | .quick-add-modal__content { 33 | position: absolute; 34 | top: 0; 35 | left: 50%; 36 | transform: translateX(-50%); 37 | margin: 3.2rem auto 0; 38 | width: 100%; 39 | background-color: rgb(var(--color-background)); 40 | overflow: hidden; 41 | max-width: var(--page-width); 42 | width: calc(100% - 3rem); 43 | } 44 | 45 | @media screen and (min-width: 750px) { 46 | .quick-add-modal__content { 47 | margin-top: 10rem; 48 | width: 80%; 49 | max-height: calc(100% - 20rem); 50 | overflow-y: auto; 51 | } 52 | 53 | quick-add-modal .quick-add-modal__toggle { 54 | top: 2rem; 55 | right: 2rem; 56 | } 57 | } 58 | 59 | @media screen and (min-width: 990px) { 60 | .quick-add-modal__content { 61 | width: 70%; 62 | } 63 | } 64 | 65 | .quick-add-modal__content img { 66 | max-width: 100%; 67 | } 68 | 69 | .quick-add-modal__content-info { 70 | padding-right: 4.4rem; 71 | display: flex; 72 | overflow-y: auto; 73 | padding: 2.5rem; 74 | height: 100%; 75 | } 76 | 77 | .quick-add-modal__content-info > * { 78 | height: auto; 79 | margin: 0 auto; 80 | max-width: 100%; 81 | width: 100%; 82 | } 83 | 84 | @media screen and (max-width: 749px) { 85 | quick-add-modal .slider .product__media-item.grid__item { 86 | margin-left: 1.5rem; 87 | margin-right: 1.5rem; 88 | } 89 | 90 | .quick-add-modal__content { 91 | bottom: 3.2rem; 92 | } 93 | 94 | .quick-add-modal__content-info > * { 95 | max-height: 100%; 96 | } 97 | } 98 | 99 | .quick-add-modal__toggle { 100 | background-color: rgb(var(--color-background)); 101 | border: 0.1rem solid rgba(var(--color-foreground), 0.1); 102 | border-radius: 50%; 103 | color: rgba(var(--color-foreground), 0.55); 104 | display: flex; 105 | align-items: center; 106 | justify-content: center; 107 | cursor: pointer; 108 | padding: 1.2rem; 109 | z-index: 5; 110 | width: 4rem; 111 | position: fixed; 112 | top: 1.5rem; 113 | right: 1.5rem; 114 | } 115 | 116 | .quick-add-modal__toggle:hover { 117 | color: rgba(var(--color-foreground), 0.75); 118 | } 119 | 120 | .quick-add-modal__toggle .icon { 121 | height: auto; 122 | margin: 0; 123 | width: 2.2rem; 124 | } 125 | 126 | quick-add-modal .product:not(.featured-product) .product__view-details { 127 | display: block; 128 | } 129 | 130 | quick-add-modal .quick-add-hidden, 131 | quick-add-modal .product__modal-opener:not(.product__modal-opener--image), 132 | quick-add-modal .product__media-item:not(:first-child) { 133 | display: none !important; 134 | } 135 | 136 | quick-add-modal .slider.slider--mobile { 137 | overflow: visible; 138 | } 139 | 140 | quick-add-modal .product__media-list { 141 | margin-bottom: 0; 142 | } 143 | 144 | quick-add-modal .product__media-list .deferred-media { 145 | display: block; 146 | width: 100%; 147 | } 148 | 149 | quick-add-modal .product--thumbnail .product__media-gallery, 150 | quick-add-modal .product--thumbnail_slider .product__media-gallery, 151 | quick-add-modal .product--stacked .product__info-container--sticky { 152 | top: 0; 153 | position: relative; 154 | } 155 | 156 | @media screen and (min-width: 750px) { 157 | quick-add-modal .product:not(.product--no-media) .product__media-wrapper { 158 | max-width: 45%; 159 | width: calc(45% - var(--grid-desktop-horizontal-spacing) / 2); 160 | } 161 | 162 | quick-add-modal .product:not(.product--no-media) .product__info-wrapper { 163 | padding-left: 4rem; 164 | max-width: 54%; 165 | width: calc(54% - var(--grid-desktop-horizontal-spacing) / 2) 166 | } 167 | 168 | quick-add-modal .thumbnail-slider .thumbnail-list.slider--tablet-up { 169 | display: none; 170 | } 171 | } 172 | 173 | quick-add-modal .page-width { 174 | padding: 0; 175 | } 176 | 177 | quick-add-modal .product__title > h1 { 178 | display: none; 179 | } 180 | 181 | quick-add-modal .product__title > a { 182 | display: block; 183 | text-decoration: none; 184 | } 185 | 186 | quick-add-modal .product__title > a:hover { 187 | color: rgb(var(--color-foreground)); 188 | text-decoration: underline; 189 | text-underline-offset: 0.2rem; 190 | text-decoration-thickness: 0.3rem; 191 | } 192 | 193 | quick-add-modal .product-form__buttons { 194 | max-width: initial; 195 | } 196 | 197 | .quick-add__submit { 198 | padding: 0.8rem; 199 | min-width: 100%; 200 | box-sizing: border-box; 201 | } 202 | -------------------------------------------------------------------------------- /assets/component-predictive-search.css: -------------------------------------------------------------------------------- 1 | .predictive-search { 2 | display: none; 3 | position: absolute; 4 | top: calc(100% + 0.1rem); 5 | left: -0.1rem; 6 | border-width: var(--popup-border-width); 7 | border-style: solid; 8 | border-color: rgba(var(--color-foreground), var(--popup-border-opacity)); 9 | background-color: rgb(var(--color-background)); 10 | z-index: 3; 11 | border-bottom-right-radius: var(--popup-corner-radius); 12 | border-bottom-left-radius: var(--popup-corner-radius); 13 | box-shadow: var(--popup-shadow-horizontal-offset) var(--popup-shadow-vertical-offset) var(--popup-shadow-blur-radius) rgba(var(--color-shadow), var(--popup-shadow-opacity)); 14 | } 15 | 16 | .predictive-search--search-template { 17 | z-index: 2; 18 | width: calc(100% + 0.2rem); 19 | } 20 | 21 | @media screen and (max-width: 749px) { 22 | .predictive-search--header { 23 | right: 0; 24 | left: 0; 25 | top: 100%; 26 | } 27 | } 28 | 29 | @media screen and (max-width: 989px) { 30 | .predictive-search { 31 | overflow-y: auto; 32 | -webkit-overflow-scrolling: touch; 33 | 34 | } 35 | } 36 | 37 | @media screen and (min-width: 750px) { 38 | .predictive-search { 39 | border-top: none; 40 | width: calc(100% + 0.2rem); 41 | } 42 | 43 | .header predictive-search { 44 | position: relative; 45 | } 46 | } 47 | 48 | predictive-search[open] .predictive-search, 49 | predictive-search[loading] .predictive-search { 50 | display: block; 51 | } 52 | 53 | .predictive-search__heading { 54 | border-bottom: 0.1rem solid rgba(var(--color-foreground), 0.08); 55 | margin: 0 auto; 56 | padding: 1.5rem 0 0.75rem; 57 | display: flex; 58 | justify-content: space-between; 59 | align-items: center; 60 | width: calc(100% - 4rem); 61 | color: rgba(var(--color-foreground), 0.7); 62 | } 63 | 64 | predictive-search .spinner { 65 | width: 1.5rem; 66 | height: 1.5rem; 67 | line-height: 0; 68 | } 69 | 70 | .predictive-search__heading .spinner { 71 | margin: 0 0.2rem 0 2rem; 72 | } 73 | 74 | predictive-search:not([loading]) .predictive-search__heading .spinner, 75 | predictive-search:not([loading]) .predictive-search__loading-state, 76 | predictive-search:not([loading]) .predictive-search-status__loading { 77 | display: none; 78 | } 79 | 80 | predictive-search[loading] .predictive-search__loading-state { 81 | display: flex; 82 | justify-content: center; 83 | padding: 1rem; 84 | } 85 | 86 | predictive-search[loading] .predictive-search__heading ~ .predictive-search__loading-state, 87 | predictive-search[loading] .predictive-search__results-list:first-child { 88 | display: none; 89 | } 90 | 91 | .predictive-search__list-item:nth-last-child(2) { 92 | border-bottom: 0.1rem solid rgba(var(--color-foreground), 0.08); 93 | } 94 | 95 | .predictive-search__list-item[aria-selected="true"] > *, 96 | .predictive-search__list-item:hover > * { 97 | color: rgb(var(--color-foreground)); 98 | background-color: rgba(var(--color-foreground), 0.04); 99 | } 100 | 101 | .predictive-search__list-item[aria-selected="true"] .predictive-search__item-heading, 102 | .predictive-search__list-item:hover .predictive-search__item-heading { 103 | text-decoration: underline; 104 | text-underline-offset: 0.3rem; 105 | } 106 | 107 | .predictive-search__item { 108 | display: flex; 109 | padding: 1rem 2rem; 110 | text-align: left; 111 | text-decoration: none; 112 | width: 100%; 113 | } 114 | 115 | .predictive-search__item--link { 116 | display: grid; 117 | grid-template-columns: 5rem 1fr; 118 | grid-column-gap: 2rem; 119 | grid-template-areas: 'product-image product-content'; 120 | } 121 | 122 | .predictive-search__item-content { 123 | grid-area: product-content; 124 | display: flex; 125 | flex-direction: column; 126 | } 127 | 128 | .predictive-search__item-content--centered { 129 | justify-content: center; 130 | } 131 | 132 | .predictive-search__item-vendor { 133 | font-size: 0.9rem; 134 | } 135 | 136 | .predictive-search__item-heading { 137 | margin: 0; 138 | } 139 | 140 | .predictive-search__item .price { 141 | color: rgba(var(--color-foreground), 0.7); 142 | font-size: 1.2rem; 143 | } 144 | 145 | .predictive-search__item-vendor + .predictive-search__item-heading, 146 | .predictive-search .price { 147 | margin-top: 0.5rem; 148 | } 149 | 150 | .predictive-search__item--term { 151 | justify-content: space-between; 152 | align-items: center; 153 | padding: 1.3rem 2rem; 154 | word-break: break-all; 155 | line-height: calc(1 + 0.4 / var(--font-body-scale)); 156 | } 157 | 158 | @media screen and (min-width: 750px) { 159 | .predictive-search__item--term { 160 | padding-top: 1rem; 161 | padding-bottom: 1rem; 162 | } 163 | } 164 | 165 | .predictive-search__item--term .icon-arrow { 166 | width: calc(var(--font-heading-scale) * 1.4rem); 167 | height: calc(var(--font-heading-scale) * 1.4rem); 168 | flex-shrink: 0; 169 | margin-left: calc(var(--font-heading-scale) * 2rem); 170 | color: rgb(var(--color-link)); 171 | } 172 | 173 | .predictive-search__image { 174 | grid-area: product-image; 175 | object-fit: contain; 176 | font-family: 'object-fit: contain'; 177 | } 178 | --------------------------------------------------------------------------------