+
+ {{ forms.editableTableField({
+ label: "Routing Settings"|t('shopify'),
+ instructions: "Configure the product’s front-end routing settings."|t('shopify'),
+ id: 'routing',
+ name: 'settings',
+ cols: {
+ uriFormat: {
+ type: 'singleline',
+ heading: "Product URI Format"|t('shopify'),
+ info: "What product URIs should look like."|t('shopify'),
+ placeholder: "Leave blank if products don’t have URLs"|t('shopify'),
+ code: true
+ },
+ template: not headlessMode ? {
+ type: 'template',
+ heading: "Template"|t('app'),
+ info: "Which template should be loaded when a product’s URL is requested."|t('shopify'),
+ code: true
+ },
+ }|filter,
+ rows: {
+ 'routing': {
+ uriFormat: {
+ value: settings.uriFormat ?? null,
+ hasErrors: settings.hasErrors('uriFormat') ?? false
+ },
+ template: not headlessMode ? {
+ value: settings.template ?? null,
+ hasErrors: settings.hasErrors('template') ?? false,
+ }
+ }
+ },
+ allowAdd: false,
+ allowDelete: false,
+ allowReorder: false,
+ errors: []|unique
+ }) }}
+
+ {{ forms.fieldLayoutDesignerField({
+ fieldLayout: settings.getProductFieldLayout(),
+ }) }}
+
+
+
+ {{ forms.autosuggestField({
+ first: true,
+ label: 'API Key'|t('shopify'),
+ id: 'apiKey',
+ name: 'settings[apiKey]',
+ value: settings.apiKey,
+ errors: settings.getErrors('apiKey'),
+ suggestEnvVars: true,
+ autofocus: true,
+ }) }}
+
+ {{ forms.autosuggestField({
+ label: 'API Secret Key'|t('shopify'),
+ id: 'apiSecretKey',
+ name: 'settings[apiSecretKey]',
+ value: settings.apiSecretKey,
+ errors: settings.getErrors('apiSecretKey'),
+ suggestEnvVars: true,
+ }) }}
+
+ {{ forms.autosuggestField({
+ label: 'Access Token'|t('shopify'),
+ id: 'accessToken',
+ name: 'settings[accessToken]',
+ value: settings.accessToken,
+ errors: settings.getErrors('accessToken'),
+ suggestEnvVars: true,
+ }) }}
+
+ {{ forms.autosuggestField({
+ label: 'Host Name'|t('shopify'),
+ id: 'hostName',
+ name: 'settings[hostName]',
+ value: settings.hostName,
+ errors: settings.getErrors('hostName'),
+ suggestEnvVars: true,
+ }) }}
+
+
{{ "Webhook Management"|t('shopify') }}
+
+
+ {% set tableData = [] %}
+ {% for webhook in webhooks %}
+ {% set tableData = tableData|merge([{
+ id: webhook.id,
+ title: webhook.topic,
+ address: webhook.address
+ }]) %}
+ {% endfor %}
+
+ {% js %}
+ var columns = [
+ { name: '__slot:title', title: '{{ 'Topic'|t('shopify') }}' },
+ { name: 'address', title: '{{ 'URL'|t('shopify') }}' }
+ ];
+
+ new Craft.VueAdminTable({
+ fullPane: false,
+ columns: columns,
+ container: '#webhooks-container',
+ deleteAction: 'shopify/settings/delete-webhook',
+ deleteConfirmationMessage: Craft.t('shopify', "Are you sure you want to delete this webhook?"),
+ deleteFailMessage: Craft.t('shopify', "Webhook could not be deleted"),
+ deleteSuccessMessage: Craft.t('shopify', "Webhook deleted"),
+ emptyMessage: Craft.t('app', 'No webhooks exist yet.'),
+ tableData: {{ tableData|json_encode|raw }}
+ });
+ {% endjs %}
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/src/translations/en/shopify.php b/src/translations/en/shopify.php
new file mode 100644
index 0000000..06b15d4
--- /dev/null
+++ b/src/translations/en/shopify.php
@@ -0,0 +1,18 @@
+ 'Shopify plugin loaded',
+];
diff --git a/src/web/assets/shopifycp/ShopifyCpAsset.php b/src/web/assets/shopifycp/ShopifyCpAsset.php
new file mode 100644
index 0000000..5ccbca2
--- /dev/null
+++ b/src/web/assets/shopifycp/ShopifyCpAsset.php
@@ -0,0 +1,55 @@
+
+ * @since 2.0
+ */
+class ShopifyCpAsset extends AssetBundle
+{
+ /**
+ * @inheritdoc
+ */
+ public function init(): void
+ {
+ $this->sourcePath = __DIR__ . '/dist';
+
+ $this->depends = [
+ CpAsset::class,
+ JqueryAsset::class,
+ HtmxAsset::class
+ ];
+
+ $this->css[] = 'css/shopifycp.css';
+ $this->js[] = 'shopifycp.js';
+
+ parent::init();
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function registerAssetFiles($view): void
+ {
+ parent::registerAssetFiles($view);
+
+ if ($view instanceof View) {
+ $view->registerTranslations('shopify', [
+ ]);
+ }
+ }
+}
diff --git a/src/web/assets/shopifycp/dist/css/shopifycp.css b/src/web/assets/shopifycp/dist/css/shopifycp.css
new file mode 100644
index 0000000..7cd38ca
--- /dev/null
+++ b/src/web/assets/shopifycp/dist/css/shopifycp.css
@@ -0,0 +1,2 @@
+.proxy-element-card{padding-bottom:40px;padding-top:15px;position:relative}.proxy-element-card .pec-header{color:#3f4d5a;display:block;position:relative;width:100%}.proxy-element-card .pec-header:hover{color:#3f4d5a;text-decoration:none}.proxy-element-card .pec-header .pec-external-icon{color:#3f4d5a;position:absolute;top:50%;-webkit-transform:translate(-50%,-50%);-o-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}body.ltr .proxy-element-card .pec-header .pec-external-icon{right:0}body.rtl .proxy-element-card .pec-header .pec-external-icon{left:0}.proxy-element-card .pec-header:hover .pec-external-icon{color:#0b69a3}.proxy-element-card .pec-header .pec-title{margin-bottom:0}.proxy-element-card .pec-header .pec-subtitle{margin:.2em 0}.proxy-element-card .pec-footer{background-color:#e4edf6;border-bottom-left-radius:5px;border-bottom-right-radius:5px;bottom:0;font-size:12px;padding:10px 24px;position:absolute;width:100%}body.ltr .proxy-element-card .pec-footer{right:0}body.rtl .proxy-element-card .pec-footer{left:0}.proxy-element-card .pec-footer a{color:#3f4d5a;text-decoration:underline}.proxy-element-card .pec-footer a:hover{color:#0b69a3;text-decoration:underline}.proxy-element-card .pec-footer .spinner{position:absolute;top:50%;-webkit-transform:translate(-50%,-50%);-o-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}body.ltr .proxy-element-card .pec-footer .spinner{right:0}body.rtl .proxy-element-card .pec-footer .spinner{left:0}.proxy-element-card hr{margin-left:var(--neg-padding);margin-right:var(--neg-padding)}
+/*# sourceMappingURL=shopifycp.css.map*/
\ No newline at end of file
diff --git a/src/web/assets/shopifycp/dist/css/shopifycp.css.map b/src/web/assets/shopifycp/dist/css/shopifycp.css.map
new file mode 100644
index 0000000..a15bc66
--- /dev/null
+++ b/src/web/assets/shopifycp/dist/css/shopifycp.css.map
@@ -0,0 +1 @@
+{"version":3,"file":"css/shopifycp.css","mappings":"AAEA,oBAGE,oBADA,iBADA,iBAEA,CAEA,gCAGE,aCEM,CDHN,cADA,kBAGA,WAEA,sCACE,aCFI,CDGJ,qBAGF,mDAKE,cAJA,kBACA,QAEA,uGCVI,CA+OR,4DACE,ODvOiB,CCyOnB,4DACE,MD1OiB,CAMf,yDACE,aCHE,CDON,2CACE,gBAGF,8CACE,cAIJ,gCAME,wBC3CM,CD4CN,6BC0EgB,CDzEhB,8BCyEgB,CD/EhB,SAGA,eAIA,kBARA,kBAEA,UAMA,CCyMF,yCACE,OD/Me,CCiNjB,yCACE,MDlNe,CAMf,kCACE,aCxCI,CDyCJ,0BAGF,wCACE,aChCI,CDiCJ,0BAGF,yCACE,kBACA,QAEA,wGC0LJ,kDACE,OD5LiB,CC8LnB,kDACE,MD/LiB,CAKnB,uBACE,+BACA","sources":["webpack:///./scss/shopifycp.scss","webpack:///../../../../../node_modules/craftcms-sass/_mixins.scss"],"sourcesContent":["@import \"node_modules/craftcms-sass/_mixins\";\n\n.proxy-element-card {\n position: relative;\n padding-top: 15px;\n padding-bottom: 40px;\n\n .pec-header {\n position: relative;\n display: block;\n color: $textColor;\n width: 100%;\n\n &:hover {\n color: $textColor;\n text-decoration: none;\n }\n\n .pec-external-icon {\n position: absolute;\n top: 50%;\n @include right(0px);\n transform: translate(-50%, -50%);\n color: $textColor;\n }\n\n &:hover {\n .pec-external-icon {\n color: $linkColor;\n }\n }\n\n .pec-title {\n margin-bottom: 0;\n }\n\n .pec-subtitle {\n margin: 0.2em 0;\n }\n }\n\n .pec-footer {\n position: absolute;\n bottom: 0;\n width: 100%;\n @include right(0);\n font-size: 12px;\n background-color: $grey100;\n border-bottom-left-radius: $largeBorderRadius;\n border-bottom-right-radius: $largeBorderRadius;\n padding: 10px 24px;\n a {\n color: $textColor;\n text-decoration: underline;\n }\n\n a:hover {\n color: $linkColor;\n text-decoration: underline;\n }\n\n .spinner {\n position: absolute;\n top: 50%;\n @include right(0px);\n transform: translate(-50%, -50%);\n }\n }\n\n hr {\n margin-left: var(--neg-padding);\n margin-right: var(--neg-padding);\n }\n}\n","$white: #fff;\n$black: #000;\n\n$grey050: hsl(212, 60%, 97%);\n$grey100: hsl(212, 50%, 93%);\n$grey200: hsl(212, 30%, 85%);\n$grey300: hsl(211, 13%, 65%);\n$grey350: hsl(211, 11%, 59%);\n$grey400: hsl(210, 10%, 53%);\n$grey500: hsl(211, 12%, 43%);\n$grey550: hsl(210, 13%, 40%);\n$grey600: hsl(209, 14%, 37%);\n$grey700: hsl(209, 18%, 30%);\n$grey800: hsl(209, 20%, 25%);\n$grey900: hsl(210, 24%, 16%);\n$grey1000: hsl(210, 24%, 10%);\n\n$blue050: #E3F8FF;\n$blue100: #B3ECFF;\n$blue200: #81DEFD;\n$blue300: #5ED0FA;\n$blue400: #40C3F7;\n$blue500: #2BB0ED;\n$blue600: #1992D4;\n$blue700: #127FBF;\n$blue800: #0B69A3;\n$blue900: #035388;\n\n$cyan050: #E0FCFF;\n$cyan100: #BEF8FD;\n$cyan200: #87EAF2;\n$cyan300: #54D1DB;\n$cyan400: #38BEC9;\n$cyan500: #2CB1BC;\n$cyan600: #14919B;\n$cyan700: #0E7C86;\n$cyan800: #0A6C74;\n$cyan900: #044E54;\n\n$pink050: #FFE3EC;\n$pink100: #FFB8D2;\n$pink200: #FF8CBA;\n$pink300: #F364A2;\n$pink400: #E8368F;\n$pink500: #DA127D;\n$pink600: #BC0A6F;\n$pink700: #A30664;\n$pink800: #870557;\n$pink900: #620042;\n\n$red050: #FFE3E3;\n$red100: #FFBDBD;\n$red200: #FF9B9B;\n$red300: #F86A6A;\n$red400: #EF4E4E;\n$red500: #E12D39;\n$red600: #CF1124;\n$red700: #AB091E;\n$red800: #8A041A;\n$red900: #610316;\n\n$yellow050: #FFFBEA;\n$yellow100: #FFF3C4;\n$yellow200: #FCE588;\n$yellow300: #FADB5F;\n$yellow400: #F7C948;\n$yellow500: #F0B429;\n$yellow600: #DE911D;\n$yellow700: #CB6E17;\n$yellow800: #B44D12;\n$yellow900: #8D2B0B;\n\n$teal050: #EFFCF6;\n$teal100: #C6F7E2;\n$teal200: #8EEDC7;\n$teal300: #65D6AD;\n$teal400: #3EBD93;\n$teal500: #27AB83;\n$teal600: #199473;\n$teal700: #147D64;\n$teal800: #0C6B58;\n$teal900: #014D40;\n\n// submit button colors\n$primaryColor: $red500;\n$secondaryColor: $grey500;\n\n$inputColor: hsl(212, 25%, 50%);\n\n// text colors\n$textColor: $grey700;\n$mediumDarkTextColor: $grey550;\n$mediumTextColor: $grey550;\n$lightTextColor: $grey500;\n$linkColor: $blue800;\n\n// hairline colors\n$hairlineColor: transparentize($grey800, 0.9);\n$mediumHairlineColor: transparentize($grey600, 0.75);\n$darkHairlineColor: transparentize($grey400, 0.5);\n\n// focus colors\n$lightFocusColor: $blue600;\n$darkFocusColor: $blue700;\n\n// focus rings\n$lightFocusRing: 0 0 0 1px $lightFocusColor, 0 0 0 3px transparentize($lightFocusColor, 0.5);\n$darkFocusRing: 0 0 0 1px $darkFocusColor, 0 0 0 3px transparentize($darkFocusColor, 0.5);\n\n// selection colors\n$lightSelColor: $grey200;\n$darkSelColor: $grey600;\n\n// alert/notice colors\n$errorColor: $red600;\n$warningColor: $yellow800;\n$successColor: $teal500;\n$noticeColor: $blue800;\n\n// UI element styles\n$smallBorderRadius: 3px;\n$mediumBorderRadius: 4px;\n$largeBorderRadius: 5px;\n\n$checkboxSize: 16px;\n$radioSize: 16px;\n\n@mixin sans-serif-font {\n font-family: system-ui, BlinkMacSystemFont, -apple-system, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n}\n\n@mixin fixed-width-font {\n font-family: \"SFMono-Regular\", Consolas, \"Liberation Mono\", Menlo, Courier, monospace;\n font-size: 0.9em !important;\n}\n\n// Other\n\n@mixin svg-mask($color) {\n rect, circle, ellipse, line, polyline, polygon, path, text {\n fill: $color;\n stroke-width: 0;\n transition: fill linear 100ms;\n }\n}\n\n@mixin icon {\n font-family: 'Craft';\n speak: none;\n -webkit-font-feature-settings: \"liga\", \"dlig\";\n -moz-font-feature-settings: \"liga=1, dlig=1\";\n -moz-font-feature-settings: \"liga\", \"dlig\";\n -ms-font-feature-settings: \"liga\", \"dlig\";\n -o-font-feature-settings: \"liga\", \"dlig\";\n font-feature-settings: \"liga\", \"dlig\";\n text-rendering: optimizeLegibility;\n font-weight: normal;\n font-variant: normal;\n text-transform: none;\n line-height: 1;\n direction: ltr; // Fixes a rendering issue in Chrome/Win\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n\n display: inline-block;\n text-align: center;\n font-style: normal;\n vertical-align: middle;\n word-wrap: normal !important;\n user-select: none;\n\n opacity: 0.8;\n}\n\n@mixin angle($dir: down, $color: $mediumTextColor) {\n display: block;\n content: '';\n font-size: 0;\n width: 5px;\n height: 5px;\n border: solid $color;\n border-width: 0 2px 2px 0;\n\n @if $dir == up {\n transform: rotate(225deg);\n } @else if $dir == down {\n transform: rotate(45deg);\n } @else if $dir == left {\n body.ltr & {\n transform: rotate(135deg);\n }\n body.rtl & {\n transform: rotate(-45deg);\n }\n } @else if $dir == right {\n body.ltr & {\n transform: rotate(-45deg);\n }\n body.rtl & {\n transform: rotate(135deg);\n }\n }\n}\n\n@mixin clearafter {\n content: '';\n display: block;\n height: 0;\n clear: both;\n visibility: hidden;\n}\n\n@mixin shadow {\n box-shadow: 0 1px 5px -1px transparentize($grey900, 0.8);\n}\n\n@mixin pane {\n background: $white;\n box-shadow: 0 0 0 1px transparentize($grey200, 0.75), 0 2px 12px transparentize($grey200, 0.5);\n\n &:focus {\n box-shadow: $darkFocusRing\n }\n}\n\n@mixin modal {\n border-radius: $largeBorderRadius;\n background-color: $white;\n box-shadow: 0 25px 100px transparentize($grey900, 0.5);\n}\n\n@mixin light-on-dark-text() {\n // Make light on dark text sharp on Macs\n // (sub-pixel antialiasing looks too bold/blurry with light text on dark background)\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-weight: 500;\n}\n\n// RTL stuff\n\n@mixin left($left) {\n body.ltr & {\n left: $left;\n }\n body.rtl & {\n right: $left;\n }\n}\n\n@mixin right($right) {\n body.ltr & {\n right: $right;\n }\n body.rtl & {\n left: $right;\n }\n}\n\n@mixin alignleft {\n body.ltr & {\n text-align: left;\n }\n body.rtl & {\n text-align: right;\n }\n}\n\n@mixin alignright {\n body.ltr & {\n text-align: right;\n }\n body.rtl & {\n text-align: left;\n }\n}\n\n@mixin border-left($params...) {\n body.ltr & {\n border-left: $params;\n }\n body.rtl & {\n border-right: $params;\n }\n}\n\n@mixin border-right($params...) {\n body.ltr & {\n border-right: $params;\n }\n body.rtl & {\n border-left: $params;\n }\n}\n\n@mixin border-left-width($param) {\n body.ltr & {\n border-left-width: $param;\n }\n body.rtl & {\n border-right-width: $param;\n }\n}\n\n@mixin border-right-width($param) {\n body.ltr & {\n border-right-width: $param;\n }\n body.rtl & {\n border-left-width: $param;\n }\n}\n\n@mixin border-radius($tl, $tr, $br, $bl) {\n body.ltr & {\n border-radius: $tl $tr $br $bl;\n }\n body.rtl & {\n border-radius: $tr $tl $bl $br;\n }\n}\n\n@mixin border-top-left-radius($params...) {\n body.ltr & {\n border-top-left-radius: $params;\n }\n body.rtl & {\n border-top-right-radius: $params;\n }\n}\n\n@mixin border-top-right-radius($params...) {\n body.ltr & {\n border-top-right-radius: $params;\n }\n body.rtl & {\n border-top-left-radius: $params;\n }\n}\n\n@mixin border-bottom-left-radius($params...) {\n body.ltr & {\n border-bottom-left-radius: $params;\n }\n body.rtl & {\n border-bottom-right-radius: $params;\n }\n}\n\n@mixin border-bottom-right-radius($params...) {\n body.ltr & {\n border-bottom-right-radius: $params;\n }\n body.rtl & {\n border-bottom-left-radius: $params;\n }\n}\n\n@mixin floatleft {\n body.ltr & {\n float: left;\n }\n body.rtl & {\n float: right;\n }\n}\n\n@mixin floatright {\n body.ltr & {\n float: right;\n }\n body.rtl & {\n float: left;\n }\n}\n\n@mixin margin($t, $r, $b, $l, $important: '') {\n body.ltr & {\n margin: $t $r $b $l unquote($important);\n }\n body.rtl & {\n margin: $t $l $b $r unquote($important);\n }\n}\n\n@mixin margin-left($margin...) {\n body.ltr & {\n margin-left: $margin;\n }\n body.rtl & {\n margin-right: $margin;\n }\n}\n\n@mixin margin-right($margin...) {\n body.ltr & {\n margin-right: $margin;\n }\n body.rtl & {\n margin-left: $margin;\n }\n}\n\n@mixin padding($t, $r, $b, $l, $important: '') {\n body.ltr & {\n padding: $t $r $b $l unquote($important);\n }\n body.rtl & {\n padding: $t $l $b $r unquote($important);\n }\n}\n\n@mixin padding-left($padding...) {\n body.ltr & {\n padding-left: $padding;\n }\n body.rtl & {\n padding-right: $padding;\n }\n}\n\n@mixin padding-right($padding...) {\n body.ltr & {\n padding-right: $padding;\n }\n body.rtl & {\n padding-left: $padding;\n }\n}\n\n// Misc\n\n@mixin dark-inputs {\n @include placeholder-styles($grey400);\n\n .btn,\n .select:not(.selectize) select {\n background-color: $grey200;\n\n &:focus,\n &:hover {\n background-color: darken($grey200, 5%);\n }\n\n &:active,\n &.active {\n background-color: darken($grey200, 10%);\n }\n }\n\n .text {\n background-color: $grey200;\n\n &:focus {\n background-color: darken($grey200, 5%);\n }\n }\n}\n\n@mixin h6-styles {\n margin: 14px 0 3px;\n font-size: 10px;\n line-height: 1.2;\n color: $lightTextColor;\n text-transform: uppercase;\n font-weight: bold;\n}\n\n@mixin token-styles {\n display: inline-block;\n border-radius: 10px;\n padding: 2px 7px;\n font-size: 12px;\n line-height: 14px;\n color: $textColor;\n background-color: transparentize($white, 0.5);\n box-shadow: 0 0 0 1px $darkHairlineColor;\n}\n\n@mixin menu-styles {\n z-index: 100;\n border-radius: $mediumBorderRadius;\n padding: 0 14px;\n overflow: auto;\n background: $white;\n user-select: none;\n box-shadow: 0 0 0 1px transparentize($grey900, 0.9), 0 5px 20px transparentize($grey900, 0.75);\n}\n\n@mixin menu-option-styles {\n margin: 0 -14px;\n padding: 10px 14px;\n color: $textColor;\n text-decoration: none;\n white-space: nowrap;\n}\n\n@mixin menu-option-active-styles {\n color: $textColor;\n background-color: $grey050;\n}\n\n@mixin input-styles {\n border-radius: $smallBorderRadius;\n border: 1px solid transparentize($inputColor, 0.75);\n background-color: hsl(212, 50%, 99%);\n background-clip: padding-box;\n}\n\n@mixin input-focused-styles {\n border-color: $darkFocusColor;\n box-shadow: 0 0 0 2px transparentize($darkFocusColor, 0.5);\n}\n\n@mixin placeholder-styles($color) {\n ::-webkit-input-placeholder {\n color: $color;\n }\n\n input:-ms-input-placeholder {\n color: $color;\n }\n\n ::-ms-input-placeholder {\n color: $color;\n }\n\n :-moz-placeholder {\n color: $color;\n }\n\n ::-moz-placeholder {\n color: $color;\n }\n\n ::placeholder {\n color: $color;\n }\n}\n\n@mixin select-styles {\n position: relative;\n border-radius: $largeBorderRadius;\n white-space: nowrap;\n}\n\n@mixin select-container-styles {\n max-width: 100%;\n position: relative;\n :not(.flex) > & {\n display: inline-block;\n }\n}\n\n@mixin select-arrow-styles {\n @include angle;\n position: absolute;\n z-index: 1;\n top: calc(50% - 5px);\n @include right(9px);\n user-select: none;\n pointer-events: none;\n}\n\n@mixin select-input-styles {\n display: block;\n position: relative;\n max-width: 100%;\n border: none;\n @include padding(7px, 22px, 7px, 10px);\n font-size: 14px;\n line-height: 20px;\n color: $textColor;\n background-color: transparentize($inputColor, 0.75);\n appearance: none;\n // from https://stackoverflow.com/a/15933790/1688568\n &::-ms-expand {\n display: none;\n }\n}\n\n@mixin select-input-fullwidth-styles {\n min-width: 100%;\n}\n\n@mixin select-input-focused-styles {\n outline-color: transparent;\n background-color: transparentize($inputColor, 0.5);\n}\n\n@mixin readable {\n font-size: 16px;\n line-height: 22px;\n\n h1, h2, h3, h4, h5, h6 {\n margin: 24px 0 16px;\n font-weight: 600;\n }\n\n h1 {\n font-size: 32px;\n line-height: 40px;\n color: #000;\n }\n\n h2 {\n font-size: 24px;\n line-height: 30px;\n }\n\n h3 {\n font-size: 20px;\n line-height: 24px;\n }\n\n h4 {\n font-size: 16px;\n line-height: 20px;\n }\n\n h5 {\n font-size: 14px;\n line-height: 18px;\n }\n\n h6 {\n font-size: 13.6px;\n line-height: 17px;\n color: $mediumTextColor;\n }\n\n ul,\n ol {\n margin: 1em 0;\n @include padding-left(2em);\n }\n\n ul li {\n list-style-type: disc;\n }\n\n li + li {\n margin-top: 0.25em;\n }\n\n blockquote {\n margin: 16px 0;\n\n &:not(.note) {\n padding: 0 16px;\n color: $mediumTextColor;\n @include border-left(4px solid $hairlineColor);\n }\n\n &.note {\n position: relative;\n border-radius: 4px;\n padding: 1em;\n @include padding-left(56px);\n border: 1px solid;\n\n &:not(.tip):not(.warning) {\n border-color: $errorColor;\n color: #bf503f;\n\n &:before {\n content: 'alert';\n color: $errorColor;\n }\n }\n\n &.tip {\n border-color: $linkColor;\n color: $mediumTextColor;\n\n &:before {\n content: 'lightbulb';\n color: $linkColor;\n }\n }\n\n &.warning {\n border-color: $warningColor;\n color: #cf783a;\n\n &:before {\n content: 'alert';\n color: $warningColor;\n }\n }\n\n &:before {\n @include icon;\n position: absolute;\n top: 12px;\n @include left(16px);\n font-size: 30px;\n width: 24px;\n }\n }\n }\n}\n"],"names":[],"sourceRoot":""}
\ No newline at end of file
diff --git a/src/web/assets/shopifycp/dist/shopifycp.js b/src/web/assets/shopifycp/dist/shopifycp.js
new file mode 100644
index 0000000..9a8e25d
--- /dev/null
+++ b/src/web/assets/shopifycp/dist/shopifycp.js
@@ -0,0 +1,2 @@
+!function(){var e={699:function(){function e(t){return e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e(t)}jQuery,"undefined"===e(Craft.Shopify)&&(Craft.Shopify={})},532:function(){},525:function(e,t,n){var r=n(532);r.__esModule&&(r=r.default),"string"==typeof r&&(r=[[e.id,r,""]]),r.locals&&(e.exports=r.locals),(0,n(673).Z)("3f65cd01",r,!0,{})},673:function(e,t,n){"use strict";function r(e,t){for(var n=[],r={},o=0;o