├── .browserslistrc ├── .editorconfig ├── .eslintrc.js ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── 1-Bug-report.md │ └── 2-Enhancement.md ├── label-sync-config.json ├── pull_request_template.md └── workflows │ ├── approved-with-labels.yml │ ├── e2e-tests.yml │ ├── linting.yml │ └── php-coding-standards.yml ├── .gitignore ├── .nvmrc ├── .prettierrc.js ├── .stylelintignore ├── .stylelintrc.json ├── .wp-env.json ├── 404.php ├── CONTRIBUTING.md ├── README.md ├── README.txt ├── STOREFRONT_STATUS.md ├── archive.php ├── assets ├── css │ ├── admin │ │ ├── admin.scss │ │ ├── buttons.scss │ │ ├── customizer │ │ │ └── customizer.scss │ │ ├── plugin-install.scss │ │ └── welcome-screen │ │ │ └── welcome.scss │ ├── base │ │ ├── _base.scss │ │ ├── _layout.scss │ │ ├── gutenberg-blocks.scss │ │ ├── gutenberg-editor.scss │ │ └── icons.scss │ ├── jetpack │ │ ├── infinite-scroll.scss │ │ └── widgets.scss │ ├── sass │ │ ├── utils │ │ │ ├── _mixins.scss │ │ │ └── _variables.scss │ │ └── vendors │ │ │ ├── _modular-scale.scss │ │ │ ├── _normalize.scss │ │ │ ├── font-awesome │ │ │ ├── _animated.scss │ │ │ ├── _bordered-pulled.scss │ │ │ ├── _core.scss │ │ │ ├── _fixed-width.scss │ │ │ ├── _icons.scss │ │ │ ├── _larger.scss │ │ │ ├── _list.scss │ │ │ ├── _mixins.scss │ │ │ ├── _rotated-flipped.scss │ │ │ ├── _screen-reader.scss │ │ │ ├── _shims.scss │ │ │ ├── _stacked.scss │ │ │ ├── _variables.scss │ │ │ ├── brands.scss │ │ │ ├── fontawesome.scss │ │ │ ├── regular.scss │ │ │ ├── solid.scss │ │ │ └── v4-shims.scss │ │ │ └── modular-scale │ │ │ ├── _calc.scss │ │ │ ├── _function-list.scss │ │ │ ├── _function.scss │ │ │ ├── _generate-list.scss │ │ │ ├── _pow.scss │ │ │ ├── _ratios.scss │ │ │ ├── _respond.scss │ │ │ ├── _round-px.scss │ │ │ ├── _sort-list.scss │ │ │ └── _tests.scss │ └── woocommerce │ │ ├── extensions │ │ ├── advanced-product-labels.scss │ │ ├── ajax-layered-nav.scss │ │ ├── bookings.scss │ │ ├── brands.scss │ │ ├── bundles.scss │ │ ├── composite-products.scss │ │ ├── deposits.scss │ │ ├── memberships.scss │ │ ├── mix-and-match.scss │ │ ├── photography.scss │ │ ├── product-recommendations.scss │ │ ├── product-reviews-pro.scss │ │ ├── quick-view.scss │ │ ├── ship-multiple-addresses.scss │ │ ├── smart-coupons.scss │ │ ├── variation-swatches.scss │ │ └── wishlists.scss │ │ └── woocommerce.scss ├── fonts │ ├── fa-brands-400.eot │ ├── fa-brands-400.svg │ ├── fa-brands-400.ttf │ ├── fa-brands-400.woff │ ├── fa-brands-400.woff2 │ ├── fa-regular-400.eot │ ├── fa-regular-400.svg │ ├── fa-regular-400.ttf │ ├── fa-regular-400.woff │ ├── fa-regular-400.woff2 │ ├── fa-solid-900.eot │ ├── fa-solid-900.svg │ ├── fa-solid-900.ttf │ ├── fa-solid-900.woff │ └── fa-solid-900.woff2 ├── images │ ├── admin │ │ ├── storefront-icon.svg │ │ └── welcome-screen │ │ │ ├── automattic.png │ │ │ ├── child-themes.jpg │ │ │ └── storefront-bundle-hero.png │ ├── credit-cards │ │ ├── amex.svg │ │ ├── diners.svg │ │ ├── discover.svg │ │ ├── jcb.svg │ │ ├── laser.svg │ │ ├── maestro.svg │ │ ├── mastercard.svg │ │ ├── paypal.svg │ │ ├── unknown.svg │ │ └── visa.svg │ └── customizer │ │ ├── controls │ │ ├── 2cl.png │ │ └── 2cr.png │ │ └── starter-content │ │ ├── categories │ │ ├── accessories.jpg │ │ ├── hoodies.jpg │ │ └── tshirts.jpg │ │ ├── hero.jpg │ │ └── products │ │ ├── beanie.jpg │ │ ├── belt.jpg │ │ ├── cap.jpg │ │ ├── hoodie-with-logo.jpg │ │ ├── hoodie-with-pocket.jpg │ │ ├── hoodie-with-zipper.jpg │ │ ├── hoodie.jpg │ │ ├── long-sleeve-tee.jpg │ │ ├── polo.jpg │ │ ├── sunglasses.jpg │ │ ├── tshirt.jpg │ │ └── vneck-tee.jpg └── js │ ├── admin │ ├── admin.js │ ├── customizer.js │ └── plugin-install.js │ ├── footer.js │ ├── homepage.js │ ├── navigation.js │ ├── sticky-add-to-cart.js │ └── woocommerce │ ├── extensions │ └── brands.js │ └── header-cart.js ├── comments.php ├── composer.json ├── composer.lock ├── content-homepage.php ├── content-none.php ├── content-page.php ├── content-single.php ├── content.php ├── e2e └── specs │ └── browser.test.js ├── footer.php ├── functions.php ├── header.php ├── inc ├── admin │ ├── class-storefront-admin.php │ └── class-storefront-plugin-install.php ├── class-storefront.php ├── customizer │ ├── class-storefront-customizer-control-arbitrary.php │ ├── class-storefront-customizer-control-more.php │ ├── class-storefront-customizer-control-radio-image.php │ └── class-storefront-customizer.php ├── jetpack │ └── class-storefront-jetpack.php ├── nux │ ├── class-storefront-nux-admin-inbox-messages-customize.php │ ├── class-storefront-nux-admin.php │ ├── class-storefront-nux-guided-tour.php │ └── class-storefront-nux-starter-content.php ├── storefront-functions.php ├── storefront-template-functions.php ├── storefront-template-hooks.php ├── woocommerce │ ├── class-storefront-woocommerce-adjacent-products.php │ ├── class-storefront-woocommerce-customizer.php │ ├── class-storefront-woocommerce.php │ ├── storefront-woocommerce-functions.php │ ├── storefront-woocommerce-template-functions.php │ └── storefront-woocommerce-template-hooks.php └── wordpress-shims.php ├── index.php ├── languages ├── README.md └── storefront.pot ├── loop.php ├── package-lock.json ├── package.json ├── page.php ├── phpcs.xml ├── renovate.json ├── screenshot.png ├── search.php ├── sidebar.php ├── single.php ├── style.scss ├── template-fullwidth.php ├── template-homepage.php └── validate-build.sh /.browserslistrc: -------------------------------------------------------------------------------- 1 | extends @wordpress/browserslist-config 2 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | 4 | # WordPress Coding Standards 5 | # https://make.wordpress.org/core/handbook/coding-standards/ 6 | 7 | root = true 8 | 9 | [*] 10 | charset = utf-8 11 | end_of_line = lf 12 | indent_size = 4 13 | tab_width = 4 14 | indent_style = tab 15 | insert_final_newline = true 16 | trim_trailing_whitespace = true 17 | 18 | [*.txt] 19 | trim_trailing_whitespace = false 20 | 21 | [*.{md,yml}] 22 | trim_trailing_whitespace = false 23 | indent_style = space 24 | indent_size = 2 25 | 26 | [*.json] 27 | indent_style = tab 28 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [ 'plugin:@woocommerce/eslint-plugin/recommended' ], 3 | globals: { 4 | jQuery: 'readonly', 5 | }, 6 | settings: {}, 7 | rules: { 8 | 'woocommerce/feature-flag': 'off', 9 | '@wordpress/no-global-active-element': 'warn', 10 | camelcase: 'off', 11 | '@typescript-eslint/no-this-alias': 'off', 12 | }, 13 | ignorePatterns: [ '**/*.min.js' ], 14 | }; 15 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Define @woocommerce/kirigami, as the code owners of the repo so the team is 2 | # tagged to review new PRs automatically. 3 | * @woocommerce/kirigami 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/1-Bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F41E Bug report" 3 | about: Report a bug if something isn't working as expected in Storefront. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Describe the bug 11 | Clearly describe the issue. Please be as descriptive as possible; issues lacking detail, or for any other reason than to report a bug, may be closed without action. 12 | 13 | Isolating the problem (mark completed items with an [x]): 14 | - [ ] I have deactivated other plugins and themes and confirmed this bug occurs when only WooCommerce + Storefront theme are active. 15 | - [ ] I can reproduce this bug consistently using the steps below. 16 | 17 | ## To Reproduce 18 | Steps to reproduce the behavior: 19 | 1. Go to '...' 20 | 2. Click on '....' 21 | 3. Scroll down to '....' 22 | 4. See error 23 | 24 | ## Screenshots 25 | If applicable, add screenshots to help explain your problem. 26 | 27 | ## Expected behavior 28 | A clear and concise description of what you expected to happen. 29 | 30 | ### Browser Environment 31 | Please provide as much detail as possible about your testing environment. 32 | 33 | - Platform: e.g. macOS, Windows, iOS 34 | - Browser(s): 35 | 36 | ### WordPress Environment 37 | Please provide relevant details of your WordPress setup and server environment. 38 | 39 |
40 | ``` 41 | Copy and paste the system status report from WooCommerce > System Status in WordPress admin. 42 | ``` 43 |
44 | 45 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/2-Enhancement.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "✨ Enhancement" 3 | about: If you have an idea to improve Storefront, please let us know – or submit a Pull Request! 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Is your feature request related to a problem? Please describe. 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | ## Describe the solution you'd like 14 | A clear and concise description of what you want to happen. 15 | 16 | ## Describe alternatives you've considered 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | ## Additional context 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/label-sync-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "category: accessibility", 4 | "color": "5804ea", 5 | "aliases": [ "scope: accessibility", "Accessibility" ], 6 | "description": "The issue/PR is related to accessibility." 7 | }, 8 | { 9 | "name": "category: duplicate", 10 | "color": "5804ea", 11 | "aliases": [ "Invalid / Duplicate" ], 12 | "description": "The issue/PR is a duplicate of another issue." 13 | }, 14 | { 15 | "name": "category: i18n", 16 | "color": "5804ea", 17 | "aliases": [ "scope: i18n" ], 18 | "description": "The issue/PR is related to internationalization." 19 | }, 20 | { 21 | "name": "category: performance", 22 | "color": "5804ea", 23 | "aliases": [ "type: performance" ], 24 | "description": "The issue/PR is related to performance." 25 | }, 26 | { 27 | "name": "category: refactor", 28 | "color": "5804ea", 29 | "aliases": [ "type: refactor", "Type: Refactor" ], 30 | "description": "The issue/PR is related to refactoring." 31 | }, 32 | { 33 | "name": "category: won't fix", 34 | "color": "5804ea", 35 | "aliases": [ "Status: Won't Fix" ], 36 | "description": "The issue won’t be fixed." 37 | }, 38 | { 39 | "name": "category: styles", 40 | "color": "5804ea", 41 | "aliases": [ "scope: styles" ], 42 | "description": "Issues related to styling" 43 | }, 44 | { 45 | "name": "good first issue", 46 | "color": "1eff05", 47 | "aliases": [ "type: good first issue", "[Type] Good First Change", "Help Wanted" ], 48 | "description": "The issue is a good candidate for the first community contribution/for a newcomer to the team." 49 | }, 50 | { 51 | "name": "impact: high", 52 | "color": "d73a4a", 53 | "aliases": [], 54 | "description": "This issue impacts a lot of users as reported by our Happiness Engineers." 55 | }, 56 | { 57 | "name": "needs design", 58 | "color": "ed95d2", 59 | "aliases": [ "action: needs design", "[Status] Needs Design", "Status: Needs Design" ], 60 | "description": "The issue requires design input/work from a designer." 61 | }, 62 | { 63 | "name": "needs docs", 64 | "color": "ed95d2", 65 | "aliases": [ "Status: Needs Docs" ], 66 | "description": "The issue/PR requires documentation to be added." 67 | }, 68 | { 69 | "name": "needs feedback", 70 | "color": "ed95d2", 71 | "aliases": [ "action: needs feedback", "[Status] Needs Discussion", "Status: Needs Author Feedback" ], 72 | "description": "The issue/PR needs a response from any of the parties involved in the issue." 73 | }, 74 | { 75 | "name": "needs tests", 76 | "color": "ed95d2", 77 | "aliases": [ "scope: tests", "[Type] E2E" ], 78 | "description": "The issue/PR needs tests before it can move forward." 79 | }, 80 | { 81 | "name": "priority: critical", 82 | "color": "d73a4a", 83 | "aliases": [ "[Pri] CRITICAL", "Priority: Critical" ], 84 | "description": "The issue is critical—e.g. a fatal error, security problem affecting many customers." 85 | }, 86 | { 87 | "name": "priority: high", 88 | "color": "d93f0b", 89 | "aliases": [ "[Pri] High", "Priority: High" ], 90 | "description": "The issue/PR is high priority—it affects lots of customers substantially, but not critically." 91 | }, 92 | { 93 | "name": "priority: low", 94 | "color": "e2f78c", 95 | "aliases": [ "[Pri] Low", "Priority: Low" ], 96 | "description": "The issue/PR is low priority—not many people are affected or there’s a workaround, etc." 97 | }, 98 | { 99 | "name": "status: blocked", 100 | "color": "d73a4a", 101 | "aliases": [ "status: blocked", "[Status] Blocked", "Status: Blocked/Hold" ], 102 | "description": "The issue is blocked from progressing, waiting for another piece of work to be done." 103 | }, 104 | { 105 | "name": "status: on hold", 106 | "color": "d93f0b", 107 | "aliases": [], 108 | "description": "The issue is currently not prioritized." 109 | }, 110 | { 111 | "name": "type: bug", 112 | "color": "d73a4a", 113 | "aliases": [ "type: bug", "[Type] Bug" ], 114 | "description": "The issue is a confirmed bug." 115 | }, 116 | { 117 | "name": "type: documentation", 118 | "color": "0075ca", 119 | "aliases": [ "scope: documentation" ], 120 | "description": "This issue is a request for better documentation." 121 | }, 122 | { 123 | "name": "type: enhancement", 124 | "color": "0075ca", 125 | "aliases": [ "type: enhancement", "[Type] Enhancement", "Type: Enhancement" ], 126 | "description": "The issue is a request for an enhancement." 127 | }, 128 | { 129 | "name": "type: question", 130 | "color": "0075ca", 131 | "aliases": [ "type: support", "[Type] Question", "Question" ], 132 | "description": "The issue is a question about how code works." 133 | }, 134 | { 135 | "name": "type: task", 136 | "color": "0075ca", 137 | "aliases": [ "[Type] Task" ], 138 | "description": "The issue is an internally driven task (e.g. from another A8c team)." 139 | }, 140 | { 141 | "name": "type: technical debt", 142 | "color": "0075ca", 143 | "aliases": [ "[Type] Technical Debt" ], 144 | "description": "This issue/PR represents/solves the technical debt of the project." 145 | }, 146 | { 147 | "name": "type: compatibility", 148 | "color": "0075ca", 149 | "aliases": [ "[Type] Compatibility" ] 150 | }, 151 | { 152 | "name": "type: build", 153 | "color": "0075ca", 154 | "aliases": [ "Type: build" ], 155 | "description": "Issues related to build processes" 156 | }, 157 | { 158 | "name": "status: needs review", 159 | "color": "fbca04", 160 | "aliases": [ "[Status] Needs Review", "Status: Needs Review" ], 161 | "description": "PR that needs review" 162 | } 163 | ] 164 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 2 | Fixes # 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | ### Screenshots 11 | 12 | 13 | ### How to test the changes in this Pull Request: 14 | 15 | 16 | 1. 17 | 2. 18 | 3. 19 | 20 | 21 | 22 | - 23 | - 24 | 25 | ### Changelog 26 | 27 | 28 | 29 | > Fix – Edit, reply and author icons are now displayed in comment list form. #1319 30 | 31 | 32 | -------------------------------------------------------------------------------- /.github/workflows/approved-with-labels.yml: -------------------------------------------------------------------------------- 1 | on: pull_request_review 2 | name: Add Labels to Approved Pull Requests 3 | jobs: 4 | labelWhenApproved: 5 | name: Label when approved 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: Label when approved 9 | uses: pullreminders/label-when-approved-action@master 10 | env: 11 | APPROVALS: "1" 12 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 13 | ADD_LABEL: "status: ready to merge" 14 | REMOVE_LABEL: "status:%20needs%20review" 15 | -------------------------------------------------------------------------------- /.github/workflows/e2e-tests.yml: -------------------------------------------------------------------------------- 1 | name: End-to-End Tests 2 | 3 | on: 4 | push: 5 | branches: [trunk] 6 | pull_request: 7 | jobs: 8 | Setup: 9 | name: Setup 10 | runs-on: ubuntu-22.04 11 | steps: 12 | - uses: actions/checkout@v3 13 | - name: Cache node modules 14 | uses: actions/cache@v3 15 | env: 16 | cache-name: cache-node-modules 17 | with: 18 | # npm cache files are stored in `~/.npm` on Linux/macOS 19 | path: ~/.npm 20 | key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} 21 | restore-keys: | 22 | ${{ runner.os }}-build-${{ env.cache-name }}- 23 | ${{ runner.os }}-build- 24 | ${{ runner.os }}- 25 | 26 | - name: Use Node.js 20.x 27 | uses: actions/setup-node@v3 28 | with: 29 | node-version: 20.x 30 | 31 | - name: Npm install and build 32 | run: | 33 | npm ci 34 | npm run build 35 | 36 | - name: Install WordPress 37 | run: | 38 | chmod -R 767 ./ # TODO: Possibly integrate in wp-env 39 | npm run wp-env start 40 | npm run wp-env run tests-cli wp theme activate storefront 41 | 42 | - name: Running the tests 43 | run: | 44 | npm run test:e2e 45 | 46 | - name: Archive debug artifacts (screenshots, HTML snapshots) 47 | uses: actions/upload-artifact@v3 48 | if: always() 49 | with: 50 | name: failures-artifacts 51 | path: artifacts 52 | -------------------------------------------------------------------------------- /.github/workflows/linting.yml: -------------------------------------------------------------------------------- 1 | name: JavaScript and CSS Linting 2 | on: 3 | pull_request: 4 | push: 5 | branches: [trunk] 6 | jobs: 7 | Setup: 8 | name: Setup for Jobs 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v3 13 | - name: Cache node modules 14 | uses: actions/cache@v3 15 | with: 16 | path: node_modules 17 | key: ${{ runner.OS }}-build-${{ hashFiles('**/package-lock.json') }} 18 | restore-keys: | 19 | ${{ runner.OS }}-build-${{ env.cache-name }}- 20 | ${{ runner.OS }}-build- 21 | ${{ runner.OS }}- 22 | - name: Install Node Dependencies 23 | run: npm install 24 | 25 | eslint: 26 | name: Lint JavaScript 27 | needs: Setup 28 | runs-on: ubuntu-latest 29 | steps: 30 | - uses: actions/checkout@v3 31 | - name: Cache node modules 32 | uses: actions/cache@v3 33 | with: 34 | path: node_modules 35 | key: ${{ runner.OS }}-build-${{ hashFiles('**/package-lock.json') }} 36 | restore-keys: | 37 | ${{ runner.OS }}-build-${{ env.cache-name }}- 38 | ${{ runner.OS }}-build- 39 | ${{ runner.OS }}- 40 | - name: Install Node Dependencies 41 | run: npm install 42 | - if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository }} 43 | name: Run ESLint 44 | run: npm run lint:js 45 | - if: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository }} 46 | name: Save Code Linting Report JSON 47 | run: npm run lint:js:report 48 | # Continue to the next step even if this fails 49 | continue-on-error: true 50 | - if: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository }} 51 | name: Upload ESLint report 52 | uses: actions/upload-artifact@v4 53 | with: 54 | name: eslint_report.json 55 | path: eslint_report.json 56 | - if: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository }} 57 | name: Annotate Code Linting Results 58 | uses: ataylorme/eslint-annotate-action@1.2.0 59 | with: 60 | repo-token: '${{ secrets.GITHUB_TOKEN }}' 61 | report-json: 'eslint_report.json' 62 | 63 | stylelint: 64 | name: Lint CSS 65 | needs: Setup 66 | runs-on: ubuntu-latest 67 | steps: 68 | - uses: actions/checkout@v3 69 | - name: Cache node modules 70 | uses: actions/cache@v3 71 | with: 72 | path: node_modules 73 | key: ${{ runner.OS }}-build-${{ hashFiles('**/package-lock.json') }} 74 | restore-keys: | 75 | ${{ runner.OS }}-build-${{ env.cache-name }}- 76 | ${{ runner.OS }}-build- 77 | ${{ runner.OS }}- 78 | - name: Install Node Dependencies 79 | run: npm install 80 | - name: Lint CSS 81 | run: npm run lint:css 82 | -------------------------------------------------------------------------------- /.github/workflows/php-coding-standards.yml: -------------------------------------------------------------------------------- 1 | name: PHP Coding Standards 2 | 3 | on: 4 | push: 5 | branches: 6 | - trunk 7 | pull_request: 8 | 9 | jobs: 10 | # Runs PHP coding standards checks. 11 | # Note: Inspired by https://github.com/WordPress/wordpress-develop/blob/master/.github/workflows/coding-standards.yml 12 | # 13 | # Violations are reported inline with annotations. 14 | # 15 | # Performs the following steps: 16 | # - Checks out the repository. 17 | # - Configures caching for Composer. 18 | # - Sets up PHP. 19 | # - Logs debug information. 20 | # - Installs Composer dependencies (from cache if possible). 21 | # - Logs PHP_CodeSniffer debug information. 22 | # - Runs PHPCS on the full codebase with warnings suppressed. 23 | # - todo: Configure Slack notifications for failing scans. 24 | phpcs: 25 | name: PHP coding standards 26 | runs-on: ubuntu-latest 27 | steps: 28 | - name: Checkout repository 29 | uses: actions/checkout@v3 30 | 31 | - name: Get Composer cache directory 32 | id: composer-cache 33 | run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT" 34 | 35 | - name: Set up Composer caching 36 | uses: actions/cache@v3 37 | env: 38 | cache-name: cache-composer-dependencies 39 | with: 40 | path: ${{ steps.composer-cache.outputs.dir }} 41 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} 42 | restore-keys: | 43 | ${{ runner.os }}-composer- 44 | - name: Set up PHP 45 | uses: shivammathur/setup-php@v2 46 | with: 47 | php-version: '7.4' 48 | coverage: none 49 | tools: composer, cs2pr 50 | 51 | - name: Log debug information 52 | run: | 53 | php --version 54 | composer --version 55 | - name: Install Composer dependencies 56 | run: | 57 | composer install --prefer-dist --no-suggest --no-progress --no-ansi --no-interaction 58 | echo "${PWD}/vendor/bin" >> $GITHUB_PATH 59 | - name: Log PHPCS debug information 60 | run: phpcs -i 61 | 62 | - name: Run PHPCS on all files 63 | run: phpcs ./inc -q -n --report=checkstyle | cs2pr 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled CSS 2 | *.css 3 | 4 | # Minified js 5 | *.min.js 6 | /assets/js/vendor/*.min.js 7 | /assets/js/editor.js 8 | 9 | # Sass 10 | .sass-cache 11 | node_modules 12 | storefront 13 | storefront.zip 14 | npm-debug.log 15 | 16 | # Codekit 17 | config.codekit 18 | 19 | # Transifex 20 | .transifexrc 21 | /languages/*.po 22 | /languages/*.mo 23 | 24 | # PhpStorm 25 | .idea 26 | 27 | # macOS 28 | .DS_Store 29 | 30 | # Composer 31 | vendor 32 | /eslint_report.json 33 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 20.11.1 2 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = require( '@wordpress/prettier-config' ); 2 | -------------------------------------------------------------------------------- /.stylelintignore: -------------------------------------------------------------------------------- 1 | assets/css/sass/vendors/** 2 | *.js 3 | -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@wordpress/stylelint-config/scss", 3 | "rules": { 4 | "at-rule-empty-line-before": null, 5 | "at-rule-no-unknown": null, 6 | "comment-empty-line-before": null, 7 | "declaration-block-no-duplicate-properties": null, 8 | "declaration-property-unit-allowed-list": null, 9 | "font-weight-notation": null, 10 | "max-line-length": null, 11 | "no-descending-specificity": null, 12 | "no-duplicate-selectors": null, 13 | "rule-empty-line-before": null, 14 | "selector-class-pattern": null, 15 | "value-keyword-case": null, 16 | "font-family-no-missing-generic-family-keyword": null, 17 | "selector-id-pattern": null, 18 | "scss/selector-no-redundant-nesting-selector": null, 19 | "scss/no-global-function-names": null 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.wp-env.json: -------------------------------------------------------------------------------- 1 | { 2 | "core": null, 3 | "plugins": [ 4 | "https://downloads.wordpress.org/plugin/woocommerce.latest-stable.zip" 5 | ], 6 | "themes": ["./"], 7 | "port": 8801, 8 | "testsPort": 8802 9 | } 10 | -------------------------------------------------------------------------------- /404.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | 12 |
13 | 14 |
15 | 16 |
17 | 18 | 21 | 22 |

23 | 24 | '; 26 | 27 | if ( storefront_is_woocommerce_activated() ) { 28 | the_widget( 'WC_Widget_Product_Search' ); 29 | } else { 30 | get_search_form(); 31 | } 32 | 33 | echo ''; 34 | 35 | if ( storefront_is_woocommerce_activated() ) { 36 | 37 | echo '
'; 38 | 39 | echo '
'; 40 | 41 | storefront_promoted_products(); 42 | 43 | echo '
'; 44 | 45 | echo ''; 57 | 58 | echo '
'; 59 | 60 | echo '
'; 61 | 62 | echo '

' . esc_html__( 'Popular Products', 'storefront' ) . '

'; 63 | 64 | $shortcode_content = storefront_do_shortcode( 65 | 'best_selling_products', 66 | array( 67 | 'per_page' => 4, 68 | 'columns' => 4, 69 | ) 70 | ); 71 | 72 | echo $shortcode_content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 73 | 74 | echo '
'; 75 | } 76 | ?> 77 | 78 |
79 |
80 | 81 |
82 |
83 | 84 | 2 | Storefront 3 | 4 | 5 |

6 | license 7 | Designed for WooCommerce 8 | WordPress.org downloads 9 | WordPress.org rating 10 |

11 | 12 | _Storefront_ is a robust and flexible [WordPress](https://wordpress.org) theme, designed and built by the team at [WooCommerce](https://woocommerce.com/) to help you make the most out of using the [WooCommerce](https://woocommerce.com) plugin to power your online store. It's available to download for free from the WordPress [theme repository](https://wordpress.org/themes/storefront/). 13 | 14 | It features deep integration with WooCommerce core plus several of the most popular extensions: 15 | 16 | - [WooCommerce Bookings](https://woocommerce.com/products/woocommerce-bookings/) 17 | - [WooCommerce Wishlists](https://woocommerce.com/products/woocommerce-wishlists/) 18 | - [WooCommerce Brands](https://woocommerce.com/products/brands/) 19 | - [WooCommerce Subscriptions](https://woocommerce.com/products/woocommerce-subscriptions/) 20 | 21 | For developers, Storefront is the perfect starting point for your project. Its lean and extensible codebase will allow you to easily add functionality to your site via a child theme and/or custom plugin(s). 22 | 23 | ## Storefront Status 24 | 25 | Please read [this document](./STOREFRONT_STATUS.md) explaining the current status of Storefront development. 26 | 27 | ## Storefront extensions 28 | 29 | Looking to take your storefront powered store to the next level? Be sure to checkout the premium [Storefront extensions](https://woocommerce.com/product-category/storefront-extensions/). 30 | 31 | ## Storefront Documentation 32 | 33 | You can view detailed Storefront documentation on the [WooCommerce documentation website](https://woocommerce.com/documentation/themes/storefront/). 34 | 35 | ## Storefront in your language 36 | 37 | Storefront translations can be downloaded from [WordPress.org](https://translate.wordpress.org/projects/wp-themes/storefront). To use one of these translations it is recommended that you upload it to `wp-content/languages/themes/storefront-pt_BR.mo`. Adding it to this location means the file will not be lost when you update Storefront. It is however possible to add a translation to the `languages` folder in your child theme if you'd prefer. 38 | 39 | ## Storefront help & support 40 | 41 | WooCommerce customers can get support at the [WooCommerce support portal](https://woocommerce.com/contact-us/). Otherwise, you can try posting on the [WordPress support forums](https://wordpress.org/support/theme/storefront/). Please remember, GitHub is for bug reports and contributions, _not_ support. 42 | 43 | ## Contributing to Storefront 44 | 45 | If you have a patch, or you've stumbled upon an issue with Storefront core, you can contribute this back to the code. Please read our [contributor guidelines](https://github.com/woocommerce/storefront/blob/master/CONTRIBUTING.md) for more information about how you can do this. 46 | 47 | If you have an idea or feature request please take a look at the [Storefront Feature Requests](https://woocommerce.com/feature-requests/storefront/) to see if it's already been suggested, planned, or is under development. If not, please add it there. 48 | 49 | You can keep up with the latest Storefront developments on the [dev blog](https://woocommerce.wordpress.com/category/storefront/). 50 | 51 | ## Testing Storefront 52 | 53 | Want to help test upcoming Storefront releases? Check out the [Storefront Beta Tester](https://github.com/seb86/Storefront-Beta-Tester) plugin. 54 | -------------------------------------------------------------------------------- /STOREFRONT_STATUS.md: -------------------------------------------------------------------------------- 1 | # Status of Storefront 2 | 3 | > **tl;dr:** Storefront is in active development and we’ll continue to improve it alongside priorities like the new optimised checkout. 4 | 5 | Storefront continues to be a theme that powers a significant number of WooCommerce stores in the ecosystem and we continue to invest active development time that ensures Storefront remains a valuable resource for the ecosystem. On the horizon there are a number of transitions happening in the WordPress theme industry and in order to be prepared as a team we are also prioritizing and investing in experimenting with and building new features to support this direction that ultimately benefits WooCommerce stores, merchants and shoppers. 6 | 7 | To that end, to bring clarity to what we are prioritizing for active Storefront development, we’ve created this criteria list. Our engineers are using this list to help us effectively triage issues. Going forward, we will only be actively addressing issues that fall in one of these criteria “buckets”: 8 | 9 | - Contribute to improving our release processes or documentation. 10 | - Critical bugs that break expected functionality for important flows in a store (eg. Checkout flow). This also includes security related issues that require immediate release after fixing. 11 | - Non critical bugs that are still affecting a significant number of merchants or stores but don’t break critical flows (including those related to accessibility or internationalisation). 12 | - Address significant compatibility issues with any one of: WordPress core updates, WooCommerce core updates, or signature products important to be compatible with (such as WooCommerce Blocks). 13 | 14 | At this time, most enhancements and features will not be worked on and in order to be clear about expectations we will be generally closing issues unless they fall into one of the above buckets. 15 | 16 | While we also welcome contributions (pull requests) from the community. There is still an investment of time needed by our team to review the prs and consider the impact of merging to Storefront. So at this time, unless a pull request falls into one of the above buckets, we will be closing it. 17 | -------------------------------------------------------------------------------- /archive.php: -------------------------------------------------------------------------------- 1 | 11 | 12 |
13 |
14 | 15 | 16 | 17 | 23 | 24 | 33 | 34 |
35 |
36 | 37 | li { position: relative; } 10 | } 11 | 12 | .#{$fa-css-prefix}-li { 13 | left: -$fa-li-width; 14 | position: absolute; 15 | text-align: center; 16 | width: $fa-li-width; 17 | line-height: inherit; 18 | } 19 | -------------------------------------------------------------------------------- /assets/css/sass/vendors/font-awesome/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | @mixin fa-icon { 5 | -webkit-font-smoothing: antialiased; 6 | -moz-osx-font-smoothing: grayscale; 7 | display: inline-block; 8 | font-style: normal; 9 | font-variant: normal; 10 | font-weight: normal; 11 | line-height: 1; 12 | } 13 | 14 | @mixin fa-icon-rotate($degrees, $rotation) { 15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})"; 16 | transform: rotate($degrees); 17 | } 18 | 19 | @mixin fa-icon-flip($horiz, $vert, $rotation) { 20 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)"; 21 | transform: scale($horiz, $vert); 22 | } 23 | 24 | 25 | // Only display content to screen readers. A la Bootstrap 4. 26 | // 27 | // See: http://a11yproject.com/posts/how-to-hide-content/ 28 | 29 | @mixin sr-only { 30 | border: 0; 31 | clip: rect(0, 0, 0, 0); 32 | height: 1px; 33 | margin: -1px; 34 | overflow: hidden; 35 | padding: 0; 36 | position: absolute; 37 | width: 1px; 38 | } 39 | 40 | // Use in conjunction with .sr-only to only display content when it's focused. 41 | // 42 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 43 | // 44 | // Credit: HTML5 Boilerplate 45 | 46 | @mixin sr-only-focusable { 47 | &:active, 48 | &:focus { 49 | clip: auto; 50 | height: auto; 51 | margin: 0; 52 | overflow: visible; 53 | position: static; 54 | width: auto; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /assets/css/sass/vendors/font-awesome/_rotated-flipped.scss: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 7 | 8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 10 | .#{$fa-css-prefix}-flip-both, .#{$fa-css-prefix}-flip-horizontal.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(-1, -1, 2); } 11 | 12 | // Hook for IE8-9 13 | // ------------------------- 14 | 15 | :root { 16 | .#{$fa-css-prefix}-rotate-90, 17 | .#{$fa-css-prefix}-rotate-180, 18 | .#{$fa-css-prefix}-rotate-270, 19 | .#{$fa-css-prefix}-flip-horizontal, 20 | .#{$fa-css-prefix}-flip-vertical, 21 | .#{$fa-css-prefix}-flip-both { 22 | filter: none; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /assets/css/sass/vendors/font-awesome/_screen-reader.scss: -------------------------------------------------------------------------------- 1 | // Screen Readers 2 | // ------------------------- 3 | 4 | .sr-only { @include sr-only; } 5 | .sr-only-focusable { @include sr-only-focusable; } 6 | -------------------------------------------------------------------------------- /assets/css/sass/vendors/font-awesome/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | display: inline-block; 6 | height: 2em; 7 | line-height: 2em; 8 | position: relative; 9 | vertical-align: middle; 10 | width: ($fa-fw-width*2); 11 | } 12 | 13 | .#{$fa-css-prefix}-stack-1x, 14 | .#{$fa-css-prefix}-stack-2x { 15 | left: 0; 16 | position: absolute; 17 | text-align: center; 18 | width: 100%; 19 | } 20 | 21 | .#{$fa-css-prefix}-stack-1x { 22 | line-height: inherit; 23 | } 24 | 25 | .#{$fa-css-prefix}-stack-2x { 26 | font-size: 2em; 27 | } 28 | 29 | .#{$fa-css-prefix}-inverse { 30 | color: $fa-inverse; 31 | } 32 | -------------------------------------------------------------------------------- /assets/css/sass/vendors/font-awesome/brands.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import 'variables'; 6 | 7 | @font-face { 8 | font-family: 'Font Awesome 5 Brands'; 9 | font-style: normal; 10 | font-weight: 400; 11 | font-display: $fa-font-display; 12 | src: url('#{$fa-font-path}/fa-brands-400.eot'); 13 | src: url('#{$fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'), 14 | url('#{$fa-font-path}/fa-brands-400.woff2') format('woff2'), 15 | url('#{$fa-font-path}/fa-brands-400.woff') format('woff'), 16 | url('#{$fa-font-path}/fa-brands-400.ttf') format('truetype'), 17 | url('#{$fa-font-path}/fa-brands-400.svg#fontawesome') format('svg'); 18 | } 19 | 20 | .fab { 21 | font-family: 'Font Awesome 5 Brands'; 22 | font-weight: 400; 23 | } 24 | -------------------------------------------------------------------------------- /assets/css/sass/vendors/font-awesome/fontawesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import 'variables'; 6 | @import 'mixins'; 7 | @import 'core'; 8 | @import 'larger'; 9 | @import 'fixed-width'; 10 | @import 'list'; 11 | @import 'bordered-pulled'; 12 | @import 'animated'; 13 | @import 'rotated-flipped'; 14 | @import 'stacked'; 15 | @import 'icons'; 16 | @import 'screen-reader'; 17 | -------------------------------------------------------------------------------- /assets/css/sass/vendors/font-awesome/regular.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import 'variables'; 6 | 7 | @font-face { 8 | font-family: 'Font Awesome 5 Free'; 9 | font-style: normal; 10 | font-weight: 400; 11 | font-display: $fa-font-display; 12 | src: url('#{$fa-font-path}/fa-regular-400.eot'); 13 | src: url('#{$fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'), 14 | url('#{$fa-font-path}/fa-regular-400.woff2') format('woff2'), 15 | url('#{$fa-font-path}/fa-regular-400.woff') format('woff'), 16 | url('#{$fa-font-path}/fa-regular-400.ttf') format('truetype'), 17 | url('#{$fa-font-path}/fa-regular-400.svg#fontawesome') format('svg'); 18 | } 19 | 20 | .far { 21 | font-family: 'Font Awesome 5 Free'; 22 | font-weight: 400; 23 | } 24 | -------------------------------------------------------------------------------- /assets/css/sass/vendors/font-awesome/solid.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import 'variables'; 6 | 7 | @font-face { 8 | font-family: 'Font Awesome 5 Free'; 9 | font-style: normal; 10 | font-weight: 900; 11 | font-display: $fa-font-display; 12 | src: url('#{$fa-font-path}/fa-solid-900.eot'); 13 | src: url('#{$fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'), 14 | url('#{$fa-font-path}/fa-solid-900.woff2') format('woff2'), 15 | url('#{$fa-font-path}/fa-solid-900.woff') format('woff'), 16 | url('#{$fa-font-path}/fa-solid-900.ttf') format('truetype'), 17 | url('#{$fa-font-path}/fa-solid-900.svg#fontawesome') format('svg'); 18 | } 19 | 20 | .fa, 21 | .fas { 22 | font-family: 'Font Awesome 5 Free'; 23 | font-weight: 900; 24 | } 25 | -------------------------------------------------------------------------------- /assets/css/sass/vendors/font-awesome/v4-shims.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @import 'variables'; 6 | @import 'shims'; 7 | -------------------------------------------------------------------------------- /assets/css/sass/vendors/modular-scale/_calc.scss: -------------------------------------------------------------------------------- 1 | @function ms-calc($Value, $Base: $ms-base, $Ratio: $ms-ratio) { 2 | 3 | // If pow exists use it. 4 | // It supports non-interger values! 5 | @if $MS-pow-exists { 6 | 7 | // The formula for figuring out modular scales is: 8 | // (r^v)*b 9 | @return pow($Ratio, $Value) * $Base; 10 | } 11 | 12 | // If not, use ms-pow(). 13 | // Not as fast or capable of non-integer exponents. 14 | @else { 15 | @return ms-pow($Ratio, $Value) * $Base; 16 | } 17 | } -------------------------------------------------------------------------------- /assets/css/sass/vendors/modular-scale/_function-list.scss: -------------------------------------------------------------------------------- 1 | // Outputs a list of values instead of a single value 2 | @function ms-list($Start: 0, $End: 0, $Bases: $ms-base, $Ratios: $ms-ratio) { 3 | 4 | // Seed results 5 | $Positive-return: (); 6 | $Negitive-return: (); 7 | $Return: (); 8 | 9 | @if $End >= 0 { 10 | // Generate a list of all possible values 11 | $Positive-return: ms-generate-list($End, $Bases, $Ratios); 12 | 13 | // Sort the generated lists 14 | $Positive-return: ms-sort-list($Positive-return); 15 | 16 | // Trim list 17 | $Trim-list: (); 18 | // If the starting value is a positive number 19 | // trim the positive return from that 20 | @if $Start >= 0 { 21 | @for $i from ($Start + 1) through $End + 1 { 22 | $Trim-list: join($Trim-list, nth($Positive-return, $i)); 23 | } 24 | } 25 | // If not, then include everything up to the end. 26 | @else { 27 | @for $i from 1 through $End + 1 { 28 | $Trim-list: join($Trim-list, nth($Positive-return, $i)); 29 | } 30 | } 31 | $Positive-return: $Trim-list; 32 | } 33 | 34 | // Generate a negitive list 35 | @if $Start < 0 { 36 | // Generate a list of all possible values 37 | $Negitive-return: ms-generate-list($Start, $Bases, $Ratios); 38 | 39 | // Sort the generated lists 40 | $Negitive-return: ms-sort-list($Negitive-return); 41 | 42 | // Reverse negitive list results. 43 | $MS-new-return: (); 44 | @each $i in $Negitive-return { 45 | $MS-new-return: join($i, $MS-new-return); 46 | } 47 | $Negitive-return: $MS-new-return; 48 | 49 | // Trim list 50 | $Trim-list: (); 51 | @if $End < 0 { 52 | @for $i from abs($End) through (abs($Start) + 2) { 53 | $Trim-list: join(nth($Negitive-return, $i), $Trim-list); 54 | } 55 | } 56 | @else { 57 | @for $i from 2 through (abs($Start) + 1) { 58 | $Trim-list: join(nth($Negitive-return, $i), $Trim-list); 59 | } 60 | } 61 | $Negitive-return: $Trim-list; 62 | } 63 | 64 | // Join both positive and negitive possibilities. 65 | $Return: join($Negitive-return, $Positive-return); 66 | 67 | @return $Return; 68 | } 69 | -------------------------------------------------------------------------------- /assets/css/sass/vendors/modular-scale/_function.scss: -------------------------------------------------------------------------------- 1 | // The main function that brings it all together 2 | @use "sass:math"; 3 | 4 | @function ms($Value: 0, $Bases: $ms-base, $Ratios: $ms-ratio) { 5 | 6 | // If no multi-base or multi-ratio stuff is going on 7 | // then just retrn the basic calculaiton 8 | @if length($Bases) == 1 and length($Ratios) == 1 { 9 | @return ms-round-px(ms-calc($Value, $Bases, $Ratios)); 10 | } 11 | 12 | // Do calculations directly in Ruby when avalible 13 | @if $MS-gem-exists { 14 | 15 | // Remove units from bases 16 | $Unit: nth($Bases, 1) * 0 + 1; // Extracts the unit from the base 17 | $Unitless-Bases: (); 18 | @each $Base in $Bases { 19 | $Base: math.div($Base, $Unit); 20 | $Unitless-Bases: join($Unitless-Bases, $Base); 21 | } 22 | 23 | // Calculate natively in Ruby 24 | @return ms-round-px(ms-gem-func($Value, $Unitless-Bases, $Ratios) * $Unit); 25 | } 26 | 27 | // Generate a list of all possible values 28 | $Return: ms-generate-list($Value, $Bases, $Ratios); 29 | 30 | // Sort the generated lists 31 | $Return: ms-sort-list($Return); 32 | 33 | // Reverse list if its negitive. 34 | @if $Value < 0 { 35 | $MS-new-return: (); 36 | @each $i in $Return { 37 | $MS-new-return: join($i, $MS-new-return); 38 | } 39 | $Return: $MS-new-return; 40 | } 41 | 42 | // Normalize value for counting from 1 43 | // Because CSS counts things from 1 44 | // So Sass does as well 45 | // So I get to write fun stuff like this 46 | $Value: abs($Value) + 1; 47 | 48 | // Find the correct value in the list 49 | $Return: nth($Return, $Value); 50 | 51 | @return ms-round-px($Return); 52 | } 53 | 54 | // Same function, different name, for good measure. 55 | @function modular-scale($Value: 0, $Bases: $ms-base, $Ratios: $ms-ratio) { 56 | @return ms($Value, $Bases, $Ratios); 57 | } -------------------------------------------------------------------------------- /assets/css/sass/vendors/modular-scale/_generate-list.scss: -------------------------------------------------------------------------------- 1 | @function ms-reverse-list($list) { 2 | @if length($list) > 1 { 3 | @if nth($list, 1) > nth($list, length($list)) { 4 | $MS-reversed-list: (); 5 | @each $Value in $list { 6 | $MS-reversed-list: join($Value, $MS-reversed-list); 7 | } 8 | @return $MS-reversed-list; 9 | } 10 | } 11 | @return $list; 12 | } 13 | 14 | 15 | @function ms-generate-list($Value: 0, $Bases: $ms-base, $Ratios: $ms-ratio) { 16 | 17 | // Create blank lists 18 | $MS-list: (); 19 | $MS-base-list: (); 20 | 21 | // Loop through each ratio AND each base 22 | // to generate all possibilities. 23 | @each $Ratio in $Ratios { 24 | @each $Base in $Bases { 25 | 26 | // Set base variables 27 | $MS-base-list: (); 28 | $Base-counter: 0; 29 | 30 | // Seed list with an initial value 31 | $MS-base-list: $Base; 32 | 33 | // Find values on a positive scale 34 | @if $Value >= 0 { 35 | 36 | // Find lower values on the scale 37 | $Base-counter: -1; 38 | @while ms-calc($Base-counter, $Base, $Ratio) >= nth($Bases, 1) { 39 | $MS-base-list: join($MS-base-list, ms-calc($Base-counter, $Base, $Ratio)); 40 | $Base-counter: $Base-counter - 1; 41 | } 42 | 43 | // Ensure the list is smallest to largest 44 | $MS-base-list: ms-reverse-list($MS-base-list); 45 | 46 | // Find higher possible values on the scale 47 | $Base-counter: 1; 48 | @while ms-calc($Base-counter, $Base, $Ratio) <= ms-calc($Value, nth($Bases, 1), $Ratio) { 49 | $MS-base-list: join($MS-base-list, ms-calc($Base-counter, $Base, $Ratio)); 50 | $Base-counter: $Base-counter + 1; 51 | } 52 | } 53 | 54 | // Find values on a negitive scale 55 | @else { 56 | 57 | // Find lower values on the scale 58 | $Base-counter: 1; 59 | @while ms-calc($Base-counter, $Base, $Ratio) <= nth($Bases, 1) { 60 | $MS-base-list: join($MS-base-list, ms-calc($Base-counter, $Base, $Ratio)); 61 | $Base-counter: $Base-counter + 1; 62 | } 63 | 64 | // Ensure the list is smallest to largest 65 | $MS-base-list: ms-reverse-list($MS-base-list); 66 | 67 | // Find higher possible values on the scale 68 | $Base-counter: -1; 69 | @while ms-calc($Base-counter, $Base, $Ratio) >= ms-calc($Value, nth($Bases, 1), $Ratio) { 70 | $MS-calc: ms-calc($Base-counter, $Base, $Ratio); 71 | // detect if the value excedes the main base value 72 | @if $MS-calc < nth($Bases, 1) { 73 | $MS-base-list: join($MS-base-list, $MS-calc); 74 | } 75 | $Base-counter: $Base-counter - 1; 76 | } 77 | 78 | // Trim outlier base. 79 | @if length($Bases) > 1 { 80 | @for $i from 2 through length($Bases) { 81 | @if nth($MS-base-list, 1) > nth($Bases, 1) { 82 | $MS-new-list: (); 83 | @for $i from 2 through length($MS-base-list) { 84 | $MS-new-list: join($MS-new-list, nth($MS-base-list, $i)); 85 | } 86 | $MS-base-list: $MS-new-list; 87 | } 88 | } 89 | } 90 | } 91 | 92 | // reverse list if its largest to smallest 93 | $MS-base-list: ms-reverse-list($MS-base-list); 94 | 95 | // Add new possibilities to the master list 96 | $MS-list: append($MS-list, $MS-base-list, comma); 97 | 98 | } 99 | } 100 | 101 | // After all the possibilities are found, output a master list 102 | @return $MS-list; 103 | } -------------------------------------------------------------------------------- /assets/css/sass/vendors/modular-scale/_pow.scss: -------------------------------------------------------------------------------- 1 | // If a native exponent function doesnt exist 2 | // this one is needed. 3 | @use "sass:math"; 4 | 5 | @function ms-pow($Base, $Exponent) { 6 | 7 | // Find and remove unit. 8 | // Avoids messyness with unit calculations 9 | $Unit: $Base * 0 + 1; 10 | $Base: math.div($Base, $Unit); 11 | 12 | // This function doesnt support non-interger exponents. 13 | // Warn the user about why this is breaking. 14 | @if round($Exponent) != $Exponent { 15 | @warn "Unfortunately, you need Compass to use non-integer exponents"; 16 | } 17 | 18 | // Set up the loop, priming the return with the base. 19 | $Return: $Base; 20 | 21 | // If the number is positive, multiply it. 22 | @if $Exponent > 0 { 23 | // Basic feedback loop as exponents 24 | // are recursivley multiplied numbers. 25 | @for $i from 1 to $Exponent { 26 | $Return: $Return * $Base; 27 | } 28 | } 29 | 30 | // If the number is 0 or negitive 31 | // divide instead of multiply. 32 | @else { 33 | // Libsass doesnt allow negitive values in loops 34 | @for $i from (-1 + 1) to (abs($Exponent) + 1) { 35 | $Return: math.div($Return, $Base); 36 | } 37 | } 38 | 39 | // Return is now compounded redy to be returned. 40 | // Add the unit back onto the number. 41 | @return $Return * $Unit; 42 | } -------------------------------------------------------------------------------- /assets/css/sass/vendors/modular-scale/_ratios.scss: -------------------------------------------------------------------------------- 1 | // Golden ratio 2 | $phi : 1.618034 ; 3 | $golden : $phi ; 4 | 5 | $double-octave : 4 ; 6 | $major-twelfth : 3 ; 7 | $major-eleventh : 2.666666667 ; 8 | $major-tenth : 2.5 ; 9 | $octave : 2 ; 10 | $major-seventh : 1.875 ; 11 | $minor-seventh : 1.777777778 ; 12 | $major-sixth : 1.666666667 ; 13 | $minor-sixth : 1.6 ; 14 | $fifth : 1.5 ; 15 | $augmented-fourth : 1.41421 ; 16 | $fourth : 1.333333333 ; 17 | $major-third : 1.25 ; 18 | $minor-third : 1.2 ; 19 | $major-second : 1.125 ; 20 | $minor-second : 1.066666667 ; -------------------------------------------------------------------------------- /assets/css/sass/vendors/modular-scale/_respond.scss: -------------------------------------------------------------------------------- 1 | // Stripping units is rarely a best practice and this function 2 | // should not be used elsewhere 3 | @use "sass:math"; 4 | 5 | @function ms-unitless($val) { 6 | $val: math.div($val, $val - $val + 1); 7 | @return $val; 8 | } 9 | 10 | // Search config for values 11 | @function ms-range($x,$y,$range:$ms-range) { 12 | @return nth(nth($range,$x),$y); 13 | } 14 | 15 | // Generate calc() function 16 | @function ms-respond-calc($value, $n, $range: $ms-range, $base: $ms-base) { 17 | $val1: ms($value,$base,ms-range($n,1,$range)); 18 | $val2: ms($value,$base,ms-range($n+1,1,$range)); 19 | $break1: ms-range($n,2,$range); 20 | $break2: ms-range($n+1,2,$range); 21 | $diff: ms-unitless($val2) - ms-unitless($val1); 22 | @if $ms-fluid { 23 | @return calc( #{$val1} + #{$diff} * ( ( 100vw - #{$break1}) / #{ms-unitless($break2) - ms-unitless($break1)} ) ); 24 | } @else { 25 | @return ms($value,$base,ms-range($n,1,$range)); 26 | } 27 | } 28 | 29 | // Main responsive mixin 30 | @mixin ms-respond($property, $value, $range: $ms-range, $base: $ms-base) { 31 | // If there is no responsive config, just output the property and value 32 | @if $ms-range == null { 33 | #{$property}: ms($value,$base,$ms-ratio); 34 | } @else { 35 | 36 | // Initial value 37 | #{$property}: ms($value,$base,ms-range(1,1,$range)); 38 | 39 | // Loop through breakpoints 40 | @for $i from 1 through (length($range) - 1) { 41 | @media (min-width: ms-range($i,2,$range)) and (max-width: ms-range($i+1,2,$range)) { 42 | #{$property}: ms-respond-calc($value, $i, $range, $base); 43 | } 44 | } 45 | 46 | // Final breakpoint is just an override value 47 | @media (min-width: ms-range(length($range),2,$range)) { 48 | #{$property}: ms($value,$base,ms-range(length($range),1,$range)); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /assets/css/sass/vendors/modular-scale/_round-px.scss: -------------------------------------------------------------------------------- 1 | @function ms-round-px($Result) { 2 | @if unit($Result) == 'px' { 3 | @return round($Result); 4 | } 5 | @return $Result; 6 | } -------------------------------------------------------------------------------- /assets/css/sass/vendors/modular-scale/_sort-list.scss: -------------------------------------------------------------------------------- 1 | // List sorting via a modified merge-sort algorythmn 2 | // http://en.wikipedia.org/wiki/Merge_sort 3 | 4 | @function ms-merge($A, $B) { 5 | 6 | $Return: (); 7 | 8 | // Some empty lists get passed through 9 | // so just pass the other list throguh 10 | @if length($A) == 0 { 11 | @return $B; 12 | } 13 | 14 | // If lists fit next to each other, just merge them 15 | // This helps performance skipping the need to check each value 16 | @if nth($A, length($A)) < nth($B, 1) { 17 | @return join($A, $B); 18 | } 19 | @if nth($B, length($B)) < nth($A, 1) { 20 | @return join($B, $A); 21 | } 22 | 23 | // Counters start at 1 24 | $A-counter: 1; 25 | $B-counter: 1; 26 | 27 | // Start looping through all numbers in array 28 | @while $A-counter <= length($A) and $B-counter <= length($B) { 29 | 30 | // Check if the A value is smaller 31 | // Uses or equal to avoid duplicate numbers 32 | @if nth($A, $A-counter) <= nth($B, $B-counter) { 33 | $Return: join($Return, nth($A, $A-counter)); 34 | $A-counter: $A-counter + 1; 35 | } 36 | 37 | // Check if the B value is smaller 38 | @else if nth($A, $A-counter) > nth($B, $B-counter) { 39 | $Return: join($Return, nth($B, $B-counter)); 40 | $B-counter: $B-counter + 1; 41 | } 42 | } 43 | 44 | // Run through remainder values in the list 45 | @while $A-counter <= length($A) { 46 | $Current: nth($A, $A-counter); 47 | @if $Current != nth($Return, length($Return)) { 48 | $Return: join($Return, $Current); 49 | } 50 | $A-counter: $A-counter + 1; 51 | } 52 | @while $B-counter <= length($B) { 53 | $Current: nth($B, $B-counter); 54 | @if $Current != nth($Return, length($Return)) { 55 | $Return: join($Return, $Current); 56 | } 57 | $B-counter: $B-counter + 1; 58 | } 59 | 60 | // Done! return is now sorted and complete 61 | @return $Return; 62 | } 63 | 64 | 65 | 66 | // Pull it all together 67 | @function ms-sort-list($Lists) { 68 | 69 | $Return: (); 70 | 71 | @each $List in $Lists { 72 | @if $Return == () { 73 | $Return: $List; 74 | } 75 | @else { 76 | $Return: ms-merge($List, $Return); 77 | } 78 | } 79 | 80 | // final cleanup of repeated items 81 | $Last: null; 82 | $New-list: (); 83 | @each $Item in $Return { 84 | @if $Item != $Last { 85 | $New-list: join($New-list, $Item); 86 | } 87 | $Last: $Item; 88 | } 89 | $Return: $New-list; 90 | 91 | 92 | @return $Return; 93 | } -------------------------------------------------------------------------------- /assets/css/sass/vendors/modular-scale/_tests.scss: -------------------------------------------------------------------------------- 1 | // Feature testing 2 | 3 | 4 | // Test if the pow() function exists 5 | @function ms-pow-exists() { 6 | @if pow(4, 2) == 16 { 7 | @return true; 8 | } 9 | @return false; 10 | } 11 | 12 | $MS-pow-exists: ms-pow-exists(); 13 | 14 | // Test if MS was installed via the gem 15 | @function ms-gem-exists() { 16 | @if ms-gem-installed() == true { 17 | @return true; 18 | } 19 | @return false; 20 | } 21 | 22 | $MS-gem-exists: ms-gem-exists(); -------------------------------------------------------------------------------- /assets/css/woocommerce/extensions/advanced-product-labels.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * WooCommerce Advanced Product Labels 3 | */ 4 | 5 | /** 6 | * Imports 7 | */ 8 | @import "bourbon"; 9 | @import "../../sass/utils/variables"; 10 | @import "../../sass/vendors/modular-scale"; 11 | 12 | .wapl-flash, 13 | .wapl-flash .product-label { 14 | font-size: 1em; 15 | } 16 | 17 | .wapl-flash, 18 | .wapl-flash .product-label { 19 | width: ms(6); 20 | height: ms(6); 21 | line-height: ms(6); 22 | border: 0; 23 | } 24 | 25 | .wapl-label .product-label { 26 | padding: ms(-2) ms(-1); 27 | display: inline-block; 28 | margin: 0 auto; 29 | font-size: ms(0); 30 | 31 | &:empty { 32 | display: none; 33 | } 34 | } 35 | 36 | .wapl-label { 37 | margin-bottom: ms(-1); 38 | } 39 | -------------------------------------------------------------------------------- /assets/css/woocommerce/extensions/ajax-layered-nav.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * WooCommerce AJAX Layered Nav 3 | */ 4 | 5 | /** 6 | * Imports 7 | */ 8 | @import "bourbon"; 9 | @import "../../sass/utils/variables"; 10 | @import "../../sass/utils/mixins"; 11 | @import "../../sass/vendors/modular-scale"; 12 | 13 | .widget_layered_nav { 14 | 15 | ul.colors { 16 | 17 | li { 18 | 19 | a { 20 | display: block; 21 | } 22 | 23 | .box { 24 | border: 0; 25 | display: inline-block; 26 | box-sizing: border-box; 27 | border-radius: 0.202em; 28 | height: ms(3); 29 | width: ms(3); 30 | } 31 | 32 | &.chosen { 33 | 34 | a { 35 | opacity: 1; 36 | 37 | &:hover { 38 | opacity: 0.5; 39 | } 40 | } 41 | } 42 | } 43 | } 44 | 45 | ul.checkboxes { 46 | 47 | li { 48 | 49 | input { 50 | margin-right: ms(-2); 51 | } 52 | } 53 | } 54 | 55 | ul.sizes { 56 | 57 | li { 58 | 59 | a { 60 | opacity: 1; 61 | } 62 | 63 | .size-filter { 64 | font-size: 1em; 65 | height: ms(3); 66 | min-width: ms(3); 67 | text-align: center; 68 | line-height: 1.618; 69 | background-color: #fff; 70 | border: 0; 71 | opacity: 0.5; 72 | font-weight: 600; 73 | border-radius: 0.202em; 74 | 75 | &:hover { 76 | opacity: 1; 77 | } 78 | } 79 | 80 | &.chosen { 81 | 82 | .size-filter { 83 | opacity: 1; 84 | 85 | &:hover { 86 | opacity: 0.5; 87 | } 88 | } 89 | } 90 | } 91 | } 92 | 93 | ul.colors, 94 | ul.checkboxes, 95 | ul.sizes { 96 | 97 | li { 98 | 99 | &.chosen { 100 | 101 | &::before { 102 | display: none; 103 | } 104 | } 105 | 106 | &.show-count { 107 | 108 | a { 109 | display: inline-block; 110 | } 111 | 112 | .count { 113 | float: right; 114 | line-height: 1.618; 115 | font-size: 1em; 116 | } 117 | } 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /assets/css/woocommerce/extensions/bookings.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * WooCommerce Bookings 3 | */ 4 | 5 | /** 6 | * Imports 7 | */ 8 | @import "bourbon"; 9 | @import "../../sass/utils/variables"; 10 | @import "../../sass/utils/mixins"; 11 | @import "susy"; 12 | @import "../../sass/vendors/modular-scale"; 13 | 14 | #wc-bookings-booking-form { 15 | border: 0; 16 | padding: 0; 17 | 18 | .wc-bookings-booking-cost { 19 | margin: 0; 20 | border: 0; 21 | } 22 | 23 | .wc-bookings-date-picker-date-fields { 24 | 25 | input { 26 | margin-bottom: 0; 27 | } 28 | 29 | label { 30 | width: 20%; 31 | } 32 | } 33 | 34 | .ui-widget { 35 | font-family: inherit; 36 | } 37 | 38 | .wc-bookings-date-picker { 39 | 40 | .ui-datepicker-header { 41 | border: 0; 42 | background-image: none; 43 | } 44 | 45 | .ui-widget-content { 46 | box-shadow: none; 47 | -moz-box-shadow: none; 48 | -webkit-box-shadow: none; 49 | background: none; 50 | } 51 | 52 | .ui-datepicker { 53 | 54 | table { 55 | font-size: 1em; 56 | } 57 | 58 | 59 | th { 60 | border: 0; 61 | } 62 | 63 | td { 64 | border: 0; 65 | 66 | &.bookable { 67 | 68 | a { 69 | text-shadow: none; 70 | } 71 | } 72 | 73 | &.ui-datepicker-today { 74 | 75 | a, 76 | span { 77 | box-shadow: inset 0 0 0 3px rgba(#000, 0.2); 78 | } 79 | } 80 | 81 | &.fully_booked { 82 | 83 | a, 84 | span { 85 | text-decoration: line-through; 86 | cursor: not-allowed; 87 | } 88 | } 89 | } 90 | } 91 | } 92 | 93 | .block-picker { 94 | text-align: left; 95 | 96 | li { 97 | 98 | a { 99 | border: 0 !important; 100 | padding: 0.236em ms(-3); 101 | display: inline-block; 102 | text-align: center; 103 | 104 | &:hover { 105 | text-decoration: none; 106 | border: 0; 107 | } 108 | } 109 | } 110 | } 111 | } 112 | 113 | .product-type-booking { 114 | 115 | form.cart { 116 | padding-left: 0; 117 | padding-right: 0; 118 | } 119 | } 120 | 121 | @include susy-media($desktop) { 122 | 123 | table.my_account_bookings { 124 | font-size: ms(-1); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /assets/css/woocommerce/extensions/brands.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * WooCommerce Brands 3 | */ 4 | 5 | /** 6 | * Imports 7 | */ 8 | @import "bourbon"; 9 | @import "../../sass/utils/variables"; 10 | @import "../../sass/utils/mixins"; 11 | @import "susy"; 12 | @import "../../sass/vendors/modular-scale"; 13 | 14 | /** 15 | * Header region 16 | */ 17 | .header-widget-region { 18 | 19 | .widget_brand_thumbnails { 20 | 21 | ul.brand-thumbnails { 22 | 23 | @include clearfix; 24 | text-align: center; 25 | 26 | li { 27 | display: inline-block; 28 | width: auto !important; 29 | float: none !important; 30 | margin-bottom: 0 !important; 31 | 32 | img { 33 | max-height: 16px; 34 | width: auto; 35 | display: block; 36 | } 37 | } 38 | } 39 | } 40 | } 41 | 42 | /** 43 | * WooCommerce Brand Layered Nav 44 | */ 45 | .widget_brand_nav { 46 | 47 | ul { 48 | 49 | li { 50 | 51 | .count { 52 | float: right; 53 | } 54 | } 55 | } 56 | } 57 | 58 | /** 59 | * WooCommerce Brand Archive 60 | */ 61 | .tax-product_brand { 62 | 63 | .woocommerce-products-header { 64 | display: flex; 65 | flex-direction: column; 66 | margin: 0 0 ms(4); 67 | text-align: center; 68 | 69 | .brand-thumbnail { 70 | margin: 0 0 ms(1); 71 | width: auto; 72 | max-height: ms(4); 73 | align-self: center; 74 | order: 1; 75 | } 76 | 77 | .woocommerce-products-header__title, 78 | .term-description { 79 | order: 2; 80 | } 81 | } 82 | } 83 | 84 | div#brands_a_z { 85 | 86 | @include clearfix; 87 | 88 | ul.brands_index { 89 | margin-left: 0; 90 | padding: 0; 91 | 92 | li { 93 | float: none; 94 | display: inline-block; 95 | margin: 0 ms(-5) ms(-6) 0; 96 | padding: 0; 97 | text-transform: uppercase; 98 | 99 | a, 100 | span { 101 | float: none; 102 | display: block; 103 | border: 0; 104 | padding: ms(-4); 105 | min-width: ms(3); 106 | text-align: center; 107 | background-color: #eee; 108 | color: $color_body; 109 | line-height: 1; 110 | } 111 | 112 | span { 113 | opacity: 0.3; 114 | } 115 | } 116 | } 117 | 118 | h3 { 119 | text-transform: uppercase; 120 | } 121 | 122 | a.top { 123 | padding: ms(-2); 124 | background-color: #eee; 125 | color: $color_body; 126 | border: 0; 127 | line-height: 1; 128 | } 129 | 130 | ul.brands { 131 | margin-left: 0; 132 | list-style-position: inside; 133 | 134 | li { 135 | margin: 0 0 ms(-4); 136 | padding: 0 0 ms(-4); 137 | border-bottom: 1px solid $color_border; 138 | } 139 | } 140 | } 141 | 142 | /** 143 | * WooCommerce Brand single product 144 | */ 145 | .storefront-wc-brands-single-product { 146 | margin: 0 0 ms(-3); 147 | 148 | img { 149 | max-height: ms(4); 150 | } 151 | } 152 | 153 | @include susy-media($desktop) { 154 | 155 | div#brands_a_z { 156 | 157 | ul.brands_index { 158 | 159 | @include span(3 of 12); 160 | transition: all 0.5s ease; 161 | } 162 | 163 | h3 { 164 | 165 | @include span(last 9 of 12); 166 | clear: right; 167 | text-transform: uppercase; 168 | 169 | &:first-of-type { 170 | margin-top: 0; 171 | } 172 | } 173 | 174 | a.top { 175 | clear: right; 176 | } 177 | 178 | ul.brands { 179 | 180 | @include span(last 9 of 12); 181 | clear: right; 182 | } 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /assets/css/woocommerce/extensions/bundles.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * WooCommerce Product Bundles 3 | */ 4 | 5 | /** 6 | * Imports 7 | */ 8 | 9 | @import "bourbon"; 10 | @import "../../sass/utils/variables"; 11 | @import "../../sass/utils/mixins"; 12 | @import "susy"; 13 | @import "../../sass/vendors/modular-scale"; 14 | 15 | /** 16 | * Base 17 | */ 18 | 19 | .bundle_form { 20 | 21 | div.bundled_product_summary { 22 | 23 | padding-bottom: ms(3) !important; 24 | margin-bottom: ms(3); 25 | border-bottom: 1px solid $color_border; 26 | 27 | padding-left: 0; 28 | 29 | .bundled_product_images { 30 | 31 | margin-left: 0; 32 | 33 | a { 34 | margin: 0 !important; 35 | } 36 | 37 | img { 38 | width: 100% !important; 39 | margin-bottom: 0; 40 | } 41 | } 42 | } 43 | 44 | div.bundled_product_summary, 45 | tr.bundled_product_summary { 46 | 47 | .details { 48 | font-size: ms(-1); 49 | } 50 | } 51 | } 52 | 53 | .woocommerce, 54 | .woocommerce-page { 55 | 56 | #content div.product, 57 | div.product { 58 | 59 | .bundle_form div.bundled_product_summary .bundled_product_images { 60 | 61 | @include span( 2 of 10 ); 62 | } 63 | } 64 | } 65 | 66 | .bundle_form { 67 | 68 | div.bundled_product_summary:not(.thumbnail_hidden) { 69 | 70 | .details { 71 | 72 | @include span( last 8 of 10 ); 73 | } 74 | } 75 | } 76 | 77 | 78 | .bundle_form { 79 | 80 | div.bundled_product_summary:not(.thumbnail_hidden) { 81 | 82 | .details { 83 | padding: 0 !important; 84 | } 85 | } 86 | } 87 | 88 | .bundled_table_item { 89 | 90 | .product-name { 91 | padding-left: 4rem; 92 | } 93 | } 94 | 95 | table.shop_table_responsive tr.bundled_table_item { 96 | display: none; 97 | } 98 | 99 | /** 100 | * Desktop 101 | */ 102 | 103 | @include susy-media($desktop) { 104 | 105 | .bundle_table_item dl.bundle_configuration { 106 | display: none; 107 | } 108 | 109 | table.shop_table_responsive tr.bundled_table_item { 110 | display: table-row; 111 | } 112 | 113 | .sp-product-gallery-stacked, 114 | .storefront-full-width-content, 115 | .page-template-template-fullwidth-php { 116 | 117 | .bundle_form { 118 | 119 | .bundled_product_summary { 120 | 121 | .details { 122 | font-size: 1em; 123 | } 124 | } 125 | } 126 | } 127 | 128 | .sp-product-gallery-stacked, 129 | .storefront-full-width-content, 130 | .page-template-template-fullwidth-php { 131 | 132 | #content div.product, 133 | div.product { 134 | 135 | .bundle_form div.bundled_product_summary .bundled_product_images { 136 | 137 | @include span( 2 of 8 ); 138 | } 139 | } 140 | 141 | .bundle_form { 142 | 143 | div.bundled_product_summary:not(.thumbnail_hidden) { 144 | 145 | .details { 146 | 147 | @include span( last 6 of 8 ); 148 | } 149 | } 150 | } 151 | } 152 | } 153 | 154 | /** 155 | * Handheld 156 | */ 157 | 158 | @include susy-media(max-width $handheld) { 159 | 160 | .woocommerce, 161 | .woocommerce-page { 162 | 163 | #content div.product, 164 | div.product { 165 | 166 | .bundle_form div.bundled_product_summary .bundled_product_images { 167 | 168 | @include span( 10 of 10 ); 169 | } 170 | } 171 | } 172 | 173 | .bundle_form { 174 | 175 | div.bundled_product_summary:not(.thumbnail_hidden) { 176 | 177 | .details { 178 | 179 | @include span( 10 of 10 ); 180 | } 181 | } 182 | } 183 | 184 | .bundle_form { 185 | 186 | div.bundled_product_summary .bundled_product_images { 187 | max-width: 50%; 188 | } 189 | 190 | div.bundled_product_summary .bundled_product_images { 191 | 192 | img { 193 | margin-bottom: 1em; 194 | } 195 | } 196 | 197 | table.bundled_products td { 198 | display: block; 199 | } 200 | 201 | table.bundled_products thead { 202 | display: none; 203 | } 204 | 205 | table.bundled_products tr td.bundled_item_images_col { 206 | width: 100%; 207 | padding-bottom: 0; 208 | } 209 | 210 | table.bundled_products tr { 211 | 212 | td.bundled_item_images_col, 213 | td.bundled_item_details_col { 214 | padding-bottom: 0; 215 | } 216 | 217 | td.bundled_item_images_col { 218 | width: 100%; 219 | } 220 | } 221 | 222 | table.bundled_products tr td.bundled_item_qty_col { 223 | max-width: 100%; 224 | text-align: left; 225 | } 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /assets/css/woocommerce/extensions/deposits.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * WooCommerce Deposits 3 | */ 4 | 5 | /** 6 | * Imports 7 | */ 8 | @import "bourbon"; 9 | @import "../../sass/utils/variables"; 10 | @import "../../sass/utils/mixins"; 11 | @import "../../sass/vendors/modular-scale"; 12 | 13 | /** 14 | * Style 15 | */ 16 | .wc-deposits-wrapper { 17 | 18 | .wc-deposits-option { 19 | 20 | li { 21 | padding: ms(-2) 1em; 22 | border: none; 23 | background: rgba(#000, 0.0125); 24 | box-shadow: none; 25 | border-radius: 0; 26 | 27 | &:hover { 28 | background: rgba(#000, 0.02); 29 | } 30 | 31 | input { 32 | margin-right: ms(-2); 33 | } 34 | } 35 | } 36 | 37 | .wc-deposits-payment-description { 38 | color: inherit; 39 | } 40 | 41 | .wc-deposits-payment-plans { 42 | background: transparent; 43 | padding: 0; 44 | border: 0; 45 | box-shadow: none; 46 | 47 | li.wc-deposits-payment-plan { 48 | border: 1em solid rgba(#000, 0.0125); 49 | padding: ms(3); 50 | margin-bottom: 1em; 51 | 52 | input { 53 | margin-right: 0; 54 | } 55 | 56 | &:hover { 57 | background: rgba(#000, 0.0125); 58 | } 59 | 60 | &:last-child { 61 | border-bottom: 1em solid rgba(#000, 0.0125); 62 | } 63 | 64 | .wc-deposits-payment-plan-description { 65 | color: inherit; 66 | display: block; 67 | font-weight: 400; 68 | opacity: 0.5; 69 | } 70 | 71 | label { 72 | max-width: none; 73 | } 74 | } 75 | } 76 | 77 | &.wc-deposits-optional { 78 | 79 | .wc-deposits-payment-plans { 80 | margin-bottom: ms(3); 81 | 82 | &::after { 83 | display: none; 84 | } 85 | 86 | &::before { 87 | border-bottom-color: rgba(#000, 0.025); 88 | top: -1px; 89 | } 90 | } 91 | } 92 | } 93 | 94 | -------------------------------------------------------------------------------- /assets/css/woocommerce/extensions/memberships.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * WooCommerce Memberships 3 | */ 4 | 5 | /** 6 | * Imports 7 | */ 8 | @import "bourbon"; 9 | @import "../../sass/utils/variables"; 10 | @import "../../sass/utils/mixins"; 11 | @import "susy"; 12 | @import "../../sass/vendors/modular-scale"; 13 | @import "../../sass/vendors/font-awesome/variables"; 14 | 15 | .woocommerce, 16 | .woocommerce-page { 17 | 18 | .woocommerce-MyAccount-navigation { 19 | 20 | ul { 21 | 22 | li.woocommerce-MyAccount-navigation-link--members-area a::before { 23 | content: fa-content($fa-var-lock); 24 | } 25 | 26 | li.woocommerce-MyAccount-navigation-link--back-to-memberships a::before { 27 | content: fa-content($fa-var-arrow-circle-left); 28 | } 29 | 30 | li.woocommerce-MyAccount-navigation-link--my-membership-content a::before { 31 | content: fa-content($fa-var-lock); 32 | } 33 | 34 | li.woocommerce-MyAccount-navigation-link--my-membership-products a::before { 35 | content: fa-content($fa-var-shopping-cart); 36 | } 37 | 38 | li.woocommerce-MyAccount-navigation-link--my-membership-discounts a::before { 39 | content: fa-content($fa-var-tags); 40 | } 41 | 42 | li.woocommerce-MyAccount-navigation-link--my-membership-notes a::before { 43 | content: fa-content($fa-var-comment); 44 | } 45 | 46 | li.woocommerce-MyAccount-navigation-link--my-membership-details a::before { 47 | content: fa-content($fa-var-cog); 48 | } 49 | } 50 | } 51 | } 52 | 53 | @include susy-media (max-width $desktop) { 54 | 55 | .woocommerce-account { 56 | 57 | table { 58 | 59 | &.my_account_memberships { 60 | table-layout: auto; 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /assets/css/woocommerce/extensions/mix-and-match.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * WooCommerce Mix and Match 3 | */ 4 | 5 | /** 6 | * Imports 7 | */ 8 | @import "bourbon"; 9 | @import "../../sass/utils/variables"; 10 | @import "../../sass/vendors/modular-scale"; 11 | 12 | .mnm_table { 13 | 14 | .product-thumbnail, 15 | .product-name, 16 | .product-quantity, 17 | .container-quantity { 18 | padding: ms(-2) ms(-1) !important; 19 | } 20 | 21 | .mnm_item { 22 | 23 | img { 24 | max-width: 100%; 25 | } 26 | } 27 | 28 | .product-name { 29 | vertical-align: middle; 30 | } 31 | } 32 | 33 | .cart, 34 | .shop_table { 35 | 36 | .mnm_table_item { 37 | 38 | .product-thumbnail { 39 | 40 | img { 41 | max-width: ms(5) !important; 42 | } 43 | } 44 | 45 | .mnm_table_item_indent { 46 | padding-left: 0; 47 | } 48 | 49 | .product-name, 50 | .product-price, 51 | .product-quantity { 52 | font-size: 1em; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /assets/css/woocommerce/extensions/photography.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * WooCommerce Photography 3 | */ 4 | 5 | /** 6 | * Imports 7 | */ 8 | @import "bourbon"; 9 | @import "../../sass/utils/variables"; 10 | @import "../../sass/utils/mixins"; 11 | @import "susy"; 12 | @import "../../sass/vendors/modular-scale"; 13 | 14 | .woocommerce, 15 | .woocommerce-page { 16 | 17 | ul.products { 18 | 19 | li.product-type-photography { 20 | 21 | @include clearfix; 22 | text-align: left; 23 | 24 | .photography-image, 25 | .photography-content { 26 | float: none; 27 | width: 100%; 28 | } 29 | 30 | .photography-image { 31 | 32 | img { 33 | width: 100%; 34 | } 35 | } 36 | 37 | .photography-sku { 38 | border-bottom: 1px solid $color_border; 39 | } 40 | 41 | .sku { 42 | font-weight: 600; 43 | } 44 | } 45 | } 46 | } 47 | 48 | .woocommerce, 49 | .woocommerce-page { 50 | 51 | .photography-products { 52 | 53 | .tools { 54 | margin-bottom: ms(5); 55 | background-color: rgba(0, 0, 0, 0.025); 56 | padding: 1em 1em 1em ms(3); 57 | border: 0; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /assets/css/woocommerce/extensions/product-recommendations.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * WooCommerce Product Recommendations 3 | */ 4 | 5 | /** 6 | * Imports 7 | */ 8 | 9 | @import "bourbon"; 10 | @import "../../sass/utils/variables"; 11 | @import "../../sass/utils/mixins"; 12 | @import "susy"; 13 | @import "../../sass/vendors/modular-scale"; 14 | 15 | /** 16 | * Base 17 | */ 18 | .wc-prl-recommendations { 19 | 20 | h2 { 21 | font-size: ms(3); 22 | } 23 | 24 | &.wc-prl-page-product_details { 25 | 26 | &.wc-prl-location-before_tabs, 27 | &.wc-prl-location-after_tabs { 28 | 29 | h2 { 30 | margin-bottom: ms(1); 31 | text-align: center; 32 | } 33 | } 34 | 35 | &.wc-prl-location-after_summary { 36 | margin-top: ms(2); 37 | } 38 | } 39 | 40 | &.wc-prl-location-after_pay_button { 41 | margin-top: ms(2); 42 | } 43 | 44 | &.wc-prl-page-checkout { 45 | 46 | &.wc-prl-location-order_review { 47 | margin-top: ms(5); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /assets/css/woocommerce/extensions/product-reviews-pro.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * WooCommerce Product Reviews Pro 3 | */ 4 | 5 | /** 6 | * Imports 7 | */ 8 | @import "bourbon"; 9 | @import "../../sass/utils/variables"; 10 | @import "../../sass/utils/mixins"; 11 | @import "susy"; 12 | @import "../../sass/vendors/modular-scale"; 13 | 14 | .woocommerce, 15 | .woocommerce-page { 16 | 17 | #reviews { 18 | 19 | .product-rating { 20 | 21 | .product-rating-summary, 22 | .product-rating-details { 23 | display: block; 24 | width: 100%; 25 | } 26 | 27 | .product-rating-summary { 28 | text-align: left; 29 | } 30 | 31 | .product-rating-details { 32 | 33 | table { 34 | 35 | td { 36 | padding: 0.202em ms(-3); 37 | 38 | &.rating-graph { 39 | 40 | .bar { 41 | background-color: $color_body; 42 | } 43 | } 44 | 45 | &.rating-count { 46 | 47 | a { 48 | text-decoration: none; 49 | } 50 | } 51 | } 52 | } 53 | } 54 | } 55 | 56 | .form-contribution { 57 | border-color: $color_border; 58 | padding: 1em; 59 | 60 | #review_rating_field { 61 | 62 | fieldset { 63 | float: left; 64 | 65 | label { 66 | display: inline-block; 67 | float: right; 68 | 69 | &.checkbox::before { 70 | font-size: ms(-1); 71 | } 72 | } 73 | 74 | .star-label { 75 | float: none; 76 | margin-left: ms(-2); 77 | } 78 | } 79 | } 80 | 81 | .form-row { 82 | clear: both; 83 | } 84 | } 85 | 86 | .contribution-karma { 87 | margin-left: 0; 88 | } 89 | 90 | #comments { 91 | 92 | ol.commentlist { 93 | 94 | li { 95 | padding-top: 0; 96 | 97 | img.avatar { 98 | width: ms(5); 99 | height: auto; 100 | margin: 0; 101 | float: right; 102 | } 103 | 104 | .description { 105 | padding-bottom: 0; 106 | } 107 | 108 | .comment-text { 109 | margin-left: 0; 110 | 111 | img, 112 | iframe { 113 | margin-bottom: ms(3); 114 | } 115 | } 116 | 117 | h3.contribution-title { 118 | margin: 0; 119 | font-size: 1em; 120 | } 121 | 122 | .contribution-actions { 123 | 124 | a { 125 | color: $color_links; 126 | 127 | &.done { 128 | opacity: 0.5; 129 | } 130 | } 131 | } 132 | 133 | ul.children { 134 | 135 | li { 136 | margin-bottom: ms(3); 137 | } 138 | } 139 | } 140 | } 141 | 142 | .form-contribution_comment { 143 | 144 | @include span(last 5 of 6); 145 | margin-bottom: ms(6); 146 | padding-top: ms(3); 147 | } 148 | 149 | ul.children + .form-contribution_comment { 150 | border-top: 0; 151 | padding-top: 0; 152 | } 153 | } 154 | 155 | .contribution-flag-form { 156 | background-color: rgba(0, 0, 0, 0.1); 157 | padding: ms(3); 158 | margin-bottom: ms(3); 159 | } 160 | } 161 | 162 | .form-photo { 163 | 164 | #photo_attachment_file { 165 | color: inherit; 166 | margin: 1em 0; 167 | } 168 | } 169 | 170 | .contribution-type-selector { 171 | margin: 0; 172 | 173 | > a { 174 | display: inline-block; 175 | margin-right: 1em; 176 | padding: ms(-3) 0; 177 | border-bottom: 0.202em solid rgba(0, 0, 0, 0.05); 178 | 179 | &.active { 180 | border-bottom-color: $color_border; 181 | } 182 | } 183 | } 184 | 185 | .star-rating-selector { 186 | 187 | fieldset { 188 | float: none; 189 | clear: both; 190 | } 191 | 192 | > label:first-child { 193 | display: block !important; 194 | } 195 | } 196 | 197 | .star-rating-selector:not(:checked) { 198 | 199 | label.checkbox { 200 | float: none; 201 | } 202 | } 203 | 204 | #wc-product-reviews-pro-modal { 205 | 206 | #customer_login { 207 | 208 | .col-1, 209 | .col-2 { 210 | width: 100%; 211 | } 212 | } 213 | } 214 | } 215 | 216 | #tiptip_content, 217 | .chart-tooltip { 218 | font-size: ms(-1); 219 | padding: ms(-2) 1em; 220 | background-color: rgba(0, 0, 0, 0.8); 221 | } 222 | 223 | #tiptip_holder.tip_bottom #tiptip_arrow_inner { 224 | border-bottom-color: rgba(0, 0, 0, 0.8); 225 | margin-top: -6px; 226 | } 227 | -------------------------------------------------------------------------------- /assets/css/woocommerce/extensions/quick-view.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * WooCommerce Mix and Match 3 | */ 4 | 5 | /** 6 | * Imports 7 | */ 8 | @import "bourbon"; 9 | @import "../../sass/utils/variables"; 10 | @import "../../sass/utils/mixins"; 11 | @import "../../sass/vendors/modular-scale"; 12 | 13 | .quick-view-button { 14 | 15 | span { 16 | display: none; 17 | } 18 | } 19 | 20 | div.quick-view div.quick-view-image a.button { 21 | 22 | @include button(); 23 | line-height: inherit; 24 | display: block; 25 | } 26 | -------------------------------------------------------------------------------- /assets/css/woocommerce/extensions/ship-multiple-addresses.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * WooCommerce Product Reviews Pro 3 | */ 4 | 5 | /** 6 | * Imports 7 | */ 8 | @import "bourbon"; 9 | @import "../../sass/utils/variables"; 10 | @import "../../sass/utils/mixins"; 11 | @import "susy"; 12 | @import "../../sass/vendors/modular-scale"; 13 | 14 | .woocommerce-page { 15 | 16 | .woocommerce-checkout-review-order-table { 17 | 18 | th.product-name { 19 | width: 70%; 20 | } 21 | } 22 | 23 | #shipping_addresses { 24 | padding-top: ms(3); 25 | } 26 | 27 | .ship_address, 28 | .no_shipping_address { 29 | float: none; 30 | width: auto; 31 | margin: 0 0 ms(3); 32 | background-color: rgba(#000, 0.025); 33 | border: 0; 34 | padding: 1em; 35 | line-height: inherit; 36 | border-radius: 0; 37 | font-size: ms(-1); 38 | 39 | dl { 40 | margin-top: 0; 41 | 42 | dd { 43 | margin-bottom: 1em; 44 | } 45 | } 46 | 47 | address { 48 | margin: 0; 49 | } 50 | 51 | .note-form { 52 | margin-bottom: ms(3); 53 | padding-top: 1em; 54 | } 55 | 56 | .modify-address-button { 57 | display: block; 58 | margin-top: 1em; 59 | } 60 | } 61 | 62 | .addresses { 63 | clear: both; 64 | 65 | @include clearfix; 66 | 67 | .address-block { 68 | margin: 0 0 ms(3); 69 | 70 | @include span(4.5 of 9); 71 | 72 | &:nth-child(3), 73 | &:nth-child(5), 74 | &:nth-child(7) { 75 | margin-right: 0 !important; 76 | } 77 | 78 | .buttons { 79 | text-align: inherit; 80 | position: static; 81 | 82 | .button { 83 | width: auto; 84 | } 85 | } 86 | } 87 | } 88 | 89 | &.page-template-template-fullwidth-php { 90 | 91 | .ship_address, 92 | .no_shipping_address { 93 | font-size: 1em; 94 | } 95 | 96 | .address-block { 97 | 98 | @include span(6 of 12); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /assets/css/woocommerce/extensions/smart-coupons.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * WooCommerce Smart Coupons 3 | */ 4 | 5 | /** 6 | * Imports 7 | */ 8 | @import "../../sass/utils/variables"; 9 | @import "susy"; 10 | @import "../../sass/vendors/modular-scale"; 11 | 12 | .woocommerce, 13 | .woocommerce-page { 14 | 15 | .coupon-container { 16 | margin: 0; 17 | box-shadow: none; 18 | 19 | &.medium { 20 | line-height: inherit; 21 | padding: ms(-2); 22 | } 23 | } 24 | 25 | .generated_coupon_summary { 26 | margin: 0; 27 | } 28 | 29 | .coupon-content { 30 | 31 | &.small { 32 | padding: ms(-2) ms(2); 33 | } 34 | 35 | .coupon-expire, 36 | .discount-info { 37 | font-family: inherit; 38 | } 39 | } 40 | 41 | #coupons_list { 42 | margin-bottom: ms(3); 43 | } 44 | } 45 | 46 | .sd-buttons-transparent { 47 | 48 | &.woocommerce, 49 | &.woocommerce-page { 50 | 51 | .coupon-container { 52 | background: transparent !important; 53 | padding: 0; 54 | } 55 | } 56 | } 57 | 58 | @include susy-media($desktop) { 59 | 60 | .sc_info_box { 61 | 62 | @include span(last 4 of 9); 63 | @include gutters(inside); 64 | } 65 | 66 | .page-template-template-fullwidth-php { 67 | 68 | .sc_info_box { 69 | 70 | @include span(last 5 of 12); 71 | margin-left: 0; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /assets/css/woocommerce/extensions/variation-swatches.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * WooCommerce Variation Swatches 3 | */ 4 | 5 | /** 6 | * Imports 7 | */ 8 | @import "bourbon"; 9 | @import "../../sass/utils/variables"; 10 | @import "../../sass/utils/mixins"; 11 | @import "../../sass/vendors/modular-scale"; 12 | 13 | .variations-table { 14 | margin: 0; 15 | 16 | th, 17 | td { 18 | display: block; 19 | padding: 0; 20 | background-color: transparent; 21 | } 22 | 23 | td.label { 24 | margin-bottom: 1em; 25 | } 26 | 27 | .swatch-wrapper { 28 | padding: ms(-2); 29 | background-color: transparent; 30 | border: 1px solid rgba(#000, 0.1); 31 | float: left; 32 | display: inline-block; 33 | margin: 0 0.327em 1em 0; 34 | 35 | img { 36 | opacity: 0.5; 37 | } 38 | 39 | .swatch-anchor { 40 | 41 | &:focus { 42 | outline: none; 43 | } 44 | } 45 | 46 | &.selected, 47 | &:hover { 48 | padding: ms(-2); 49 | background-color: #fff; 50 | 51 | img { 52 | opacity: 1; 53 | } 54 | } 55 | 56 | &.selected { 57 | border-width: 1px; 58 | border-color: rgba(#000, 0.1); 59 | } 60 | } 61 | } 62 | 63 | a#variations_clear { 64 | display: block; 65 | margin: 1em 0 ms(3); 66 | } 67 | -------------------------------------------------------------------------------- /assets/css/woocommerce/extensions/wishlists.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * WooCommerce Wishlists 3 | */ 4 | 5 | /** 6 | * Imports 7 | */ 8 | @import "bourbon"; 9 | @import "../../sass/utils/variables"; 10 | @import "../../sass/utils/mixins"; 11 | @import "susy"; 12 | @import "../../sass/vendors/modular-scale"; 13 | 14 | #wl-wrapper.wl-button-wrap { 15 | padding: ms(3) 0 0 0; 16 | } 17 | 18 | .wl-add-link { 19 | padding-left: 0 !important; 20 | background: none !important; 21 | } 22 | 23 | #wl-wrapper { 24 | 25 | .wl-tabs { 26 | border-bottom: 0 !important; 27 | 28 | > li { 29 | float: none !important; 30 | 31 | > a { 32 | padding: 1em ms(2); 33 | border: 0 !important; 34 | margin: 0 !important; 35 | 36 | @include border-top-radius(0); 37 | background-color: transparent !important; 38 | } 39 | 40 | &.active { 41 | 42 | a { 43 | box-shadow: inset 0 -3px 0 rgba(0, 0, 0, 0.1); 44 | } 45 | } 46 | } 47 | } 48 | 49 | .wl-table { 50 | 51 | td { 52 | padding: ms(-1) ms(2) !important; 53 | 54 | &:first-child { 55 | padding-left: ms(2) !important; 56 | } 57 | } 58 | 59 | &.manage { 60 | 61 | td { 62 | padding: ms(-3) !important; 63 | } 64 | } 65 | } 66 | 67 | .wl-meta-share, 68 | .wl-share-url { 69 | border-bottom-color: $color_border; 70 | } 71 | } 72 | 73 | .wl-tab-wrap { 74 | 75 | ul.tabs, 76 | .panel { 77 | width: 100%; 78 | margin: 0; 79 | } 80 | 81 | ul.tabs { 82 | 83 | li { 84 | 85 | &::after { 86 | display: none !important; 87 | } 88 | } 89 | } 90 | } 91 | 92 | @include susy-media($desktop) { 93 | 94 | #wl-wrapper { 95 | 96 | .wl-tabs { 97 | 98 | > li { 99 | 100 | a { 101 | padding-left: 0; 102 | } 103 | 104 | &.active { 105 | 106 | a { 107 | box-shadow: none; 108 | } 109 | } 110 | } 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /assets/fonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/fonts/fa-brands-400.eot -------------------------------------------------------------------------------- /assets/fonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/fonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /assets/fonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/fonts/fa-brands-400.woff -------------------------------------------------------------------------------- /assets/fonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/fonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /assets/fonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/fonts/fa-regular-400.eot -------------------------------------------------------------------------------- /assets/fonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/fonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /assets/fonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/fonts/fa-regular-400.woff -------------------------------------------------------------------------------- /assets/fonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/fonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /assets/fonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/fonts/fa-solid-900.eot -------------------------------------------------------------------------------- /assets/fonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/fonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /assets/fonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/fonts/fa-solid-900.woff -------------------------------------------------------------------------------- /assets/fonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/fonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /assets/images/admin/storefront-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/images/admin/welcome-screen/automattic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/admin/welcome-screen/automattic.png -------------------------------------------------------------------------------- /assets/images/admin/welcome-screen/child-themes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/admin/welcome-screen/child-themes.jpg -------------------------------------------------------------------------------- /assets/images/admin/welcome-screen/storefront-bundle-hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/admin/welcome-screen/storefront-bundle-hero.png -------------------------------------------------------------------------------- /assets/images/credit-cards/diners.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | diners 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /assets/images/credit-cards/discover.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | discover 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /assets/images/credit-cards/laser.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 12 | Slice 1 13 | Created with Sketch. 14 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /assets/images/credit-cards/paypal.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | amex-outline 8 | Created with Sketch. 9 | 11 | 18 | 21 | 27 | 36 | 44 | 52 | 53 | -------------------------------------------------------------------------------- /assets/images/credit-cards/unknown.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | Slice 1 10 | Created with Sketch. 11 | 13 | 14 | -------------------------------------------------------------------------------- /assets/images/credit-cards/visa.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Slice 1 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /assets/images/customizer/controls/2cl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/customizer/controls/2cl.png -------------------------------------------------------------------------------- /assets/images/customizer/controls/2cr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/customizer/controls/2cr.png -------------------------------------------------------------------------------- /assets/images/customizer/starter-content/categories/accessories.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/customizer/starter-content/categories/accessories.jpg -------------------------------------------------------------------------------- /assets/images/customizer/starter-content/categories/hoodies.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/customizer/starter-content/categories/hoodies.jpg -------------------------------------------------------------------------------- /assets/images/customizer/starter-content/categories/tshirts.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/customizer/starter-content/categories/tshirts.jpg -------------------------------------------------------------------------------- /assets/images/customizer/starter-content/hero.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/customizer/starter-content/hero.jpg -------------------------------------------------------------------------------- /assets/images/customizer/starter-content/products/beanie.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/customizer/starter-content/products/beanie.jpg -------------------------------------------------------------------------------- /assets/images/customizer/starter-content/products/belt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/customizer/starter-content/products/belt.jpg -------------------------------------------------------------------------------- /assets/images/customizer/starter-content/products/cap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/customizer/starter-content/products/cap.jpg -------------------------------------------------------------------------------- /assets/images/customizer/starter-content/products/hoodie-with-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/customizer/starter-content/products/hoodie-with-logo.jpg -------------------------------------------------------------------------------- /assets/images/customizer/starter-content/products/hoodie-with-pocket.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/customizer/starter-content/products/hoodie-with-pocket.jpg -------------------------------------------------------------------------------- /assets/images/customizer/starter-content/products/hoodie-with-zipper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/customizer/starter-content/products/hoodie-with-zipper.jpg -------------------------------------------------------------------------------- /assets/images/customizer/starter-content/products/hoodie.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/customizer/starter-content/products/hoodie.jpg -------------------------------------------------------------------------------- /assets/images/customizer/starter-content/products/long-sleeve-tee.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/customizer/starter-content/products/long-sleeve-tee.jpg -------------------------------------------------------------------------------- /assets/images/customizer/starter-content/products/polo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/customizer/starter-content/products/polo.jpg -------------------------------------------------------------------------------- /assets/images/customizer/starter-content/products/sunglasses.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/customizer/starter-content/products/sunglasses.jpg -------------------------------------------------------------------------------- /assets/images/customizer/starter-content/products/tshirt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/customizer/starter-content/products/tshirt.jpg -------------------------------------------------------------------------------- /assets/images/customizer/starter-content/products/vneck-tee.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/assets/images/customizer/starter-content/products/vneck-tee.jpg -------------------------------------------------------------------------------- /assets/js/admin/admin.js: -------------------------------------------------------------------------------- 1 | /* global ajaxurl, storefrontNUX */ 2 | ( function ( wp, $ ) { 3 | 'use strict'; 4 | 5 | if ( ! wp ) { 6 | return; 7 | } 8 | 9 | /* 10 | * Ajax request that will hide the Storefront NUX admin notice or message. 11 | */ 12 | function dismissNux() { 13 | $.ajax( { 14 | type: 'POST', 15 | url: ajaxurl, 16 | data: { 17 | nonce: storefrontNUX.nonce, 18 | action: 'storefront_dismiss_notice', 19 | }, 20 | dataType: 'json', 21 | } ); 22 | } 23 | 24 | $( function () { 25 | // Dismiss notice 26 | $( document ).on( 27 | 'click', 28 | '.sf-notice-nux .notice-dismiss', 29 | function () { 30 | dismissNux(); 31 | } 32 | ); 33 | 34 | // Dismiss notice inside theme page. 35 | $( document ).on( 'click', '.sf-nux-dismiss-button', function () { 36 | dismissNux(); 37 | $( '.storefront-intro-setup' ).hide(); 38 | $( '.storefront-intro-message' ).fadeIn( 'slow' ); 39 | } ); 40 | } ); 41 | } )( window.wp, jQuery ); 42 | -------------------------------------------------------------------------------- /assets/js/admin/plugin-install.js: -------------------------------------------------------------------------------- 1 | ( function ( wp, $ ) { 2 | 'use strict'; 3 | 4 | if ( ! wp ) { 5 | return; 6 | } 7 | 8 | $( function () { 9 | $( document ).on( 'click', '.sf-install-now', function ( event ) { 10 | const $button = $( event.target ); 11 | 12 | if ( $button.hasClass( 'activate-now' ) ) { 13 | return true; 14 | } 15 | 16 | event.preventDefault(); 17 | 18 | if ( 19 | $button.hasClass( 'updating-message' ) || 20 | $button.hasClass( 'button-disabled' ) 21 | ) { 22 | return; 23 | } 24 | 25 | if ( 26 | wp.updates.shouldRequestFilesystemCredentials && 27 | ! wp.updates.ajaxLocked 28 | ) { 29 | wp.updates.requestFilesystemCredentials( event ); 30 | 31 | $( document ).on( 'credential-modal-cancel', function () { 32 | const $message = $( '.sf-install-now.updating-message' ); 33 | 34 | $message 35 | .removeClass( 'updating-message' ) 36 | .text( wp.updates.l10n.installNow ); 37 | 38 | wp.a11y.speak( wp.updates.l10n.updateCancel, 'polite' ); 39 | } ); 40 | } 41 | 42 | wp.updates.installPlugin( { 43 | slug: $button.data( 'slug' ), 44 | } ); 45 | } ); 46 | } ); 47 | } )( window.wp, jQuery ); 48 | -------------------------------------------------------------------------------- /assets/js/footer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * footer.js 3 | * 4 | * Adds a class required to reveal the search in the handheld footer bar. 5 | * Also hides the handheld footer bar when an input is focused. 6 | */ 7 | ( function () { 8 | // Wait for DOM to be ready. 9 | document.addEventListener( 'DOMContentLoaded', function () { 10 | if ( 11 | document.getElementsByClassName( 'storefront-handheld-footer-bar' ) 12 | .length === 0 13 | ) { 14 | return; 15 | } 16 | 17 | // Add class to footer search when clicked. 18 | [].forEach.call( 19 | document.querySelectorAll( 20 | '.storefront-handheld-footer-bar .search > a' 21 | ), 22 | function ( anchor ) { 23 | anchor.addEventListener( 'click', function ( event ) { 24 | anchor.parentElement.classList.toggle( 'active' ); 25 | event.preventDefault(); 26 | } ); 27 | } 28 | ); 29 | 30 | // Add focus class to body when an input field is focused. 31 | // This is used to hide the Handheld Footer Bar when an input is focused. 32 | const footerBar = document.getElementsByClassName( 33 | 'storefront-handheld-footer-bar' 34 | ); 35 | const forms = document.forms; 36 | const isFocused = function ( focused ) { 37 | return function ( event ) { 38 | if ( !! focused && event.target.tabIndex !== -1 ) { 39 | document.body.classList.add( 'sf-input-focused' ); 40 | } else { 41 | document.body.classList.remove( 'sf-input-focused' ); 42 | } 43 | }; 44 | }; 45 | 46 | if ( footerBar.length && forms.length ) { 47 | for ( let i = 0; i < forms.length; i++ ) { 48 | if ( footerBar[ 0 ].contains( forms[ i ] ) ) { 49 | continue; 50 | } 51 | 52 | forms[ i ].addEventListener( 'focus', isFocused( true ), true ); 53 | forms[ i ].addEventListener( 'blur', isFocused( false ), true ); 54 | } 55 | } 56 | } ); 57 | } )(); 58 | -------------------------------------------------------------------------------- /assets/js/homepage.js: -------------------------------------------------------------------------------- 1 | /** 2 | * homepage.js 3 | * 4 | * Handles behaviour of the homepage featured image 5 | */ 6 | ( function () { 7 | /** 8 | * Set hero content dimensions / layout 9 | * Run adaptive backgrounds and set colors 10 | */ 11 | document.addEventListener( 'DOMContentLoaded', function () { 12 | const homepageContent = document.querySelector( 13 | '.page-template-template-homepage .type-page.has-post-thumbnail' 14 | ); 15 | 16 | if ( ! homepageContent ) { 17 | // Only apply layout to the homepage content component if it exists on the page 18 | return; 19 | } 20 | 21 | const entries = homepageContent.querySelectorAll( 22 | '.entry-title, .entry-content' 23 | ); 24 | for ( let i = 0; i < entries.length; i++ ) { 25 | entries[ i ].classList.add( 'loaded' ); 26 | } 27 | 28 | const siteMain = document.querySelector( '.site-main' ); 29 | const htmlDirValue = document.documentElement.getAttribute( 'dir' ); 30 | 31 | const updateDimensions = function () { 32 | if ( updateDimensions._tick ) { 33 | window.cancelAnimationFrame( updateDimensions._tick ); 34 | } 35 | 36 | updateDimensions._tick = window.requestAnimationFrame( function () { 37 | updateDimensions._tick = null; 38 | 39 | // Make the homepage content full width and centrally aligned. 40 | homepageContent.style.width = window.innerWidth + 'px'; 41 | 42 | if ( htmlDirValue !== 'rtl' ) { 43 | homepageContent.style.marginLeft = 44 | -siteMain.getBoundingClientRect().left + 'px'; 45 | } else { 46 | homepageContent.style.marginRight = 47 | -siteMain.getBoundingClientRect().left + 'px'; 48 | } 49 | } ); 50 | }; 51 | 52 | // On window resize, set hero content dimensions / layout. 53 | window.addEventListener( 'resize', updateDimensions ); 54 | updateDimensions(); 55 | } ); 56 | } )(); 57 | -------------------------------------------------------------------------------- /assets/js/sticky-add-to-cart.js: -------------------------------------------------------------------------------- 1 | /*global storefront_sticky_add_to_cart_params */ 2 | ( function () { 3 | document.addEventListener( 'DOMContentLoaded', function () { 4 | const stickyAddToCart = document.getElementsByClassName( 5 | 'storefront-sticky-add-to-cart' 6 | ); 7 | 8 | if ( ! stickyAddToCart.length ) { 9 | return; 10 | } 11 | 12 | // eslint-disable-next-line camelcase 13 | if ( typeof storefront_sticky_add_to_cart_params === 'undefined' ) { 14 | return; 15 | } 16 | 17 | const trigger = document.getElementsByClassName( 18 | storefront_sticky_add_to_cart_params.trigger_class 19 | ); 20 | 21 | if ( trigger.length > 0 ) { 22 | const stickyAddToCartToggle = function () { 23 | if ( 24 | trigger[ 0 ].getBoundingClientRect().top + 25 | trigger[ 0 ].scrollHeight < 26 | 0 27 | ) { 28 | stickyAddToCart[ 0 ].classList.add( 29 | 'storefront-sticky-add-to-cart--slideInDown' 30 | ); 31 | stickyAddToCart[ 0 ].classList.remove( 32 | 'storefront-sticky-add-to-cart--slideOutUp' 33 | ); 34 | } else if ( 35 | stickyAddToCart[ 0 ].classList.contains( 36 | 'storefront-sticky-add-to-cart--slideInDown' 37 | ) 38 | ) { 39 | stickyAddToCart[ 0 ].classList.add( 40 | 'storefront-sticky-add-to-cart--slideOutUp' 41 | ); 42 | stickyAddToCart[ 0 ].classList.remove( 43 | 'storefront-sticky-add-to-cart--slideInDown' 44 | ); 45 | } 46 | }; 47 | 48 | stickyAddToCartToggle(); 49 | 50 | window.addEventListener( 'scroll', function () { 51 | stickyAddToCartToggle(); 52 | } ); 53 | 54 | // Get product id 55 | let productId = null; 56 | 57 | document.body.classList.forEach( function ( item ) { 58 | if ( item.substring( 0, 7 ) === 'postid-' ) { 59 | productId = item.replace( /[^0-9]/g, '' ); 60 | } 61 | } ); 62 | 63 | if ( productId ) { 64 | const product = document.getElementById( 65 | 'product-' + productId 66 | ); 67 | 68 | if ( product ) { 69 | if ( 70 | ! product.classList.contains( 'product-type-simple' ) && 71 | ! product.classList.contains( 'product-type-external' ) 72 | ) { 73 | const selectOptions = document.getElementsByClassName( 74 | 'storefront-sticky-add-to-cart__content-button' 75 | ); 76 | 77 | selectOptions[ 0 ].addEventListener( 78 | 'click', 79 | function ( event ) { 80 | event.preventDefault(); 81 | document 82 | .getElementById( 'product-' + productId ) 83 | .scrollIntoView(); 84 | } 85 | ); 86 | } 87 | } 88 | } 89 | } 90 | } ); 91 | } )(); 92 | -------------------------------------------------------------------------------- /assets/js/woocommerce/extensions/brands.js: -------------------------------------------------------------------------------- 1 | /** 2 | * brands.js 3 | * 4 | * Adds sticky functionality to the brands index. 5 | */ 6 | ( function () { 7 | document.addEventListener( 'DOMContentLoaded', function () { 8 | const brandsAZ = document.getElementsByClassName( 'brands_index' ); 9 | 10 | if ( ! brandsAZ.length ) { 11 | return; 12 | } 13 | 14 | const adminBar = document.body.classList.contains( 'admin-bar' ) 15 | ? 32 16 | : 0, 17 | brandsContainerHeight = 18 | document.getElementById( 'brands_a_z' ).scrollHeight, 19 | brandsAZHeight = brandsAZ[ 0 ].scrollHeight + 40; 20 | 21 | const stickyBrandsAZ = function () { 22 | if ( 23 | window.innerWidth > 768 && 24 | brandsAZ[ 0 ].getBoundingClientRect().top < 0 25 | ) { 26 | brandsAZ[ 0 ].style.paddingTop = 27 | Math.min( 28 | Math.abs( brandsAZ[ 0 ].getBoundingClientRect().top ) + 29 | 20 + 30 | adminBar, 31 | brandsContainerHeight - brandsAZHeight 32 | ) + 'px'; 33 | } else { 34 | brandsAZ[ 0 ].style.paddingTop = 0; 35 | } 36 | }; 37 | 38 | stickyBrandsAZ(); 39 | 40 | window.addEventListener( 'scroll', function () { 41 | stickyBrandsAZ(); 42 | } ); 43 | } ); 44 | } )(); 45 | -------------------------------------------------------------------------------- /assets/js/woocommerce/header-cart.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Makes the header cart content scrollable if the height of the dropdown exceeds the window height. 3 | * Mouseover is used as items can be added to the cart via ajax and we'll need to recheck. 4 | */ 5 | ( function () { 6 | if ( 7 | document.body.classList.contains( 'woocommerce-cart' ) || 8 | document.body.classList.contains( 'woocommerce-checkout' ) || 9 | window.innerWidth < 768 || 10 | ! document.getElementById( 'site-header-cart' ) 11 | ) { 12 | return; 13 | } 14 | 15 | window.addEventListener( 'load', function () { 16 | const cart = document.querySelector( '.site-header-cart' ); 17 | 18 | cart.addEventListener( 'mouseover', function () { 19 | const windowHeight = window.outerHeight, 20 | cartBottomPos = 21 | this.querySelector( 22 | '.widget_shopping_cart_content' 23 | ).getBoundingClientRect().bottom + this.offsetHeight, 24 | cartList = this.querySelector( '.cart_list' ); 25 | 26 | if ( cartBottomPos > windowHeight ) { 27 | cartList.style.maxHeight = '15em'; 28 | cartList.style.overflowY = 'auto'; 29 | } 30 | } ); 31 | } ); 32 | } )(); 33 | -------------------------------------------------------------------------------- /comments.php: -------------------------------------------------------------------------------- 1 | 20 | 21 |
22 | 23 | 26 |

27 | ' . get_the_title() . '' 34 | ); 35 | // phpcs:enable 36 | ?> 37 |

38 | 39 | 1 && get_option( 'page_comments' ) ) : // Are there comments to navigate through. ?> 40 | 45 | 46 | 47 |
    48 | 'ol', 52 | 'short_ping' => true, 53 | 'callback' => 'storefront_comment', 54 | ) 55 | ); 56 | ?> 57 |
58 | 59 | 1 && get_option( 'page_comments' ) ) : // Are there comments to navigate through. ?> 60 | 65 | 72 |

73 | '', 80 | 'title_reply_after' => '', 81 | ) 82 | ); 83 | 84 | comment_form( $args ); 85 | ?> 86 | 87 |
88 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "woocommerce/storefront", 3 | "description": "Storefront is a robust and flexible WordPress theme, designed and built by the team at WooCommerce to help you make the most out of using the WooCommerce plugin to power your online store. It's available to download for free from the WordPress theme repository.", 4 | "homepage": "https://woocommerce.com/", 5 | "type": "wordpress-theme", 6 | "license": "GPL-3.0+", 7 | "require": { 8 | "composer/installers": "2.2.0" 9 | }, 10 | "archive": { 11 | "exclude": [ 12 | "!/assets", 13 | "!/languages", 14 | "!/style.css", 15 | "!/style-rtl.css", 16 | "/assets/css/sass", 17 | "/assets/css/**/*.scss", 18 | "/e2e", 19 | "/vendor", 20 | "composer.json", 21 | "composer.lock", 22 | "package.json", 23 | "package-lock.json", 24 | "phpcs.xml", 25 | "phpunit.xml", 26 | "README.md", 27 | "CONTRIBUTING.md", 28 | "STOREFRONT_STATUS.md", 29 | "renovate.json", 30 | "node_modules", 31 | "storefront.zip", 32 | "validate-build.sh", 33 | ".*" 34 | ] 35 | }, 36 | "require-dev": { 37 | "squizlabs/php_codesniffer": "3.7.1", 38 | "wp-coding-standards/wpcs": "2.3.0", 39 | "woocommerce/woocommerce-sniffs": "0.1.3", 40 | "phpcompatibility/php-compatibility": "9.3.5", 41 | "woocommerce/woocommerce-git-hooks": "1.0.5", 42 | "dealerdirect/phpcodesniffer-composer-installer": "0.7.2" 43 | }, 44 | "scripts": { 45 | "pre-update-cmd": [ 46 | "WooCommerce\\GitHooks\\Hooks::preHooks" 47 | ], 48 | "pre-install-cmd": [ 49 | "WooCommerce\\GitHooks\\Hooks::preHooks" 50 | ], 51 | "post-install-cmd": [ 52 | "WooCommerce\\GitHooks\\Hooks::postHooks" 53 | ], 54 | "post-update-cmd": [ 55 | "WooCommerce\\GitHooks\\Hooks::postHooks" 56 | ], 57 | "phpcs": [ 58 | "phpcs --extensions=php -s -p" 59 | ], 60 | "phpcbf": [ 61 | "phpcbf --extensions=php -p" 62 | ] 63 | }, 64 | "extra": { 65 | "scripts-description": { 66 | "test": "Run unit tests", 67 | "phpcs": "Analyze code against the WordPress coding standards with PHP_CodeSniffer", 68 | "phpcbf": "Fix coding standards warnings/errors automatically with PHP Code Beautifier" 69 | } 70 | }, 71 | "config": { 72 | "allow-plugins": { 73 | "dealerdirect/phpcodesniffer-composer-installer": true, 74 | "composer/installers": true 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /content-homepage.php: -------------------------------------------------------------------------------- 1 | 9 | 12 | 13 |
style="" data-featured-image=""> 14 |
15 | 24 |
25 |
26 | -------------------------------------------------------------------------------- /content-none.php: -------------------------------------------------------------------------------- 1 | 11 | 12 |
13 | 16 | 17 |
18 | 19 | 20 |

21 | Get started here.', 'storefront' ), array( 'a' => array( 'href' => array() ) ) ), esc_url( admin_url( 'post-new.php' ) ) ); 24 | ?> 25 |

26 | 27 | 28 | 29 |

30 | 31 | 32 | 33 | 34 |

35 | 36 | 37 | 38 |
39 |
40 | -------------------------------------------------------------------------------- /content-page.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
> 11 | 20 |
21 | -------------------------------------------------------------------------------- /content-single.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
> 11 | 12 | 31 | 32 |
33 | -------------------------------------------------------------------------------- /content.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
> 11 | 12 | 22 | 23 |
24 | -------------------------------------------------------------------------------- /e2e/specs/browser.test.js: -------------------------------------------------------------------------------- 1 | describe( 'Storefront', () => { 2 | beforeAll( async () => { 3 | await page.goto( STORE_URL ); 4 | } ); 5 | 6 | it( 'should have "built with WooCommerce" footer', async () => { 7 | const footerText = await page.evaluate( () => document.querySelector( 'body' ).innerText ); 8 | expect( footerText ).toMatch( 'Built with WooCommerce.' ); 9 | } ); 10 | } ); 11 | -------------------------------------------------------------------------------- /footer.php: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /functions.php: -------------------------------------------------------------------------------- 1 | $storefront_version, 23 | 24 | /** 25 | * Initialize all the things. 26 | */ 27 | 'main' => require 'inc/class-storefront.php', 28 | 'customizer' => require 'inc/customizer/class-storefront-customizer.php', 29 | ); 30 | 31 | require 'inc/storefront-functions.php'; 32 | require 'inc/storefront-template-hooks.php'; 33 | require 'inc/storefront-template-functions.php'; 34 | require 'inc/wordpress-shims.php'; 35 | 36 | if ( class_exists( 'Jetpack' ) ) { 37 | $storefront->jetpack = require 'inc/jetpack/class-storefront-jetpack.php'; 38 | } 39 | 40 | if ( storefront_is_woocommerce_activated() ) { 41 | $storefront->woocommerce = require 'inc/woocommerce/class-storefront-woocommerce.php'; 42 | $storefront->woocommerce_customizer = require 'inc/woocommerce/class-storefront-woocommerce-customizer.php'; 43 | 44 | require 'inc/woocommerce/class-storefront-woocommerce-adjacent-products.php'; 45 | 46 | require 'inc/woocommerce/storefront-woocommerce-template-hooks.php'; 47 | require 'inc/woocommerce/storefront-woocommerce-template-functions.php'; 48 | require 'inc/woocommerce/storefront-woocommerce-functions.php'; 49 | } 50 | 51 | if ( is_admin() ) { 52 | $storefront->admin = require 'inc/admin/class-storefront-admin.php'; 53 | 54 | require 'inc/admin/class-storefront-plugin-install.php'; 55 | } 56 | 57 | /** 58 | * NUX 59 | * Only load if wp version is 4.7.3 or above because of this issue; 60 | * https://core.trac.wordpress.org/ticket/39610?cversion=1&cnum_hist=2 61 | */ 62 | if ( version_compare( get_bloginfo( 'version' ), '4.7.3', '>=' ) && ( is_admin() || is_customize_preview() ) ) { 63 | require 'inc/nux/class-storefront-nux-admin.php'; 64 | require 'inc/nux/class-storefront-nux-guided-tour.php'; 65 | require 'inc/nux/class-storefront-nux-starter-content.php'; 66 | } 67 | 68 | /** 69 | * Note: Do not add any custom code here. Please use a custom plugin so that your customizations aren't lost during updates. 70 | * https://github.com/woocommerce/theme-customisations 71 | */ 72 | -------------------------------------------------------------------------------- /header.php: -------------------------------------------------------------------------------- 1 | section and everything up till
6 | * 7 | * @package storefront 8 | */ 9 | 10 | ?> 11 | > 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | > 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 | 52 | 53 | 62 | 63 |
64 |
65 | 66 | type ) { 38 | default: 39 | case 'text': 40 | echo '

' . wp_kses_post( $this->description ) . '

'; 41 | break; 42 | 43 | case 'heading': 44 | echo '' . esc_html( $this->label ) . ''; 45 | break; 46 | 47 | case 'divider': 48 | echo '
'; 49 | break; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /inc/customizer/class-storefront-customizer-control-more.php: -------------------------------------------------------------------------------- 1 | 22 | 48 | choices ) ) { 49 | return; 50 | } 51 | 52 | $name = '_customize-radio-' . $this->id; ?> 53 | 54 | 55 | label ); ?> 56 | 57 | 58 | description ) ) : ?> 59 | description ); ?> 60 | 61 | 62 |
63 | choices as $value => $label ) : ?> 64 | link(); 67 | checked( $this->value(), $value ); 68 | ?> 69 | > 70 | 73 | 74 | 75 |
76 | 77 | 78 | 'main', 45 | 'footer' => 'page', 46 | 'render' => array( $this, 'jetpack_infinite_scroll_loop' ), 47 | 'footer_widgets' => array( 48 | 'footer-1', 49 | 'footer-2', 50 | 'footer-3', 51 | 'footer-4', 52 | ), 53 | ) 54 | ) 55 | ); 56 | } 57 | 58 | /** 59 | * A loop used to display content appended using Jetpack infinite scroll 60 | * 61 | * @return void 62 | */ 63 | public function jetpack_infinite_scroll_loop() { 64 | do_action( 'storefront_jetpack_infinite_scroll_before' ); 65 | 66 | if ( function_exists( 'storefront_is_product_archive' ) && storefront_is_product_archive() ) { 67 | do_action( 'storefront_jetpack_product_infinite_scroll_before' ); 68 | woocommerce_product_loop_start(); 69 | } 70 | 71 | while ( have_posts() ) : 72 | the_post(); 73 | if ( function_exists( 'storefront_is_product_archive' ) && storefront_is_product_archive() ) { 74 | wc_get_template_part( 'content', 'product' ); 75 | } else { 76 | get_template_part( 'content', get_post_format() ); 77 | } 78 | endwhile; // end of the loop. 79 | 80 | if ( function_exists( 'storefront_is_product_archive' ) && storefront_is_product_archive() ) { 81 | woocommerce_product_loop_end(); 82 | do_action( 'storefront_jetpack_product_infinite_scroll_after' ); 83 | } 84 | 85 | do_action( 'storefront_jetpack_infinite_scroll_after' ); 86 | } 87 | 88 | /** 89 | * Adds columns wrapper to content appended by Jetpack infinite scroll 90 | * 91 | * @return void 92 | */ 93 | public function jetpack_infinite_scroll_wrapper_columns() { 94 | add_action( 'storefront_jetpack_product_infinite_scroll_before', 'storefront_product_columns_wrapper' ); 95 | add_action( 'storefront_jetpack_product_infinite_scroll_after', 'storefront_product_columns_wrapper_close' ); 96 | } 97 | 98 | /** 99 | * Enqueue jetpack styles. 100 | * 101 | * @since 1.6.1 102 | */ 103 | public function jetpack_scripts() { 104 | global $storefront_version; 105 | 106 | if ( wp_style_is( 'the-neverending-homepage', 'enqueued' ) ) { 107 | wp_enqueue_style( 'storefront-jetpack-infinite-scroll', get_template_directory_uri() . '/assets/css/jetpack/infinite-scroll.css', array( 'the-neverending-homepage' ), $storefront_version ); 108 | wp_style_add_data( 'storefront-jetpack-infinite-scroll', 'rtl', 'replace' ); 109 | } 110 | 111 | wp_enqueue_style( 'storefront-jetpack-widgets', get_template_directory_uri() . '/assets/css/jetpack/widgets.css', array(), $storefront_version ); 112 | wp_style_add_data( 'storefront-jetpack-widgets', 'rtl', 'replace' ); 113 | } 114 | } 115 | 116 | endif; 117 | 118 | return new Storefront_Jetpack(); 119 | -------------------------------------------------------------------------------- /inc/nux/class-storefront-nux-admin-inbox-messages-customize.php: -------------------------------------------------------------------------------- 1 | set_title( __( 'Design your store with Storefront 🎨', 'storefront' ) ); 35 | $note->set_content( __( 'Visit the Storefront settings page to start setup and customization of your shop.', 'storefront' ) ); 36 | $note->set_type( Note::E_WC_ADMIN_NOTE_INFORMATIONAL ); 37 | $note->set_name( self::NOTE_NAME ); 38 | $note->set_content_data( (object) array() ); 39 | $note->set_source( 'storefront' ); 40 | $note->add_action( 41 | 'customize-store-with-storefront', 42 | __( 'Let\'s go!', 'storefront' ), 43 | admin_url( 'themes.php?page=storefront-welcome' ), 44 | Note::E_WC_ADMIN_NOTE_ACTIONED, 45 | true 46 | ); 47 | return $note; 48 | } 49 | } 50 | endif; 51 | -------------------------------------------------------------------------------- /inc/nux/class-storefront-nux-guided-tour.php: -------------------------------------------------------------------------------- 1 | guided_tour_steps() ); 64 | } 65 | 66 | /** 67 | * Template for steps. 68 | * 69 | * @since 2.2.0 70 | */ 71 | public function print_templates() { 72 | ?> 73 | 97 | __( 'Welcome to the Customizer', 'storefront' ), 110 | /* translators: %s: 'End Of Line' symbol */ 111 | 'message' => sprintf( __( 'Here you can control the overall look and feel of your store.%sTo get started, let\'s add your logo', 'storefront' ), PHP_EOL . PHP_EOL ), 112 | 'button_text' => __( 'Let\'s go!', 'storefront' ), 113 | 'section' => '#customize-info', 114 | ); 115 | 116 | if ( ! has_custom_logo() ) { 117 | $steps[] = array( 118 | 'title' => __( 'Add your logo', 'storefront' ), 119 | 'message' => __( 'Open the Site Identity Panel, then click the \'Select Logo\' button to upload your logo.', 'storefront' ), 120 | 'section' => 'title_tagline', 121 | ); 122 | } 123 | 124 | $steps[] = array( 125 | 'title' => __( 'Customize your navigation menus', 'storefront' ), 126 | 'message' => __( 'Organize your menus by adding Pages, Categories, Tags, and Custom Links.', 'storefront' ), 127 | 'section' => 'nav_menus', 128 | ); 129 | 130 | $steps[] = array( 131 | 'title' => __( 'Choose your accent color', 'storefront' ), 132 | 'message' => __( 'In the typography panel you can specify an accent color which will be applied to things like links and star ratings. We recommend using your brand color for this setting.', 'storefront' ), 133 | 'section' => 'storefront_typography', 134 | ); 135 | 136 | $steps[] = array( 137 | 'title' => __( 'Color your buttons', 'storefront' ), 138 | 'message' => __( 'Choose colors for your button backgrounds and text. Once again, brand colors are good choices here.', 'storefront' ), 139 | 'section' => 'storefront_buttons', 140 | ); 141 | 142 | $steps[] = array( 143 | 'title' => '', 144 | /* translators: 1: open tag, 2: close tag, 3: 'End Of Line' symbol */ 145 | 'message' => sprintf( __( 'All set! Remember to %1$ssave & publish%2$s your changes when you\'re done.%3$sYou can return to your dashboard by clicking the X in the top left corner.', 'storefront' ), '', '', PHP_EOL . PHP_EOL ), 146 | 'section' => '#customize-header-actions .save', 147 | 'button_text' => __( 'Done', 'storefront' ), 148 | ); 149 | 150 | return $steps; 151 | } 152 | } 153 | 154 | endif; 155 | 156 | return new Storefront_NUX_Guided_Tour(); 157 | -------------------------------------------------------------------------------- /inc/storefront-template-hooks.php: -------------------------------------------------------------------------------- 1 | in_same_term = $in_same_term; 67 | $this->excluded_terms = $excluded_terms; 68 | $this->taxonomy = $taxonomy; 69 | $this->previous = $previous; 70 | } 71 | 72 | /** 73 | * Get adjacent product or circle back to the first/last valid product. 74 | * 75 | * @since 2.4.3 76 | * 77 | * @return WC_Product|false Product object if successful. False if no valid product is found. 78 | */ 79 | public function get_product() { 80 | global $post; 81 | 82 | $product = false; 83 | $this->current_product = $post->ID; 84 | 85 | // Try to get a valid product via `get_adjacent_post()`. 86 | // phpcs:ignore WordPress.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition 87 | while ( $adjacent = $this->get_adjacent() ) { 88 | $product = wc_get_product( $adjacent->ID ); 89 | 90 | if ( $product && $product->is_visible() ) { 91 | break; 92 | } 93 | 94 | $product = false; 95 | $this->current_product = $adjacent->ID; 96 | } 97 | 98 | if ( $product ) { 99 | return $product; 100 | } 101 | 102 | // No valid product found; Query WC for first/last product. 103 | $product = $this->query_wc(); 104 | 105 | if ( $product ) { 106 | return $product; 107 | } 108 | 109 | return false; 110 | } 111 | 112 | /** 113 | * Get adjacent post. 114 | * 115 | * @since 2.4.3 116 | * 117 | * @return WP_POST|false Post object if successful. False if no valid post is found. 118 | */ 119 | private function get_adjacent() { 120 | global $post; 121 | 122 | $direction = $this->previous ? 'previous' : 'next'; 123 | 124 | add_filter( 'get_' . $direction . '_post_where', array( $this, 'filter_post_where' ) ); 125 | 126 | $adjacent = get_adjacent_post( $this->in_same_term, $this->excluded_terms, $this->previous, $this->taxonomy ); 127 | 128 | remove_filter( 'get_' . $direction . '_post_where', array( $this, 'filter_post_where' ) ); 129 | 130 | return $adjacent; 131 | } 132 | 133 | /** 134 | * Filters the WHERE clause in the SQL for an adjacent post query, replacing the 135 | * date with date of the next post to consider. 136 | * 137 | * @since 2.4.3 138 | * 139 | * @param string $where The `WHERE` clause in the SQL. 140 | * @return WP_POST|false Post object if successful. False if no valid post is found. 141 | */ 142 | public function filter_post_where( $where ) { 143 | global $post; 144 | 145 | $new = get_post( $this->current_product ); 146 | 147 | $where = str_replace( $post->post_date, $new->post_date, $where ); 148 | 149 | return $where; 150 | } 151 | 152 | /** 153 | * Query WooCommerce for either the first or last products. 154 | * 155 | * @since 2.4.3 156 | * 157 | * @return WC_Product|false Post object if successful. False if no valid post is found. 158 | */ 159 | private function query_wc() { 160 | global $post; 161 | 162 | $args = array( 163 | 'limit' => 2, 164 | 'visibility' => 'catalog', 165 | 'exclude' => array( $post->ID ), 166 | 'orderby' => 'date', 167 | 'status' => 'publish', 168 | ); 169 | 170 | if ( ! $this->previous ) { 171 | $args['order'] = 'ASC'; 172 | } 173 | 174 | if ( $this->in_same_term ) { 175 | $terms = get_the_terms( $post->ID, $this->taxonomy ); 176 | 177 | if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) { 178 | $args['category'] = wp_list_pluck( $terms, 'slug' ); 179 | } 180 | } 181 | 182 | $products = wc_get_products( apply_filters( 'storefront_woocommerce_adjacent_query_args', $args ) ); 183 | 184 | // At least 2 results are required, otherwise previous/next will be the same. 185 | if ( ! empty( $products ) && count( $products ) >= 2 ) { 186 | return $products[0]; 187 | } 188 | 189 | return false; 190 | } 191 | } 192 | 193 | endif; 194 | -------------------------------------------------------------------------------- /inc/woocommerce/storefront-woocommerce-functions.php: -------------------------------------------------------------------------------- 1 | get_product(); 34 | } 35 | 36 | /** 37 | * Retrieves the next product. 38 | * 39 | * @since 2.4.3 40 | * 41 | * @param bool $in_same_term Optional. Whether post should be in a same taxonomy term. Default false. 42 | * @param array|string $excluded_terms Optional. Comma-separated list of excluded term IDs. Default empty. 43 | * @param string $taxonomy Optional. Taxonomy, if $in_same_term is true. Default 'product_cat'. 44 | * @return WC_Product|false Product object if successful. False if no valid product is found. 45 | */ 46 | function storefront_get_next_product( $in_same_term = false, $excluded_terms = '', $taxonomy = 'product_cat' ) { 47 | $product = new Storefront_WooCommerce_Adjacent_Products( $in_same_term, $excluded_terms, $taxonomy ); 48 | return $product->get_product(); 49 | } 50 | -------------------------------------------------------------------------------- /inc/woocommerce/storefront-woocommerce-template-hooks.php: -------------------------------------------------------------------------------- 1 | 15 | 16 |
17 |
18 | 19 | 30 | 31 |
32 |
33 | 34 | $file.min.js; done", 31 | "prebuild:css": "rm -f $npm_package_config_assets_css_min", 32 | "build:css": "echo \"$(tput setaf \"3\")Building CSS Files$(tput sgr0)\"; sass -I node_modules/bourbon/core -I node_modules/susy/sass assets/css:assets/css --style compressed --no-source-map && sass -I node_modules/bourbon/core -I node_modules/susy/sass style.scss:style.css --style compressed --no-source-map", 33 | "postbuild:css": "npm run autoprefixer && npm run rtlcss", 34 | "autoprefixer": "echo \"$(tput setaf \"3\")Running Autoprefixer$(tput sgr0)\"; for f in $npm_package_config_assets_css_min; do file=${f%.css}; postcss $f --use autoprefixer -r --verbose --no-map; done", 35 | "rtlcss": "echo \"$(tput setaf \"3\")Building RTL CSS$(tput sgr0)\"; for f in $npm_package_config_assets_css_min; do file=${f%.css}; rtlcss $f $file-rtl.css; done", 36 | "makepot": "echo \"$(tput setaf \"3\")Updating POT file$(tput sgr0)\"; wpi18n addtextdomain storefront; wpi18n makepot --domain-path languages --pot-file storefront.pot --type theme --exclude node_modules", 37 | "watchsass": "sass -I node_modules/bourbon/core -I node_modules/susy/sass assets/css:assets/css --style compressed --watch --no-source-map", 38 | "watchjs": "onchange \"assets/js/**/*.js\" -d 1000 -k -e \"assets/js/**/*.min.js\" -- npm run build:js", 39 | "start": "concurrently --kill-others \"npm run watchjs\" \"npm run watchsass\"", 40 | "labels:dry": "github-label-sync --labels ./.github/label-sync-config.json --allow-added-labels --dry-run woocommerce/storefront", 41 | "labels:sync": "github-label-sync --labels ./.github/label-sync-config.json --allow-added-labels woocommerce/storefront", 42 | "lint": "npm run lint:php && npm run lint:css && npm run lint:js", 43 | "lint:ci": "npm run lint:js && npm run lint:css", 44 | "lint:css": "stylelint 'assets/**/*.scss'", 45 | "lint:css-fix": "stylelint 'assets/**/*.scss' --fix", 46 | "lint:js": "wp-scripts lint-js assets/js --ext=js,ts,tsx", 47 | "lint:js:report": "npm run lint:js -- --output-file eslint_report.json --ext=js,ts,tsx --format json", 48 | "lint:js-fix": "eslint assets/js --ext=js,jsx,ts,tsx --fix", 49 | "lint:php": "composer run-script phpcs ./inc", 50 | "wp-env": "wp-env", 51 | "test:e2e": "npm run wp-env run tests-cli wp theme activate storefront && cross-env wp-scripts test-e2e", 52 | "validate-build": "./validate-build.sh" 53 | }, 54 | "jest": { 55 | "preset": "jest-puppeteer", 56 | "setupFilesAfterEnv": [ 57 | "expect-puppeteer" 58 | ], 59 | "globals": { 60 | "STORE_URL": "http://localhost:8802" 61 | }, 62 | "reporters": [ 63 | "default", 64 | [ 65 | "jest-html-reporters", 66 | { 67 | "publicPath": "./artifacts", 68 | "filename": "report.html" 69 | } 70 | ] 71 | ] 72 | }, 73 | "config": { 74 | "wp_org_slug": "storefront", 75 | "translate": true, 76 | "assets": { 77 | "js": { 78 | "min": "assets/js/**/**/*.min.js assets/js/**/*.min.js assets/js/*.min.js", 79 | "src": "assets/js/*.js assets/js/**/*.js assets/js/**/**/*.js" 80 | }, 81 | "css": { 82 | "min": "assets/css/**/*.css assets/css/**/**/*.css *.css", 83 | "src": "assets/css/**/*.scss assets/css/**/**/*.scss *.scss" 84 | } 85 | } 86 | }, 87 | "license": "GPL-3.0+", 88 | "devDependencies": { 89 | "@woocommerce/eslint-plugin": "2.3.0", 90 | "@wordpress/browserslist-config": "6.6.0", 91 | "@wordpress/env": "10.6.0", 92 | "@wordpress/eslint-plugin": "15.1.0", 93 | "@wordpress/prettier-config": "2.25.13", 94 | "@wordpress/scripts": "27.2.6", 95 | "autoprefixer": "10.4.20", 96 | "bourbon": "7.3.0", 97 | "browserslist": "4.23.3", 98 | "concurrently": "8.2.2", 99 | "cross-env": "7.0.3", 100 | "eslint-plugin-import": "2.29.1", 101 | "github-label-sync": "2.3.1", 102 | "jest-puppeteer": "10.1.0", 103 | "jest-html-reporters": "^3.1.7", 104 | "lodash": "4.17.21", 105 | "node-wp-i18n": "1.2.7", 106 | "onchange": "7.1.0", 107 | "postcss-cli": "11.0.0", 108 | "prettier": "npm:wp-prettier@2.8.5", 109 | "puppeteer": "23.2.1", 110 | "rtlcss": "4.3.0", 111 | "susy": "2.2.14", 112 | "typescript": "5.5.4", 113 | "uglify-js": "3.19.3" 114 | }, 115 | "engines": { 116 | "node": "20.17.0", 117 | "npm": "10.8.2" 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /page.php: -------------------------------------------------------------------------------- 1 | 14 | 15 |
16 |
17 | 18 | 35 | 36 |
37 |
38 | 39 | 2 | 3 | WooCommerce Dev Ruleset 4 | 5 | 6 | */node_modules/* 7 | */vendor/* 8 | */tests/* 9 | */languages/* 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | tests/ 26 | 27 | 28 | 29 | */**/abstract-*.php 30 | tests/* 31 | src/* 32 | 33 | 34 | 35 | src/* 36 | tests/* 37 | 38 | 39 | 40 | src/ 41 | tests/php 42 | 43 | 44 | src/ 45 | tests/php 46 | 47 | 48 | 49 | tests/ 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | src/* 59 | 60 | 61 | 62 | * 63 | 64 | 65 | 66 | * 67 | 68 | 69 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ], 5 | "packageRules": [ 6 | { 7 | "updateTypes": ["minor", "patch", "pin", "digest"], 8 | "automerge": true, 9 | "requiredStatusChecks": null 10 | } 11 | ], 12 | "ignoreDeps": ["susy"], 13 | "reviewers": ["team:woo-fse"], 14 | "enabled": false 15 | } 16 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woocommerce/storefront/6e83afd56123e7234b3c0ef5ae653e77c274c8f9/screenshot.png -------------------------------------------------------------------------------- /search.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |
12 | 13 | 14 | 15 | 23 | 24 | 33 | 34 |
35 |
36 | 37 | 12 | 13 | 16 | -------------------------------------------------------------------------------- /single.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |
12 | 13 | 25 | 26 |
27 |
28 | 29 | Additional CSS. 34 | ====== 35 | */ 36 | 37 | // Bourbon 38 | // See: https://www.bourbon.io/docs/latest/ 39 | @import "bourbon"; 40 | 41 | // Susy 42 | // Susy grid system. See: http://oddbird.net/susy/docs/ 43 | @import "susy"; 44 | 45 | // Vendors 46 | // External libraries and frameworks. 47 | @import "assets/css/sass/vendors/normalize"; 48 | @import "assets/css/sass/vendors/modular-scale"; 49 | 50 | // Utilities 51 | // Sass tools and helpers used across the project. 52 | @import "assets/css/sass/utils/variables"; 53 | @import "assets/css/sass/utils/mixins"; 54 | 55 | // Base 56 | // Includes all the main Storefront CSS. 57 | @import "assets/css/base/base"; 58 | @import "assets/css/base/layout"; 59 | -------------------------------------------------------------------------------- /template-fullwidth.php: -------------------------------------------------------------------------------- 1 | 11 | 12 |
13 |
14 | 15 | 32 | 33 |
34 |
35 | 36 | 16 | 17 |
18 |
19 | 20 | 34 | 35 |
36 |
37 |