diff --git a/CHANGELOG.md b/CHANGELOG.md index 5009530..3e54893 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ The GitHub release body is a summary, not a copy of the changelog section. Write ## Unreleased +- Added the Image with Text homepage section (`partials/section_image_text.html`, Theme Settings > Homepage > Image with Text, toggle `show_image_text`, off by default). It is a 50/50 image and copy split with image left/right, a square/portrait/landscape/native image ratio, eyebrow, heading, rich-text body, a CTA with primary/secondary/outline styles, and background and text colours; on mobile it stacks image first. It is included from `templates/index.html` between Featured Categories and On Sale. With the toggle on and nothing configured it renders the same setup placeholder pattern as the other sections. `partials/cta_button.html` gained a `secondary` style so the section can reuse the existing `.btn-secondary` class. Spec: `docs/section-specs/image-text.md`. `assets/main.css` grew from 50298 to 50536 bytes for the new ratio and ordering utilities. - Published the app-hook contract in `docs/app-hooks.md`: an inventory of all 13 `{% app_hook %}` sites with the file, page position, surrounding DOM, and whether each renders once per page or once per product card; the `_` naming rule derived from the existing names; and a stability policy (existing hook names are stable, new hooks are additive, renames and removals keep the old hook for at least one minor release). The two locations the platform Tag Reference documents, `global_header` and `global_footer`, are both carried. Linked from `docs/README.md`, `docs/extending-spark.md`, and `CLAUDE.md`; the matching `TODOS.md` entry is closed. - The default for `membership_status_metadata_key` is now the neutral `member_status` in `configs/settings_schema.json`, `layouts/base.html`, and `assets/js/spark-membership-pricing.js`. It previously shipped a store-specific key. A store that enabled membership pricing without setting the key explicitly must now set it in Theme Settings; the migration note in `docs/theme-settings-partials.md` names the old value. - `PLAN.md` now lists all six Web Components (it omitted ``) and states the shipped version as 1.4.1 rather than 1.1.1. diff --git a/CLAUDE.md b/CLAUDE.md index 446c3da..25499bb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -111,7 +111,7 @@ CSS custom properties set in `layouts/base.html` from `store.branding`: Stable `{% app_hook 'NAME' %}` extension surfaces for Apps (Reviews app uses them today). Future Apps should target the same pattern rather than fork the theme. The published contract is `docs/app-hooks.md`: the full inventory with DOM context, the `_` naming rule, and the stability policy (existing names stable, new hooks additive, renames need one minor release of overlap). Update that doc in the same PR as any hook change. ### Settings (`configs/settings_schema.json`) -Typography (fonts, text/heading/link colors), Navigation (main menu, navbar colors), Footer (menu, colors, social links ×8, payment icons, disclaimer), homepage section partials (hero with text overlay, featured products/categories, recommended products, On Sale, Promo Banner, Featured Product — each with its own toggle), Announcement Bar, Advanced (noindex, account-only mode). v1.1 added 22 settings and restructured homepage settings around fixed-order section partials. +Typography (fonts, text/heading/link colors), Navigation (main menu, navbar colors), Footer (menu, colors, social links ×8, payment icons, disclaimer), homepage section partials (hero with text overlay, featured products/categories, recommended products, On Sale, Promo Banner, Featured Product, Image with Text — each with its own toggle), Announcement Bar, Advanced (noindex, account-only mode). v1.1 added 22 settings and restructured homepage settings around fixed-order section partials. ### Architecture Docs - `CONTEXT.md` defines Spark's domain language for architecture reviews. diff --git a/README.md b/README.md index 614ec95..09b57fe 100644 --- a/README.md +++ b/README.md @@ -139,7 +139,7 @@ Tracked theme documentation starts at [docs/README.md](docs/README.md). Current - **Documented extension modules** — `SparkEvents`, `SparkVariantState`, `SparkCartRewards`, and the cart drawer renderer keep extension points explicit for theme developers and apps. - **Cart milestones** — multi-step progress bar with default thresholds for free shipping and free gifts; auto-add/remove driven by progress events. - **Tailwind CSS v4** — standalone CLI binary, no Node dependency. CSS-based config with `@theme`, `@layer base`, and `@layer components`. -- **Homepage section partials (Wave 1 + 1.1.1)** — hero with text overlay, featured products, featured categories, recommended products, On Sale, Promo Banner, Featured Product. Each section partial has its own toggle in Theme Settings and is included from `templates/index.html` in a fixed order. +- **Homepage section partials (Wave 1 + 1.1.1)** — hero with text overlay, featured products, featured categories, recommended products, On Sale, Promo Banner, Featured Product, Image with Text. Each section partial has its own toggle in Theme Settings and is included from `templates/index.html` in a fixed order. - **Sale badges** — automatic on product cards when `compare_at_price > price`. - **Review app hooks** — template surfaces (`{% app_hook %}`) for product cards, PDP rating summary, full reviews module, home/collection review feeds, and global social proof. Apps render into Spark without theme edits. - **Membership price presentation** — optional client-side member price display driven by logged-in customer metadata, designed to pair with platform-side checkout discounts. diff --git a/assets/main.css b/assets/main.css index 883ad58..7c79393 100644 --- a/assets/main.css +++ b/assets/main.css @@ -1,2 +1,2 @@ /*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */ -*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-top:initial;right:initial;bottom:initial;left:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-50:#fef2f2;--color-red-200:#ffc9c9;--color-red-400:#ff6467;--color-red-500:#fb2c36;--color-red-600:#e7000b;--color-red-800:#9f0712;--color-amber-50:#fffbeb;--color-amber-200:#fee685;--color-amber-400:#ffb900;--color-amber-800:#973c00;--color-green-50:#f0fdf4;--color-green-200:#b9f8cf;--color-green-600:#00a63e;--color-green-800:#016630;--color-blue-50:#eff6ff;--color-blue-200:#bedbff;--color-blue-800:#193cb8;--color-slate-50:#f8fafc;--color-slate-100:#f1f5f9;--color-slate-200:#e2e8f0;--color-slate-300:#cbd5e1;--color-slate-400:#94a3b8;--color-slate-500:#64748b;--color-slate-600:#475569;--color-slate-700:#334155;--color-slate-800:#1e293b;--color-slate-900:#0f172a;--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--text-6xl:3.75rem;--text-6xl--line-height:1;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-wider:.05em;--leading-tight:1.25;--leading-relaxed:1.625;--radius-md:.375rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--radius-card:var(--card-radius,0);--spacing-section-y:var(--section-padding-y,3rem);--spacing-section-y-md:calc(var(--section-padding-y,3rem) * 4 / 3);--spacing-band-y:calc(var(--section-padding-y,3rem) * 4 / 3);--spacing-band-y-md:calc(var(--section-padding-y,3rem) * 5 / 3);--spacing-content-md:calc(var(--content-gap,1.5rem) * 4 / 3);--spacing-content-lg:calc(var(--content-gap,1.5rem) * 2);--text-h3:calc(1.25rem * var(--heading-scale,1));--text-h3--line-height:calc(1.75 / 1.25);--text-h2:calc(1.5rem * var(--heading-scale,1));--text-h2--line-height:calc(2 / 1.5);--text-h1:calc(1.875rem * var(--heading-scale,1));--text-h1--line-height:calc(2.25 / 1.875);--text-h1-md:calc(2.25rem * var(--heading-scale,1));--text-h1-md--line-height:calc(2.5 / 2.25);--text-display:calc(1.875rem * var(--heading-scale,1));--text-display--line-height:calc(2.25 / 1.875);--text-display-md:calc(3rem * var(--heading-scale,1));--text-display-md--line-height:1}*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}select[multiple],[size] optgroup{font-weight:bolder}select[multiple],[size] optgroup option{padding-left:20px}::file-selector-button{margin-right:4px}::placeholder{opacity:1}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-year-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-month-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-day-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-hour-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-minute-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-second-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-millisecond-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-meridiem-field{padding-top:0;padding-bottom:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input[type=button],[type=reset],[type=submit]{appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:not([hidden=until-found]){display:none!important}:root{--primary-color:#1e293b;--accent-color:#475569}body{font-family:var(--font-sans);font-size:var(--body-size,1rem);color:#1e293b;background-color:var(--body-bg-color,#fff);line-height:1.6}h1,h2,h3,h4,h5,h6{color:#1e293b;font-weight:600;line-height:1.2}a{color:var(--primary-color);text-decoration:none}a:hover{opacity:.8}img{max-width:100%;height:auto}.btn{border-radius:var(--control-radius,.25rem);cursor:pointer;justify-content:center;align-items:center;padding:.625rem 1.5rem;font-size:.875rem;font-weight:500;line-height:1.25rem;transition:opacity .15s ease-out;display:inline-flex}.btn:hover{opacity:.9}.btn:disabled{opacity:.5;cursor:not-allowed}.btn-primary{background-color:var(--primary-color)!important;color:#fff!important;border-color:var(--primary-color)!important}.btn-accent{background-color:var(--accent-color)!important;color:#fff!important;border-color:var(--accent-color)!important}.btn-outline{color:var(--btn-color,var(--primary-color))!important;border:1px solid var(--btn-color,var(--primary-color))!important;background-color:#0000!important}.btn-secondary{color:var(--primary-color);border:1px solid var(--border-color,#e2e8f0);background-color:#0000}.btn-secondary:hover{background-color:#f8fafc}.container{width:100%;max-width:var(--container-max,1280px);margin-left:auto;margin-right:auto;padding-left:1rem;padding-right:1rem}@media (min-width:768px){.container{padding-left:1.5rem;padding-right:1.5rem}}.product-card{border-radius:var(--card-radius,0);flex-direction:column;display:flex;overflow:hidden}.product-card-bordered{border:1px solid var(--border-color,#e2e8f0)}.product-card-bordered .product-title{padding-left:1rem;padding-right:1rem}.product-card-bordered .product-price{padding-bottom:1rem;padding-left:1rem;padding-right:1rem}.product-card img{aspect-ratio:1;object-fit:cover;background-color:#f8fafc}.product-card .product-title{margin-top:.75rem;font-size:.875rem;font-weight:500}.product-card .product-price{color:#475569;margin-top:.25rem;font-size:.875rem}.product-card-sold-out-badge{color:#fff;background-color:#475569;padding:.125rem .5rem;font-size:.75rem;font-weight:500;line-height:1.25rem;position:absolute;top:0;left:0}.product-card-sold-out img,.product-card-sold-out .product-title,.product-card-sold-out .product-price{opacity:.5}[data-spark-membership-price][data-membership-active=true] [data-spark-public-price]{color:#94a3b8;font-weight:400;text-decoration-line:line-through}.spark-member-price{color:#1e293b;flex-wrap:wrap;align-items:baseline;gap:.375rem;margin-top:.25rem;display:flex}.spark-member-price-label{color:var(--primary-color);text-transform:uppercase;font-size:.75rem;font-weight:600}.spark-member-price-value{font-weight:700}.spark-member-price-detail{color:#64748b;font-size:.75rem;font-weight:400}.product-card .spark-member-price,[data-spark-membership-layout=sticky] .spark-member-price{gap:.25rem;margin-top:.125rem}.product-card .spark-member-price-label,[data-spark-membership-layout=sticky] .spark-member-price-label{font-size:.6875rem}[data-spark-membership-layout=sticky][data-membership-active=true]{line-height:1.25;display:block}.product-grid{gap:var(--content-gap,1.5rem);grid-template-columns:repeat(1,1fr);display:grid}@media (min-width:768px){.product-grid{grid-template-columns:repeat(2,1fr)}}@media (min-width:1024px){.product-grid{grid-template-columns:repeat(var(--product-grid-columns,3), 1fr)}}.category-grid{gap:calc(var(--content-gap,1.5rem) * 2 / 3);grid-template-columns:repeat(1,1fr);display:grid}@media (min-width:768px){.category-grid{grid-template-columns:repeat(var(--category-grid-columns,2), 1fr)}}.skeleton-card{flex-direction:column;display:flex}.skeleton-card .skeleton-image{aspect-ratio:1;background-color:#f1f5f9;position:relative;overflow:hidden}.skeleton-card .skeleton-image:after{content:"";background:linear-gradient(90deg,#f1f5f9,#e2e8f0,#f1f5f9);animation:1.5s ease-in-out infinite shimmer;position:absolute;top:0;right:0;bottom:0;left:0}.skeleton-card .skeleton-text{background-color:#f1f5f9;height:12px;margin-top:.75rem;position:relative;overflow:hidden}.skeleton-card .skeleton-text:after{content:"";background:linear-gradient(90deg,#f1f5f9,#e2e8f0,#f1f5f9);animation:1.5s ease-in-out infinite shimmer;position:absolute;top:0;right:0;bottom:0;left:0}.skeleton-card .skeleton-text-short{background-color:#f1f5f9;width:40%;height:12px;margin-top:.25rem;position:relative;overflow:hidden}.skeleton-card .skeleton-text-short:after{content:"";background:linear-gradient(90deg,#f1f5f9,#e2e8f0,#f1f5f9);animation:1.5s ease-in-out infinite shimmer;position:absolute;top:0;right:0;bottom:0;left:0}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.cart-badge{background-color:var(--primary-color);color:#fff;text-align:center;pointer-events:none;border-radius:50%;width:16px;height:16px;font-size:10px;font-weight:600;line-height:16px;position:absolute;top:-4px;right:-4px}[data-light-primary] .cart-badge{color:#1e293b}.cart-badge[data-animate]{animation:.3s ease-out badge-pulse}@keyframes badge-pulse{0%{transform:scale(1)}50%{transform:scale(1.3)}to{transform:scale(1)}}.spark-gallery{flex-direction:column;gap:.75rem;display:flex}@media (min-width:768px){.spark-gallery-left{flex-direction:row-reverse;gap:.75rem}.spark-gallery-left .spark-gallery-main{flex:1;min-width:0}.spark-gallery-left .spark-gallery-thumbs{flex-direction:column;justify-content:flex-start;width:72px;max-height:520px;overflow:hidden auto}.spark-gallery-left .spark-gallery-thumb{flex-shrink:0;width:72px;height:72px}}.spark-gallery-main{aspect-ratio:1;background-color:#f8fafc;max-height:560px;position:relative;overflow:hidden}.spark-gallery-hero{object-fit:contain;width:100%;height:100%;transition:opacity .2s ease-out}.spark-gallery-hero.spark-gallery-fading{opacity:0}.spark-gallery-thumbs{scrollbar-width:thin;scrollbar-color:#cbd5e1 transparent;justify-content:center;gap:.5rem;padding:.25rem 0;display:flex;overflow:auto hidden}.spark-gallery-thumb{cursor:pointer;opacity:.6;background:#f8fafc;border:2px solid #0000;flex-shrink:0;width:72px;height:72px;padding:0;transition:border-color .2s ease-out,opacity .2s ease-out;overflow:hidden}.spark-gallery-thumb:hover{opacity:1;border-color:#cbd5e1}.spark-gallery-thumb-active{opacity:1!important;border-color:var(--primary-color)!important}.spark-gallery-prev,.spark-gallery-next{cursor:pointer;color:#475569;opacity:0;z-index:2;background:#ffffffe6;border:none;border-radius:50%;justify-content:center;align-items:center;width:36px;height:36px;transition:opacity .2s ease-out,background-color .15s ease-out;display:flex;position:absolute;top:50%;transform:translateY(-50%);box-shadow:0 1px 3px #0000001a}.spark-gallery-prev{left:.75rem}.spark-gallery-next{right:.75rem}.spark-gallery-prev:hover,.spark-gallery-next:hover{color:#1e293b;background:#fff}.spark-gallery:hover .spark-gallery-prev,.spark-gallery:hover .spark-gallery-next,.spark-gallery:focus-within .spark-gallery-prev,.spark-gallery:focus-within .spark-gallery-next{opacity:1}@media (hover:none){.spark-gallery-prev,.spark-gallery-next{opacity:.7}}.sticky-atc{z-index:50;background:#fff;border-top:1px solid #e2e8f0;transition:transform .25s ease-out;position:fixed;bottom:0;left:0;right:0;transform:translateY(100%);box-shadow:0 -2px 8px #0000000f}.sticky-atc-visible{transform:translateY(0)}.sticky-atc-inner{justify-content:space-between;align-items:center;gap:1rem;max-width:1280px;margin:0 auto;padding:.75rem 1rem;display:flex}.sticky-atc-info{flex-direction:column;min-width:0;display:flex}.sticky-atc-title{color:#1e293b;white-space:nowrap;text-overflow:ellipsis;font-size:.875rem;font-weight:500;overflow:hidden}.sticky-atc-price{color:#475569;font-size:.875rem}.sticky-atc-btn{white-space:nowrap;flex-shrink:0;padding:.625rem 1.5rem}@media (min-width:1024px){.sticky-atc{display:none}}.search-overlay{z-index:60;opacity:0;visibility:hidden;justify-content:center;align-items:flex-start;transition:opacity .2s ease-out,visibility .2s ease-out;display:flex;position:fixed;top:0;right:0;bottom:0;left:0}.search-overlay-visible{opacity:1;visibility:visible}.search-overlay-backdrop{background:#0006;position:absolute;top:0;right:0;bottom:0;left:0}.search-overlay-content{z-index:1;width:100%;max-width:640px;margin-top:5rem;padding:0 1rem;transition:transform .2s ease-out;position:relative;transform:translateY(-12px)}.search-overlay-visible .search-overlay-content{transform:translateY(0)}.search-overlay-form{background:#fff;border:1px solid #e2e8f0;align-items:center;display:flex;box-shadow:0 8px 30px #0000001f}.search-overlay-input{color:#1e293b;background:0 0;border:none;outline:none;flex:1;padding:1rem 1.25rem;font-size:1rem}.search-overlay-input::placeholder{color:#94a3b8}.search-overlay-submit{color:#475569;cursor:pointer;background:0 0;border:none;padding:.75rem}.search-overlay-submit:hover{color:#1e293b}.search-overlay-close{color:#94a3b8;cursor:pointer;background:0 0;border:none;padding:.75rem}.search-overlay-close:hover{color:#475569}.sr-only,.skip-to-content{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.skip-to-content:focus{z-index:100;clip:auto;width:auto;height:auto;font-family:var(--font-sans);background-color:#1e293b;border:1px solid #1e293b;border-radius:2px;margin:0;padding:.625rem 1rem;font-size:.875rem;font-weight:500;line-height:1.25rem;top:1rem;left:1rem;overflow:visible;color:#fff!important}@media (min-width:1024px){.catalogue-layout{grid-template-columns:15rem minmax(0,1fr);align-items:start;gap:2rem;display:grid}}.catalogue-rail{display:none}@media (min-width:1024px){.catalogue-rail{display:block;position:sticky;top:5.5rem}}.catalogue-filter-inline{margin-bottom:1.5rem;display:flex}@media (min-width:1024px){.catalogue-filter-inline{display:none}}.catalogue-filter-button{color:#1e293b;cursor:pointer;background:#fff;border:1px solid #e2e8f0;border-radius:.25rem;justify-content:center;align-items:center;gap:.5rem;width:100%;min-height:44px;padding:.625rem 1rem;font-family:inherit;font-size:.875rem;font-weight:500;line-height:1.25rem;display:inline-flex}.catalogue-bar{z-index:50;visibility:hidden;pointer-events:none;background:#fff;border-top:1px solid #e2e8f0;transition:transform .25s ease-in,visibility 0s linear .25s;position:fixed;bottom:0;left:0;right:0;transform:translateY(100%)}.catalogue-bar-visible{visibility:visible;pointer-events:auto;transition:transform .25s ease-out;transform:translateY(0)}.catalogue-bar-inner{align-items:stretch;gap:.75rem;max-width:1280px;margin:0 auto;padding:.75rem 1rem;display:flex}.catalogue-bar-control{flex:1 1 0;min-width:0}.catalogue-bar-count{background:var(--primary-color);color:#fff;border-radius:9999px;justify-content:center;align-items:center;min-width:1.25rem;height:1.25rem;padding:0 .25rem;font-size:10px;font-weight:600;line-height:1;display:inline-flex}@media (min-width:1024px){.catalogue-bar{display:none}}.filter-drawer{z-index:60;visibility:hidden;pointer-events:none;position:fixed;top:0;right:0;bottom:0;left:0}.filter-drawer-visible{visibility:visible;pointer-events:auto}.filter-drawer-backdrop{opacity:0;background:#0000004d;transition:opacity .2s ease-out;position:absolute;top:0;right:0;bottom:0;left:0}.filter-drawer-visible .filter-drawer-backdrop{opacity:1}.filter-drawer-panel{background:#fff;border-top:1px solid #e2e8f0;flex-direction:column;max-height:85vh;transition:transform .25s ease-out;display:flex;position:absolute;bottom:0;left:0;right:0;transform:translateY(100%)}.filter-drawer-visible .filter-drawer-panel{transform:translateY(0)}.filter-drawer-header{border-bottom:1px solid #e2e8f0;justify-content:space-between;align-items:center;gap:1rem;padding:.75rem 1rem;display:flex}.filter-drawer-title{color:#1e293b;font-size:.875rem;font-weight:600}.filter-drawer-close{color:#475569;cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;width:44px;height:44px;margin-right:-.75rem;display:inline-flex}.filter-drawer-body{padding:1rem;overflow-y:auto}@media (min-width:1024px){.filter-drawer{display:none}}:focus-visible{outline:2px solid var(--primary-color);outline-offset:2px}@media print{header,footer,#announcement-bar,.sidecart,.breadcrumb,nav[aria-label=breadcrumb]{display:none!important}.container{max-width:100%;padding:0}body{color:#000;background:#fff;font-size:12pt}a{color:#000;text-decoration:underline}img{max-width:100%}.product-grid{grid-template-columns:repeat(2,1fr)}}.sidecart-open{overflow:hidden}.sidecart-open .sidecart{overflow-x:hidden}.sidecart{outline:0;font-family:inherit;position:absolute;top:0;overflow:hidden}.sidecart .sidecart-dialog{width:100vw;transition:all .6s cubic-bezier(.75,0,.55,1);right:-100vw}.sidecart.show .sidecart-dialog{transition:all .6s cubic-bezier(.33,0,0,1);right:0}.sidecart .cart-btn{color:#1e293b;cursor:pointer;text-align:center;white-space:nowrap;-webkit-user-select:none;user-select:none;background-color:#e2e8f0;border:1px solid #0000;justify-content:center;padding:.8rem 1rem;transition:background-color .15s ease-out}.sidecart .cart-btn:hover{background-color:#cbd5e1;border:1px solid #0000}.sidecart .cart-btn:focus:not(:active){box-shadow:0 0 0 2px var(--primary-color)}.sidecart .text-right{text-align:right}.sidecart .text-center{text-align:center}.sidecart .error-text{color:#ef4444;font-size:small}.sidecart a{color:#1e293b}.sidecart a:hover{color:#475569}.sidecart button{-webkit-appearance:none;cursor:pointer;background-color:#0000;border:0;padding:0;font-family:inherit}.sidecart button.close{color:#475569;float:right;font-weight:400;line-height:.5;transition:color .15s ease-out}.sidecart button.close:hover{color:#1e293b}.sidecart-dialog{pointer-events:none;z-index:99999;height:100%;margin:auto;position:fixed}.sidecart-content{pointer-events:auto;background-color:#fff;background-clip:padding-box;border:none;border-radius:0;outline:0;flex-direction:column;height:100%;display:flex;position:relative;overflow-y:auto;box-shadow:0 0 1px 1px #8890c333}.sidecart-header{background-color:#fff;border-bottom:none;justify-content:center;align-items:center;height:60px;padding:1rem;display:flex;position:relative}.sidecart-header button.close{color:#475569;font-size:2rem;position:absolute;right:1rem}.sidecart-header button.close:hover{color:#1e293b}.sidecart-title{text-align:center;margin-bottom:0;font-weight:700}#basket-content-div{overflow-y:auto}.sidecart-body{position:inherit;flex:auto;padding:.5rem .5rem 6rem;overflow-y:auto}.sidecart-footer{background-color:#fff;border-top:1px solid #e2e8f0;width:auto;padding:1rem;display:flex;bottom:0}.sidecart-footer .cart-btn{text-align:center;cursor:pointer;border:1px solid #0000;border-radius:.3rem;width:100%;height:auto;padding:1.25rem;font-size:24px;font-weight:700;text-decoration:none;display:inline-block;background-color:var(--primary-color)!important;color:#fff!important}.sidecart-footer .cart-btn:hover{border:1px solid #0000;background-color:var(--primary-color-darker)!important;color:#fff!important}.sidecart .form-control{color:#1e293b;appearance:none;background-color:#fff;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23475569' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");background-position:right .5rem center;background-repeat:no-repeat;background-size:14px 10px;border:1px solid #e2e8f0;border-radius:.25rem;width:100%;padding:.25rem 2rem .25rem .5rem;font-size:.875rem;line-height:1.5;display:block}.cart-items{margin:0 0 20px}.cart-item{box-shadow:none;border-bottom:1px solid #e2e8f0;flex-flow:row;justify-content:flex-start;margin:0 0 .75rem;padding:.75rem;display:flex}.cart-item:first-child{border-top:1px solid #e2e8f0}.cart-item img{width:100%}.cart-item .item-img{width:110px;margin-right:5%;padding:5px}.cart-item .item-details{width:100%;padding-top:.5rem}.cart-item .item-title{margin-bottom:.5rem;font-family:inherit;font-size:1rem;font-weight:500;line-height:1.2;display:block}.cart-item .item-description{flex-flow:wrap;align-items:center;width:100%;margin:0 0 .5em;display:flex}.cart-item .item-description .basket-action{flex-direction:column;flex:40%;height:fit-content;margin-right:20px;display:flex}.cart-item .item-description .basket-action:last-child{margin-right:0}.cart-item .item-description label{margin-bottom:0;display:inline-block}.cart-item .item-description button.close{font-size:smaller}.cart-item .item-price{width:100%}.cart-item .close{font-size:1.5rem}table.sidecart-table{background-color:#0000;width:100%}table.sidecart-table td{vertical-align:top;border-top:1px solid #e2e8f0;padding:.75rem}table.sidecart-table tr:first-child td{border-top:none}table.sidecart-table.table-sm td{padding:.15rem;font-size:small}.cart-totals{font-size:initial}.cart-coupon-wrapper{padding:.75rem}.cart-coupon-wrapper h5{font-family:inherit;font-size:1em}.cart-coupon-wrapper table{width:100%}.cart-coupon-wrapper td:first-child{width:75%}.cart-coupon-wrapper .form-input-group .btn{padding:.75em;font-size:1.125em}.cart-coupon{margin:5% 0}.coupon-remove{font-size:1.5em}.coupon-form{margin:20px 0}.coupon-form .form-input-group{flex-wrap:wrap;width:auto;display:flex}.coupon-form .form-input-group input{background-color:#fff;border:1px solid #e2e8f0;flex:75%;padding:.8rem 1rem}.coupon-form .form-input-group .cart-btn{text-align:center;white-space:nowrap;flex:1;margin-top:10px}.coupon-code{font-size:initial;text-align:center;white-space:nowrap;vertical-align:baseline;color:#fff;background-color:#22c55e;padding:.1em .5em;font-weight:700;line-height:1}.loader{margin:25% 0}.loader .loading{text-align:center;margin:30px;padding:25px}.loader .loading:before{content:"";border-style:solid;border-width:4px;border-color:var(--primary-color) #eee #eee;border-radius:100%;width:50px;height:50px;margin:-25px auto auto -25px;animation:.7s linear infinite rotation;position:absolute;left:50%}@keyframes rotation{0%{transform:rotate(0)}to{transform:rotate(359deg)}}.cart-empty{margin:25% 0}@media (min-width:768px) and (max-width:991.98px){.sidecart .sidecart-dialog{width:60vw}.sidecart-body{padding:1rem 1rem 6rem}.coupon-form .form-input-group input{flex:50%}.coupon-form .form-input-group .cart-btn{margin-top:0}}@media (min-width:992px){.sidecart .sidecart-dialog{width:50vw}.sidecart-body{padding:1rem 2rem 6rem}.coupon-form .form-input-group input{flex:50%}.coupon-form .form-input-group .cart-btn{margin-top:0}}@media (min-width:1200px){.sidecart .sidecart-dialog{width:45vw}}@media (min-width:1400px){.sidecart .sidecart-dialog{width:40vw}}@media (min-width:1600px){.sidecart .sidecart-dialog{width:35vw}}@media (max-width:576px){.cart-coupon-wrapper .form-input-group .btn{padding:.9em}}.cart-popover-wrapper{display:inline-block;position:relative}.cart-popover-wrapper .popover-content{opacity:0;visibility:hidden;background-color:#fff;width:auto;padding:.5rem;position:absolute;top:50px;left:-130px;transform:translateY(10px);box-shadow:0 2px 5px #00000042}.cart-popover-wrapper .popover-content p{margin-bottom:.5rem}.cart-popover-wrapper .popover-content table.popover-table{margin-top:.75em;margin-bottom:.75em;font-size:.875rem}.cart-popover-wrapper .popover-content table.popover-table tr:first-child td{border-top:none}.cart-popover-wrapper .popover-content table.popover-table tr:first-child td,.cart-popover-wrapper .popover-content table.popover-table tr:last-child td,.cart-popover-wrapper .popover-content table.popover-table tr:nth-last-child(2){font-weight:600}.cart-popover-wrapper .popover-content table.popover-table td{border-top:1px solid #dee2e6;padding:.375rem}.cart-popover-wrapper:hover .popover-content{z-index:10;opacity:1;visibility:visible;width:max-content;transition:all .5s cubic-bezier(.75,-.02,.2,.97);transform:translateY(-20px)}.cart-popover-wrapper .help-icon{cursor:pointer;vertical-align:middle;background-image:url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='18px' height='18px' fill='%23606975' viewBox='0 0 24 24' style='enable-background:new 0 0 24 24;' xml:space='preserve'%3E%3Cg id='' style='opacity:0.75;'%3E%3Cg id='help'%3E%3Cpath id='circle' style='fill-rule:evenodd;clip-rule:evenodd;' d='M12.001,2.085c-5.478,0-9.916,4.438-9.916,9.916 c0,5.476,4.438,9.914,9.916,9.914c5.476,0,9.914-4.438,9.914-9.914C21.915,6.523,17.477,2.085,12.001,2.085z M12.002,20.085 c-4.465,0-8.084-3.619-8.084-8.083c0-4.465,3.619-8.084,8.084-8.084c4.464,0,8.083,3.619,8.083,8.084 C20.085,16.466,16.466,20.085,12.002,20.085z' /%3E%3Cg id='question_mark'%3E%3Cpath id='top' style='fill-rule:evenodd;clip-rule:evenodd;' d='M11.766,6.688c-2.5,0-3.219,2.188-3.219,2.188l1.411,0.854 c0,0,0.298-0.791,0.901-1.229c0.516-0.375,1.625-0.625,2.219,0.125c0.701,0.885-0.17,1.587-1.078,2.719 C11.047,12.531,11,15,11,15h1.969c0,0,0.135-2.318,1.041-3.381c0.603-0.707,1.443-1.338,1.443-2.494S14.266,6.688,11.766,6.688z' /%3E%3Crect id='bottom' x='11' y='16' style='fill-rule:evenodd;clip-rule:evenodd;' width='2' height='2' /%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/svg%3E");background-repeat:no-repeat;width:20px;height:20px;display:inline-block}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{top:calc(var(--spacing) * 0);right:calc(var(--spacing) * 0);bottom:calc(var(--spacing) * 0);left:calc(var(--spacing) * 0)}.end{right:var(--spacing)}.top-0{top:calc(var(--spacing) * 0)}.top-full{top:100%}.bottom-0{bottom:calc(var(--spacing) * 0)}.bottom-2{bottom:calc(var(--spacing) * 2)}.left-0{left:calc(var(--spacing) * 0)}.left-1\/2{left:50%}.z-50{z-index:50}.order-1{order:1}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mx-4{margin-left:calc(var(--spacing) * 4);margin-right:calc(var(--spacing) * 4)}.mx-auto{margin-left:auto;margin-right:auto}.my-8{margin-top:calc(var(--spacing) * 8);margin-bottom:calc(var(--spacing) * 8)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-10{margin-top:calc(var(--spacing) * 10)}.mt-12{margin-top:calc(var(--spacing) * 12)}.mt-16{margin-top:calc(var(--spacing) * 16)}.mt-auto{margin-top:auto}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.mb-8{margin-bottom:calc(var(--spacing) * 8)}.mb-10{margin-bottom:calc(var(--spacing) * 10)}.-ml-2{margin-left:calc(var(--spacing) * -2)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-10{margin-left:calc(var(--spacing) * 10)}.ml-auto{margin-left:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.aspect-square{aspect-ratio:1}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-3{height:calc(var(--spacing) * 3)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-8{height:calc(var(--spacing) * 8)}.h-10{height:calc(var(--spacing) * 10)}.h-16{height:calc(var(--spacing) * 16)}.h-20{height:calc(var(--spacing) * 20)}.h-28{height:calc(var(--spacing) * 28)}.h-48{height:calc(var(--spacing) * 48)}.h-\[50vh\]{height:50vh}.h-\[65vh\]{height:65vh}.h-full{height:100%}.h-screen{height:100vh}.max-h-16{max-height:calc(var(--spacing) * 16)}.max-h-20{max-height:calc(var(--spacing) * 20)}.max-h-80{max-height:calc(var(--spacing) * 80)}.min-h-\[44px\]{min-height:44px}.min-h-\[70vh\]{min-height:70vh}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-1\/3{width:33.3333%}.w-2\/3{width:66.6667%}.w-3\/4{width:75%}.w-4\/6{width:66.6667%}.w-5\/6{width:83.3333%}.w-10{width:calc(var(--spacing) * 10)}.w-20{width:calc(var(--spacing) * 20)}.w-28{width:calc(var(--spacing) * 28)}.w-32{width:calc(var(--spacing) * 32)}.w-48{width:calc(var(--spacing) * 48)}.w-52{width:calc(var(--spacing) * 52)}.w-56{width:calc(var(--spacing) * 56)}.w-72{width:calc(var(--spacing) * 72)}.w-auto{width:auto}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.max-w-xl{max-width:var(--container-xl)}.min-w-0{min-width:calc(var(--spacing) * 0)}.flex-1{flex:1}.flex-shrink{flex-shrink:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-pointer{cursor:pointer}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.gap-1{gap:calc(var(--spacing) * 1)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-8{gap:calc(var(--spacing) * 8)}.gap-content-md{gap:var(--spacing-content-md)}.space-y-1>:not(:last-child){--tw-space-y-reverse:0;margin-top:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-bottom:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}.space-y-2>:not(:last-child){--tw-space-y-reverse:0;margin-top:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-bottom:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}.space-y-3>:not(:last-child){--tw-space-y-reverse:0;margin-top:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-bottom:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}.space-y-4>:not(:last-child){--tw-space-y-reverse:0;margin-top:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-bottom:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}.space-y-6>:not(:last-child){--tw-space-y-reverse:0;margin-top:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-bottom:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}.divide-y>:not(:last-child){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}.divide-slate-100>:not(:last-child){border-color:var(--color-slate-100)}.divide-slate-200>:not(:last-child){border-color:var(--color-slate-200)}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-card{border-radius:var(--radius-card)}.rounded-full{border-radius:9999px}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-none{--tw-border-style:none;border-style:none}.border-amber-200{border-color:var(--color-amber-200)}.border-blue-200{border-color:var(--color-blue-200)}.border-green-200{border-color:var(--color-green-200)}.border-red-200{border-color:var(--color-red-200)}.border-slate-100{border-color:var(--color-slate-100)}.border-slate-200{border-color:var(--color-slate-200)}.border-slate-800{border-color:var(--color-slate-800)}.bg-\[var\(--primary-color\)\]{background-color:var(--primary-color)}.bg-amber-50{background-color:var(--color-amber-50)}.bg-black\/30{background-color:#0000004d}.bg-black\/30{background-color:rgba(0,0,0,0.3)}.bg-blue-50{background-color:var(--color-blue-50)}.bg-green-50{background-color:var(--color-green-50)}.bg-red-50{background-color:var(--color-red-50)}.bg-slate-50{background-color:var(--color-slate-50)}.bg-slate-100{background-color:var(--color-slate-100)}.bg-slate-200{background-color:var(--color-slate-200)}.bg-slate-300{background-color:var(--color-slate-300)}.bg-slate-800{background-color:var(--color-slate-800)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.object-cover{object-fit:cover}.p-2{padding:calc(var(--spacing) * 2)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.px-2{padding-left:calc(var(--spacing) * 2);padding-right:calc(var(--spacing) * 2)}.px-3{padding-left:calc(var(--spacing) * 3);padding-right:calc(var(--spacing) * 3)}.px-4{padding-left:calc(var(--spacing) * 4);padding-right:calc(var(--spacing) * 4)}.px-5{padding-left:calc(var(--spacing) * 5);padding-right:calc(var(--spacing) * 5)}.px-6{padding-left:calc(var(--spacing) * 6);padding-right:calc(var(--spacing) * 6)}.px-8{padding-left:calc(var(--spacing) * 8);padding-right:calc(var(--spacing) * 8)}.py-0\.5{padding-top:calc(var(--spacing) * .5);padding-bottom:calc(var(--spacing) * .5)}.py-1{padding-top:calc(var(--spacing) * 1);padding-bottom:calc(var(--spacing) * 1)}.py-2{padding-top:calc(var(--spacing) * 2);padding-bottom:calc(var(--spacing) * 2)}.py-2\.5{padding-top:calc(var(--spacing) * 2.5);padding-bottom:calc(var(--spacing) * 2.5)}.py-3{padding-top:calc(var(--spacing) * 3);padding-bottom:calc(var(--spacing) * 3)}.py-4{padding-top:calc(var(--spacing) * 4);padding-bottom:calc(var(--spacing) * 4)}.py-6{padding-top:calc(var(--spacing) * 6);padding-bottom:calc(var(--spacing) * 6)}.py-8{padding-top:calc(var(--spacing) * 8);padding-bottom:calc(var(--spacing) * 8)}.py-12{padding-top:calc(var(--spacing) * 12);padding-bottom:calc(var(--spacing) * 12)}.py-16{padding-top:calc(var(--spacing) * 16);padding-bottom:calc(var(--spacing) * 16)}.py-20{padding-top:calc(var(--spacing) * 20);padding-bottom:calc(var(--spacing) * 20)}.py-band-y{padding-top:var(--spacing-band-y);padding-bottom:var(--spacing-band-y)}.py-section-y{padding-top:var(--spacing-section-y);padding-bottom:var(--spacing-section-y)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-4{padding-left:calc(var(--spacing) * 4)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-6xl{font-size:var(--text-6xl);line-height:var(--tw-leading,var(--text-6xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-display{font-size:var(--text-display);line-height:var(--tw-leading,var(--text-display--line-height))}.text-h1{font-size:var(--text-h1);line-height:var(--tw-leading,var(--text-h1--line-height))}.text-h2{font-size:var(--text-h2);line-height:var(--tw-leading,var(--text-h2--line-height))}.text-h3{font-size:var(--text-h3);line-height:var(--tw-leading,var(--text-h3--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.text-amber-400{color:var(--color-amber-400)}.text-amber-800{color:var(--color-amber-800)}.text-blue-800{color:var(--color-blue-800)}.text-current{color:currentColor}.text-green-600{color:var(--color-green-600)}.text-green-800{color:var(--color-green-800)}.text-red-400{color:var(--color-red-400)}.text-red-500{color:var(--color-red-500)}.text-red-800{color:var(--color-red-800)}.text-slate-200{color:var(--color-slate-200)}.text-slate-300{color:var(--color-slate-300)}.text-slate-400{color:var(--color-slate-400)}.text-slate-500{color:var(--color-slate-500)}.text-slate-600{color:var(--color-slate-600)}.text-slate-700{color:var(--color-slate-700)}.text-slate-800{color:var(--color-slate-800)}.text-slate-900{color:var(--color-slate-900)}.text-white{color:var(--color-white)}.text-white\/70{color:#ffffffb3}.text-white\/70{color:rgba(255,255,255,0.7)}.uppercase{text-transform:uppercase}.not-italic{font-style:normal}.line-through{text-decoration-line:line-through}.underline{text-decoration-line:underline}.accent-\[var\(--primary-color\)\]{accent-color:var(--primary-color)}.opacity-90{opacity:.9}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-300{--tw-duration:.3s;transition-duration:.3s}.outline-none{--tw-outline-style:none;outline-style:none}@media (hover:hover){.group-hover\:scale-105.group:hover *{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x) var(--tw-scale-y)}.group-hover\:text-slate-600.group:hover *{color:var(--color-slate-600)}}.focus-within\:border-slate-400:focus-within{border-color:var(--color-slate-400)}@media (hover:hover){.hover\:border-slate-400:hover{border-color:var(--color-slate-400)}.hover\:bg-slate-50:hover{background-color:var(--color-slate-50)}.hover\:bg-slate-100:hover{background-color:var(--color-slate-100)}.hover\:bg-slate-200:hover{background-color:var(--color-slate-200)}.hover\:text-red-500:hover{color:var(--color-red-500)}.hover\:text-red-600:hover{color:var(--color-red-600)}.hover\:text-slate-600:hover{color:var(--color-slate-600)}.hover\:text-slate-700:hover{color:var(--color-slate-700)}.hover\:text-slate-800:hover{color:var(--color-slate-800)}.hover\:text-slate-900:hover{color:var(--color-slate-900)}.hover\:text-white:hover{color:var(--color-white)}.hover\:opacity-70:hover{opacity:.7}.hover\:opacity-80:hover{opacity:.8}}@media (min-width:40rem){.sm\:mb-0{margin-bottom:calc(var(--spacing) * 0)}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:justify-between{justify-content:space-between}}@media (min-width:48rem){.md\:absolute{position:absolute}.md\:sticky{position:sticky}.md\:top-24{top:calc(var(--spacing) * 24)}.md\:left-1\/2{left:50%}.md\:order-1{order:1}.md\:order-2{order:2}.md\:order-3{order:3}.md\:order-none{order:0}.md\:col-span-1{grid-column:span 1/span 1}.md\:col-span-2{grid-column:span 2/span 2}.md\:col-span-3{grid-column:span 3/span 3}.md\:mx-8{margin-left:calc(var(--spacing) * 8);margin-right:calc(var(--spacing) * 8)}.md\:ml-auto{margin-left:auto}.md\:block{display:block}.md\:flex{display:flex}.md\:hidden{display:none}.md\:h-64{height:calc(var(--spacing) * 64)}.md\:h-\[70vh\]{height:70vh}.md\:h-\[80vh\]{height:80vh}.md\:-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.md\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:justify-between{justify-content:space-between}.md\:gap-12{gap:calc(var(--spacing) * 12)}.md\:gap-content-lg{gap:var(--spacing-content-lg)}.md\:p-12{padding:calc(var(--spacing) * 12)}.md\:py-12{padding-top:calc(var(--spacing) * 12);padding-bottom:calc(var(--spacing) * 12)}.md\:py-16{padding-top:calc(var(--spacing) * 16);padding-bottom:calc(var(--spacing) * 16)}.md\:py-24{padding-top:calc(var(--spacing) * 24);padding-bottom:calc(var(--spacing) * 24)}.md\:py-32{padding-top:calc(var(--spacing) * 32);padding-bottom:calc(var(--spacing) * 32)}.md\:py-band-y-md{padding-top:var(--spacing-band-y-md);padding-bottom:var(--spacing-band-y-md)}.md\:py-section-y-md{padding-top:var(--spacing-section-y-md);padding-bottom:var(--spacing-section-y-md)}.md\:text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.md\:text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.md\:text-display-md{font-size:var(--text-display-md);line-height:var(--tw-leading,var(--text-display-md--line-height))}.md\:text-h1-md{font-size:var(--text-h1-md);line-height:var(--tw-leading,var(--text-h1-md--line-height))}.md\:text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}}.nav-item{position:relative}.nav-item:hover>.nav-submenu,.nav-item:focus-within>.nav-submenu{opacity:1;pointer-events:auto;transform:scale(1)}.nav-submenu{opacity:0;transform-origin:0 0;pointer-events:none;z-index:80;transition:all .2s ease-out;transform:scale(.98)}.spark-preview-indicator{z-index:100;color:#fff;background:#0f172a;border:1px solid #fff3;border-radius:.75rem;align-items:center;gap:.75rem;max-width:calc(100vw - 2rem);padding:.75rem 1rem;font-size:.875rem;line-height:1.25rem;display:flex;position:fixed;bottom:1rem;right:1rem;box-shadow:0 12px 32px #0f172a47}.spark-preview-indicator__message{font-weight:600}.spark-preview-indicator__exit{color:#0f172a;background:#fff;border-radius:.375rem;padding:.25rem .5rem;font-weight:700;text-decoration:none}.spark-preview-indicator__exit:focus-visible{outline-offset:3px;outline:3px solid #fbbf24}@media (hover:hover){.spark-preview-indicator__exit:hover{color:#0f172a;opacity:1;background:#e2e8f0}}@media not all and (min-width:30rem){.spark-preview-indicator{justify-content:space-between;max-width:none;bottom:.75rem;left:.75rem;right:.75rem}}.variant-option-list{flex-wrap:wrap;gap:.5rem;display:flex}.variant-option{display:inline-flex;position:relative}.variant-option input{opacity:0;cursor:pointer;width:100%;height:100%;margin:0;position:absolute;top:0;right:0;bottom:0;left:0}.variant-option-label{color:#334155;white-space:nowrap;cursor:pointer;background-color:#fff;border:1px solid #e2e8f0;justify-content:center;align-items:center;min-height:44px;padding:0 1.25rem;font-size:.875rem;line-height:1.25rem;transition:border-color .15s ease-out,background-color .15s ease-out,color .15s ease-out;display:inline-flex}.variant-option:hover .variant-option-label{border-color:#94a3b8}.variant-option input:focus-visible+.variant-option-label{outline:2px solid var(--primary-color);outline-offset:2px}.variant-option input:checked+.variant-option-label{background-color:var(--primary-color);border-color:var(--primary-color);color:#fff}[data-light-primary] .variant-option input:checked+.variant-option-label{color:#1e293b}.variant-option[data-variant-unavailable=true] input:not(:checked)+.variant-option-label{opacity:.55;color:#64748b}.variant-option[data-variant-unavailable=true] .variant-option-label:after{content:"";pointer-events:none;background-image:linear-gradient(to top right,#fff0 47.5%,#94a3b8 47.5% 52.5%,#fff0 52.5%);position:absolute;top:0;right:0;bottom:0;left:0}.variant-option input:checked+.variant-option-label:after{background-image:linear-gradient(to top right,#fff0 47.5%,#fff 47.5% 52.5%,#fff0 52.5%)}[data-light-primary] .variant-option input:checked+.variant-option-label:after{background-image:linear-gradient(to top right,#fff0 47.5%,#1e293b 47.5% 52.5%,#fff0 52.5%)}.variant-option-value{color:#0f172a;font-weight:500}.variant-size-guide{color:#475569;text-underline-offset:2px;font-size:.75rem;line-height:1rem;text-decoration:underline} \ No newline at end of file +*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-top:initial;right:initial;bottom:initial;left:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-50:#fef2f2;--color-red-200:#ffc9c9;--color-red-400:#ff6467;--color-red-500:#fb2c36;--color-red-600:#e7000b;--color-red-800:#9f0712;--color-amber-50:#fffbeb;--color-amber-200:#fee685;--color-amber-400:#ffb900;--color-amber-800:#973c00;--color-green-50:#f0fdf4;--color-green-200:#b9f8cf;--color-green-600:#00a63e;--color-green-800:#016630;--color-blue-50:#eff6ff;--color-blue-200:#bedbff;--color-blue-800:#193cb8;--color-slate-50:#f8fafc;--color-slate-100:#f1f5f9;--color-slate-200:#e2e8f0;--color-slate-300:#cbd5e1;--color-slate-400:#94a3b8;--color-slate-500:#64748b;--color-slate-600:#475569;--color-slate-700:#334155;--color-slate-800:#1e293b;--color-slate-900:#0f172a;--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--text-6xl:3.75rem;--text-6xl--line-height:1;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-wide:.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-relaxed:1.625;--radius-md:.375rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--radius-card:var(--card-radius,0);--spacing-section-y:var(--section-padding-y,3rem);--spacing-section-y-md:calc(var(--section-padding-y,3rem) * 4 / 3);--spacing-band-y:calc(var(--section-padding-y,3rem) * 4 / 3);--spacing-band-y-md:calc(var(--section-padding-y,3rem) * 5 / 3);--spacing-content-md:calc(var(--content-gap,1.5rem) * 4 / 3);--spacing-content-lg:calc(var(--content-gap,1.5rem) * 2);--text-h3:calc(1.25rem * var(--heading-scale,1));--text-h3--line-height:calc(1.75 / 1.25);--text-h2:calc(1.5rem * var(--heading-scale,1));--text-h2--line-height:calc(2 / 1.5);--text-h1:calc(1.875rem * var(--heading-scale,1));--text-h1--line-height:calc(2.25 / 1.875);--text-h1-md:calc(2.25rem * var(--heading-scale,1));--text-h1-md--line-height:calc(2.5 / 2.25);--text-display:calc(1.875rem * var(--heading-scale,1));--text-display--line-height:calc(2.25 / 1.875);--text-display-md:calc(3rem * var(--heading-scale,1));--text-display-md--line-height:1}*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}select[multiple],[size] optgroup{font-weight:bolder}select[multiple],[size] optgroup option{padding-left:20px}::file-selector-button{margin-right:4px}::placeholder{opacity:1}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-year-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-month-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-day-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-hour-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-minute-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-second-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-millisecond-field{padding-top:0;padding-bottom:0}::-webkit-datetime-edit-meridiem-field{padding-top:0;padding-bottom:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input[type=button],[type=reset],[type=submit]{appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:not([hidden=until-found]){display:none!important}:root{--primary-color:#1e293b;--accent-color:#475569}body{font-family:var(--font-sans);font-size:var(--body-size,1rem);color:#1e293b;background-color:var(--body-bg-color,#fff);line-height:1.6}h1,h2,h3,h4,h5,h6{color:#1e293b;font-weight:600;line-height:1.2}a{color:var(--primary-color);text-decoration:none}a:hover{opacity:.8}img{max-width:100%;height:auto}.btn{border-radius:var(--control-radius,.25rem);cursor:pointer;justify-content:center;align-items:center;padding:.625rem 1.5rem;font-size:.875rem;font-weight:500;line-height:1.25rem;transition:opacity .15s ease-out;display:inline-flex}.btn:hover{opacity:.9}.btn:disabled{opacity:.5;cursor:not-allowed}.btn-primary{background-color:var(--primary-color)!important;color:#fff!important;border-color:var(--primary-color)!important}.btn-accent{background-color:var(--accent-color)!important;color:#fff!important;border-color:var(--accent-color)!important}.btn-outline{color:var(--btn-color,var(--primary-color))!important;border:1px solid var(--btn-color,var(--primary-color))!important;background-color:#0000!important}.btn-secondary{color:var(--primary-color);border:1px solid var(--border-color,#e2e8f0);background-color:#0000}.btn-secondary:hover{background-color:#f8fafc}.container{width:100%;max-width:var(--container-max,1280px);margin-left:auto;margin-right:auto;padding-left:1rem;padding-right:1rem}@media (min-width:768px){.container{padding-left:1.5rem;padding-right:1.5rem}}.product-card{border-radius:var(--card-radius,0);flex-direction:column;display:flex;overflow:hidden}.product-card-bordered{border:1px solid var(--border-color,#e2e8f0)}.product-card-bordered .product-title{padding-left:1rem;padding-right:1rem}.product-card-bordered .product-price{padding-bottom:1rem;padding-left:1rem;padding-right:1rem}.product-card img{aspect-ratio:1;object-fit:cover;background-color:#f8fafc}.product-card .product-title{margin-top:.75rem;font-size:.875rem;font-weight:500}.product-card .product-price{color:#475569;margin-top:.25rem;font-size:.875rem}.product-card-sold-out-badge{color:#fff;background-color:#475569;padding:.125rem .5rem;font-size:.75rem;font-weight:500;line-height:1.25rem;position:absolute;top:0;left:0}.product-card-sold-out img,.product-card-sold-out .product-title,.product-card-sold-out .product-price{opacity:.5}[data-spark-membership-price][data-membership-active=true] [data-spark-public-price]{color:#94a3b8;font-weight:400;text-decoration-line:line-through}.spark-member-price{color:#1e293b;flex-wrap:wrap;align-items:baseline;gap:.375rem;margin-top:.25rem;display:flex}.spark-member-price-label{color:var(--primary-color);text-transform:uppercase;font-size:.75rem;font-weight:600}.spark-member-price-value{font-weight:700}.spark-member-price-detail{color:#64748b;font-size:.75rem;font-weight:400}.product-card .spark-member-price,[data-spark-membership-layout=sticky] .spark-member-price{gap:.25rem;margin-top:.125rem}.product-card .spark-member-price-label,[data-spark-membership-layout=sticky] .spark-member-price-label{font-size:.6875rem}[data-spark-membership-layout=sticky][data-membership-active=true]{line-height:1.25;display:block}.product-grid{gap:var(--content-gap,1.5rem);grid-template-columns:repeat(1,1fr);display:grid}@media (min-width:768px){.product-grid{grid-template-columns:repeat(2,1fr)}}@media (min-width:1024px){.product-grid{grid-template-columns:repeat(var(--product-grid-columns,3), 1fr)}}.category-grid{gap:calc(var(--content-gap,1.5rem) * 2 / 3);grid-template-columns:repeat(1,1fr);display:grid}@media (min-width:768px){.category-grid{grid-template-columns:repeat(var(--category-grid-columns,2), 1fr)}}.skeleton-card{flex-direction:column;display:flex}.skeleton-card .skeleton-image{aspect-ratio:1;background-color:#f1f5f9;position:relative;overflow:hidden}.skeleton-card .skeleton-image:after{content:"";background:linear-gradient(90deg,#f1f5f9,#e2e8f0,#f1f5f9);animation:1.5s ease-in-out infinite shimmer;position:absolute;top:0;right:0;bottom:0;left:0}.skeleton-card .skeleton-text{background-color:#f1f5f9;height:12px;margin-top:.75rem;position:relative;overflow:hidden}.skeleton-card .skeleton-text:after{content:"";background:linear-gradient(90deg,#f1f5f9,#e2e8f0,#f1f5f9);animation:1.5s ease-in-out infinite shimmer;position:absolute;top:0;right:0;bottom:0;left:0}.skeleton-card .skeleton-text-short{background-color:#f1f5f9;width:40%;height:12px;margin-top:.25rem;position:relative;overflow:hidden}.skeleton-card .skeleton-text-short:after{content:"";background:linear-gradient(90deg,#f1f5f9,#e2e8f0,#f1f5f9);animation:1.5s ease-in-out infinite shimmer;position:absolute;top:0;right:0;bottom:0;left:0}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.cart-badge{background-color:var(--primary-color);color:#fff;text-align:center;pointer-events:none;border-radius:50%;width:16px;height:16px;font-size:10px;font-weight:600;line-height:16px;position:absolute;top:-4px;right:-4px}[data-light-primary] .cart-badge{color:#1e293b}.cart-badge[data-animate]{animation:.3s ease-out badge-pulse}@keyframes badge-pulse{0%{transform:scale(1)}50%{transform:scale(1.3)}to{transform:scale(1)}}.spark-gallery{flex-direction:column;gap:.75rem;display:flex}@media (min-width:768px){.spark-gallery-left{flex-direction:row-reverse;gap:.75rem}.spark-gallery-left .spark-gallery-main{flex:1;min-width:0}.spark-gallery-left .spark-gallery-thumbs{flex-direction:column;justify-content:flex-start;width:72px;max-height:520px;overflow:hidden auto}.spark-gallery-left .spark-gallery-thumb{flex-shrink:0;width:72px;height:72px}}.spark-gallery-main{aspect-ratio:1;background-color:#f8fafc;max-height:560px;position:relative;overflow:hidden}.spark-gallery-hero{object-fit:contain;width:100%;height:100%;transition:opacity .2s ease-out}.spark-gallery-hero.spark-gallery-fading{opacity:0}.spark-gallery-thumbs{scrollbar-width:thin;scrollbar-color:#cbd5e1 transparent;justify-content:center;gap:.5rem;padding:.25rem 0;display:flex;overflow:auto hidden}.spark-gallery-thumb{cursor:pointer;opacity:.6;background:#f8fafc;border:2px solid #0000;flex-shrink:0;width:72px;height:72px;padding:0;transition:border-color .2s ease-out,opacity .2s ease-out;overflow:hidden}.spark-gallery-thumb:hover{opacity:1;border-color:#cbd5e1}.spark-gallery-thumb-active{opacity:1!important;border-color:var(--primary-color)!important}.spark-gallery-prev,.spark-gallery-next{cursor:pointer;color:#475569;opacity:0;z-index:2;background:#ffffffe6;border:none;border-radius:50%;justify-content:center;align-items:center;width:36px;height:36px;transition:opacity .2s ease-out,background-color .15s ease-out;display:flex;position:absolute;top:50%;transform:translateY(-50%);box-shadow:0 1px 3px #0000001a}.spark-gallery-prev{left:.75rem}.spark-gallery-next{right:.75rem}.spark-gallery-prev:hover,.spark-gallery-next:hover{color:#1e293b;background:#fff}.spark-gallery:hover .spark-gallery-prev,.spark-gallery:hover .spark-gallery-next,.spark-gallery:focus-within .spark-gallery-prev,.spark-gallery:focus-within .spark-gallery-next{opacity:1}@media (hover:none){.spark-gallery-prev,.spark-gallery-next{opacity:.7}}.sticky-atc{z-index:50;background:#fff;border-top:1px solid #e2e8f0;transition:transform .25s ease-out;position:fixed;bottom:0;left:0;right:0;transform:translateY(100%);box-shadow:0 -2px 8px #0000000f}.sticky-atc-visible{transform:translateY(0)}.sticky-atc-inner{justify-content:space-between;align-items:center;gap:1rem;max-width:1280px;margin:0 auto;padding:.75rem 1rem;display:flex}.sticky-atc-info{flex-direction:column;min-width:0;display:flex}.sticky-atc-title{color:#1e293b;white-space:nowrap;text-overflow:ellipsis;font-size:.875rem;font-weight:500;overflow:hidden}.sticky-atc-price{color:#475569;font-size:.875rem}.sticky-atc-btn{white-space:nowrap;flex-shrink:0;padding:.625rem 1.5rem}@media (min-width:1024px){.sticky-atc{display:none}}.search-overlay{z-index:60;opacity:0;visibility:hidden;justify-content:center;align-items:flex-start;transition:opacity .2s ease-out,visibility .2s ease-out;display:flex;position:fixed;top:0;right:0;bottom:0;left:0}.search-overlay-visible{opacity:1;visibility:visible}.search-overlay-backdrop{background:#0006;position:absolute;top:0;right:0;bottom:0;left:0}.search-overlay-content{z-index:1;width:100%;max-width:640px;margin-top:5rem;padding:0 1rem;transition:transform .2s ease-out;position:relative;transform:translateY(-12px)}.search-overlay-visible .search-overlay-content{transform:translateY(0)}.search-overlay-form{background:#fff;border:1px solid #e2e8f0;align-items:center;display:flex;box-shadow:0 8px 30px #0000001f}.search-overlay-input{color:#1e293b;background:0 0;border:none;outline:none;flex:1;padding:1rem 1.25rem;font-size:1rem}.search-overlay-input::placeholder{color:#94a3b8}.search-overlay-submit{color:#475569;cursor:pointer;background:0 0;border:none;padding:.75rem}.search-overlay-submit:hover{color:#1e293b}.search-overlay-close{color:#94a3b8;cursor:pointer;background:0 0;border:none;padding:.75rem}.search-overlay-close:hover{color:#475569}.sr-only,.skip-to-content{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.skip-to-content:focus{z-index:100;clip:auto;width:auto;height:auto;font-family:var(--font-sans);background-color:#1e293b;border:1px solid #1e293b;border-radius:2px;margin:0;padding:.625rem 1rem;font-size:.875rem;font-weight:500;line-height:1.25rem;top:1rem;left:1rem;overflow:visible;color:#fff!important}@media (min-width:1024px){.catalogue-layout{grid-template-columns:15rem minmax(0,1fr);align-items:start;gap:2rem;display:grid}}.catalogue-rail{display:none}@media (min-width:1024px){.catalogue-rail{display:block;position:sticky;top:5.5rem}}.catalogue-filter-inline{margin-bottom:1.5rem;display:flex}@media (min-width:1024px){.catalogue-filter-inline{display:none}}.catalogue-filter-button{color:#1e293b;cursor:pointer;background:#fff;border:1px solid #e2e8f0;border-radius:.25rem;justify-content:center;align-items:center;gap:.5rem;width:100%;min-height:44px;padding:.625rem 1rem;font-family:inherit;font-size:.875rem;font-weight:500;line-height:1.25rem;display:inline-flex}.catalogue-bar{z-index:50;visibility:hidden;pointer-events:none;background:#fff;border-top:1px solid #e2e8f0;transition:transform .25s ease-in,visibility 0s linear .25s;position:fixed;bottom:0;left:0;right:0;transform:translateY(100%)}.catalogue-bar-visible{visibility:visible;pointer-events:auto;transition:transform .25s ease-out;transform:translateY(0)}.catalogue-bar-inner{align-items:stretch;gap:.75rem;max-width:1280px;margin:0 auto;padding:.75rem 1rem;display:flex}.catalogue-bar-control{flex:1 1 0;min-width:0}.catalogue-bar-count{background:var(--primary-color);color:#fff;border-radius:9999px;justify-content:center;align-items:center;min-width:1.25rem;height:1.25rem;padding:0 .25rem;font-size:10px;font-weight:600;line-height:1;display:inline-flex}@media (min-width:1024px){.catalogue-bar{display:none}}.filter-drawer{z-index:60;visibility:hidden;pointer-events:none;position:fixed;top:0;right:0;bottom:0;left:0}.filter-drawer-visible{visibility:visible;pointer-events:auto}.filter-drawer-backdrop{opacity:0;background:#0000004d;transition:opacity .2s ease-out;position:absolute;top:0;right:0;bottom:0;left:0}.filter-drawer-visible .filter-drawer-backdrop{opacity:1}.filter-drawer-panel{background:#fff;border-top:1px solid #e2e8f0;flex-direction:column;max-height:85vh;transition:transform .25s ease-out;display:flex;position:absolute;bottom:0;left:0;right:0;transform:translateY(100%)}.filter-drawer-visible .filter-drawer-panel{transform:translateY(0)}.filter-drawer-header{border-bottom:1px solid #e2e8f0;justify-content:space-between;align-items:center;gap:1rem;padding:.75rem 1rem;display:flex}.filter-drawer-title{color:#1e293b;font-size:.875rem;font-weight:600}.filter-drawer-close{color:#475569;cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;width:44px;height:44px;margin-right:-.75rem;display:inline-flex}.filter-drawer-body{padding:1rem;overflow-y:auto}@media (min-width:1024px){.filter-drawer{display:none}}:focus-visible{outline:2px solid var(--primary-color);outline-offset:2px}@media print{header,footer,#announcement-bar,.sidecart,.breadcrumb,nav[aria-label=breadcrumb]{display:none!important}.container{max-width:100%;padding:0}body{color:#000;background:#fff;font-size:12pt}a{color:#000;text-decoration:underline}img{max-width:100%}.product-grid{grid-template-columns:repeat(2,1fr)}}.sidecart-open{overflow:hidden}.sidecart-open .sidecart{overflow-x:hidden}.sidecart{outline:0;font-family:inherit;position:absolute;top:0;overflow:hidden}.sidecart .sidecart-dialog{width:100vw;transition:all .6s cubic-bezier(.75,0,.55,1);right:-100vw}.sidecart.show .sidecart-dialog{transition:all .6s cubic-bezier(.33,0,0,1);right:0}.sidecart .cart-btn{color:#1e293b;cursor:pointer;text-align:center;white-space:nowrap;-webkit-user-select:none;user-select:none;background-color:#e2e8f0;border:1px solid #0000;justify-content:center;padding:.8rem 1rem;transition:background-color .15s ease-out}.sidecart .cart-btn:hover{background-color:#cbd5e1;border:1px solid #0000}.sidecart .cart-btn:focus:not(:active){box-shadow:0 0 0 2px var(--primary-color)}.sidecart .text-right{text-align:right}.sidecart .text-center{text-align:center}.sidecart .error-text{color:#ef4444;font-size:small}.sidecart a{color:#1e293b}.sidecart a:hover{color:#475569}.sidecart button{-webkit-appearance:none;cursor:pointer;background-color:#0000;border:0;padding:0;font-family:inherit}.sidecart button.close{color:#475569;float:right;font-weight:400;line-height:.5;transition:color .15s ease-out}.sidecart button.close:hover{color:#1e293b}.sidecart-dialog{pointer-events:none;z-index:99999;height:100%;margin:auto;position:fixed}.sidecart-content{pointer-events:auto;background-color:#fff;background-clip:padding-box;border:none;border-radius:0;outline:0;flex-direction:column;height:100%;display:flex;position:relative;overflow-y:auto;box-shadow:0 0 1px 1px #8890c333}.sidecart-header{background-color:#fff;border-bottom:none;justify-content:center;align-items:center;height:60px;padding:1rem;display:flex;position:relative}.sidecart-header button.close{color:#475569;font-size:2rem;position:absolute;right:1rem}.sidecart-header button.close:hover{color:#1e293b}.sidecart-title{text-align:center;margin-bottom:0;font-weight:700}#basket-content-div{overflow-y:auto}.sidecart-body{position:inherit;flex:auto;padding:.5rem .5rem 6rem;overflow-y:auto}.sidecart-footer{background-color:#fff;border-top:1px solid #e2e8f0;width:auto;padding:1rem;display:flex;bottom:0}.sidecart-footer .cart-btn{text-align:center;cursor:pointer;border:1px solid #0000;border-radius:.3rem;width:100%;height:auto;padding:1.25rem;font-size:24px;font-weight:700;text-decoration:none;display:inline-block;background-color:var(--primary-color)!important;color:#fff!important}.sidecart-footer .cart-btn:hover{border:1px solid #0000;background-color:var(--primary-color-darker)!important;color:#fff!important}.sidecart .form-control{color:#1e293b;appearance:none;background-color:#fff;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23475569' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");background-position:right .5rem center;background-repeat:no-repeat;background-size:14px 10px;border:1px solid #e2e8f0;border-radius:.25rem;width:100%;padding:.25rem 2rem .25rem .5rem;font-size:.875rem;line-height:1.5;display:block}.cart-items{margin:0 0 20px}.cart-item{box-shadow:none;border-bottom:1px solid #e2e8f0;flex-flow:row;justify-content:flex-start;margin:0 0 .75rem;padding:.75rem;display:flex}.cart-item:first-child{border-top:1px solid #e2e8f0}.cart-item img{width:100%}.cart-item .item-img{width:110px;margin-right:5%;padding:5px}.cart-item .item-details{width:100%;padding-top:.5rem}.cart-item .item-title{margin-bottom:.5rem;font-family:inherit;font-size:1rem;font-weight:500;line-height:1.2;display:block}.cart-item .item-description{flex-flow:wrap;align-items:center;width:100%;margin:0 0 .5em;display:flex}.cart-item .item-description .basket-action{flex-direction:column;flex:40%;height:fit-content;margin-right:20px;display:flex}.cart-item .item-description .basket-action:last-child{margin-right:0}.cart-item .item-description label{margin-bottom:0;display:inline-block}.cart-item .item-description button.close{font-size:smaller}.cart-item .item-price{width:100%}.cart-item .close{font-size:1.5rem}table.sidecart-table{background-color:#0000;width:100%}table.sidecart-table td{vertical-align:top;border-top:1px solid #e2e8f0;padding:.75rem}table.sidecart-table tr:first-child td{border-top:none}table.sidecart-table.table-sm td{padding:.15rem;font-size:small}.cart-totals{font-size:initial}.cart-coupon-wrapper{padding:.75rem}.cart-coupon-wrapper h5{font-family:inherit;font-size:1em}.cart-coupon-wrapper table{width:100%}.cart-coupon-wrapper td:first-child{width:75%}.cart-coupon-wrapper .form-input-group .btn{padding:.75em;font-size:1.125em}.cart-coupon{margin:5% 0}.coupon-remove{font-size:1.5em}.coupon-form{margin:20px 0}.coupon-form .form-input-group{flex-wrap:wrap;width:auto;display:flex}.coupon-form .form-input-group input{background-color:#fff;border:1px solid #e2e8f0;flex:75%;padding:.8rem 1rem}.coupon-form .form-input-group .cart-btn{text-align:center;white-space:nowrap;flex:1;margin-top:10px}.coupon-code{font-size:initial;text-align:center;white-space:nowrap;vertical-align:baseline;color:#fff;background-color:#22c55e;padding:.1em .5em;font-weight:700;line-height:1}.loader{margin:25% 0}.loader .loading{text-align:center;margin:30px;padding:25px}.loader .loading:before{content:"";border-style:solid;border-width:4px;border-color:var(--primary-color) #eee #eee;border-radius:100%;width:50px;height:50px;margin:-25px auto auto -25px;animation:.7s linear infinite rotation;position:absolute;left:50%}@keyframes rotation{0%{transform:rotate(0)}to{transform:rotate(359deg)}}.cart-empty{margin:25% 0}@media (min-width:768px) and (max-width:991.98px){.sidecart .sidecart-dialog{width:60vw}.sidecart-body{padding:1rem 1rem 6rem}.coupon-form .form-input-group input{flex:50%}.coupon-form .form-input-group .cart-btn{margin-top:0}}@media (min-width:992px){.sidecart .sidecart-dialog{width:50vw}.sidecart-body{padding:1rem 2rem 6rem}.coupon-form .form-input-group input{flex:50%}.coupon-form .form-input-group .cart-btn{margin-top:0}}@media (min-width:1200px){.sidecart .sidecart-dialog{width:45vw}}@media (min-width:1400px){.sidecart .sidecart-dialog{width:40vw}}@media (min-width:1600px){.sidecart .sidecart-dialog{width:35vw}}@media (max-width:576px){.cart-coupon-wrapper .form-input-group .btn{padding:.9em}}.cart-popover-wrapper{display:inline-block;position:relative}.cart-popover-wrapper .popover-content{opacity:0;visibility:hidden;background-color:#fff;width:auto;padding:.5rem;position:absolute;top:50px;left:-130px;transform:translateY(10px);box-shadow:0 2px 5px #00000042}.cart-popover-wrapper .popover-content p{margin-bottom:.5rem}.cart-popover-wrapper .popover-content table.popover-table{margin-top:.75em;margin-bottom:.75em;font-size:.875rem}.cart-popover-wrapper .popover-content table.popover-table tr:first-child td{border-top:none}.cart-popover-wrapper .popover-content table.popover-table tr:first-child td,.cart-popover-wrapper .popover-content table.popover-table tr:last-child td,.cart-popover-wrapper .popover-content table.popover-table tr:nth-last-child(2){font-weight:600}.cart-popover-wrapper .popover-content table.popover-table td{border-top:1px solid #dee2e6;padding:.375rem}.cart-popover-wrapper:hover .popover-content{z-index:10;opacity:1;visibility:visible;width:max-content;transition:all .5s cubic-bezier(.75,-.02,.2,.97);transform:translateY(-20px)}.cart-popover-wrapper .help-icon{cursor:pointer;vertical-align:middle;background-image:url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='18px' height='18px' fill='%23606975' viewBox='0 0 24 24' style='enable-background:new 0 0 24 24;' xml:space='preserve'%3E%3Cg id='' style='opacity:0.75;'%3E%3Cg id='help'%3E%3Cpath id='circle' style='fill-rule:evenodd;clip-rule:evenodd;' d='M12.001,2.085c-5.478,0-9.916,4.438-9.916,9.916 c0,5.476,4.438,9.914,9.916,9.914c5.476,0,9.914-4.438,9.914-9.914C21.915,6.523,17.477,2.085,12.001,2.085z M12.002,20.085 c-4.465,0-8.084-3.619-8.084-8.083c0-4.465,3.619-8.084,8.084-8.084c4.464,0,8.083,3.619,8.083,8.084 C20.085,16.466,16.466,20.085,12.002,20.085z' /%3E%3Cg id='question_mark'%3E%3Cpath id='top' style='fill-rule:evenodd;clip-rule:evenodd;' d='M11.766,6.688c-2.5,0-3.219,2.188-3.219,2.188l1.411,0.854 c0,0,0.298-0.791,0.901-1.229c0.516-0.375,1.625-0.625,2.219,0.125c0.701,0.885-0.17,1.587-1.078,2.719 C11.047,12.531,11,15,11,15h1.969c0,0,0.135-2.318,1.041-3.381c0.603-0.707,1.443-1.338,1.443-2.494S14.266,6.688,11.766,6.688z' /%3E%3Crect id='bottom' x='11' y='16' style='fill-rule:evenodd;clip-rule:evenodd;' width='2' height='2' /%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/svg%3E");background-repeat:no-repeat;width:20px;height:20px;display:inline-block}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{top:calc(var(--spacing) * 0);right:calc(var(--spacing) * 0);bottom:calc(var(--spacing) * 0);left:calc(var(--spacing) * 0)}.end{right:var(--spacing)}.top-0{top:calc(var(--spacing) * 0)}.top-full{top:100%}.bottom-0{bottom:calc(var(--spacing) * 0)}.bottom-2{bottom:calc(var(--spacing) * 2)}.left-0{left:calc(var(--spacing) * 0)}.left-1\/2{left:50%}.z-50{z-index:50}.order-1{order:1}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mx-4{margin-left:calc(var(--spacing) * 4);margin-right:calc(var(--spacing) * 4)}.mx-auto{margin-left:auto;margin-right:auto}.my-8{margin-top:calc(var(--spacing) * 8);margin-bottom:calc(var(--spacing) * 8)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-10{margin-top:calc(var(--spacing) * 10)}.mt-12{margin-top:calc(var(--spacing) * 12)}.mt-16{margin-top:calc(var(--spacing) * 16)}.mt-auto{margin-top:auto}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.mb-8{margin-bottom:calc(var(--spacing) * 8)}.mb-10{margin-bottom:calc(var(--spacing) * 10)}.-ml-2{margin-left:calc(var(--spacing) * -2)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-10{margin-left:calc(var(--spacing) * 10)}.ml-auto{margin-left:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.aspect-\[4\/3\]{aspect-ratio:4/3}.aspect-\[4\/5\]{aspect-ratio:4/5}.aspect-square{aspect-ratio:1}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-3{height:calc(var(--spacing) * 3)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-8{height:calc(var(--spacing) * 8)}.h-10{height:calc(var(--spacing) * 10)}.h-16{height:calc(var(--spacing) * 16)}.h-20{height:calc(var(--spacing) * 20)}.h-28{height:calc(var(--spacing) * 28)}.h-48{height:calc(var(--spacing) * 48)}.h-\[50vh\]{height:50vh}.h-\[65vh\]{height:65vh}.h-auto{height:auto}.h-full{height:100%}.h-screen{height:100vh}.max-h-16{max-height:calc(var(--spacing) * 16)}.max-h-20{max-height:calc(var(--spacing) * 20)}.max-h-80{max-height:calc(var(--spacing) * 80)}.min-h-\[44px\]{min-height:44px}.min-h-\[70vh\]{min-height:70vh}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-1\/3{width:33.3333%}.w-1\/4{width:25%}.w-2\/3{width:66.6667%}.w-3\/4{width:75%}.w-4\/6{width:66.6667%}.w-5\/6{width:83.3333%}.w-10{width:calc(var(--spacing) * 10)}.w-20{width:calc(var(--spacing) * 20)}.w-28{width:calc(var(--spacing) * 28)}.w-32{width:calc(var(--spacing) * 32)}.w-48{width:calc(var(--spacing) * 48)}.w-52{width:calc(var(--spacing) * 52)}.w-56{width:calc(var(--spacing) * 56)}.w-72{width:calc(var(--spacing) * 72)}.w-auto{width:auto}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.max-w-xl{max-width:var(--container-xl)}.min-w-0{min-width:calc(var(--spacing) * 0)}.flex-1{flex:1}.flex-shrink{flex-shrink:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-pointer{cursor:pointer}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.gap-1{gap:calc(var(--spacing) * 1)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-8{gap:calc(var(--spacing) * 8)}.gap-content-md{gap:var(--spacing-content-md)}.space-y-1>:not(:last-child){--tw-space-y-reverse:0;margin-top:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-bottom:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}.space-y-2>:not(:last-child){--tw-space-y-reverse:0;margin-top:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-bottom:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}.space-y-3>:not(:last-child){--tw-space-y-reverse:0;margin-top:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-bottom:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}.space-y-4>:not(:last-child){--tw-space-y-reverse:0;margin-top:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-bottom:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}.space-y-6>:not(:last-child){--tw-space-y-reverse:0;margin-top:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-bottom:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}.divide-y>:not(:last-child){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}.divide-slate-100>:not(:last-child){border-color:var(--color-slate-100)}.divide-slate-200>:not(:last-child){border-color:var(--color-slate-200)}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-card{border-radius:var(--radius-card)}.rounded-full{border-radius:9999px}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-none{--tw-border-style:none;border-style:none}.border-amber-200{border-color:var(--color-amber-200)}.border-blue-200{border-color:var(--color-blue-200)}.border-green-200{border-color:var(--color-green-200)}.border-red-200{border-color:var(--color-red-200)}.border-slate-100{border-color:var(--color-slate-100)}.border-slate-200{border-color:var(--color-slate-200)}.border-slate-800{border-color:var(--color-slate-800)}.bg-\[var\(--primary-color\)\]{background-color:var(--primary-color)}.bg-amber-50{background-color:var(--color-amber-50)}.bg-black\/30{background-color:#0000004d}.bg-black\/30{background-color:rgba(0,0,0,0.3)}.bg-blue-50{background-color:var(--color-blue-50)}.bg-green-50{background-color:var(--color-green-50)}.bg-red-50{background-color:var(--color-red-50)}.bg-slate-50{background-color:var(--color-slate-50)}.bg-slate-100{background-color:var(--color-slate-100)}.bg-slate-200{background-color:var(--color-slate-200)}.bg-slate-300{background-color:var(--color-slate-300)}.bg-slate-800{background-color:var(--color-slate-800)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.object-cover{object-fit:cover}.p-2{padding:calc(var(--spacing) * 2)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.px-2{padding-left:calc(var(--spacing) * 2);padding-right:calc(var(--spacing) * 2)}.px-3{padding-left:calc(var(--spacing) * 3);padding-right:calc(var(--spacing) * 3)}.px-4{padding-left:calc(var(--spacing) * 4);padding-right:calc(var(--spacing) * 4)}.px-5{padding-left:calc(var(--spacing) * 5);padding-right:calc(var(--spacing) * 5)}.px-6{padding-left:calc(var(--spacing) * 6);padding-right:calc(var(--spacing) * 6)}.px-8{padding-left:calc(var(--spacing) * 8);padding-right:calc(var(--spacing) * 8)}.py-0\.5{padding-top:calc(var(--spacing) * .5);padding-bottom:calc(var(--spacing) * .5)}.py-1{padding-top:calc(var(--spacing) * 1);padding-bottom:calc(var(--spacing) * 1)}.py-2{padding-top:calc(var(--spacing) * 2);padding-bottom:calc(var(--spacing) * 2)}.py-2\.5{padding-top:calc(var(--spacing) * 2.5);padding-bottom:calc(var(--spacing) * 2.5)}.py-3{padding-top:calc(var(--spacing) * 3);padding-bottom:calc(var(--spacing) * 3)}.py-4{padding-top:calc(var(--spacing) * 4);padding-bottom:calc(var(--spacing) * 4)}.py-6{padding-top:calc(var(--spacing) * 6);padding-bottom:calc(var(--spacing) * 6)}.py-8{padding-top:calc(var(--spacing) * 8);padding-bottom:calc(var(--spacing) * 8)}.py-12{padding-top:calc(var(--spacing) * 12);padding-bottom:calc(var(--spacing) * 12)}.py-16{padding-top:calc(var(--spacing) * 16);padding-bottom:calc(var(--spacing) * 16)}.py-20{padding-top:calc(var(--spacing) * 20);padding-bottom:calc(var(--spacing) * 20)}.py-band-y{padding-top:var(--spacing-band-y);padding-bottom:var(--spacing-band-y)}.py-section-y{padding-top:var(--spacing-section-y);padding-bottom:var(--spacing-section-y)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-4{padding-left:calc(var(--spacing) * 4)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-6xl{font-size:var(--text-6xl);line-height:var(--tw-leading,var(--text-6xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-display{font-size:var(--text-display);line-height:var(--tw-leading,var(--text-display--line-height))}.text-h1{font-size:var(--text-h1);line-height:var(--tw-leading,var(--text-h1--line-height))}.text-h2{font-size:var(--text-h2);line-height:var(--tw-leading,var(--text-h2--line-height))}.text-h3{font-size:var(--text-h3);line-height:var(--tw-leading,var(--text-h3--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.text-amber-400{color:var(--color-amber-400)}.text-amber-800{color:var(--color-amber-800)}.text-blue-800{color:var(--color-blue-800)}.text-current{color:currentColor}.text-green-600{color:var(--color-green-600)}.text-green-800{color:var(--color-green-800)}.text-red-400{color:var(--color-red-400)}.text-red-500{color:var(--color-red-500)}.text-red-800{color:var(--color-red-800)}.text-slate-200{color:var(--color-slate-200)}.text-slate-300{color:var(--color-slate-300)}.text-slate-400{color:var(--color-slate-400)}.text-slate-500{color:var(--color-slate-500)}.text-slate-600{color:var(--color-slate-600)}.text-slate-700{color:var(--color-slate-700)}.text-slate-800{color:var(--color-slate-800)}.text-slate-900{color:var(--color-slate-900)}.text-white{color:var(--color-white)}.text-white\/70{color:#ffffffb3}.text-white\/70{color:rgba(255,255,255,0.7)}.uppercase{text-transform:uppercase}.not-italic{font-style:normal}.line-through{text-decoration-line:line-through}.underline{text-decoration-line:underline}.accent-\[var\(--primary-color\)\]{accent-color:var(--primary-color)}.opacity-80{opacity:.8}.opacity-90{opacity:.9}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-300{--tw-duration:.3s;transition-duration:.3s}.outline-none{--tw-outline-style:none;outline-style:none}@media (hover:hover){.group-hover\:scale-105.group:hover *{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x) var(--tw-scale-y)}.group-hover\:text-slate-600.group:hover *{color:var(--color-slate-600)}}.focus-within\:border-slate-400:focus-within{border-color:var(--color-slate-400)}@media (hover:hover){.hover\:border-slate-400:hover{border-color:var(--color-slate-400)}.hover\:bg-slate-50:hover{background-color:var(--color-slate-50)}.hover\:bg-slate-100:hover{background-color:var(--color-slate-100)}.hover\:bg-slate-200:hover{background-color:var(--color-slate-200)}.hover\:text-red-500:hover{color:var(--color-red-500)}.hover\:text-red-600:hover{color:var(--color-red-600)}.hover\:text-slate-600:hover{color:var(--color-slate-600)}.hover\:text-slate-700:hover{color:var(--color-slate-700)}.hover\:text-slate-800:hover{color:var(--color-slate-800)}.hover\:text-slate-900:hover{color:var(--color-slate-900)}.hover\:text-white:hover{color:var(--color-white)}.hover\:opacity-70:hover{opacity:.7}.hover\:opacity-80:hover{opacity:.8}}@media (min-width:40rem){.sm\:mb-0{margin-bottom:calc(var(--spacing) * 0)}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:justify-between{justify-content:space-between}}@media (min-width:48rem){.md\:absolute{position:absolute}.md\:sticky{position:sticky}.md\:top-24{top:calc(var(--spacing) * 24)}.md\:left-1\/2{left:50%}.md\:order-1{order:1}.md\:order-2{order:2}.md\:order-3{order:3}.md\:order-none{order:0}.md\:col-span-1{grid-column:span 1/span 1}.md\:col-span-2{grid-column:span 2/span 2}.md\:col-span-3{grid-column:span 3/span 3}.md\:mx-8{margin-left:calc(var(--spacing) * 8);margin-right:calc(var(--spacing) * 8)}.md\:ml-auto{margin-left:auto}.md\:block{display:block}.md\:flex{display:flex}.md\:hidden{display:none}.md\:h-64{height:calc(var(--spacing) * 64)}.md\:h-\[70vh\]{height:70vh}.md\:h-\[80vh\]{height:80vh}.md\:-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.md\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:justify-between{justify-content:space-between}.md\:gap-12{gap:calc(var(--spacing) * 12)}.md\:gap-content-lg{gap:var(--spacing-content-lg)}.md\:p-12{padding:calc(var(--spacing) * 12)}.md\:py-12{padding-top:calc(var(--spacing) * 12);padding-bottom:calc(var(--spacing) * 12)}.md\:py-16{padding-top:calc(var(--spacing) * 16);padding-bottom:calc(var(--spacing) * 16)}.md\:py-24{padding-top:calc(var(--spacing) * 24);padding-bottom:calc(var(--spacing) * 24)}.md\:py-32{padding-top:calc(var(--spacing) * 32);padding-bottom:calc(var(--spacing) * 32)}.md\:py-band-y-md{padding-top:var(--spacing-band-y-md);padding-bottom:var(--spacing-band-y-md)}.md\:py-section-y-md{padding-top:var(--spacing-section-y-md);padding-bottom:var(--spacing-section-y-md)}.md\:text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.md\:text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.md\:text-display-md{font-size:var(--text-display-md);line-height:var(--tw-leading,var(--text-display-md--line-height))}.md\:text-h1-md{font-size:var(--text-h1-md);line-height:var(--tw-leading,var(--text-h1-md--line-height))}.md\:text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}}.nav-item{position:relative}.nav-item:hover>.nav-submenu,.nav-item:focus-within>.nav-submenu{opacity:1;pointer-events:auto;transform:scale(1)}.nav-submenu{opacity:0;transform-origin:0 0;pointer-events:none;z-index:80;transition:all .2s ease-out;transform:scale(.98)}.spark-preview-indicator{z-index:100;color:#fff;background:#0f172a;border:1px solid #fff3;border-radius:.75rem;align-items:center;gap:.75rem;max-width:calc(100vw - 2rem);padding:.75rem 1rem;font-size:.875rem;line-height:1.25rem;display:flex;position:fixed;bottom:1rem;right:1rem;box-shadow:0 12px 32px #0f172a47}.spark-preview-indicator__message{font-weight:600}.spark-preview-indicator__exit{color:#0f172a;background:#fff;border-radius:.375rem;padding:.25rem .5rem;font-weight:700;text-decoration:none}.spark-preview-indicator__exit:focus-visible{outline-offset:3px;outline:3px solid #fbbf24}@media (hover:hover){.spark-preview-indicator__exit:hover{color:#0f172a;opacity:1;background:#e2e8f0}}@media not all and (min-width:30rem){.spark-preview-indicator{justify-content:space-between;max-width:none;bottom:.75rem;left:.75rem;right:.75rem}}.variant-option-list{flex-wrap:wrap;gap:.5rem;display:flex}.variant-option{display:inline-flex;position:relative}.variant-option input{opacity:0;cursor:pointer;width:100%;height:100%;margin:0;position:absolute;top:0;right:0;bottom:0;left:0}.variant-option-label{color:#334155;white-space:nowrap;cursor:pointer;background-color:#fff;border:1px solid #e2e8f0;justify-content:center;align-items:center;min-height:44px;padding:0 1.25rem;font-size:.875rem;line-height:1.25rem;transition:border-color .15s ease-out,background-color .15s ease-out,color .15s ease-out;display:inline-flex}.variant-option:hover .variant-option-label{border-color:#94a3b8}.variant-option input:focus-visible+.variant-option-label{outline:2px solid var(--primary-color);outline-offset:2px}.variant-option input:checked+.variant-option-label{background-color:var(--primary-color);border-color:var(--primary-color);color:#fff}[data-light-primary] .variant-option input:checked+.variant-option-label{color:#1e293b}.variant-option[data-variant-unavailable=true] input:not(:checked)+.variant-option-label{opacity:.55;color:#64748b}.variant-option[data-variant-unavailable=true] .variant-option-label:after{content:"";pointer-events:none;background-image:linear-gradient(to top right,#fff0 47.5%,#94a3b8 47.5% 52.5%,#fff0 52.5%);position:absolute;top:0;right:0;bottom:0;left:0}.variant-option input:checked+.variant-option-label:after{background-image:linear-gradient(to top right,#fff0 47.5%,#fff 47.5% 52.5%,#fff0 52.5%)}[data-light-primary] .variant-option input:checked+.variant-option-label:after{background-image:linear-gradient(to top right,#fff0 47.5%,#1e293b 47.5% 52.5%,#fff0 52.5%)}.variant-option-value{color:#0f172a;font-weight:500}.variant-size-guide{color:#475569;text-underline-offset:2px;font-size:.75rem;line-height:1rem;text-decoration:underline} \ No newline at end of file diff --git a/configs/settings_data.json b/configs/settings_data.json index ae8fa48..d55f5b0 100644 --- a/configs/settings_data.json +++ b/configs/settings_data.json @@ -3,6 +3,7 @@ "show_featured_product": false, "show_featured_products": true, "show_featured_categories": true, + "show_image_text": false, "homepage_hero_image": "", "homepage_hero_image_mobile": "", "homepage_hero_heading": "", @@ -127,6 +128,17 @@ "promo_banner_text_color": "", "promo_banner_cta_style": "primary", "promo_banner_cta_outline": true, + "image_text_image": "", + "image_text_image_alt": "", + "image_text_image_position": "left", + "image_text_image_ratio": "square", + "image_text_eyebrow": "", + "image_text_heading": "", + "image_text_body": "", + "image_text_cta_url": "", + "image_text_cta_style": "primary", + "image_text_bg_color": "", + "image_text_text_color": "", "site_index": false, "account_only": false, "account_only_show_footer": true, diff --git a/configs/settings_optional.txt b/configs/settings_optional.txt index 1fb05ed..9edc91b 100644 --- a/configs/settings_optional.txt +++ b/configs/settings_optional.txt @@ -8,6 +8,7 @@ featured_products_cta_text # template applies a default filter featured_products_header # template applies a default filter final_step_message # template applies a default filter homepage_hero_cta # template applies a default filter +image_text_cta_text # template applies a default filter membership_active_status_value # template applies a default filter membership_detail_text # template applies a default filter membership_discount_percent # template applies a default filter diff --git a/configs/settings_schema.json b/configs/settings_schema.json index 07013bc..0c43dc1 100644 --- a/configs/settings_schema.json +++ b/configs/settings_schema.json @@ -42,6 +42,13 @@ "type": "checkbox", "default": false, "help_text": "Display a full-width promotional banner with a heading and call-to-action button." + }, + { + "name": "show_image_text", + "label": "Show Image with Text", + "type": "checkbox", + "default": false, + "help_text": "Display a two-column image and text section for a brand story, ingredient callout, or explainer." } ], "Hero": [ @@ -714,6 +721,131 @@ "help_text": "Text color for category tile labels. Leave blank for white." } ], + "Image with Text": [ + { + "name": "image_text_image", + "label": "Image", + "type": "image_picker", + "help_text": "Image for one half of the section. Use a product or lifestyle photo that survives cropping." + }, + { + "name": "image_text_image_alt", + "label": "Image Alt Text", + "type": "text", + "help_text": "Accessible description of the image. Leave blank to use the heading.", + "max_length": 250 + }, + { + "name": "image_text_image_position", + "label": "Image Position", + "type": "select", + "options": [ + { + "name": "Left", + "value": "left" + }, + { + "name": "Right", + "value": "right" + } + ], + "default": "left", + "help_text": "Which side the image sits on at tablet and desktop widths. On mobile the image always stacks above the text." + }, + { + "name": "image_text_image_ratio", + "label": "Image Ratio", + "type": "select", + "options": [ + { + "name": "Square", + "value": "square" + }, + { + "name": "Portrait", + "value": "portrait" + }, + { + "name": "Landscape", + "value": "landscape" + }, + { + "name": "Native", + "value": "native" + } + ], + "default": "square", + "help_text": "Crop the image to a fixed ratio, or use Native to show the image at its own proportions." + }, + { + "name": "image_text_eyebrow", + "label": "Eyebrow", + "type": "text", + "help_text": "Short uppercase label above the heading.", + "max_length": 50 + }, + { + "name": "image_text_heading", + "label": "Heading", + "type": "text", + "help_text": "Section heading beside the image.", + "max_length": 100 + }, + { + "name": "image_text_body", + "label": "Body", + "type": "richtext", + "help_text": "Supporting copy below the heading.", + "max_length": 1000 + }, + { + "name": "image_text_cta_text", + "label": "Button Text", + "type": "text", + "help_text": "Optional button text. Leave blank to use the localized default.", + "max_length": 50 + }, + { + "name": "image_text_cta_url", + "label": "Button URL", + "type": "url", + "help_text": "Where the button links to (e.g. /catalogue/). Leave blank to hide the button.", + "max_length": 500 + }, + { + "name": "image_text_cta_style", + "label": "Button Style", + "type": "select", + "options": [ + { + "name": "Primary", + "value": "primary" + }, + { + "name": "Secondary", + "value": "secondary" + }, + { + "name": "Outline", + "value": "outline" + } + ], + "default": "primary", + "help_text": "Primary fills with your primary color, Secondary is a quiet bordered button, Outline follows the section text color." + }, + { + "name": "image_text_bg_color", + "label": "Background Color", + "type": "color", + "help_text": "Section background color. Leave blank for the page background." + }, + { + "name": "image_text_text_color", + "label": "Text Color", + "type": "color", + "help_text": "Heading, body, and outline button color. Leave blank for the theme defaults." + } + ], "Custom CSS": [ { "name": "home_page_css", diff --git a/docs/design-block-authoring.md b/docs/design-block-authoring.md index a5a4799..dec5c16 100644 --- a/docs/design-block-authoring.md +++ b/docs/design-block-authoring.md @@ -92,6 +92,7 @@ Supported styles: - `primary` - `accent` +- `secondary` (quiet bordered button, used by Image with Text) Set `outline` to render an outline button using the selected brand color. diff --git a/docs/figma-section-library-plan.md b/docs/figma-section-library-plan.md index efb8430..136ecc4 100644 --- a/docs/figma-section-library-plan.md +++ b/docs/figma-section-library-plan.md @@ -103,8 +103,9 @@ Use snake_case for exported properties. If Figma display labels need to be short | Featured categories | `partials/section_featured_categories.html` | `product_categories`, overlay settings | First-pass spec in `docs/section-specs/featured-categories.md`. Needs 2-5 desktop column states, missing category image state, overlay opacity states, and long category label behavior. | | On Sale | `partials/section_on_sale.html` | `products`, product card sale state | First-pass spec in `docs/section-specs/on-sale.md`. Needs sale badge and compare-at price states from `partials/product_card.html`; otherwise this should share grid anatomy with Featured products. | | Promo banner | `partials/section_promo_banner.html` | text, CTA settings, colors | First-pass spec in `docs/section-specs/promo-banner.md`. Needs contrast states, short and long copy states, no-CTA state, and primary/accent/outline button states. | +| Image with text | `partials/section_image_text.html` | `image_picker`, text, rich text, CTA settings, colors | First-pass spec in `docs/section-specs/image-text.md`. Needs image left/right states, four image ratio states, missing-image state, long heading state, and primary/secondary/outline button states. | -These are enough for the first Figma library pass. The full roster of section partials Spark needs to ship to fully cover D2C storefronts — including image-with-text, FAQ, comparison table, process steps, press logos, testimonials, value props, and the rest of the Tier 1/2/3 catalog — lives in [`section-roster.md`](./section-roster.md). New section ideas should follow the section authoring unit pattern below. +These are enough for the first Figma library pass. The full roster of section partials Spark needs to ship to fully cover D2C storefronts — including FAQ, comparison table, process steps, press logos, testimonials, value props, and the rest of the Tier 1/2/3 catalog — lives in [`section-roster.md`](./section-roster.md). New section ideas should follow the section authoring unit pattern below. ## Section Spec Template diff --git a/docs/section-roster.md b/docs/section-roster.md index 12096bc..48f9254 100644 --- a/docs/section-roster.md +++ b/docs/section-roster.md @@ -22,9 +22,9 @@ Three inputs shaped this roster: / Crave (free D2C-friendly), Impulse / Motion / Prestige (paid). Section catalogs across these are the de facto standard for what merchants expect to find in a theme editor. -3. **Spark's existing partials** — 6 homepage sections shipped today +3. **Spark's existing partials** — 7 homepage sections shipped today (hero, featured_product, featured_products, featured_categories, - on_sale, promo_banner). See `figma-section-library-plan.md` for the + on_sale, promo_banner, image_text). See `figma-section-library-plan.md` for the current "Current Homepage Section Units" table. ## Naming and conventions @@ -39,7 +39,7 @@ Three inputs shaped this roster: - Each section gets a spec in `docs/section-specs/.md` following the [Section Spec Template](./figma-section-library-plan.md#section-spec-template). -## Tier 0 — already shipped (6) +## Tier 0 — already shipped (7) | Section | Partial | Status | |---|---|---| @@ -49,8 +49,9 @@ Three inputs shaped this roster: | Featured categories | `section_featured_categories` | First-pass spec | | On sale | `section_on_sale` | First-pass spec | | Promo banner | `section_promo_banner` | First-pass spec | +| Image with text | `section_image_text` | First-pass spec | -## Tier 1 — must-have for D2C parity (12) +## Tier 1 — must-have for D2C parity (11 remaining) These cover the layout patterns that today require either bespoke partial work or static HTML in Page content. Each one shows up across @@ -180,6 +181,8 @@ pages, mission copy between product showcases. - `text_bg_color`, `text_color` ### 10. `section_image_text` +**Status:** Shipped. Spec in [`section-specs/image-text.md`](./section-specs/image-text.md); +the settings below are the implemented names, plus `image_text_image_alt`. **Purpose:** 50/50 image + text split. Foundational layout for any story or explainer page. **Pattern:** Founder story chapters, ingredient deep-dives, "how it @@ -361,9 +364,9 @@ closes the most merchant friction fastest is: | 7 | Tier 3 on demand | Lookbook, countdown, instagram_feed if merchants ask. | | 8 | Commerce primitives — sticky_atc, quick_view, stock_indicator | PDP polish. | -12 Tier-1 + 8 Tier-2 = 20 sections. With variants on existing -partials, the total Figma component library lands at roughly 28 -section components plus the 6 already-shipped — call it 34. +11 remaining Tier-1 + 8 Tier-2 = 19 sections. With variants on +existing partials, the total Figma component library lands at roughly +27 section components plus the 7 already-shipped — call it 34. ## Coverage validation diff --git a/docs/section-specs/README.md b/docs/section-specs/README.md index 1a54142..5f3dcfe 100644 --- a/docs/section-specs/README.md +++ b/docs/section-specs/README.md @@ -14,6 +14,7 @@ Each spec should describe one merchant-configurable section across Figma, Theme | [Featured categories](featured-categories.md) | First pass | `partials/section_featured_categories.html` | | [On Sale](on-sale.md) | First pass | `partials/section_on_sale.html` | | [Promo banner](promo-banner.md) | First pass | `partials/section_promo_banner.html` | +| [Image with text](image-text.md) | First pass | `partials/section_image_text.html` | Use `docs/figma-section-library-plan.md` for the overall workflow and library structure, and [`docs/section-roster.md`](../section-roster.md) for the full Tier 1/2/3 partial roster Spark should ship to fully cover modern D2C storefronts. diff --git a/docs/section-specs/image-text.md b/docs/section-specs/image-text.md new file mode 100644 index 0000000..ac1ca7b --- /dev/null +++ b/docs/section-specs/image-text.md @@ -0,0 +1,175 @@ +# Image with Text Section Spec + +Status: first-pass section authoring unit for the Spark Figma component library. + +The Image with text section renders a 50/50 split of one image and one copy column (eyebrow, heading, rich-text body, optional CTA). It is the foundational story and explainer layout: founder story chapters, ingredient deep-dives, technology callouts. It is not a product spotlight; use Featured product when the copy belongs to a catalogue product. + +## Module Summary + +| Field | Value | +| --- | --- | +| Stable slug | `image_text` | +| Merchant label | Image with Text | +| Current Interface | Global Theme Settings under `show_image_text` and `image_text_*` | +| Current Implementation | `partials/section_image_text.html` | +| Included from | `templates/index.html` | +| Settings groups | `Homepage > Sections`, `Homepage > Image with Text` | +| Defaults file | `configs/settings_data.json` | +| Design references | `image_text-desktop`, `image_text-tablet`, `image_text-mobile` | +| Runtime JS | None | +| App hooks | None | + +## Current Render Contract + +- The section renders only when `settings.show_image_text` is true. +- With the toggle on and neither heading nor body configured, the section renders the setup placeholder (dashed border, neutral blocks, pointer to the settings location) instead of an empty band. An image alone is not enough: a lone image beside an empty copy column is never rendered live. +- With a heading or body configured, the section renders live: two columns at `md` and above, one column below `md` with the image always first in DOM order and therefore on top. +- `image_text_image_position` moves the image column with `md:order-*`; it has no effect below `md`. +- `image_text_image_ratio` wraps the image in a fixed-ratio box with `object-cover` for `square` (1:1), `portrait` (4:5), and `landscape` (4:3). `native` renders the image at its own proportions with no crop. +- A missing image with copy present renders a neutral `bg-slate-100` block at the selected ratio (square when `native`), so the layout keeps its shape while the merchant finishes setup. +- Image `alt` is `image_text_image_alt`, falling back to `image_text_heading`. +- Eyebrow, heading, and body each render only when present. Body is rich text and renders with `|safe`, trusting the platform's `richtext` setting type to deliver sanitised HTML, the same assumption the other rich-text sections make. Any change that lets unsanitised markup reach a `richtext` setting must revisit this filter. +- CTA renders only when `image_text_cta_url` is present, through `partials/cta_button.html`. Label falls back to the localized `homepage.cta.shop_now`. +- `image_text_cta_style` maps to the shared button classes: `primary` renders `btn-primary`, `secondary` renders `btn-secondary`, `outline` renders `btn-outline` with the outline colour following `image_text_text_color` when set and the primary brand colour otherwise (the helper's default, so no `style` argument is passed in that branch). +- Background colour is applied only when set; the default is the page background. +- Text colour is applied to the section only when set. When empty the copy uses the theme slate defaults (`text-slate-800` heading, `text-slate-600` body, `text-slate-500` eyebrow). When set, the eyebrow and body inherit the colour at reduced opacity, and the heading carries it as an inline style because the base stylesheet (and the global heading colour setting) give every heading an explicit colour that inheritance cannot override. +- The image is lazy-loaded. This section is not expected to hold the LCP image. +- There is no client-side behavior and no GraphQL dependency. + +## Figma Component + +Recommended component name: + +```text +Homepage/Image with Text +``` + +Recommended reference frame names: + +```text +image_text-desktop +image_text-tablet +image_text-mobile +``` + +Recommended component properties: + +| Property | Type | Maps To | +| --- | --- | --- | +| `show` | Boolean | `show_image_text` | +| `image` | Image placeholder | `image_text_image` | +| `alt_text` | Text annotation | `image_text_image_alt` | +| `image_position` | Variant | `image_text_image_position` | +| `image_ratio` | Variant | `image_text_image_ratio` | +| `eyebrow` | Text | `image_text_eyebrow` | +| `heading` | Text | `image_text_heading` | +| `body` | Text | `image_text_body` | +| `cta_label` | Text | `image_text_cta_text` | +| `cta_url` | Link annotation | `image_text_cta_url` | +| `cta_style` | Variant | `image_text_cta_style` | +| `background_color` | Color | `image_text_bg_color` | +| `text_color` | Color | `image_text_text_color` | + +## Setting Map + +| Key | Type | Default | Figma Property | Values / Limits | Notes | +| --- | --- | --- | --- | --- | --- | +| `show_image_text` | `checkbox` | `false` | `show` | `true`, `false` | Lives in `Homepage > Sections`; hides the whole section when false. Off by default so existing stores are unchanged. | +| `image_text_image` | `image_picker` | empty | `image` | Image asset | Empty with copy present renders a neutral block. Set without copy still renders the setup placeholder; the image alone never goes live. | +| `image_text_image_alt` | `text` | empty | `alt_text` | Max 250 chars | Falls back to the heading. | +| `image_text_image_position` | `select` | `left` | `image_position` | `left`, `right` | Desktop and tablet only; mobile always stacks image first. | +| `image_text_image_ratio` | `select` | `square` | `image_ratio` | `square`, `portrait`, `landscape`, `native` | Fixed ratios crop with `object-cover`; `native` never crops. | +| `image_text_eyebrow` | `text` | empty | `eyebrow` | Max 50 chars | Uppercase label above the heading. | +| `image_text_heading` | `text` | empty | `heading` | Max 100 chars | Renders as an `h2`. | +| `image_text_body` | `richtext` | empty | `body` | Max 1000 chars | Rendered with `\|safe`. | +| `image_text_cta_text` | `text` | `Shop now` (localized) | `cta_label` | Max 50 chars | No schema default; the template applies the localized fallback. Requires URL to render. | +| `image_text_cta_url` | `url` | empty | `cta_url` | Max 500 chars | Empty hides the CTA. | +| `image_text_cta_style` | `select` | `primary` | `cta_style` | `primary`, `secondary`, `outline` | Shared `.btn-*` classes. Outline follows the text colour. | +| `image_text_bg_color` | `color` | empty | `background_color` | Color | Empty renders the page background. | +| `image_text_text_color` | `color` | empty | `text_color` | Color | Empty renders the theme slate defaults. | + +## Layout Details + +| Element | Current Implementation | +| --- | --- | +| Section | `py-section-y md:py-section-y-md`, optional inline background and text colour. | +| Container | Shared `.container`. | +| Grid | `grid-cols-1 md:grid-cols-2`, `gap-content-md md:gap-content-lg`, `items-center`. | +| Image box | Ratio wrapper with `overflow-hidden rounded-card`; `native` uses `w-full h-auto rounded-card` on the image directly. | +| Eyebrow | `text-xs font-semibold uppercase tracking-wide mb-3`. | +| Heading | `text-h1 md:text-h1-md font-semibold mb-4`. | +| Body | Rich text, `mb-6`. | +| CTA | Shared Spark button helper. | + +## Image Guidance + +- Recommended source minimum: 1200px on the long edge. The column is at most half the container, so 1600px covers 2x displays. +- Keep the subject centred for `square` and `portrait`; `object-cover` crops from the edges as the column width changes between tablet and desktop. +- Use `native` for product cut-outs, illustrations, or any image whose edges carry meaning. +- Do not bake copy into the image. Use the eyebrow, heading, and body settings so the text stays editable and translatable. + +## Required Figma States + +| State | Why It Matters | +| --- | --- | +| Default, image left | Eyebrow, heading, body, primary CTA, square image. | +| Image right | `image_text_image_position` set to `right`. | +| Mobile stacked | Image above copy regardless of position. | +| Square, portrait, landscape, native | One frame per ratio so cropping expectations are explicit. | +| No eyebrow | Heading, body, CTA only. | +| No CTA | CTA URL is empty. | +| Secondary and outline CTA | Both alternate button styles, outline on both default and custom text colour. | +| Custom background and text colour | Dark background with light text. | +| Long heading | Heading at 100 chars wrapping across three lines beside a square image. | +| Missing image | Copy present, neutral block in the image column. | +| Setup placeholder | Toggle on, no heading or body. | +| Image only | Image set, no heading or body: renders the setup placeholder, never a lone image. | + +## Accessibility + +- The heading renders as `h2`; Hero image keeps the homepage `h1`. +- Every configured image should have merchant-authored alt text. Empty alt falls back to the heading, which is the section's own description of the image subject. +- Custom background and text colours are merchant choices; Figma should include at least one low-contrast pairing that the design guardrails reject. +- The CTA is a normal link and receives the shared focus-visible treatment. + +## Performance + +- The image uses `loading="lazy"` and is not preloaded. If a merchant places this section directly under a hidden Hero so that it becomes the LCP, revisit the loading hint before changing defaults. +- No JavaScript, no per-user data. + +## QA Checklist + +- Verify at desktop 1440px, tablet 768px, and the chosen mobile width. +- Confirm image left and image right swap at `md` and stack image-first on mobile. +- Confirm each ratio value renders the expected box and that `native` does not crop. +- Confirm the long-heading state (100 chars) wraps without overflow and keeps the image vertically centred. +- Confirm the missing-image state renders the neutral block at the selected ratio and the copy still renders. +- Confirm no CTA renders when `image_text_cta_url` is empty, and the localized `Shop now` label renders when only the URL is set. +- Confirm primary, secondary, and outline CTA states match shared Spark button styling, and that outline follows a custom text colour. +- Confirm background and text colours apply only when set and default stores render unchanged. +- Confirm the setup placeholder appears with the toggle on and no content, and disappears once any of image, heading, or body is set. + +## Future Theme Section Migration + +| Current Key | Future Instance Setting | +| --- | --- | +| `image_text_image` | `section.settings.image` | +| `image_text_image_alt` | `section.settings.alt_text` | +| `image_text_image_position` | `section.settings.image_position` | +| `image_text_image_ratio` | `section.settings.image_ratio` | +| `image_text_eyebrow` | `section.settings.eyebrow` | +| `image_text_heading` | `section.settings.heading` | +| `image_text_body` | `section.settings.body` | +| `image_text_cta_text` | `section.settings.cta_label` | +| `image_text_cta_url` | `section.settings.cta_url` | +| `image_text_cta_style` | `section.settings.cta_style` | +| `image_text_bg_color` | `section.settings.background_color` | +| `image_text_text_color` | `section.settings.text_color` | + +`show_image_text` should become section presence once merchants can add, remove, reorder, and duplicate section instances. This section is the first one where duplication matters: alternating image/text chapters need several instances with different content, which the fixed-order global settings model cannot express. + +## Implementation Gaps Exposed + +- `image_text_cta_style` uses a single three-way select (`primary`, `secondary`, `outline`) as the roster sketch specifies, while the six earlier sections use a `*_cta_style` (`primary`/`accent`) select plus a `*_cta_outline` checkbox. `partials/cta_button.html` gained a `secondary` style so both models share one helper. Decide before public release whether new sections standardise on the three-way select or the older pair. +- Only one instance is possible until true theme sections exist, so "alternating image/text blocks" from the roster still needs static page content today. +- The CTA label fallback reuses `homepage.cta.shop_now`. A story section may want a "Learn more" default; that needs a new locale key across every locale file. diff --git a/docs/sections-architecture-proposal.md b/docs/sections-architecture-proposal.md index 0273e47..bc1ee83 100644 --- a/docs/sections-architecture-proposal.md +++ b/docs/sections-architecture-proposal.md @@ -116,6 +116,7 @@ The important contract: inside a section partial, `section.settings.foo` should - `section_featured_categories.html` - `section_on_sale.html` - `section_promo_banner.html` + - `section_image_text.html` 3. Generate a default homepage composition from current `show_*` toggles and settings. 4. Update section partials to read `section.settings.*` first and fall back to global `settings.*` during migration. 5. Once stable, deprecate homepage-only global section settings in favor of section instances. diff --git a/docs/theme-settings-partials.md b/docs/theme-settings-partials.md index 4df2468..43ae8ca 100644 --- a/docs/theme-settings-partials.md +++ b/docs/theme-settings-partials.md @@ -22,6 +22,7 @@ These are the primary design blocks for quick storefront builds. They are includ | `partials/section_featured_categories.html` | Homepage > Featured Categories | Category image tile grid. | `show_featured_categories`, `featured_categories`, `featured_categories_header`, `featured_categories_header_size`, `featured_categories_header_align`, `featured_categories_columns`, `featured_categories_bg_color`, `featured_categories_overlay_color`, `featured_categories_overlay_opacity`, `featured_categories_text_color` | | `partials/section_on_sale.html` | Homepage > On Sale | Merchant-curated sale product grid. | `show_on_sale`, `on_sale_products`, `on_sale_header`, `on_sale_header_size`, `on_sale_header_align`, `on_sale_columns`, `on_sale_bg_color`, `on_sale_card_bg` | | `partials/section_promo_banner.html` | Homepage > Promo Banner | Full-width text and CTA promotion band. | `show_promo_banner`, `promo_banner_heading`, `promo_banner_subheading`, `promo_banner_cta_text`, `promo_banner_cta_url`, `promo_banner_bg_color`, `promo_banner_text_color`, `promo_banner_cta_style`, `promo_banner_cta_outline` | +| `partials/section_image_text.html` | Homepage > Image with Text | 50/50 image and text split with eyebrow, heading, rich-text body, and CTA. | `show_image_text`, `image_text_image`, `image_text_image_alt`, `image_text_image_position`, `image_text_image_ratio`, `image_text_eyebrow`, `image_text_heading`, `image_text_body`, `image_text_cta_text`, `image_text_cta_url`, `image_text_cta_style`, `image_text_bg_color`, `image_text_text_color` | ## Global Partials diff --git a/locales/de.json b/locales/de.json index 2729810..bf41e3d 100644 --- a/locales/de.json +++ b/locales/de.json @@ -299,7 +299,8 @@ "featured_products": "Ausgewählte Produkte - Einstellungen > Homepage > Ausgewählte Produkte", "featured_categories": "Ausgewählte Kategorien - Einstellungen > Homepage > Ausgewählte Kategorien", "on_sale": "Im Angebot - Einstellungen > Homepage > Im Angebot > Produkte", - "featured_product": "Ausgewähltes Produkt - Einstellungen > Homepage > Ausgewähltes Produkt" + "featured_product": "Ausgewähltes Produkt - Einstellungen > Homepage > Ausgewähltes Produkt", + "image_text": "Bild mit Text - Einstellungen > Homepage > Bild mit Text" } } } diff --git a/locales/en.default.json b/locales/en.default.json index 5596946..183b2bf 100644 --- a/locales/en.default.json +++ b/locales/en.default.json @@ -299,7 +299,8 @@ "featured_products": "Featured Products - Settings > Homepage > Featured Products", "featured_categories": "Featured Categories - Settings > Homepage > Featured Categories", "on_sale": "On Sale - Settings > Homepage > On Sale > Products", - "featured_product": "Featured Product - Settings > Homepage > Featured Product" + "featured_product": "Featured Product - Settings > Homepage > Featured Product", + "image_text": "Image with Text - Settings > Homepage > Image with Text" } } } diff --git a/locales/es.json b/locales/es.json index 5890f48..61aed26 100644 --- a/locales/es.json +++ b/locales/es.json @@ -299,7 +299,8 @@ "featured_products": "Productos destacados - Configuración > Inicio > Productos destacados", "featured_categories": "Categorías destacadas - Configuración > Inicio > Categorías destacadas", "on_sale": "En oferta - Configuración > Inicio > En oferta > Productos", - "featured_product": "Producto destacado - Configuración > Inicio > Producto destacado" + "featured_product": "Producto destacado - Configuración > Inicio > Producto destacado", + "image_text": "Imagen con texto - Configuración > Inicio > Imagen con texto" } } } diff --git a/locales/fi.json b/locales/fi.json index ed841c9..8899afe 100644 --- a/locales/fi.json +++ b/locales/fi.json @@ -299,7 +299,8 @@ "featured_products": "Featured Products - Settings > Homepage > Featured Products", "featured_categories": "Featured Categories - Settings > Homepage > Featured Categories", "on_sale": "On Sale - Settings > Homepage > On Sale > Products", - "featured_product": "Featured Product - Settings > Homepage > Featured Product" + "featured_product": "Featured Product - Settings > Homepage > Featured Product", + "image_text": "Image with Text - Settings > Homepage > Image with Text" } } } diff --git a/locales/fr.json b/locales/fr.json index 2a2c1c3..64f08fc 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -299,7 +299,8 @@ "featured_products": "Produits en vedette - Paramètres > Accueil > Produits en vedette", "featured_categories": "Catégories en vedette - Paramètres > Accueil > Catégories en vedette", "on_sale": "En promotion - Paramètres > Accueil > En promotion > Produits", - "featured_product": "Produit en vedette - Paramètres > Accueil > Produit en vedette" + "featured_product": "Produit en vedette - Paramètres > Accueil > Produit en vedette", + "image_text": "Image avec texte - Paramètres > Accueil > Image avec texte" } } } diff --git a/locales/it.json b/locales/it.json index ad6b7cb..d7a698d 100644 --- a/locales/it.json +++ b/locales/it.json @@ -299,7 +299,8 @@ "featured_products": "Featured Products - Settings > Homepage > Featured Products", "featured_categories": "Featured Categories - Settings > Homepage > Featured Categories", "on_sale": "On Sale - Settings > Homepage > On Sale > Products", - "featured_product": "Featured Product - Settings > Homepage > Featured Product" + "featured_product": "Featured Product - Settings > Homepage > Featured Product", + "image_text": "Image with Text - Settings > Homepage > Image with Text" } } } diff --git a/locales/nl.json b/locales/nl.json index 1382c86..b367406 100644 --- a/locales/nl.json +++ b/locales/nl.json @@ -299,7 +299,8 @@ "featured_products": "Featured Products - Settings > Homepage > Featured Products", "featured_categories": "Featured Categories - Settings > Homepage > Featured Categories", "on_sale": "On Sale - Settings > Homepage > On Sale > Products", - "featured_product": "Featured Product - Settings > Homepage > Featured Product" + "featured_product": "Featured Product - Settings > Homepage > Featured Product", + "image_text": "Image with Text - Settings > Homepage > Image with Text" } } } diff --git a/locales/no.json b/locales/no.json index 57f1825..399e388 100644 --- a/locales/no.json +++ b/locales/no.json @@ -299,7 +299,8 @@ "featured_products": "Featured Products - Settings > Homepage > Featured Products", "featured_categories": "Featured Categories - Settings > Homepage > Featured Categories", "on_sale": "On Sale - Settings > Homepage > On Sale > Products", - "featured_product": "Featured Product - Settings > Homepage > Featured Product" + "featured_product": "Featured Product - Settings > Homepage > Featured Product", + "image_text": "Image with Text - Settings > Homepage > Image with Text" } } } diff --git a/locales/pt.json b/locales/pt.json index 10481bb..f6c99ef 100644 --- a/locales/pt.json +++ b/locales/pt.json @@ -299,7 +299,8 @@ "featured_products": "Featured Products - Settings > Homepage > Featured Products", "featured_categories": "Featured Categories - Settings > Homepage > Featured Categories", "on_sale": "On Sale - Settings > Homepage > On Sale > Products", - "featured_product": "Featured Product - Settings > Homepage > Featured Product" + "featured_product": "Featured Product - Settings > Homepage > Featured Product", + "image_text": "Image with Text - Settings > Homepage > Image with Text" } } } diff --git a/locales/sv.json b/locales/sv.json index fa033cd..ca22534 100644 --- a/locales/sv.json +++ b/locales/sv.json @@ -299,7 +299,8 @@ "featured_products": "Featured Products - Settings > Homepage > Featured Products", "featured_categories": "Featured Categories - Settings > Homepage > Featured Categories", "on_sale": "On Sale - Settings > Homepage > On Sale > Products", - "featured_product": "Featured Product - Settings > Homepage > Featured Product" + "featured_product": "Featured Product - Settings > Homepage > Featured Product", + "image_text": "Image with Text - Settings > Homepage > Image with Text" } } } diff --git a/locales/th.json b/locales/th.json index 10dc971..2ce0f09 100644 --- a/locales/th.json +++ b/locales/th.json @@ -299,7 +299,8 @@ "featured_products": "Featured Products - Settings > Homepage > Featured Products", "featured_categories": "Featured Categories - Settings > Homepage > Featured Categories", "on_sale": "On Sale - Settings > Homepage > On Sale > Products", - "featured_product": "Featured Product - Settings > Homepage > Featured Product" + "featured_product": "Featured Product - Settings > Homepage > Featured Product", + "image_text": "Image with Text - Settings > Homepage > Image with Text" } } } diff --git a/partials/cta_button.html b/partials/cta_button.html index dd98049..4c67a53 100644 --- a/partials/cta_button.html +++ b/partials/cta_button.html @@ -1,7 +1,7 @@ -{# Shared CTA helper. Expects href, label, style, outline. Optional: outline_color. style: primary|accent. #} +{# Shared CTA helper. Expects href, label, style, outline. Optional: outline_color. style: primary|accent|secondary. #} {% if href and label %} {{ label }} diff --git a/partials/section_image_text.html b/partials/section_image_text.html new file mode 100644 index 0000000..116eecd --- /dev/null +++ b/partials/section_image_text.html @@ -0,0 +1,63 @@ +{# Spark homepage image with text section: 50/50 image and copy split. Controlled by Homepage > Sections + Image with Text settings. #} +{% if settings.show_image_text %} + {% if settings.image_text_heading or settings.image_text_body %} +
+
+
+
+ {% if settings.image_text_image %} + {% if settings.image_text_image_ratio == 'native' %} + {% firstof settings.image_text_image_alt settings.image_text_heading %} + {% else %} +
+ {% firstof settings.image_text_image_alt settings.image_text_heading %} +
+ {% endif %} + {% else %} +
+ {% endif %} +
+
+ {% if settings.image_text_eyebrow %} +

{{ settings.image_text_eyebrow }}

+ {% endif %} + {% if settings.image_text_heading %} +

{{ settings.image_text_heading }}

+ {% endif %} + {% if settings.image_text_body %} +
{{ settings.image_text_body|safe }}
+ {% endif %} + {% if settings.image_text_cta_url %} + {% t "homepage.cta.shop_now" as default_shop_now %} + {% if settings.image_text_cta_style == 'outline' %} + {% include "partials/cta_button.html" with href=settings.image_text_cta_url label=settings.image_text_cta_text|default:default_shop_now outline=True outline_color=settings.image_text_text_color %} + {% else %} + {% include "partials/cta_button.html" with href=settings.image_text_cta_url label=settings.image_text_cta_text|default:default_shop_now style=settings.image_text_cta_style %} + {% endif %} + {% endif %} +
+
+
+
+ {% else %} +
+
+
+
+
+
+
+
+
+
+

{% t "homepage.placeholder.image_text" %}

+
+ {% endif %} +{% endif %} diff --git a/templates/index.html b/templates/index.html index d5cf942..b4dc9bf 100644 --- a/templates/index.html +++ b/templates/index.html @@ -38,6 +38,7 @@ {% include "partials/section_featured_product.html" %} {% include "partials/section_featured_products.html" %} {% include "partials/section_featured_categories.html" %} +{% include "partials/section_image_text.html" %} {% include "partials/section_on_sale.html" %} {% include "partials/section_promo_banner.html" %} diff --git a/tests/test_localization_contracts.py b/tests/test_localization_contracts.py index 237b4a4..45f639e 100644 --- a/tests/test_localization_contracts.py +++ b/tests/test_localization_contracts.py @@ -16,6 +16,7 @@ "featured_products_header", "final_step_message", "homepage_hero_cta", + "image_text_cta_text", "membership_detail_text", "membership_label", "on_sale_header",