├── resources ├── img │ └── .gitkeep ├── lang │ └── .gitkeep ├── fonts │ └── .gitkeep ├── scss │ ├── components │ │ ├── _app-main.scss │ │ ├── _app.scss │ │ ├── _widget.scss │ │ ├── _sidebar.scss │ │ ├── _app-footer.scss │ │ ├── _svg.scss │ │ ├── _archive-header.scss │ │ ├── _app-content.scss │ │ ├── _gallery.scss │ │ ├── _app-header.scss │ │ ├── _button.scss │ │ ├── _comments.scss │ │ ├── _table.scss │ │ ├── _comment-respond.scss │ │ ├── _pagination.scss │ │ ├── _form.scss │ │ ├── _comment.scss │ │ ├── _entry.scss │ │ └── _menu.scss │ ├── blocks │ │ ├── _wp-block-code.scss │ │ ├── _wp-block-verse.scss │ │ ├── _wp-block-preformatted.scss │ │ ├── _wp-block-audio.scss │ │ ├── _wp-block-categories.scss │ │ ├── _wp-block-quote.scss │ │ ├── _wp-block-separator.scss │ │ ├── _wp-block-table.scss │ │ ├── _wp-block-image.scss │ │ ├── _wp-block-pullquote.scss │ │ ├── _wp-block-file.scss │ │ ├── _wp-block-latest-posts.scss │ │ ├── _wp-block-embed.scss │ │ ├── _wp-block-columns.scss │ │ ├── _wp-block-media-text.scss │ │ ├── _wp-block-cover.scss │ │ ├── _wp-block-gallery.scss │ │ └── _wp-block-button.scss │ ├── utilities │ │ ├── _clearfix.scss │ │ ├── _hide.scss │ │ ├── _color-palette.scss │ │ ├── _headings.scss │ │ └── _alignment.scss │ ├── objects │ │ ├── _animations.scss │ │ ├── _wrapper.scss │ │ ├── _layout.scss │ │ └── _media.scss │ ├── elements │ │ ├── _hr.scss │ │ ├── _misc.scss │ │ ├── _tables.scss │ │ ├── _blockquote.scss │ │ ├── _links.scss │ │ ├── _lists.scss │ │ ├── _headings.scss │ │ ├── _code.scss │ │ ├── _page.scss │ │ ├── _media.scss │ │ └── _forms.scss │ ├── vendor │ │ └── woocommerce │ │ │ ├── _order-confirmation.scss │ │ │ ├── _archive-product.scss │ │ │ ├── components │ │ │ ├── _tabs.scss │ │ │ └── _gallery.scss │ │ │ ├── _my-account.scss │ │ │ ├── _single-product.scss │ │ │ ├── _cart.scss │ │ │ ├── _checkout.scss │ │ │ └── _general.scss │ ├── tools │ │ ├── _vr.scss │ │ ├── _wrapper.scss │ │ ├── _clearfix.scss │ │ ├── _responsive-embed.scss │ │ ├── _button.scss │ │ ├── _units.scss │ │ ├── _hidden.scss │ │ └── _font-size.scss │ ├── generic │ │ ├── _box-sizing.scss │ │ ├── _reset.scss │ │ └── _normalize.scss │ ├── settings │ │ ├── _global.scss │ │ └── _colors.scss │ ├── woocommerce.scss │ ├── editor.scss │ └── screen.scss ├── views │ ├── layouts │ │ ├── woocommerce.php │ │ ├── single.php │ │ ├── 404.php │ │ ├── index.php │ │ ├── offline.php │ │ └── 500.php │ ├── components │ │ ├── head.php │ │ ├── pagination-singular.php │ │ ├── archive-header.php │ │ ├── sidebar.php │ │ ├── pagination-posts.php │ │ ├── pagination-comments.php │ │ ├── footer.php │ │ ├── header.php │ │ ├── menu.php │ │ ├── menu-primary.php │ │ ├── comments.php │ │ └── comment.php │ ├── content │ │ ├── index.php │ │ ├── single.php │ │ ├── home.php │ │ └── single-post.php │ └── index.php ├── svg │ ├── minus.svg │ ├── plus.svg │ ├── facebook.svg │ ├── chevron-down.svg │ ├── reply.svg │ ├── bars.svg │ ├── linkedin.svg │ ├── youtube.svg │ ├── folder-open.svg │ ├── vimeo.svg │ ├── pinterest.svg │ ├── twitter.svg │ ├── instagram.svg │ └── hashtag.svg └── js │ ├── app.js │ └── customizer.js ├── .eslintignore ├── .browserslistrc ├── .gitignore ├── .stylelintignore ├── .babelrc ├── .eslintrc ├── .editorconfig ├── config ├── rename.json ├── webpack.dev.js ├── webpack.settings.js ├── webpack.prod.js └── webpack.common.js ├── .stylelintrc ├── index.php ├── style.css ├── .github └── dependabot.yml ├── app ├── functions-template.php ├── functions-page-templates.php ├── Providers │ ├── AppServiceProvider.php │ ├── CustomizeServiceProvider.php │ └── WooCommerceServiceProvider.php ├── WooCommerce │ ├── ArchiveProduct │ │ └── ArchiveProduct.php │ └── Setup │ │ └── Setup.php ├── functions-assets.php ├── functions-filters.php ├── Svg │ ├── functions-svg.php │ └── Svg.php ├── functions-setup.php └── Customize │ └── Customize.php ├── postcss.config.js ├── functions.php ├── readme.md ├── bootstrap ├── autoload.php ├── app.php └── compat.php ├── composer.json ├── package.json ├── .travis.yml └── phpcs.xml.dist /resources/img/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/lang/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/fonts/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | public/js/**/*.js 2 | -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | IE 11 4 | -------------------------------------------------------------------------------- /resources/scss/components/_app-main.scss: -------------------------------------------------------------------------------- 1 | .app-main {} 2 | -------------------------------------------------------------------------------- /resources/scss/blocks/_wp-block-code.scss: -------------------------------------------------------------------------------- 1 | .wp-block-code {} 2 | -------------------------------------------------------------------------------- /resources/scss/blocks/_wp-block-verse.scss: -------------------------------------------------------------------------------- 1 | .wp-block-verse {} 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | /vendor/ 3 | public/ 4 | /composer.lock 5 | -------------------------------------------------------------------------------- /.stylelintignore: -------------------------------------------------------------------------------- 1 | resources/scss/generic/_normalize.scss 2 | public 3 | -------------------------------------------------------------------------------- /resources/views/layouts/woocommerce.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/scss/blocks/_wp-block-preformatted.scss: -------------------------------------------------------------------------------- 1 | .wp-block-preformatted {} 2 | -------------------------------------------------------------------------------- /resources/scss/components/_app.scss: -------------------------------------------------------------------------------- 1 | .app { 2 | animation: fadein 0.5s; 3 | } 4 | -------------------------------------------------------------------------------- /resources/views/components/head.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /resources/scss/components/_widget.scss: -------------------------------------------------------------------------------- 1 | .widget { 2 | margin-bottom: vr(1); 3 | } 4 | -------------------------------------------------------------------------------- /resources/scss/utilities/_clearfix.scss: -------------------------------------------------------------------------------- 1 | .clearfix { 2 | @include clearfix(); 3 | } 4 | -------------------------------------------------------------------------------- /resources/scss/components/_sidebar.scss: -------------------------------------------------------------------------------- 1 | .sidebar--subsidiary { 2 | padding: vr(1); 3 | } 4 | -------------------------------------------------------------------------------- /resources/scss/blocks/_wp-block-audio.scss: -------------------------------------------------------------------------------- 1 | .wp-block-audio { 2 | 3 | audio { 4 | width: 100%; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /resources/scss/blocks/_wp-block-categories.scss: -------------------------------------------------------------------------------- 1 | .wp-block-categories { 2 | 3 | &-list {} 4 | 5 | &-dropdown {} 6 | } 7 | -------------------------------------------------------------------------------- /resources/scss/objects/_animations.scss: -------------------------------------------------------------------------------- 1 | @keyframes fadein { 2 | 3 | from { 4 | opacity: 0; 5 | } 6 | 7 | to { 8 | opacity: 1; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /resources/scss/components/_app-footer.scss: -------------------------------------------------------------------------------- 1 | .app-footer { 2 | padding: vr(1); 3 | 4 | &__copyright { 5 | @include font-size(14px); 6 | margin-bottom: 0; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /resources/scss/elements/_hr.scss: -------------------------------------------------------------------------------- 1 | hr { 2 | border: 0; 3 | border-bottom: 2px solid $color-hr; 4 | clear: both; 5 | height: 0; 6 | margin-bottom: vr(2); 7 | margin-top: vr(2); 8 | } 9 | -------------------------------------------------------------------------------- /resources/scss/elements/_misc.scss: -------------------------------------------------------------------------------- 1 | address { 2 | margin-bottom: vr(1); 3 | } 4 | 5 | dfn, 6 | cite, 7 | em, 8 | i { 9 | font-style: italic; 10 | } 11 | 12 | cite { 13 | color: $color-cite; 14 | } 15 | -------------------------------------------------------------------------------- /resources/svg/minus.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/views/components/pagination-singular.php: -------------------------------------------------------------------------------- 1 | true, 5 | 'prev_next' => false, 6 | 'title_text' => __( 'Pages:', 'luxe' ), 7 | ] 8 | ); 9 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "useBuiltIns": "usage", 7 | "corejs": { 8 | "version": 3 9 | } 10 | } 11 | ] 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /resources/views/components/archive-header.php: -------------------------------------------------------------------------------- 1 |
2 |

3 |
4 |
5 | -------------------------------------------------------------------------------- /resources/scss/components/_svg.scss: -------------------------------------------------------------------------------- 1 | .svg { 2 | display: inline-block; 3 | } 4 | 5 | // Loop through all social icons 6 | @each $social-network, $color in $colors-social { 7 | 8 | .svg--#{$social-network} { 9 | fill: $color; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /resources/scss/vendor/woocommerce/_order-confirmation.scss: -------------------------------------------------------------------------------- 1 | .woocommerce-thankyou-order-details { 2 | list-style: none; 3 | margin-left: 0; 4 | 5 | li { 6 | padding: vr(1/2) 0; 7 | 8 | strong { 9 | display: block; 10 | } 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /resources/views/components/sidebar.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["plugin:@wordpress/eslint-plugin/recommended"], 3 | "root": true, 4 | "env": { 5 | "browser": true, 6 | "node": true, 7 | "es6": true 8 | }, 9 | "globals": { 10 | "jQuery": "readonly", 11 | "wp": "readonly" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /resources/scss/tools/_vr.scss: -------------------------------------------------------------------------------- 1 | @function vr( 2 | $baselines: 1 3 | ) { 4 | @if (type-of($baselines) != number) { 5 | @error "`#{$baselines}` needs to be a number."; 6 | } 7 | 8 | @return (($global-line-height / $global-font-size) * 1rem) * $baselines; 9 | } 10 | -------------------------------------------------------------------------------- /resources/views/components/pagination-posts.php: -------------------------------------------------------------------------------- 1 | __( '← Previous', 'luxe' ), 5 | 'next_text' => __( 'Next →', 'luxe' ), 6 | 'title_text' => __( 'Posts Navigation', 'luxe' ), 7 | ] 8 | ); 9 | -------------------------------------------------------------------------------- /resources/views/content/index.php: -------------------------------------------------------------------------------- 1 |
> 2 |
3 | 4 |
5 | 6 |
7 | 8 |
9 |
10 | -------------------------------------------------------------------------------- /resources/scss/elements/_tables.scss: -------------------------------------------------------------------------------- 1 | table { 2 | border-collapse: collapse; 3 | border-spacing: 0; 4 | empty-cells: show; 5 | margin-bottom: vr(1); 6 | max-width: 100%; 7 | width: 100%; 8 | } 9 | 10 | th, 11 | td { 12 | padding: vr(3/4); 13 | text-align: left; 14 | } 15 | -------------------------------------------------------------------------------- /resources/scss/tools/_wrapper.scss: -------------------------------------------------------------------------------- 1 | @mixin wrapper( 2 | $width: $global-width, 3 | $margin: auto, 4 | $padding: null 5 | ) { 6 | margin-left: $margin; 7 | margin-right: $margin; 8 | max-width: rem($width); 9 | padding-left: $padding; 10 | padding-right: $padding; 11 | } 12 | -------------------------------------------------------------------------------- /resources/views/components/pagination-comments.php: -------------------------------------------------------------------------------- 1 | __( '← Previous', 'luxe' ), 5 | 'next_text' => __( 'Next →', 'luxe' ), 6 | 'title_text' => __( 'Comments Navigation', 'luxe' ), 7 | ] 8 | ); 9 | -------------------------------------------------------------------------------- /resources/scss/blocks/_wp-block-quote.scss: -------------------------------------------------------------------------------- 1 | .wp-block-quote { 2 | 3 | cite { 4 | @include font-size($global-font-size); 5 | } 6 | 7 | &.is-style-large { 8 | 9 | p { 10 | @include font-size(30px); 11 | } 12 | 13 | cite { 14 | @include font-size(20px); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /resources/scss/elements/_blockquote.scss: -------------------------------------------------------------------------------- 1 | blockquote { 2 | border-left: 4px solid $color-blockquote-border; 3 | color: $color-blockquote; 4 | margin-bottom: vr(1); 5 | padding-left: vr(1); 6 | 7 | p { 8 | @include font-size($h5); 9 | } 10 | 11 | p:last-of-type { 12 | margin-bottom: vr(1/4); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /resources/svg/plus.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/scss/components/_archive-header.scss: -------------------------------------------------------------------------------- 1 | .archive-header { 2 | flex: 0 0 100%; 3 | margin-bottom: vr(2); 4 | text-align: center; 5 | 6 | &__title {} 7 | 8 | &__description { 9 | @include font-size($h4); 10 | color: $color-grey-700; 11 | 12 | :last-child { 13 | margin-bottom: 0; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /resources/scss/generic/_box-sizing.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * More sensible default box-sizing: 3 | * css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice 4 | */ 5 | 6 | html { 7 | box-sizing: border-box; 8 | } 9 | 10 | * { 11 | 12 | &, 13 | &:before, 14 | &:after { 15 | box-sizing: inherit; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /resources/scss/blocks/_wp-block-separator.scss: -------------------------------------------------------------------------------- 1 | .wp-block-separator { 2 | 3 | &:not(.is-style-wide) { 4 | max-width: 100px; 5 | } 6 | 7 | // Wide style 8 | &.is-style-wide {} 9 | 10 | // Dots style 11 | &.is-style-dots { 12 | border-bottom-style: dotted; 13 | 14 | &::before { 15 | content: none; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /resources/scss/blocks/_wp-block-table.scss: -------------------------------------------------------------------------------- 1 | .wp-block-table { 2 | 3 | th, 4 | td { 5 | border-top: 1px solid $color-table-border; 6 | } 7 | 8 | &.has-fixed-layout { 9 | table-layout: fixed; 10 | } 11 | 12 | &.is-style-stripes { 13 | 14 | tbody tr:nth-child(odd) { 15 | background: $color-grey-100; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /resources/scss/generic/_reset.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * A very simple reset that sits on top of Normalize.css. 3 | */ 4 | 5 | body, 6 | h1, 7 | h2, 8 | h3, 9 | h4, 10 | h5, 11 | h6, 12 | blockquote, 13 | p, 14 | pre, 15 | dl, 16 | dd, 17 | ol, 18 | ul, 19 | figure, 20 | hr, 21 | fieldset, 22 | legend { 23 | margin: 0; 24 | padding: 0; 25 | } 26 | -------------------------------------------------------------------------------- /resources/views/layouts/single.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | display( 'content', Hybrid\Template\hierarchy() ) ?> 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /resources/scss/components/_app-content.scss: -------------------------------------------------------------------------------- 1 | .app-content { 2 | padding: vr(1); 3 | 4 | // Set layout if the main sidebar is active. 5 | .has-sidebar-primary & { 6 | 7 | @include mq(medium) { 8 | display: flex; 9 | flex-wrap: wrap; 10 | 11 | > * { 12 | @include nth-grid(2 1, $gutter: vr(1)); 13 | } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /resources/views/content/single.php: -------------------------------------------------------------------------------- 1 |
> 2 |
3 | 4 |
5 | 6 |
7 | 8 | display( 'components', 'pagination-singular' ) ?> 9 |
10 |
11 | -------------------------------------------------------------------------------- /resources/views/components/footer.php: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | indent_style = tab 9 | 10 | [{*.json,*.yml,.babelrc,.browserslistrc,.eslintrc,.postcssrc,.stylelintrc}] 11 | indent_style = space 12 | indent_size = 2 13 | 14 | [*.txt,wp-config-sample.php] 15 | end_of_line = crlf 16 | -------------------------------------------------------------------------------- /config/rename.json: -------------------------------------------------------------------------------- 1 | { 2 | "from": { 3 | "Name": "Luxe", 4 | "Description": "Luxe is a WordPress starter theme using a modern workflow and best practices.", 5 | "Namespace": "Luxe", 6 | "Uri": "https://github.com/brettsmason/luxe", 7 | "Author": "Brett Mason", 8 | "AuthorEmail": "brettsmason@gmail.com", 9 | "AuthorUri": "https://brettmason.co.uk" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /resources/svg/facebook.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/svg/chevron-down.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/scss/components/_gallery.scss: -------------------------------------------------------------------------------- 1 | .gallery { 2 | display: flex; 3 | flex-wrap: wrap; 4 | 5 | &-item { 6 | margin-bottom: vr(1/2); 7 | } 8 | 9 | @include mq(medium) { 10 | 11 | @for $i from 1 through 10 { 12 | &-columns-#{$i} &-item { 13 | @include nth-grid($i, $gutter: vr(1/2)); 14 | } 15 | } 16 | } 17 | 18 | &-icon { 19 | img {} 20 | } 21 | 22 | &-caption {} 23 | } 24 | -------------------------------------------------------------------------------- /resources/scss/vendor/woocommerce/_archive-product.scss: -------------------------------------------------------------------------------- 1 | .archive-product { 2 | 3 | .woocommerce-result-count { 4 | 5 | @include mq(medium) { 6 | clear: left; 7 | display: inline-block; 8 | float: left; 9 | } 10 | } 11 | 12 | .woocommerce-ordering { 13 | 14 | @include mq(medium) { 15 | clear: right; 16 | display: inline-block; 17 | float: right; 18 | } 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /resources/views/layouts/404.php: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 |
5 | 6 |
7 |

8 | 9 |
10 |
11 | -------------------------------------------------------------------------------- /.stylelintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "stylelint-config-wordpress", 3 | "plugins": [ 4 | "stylelint-order", 5 | "stylelint-scss", 6 | ], 7 | "rules": { 8 | "at-rule-empty-line-before": null, 9 | "at-rule-no-unknown": null, 10 | "declaration-no-important": true, 11 | "order/order": [ 12 | "custom-properties", 13 | "declarations" 14 | ], 15 | "order/properties-alphabetical-order": true 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /resources/scss/blocks/_wp-block-image.scss: -------------------------------------------------------------------------------- 1 | .wp-block-image { 2 | 3 | &.alignfull img { 4 | width: 100%; 5 | } 6 | 7 | &.is-resized { 8 | 9 | // Emulate min-content for Edge and IE11 10 | display: -ms-inline-grid; 11 | -ms-grid-columns: min-content; 12 | width: min-content; 13 | 14 | figcaption { 15 | -ms-grid-row: 2; 16 | } 17 | 18 | img { 19 | max-width: none; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /resources/views/layouts/index.php: -------------------------------------------------------------------------------- 1 | display( 'components', 'archive-header' ) ?> 2 | 3 | 4 | 5 | 9 | 10 | display( 'content', Hybrid\Template\hierarchy() ) ?> 11 | 12 | 13 | 14 | display( 'components', 'pagination-posts' ) ?> 15 | 16 | 17 | -------------------------------------------------------------------------------- /resources/scss/elements/_links.scss: -------------------------------------------------------------------------------- 1 | a { 2 | color: $color-link; 3 | text-decoration: underline; 4 | transition: all $global-transition-duration $global-transition-type; 5 | 6 | &:hover, 7 | &:focus, 8 | &:active { 9 | color: $color-link-hover; 10 | text-decoration: none; 11 | } 12 | 13 | &:focus { 14 | outline: 1px dotted; 15 | } 16 | 17 | &:hover, 18 | &:active { 19 | outline: 0; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /resources/svg/reply.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/svg/bars.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/views/layouts/offline.php: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 |
5 | 6 |
7 | 12 |
13 |
14 | -------------------------------------------------------------------------------- /resources/scss/blocks/_wp-block-pullquote.scss: -------------------------------------------------------------------------------- 1 | .wp-block-pullquote { 2 | text-align: center; 3 | 4 | blockquote { 5 | border: 0; 6 | margin-bottom: 0; 7 | padding: vr(2) 0; 8 | } 9 | 10 | p { 11 | @include font-size($h3); 12 | } 13 | 14 | &.alignleft, 15 | &.alignright { 16 | text-align: left; 17 | } 18 | 19 | &.is-style-solid-color { 20 | 21 | blockquote { 22 | background-color: $color-grey-100; 23 | padding: vr(1); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /resources/scss/elements/_lists.scss: -------------------------------------------------------------------------------- 1 | ul, 2 | ol { 3 | margin-bottom: vr(1); 4 | margin-left: vr(1.5); 5 | } 6 | 7 | ul { 8 | list-style-type: disc; 9 | } 10 | 11 | ol { 12 | list-style-type: decimal; 13 | } 14 | 15 | li > { 16 | 17 | ol, 18 | ul { 19 | margin-bottom: 0; 20 | } 21 | } 22 | 23 | dl { 24 | margin-bottom: vr(1); 25 | } 26 | 27 | dd { 28 | margin-bottom: vr(1/4); 29 | margin-left: vr(1/2); 30 | } 31 | 32 | dt { 33 | font-weight: 700; 34 | } 35 | -------------------------------------------------------------------------------- /resources/scss/utilities/_hide.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Hide only visually, but have it available for screen readers: 3 | * http://snook.ca/archives/html_and_css/hiding-content-for-accessibility 4 | */ 5 | 6 | .hide-visually, 7 | .screen-reader-text { 8 | @include hide-visually(); 9 | 10 | &:focus { 11 | @include show-visually(); 12 | } 13 | } 14 | 15 | /** 16 | * Hide visually and from screen readers. 17 | */ 18 | 19 | .hidden { 20 | display: none !important; 21 | } 22 | -------------------------------------------------------------------------------- /resources/scss/objects/_wrapper.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Page-level constraining and wrapping elements. 3 | */ 4 | 5 | .wrapper { 6 | @include wrapper($global-width); 7 | 8 | &--narrow { 9 | @include wrapper($global-width-narrow, $margin: null); 10 | } 11 | 12 | &--wide { 13 | @include wrapper($global-width-wide, $margin: null); 14 | } 15 | 16 | &--full { 17 | max-width: 100%; 18 | } 19 | 20 | &--flush { 21 | padding-left: 0; 22 | padding-right: 0; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /resources/views/components/header.php: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 |
6 | 7 | 8 | 9 |
10 | 11 | display( 'components', 'menu-primary' ) ?> 12 |
13 |
14 | -------------------------------------------------------------------------------- /resources/scss/components/_app-header.scss: -------------------------------------------------------------------------------- 1 | .app-header { 2 | padding: vr(1); 3 | position: relative; 4 | 5 | &__wrapper { 6 | align-items: center; 7 | display: flex; 8 | justify-content: space-between; 9 | } 10 | 11 | &__branding {} 12 | 13 | &__logo {} 14 | 15 | &__logo-link {} 16 | 17 | &__title { 18 | color: $color-header-title; 19 | margin-bottom: 0; 20 | } 21 | 22 | &__title-link { 23 | color: inherit; 24 | text-decoration: none; 25 | } 26 | 27 | &__description {} 28 | } 29 | -------------------------------------------------------------------------------- /resources/js/app.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Primary front-end script. 3 | * 4 | * Primary JavaScript file. Any includes or anything imported should 5 | * be filtered through this file and eventually saved back into the 6 | * `/public/js/app.js` file. 7 | * 8 | * @package Luxe 9 | * @author Brett Mason 10 | * @copyright Copyright (c) 2018, Brett Mason 11 | * @see @link https://github.com/brettsmason/luxe 12 | * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 13 | */ 14 | -------------------------------------------------------------------------------- /resources/svg/linkedin.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/scss/blocks/_wp-block-file.scss: -------------------------------------------------------------------------------- 1 | .wp-block-file { 2 | margin-bottom: vr(1); 3 | 4 | &.aligncenter { 5 | text-align: center; 6 | } 7 | 8 | &.alignright { 9 | text-align: right; 10 | } 11 | 12 | &__button { 13 | @include button; 14 | @include button-style; 15 | } 16 | 17 | a#{&}__button { 18 | text-decoration: none; 19 | 20 | &:hover, 21 | &:visited, 22 | &:focus, 23 | &:active { 24 | color: $color-white; 25 | text-decoration: none; 26 | } 27 | } 28 | 29 | * + &__button { 30 | margin-left: vr(1/2); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /resources/svg/youtube.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/scss/blocks/_wp-block-latest-posts.scss: -------------------------------------------------------------------------------- 1 | .wp-block-latest-posts { 2 | padding-left: vr(1.5); 3 | 4 | &.is-grid { 5 | display: flex; 6 | flex-wrap: wrap; 7 | list-style: none; 8 | padding: 0; 9 | 10 | li { 11 | margin-bottom: vr(1/4); 12 | margin-right: vr(1); 13 | width: 100%; 14 | } 15 | } 16 | 17 | @include mq(medium) { 18 | @for $i from 2 through 6 { 19 | 20 | &.columns-#{$i} li { 21 | width: calc((100% / #{$i}) - #{vr(1)}); 22 | } 23 | } 24 | } 25 | 26 | &__post-date { 27 | display: block; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /resources/scss/components/_button.scss: -------------------------------------------------------------------------------- 1 | .button { 2 | @include button; 3 | 4 | &.disabled, 5 | [disabled] { 6 | opacity: 0.5; 7 | cursor: not-allowed; 8 | } 9 | } 10 | 11 | .button--primary { 12 | @include button-style($color-primary); 13 | } 14 | 15 | .button--secondary { 16 | @include button-style($color-secondary); 17 | } 18 | 19 | .button--alert { 20 | @include button-style($color-alert); 21 | } 22 | 23 | .button--warning { 24 | @include button-style($color-warning); 25 | } 26 | 27 | .button--success { 28 | @include button-style($color-success); 29 | } 30 | -------------------------------------------------------------------------------- /resources/svg/folder-open.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /resources/views/components/menu.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | 21 | -------------------------------------------------------------------------------- /resources/views/content/home.php: -------------------------------------------------------------------------------- 1 |
> 2 |
3 | 4 |
5 | 6 |
7 | 8 | 9 | 14 |
15 | 16 |
17 | 18 |
19 |
20 | -------------------------------------------------------------------------------- /resources/svg/vimeo.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/views/layouts/500.php: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 |
5 | 6 |
7 | 15 |
16 |
17 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | display( 'index' ); 18 | -------------------------------------------------------------------------------- /resources/scss/components/_comments.scss: -------------------------------------------------------------------------------- 1 | // Comments main container. 2 | .comments-template { 3 | margin-top: vr(2); 4 | } 5 | 6 | .comments { 7 | 8 | // Header/title for the comments section. 9 | &__title { 10 | margin-bottom: vr(1); 11 | } 12 | 13 | // Comments list and children wrapper. 14 | &__list, 15 | .children { 16 | list-style: none; 17 | margin: 0; 18 | padding: 0; 19 | } 20 | 21 | .children { 22 | list-style: none; 23 | margin: 0; 24 | padding: 0; 25 | } 26 | 27 | // Comments closed message. 28 | &__closed { 29 | margin-top: vr(1.5); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /resources/scss/elements/_headings.scss: -------------------------------------------------------------------------------- 1 | h1, 2 | h2, 3 | h3, 4 | h4, 5 | h5, 6 | h6 { 7 | color: $color-heading; 8 | font-family: $font-family-heading; 9 | font-weight: $font-weight-heading; 10 | margin-bottom: vr(1/2); 11 | 12 | a { 13 | color: inherit; 14 | } 15 | } 16 | 17 | h1 { 18 | @include font-size($h1); 19 | } 20 | 21 | h2 { 22 | @include font-size($h2); 23 | } 24 | 25 | h3 { 26 | @include font-size($h3); 27 | } 28 | 29 | h4 { 30 | @include font-size($h4); 31 | } 32 | 33 | h5 { 34 | @include font-size($h5); 35 | } 36 | 37 | h6 { 38 | @include font-size($h6); 39 | } 40 | -------------------------------------------------------------------------------- /resources/scss/components/_table.scss: -------------------------------------------------------------------------------- 1 | .table--fixed { 2 | table-layout: fixed; 3 | } 4 | 5 | // Border around each cell 6 | .table--bordered { 7 | 8 | th, 9 | td { 10 | border: 1px solid $color-table-border; 11 | padding: vr(1/2); 12 | } 13 | } 14 | 15 | .table--ruled { 16 | 17 | th, 18 | td { 19 | border-bottom: 1px solid $color-table-border; 20 | padding: vr(1/2); 21 | } 22 | } 23 | 24 | // Odd striped rows 25 | .table--striped { 26 | 27 | th, 28 | td { 29 | padding: vr(1/2); 30 | } 31 | 32 | tbody tr:nth-child(odd) { 33 | background: $color-table-striped-background; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /resources/scss/components/_comment-respond.scss: -------------------------------------------------------------------------------- 1 | .comment-respond { 2 | margin-top: vr(2); 3 | 4 | // Header/title for the respond section. 5 | &__reply-title {} 6 | 7 | // The comment form. 8 | &__form {} 9 | 10 | // Note section at the top of form. 11 | &__notes {} 12 | 13 | // Logged-in message at the top of the form. 14 | &__logged-in-as {} 15 | 16 | // The wrapping element around individual form fields. 17 | &__field { 18 | 19 | &--comment {} 20 | &--author {} 21 | &--email {} 22 | &--url {} 23 | &--cookies {} 24 | &--submit {} 25 | } 26 | 27 | // Comments closed message. 28 | &__closed {} 29 | } 30 | -------------------------------------------------------------------------------- /resources/scss/utilities/_color-palette.scss: -------------------------------------------------------------------------------- 1 | .has-primary-color { 2 | color: $color-primary; 3 | } 4 | 5 | .has-primary-background-color { 6 | background-color: $color-primary; 7 | } 8 | 9 | .has-secondary-color { 10 | color: $color-secondary; 11 | } 12 | 13 | .has-secondary-background-color { 14 | background-color: $color-secondary; 15 | } 16 | 17 | .has-white-color { 18 | color: $color-white; 19 | } 20 | 21 | .has-white-background-color { 22 | background-color: $color-white; 23 | } 24 | 25 | .has-black-color { 26 | color: $color-black; 27 | } 28 | 29 | .has-black-background-color { 30 | background-color: $color-black; 31 | } 32 | -------------------------------------------------------------------------------- /resources/scss/blocks/_wp-block-embed.scss: -------------------------------------------------------------------------------- 1 | //// 2 | /// Embed block. 3 | /// 4 | /// @group Blocks 5 | //// 6 | 7 | .wp-block-embed { 8 | margin-bottom: vr(1); 9 | 10 | iframe {} 11 | figcaption {} 12 | 13 | &.is-type-image {} 14 | &.is-type-audio {} 15 | &.is-type-rich {} 16 | 17 | .wp-has-aspect-ratio &__wrapper { 18 | @include responsive-embed(); 19 | } 20 | 21 | .wp-embed-aspect-16-9 &__wrapper { 22 | @include responsive-embed(16 by 9, false); 23 | } 24 | 25 | .wp-embed-aspect-4-3 &__wrapper { 26 | @include responsive-embed(4 by 3, false); 27 | } 28 | 29 | .wp-embed-aspect-21-9 &__wrapper { 30 | @include responsive-embed(21 by 9, false); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /resources/scss/tools/_clearfix.scss: -------------------------------------------------------------------------------- 1 | /// Applies the micro clearfix hack popularized by Nicolas Gallagher. Include this mixin on a container if its children are all floated, to give the container a proper height. 2 | /// The clearfix is augmented with specific styles to prevent borders in flexbox environments 3 | /// @link http://nicolasgallagher.com/micro-clearfix-hack/ Micro Clearfix Hack 4 | /// @link http://danisadesigner.com/blog/flexbox-clear-fix-pseudo-elements/ Flexbox fix 5 | @mixin clearfix { 6 | 7 | &::before, 8 | &::after { 9 | content: ""; 10 | display: table; 11 | flex-basis: 0; 12 | order: 1; 13 | } 14 | 15 | &::after { 16 | clear: both; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /resources/scss/blocks/_wp-block-columns.scss: -------------------------------------------------------------------------------- 1 | .wp-block-columns { 2 | display: flex; 3 | flex-wrap: wrap; 4 | margin-bottom: vr(1); 5 | 6 | @include mq(medium) { 7 | flex-wrap: nowrap; 8 | } 9 | 10 | // Editor specific styling. 11 | // Make sure columns span correctly. 12 | .editor-inner-blocks { 13 | flex: 1; 14 | } 15 | } 16 | 17 | // Individual columns. 18 | .wp-block-column { 19 | flex: 0 0 100%; 20 | margin-bottom: vr(1); 21 | 22 | > :last-child, 23 | &:last-child { 24 | margin-bottom: 0; 25 | } 26 | 27 | @include mq(medium) { 28 | flex: 1; 29 | margin-bottom: 0; 30 | margin-right: vr(1); 31 | 32 | &:last-child { 33 | margin-right: 0; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Theme Name: Luxe 3 | * Theme URI: https://github.com/brettsmason/luxe 4 | * Description: Luxe is a WordPress starter theme using a modern workflow and best practices. 5 | * Version: 1.0.0 6 | * Author: Brett Mason 7 | * Author URI: https://github.com/brettsmason 8 | * Tags: custom-background, custom-colors, custom-menu, featured-images, one-column, post-formats, rtl-language-support, theme-options, threaded-comments, translation-ready 9 | * Text Domain: luxe 10 | * Domain Path: /resources/lang 11 | * Requires PHP: 5.6 12 | * License: GNU General Public License v2.0 or later 13 | * License URI: http://www.gnu.org/licenses/gpl-2.0.html 14 | */ 15 | -------------------------------------------------------------------------------- /resources/scss/elements/_code.scss: -------------------------------------------------------------------------------- 1 | code, 2 | kbd, 3 | pre, 4 | samp, 5 | var { 6 | @include font-size(14px); 7 | font-family: $font-family-monospace; 8 | } 9 | 10 | code, 11 | kbd, 12 | mark, 13 | samp { 14 | background-color: $color-code-background; 15 | color: $color-code; 16 | display: inline-block; 17 | line-height: 1; 18 | padding: vr(1/4); 19 | } 20 | 21 | pre { 22 | @include font-size(15px); 23 | background-color: $color-code-background; 24 | color: $color-code; 25 | display: block; 26 | margin-bottom: vr(1); 27 | overflow: auto; 28 | padding: vr(1); 29 | white-space: pre; 30 | 31 | code { 32 | background-color: transparent; 33 | font-size: inherit; 34 | line-height: inherit; 35 | padding: 0; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: composer 4 | directory: "/" 5 | schedule: 6 | interval: monthly 7 | open-pull-requests-limit: 10 8 | - package-ecosystem: npm 9 | directory: "/" 10 | schedule: 11 | interval: monthly 12 | open-pull-requests-limit: 10 13 | ignore: 14 | - dependency-name: sass-loader 15 | versions: 16 | - 10.1.0 17 | - 10.1.1 18 | - dependency-name: core-js 19 | versions: 20 | - 3.8.1 21 | - 3.8.3 22 | - dependency-name: webpack-cli 23 | versions: 24 | - 4.3.1 25 | - 4.4.0 26 | - dependency-name: sass 27 | versions: 28 | - 1.32.0 29 | - dependency-name: webpack-fix-style-only-entries 30 | versions: 31 | - 0.6.0 32 | -------------------------------------------------------------------------------- /resources/views/content/single-post.php: -------------------------------------------------------------------------------- 1 |
> 2 |
3 | 4 | 5 | 10 |
11 | 12 |
13 | 14 | display( 'components', 'pagination-singular' ) ?> 15 |
16 | 17 |
18 | 'category' ] ) ?> 19 | 'post_tag' ] ) ?> 20 |
21 |
22 | -------------------------------------------------------------------------------- /resources/svg/pinterest.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/functions-template.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright Copyright (c) 2018, Brett Mason 11 | * @link https://github.com/brettsmason/luxe 12 | * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 13 | */ 14 | 15 | namespace Luxe; 16 | 17 | /** 18 | * Determine whether to show the sidebar 19 | * 20 | * @since 1.0.0 21 | * @access public 22 | * @return bool 23 | */ 24 | function display_sidebar() { 25 | return apply_filters( 'luxe/display_sidebar', false ); 26 | } 27 | -------------------------------------------------------------------------------- /resources/views/components/menu-primary.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | 25 | -------------------------------------------------------------------------------- /config/webpack.dev.js: -------------------------------------------------------------------------------- 1 | const merge = require( 'webpack-merge' ); 2 | const common = require( './webpack.common.js' ); 3 | const BrowserSyncPlugin = require( 'browser-sync-webpack-plugin' ); 4 | 5 | // Build settings. 6 | const settings = require( './webpack.settings.js' ); 7 | 8 | module.exports = merge( common, { 9 | mode: 'development', 10 | devtool: 'inline-cheap-module-source-map', 11 | plugins: [ 12 | new BrowserSyncPlugin( 13 | { 14 | host: settings.browserSync.host, 15 | port: settings.browserSync.port, 16 | proxy: settings.browserSync.proxy, 17 | open: settings.browserSync.open, 18 | files: settings.browserSync.files, 19 | }, 20 | { 21 | injectCss: true, 22 | reload: false, 23 | }, 24 | ), 25 | ], 26 | } ); 27 | -------------------------------------------------------------------------------- /app/functions-page-templates.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright Copyright (c) 2018, Brett Mason 10 | * @link https://github.com/brettsmason/luxe 11 | * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 12 | */ 13 | 14 | namespace Luxe; 15 | 16 | /** 17 | * Add templates to our post types. 18 | */ 19 | add_action( 'hybrid/templates/register', function( $templates ) { 20 | 21 | $templates->add( 22 | 'templates/landing.php', 23 | [ 24 | 'label' => __( 'Landing', 'luxe' ), 25 | 'post_types' => [ 26 | 'page', 27 | ], 28 | ] 29 | ); 30 | } ); 31 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Exports the PostCSS configuration. 3 | * 4 | * @return {string} PostCSS options. 5 | */ 6 | module.exports = ( { file, options, env } ) => ( { /* eslint-disable-line */ 7 | plugins: { 8 | 'postcss-preset-env': { 9 | stage: 0, 10 | autoprefixer: { 11 | grid: true 12 | } 13 | }, 14 | // Minify style on production using cssano. 15 | cssnano: 'production' === env ? 16 | { 17 | preset: [ 18 | 'default', { 19 | autoprefixer: true, 20 | calc: { 21 | precision: 8 22 | }, 23 | convertValues: true, 24 | discardComments: { 25 | removeAll: true 26 | }, 27 | mergeLonghand: false, 28 | zindex: false, 29 | }, 30 | ], 31 | } : false, 32 | }, 33 | } ); 34 | -------------------------------------------------------------------------------- /resources/scss/utilities/_headings.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Redefine all of our basic heading styles against utility classes so as to 3 | * allow for double stranded heading hierarchy, e.g. we semantically need an H2, 4 | * but we want it to be sized like an H1: 5 | * 6 | *

7 | * 8 | */ 9 | 10 | .h1, 11 | .h2, 12 | .h3, 13 | .h4, 14 | .h5, 15 | .h6 { 16 | font-family: $font-family-heading; 17 | font-weight: $font-weight-heading; 18 | } 19 | 20 | .h1 { 21 | @include font-size($h1); 22 | } 23 | 24 | .h2 { 25 | @include font-size($h2); 26 | } 27 | 28 | .h3 { 29 | @include font-size($h3); 30 | } 31 | 32 | .h4 { 33 | @include font-size($h4); 34 | } 35 | 36 | .h5 { 37 | @include font-size($h5); 38 | } 39 | 40 | .h6 { 41 | @include font-size($h6); 42 | } 43 | -------------------------------------------------------------------------------- /resources/scss/objects/_layout.scss: -------------------------------------------------------------------------------- 1 | .grid { 2 | @include mq(medium) { 3 | display: flex; 4 | flex-wrap: wrap; 5 | } 6 | } 7 | 8 | .grid--2 { 9 | 10 | .entry { 11 | @include mq(medium) { 12 | @include nth-grid(2, $gutter: vr(1), $selector: type); 13 | } 14 | } 15 | } 16 | 17 | .grid--3 { 18 | 19 | .entry { 20 | @include mq(medium) { 21 | @include nth-grid(3, $gutter: vr(1), $selector: type); 22 | } 23 | } 24 | } 25 | 26 | .grid--4 { 27 | 28 | .entry { 29 | @include mq(medium) { 30 | @include nth-grid(4, $gutter: vr(1), $selector: type); 31 | } 32 | } 33 | } 34 | 35 | .grid--auto { 36 | @include mq(medium) { 37 | 38 | > * { 39 | flex: 1 1 0; 40 | margin-right: vr(1); 41 | 42 | &:last-child { 43 | margin-right: 0; 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /resources/scss/blocks/_wp-block-media-text.scss: -------------------------------------------------------------------------------- 1 | .wp-block-media-text { 2 | display: flex; 3 | flex-direction: column; 4 | 5 | @include mq(medium) { 6 | flex-direction: row; 7 | 8 | &.has-media-on-the-right { 9 | flex-direction: row-reverse; 10 | } 11 | } 12 | 13 | &__media { 14 | flex: 0 0 auto; 15 | margin: 0; 16 | 17 | @include mq(medium) { 18 | width: 50%; 19 | } 20 | } 21 | 22 | &__content { 23 | padding: vr(1); 24 | 25 | @include mq(medium) { 26 | display: flex; 27 | flex-direction: column; 28 | justify-content: center; 29 | padding: vr(2); 30 | } 31 | } 32 | 33 | img { 34 | height: 100%; 35 | object-fit: cover; 36 | 37 | } 38 | 39 | img, 40 | video { 41 | max-width: unset; 42 | vertical-align: middle; 43 | width: 100%; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /resources/views/index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | > 5 | display( 'components', 'head' ) ?> 6 | 7 | > 8 | 9 | 10 |
11 | display( 'components', 'header' ) ?> 12 | 13 |
14 |
15 | display( 'layouts', Hybrid\Template\hierarchy() ) ?> 16 |
17 |
18 | 19 | display( 'components', 'sidebar', [ 'location' => 'subsidiary' ] ) ?> 20 | 21 | display( 'components', 'footer' ) ?> 22 |
23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /resources/svg/twitter.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/scss/vendor/woocommerce/components/_tabs.scss: -------------------------------------------------------------------------------- 1 | .woocommerce-tabs { 2 | clear: both; 3 | margin-bottom: vr(2); 4 | } 5 | 6 | .wc-tabs { 7 | display: flex; 8 | flex-direction: column; 9 | list-style: none; 10 | margin: 0; 11 | position: relative; 12 | top: 1px; 13 | clear: both; 14 | 15 | @include mq(medium) { 16 | flex-direction: row; 17 | } 18 | 19 | a { 20 | background-color: $color-grey-300; 21 | border: 1px solid $color-grey-300; 22 | color: $color-text; 23 | display: block; 24 | padding: vr(1/2) vr(1); 25 | } 26 | 27 | .active a, 28 | a:hover, 29 | a:focus { 30 | background-color: $color-white; 31 | border-bottom-color: $color-white; 32 | text-decoration: none; 33 | } 34 | } 35 | 36 | .woocommerce-Tabs-panel { 37 | border: 1px solid $color-border; 38 | padding: vr(1); 39 | 40 | h2 { 41 | @include font-size($h6); 42 | } 43 | 44 | :last-child { 45 | margin-bottom: 0; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /resources/scss/elements/_page.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Simple page-level setup. 3 | * 4 | * 1. Set the default `font-size` and `line-height` for the entire project. 5 | * 2. Ensure the page always fills at least the entire height of the viewport. 6 | * 3. Force scrollbars to always be visible to prevent awkward ‘jumps’ when 7 | * navigating between pages that do/do not have enough content to produce 8 | * scrollbars naturally. 9 | */ 10 | 11 | html { 12 | background: $color-background; 13 | color: $color-text; 14 | font-family: $font-family-body; 15 | font-size: percentage($global-font-size / 16px); /* [1] */ 16 | -moz-osx-font-smoothing: grayscale; 17 | -webkit-font-smoothing: antialiased; 18 | line-height: $global-line-height / $global-font-size; /* [1] */ 19 | min-height: 100%; /* [2] */ 20 | overflow-x: hidden; 21 | overflow-y: scroll; /* [3] */ 22 | text-rendering: optimizeLegibility; 23 | } 24 | 25 | p { 26 | margin-bottom: vr(1); 27 | } 28 | -------------------------------------------------------------------------------- /resources/scss/vendor/woocommerce/_my-account.scss: -------------------------------------------------------------------------------- 1 | .woocommerce-account { 2 | 3 | .woocommerce { 4 | @include clearfix; 5 | } 6 | } 7 | 8 | .woocommerce-MyAccount-navigation { 9 | 10 | @include mq(medium) { 11 | width: calc(20% - #{vr(1/2)}); 12 | margin-right: vr(1); 13 | float: left; 14 | } 15 | 16 | ul { 17 | list-style: none; 18 | margin-left: 0; 19 | } 20 | } 21 | 22 | .woocommerce-MyAccount-content { 23 | 24 | @include mq(medium) { 25 | width: calc(80% - #{vr(1/2)}); 26 | float: left; 27 | } 28 | 29 | fieldset { 30 | margin-bottom: 0; 31 | } 32 | } 33 | 34 | .woocommerce-MyAccount-navigation-link { 35 | 36 | & + & { 37 | border-top: 1px solid $color-border; 38 | } 39 | 40 | a { 41 | display: block; 42 | padding: vr(1/2); 43 | text-align: center; 44 | text-decoration: none; 45 | 46 | @include mq(medium) { 47 | text-align: left; 48 | } 49 | } 50 | 51 | &.is-active { 52 | background-color: $color-grey-100; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /resources/scss/elements/_media.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * 1. Fluid images for responsive purposes. 3 | * 2. Offset `alt` text from surrounding copy. 4 | * 3. Setting `vertical-align` removes the whitespace that appears under `img` 5 | * elements when they are dropped into a page as-is. Safer alternative to 6 | * using `display: block;`. 7 | */ 8 | 9 | img { 10 | font-style: italic; /* [2] */ 11 | height: auto; 12 | max-width: 100%; /* [1] */ 13 | vertical-align: middle; /* [3] */ 14 | } 15 | 16 | /// Make sure embeds and iframes fit their containers. 17 | embed, 18 | iframe, 19 | object { 20 | max-width: 100%; 21 | } 22 | 23 | figure { 24 | margin: 0 0 vr(1); 25 | max-width: 100%; 26 | position: relative; 27 | 28 | img { 29 | display: block; 30 | margin-left: auto; 31 | margin-right: auto; 32 | } 33 | } 34 | 35 | figcaption { 36 | @include font-size(14px, $modifier: -1); 37 | font-style: italic; 38 | margin-top: vr(1/4); 39 | text-align: center; 40 | width: 100%; 41 | } 42 | -------------------------------------------------------------------------------- /resources/scss/objects/_media.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Place any image and text-like content side-by-side, as per: 3 | * http://www.stubbornella.org/content/2010/06/25/the-media-object-saves-hundreds-of-lines-of-code 4 | */ 5 | 6 | .o-media { 7 | align-items: flex-start; 8 | display: flex; 9 | } 10 | 11 | .o-media__img { 12 | margin-right: vr(1); 13 | 14 | > img { 15 | display: block; 16 | } 17 | } 18 | 19 | .o-media__body { 20 | flex: 1; 21 | 22 | &, 23 | > :last-child { 24 | margin-bottom: 0; 25 | } 26 | } 27 | 28 | /* Reversed media objects 29 | ========================================================================== */ 30 | 31 | .o-media--reverse { 32 | 33 | > .o-media__img { 34 | margin-left: vr(1); 35 | margin-right: 0; 36 | } 37 | } 38 | 39 | /* Gutterless media objects 40 | ========================================================================== */ 41 | 42 | .o-media--flush { 43 | 44 | > .o-media__img { 45 | margin-left: 0; 46 | margin-right: 0; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /resources/svg/instagram.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/scss/components/_pagination.scss: -------------------------------------------------------------------------------- 1 | .pagination { 2 | border-bottom: 1px solid $color-grey-200; 3 | border-top: 1px solid $color-grey-200; 4 | clear: both; 5 | padding-bottom: vr(1); 6 | padding-top: vr(1); 7 | width: 100%; 8 | 9 | &__items { 10 | display: flex; 11 | flex-wrap: wrap; 12 | justify-content: center; 13 | list-style: none; 14 | margin: 0; 15 | } 16 | 17 | &__item { 18 | line-height: 1; 19 | 20 | & + & { 21 | margin-left: vr(1/4); 22 | } 23 | } 24 | 25 | &__anchor { 26 | border-radius: $global-radius; 27 | display: block; 28 | line-height: 1; 29 | padding: vr(1/4) vr(1/2); 30 | text-decoration: none; 31 | 32 | &--current { 33 | background-color: $color-primary; 34 | color: $color-white; 35 | } 36 | } 37 | 38 | &__anchor-icon { 39 | fill: currentColor; 40 | height: 20px; 41 | width: 20px; 42 | 43 | &--prev { 44 | transform: rotate(90deg); 45 | } 46 | 47 | &--next { 48 | transform: rotate(-90deg); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /resources/scss/tools/_responsive-embed.scss: -------------------------------------------------------------------------------- 1 | /// Creates a responsive embed container. 2 | /// @param {List} $ratio - Ratio of the container. 3 | /// @param {Boolean} $base [true] - Include base styles or not. 4 | @mixin responsive-embed($ratio: null, $base: true) { 5 | @if $ratio { 6 | padding-bottom: ratio-to-percentage($ratio); 7 | } 8 | 9 | @if $base { 10 | height: 0; 11 | overflow: hidden; 12 | position: relative; 13 | 14 | iframe, 15 | object, 16 | embed, 17 | video { 18 | height: 100%; 19 | left: 0; 20 | position: absolute; 21 | top: 0; 22 | width: 100%; 23 | } 24 | } 25 | } 26 | 27 | /// Calculates the height as a percentage of the width for a given ratio. 28 | /// @param {List} $ratio - Ratio to use to calculate the height, formatted as `x by y`. 29 | /// @return {Number} A percentage value for the height relative to the width of a responsive container. 30 | @function ratio-to-percentage($ratio) { 31 | $w: nth($ratio, 1); 32 | $h: nth($ratio, 3); 33 | @return $h / $w * 100%; 34 | } 35 | -------------------------------------------------------------------------------- /resources/scss/components/_form.scss: -------------------------------------------------------------------------------- 1 | .form-field { 2 | margin-bottom: vr(1/2); 3 | 4 | &__description { 5 | @include font-size(14px); 6 | color: $color-grey-500; 7 | } 8 | 9 | &__required { 10 | color: $color-form-input-required; 11 | } 12 | 13 | &__checkbox label, 14 | &__radio label { 15 | font-weight: 400; 16 | } 17 | 18 | // Inline form styles. 19 | // Apply this to set radio/checkbox fields inline. 20 | &--inline { 21 | 22 | .form-field__checkbox, 23 | .form-field__radio { 24 | display: inline-block; 25 | } 26 | 27 | .form-field__checkbox + .form-field__checkbox, 28 | .form-field__radio + .form-field__radio { 29 | margin-left: vr(1/2); 30 | } 31 | } 32 | } 33 | 34 | // Add required styling for occurances when we 35 | // cant add the above classes. 36 | .required { 37 | color: $color-form-input-required; 38 | } 39 | 40 | // A padded, bordered fieldset. 41 | .form-fieldset { 42 | border: 1px solid $color-form-fieldset-border; 43 | padding: vr(1); 44 | 45 | legend { 46 | margin-bottom: 0; 47 | margin-left: -#{vr(1/2)}; 48 | padding: 0 vr(1/2); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /resources/scss/tools/_button.scss: -------------------------------------------------------------------------------- 1 | @mixin button() { 2 | -webkit-appearance: none; 3 | -moz-appearance: none; 4 | border: 1px solid transparent; 5 | border-radius: $global-radius; 6 | cursor: pointer; 7 | display: inline-block; 8 | font: inherit; 9 | line-height: 1; 10 | padding: vr(1/2) vr(3/4); 11 | text-align: center; 12 | text-decoration: none; 13 | transition: all $global-transition-duration $global-transition-type; 14 | vertical-align: middle; 15 | } 16 | 17 | 18 | @mixin button-style( 19 | $background-color: $color-primary, 20 | $color: $color-white, 21 | $background-color-hover: null, 22 | $color-hover: null, 23 | $border: null, 24 | $border-hover: null 25 | ) { 26 | @if $background-color { 27 | $background-color-hover: if($background-color-hover, $background-color-hover, darken($background-color, 10%)); 28 | } 29 | 30 | @if $color { 31 | $color-hover: if($color-hover, $color-hover, $color); 32 | } 33 | 34 | background-color: $background-color; 35 | color: $color; 36 | 37 | &:hover, 38 | &:focus { 39 | background-color: $background-color-hover; 40 | color: $color-hover; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /resources/scss/utilities/_alignment.scss: -------------------------------------------------------------------------------- 1 | .alignleft { 2 | float: left; 3 | margin-bottom: vr(1); 4 | margin-right: vr(1); 5 | max-width: 50%; 6 | 7 | @include mq($global-width) { 8 | margin-left: calc((100% - #{$global-width}) / 2); 9 | } 10 | } 11 | 12 | .alignright { 13 | float: right; 14 | margin-bottom: vr(1); 15 | margin-left: vr(1); 16 | max-width: 50%; 17 | 18 | @include mq($global-width) { 19 | margin-right: calc((100% - #{$global-width}) / 2); 20 | } 21 | } 22 | 23 | .aligncenter { 24 | clear: both; 25 | display: block; 26 | margin-bottom: vr(1); 27 | margin-left: auto; 28 | margin-right: auto; 29 | } 30 | 31 | .alignwide { 32 | max-width: rem($global-width-wide); 33 | } 34 | 35 | .alignfull { 36 | margin-left: -#{vr(1)}; 37 | margin-right: -#{vr(1)}; 38 | max-width: calc(100% + #{vr(2)}); 39 | } 40 | 41 | .float-left { 42 | float: left; 43 | } 44 | 45 | .float-right { 46 | float: right; 47 | } 48 | 49 | .clear { 50 | clear: both; 51 | } 52 | 53 | .text-center { 54 | text-align: center; 55 | } 56 | 57 | .text-left { 58 | text-align: left; 59 | } 60 | 61 | .text-right { 62 | text-align: right; 63 | } 64 | -------------------------------------------------------------------------------- /resources/views/components/comments.php: -------------------------------------------------------------------------------- 1 | 6 | 7 |
8 |
9 | 10 | 11 | 12 |

13 | 14 | 15 | 16 |
    17 | 18 | 'ol', 22 | 'callback' => function( $comment, $args, $depth ) { 23 | Hybrid\View\display( 'components', Hybrid\Comment\hierarchy(), compact( 'comment', 'args', 'depth' ) ); 24 | } 25 | ] 26 | ) 27 | ?> 28 | 29 |
30 | 31 | 32 | 33 | 34 | 35 |

36 | 37 |

38 | 39 | 40 | 41 |
42 | 43 | 44 | 45 |
46 | -------------------------------------------------------------------------------- /functions.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright Copyright (c) 2018, Brett Mason 10 | * @link https://github.com/brettsmason/luxe 11 | * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 12 | */ 13 | 14 | /** 15 | * Compatibility check. 16 | * 17 | * Check that the site meets the minimum requirements for the theme before 18 | * proceeding if this is a theme for public release. If building for a client 19 | * that meets these requirements, this code is unnecessary. 20 | */ 21 | if ( version_compare( $GLOBALS['wp_version'], '5.2', '<' ) || version_compare( PHP_VERSION, '5.6', '<' ) ) { 22 | require_once get_parent_theme_file_path( 'bootstrap/compat.php' ); 23 | return; 24 | } 25 | 26 | /** 27 | * Bootstrap the theme. 28 | * 29 | * Load the bootstrap files. Note that autoloading should happen first so that 30 | * any classes/functions are available that we might need. 31 | */ 32 | require_once get_parent_theme_file_path( 'bootstrap/autoload.php' ); 33 | require_once get_parent_theme_file_path( 'bootstrap/app.php' ); 34 | -------------------------------------------------------------------------------- /resources/svg/hashtag.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Luxe - A WordPress starter theme 2 | 3 | Luxe is a WordPress starter theme using a modern workflow and best practices. 4 | 5 | The theme's primary goal is to offer a modern development experience for WordPress theme authors while sticking as close to possible to WordPress standards as we can. Sometimes those things don't always mesh well. This theme aims to balance that. 6 | 7 | ## Requirements 8 | 9 | There's a few requirements in order to develop a new theme or contribute back to the project: 10 | 11 | * PHP 5.6+ (preferably 7+) 12 | * [Git](https://git-scm.com/) for version control. 13 | * [Composer](https://getcomposer.org/) for managing PHP dependencies. 14 | * [NPM](https://www.npmjs.com/) or [Yarn](https://yarnpkg.com/en/) (your choice) for managing JS dependencies. 15 | 16 | You should feel reasonably comfortable using the command line. The theme tries to keep this as simple as possible, but some command line knowledge is necessary in modern development. 17 | 18 | ## Documentation 19 | 20 | Check out the [project wiki](https://github.com/brettsmason/luxe/wiki) to learn how to install and set up the theme. 21 | 22 | ## Copyright and License 23 | 24 | Luxe is licensed under the GNU GPL, version 2 or later. 25 | 26 | 2018 © Brett Mason. 27 | -------------------------------------------------------------------------------- /bootstrap/autoload.php: -------------------------------------------------------------------------------- 1 | > 2 |
3 | 'comment__avatar-img' ] ) ?> 4 |
5 | 6 |
7 |
8 | 9 | sprintf( 13 | // Translators: 1 is the comment date and 2 is the time. 14 | esc_html__( '%1$s at %2$s', 'luxe' ), 15 | Hybrid\Comment\render_date( [ 'format' => 'jS F Y' ] ), 16 | Hybrid\Comment\render_time() 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 | is needed. WordPress will know where to add it. */ ?> 42 | -------------------------------------------------------------------------------- /app/Providers/AppServiceProvider.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright Copyright (c) 2018, Brett Mason 12 | * @link https://github.com/brettsmason/luxe 13 | * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 14 | */ 15 | 16 | namespace Luxe\Providers; 17 | 18 | use Hybrid\Tools\ServiceProvider; 19 | 20 | /** 21 | * App service provider. 22 | * 23 | * @since 1.0.0 24 | * @access public 25 | */ 26 | class AppServiceProvider extends ServiceProvider { 27 | 28 | /** 29 | * Callback executed when the `\Hybrid\Core\Application` class registers 30 | * providers. Use this method to bind items to the container. 31 | * 32 | * @since 1.0.0 33 | * @access public 34 | * @return void 35 | */ 36 | public function register() { 37 | 38 | // Bind the asset manifest for cache-busting. 39 | $this->app->singleton( 'luxe/manifest', function() { 40 | 41 | $file = get_theme_file_path( 'public/manifest.json' ); 42 | 43 | return file_exists( $file ) ? json_decode( file_get_contents( $file ), true ) : null; 44 | } ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "brettsmason/luxe", 3 | "type": "wordpress-theme", 4 | "description": "Luxe is a WordPress starter theme using a modern workflow and best practices.", 5 | "keywords": [ 6 | "wordpress" 7 | ], 8 | "homepage": "https://github.com/brettsmason/luxe", 9 | "license": "GPL-2.0-or-later", 10 | "authors": [ 11 | { 12 | "name": "Brett Mason", 13 | "email": "brettsmason@gmail.com", 14 | "homepage": "https://brettmason.co.uk" 15 | } 16 | ], 17 | "autoload": { 18 | "psr-4": { 19 | "Luxe\\": "app/" 20 | } 21 | }, 22 | "require": { 23 | "php": ">=5.6", 24 | "composer/installers": "~1.0", 25 | "justintadlock/hybrid-core": "^5.0.0" 26 | }, 27 | "require-dev": { 28 | "php": ">=7.0", 29 | "wp-coding-standards/wpcs": "*", 30 | "dealerdirect/phpcodesniffer-composer-installer": "*", 31 | "phpcompatibility/php-compatibility": "*" 32 | }, 33 | "scripts": { 34 | "install-codestandards": [ 35 | "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin::run" 36 | ], 37 | "post-install-cmd": [ 38 | "@install-codestandards" 39 | ], 40 | "phpcbf-dev": "\"vendor/bin/phpcbf\"", 41 | "run-phpcbf": [ 42 | "@phpcbf-dev" 43 | ], 44 | "phpcs-dev": "\"vendor/bin/phpcs\"", 45 | "run-phpcs": [ 46 | "@phpcs-dev" 47 | ] 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /resources/scss/tools/_units.scss: -------------------------------------------------------------------------------- 1 | /// Removes the unit (e.g. px, em, rem) from a value, returning the number only. 2 | /// 3 | /// @param {Number} $num - Number to strip unit from. 4 | /// 5 | /// @returns {Number} The same number, sans unit. 6 | @function strip-unit($num) { 7 | @return $num / ($num * 0 + 1); 8 | } 9 | 10 | /// Converts a pixel value to matching rem value. *Any* value passed, regardless of unit, is assumed to be a pixel value. By default, the base pixel value used to calculate the rem value is taken from the `$global-font-size` variable. 11 | /// 12 | /// @param {Number} $value - Pixel value to convert. 13 | /// @param {Number} $base [null] - Base for pixel conversion. 14 | /// 15 | /// @returns {Number} A number in rems, calculated based on the given value and the base pixel value. rem values are passed through as is. 16 | @function rem($value, $base: null) { 17 | 18 | // If no base is defined, defer to the global font size 19 | @if $base == null { 20 | $base: $global-font-size; 21 | } 22 | 23 | // Check if the value is a number 24 | @if type-of($value) != "number" { 25 | @warn inspect($value) + " was passed to rem(), which is not a number."; 26 | @return $value; 27 | } 28 | 29 | // Calculate rem if units for $value is not rem or em 30 | @if unit($value) == "px" { 31 | $value: strip-unit($value) / strip-unit($base) * 1rem; 32 | } 33 | 34 | @return $value; 35 | } 36 | -------------------------------------------------------------------------------- /resources/js/customizer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Customize preview script. 3 | * 4 | * This file handles the JavaScript for the live preview frame in the customizer. 5 | * The final result gets saved into `public/js/customizer.js`. 6 | * 7 | * @package Luxe 8 | * @author Brett Mason 9 | * @copyright Copyright (c) 2018, Brett Mason 10 | * @see @link https://github.com/brettsmason/luxe 11 | * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 12 | */ 13 | 14 | // Site title. 15 | wp.customize( 'blogname', ( value ) => { 16 | value.bind( ( to ) => { 17 | document.querySelector( '.app-header__title-link' ).textContent = to; 18 | } ); 19 | } ); 20 | 21 | // Site description. 22 | wp.customize( 'blogdescription', ( value ) => { 23 | value.bind( ( to ) => { 24 | document.querySelector( '.app-header__description' ).textContent = to; 25 | } ); 26 | } ); 27 | 28 | // Site title/description toggle. 29 | wp.customize( 'header_text', ( value ) => { 30 | value.bind( ( to ) => { 31 | const headerItems = document.querySelectorAll( '.app-header__title-link, .app-header__description' ); 32 | 33 | headerItems.forEach( ( text ) => { 34 | if ( false === to ) { 35 | text.style.clip = 'rect(0 0 0 0)'; 36 | text.style.position = 'absolute'; 37 | } else { 38 | text.style.clip = null; 39 | text.style.position = null; 40 | } 41 | } ); 42 | } ); 43 | } ); 44 | 45 | -------------------------------------------------------------------------------- /app/WooCommerce/ArchiveProduct/ArchiveProduct.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright Copyright (c) 2018, Brett Mason 8 | * @link https://github.com/brettsmason/luxe 9 | * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 10 | */ 11 | 12 | namespace Luxe\WooCommerce\ArchiveProduct; 13 | 14 | use Hybrid\Contracts\Bootable; 15 | 16 | /** 17 | * Functionality specific to product archives. 18 | * 19 | * @since 1.0.0 20 | * @access public 21 | */ 22 | class ArchiveProduct implements Bootable { 23 | 24 | /** 25 | * Adds actions on the appropriate action hooks. 26 | * 27 | * @since 1.0.0 28 | * @access public 29 | * @return void 30 | */ 31 | public function boot() { 32 | 33 | // Remove add to cart button from archive view. 34 | remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 ); 35 | 36 | // Remove WooCommerce pagination as we are using our own. 37 | remove_action( 'woocommerce_after_shop_loop', 'woocommerce_pagination', 10 ); 38 | 39 | // Add our pagination in place of WooCommerce'. 40 | add_action( 'woocommerce_after_shop_loop', [ $this, 'pagination' ], PHP_INT_MAX ); 41 | } 42 | 43 | /** 44 | * Add custom pagination. 45 | * 46 | * @since 1.0.0 47 | * @access public 48 | * @return string 49 | */ 50 | public function pagination() { 51 | \Hybrid\View\display( 'partials', 'pagination-posts' ); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/functions-assets.php: -------------------------------------------------------------------------------- 1 |

', 26 | esc_url( get_permalink( get_the_ID() ) ), 27 | /* translators: %s: Name of current post */ 28 | sprintf( __( 'Continue reading "%s"', 'luxe' ), get_the_title( get_the_ID() ) ) 29 | ); 30 | 31 | return ' … ' . $link; 32 | } 33 | add_filter( 'excerpt_more', __NAMESPACE__ . '\\excerpt_more' ); 34 | 35 | /** 36 | * Adds custom classes to the array of body classes. 37 | * 38 | * @param array $classes Classes for the body element. 39 | * @return array 40 | */ 41 | function body_class( $classes ) { 42 | 43 | // Adds a class of has-sidebar when the sidebar is enabled and is active. 44 | if ( \is_active_sidebar( 'primary' ) && display_sidebar() ) { 45 | $classes[] = 'has-sidebar-primary'; 46 | } 47 | 48 | return $classes; 49 | } 50 | add_filter( 'body_class', __NAMESPACE__ . '\\body_class' ); -------------------------------------------------------------------------------- /resources/scss/tools/_hidden.scss: -------------------------------------------------------------------------------- 1 | /// Makes an element visually hidden, but still accessible to keyboards and assistive devices. 2 | /// @link http://snook.ca/archives/html_and_css/hiding-content-for-accessibility Hiding Content for Accessibility 3 | /// @link http://hugogiraudel.com/2016/10/13/css-hide-and-seek/ 4 | /// 5 | /// @param {Boolean} $enforce - If `true`, use `!important` on applied properties 6 | @mixin hide-visually($enforce: false) { 7 | $important: if($enforce, "!important", null); 8 | 9 | border: 0 #{$important}; 10 | clip: rect(1px, 1px, 1px, 1px) #{$important}; 11 | -webkit-clip-path: inset(50%) #{$important}; 12 | clip-path: inset(50%) #{$important}; 13 | height: 1px #{$important}; 14 | overflow: hidden #{$important}; 15 | padding: 0 #{$important}; 16 | position: absolute #{$important}; 17 | white-space: nowrap #{$important}; 18 | width: 1px #{$important}; 19 | word-wrap: normal #{$important}; 20 | } 21 | 22 | /// This reverses `hide-visually()`. 23 | /// 24 | /// @param {Boolean} $enforce - If `true`, use `!important` on applied properties. 25 | @mixin show-visually($enforce: false) { 26 | $important: if($enforce, "!important", null); 27 | 28 | background-color: $color-button-background; 29 | clip: auto #{$important}; 30 | clip-path: none #{$important}; 31 | color: $color-button; 32 | height: auto #{$important}; 33 | left: vr(1); 34 | overflow: visible #{$important}; 35 | padding: vr(1/2) vr(3/4); 36 | text-decoration: none; 37 | top: vr(1); 38 | white-space: normal #{$important}; 39 | width: auto #{$important}; 40 | } 41 | -------------------------------------------------------------------------------- /resources/scss/settings/_global.scss: -------------------------------------------------------------------------------- 1 | // Media queries used throughout. 2 | $mq-breakpoints: ( 3 | small: 320px, 4 | medium: 740px, 5 | large: 980px, 6 | xlarge: 1300px 7 | ); 8 | 9 | // Baseline grid lines height. 10 | $global-baseline: 6px; 11 | 12 | // Base typographical styles. 13 | $global-font-size: 18px; 14 | $global-line-height: $global-baseline * 4.5; 15 | 16 | // UI specific treatments. 17 | $global-radius: null; 18 | $global-transition-duration: 300ms; 19 | $global-transition-type: ease-in-out; 20 | 21 | // Global widths used throughout to constrain elements. 22 | $global-width: 1024px; 23 | $global-width-wide: 1400px; 24 | $global-width-narrow: 800px; 25 | 26 | // Font families. 27 | $font-family-body: -apple-system, system-ui, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', 'Arial', sans-serif; 28 | $font-family-heading: $font-family-body; 29 | $font-family-monospace: "Monaco", "Consolas", "Andale Mono", "DejaVu Sans Mono", monospace; 30 | 31 | // Headings. 32 | $h1: ( 33 | null: 32px, 34 | medium: 48px, 35 | ); 36 | $h2: ( 37 | null: 26px, 38 | medium: 36px, 39 | ); 40 | $h3: ( 41 | null: 22px, 42 | medium: 28px, 43 | ); 44 | $h4: ( 45 | null: 20px, 46 | medium: 22px, 47 | ); 48 | $h5: ( 49 | null: 16px, 50 | medium: 20px, 51 | ); 52 | $h6: ( 53 | null: 16px, 54 | medium: 18px, 55 | ); 56 | 57 | $font-weight-heading: 700; 58 | 59 | // Buttons. 60 | $font-weight-button: 400; 61 | 62 | // Forms. 63 | $font-weight-form-legend: 700; 64 | $font-weight-form-label: 700; 65 | 66 | // Gutters for use with nth-grid. 67 | $grid-gutter: $global-line-height; 68 | -------------------------------------------------------------------------------- /bootstrap/app.php: -------------------------------------------------------------------------------- 1 | provider( \Luxe\Providers\AppServiceProvider::class ); 28 | $luxe->provider( \Luxe\Providers\CustomizeServiceProvider::class ); 29 | $luxe->provider( \Luxe\Providers\WooCommerceServiceProvider::class ); 30 | 31 | /** 32 | * Perform bootstrap actions. 33 | * 34 | * Creates an action hook for child themes (or even plugins) to hook into the 35 | * bootstrapping process and add their own bindings before the app is booted by 36 | * passing the application instance to the action callback. 37 | */ 38 | do_action( 'luxe/bootstrap', $luxe ); 39 | 40 | /** 41 | * Bootstrap the application. 42 | * 43 | * Calls the application `boot()` method, which launches the application. Pat 44 | * yourself on the back for a job well done. 45 | */ 46 | $luxe->boot(); 47 | -------------------------------------------------------------------------------- /resources/scss/blocks/_wp-block-cover.scss: -------------------------------------------------------------------------------- 1 | .wp-block-cover { 2 | align-items: center; 3 | background-position: center center; 4 | background-size: cover; 5 | display: flex; 6 | justify-content: center; 7 | margin-bottom: vr(1); 8 | min-height: 430px; 9 | position: relative; 10 | 11 | &-text { 12 | @include font-size($h2); 13 | color: $color-white; 14 | margin-bottom: 0; 15 | max-width: rem($global-width); 16 | padding: vr(1); 17 | text-align: center; 18 | z-index: 1; 19 | 20 | a, 21 | a:hover, 22 | a:focus, 23 | a:active { 24 | color: $color-white; 25 | } 26 | } 27 | 28 | &.has-left-content { 29 | justify-content: flex-start; 30 | 31 | .wp-block-cover-image-text { 32 | margin-left: 0; 33 | text-align: left; 34 | } 35 | } 36 | 37 | &.has-right-content { 38 | justify-content: flex-end; 39 | 40 | .wp-block-cover-image-text { 41 | margin-right: 0; 42 | text-align: right; 43 | } 44 | } 45 | 46 | &.has-parallax { 47 | background-attachment: fixed; 48 | } 49 | 50 | &.has-background-dim::before { 51 | background-color: rgba($color-black, 0.5); 52 | bottom: 0; 53 | content: ""; 54 | left: 0; 55 | position: absolute; 56 | right: 0; 57 | top: 0; 58 | } 59 | 60 | @for $i from 1 through 10 { 61 | 62 | &.has-background-dim-#{$i * 10}::before { 63 | background-color: rgba($color-black, $i * 0.1); 64 | } 65 | } 66 | 67 | &.components-placeholder { 68 | height: inherit; 69 | } 70 | 71 | // Apply max-width to floated items that have no intrinsic width 72 | [data-align="left"] &, 73 | [data-align="right"] &, 74 | &.alignleft, 75 | &.alignright { 76 | max-width: $global-width / 2; 77 | width: 100%; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /resources/scss/blocks/_wp-block-gallery.scss: -------------------------------------------------------------------------------- 1 | .wp-block-gallery { 2 | display: flex; 3 | flex-wrap: wrap; 4 | list-style-type: none; 5 | 6 | .blocks-gallery-item { 7 | @include nth-grid(2, $selector: type, $gutter: vr(1/2)); 8 | display: flex; 9 | flex-direction: column; 10 | flex-grow: 1; 11 | justify-content: center; 12 | margin-bottom: vr(1/2); 13 | margin-left: 0; 14 | position: relative; 15 | 16 | figure { 17 | align-items: flex-end; 18 | display: flex; 19 | height: 100%; 20 | margin: 0; 21 | } 22 | 23 | figcaption { 24 | background-color: rgba($color-black, 0.7); 25 | color: $color-white; 26 | max-height: 100%; 27 | overflow: auto; 28 | padding: vr(1); 29 | position: absolute; 30 | text-align: center; 31 | width: 100%; 32 | } 33 | } 34 | 35 | &.columns-1 .blocks-gallery-item { 36 | width: 100%; 37 | } 38 | 39 | @include mq(medium) { 40 | @for $i from 3 through 8 { 41 | 42 | &.columns-#{$i} .blocks-gallery-item { 43 | @include nth-grid($i, $selector: type, $gutter: vr(1/2)); 44 | 45 | // Remove the margin from the last child so we have nice 46 | // full width images without a gap on the right. 47 | &:last-child { 48 | margin-right: 0; 49 | } 50 | } 51 | } 52 | } 53 | 54 | // Cropped 55 | &.is-cropped .blocks-gallery-item { 56 | 57 | a, 58 | img { 59 | flex: 1; 60 | height: 100%; 61 | object-fit: cover; 62 | width: 100%; 63 | 64 | } 65 | } 66 | 67 | // Apply max-width to floated items that have no intrinsic width 68 | [data-align="left"] &, 69 | [data-align="right"] &, 70 | &.alignleft, 71 | &.alignright { 72 | max-width: $global-width / 2; 73 | width: 100%; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /app/Svg/functions-svg.php: -------------------------------------------------------------------------------- 1 | display(); 22 | } 23 | 24 | /** 25 | * Returns SVG output. 26 | * 27 | * @since 1.0.0 28 | * @access public 29 | * @param string $file The SVG file. 30 | * @param array $args An array or arguements to apply to the SVG. 31 | * @return string 32 | */ 33 | function render( $file, $args = [] ) { 34 | $svg = new Svg( $file, $args ); 35 | return $svg->render(); 36 | } 37 | 38 | /** 39 | * Returns an array of supported social links (URL and icon name). 40 | * 41 | * @return array $social_links_icons 42 | */ 43 | function social_links_icons() { 44 | // Supported social links icons. 45 | $social_links_icons = [ 46 | 'facebook.com' => 'facebook', 47 | 'instagram.com' => 'instagram', 48 | 'linkedin.com' => 'linkedin', 49 | 'medium.com' => 'medium', 50 | 'pinterest.com' => 'pinterest', 51 | 'twitter.com' => 'twitter', 52 | 'vimeo.com' => 'vimeo', 53 | 'youtube.com' => 'youtube', 54 | ]; 55 | 56 | /** 57 | * Filter social links icons. 58 | * 59 | * @param array $social_links_icons Array of social links icons. 60 | */ 61 | return apply_filters( 'luxe_social_links_icons', $social_links_icons ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound 62 | } 63 | -------------------------------------------------------------------------------- /app/Providers/CustomizeServiceProvider.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright Copyright (c) 2018, Brett Mason 12 | * @link https://github.com/brettsmason/luxe 13 | * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 14 | */ 15 | 16 | namespace Luxe\Providers; 17 | 18 | use Hybrid\Tools\ServiceProvider; 19 | use Luxe\Customize\Customize; 20 | 21 | /** 22 | * App service provider. 23 | * 24 | * @since 1.0.0 25 | * @access public 26 | */ 27 | class CustomizeServiceProvider extends ServiceProvider { 28 | 29 | /** 30 | * Callback executed when the `\Hybrid\Core\Application` class registers 31 | * providers. Use this method to bind items to the container. 32 | * 33 | * @since 1.0.0 34 | * @access public 35 | * @return void 36 | */ 37 | public function register() { 38 | 39 | // Bind a single instance of our customizer class. 40 | $this->app->singleton( Customize::class ); 41 | } 42 | 43 | /** 44 | * Callback executed after all the service providers have been registered. 45 | * This is particularly useful for single-instance container objects that 46 | * only need to be loaded once per page and need to be resolved early. 47 | * 48 | * @since 1.0.0 49 | * @access public 50 | * @return void 51 | */ 52 | public function boot() { 53 | 54 | // Boot the customizer class instance. 55 | $this->app->resolve( Customize::class )->boot(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /resources/scss/blocks/_wp-block-button.scss: -------------------------------------------------------------------------------- 1 | .wp-block-button { 2 | 3 | &__link { 4 | @include button; 5 | 6 | &:not(.has-background) { 7 | background-color: $color-button-background; 8 | 9 | &:hover, 10 | &:focus { 11 | background-color: $color-button-hover-background; 12 | } 13 | } 14 | 15 | &:not(.has-text-color) { 16 | color: $color-button; 17 | 18 | &:hover, 19 | &:focus { 20 | color: $color-button-hover; 21 | } 22 | } 23 | } 24 | 25 | &.aligncenter { 26 | text-align: center; 27 | } 28 | 29 | &.alignwide &__link, 30 | &.alignfull &__link { 31 | width: 100%; 32 | } 33 | } 34 | 35 | .is-style-outline .wp-block-button__link { 36 | background-color: transparent; 37 | border-color: $color-button-outline-border; 38 | color: $color-button-outline; 39 | 40 | &:hover, 41 | &:focus { 42 | background-color: $color-button-outline-hover-background; 43 | color: $color-button-outline-hover; 44 | } 45 | 46 | &.has-secondary-background-color { 47 | border-color: $color-secondary; 48 | color: $color-secondary; 49 | 50 | &:hover, 51 | &:focus { 52 | background-color: $color-secondary; 53 | color: $color-white; 54 | } 55 | } 56 | 57 | &.has-black-background-color { 58 | border-color: $color-black; 59 | color: $color-black; 60 | 61 | &:hover, 62 | &:focus { 63 | background-color: $color-black; 64 | color: $color-white; 65 | } 66 | } 67 | 68 | &.has-white-background-color { 69 | border-color: $color-white; 70 | color: $color-black; 71 | 72 | &:hover, 73 | &:focus { 74 | background-color: $color-white; 75 | color: $color-black; 76 | } 77 | } 78 | } 79 | 80 | .is-style-squared .wp-block-button__link { 81 | border-radius: 0; 82 | } 83 | -------------------------------------------------------------------------------- /resources/scss/components/_comment.scss: -------------------------------------------------------------------------------- 1 | .comment { 2 | align-items: flex-start; 3 | display: flex; 4 | 5 | // The comment avatar. 6 | &__avatar { 7 | margin-right: vr(1/2); 8 | min-width: 32px; 9 | 10 | &-img { 11 | border-radius: $global-radius; 12 | } 13 | } 14 | 15 | // Full comment content container. 16 | // [1] - fixes a bug when content doesn't wrap. 17 | &__body { 18 | flex: 1; 19 | min-width: 0; // [1] 20 | } 21 | 22 | // Metadata wrapper. 23 | &__meta { 24 | margin-bottom: vr(1/4); 25 | } 26 | 27 | &__author { 28 | font-weight: 700; 29 | text-decoration: none; 30 | 31 | a { 32 | text-decoration: none; 33 | 34 | &:hover, 35 | &:focus { 36 | text-decoration: underline; 37 | } 38 | } 39 | } 40 | 41 | &__date {} 42 | 43 | &__time {} 44 | 45 | &__permalink, 46 | &__edit { 47 | text-decoration: none; 48 | 49 | &:hover, 50 | &:focus, 51 | &:active { 52 | text-decoration: underline; 53 | } 54 | } 55 | 56 | // Full comment text/content. 57 | &__content { 58 | margin-bottom: vr(1/4); 59 | 60 | > :last-child { 61 | margin-bottom: 0; 62 | } 63 | } 64 | 65 | // Comment actions (reply link etc). 66 | &__actions { 67 | margin-bottom: vr(1.5); 68 | } 69 | 70 | &__reply { 71 | text-decoration: none; 72 | 73 | &:hover, 74 | &:focus, 75 | &:active { 76 | text-decoration: underline; 77 | } 78 | } 79 | 80 | &__reply-icon { 81 | height: vr(1/2); 82 | margin-right: vr(1/4); 83 | width: vr(1/2); 84 | } 85 | 86 | // Comment under moderation message. 87 | &__moderation {} 88 | 89 | // Type of comment. 90 | &--type-comment {} 91 | 92 | &--type-ping { 93 | margin-bottom: vr(1/2); 94 | } 95 | 96 | // Comment status. 97 | &--status-unapproved {} 98 | } 99 | -------------------------------------------------------------------------------- /resources/scss/vendor/woocommerce/_single-product.scss: -------------------------------------------------------------------------------- 1 | .single-product { 2 | 3 | // the main product container. 4 | .product { 5 | position: relative; 6 | } 7 | 8 | .woocommerce-product-gallery { 9 | width: 100%; 10 | margin-bottom: vr(2); 11 | position: relative; 12 | 13 | @include mq(medium) { 14 | float: left; 15 | margin-right: vr(2); 16 | width: calc(50% - #{vr(1)}); 17 | } 18 | } 19 | 20 | // Product summary, which contains title, price etc. 21 | .summary { 22 | width: 100%; 23 | margin-bottom: vr(2); 24 | 25 | @include mq(medium) { 26 | float: left; 27 | width: calc(50% - #{vr(1)}); 28 | } 29 | } 30 | 31 | .cart, 32 | .woocommerce-variation-add-to-cart { 33 | display: flex; 34 | margin-bottom: vr(1); 35 | 36 | .quantity { 37 | margin-right: vr(1/4); 38 | } 39 | } 40 | 41 | // Class added to the .cart form if variations are enabled. 42 | .variations_form { 43 | display: flex; 44 | flex-direction: column; 45 | } 46 | 47 | // Variations table. 48 | .variations { 49 | 50 | td { 51 | display: block; 52 | padding: 0; 53 | } 54 | 55 | input, 56 | select { 57 | margin-bottom: vr(1/2); 58 | } 59 | } 60 | 61 | // Variations reset link. 62 | .reset_variations {} 63 | 64 | .woocommerce-variation-price { 65 | margin-bottom: vr(1); 66 | } 67 | 68 | // Grouped products 69 | .woocommerce-grouped-product-list { 70 | margin-bottom: vr(3/4); 71 | } 72 | 73 | .woocommerce-grouped-product-list-item { 74 | margin-bottom: vr(1/4); 75 | } 76 | 77 | // Set related/upsells back to block as they include the .products 78 | // class on the container for some reason. 79 | .related, 80 | .upsells { 81 | display: block; 82 | } 83 | } 84 | 85 | @import "components/gallery"; 86 | @import "components/tabs"; 87 | -------------------------------------------------------------------------------- /resources/scss/woocommerce.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * This is the WooCommerce stylesheet. 3 | */ 4 | 5 | // Settings. 6 | // 7 | // Settings handle the configuration and don"t output CSS. This is a good 8 | // place to define things like variables. 9 | 10 | @import "settings/global"; 11 | @import "settings/colors"; 12 | 13 | 14 | // Tools. 15 | // 16 | // These are used throughout the code but don"t output CSS on their own. 17 | // Things like mixins and extensions go here. 18 | 19 | @import "tools/units"; 20 | @import "tools/clearfix"; 21 | @import "tools/hidden"; 22 | @import "tools/button"; 23 | @import "tools/font-size"; 24 | @import "tools/vr"; 25 | @import "tools/responsive-embed"; 26 | @import "tools/wrapper"; 27 | @import "~nth-grid/sass/nth-grid"; 28 | @import "~sass-mq/mq"; 29 | 30 | // Utilities. 31 | // 32 | // Utilities are helper classes and overrides. This gets loaded last. 33 | // If necessary, this is the only place where `!important` rules should 34 | // go, but only if necessary. 35 | 36 | // @import "vendor/woocommerce/global"; 37 | // @import "vendor/woocommerce/product-archive"; 38 | // @import "vendor/woocommerce/product-single"; 39 | // @import "vendor/woocommerce/product-gallery-slider"; 40 | // @import "vendor/woocommerce/my-account"; 41 | // @import "vendor/woocommerce/cart"; 42 | // @import "vendor/woocommerce/checkout"; 43 | // @import "vendor/woocommerce/order-confirmation"; 44 | 45 | .woocommerce, 46 | .woocommerce-page { 47 | 48 | .woocommerce-checkout-review-order-table { 49 | 50 | .product-name { 51 | text-align: left; 52 | } 53 | } 54 | } 55 | 56 | @import "vendor/woocommerce/general"; 57 | @import "vendor/woocommerce/archive-product"; 58 | @import "vendor/woocommerce/single-product"; 59 | @import "vendor/woocommerce/cart"; 60 | @import "vendor/woocommerce/checkout"; 61 | @import "vendor/woocommerce/my-account"; 62 | -------------------------------------------------------------------------------- /app/Providers/WooCommerceServiceProvider.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright Copyright (c) 2018, Brett Mason 12 | * @link https://github.com/brettsmason/luxe 13 | * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 14 | */ 15 | 16 | namespace Luxe\Providers; 17 | 18 | use Hybrid\Tools\ServiceProvider; 19 | use Luxe\WooCommerce\Setup; 20 | use Luxe\WooCommerce\ArchiveProduct; 21 | 22 | /** 23 | * App service provider. 24 | * 25 | * @since 1.0.0 26 | * @access public 27 | */ 28 | class WooCommerceServiceProvider extends ServiceProvider { 29 | 30 | /** 31 | * Callback executed when the `\Hybrid\Core\Application` class registers 32 | * providers. Use this method to bind items to the container. 33 | * 34 | * @since 1.0.0 35 | * @access public 36 | * @return void 37 | */ 38 | public function register() { 39 | 40 | // Bind a single instance of our WooCommerce classes. 41 | $this->app->singleton( Setup\Setup::class ); 42 | $this->app->singleton( ArchiveProduct\ArchiveProduct::class ); 43 | } 44 | 45 | /** 46 | * Callback executed after all the service providers have been registered. 47 | * This is particularly useful for single-instance container objects that 48 | * only need to be loaded once per page and need to be resolved early. 49 | * 50 | * @since 1.0.0 51 | * @access public 52 | * @return void 53 | */ 54 | public function boot() { 55 | 56 | // Boot the WooCommerce class instances. 57 | $this->app->resolve( Setup\Setup::class )->boot(); 58 | $this->app->resolve( ArchiveProduct\ArchiveProduct::class )->boot(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /config/webpack.settings.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 3 | /** 4 | * Collection of application front-end assets to be compiled. 5 | */ 6 | entries: { 7 | app: './resources/js/app.js', 8 | customizer: './resources/js/customizer.js', 9 | screen: './resources/scss/screen.scss', 10 | editor: './resources/scss/editor.scss', 11 | woocommerce: './resources/scss/woocommerce.scss', 12 | }, 13 | 14 | /** 15 | * BrowserSync settings. 16 | */ 17 | browserSync: { 18 | host: 'localhost', 19 | port: 3000, 20 | proxy: 'http://theme.test', 21 | open: false, 22 | files: [ 23 | '*.php', 24 | 'app/**/*.php', 25 | 'resources/views/**/*.php', 26 | 'public/js/**/*.js', 27 | 'public/css/**/*.css', 28 | 'public/svg/**/*.svg', 29 | 'public/img/**/*.{jpg,jpeg,png,gif}', 30 | 'public/fonts/**/*.{eot,ttf,woff,woff2,svg}', 31 | ], 32 | }, 33 | 34 | /** 35 | * List of libraries which will be provided 36 | * within application scripts as external. 37 | */ 38 | externals: { 39 | jquery: 'jQuery', 40 | }, 41 | 42 | /** 43 | * List of custom modules resolving. 44 | */ 45 | resolve: { 46 | alias: {}, 47 | }, 48 | 49 | /** 50 | * Project paths. 51 | */ 52 | paths: { 53 | public: './public', 54 | assets: './resources', 55 | sass: './resources/scss', 56 | javascript: './resources/js', 57 | }, 58 | 59 | /** 60 | * List of filename schemas for different 61 | * application assets. 62 | */ 63 | outputs: { 64 | css: 'css/[name].css', 65 | javascript: 'js/[name].js', 66 | assets: '[path][name].[ext]', 67 | }, 68 | 69 | stats: { 70 | // Copied from `'minimal'`. 71 | all: false, 72 | errors: true, 73 | maxModules: 0, 74 | modules: true, 75 | warnings: true, 76 | // Our additional options. 77 | assets: true, 78 | errorDetails: true, 79 | excludeAssets: /\.(jpe?g|png|gif|svg|woff|woff2)$/i, 80 | moduleTrace: true, 81 | performance: true, 82 | }, 83 | 84 | }; 85 | -------------------------------------------------------------------------------- /resources/scss/vendor/woocommerce/_cart.scss: -------------------------------------------------------------------------------- 1 | .woocommerce-cart { 2 | 3 | .woocommerce-cart-form__contents { 4 | 5 | .product-thumbnail { 6 | 7 | @include mq($until: medium) { 8 | display: none; 9 | } 10 | } 11 | 12 | .product-remove { 13 | 14 | @include mq(medium) { 15 | text-align: left; 16 | width: 50px; 17 | } 18 | } 19 | 20 | .product-name { 21 | 22 | @include mq(medium) { 23 | width: 40%; 24 | text-align: left; 25 | } 26 | } 27 | 28 | .product-quantity { 29 | overflow: hidden; 30 | 31 | @include mq(medium) { 32 | width: 120px; 33 | } 34 | 35 | .quantity { 36 | float: right; 37 | 38 | @include mq(medium) { 39 | float: none; 40 | } 41 | } 42 | } 43 | 44 | .actions { 45 | text-align: left; 46 | 47 | @include mq(medium) { 48 | overflow: hidden; 49 | } 50 | } 51 | 52 | .button { 53 | @include button-style($color-secondary); 54 | display: block; 55 | width: 100%; 56 | } 57 | 58 | .coupon { 59 | display: flex; 60 | flex-direction: column; 61 | margin-bottom: vr(1/2); 62 | 63 | @include mq(medium) { 64 | display: inline-flex; 65 | flex-direction: row; 66 | margin-bottom: 0; 67 | } 68 | 69 | label { 70 | display: none; 71 | } 72 | 73 | [name="coupon_code"] { 74 | margin-bottom: vr(1/2); 75 | width: 100%; 76 | 77 | @include mq(medium) { 78 | margin-bottom: 0; 79 | width: 200px; 80 | } 81 | } 82 | 83 | [name="apply_coupon"] { 84 | width: 100%; 85 | 86 | @include mq(medium) { 87 | display: inline-block; 88 | width: auto; 89 | } 90 | } 91 | } 92 | 93 | [name="update_cart"] { 94 | width: 100%; 95 | 96 | @include mq(medium) { 97 | display: inline-block; 98 | float: right; 99 | width: auto; 100 | } 101 | 102 | &[disabled] { 103 | opacity: 0.5; 104 | cursor: not-allowed; 105 | } 106 | } 107 | } 108 | 109 | // the toggleable shipping calculator 110 | .shipping-calculator-form { 111 | margin-top: vr(1); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /resources/scss/components/_entry.scss: -------------------------------------------------------------------------------- 1 | .entry { 2 | margin-bottom: vr(2); 3 | 4 | .single & { 5 | margin-bottom: 0; 6 | } 7 | 8 | // Featured image. 9 | &__image { 10 | margin-bottom: vr(1/2); 11 | } 12 | 13 | // Header wrapper. 14 | &__header {} 15 | 16 | // Entry title. 17 | &__title {} 18 | 19 | &__permalink { 20 | text-decoration: none; 21 | } 22 | 23 | // Meta wrappers. 24 | &__byline { 25 | @include font-size(16px); 26 | color: $color-grey-700; 27 | margin-bottom: vr(1); 28 | } 29 | 30 | &__published {} 31 | 32 | &__author { 33 | color: inherit; 34 | } 35 | 36 | &__comments { 37 | color: inherit; 38 | } 39 | 40 | // Full entry content. 41 | &__content { 42 | @include clearfix; 43 | margin-bottom: vr(2); 44 | 45 | .single &, 46 | > :last-child { 47 | margin-bottom: 0; 48 | } 49 | 50 | // Add some spacing for anything after entry__content. 51 | & + * { 52 | margin-top: vr(2); 53 | } 54 | 55 | > * { 56 | @include wrapper($global-width); 57 | } 58 | 59 | // Make links have an underline 60 | // when no class is present. 61 | a:not([class]) { 62 | text-decoration: underline; 63 | } 64 | 65 | > ol:not([class]), 66 | > ul:not([class]) { 67 | padding-left: vr(1.5); 68 | } 69 | } 70 | 71 | // Summary/Excerpt. 72 | &__summary { 73 | 74 | > ol:not([class]), 75 | > ul:not([class]) { 76 | padding-left: vr(1.5); 77 | } 78 | } 79 | 80 | &__footer {} 81 | 82 | &__terms-wrapper { 83 | color: $color-grey-700; 84 | display: block; 85 | 86 | & + & { 87 | margin-top: vr(1/4); 88 | } 89 | } 90 | 91 | &__terms { 92 | margin-left: vr(1/4); 93 | 94 | a { 95 | color: inherit; 96 | text-decoration: none; 97 | 98 | &:hover, 99 | &:focus, 100 | &:active { 101 | text-decoration: underline; 102 | } 103 | } 104 | } 105 | 106 | &__terms-icon { 107 | fill: currentColor; 108 | height: 16px; 109 | width: 16px; 110 | } 111 | 112 | // Sticky posts. 113 | &.sticky {} 114 | 115 | // Type of entry/post. 116 | &--type-post {} 117 | 118 | &--type-page {} 119 | } 120 | -------------------------------------------------------------------------------- /resources/scss/vendor/woocommerce/components/_gallery.scss: -------------------------------------------------------------------------------- 1 | // Product gallery. 2 | .woocommerce-product-gallery { 3 | width: 100%; 4 | margin-bottom: vr(2); 5 | position: relative; 6 | 7 | @include mq(medium) { 8 | float: left; 9 | margin-right: vr(2); 10 | width: calc(50% - #{vr(1)}); 11 | } 12 | 13 | img { 14 | display: block; 15 | width: 100%; 16 | height: auto; 17 | box-shadow: none; 18 | } 19 | 20 | &__wrapper { 21 | transition: all cubic-bezier(0.795, -0.035, 0, 1) 0.5s; 22 | margin: 0; 23 | padding: 0; 24 | max-width: none; // Important to make sure other images show. 25 | } 26 | 27 | .zoomImg { 28 | background-color: $color-white; 29 | opacity: 0; 30 | } 31 | 32 | // The zoom trigger. 33 | &__trigger { 34 | display: block; 35 | height: 20px; 36 | position: absolute; 37 | right: vr(1/4); 38 | text-align: center; 39 | top: vr(1/4); 40 | width: 20px; 41 | z-index: 1; 42 | line-height: 1; 43 | } 44 | 45 | // Default gallery without specific version enabled 46 | .woocommerce-product-gallery__image:nth-child(n + 2) { 47 | margin-right: vr(1/2); 48 | margin-top: vr(1/2); 49 | } 50 | 51 | // If its a flexslider gallery, remove margins. 52 | .flex-viewport .woocommerce-product-gallery__image { 53 | margin: 0; 54 | } 55 | 56 | @for $i from 2 through 6 { 57 | 58 | &--columns-#{$i} { 59 | 60 | .woocommerce-product-gallery__image:nth-child(n + 2) { 61 | width: calc(#{percentage(1 / $i)} - (#{vr(1/2)} / #{$i} * (#{$i} - 1))); 62 | float: left; 63 | } 64 | 65 | .woocommerce-product-gallery__image:nth-child(#{$i}n + 1) { 66 | margin-right: 0; 67 | } 68 | } 69 | } 70 | 71 | 72 | // Thumbnails if its a flexslider gallery. 73 | .flex-control-thumbs { 74 | display: flex; 75 | margin: 0; 76 | margin-top: vr(1/2); 77 | 78 | li { 79 | flex: 1; 80 | list-style: none; 81 | margin-right: vr(1/2); 82 | max-width: 100px; 83 | 84 | &:last-child { 85 | margin-right: 0; 86 | } 87 | 88 | img { 89 | cursor: pointer; 90 | opacity: 0.5; 91 | } 92 | 93 | img:hover, 94 | img:focus, 95 | .flex-active { 96 | opacity: 1; 97 | } 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /config/webpack.prod.js: -------------------------------------------------------------------------------- 1 | const merge = require( 'webpack-merge' ); 2 | const common = require( './webpack.common.js' ); 3 | const ImageminPlugin = require( 'imagemin-webpack-plugin' ).default; 4 | const imageminMozjpeg = require( 'imagemin-mozjpeg' ); 5 | const TerserPlugin = require( 'terser-webpack-plugin' ); 6 | 7 | module.exports = merge( common, { 8 | mode: 'production', 9 | plugins: [ 10 | 11 | // Minify and optimize image/SVG files. 12 | new ImageminPlugin( { 13 | test: /\.(jpe?g|png|gif|svg)$/i, 14 | optipng: { 15 | optimizationLevel: 7, 16 | }, 17 | gifsicle: { 18 | optimizationLevel: 3, 19 | }, 20 | pngquant: { 21 | quality: '65-90', 22 | speed: 4, 23 | }, 24 | svgo: { 25 | plugins: [ 26 | { cleanupIDs: false }, 27 | { mergePaths: false }, 28 | { removeUnknownsAndDefaults: false }, 29 | { removeViewBox: false }, 30 | ], 31 | }, 32 | plugins: [ imageminMozjpeg( { quality: 75 } ) ], 33 | } ), 34 | ], 35 | 36 | optimization: { 37 | minimizer: [ 38 | new TerserPlugin( { 39 | cache: true, 40 | parallel: true, 41 | sourceMap: false, 42 | terserOptions: { 43 | parse: { 44 | // We want terser to parse ecma 8 code. However, we don't want it 45 | // to apply any minfication steps that turns valid ecma 5 code 46 | // into invalid ecma 5 code. This is why the 'compress' and 'output' 47 | // sections only apply transformations that are ecma 5 safe 48 | // https://github.com/facebook/create-react-app/pull/4234 49 | ecma: 8, 50 | }, 51 | compress: { 52 | ecma: 5, 53 | warnings: false, 54 | // Disabled because of an issue with Uglify breaking seemingly valid code: 55 | // https://github.com/facebook/create-react-app/issues/2376 56 | // Pending further investigation: 57 | // https://github.com/mishoo/UglifyJS2/issues/2011 58 | comparisons: false, 59 | // Disabled because of an issue with Terser breaking valid code: 60 | // https://github.com/facebook/create-react-app/issues/5250 61 | // Pending futher investigation: 62 | // https://github.com/terser-js/terser/issues/120 63 | inline: 2, 64 | }, 65 | output: { 66 | ecma: 5, 67 | comments: false, 68 | }, 69 | ie8: false, 70 | }, 71 | } ), 72 | ], 73 | }, 74 | } ); 75 | -------------------------------------------------------------------------------- /resources/scss/elements/_forms.scss: -------------------------------------------------------------------------------- 1 | // 1. Reset Chrome and Firefox behaviour which sets a `min-width: min-content;` 2 | // on fieldsets. 3 | fieldset { 4 | border: 0; 5 | font-family: inherit; 6 | margin-bottom: vr(1); 7 | min-width: 0; /* [1] */ 8 | } 9 | 10 | legend { 11 | font-weight: $font-weight-form-legend; 12 | margin-bottom: vr(1/2); 13 | } 14 | 15 | [type="text"], 16 | [type="email"], 17 | [type="url"], 18 | [type="password"], 19 | [type="search"], 20 | [type="number"], 21 | [type="tel"], 22 | [type="range"], 23 | [type="date"], 24 | [type="month"], 25 | [type="week"], 26 | [type="time"], 27 | [type="datetime"], 28 | [type="datetime-local"], 29 | [type="color"], 30 | textarea, 31 | select { 32 | background-color: $color-form-input-background; 33 | border: 1px solid $color-form-input-border; 34 | border-radius: $global-radius; 35 | color: $color-form-input; 36 | display: block; 37 | font-family: inherit; 38 | height: vr(1.75); 39 | outline: none; 40 | padding: vr(1/4) vr(1/2); 41 | width: 100%; 42 | } 43 | 44 | select[multiple] { 45 | height: auto; 46 | padding: vr(1/4) vr(1/2); 47 | } 48 | 49 | textarea { 50 | height: auto; 51 | padding: vr(1/2); 52 | vertical-align: top; 53 | } 54 | 55 | [type="file"] { 56 | background: none; 57 | border: none; 58 | box-shadow: none; 59 | display: inline-block; 60 | height: auto; 61 | padding: 0; 62 | width: auto; 63 | } 64 | 65 | [type="radio"], 66 | [type="checkbox"] { 67 | display: inline-block; 68 | height: auto; 69 | padding: 0; 70 | width: auto; 71 | 72 | & + & { 73 | margin-left: vr(1/2); 74 | } 75 | 76 | + label { 77 | display: inline-block; 78 | margin-left: vr(1/4); 79 | } 80 | } 81 | 82 | input, 83 | textarea, 84 | select { 85 | 86 | &:focus { 87 | border-color: $color-form-input-border-focus; 88 | outline: none; 89 | } 90 | 91 | &:disabled { 92 | color: $color-grey-500; 93 | cursor: not-allowed; 94 | font-style: italic; 95 | opacity: 0.3; 96 | resize: none; 97 | } 98 | } 99 | 100 | label { 101 | color: $color-form-label; 102 | display: block; 103 | font-weight: $font-weight-form-label; 104 | margin-bottom: vr(1/4); 105 | } 106 | 107 | [type="button"], 108 | [type="reset"], 109 | [type="submit"] { 110 | @include button; 111 | @include button-style($color-button-background, $color-button); 112 | } 113 | -------------------------------------------------------------------------------- /resources/scss/vendor/woocommerce/_checkout.scss: -------------------------------------------------------------------------------- 1 | .woocommerce-checkout { 2 | 3 | /** 4 | * Notices and forms on the checkout 5 | */ 6 | .woocommerce-form-coupon-toggle, 7 | .woocommerce-form-login-toggle { 8 | 9 | @include mq(medium) { 10 | margin-left: auto; 11 | margin-right: auto; 12 | max-width: 50%; 13 | } 14 | 15 | .woocommerce-info { 16 | text-align: center; 17 | background-color: transparent; 18 | color: $color-text; 19 | padding: 0; 20 | 21 | a { 22 | color: $color-text; 23 | } 24 | } 25 | } 26 | 27 | 28 | .woocommerce-form-login { 29 | 30 | p:first-child { 31 | text-align: center; 32 | } 33 | } 34 | 35 | .checkout_coupon { 36 | text-align: center; 37 | display: flex; 38 | flex-direction: column; 39 | 40 | @include mq(medium) { 41 | margin-left: auto; 42 | margin-right: auto; 43 | max-width: 50%; 44 | flex-direction: row; 45 | flex-wrap: wrap; 46 | 47 | p { 48 | width: 100%; 49 | } 50 | } 51 | 52 | .form-row-first { 53 | margin-right: 0; 54 | margin-bottom: vr(1/2); 55 | } 56 | 57 | [name="apply_coupon"] { 58 | width: 100%; 59 | } 60 | } 61 | 62 | // login form 63 | .woocommerce-form-login { 64 | 65 | @include mq(medium) { 66 | margin-left: auto; 67 | margin-right: auto; 68 | max-width: 50%; 69 | } 70 | 71 | p:first-child { 72 | text-align: center; 73 | } 74 | } 75 | 76 | // login form submit button 77 | .woocommerce-form-login__submit { 78 | width: 100%; 79 | } 80 | 81 | // Space between the form and any notices/coupon/login 82 | .woocommerce-checkout { 83 | margin-top: vr(2); 84 | } 85 | 86 | // The ship to a different address label 87 | .woocommerce-shipping-fields .woocommerce-form__label { 88 | font-size: $global-font-size; 89 | } 90 | 91 | // Order review table. 92 | .woocommerce-checkout-review-order-table { 93 | 94 | .product-name { 95 | text-align: left; 96 | } 97 | } 98 | 99 | // Payment methods 100 | .wc_payment_methods { 101 | list-style: none; 102 | margin-left: 0; 103 | } 104 | 105 | // Individual payment method 106 | .wc_payment_method { 107 | padding-top: vr(1/4); 108 | padding-bottom: vr(1/4); 109 | } 110 | 111 | // The box describing the payment method 112 | .payment_box { 113 | border: 1px solid $color-border; 114 | padding: vr(1/2); 115 | position: relative; 116 | 117 | :last-child { 118 | margin-bottom: 0; 119 | } 120 | } 121 | 122 | [name="woocommerce_checkout_place_order"] { 123 | @include button-style($color-primary); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "luxe", 3 | "version": "1.0.0", 4 | "description": "Luxe is a WordPress starter theme using a modern workflow and best practices.", 5 | "main": "resources/js/app.js", 6 | "scripts": { 7 | "dev": "cross-env NODE_ENV=development webpack --config ./config/webpack.dev.js", 8 | "watch": "cross-env NODE_ENV=development webpack --watch --config ./config/webpack.dev.js", 9 | "production": "cross-env NODE_ENV=production webpack --config ./config/webpack.prod.js", 10 | "build": "npm run production && npm run i18n", 11 | "lint": "npm run lint:styles && npm run lint:scripts && npm run lint:php", 12 | "lint:styles": "cross-env stylelint './resources/scss/**/*.scss' --syntax scss", 13 | "lint:scripts": "cross-env eslint './resources/js/**/*.js'", 14 | "lint:php": "cross-env ./vendor/bin/phpcs .", 15 | "i18n": "npm run i18n:textdomain && npm run i18n:pot", 16 | "i18n:textdomain": "npx node-wp-i18n addtextdomain --exclude=vendor,node_modules", 17 | "i18n:pot": "npx node-wp-i18n makepot", 18 | "rename": "theme-claim --config='./config/rename.json'" 19 | }, 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/brettsmason/luxe.git" 23 | }, 24 | "author": "Brett Mason", 25 | "license": "GPL-2.0+", 26 | "bugs": { 27 | "url": "https://github.com/brettsmason/luxe/issues" 28 | }, 29 | "homepage": "https://github.com/brettsmason/luxe#readme", 30 | "devDependencies": { 31 | "@babel/core": "^7.11.1", 32 | "@babel/preset-env": "^7.11.0", 33 | "@wordpress/eslint-plugin": "^3.3.0", 34 | "babel-loader": "^8.0.6", 35 | "browser-sync": "^2.26.13", 36 | "browser-sync-webpack-plugin": "^2.3.0", 37 | "clean-webpack-plugin": "^3.0.0", 38 | "copy-webpack-plugin": "^5.1.1", 39 | "cross-env": "^7.0.0", 40 | "css-loader": "^4.2.1", 41 | "cssnano": "^4.1.10", 42 | "eslint": "^6.8.0", 43 | "eslint-plugin-import": "^2.22.1", 44 | "fibers": "^5.0.0", 45 | "friendly-errors-webpack-plugin": "^1.7.0", 46 | "imagemin-mozjpeg": "^9.0.0", 47 | "imagemin-webpack-plugin": "^2.4.2", 48 | "mini-css-extract-plugin": "^0.9.0", 49 | "nth-grid": "github:brettsmason/nth-grid", 50 | "postcss-loader": "^3.0.0", 51 | "postcss-preset-env": "^6.7.0", 52 | "sass": "^1.32.5", 53 | "sass-loader": "^8.0.2", 54 | "sass-mq": "^5.0.1", 55 | "stylelint": "^12.0.1", 56 | "stylelint-config-wordpress": "^17.0.0", 57 | "stylelint-order": "^4.1.0", 58 | "stylelint-scss": "^3.14.2", 59 | "terser-webpack-plugin": "^4.2.3", 60 | "theme-claim": "^0.2.0", 61 | "webpack": "^4.44.2", 62 | "webpack-cli": "^3.3.12", 63 | "webpack-fix-style-only-entries": "^0.4.0", 64 | "webpack-manifest-plugin": "^2.2.0", 65 | "webpack-merge": "^4.2.2", 66 | "webpackbar": "^4.0.0" 67 | }, 68 | "dependencies": { 69 | "core-js": "^3.6.5" 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /resources/scss/settings/_colors.scss: -------------------------------------------------------------------------------- 1 | // Brand colors 2 | $color-primary: #482880; 3 | $color-secondary: #292f36; 4 | $color-tertiary: #6b5ca5; 5 | 6 | // State colors 7 | $color-alert: #8c182b; 8 | $color-warning: #f6bf27; 9 | $color-success: #407d80; 10 | 11 | 12 | // Greyscale 13 | $color-grey-900: #202833; 14 | $color-grey-800: #404b5a; 15 | $color-grey-700: #6e7a8a; 16 | $color-grey-600: #929fb1; 17 | $color-grey-500: #aebecd; 18 | $color-grey-400: #ccd4db; 19 | $color-grey-300: #d5dde5; 20 | $color-grey-200: #e1e7ec; 21 | $color-grey-100: #f8f9fa; 22 | 23 | // Black/white 24 | $color-black: $color-grey-900; 25 | $color-white: #fff; 26 | 27 | /// Component specific colors 28 | 29 | // Page. 30 | $color-background: $color-white; 31 | $color-text: $color-grey-900; 32 | 33 | // Borders. 34 | $color-border: $color-grey-300; 35 | 36 | // Headings. 37 | $color-heading: $color-black; 38 | 39 | // Links. 40 | $color-link: $color-primary; 41 | $color-link-hover: $color-black; 42 | 43 | // Buttons. 44 | $color-button: $color-white; 45 | $color-button-background: $color-primary; 46 | $color-button-hover: $color-white; 47 | $color-button-hover-background: lighten($color-primary, 10%); 48 | $color-button-outline: $color-primary; 49 | $color-button-outline-border: $color-primary; 50 | $color-button-outline-hover: $color-white; 51 | $color-button-outline-hover-background: $color-primary; 52 | 53 | // Forms 54 | $color-form-fieldset-border: $color-border; 55 | $color-form-input-background: $color-white; 56 | $color-form-input: $color-text; 57 | $color-form-input-border: $color-border; 58 | $color-form-input-border-focus: $color-primary; 59 | $color-form-input-required: $color-alert; 60 | $color-form-label: $color-text; 61 | 62 | // Blockquotes. 63 | $color-blockquote: $color-grey-900; 64 | $color-blockquote-border: $color-grey-300; 65 | 66 | // Cite. 67 | $color-cite: $color-primary; 68 | 69 | // Code. 70 | $color-code: $color-grey-900; 71 | $color-code-background: $color-grey-100; 72 | 73 | // HR. 74 | $color-hr: $color-grey-300; 75 | 76 | // Colors used for social networks 77 | $colors-social: ( 78 | facebook: #3b5998, 79 | instagram: #c13584, 80 | linkedin: #0077b5, 81 | pinterest: #bd081c, 82 | twitter: #1da1f2, 83 | vimeo: #1ab7ea, 84 | youtube: #cd201f 85 | ); 86 | 87 | // Site Header. 88 | $color-header-title: $color-text; 89 | 90 | // Menu. 91 | $color-menu-items-background: $color-white; 92 | $color-menu-item-border: $color-border; 93 | $color-menu-link: $color-text; 94 | $color-menu-link-hover: $color-primary; 95 | $color-menu-dropdown-icon: $color-grey-900; 96 | $color-menu-sub-menu-background: $color-white; 97 | $color-menu-sub-menu-toggle: $color-grey-900; 98 | $color-menu-sub-menu-toggle-background: $color-grey-300; 99 | 100 | // Pagination. 101 | $color-pagination-anchor-border: $color-border; 102 | 103 | // Tables. 104 | $color-table-border: $color-border; 105 | $color-table-striped-background: $color-grey-300; 106 | -------------------------------------------------------------------------------- /bootstrap/compat.php: -------------------------------------------------------------------------------- 1 |

%s

', esc_html( luxe_compat_message() ) ); 76 | } 77 | 78 | /** 79 | * Kills the loading of the customizer. 80 | * 81 | * @since 1.0.0 82 | * @access public 83 | * @return void 84 | */ 85 | function luxe_load_customize() { 86 | wp_die( esc_html( luxe_compat_message() ), '', [ 'back_link' => true ] ); 87 | } 88 | 89 | /** 90 | * Kills the customizer previewer on installs prior to WP 4.7. 91 | * 92 | * @since 1.0.0 93 | * @access public 94 | * @return void 95 | */ 96 | function luxe_preview() { 97 | if ( isset( $_GET['preview'] ) ) { // WPCS: CSRF ok. 98 | wp_die( esc_html( luxe_compat_message() ) ); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /resources/scss/tools/_font-size.scss: -------------------------------------------------------------------------------- 1 | // Generates a rem font-size and a baseline-compatible 2 | // unitless line-height from a pixel font-size value. Basic usage is simply: 3 | // 4 | // @include font-size(18px); 5 | // 6 | // You can force a specific line-height by passing it as the second argument: 7 | // 8 | // @include font-size(16px, 1); 9 | // 10 | // You can also modify the line-height by increments, while staying in the 11 | // baseline grid, by setting the `$modifier` parameter. It takes a positive 12 | // or negative integer, and it will add or remove "lines" to the generated 13 | // line-height. This is the recomended way to do it, unless you really need 14 | // an absolute value. i.e.: 15 | // 16 | // // add 2 lines: 17 | // @include font-size(24px, $modifier: +2); 18 | // 19 | // // subtract 1 line: 20 | // @include font-size(24px, $modifier: -1); 21 | 22 | @mixin font-size( 23 | $font-size, 24 | $line-height: auto, 25 | $modifier: 0, 26 | $important: false 27 | ) { 28 | @if (type-of($font-size) == map) { 29 | @each $breakpoint, $size in $font-size { 30 | 31 | $_font-size: if(type-of($size) == list, nth($size, 1), $size); 32 | $_line-height: if(type-of($size) == list and length($size) >= 2, nth($size, 2), auto); 33 | $_modifier: if(type-of($size) == list and length($size) == 3, nth($size, 3), 0); 34 | 35 | @if ($breakpoint == null) { 36 | @include _get-font-size($_font-size, $_line-height, $_modifier); 37 | } @else { 38 | @include mq($breakpoint) { 39 | @include _get-font-size($_font-size, $_line-height, $_modifier); 40 | } 41 | } 42 | } 43 | 44 | } @else { 45 | @include _get-font-size($font-size, $line-height, $modifier, $important); 46 | } 47 | } 48 | 49 | // The internal logic for the font-size() mixin. 50 | @mixin _get-font-size( 51 | $font-size, 52 | $line-height: auto, 53 | $modifier: 0, 54 | $important: false 55 | ) { 56 | @if (type-of($font-size) == number) { 57 | @if (unit($font-size) != "px") { 58 | @error "`#{$font-size}` needs to be a pixel value."; 59 | } 60 | } @else { 61 | @error "`#{$font-size}` needs to be a number."; 62 | } 63 | 64 | @if ($important == true) { 65 | $important: !important; 66 | } @else if ($important == false) { 67 | $important: null; 68 | } @else { 69 | @error "`#{$important}` needs to be `true` or `false`."; 70 | } 71 | 72 | // Output the font size. 73 | font-size: $font-size $important; 74 | 75 | @if ($line-height == "auto") { 76 | 77 | // Define how many grid lines each text line should span. 78 | // By default, we set it to the minimum number of lines necessary 79 | // in order to contain the defined font-size, +1 for some breathing room. 80 | // This can be modified with the `$modifier` parameter. 81 | $lines: ceil($font-size / $global-baseline) + $modifier + 1; 82 | $line-height: $lines * $global-baseline; 83 | 84 | line-height: ($line-height / $font-size) $important; 85 | 86 | } @else { 87 | 88 | @if (type-of($line-height) == number or $line-height == "inherit" or $line-height == "normal") { 89 | line-height: $line-height $important; 90 | } @else if ($line-height != "none" and $line-height != false) { 91 | @error "D’oh! `#{$line-height}` is not a valid value for `$line-height`."; 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /resources/scss/editor.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Blocks stylesheet for the theme. 3 | * 4 | * This is for the editor in WordPress 5.0 and beyond. 5 | */ 6 | 7 | // Settings. 8 | // 9 | // Settings handle the configuration and don't output CSS. This is a good 10 | // place to define things like variables. 11 | 12 | @import "settings/global"; 13 | @import "settings/colors"; 14 | 15 | 16 | // Tools. 17 | // 18 | // These are used throughout the code but don't output CSS on their own. 19 | // Things like mixins and extensions go here. 20 | 21 | @import "~nth-grid/sass/nth-grid"; 22 | @import "~sass-mq/mq"; 23 | @import "tools/units"; 24 | @import "tools/clearfix"; 25 | @import "tools/hidden"; 26 | @import "tools/button"; 27 | @import "tools/font-size"; 28 | @import "tools/vr"; 29 | @import "tools/responsive-embed"; 30 | @import "tools/wrapper"; 31 | 32 | 33 | // Elements. 34 | // 35 | // Elements are (or should be) class-less designs for the base 36 | // HTML elements. 37 | 38 | @import "elements/headings"; 39 | @import "elements/links"; 40 | @import "elements/blockquote"; 41 | @import "elements/lists"; 42 | @import "elements/hr"; 43 | @import "elements/tables"; 44 | @import "elements/media"; 45 | @import "elements/code"; 46 | @import "elements/misc"; 47 | 48 | 49 | // Blocks. 50 | // 51 | // Blocks are styles for specific editor blocks. 52 | // 53 | 54 | @import "blocks/wp-block-audio"; 55 | @import "blocks/wp-block-button"; 56 | @import "blocks/wp-block-categories"; 57 | @import "blocks/wp-block-code"; 58 | @import "blocks/wp-block-columns"; 59 | @import "blocks/wp-block-cover"; 60 | @import "blocks/wp-block-embed"; 61 | @import "blocks/wp-block-file"; 62 | @import "blocks/wp-block-gallery"; 63 | @import "blocks/wp-block-image"; 64 | @import "blocks/wp-block-latest-posts"; 65 | @import "blocks/wp-block-media-text"; 66 | @import "blocks/wp-block-preformatted"; 67 | @import "blocks/wp-block-pullquote"; 68 | @import "blocks/wp-block-quote"; 69 | @import "blocks/wp-block-separator"; 70 | @import "blocks/wp-block-table"; 71 | @import "blocks/wp-block-verse"; 72 | 73 | 74 | // Utilities. 75 | // 76 | // Utilities are helper classes and overrides. This gets loaded last. 77 | // If necessary, this is the only place where `!important` rules should 78 | // go, but only if necessary. 79 | 80 | @import "utilities/alignment"; 81 | @import "utilities/clearfix"; 82 | @import "utilities/color-palette"; 83 | @import "utilities/headings"; 84 | @import "utilities/hide"; 85 | 86 | 87 | // Editor related styles which overwrite above styles. 88 | 89 | body { 90 | background-color: $color-background; 91 | color: $color-text; 92 | font-family: $font-family-body; 93 | font-size: $global-font-size; 94 | line-height: $global-line-height; 95 | } 96 | 97 | p { 98 | font-size: $global-font-size; 99 | } 100 | 101 | .editor-post-title__block .editor-post-title__input { 102 | @include font-size($h1); 103 | color: $color-heading; 104 | font-family: $font-family-heading; 105 | font-weight: $font-weight-heading; 106 | } 107 | 108 | // Sets the default width of the content and the title. 109 | .wp-block { 110 | max-width: $global-width; 111 | 112 | // Wide aligned blocks. 113 | &[data-align="wide"] { 114 | max-width: $global-width-wide; 115 | } 116 | 117 | // Full width aligned blocks. 118 | &[data-align="full"] { 119 | max-width: none; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /app/WooCommerce/Setup/Setup.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright Copyright (c) 2018, Brett Mason 8 | * @link https://github.com/brettsmason/luxe 9 | * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 10 | */ 11 | 12 | namespace Luxe\WooCommerce\Setup; 13 | 14 | use Hybrid\Contracts\Bootable; 15 | use function Hybrid\Template\path; 16 | use function Luxe\asset; 17 | 18 | /** 19 | * Handles setting up everything we need for WooCommerce. 20 | * 21 | * @since 1.0.0 22 | * @access public 23 | */ 24 | class Setup implements Bootable { 25 | 26 | /** 27 | * Adds actions on the appropriate action hooks. 28 | * 29 | * @since 1.0.0 30 | * @access public 31 | * @return void 32 | */ 33 | public function boot() { 34 | 35 | // Register theme support for WooCommerce features. 36 | add_action( 'after_setup_theme', [ $this, 'register' ] ); 37 | 38 | // Set path to WooCommerce templates. 39 | add_filter( 'woocommerce_template_loader_files', [ $this, 'templateLoaderFiles' ], PHP_INT_MAX ); 40 | 41 | // Moves the WooCommerce template path. 42 | add_filter( 'woocommerce_template_path', [ $this, 'templatePath' ] ); 43 | 44 | // Disable WooCommerce core styles. 45 | add_filter( 'woocommerce_enqueue_styles', [ $this, 'disableCoreStyles' ] ); 46 | 47 | // Add custom WooCommerce styles. 48 | add_action( 'wp_enqueue_scripts', [ $this, 'styles' ], 10 ); 49 | } 50 | 51 | /** 52 | * Add theme support for WooCommerce features. 53 | * 54 | * @link https://docs.woocommerce.com/document/woocommerce-theme-developer-handbook/ 55 | * @since 1.0.0 56 | * @access public 57 | * @return void 58 | */ 59 | public function register() { 60 | 61 | add_theme_support( 'woocommerce', [ 62 | 'thumbnail_image_width' => 300, 63 | 'single_image_width' => 600, 64 | 65 | 'product_grid' => [ 66 | 'default_rows' => 4, 67 | 'min_rows' => 2, 68 | 'max_rows' => 8, 69 | 'default_columns' => 4, 70 | 'min_columns' => 2, 71 | 'max_columns' => 6, 72 | ], 73 | ] ); 74 | 75 | add_theme_support( 'wc-product-gallery-zoom' ); 76 | add_theme_support( 'wc-product-gallery-lightbox' ); 77 | add_theme_support( 'wc-product-gallery-slider' ); 78 | } 79 | 80 | /** 81 | * This overrides the top-level WooCommerce templates that would normally go in 82 | * the theme root. By default, we're looking for a `resources/views/woocommerce.php` 83 | * template, which falls back to `resources/views/index.php`. 84 | * 85 | * @since 1.0.0 86 | * @access public 87 | * @param array $files 88 | * @return array 89 | */ 90 | public function templateLoaderFiles( $files ) { 91 | 92 | return [ 93 | path( 'woocommerce.php' ), 94 | path( 'index.php' ), 95 | ]; 96 | } 97 | 98 | /** 99 | * Filters the path to the `woocommerce` template parts folder. This filter 100 | * moves that folder to `resources/views/woocommerce`. 101 | * 102 | * @since 1.0.0 103 | * @access public 104 | * @param string $path 105 | * @return string 106 | */ 107 | public function templatePath( $path ) { 108 | 109 | return path( $path ); 110 | } 111 | 112 | /** 113 | * Disable core WooCommerce stylesheets. 114 | */ 115 | public function disableCoreStyles() { 116 | return []; 117 | } 118 | 119 | /** 120 | * Enqueue WooCommerce custom styles. 121 | * 122 | * @since 1.0.0 123 | * @access public 124 | * @return void 125 | */ 126 | public function styles() { 127 | 128 | wp_enqueue_style( 129 | 'luxe-woocommerce', 130 | asset( 'css/woocommerce.css' ), 131 | false, 132 | null 133 | ); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /config/webpack.common.js: -------------------------------------------------------------------------------- 1 | const path = require( 'path' ); 2 | const { CleanWebpackPlugin } = require( 'clean-webpack-plugin' ); 3 | const CopyWebpackPlugin = require( 'copy-webpack-plugin' ); 4 | const FixStyleOnlyEntriesPlugin = require( 'webpack-fix-style-only-entries' ); 5 | const FriendlyErrorsWebpackPlugin = require( 'friendly-errors-webpack-plugin' ); 6 | const ManifestPlugin = require( 'webpack-manifest-plugin' ); 7 | const MiniCssExtractPlugin = require( 'mini-css-extract-plugin' ); 8 | const WebpackBar = require( 'webpackbar' ); 9 | 10 | const isProduction = process.env.NODE_ENV === 'production'; 11 | 12 | // Build settings. 13 | const settings = require( './webpack.settings.js' ); 14 | 15 | module.exports = { 16 | entry: settings.entries, 17 | 18 | output: { 19 | path: path.resolve( process.cwd(), settings.paths.public ), 20 | filename: settings.outputs.javascript, 21 | }, 22 | 23 | // Console stats output. 24 | stats: settings.stats, 25 | 26 | // External objects. 27 | externals: settings.externals, 28 | 29 | // custom modules resolving. 30 | resolve: settings.resolve, 31 | 32 | // Performance settings. 33 | performance: { 34 | hints: false, 35 | maxAssetSize: 100000, 36 | }, 37 | 38 | // Build rules to handle asset files. 39 | module: { 40 | rules: [ 41 | 42 | // Scripts. 43 | { 44 | test: /\.js$/, 45 | exclude: /node_modules/, 46 | use: [ 47 | { 48 | loader: 'babel-loader', 49 | options: { 50 | cacheDirectory: true, 51 | sourceMap: ! isProduction, 52 | }, 53 | }, 54 | ], 55 | }, 56 | 57 | // Styles. 58 | { 59 | test: /\.s[ac]ss$/, 60 | include: path.resolve( process.cwd(), settings.paths.sass ), 61 | use: [ 62 | MiniCssExtractPlugin.loader, 63 | { 64 | loader: 'css-loader', 65 | options: { 66 | sourceMap: ! isProduction, 67 | url: false, 68 | }, 69 | }, 70 | { 71 | loader: 'postcss-loader', 72 | options: { 73 | sourceMap: ! isProduction, 74 | }, 75 | }, 76 | { 77 | loader: 'sass-loader', 78 | options: { 79 | implementation: require( 'sass' ), 80 | sourceMap: ! isProduction, 81 | sassOptions: { 82 | fiber: require( 'fibers' ), 83 | outputStyle: 'expanded', 84 | }, 85 | }, 86 | }, 87 | ], 88 | }, 89 | ], 90 | }, 91 | 92 | plugins: [ 93 | 94 | // Friendlier errors. 95 | new FriendlyErrorsWebpackPlugin(), 96 | 97 | // Remove the extra JS files Webpack creates for Sass entries. 98 | // This should be fixed in Webpack 5. 99 | new FixStyleOnlyEntriesPlugin( { 100 | silent: true, 101 | } ), 102 | 103 | // Clean the `public` folder on build. 104 | new CleanWebpackPlugin( { 105 | cleanStaleWebpackAssets: true, 106 | verbose: false, 107 | } ), 108 | 109 | // Create our cache busting asset manifest. 110 | new ManifestPlugin( { 111 | 112 | // Filter using only .js and .css files. 113 | filter: ( { name } ) => name.endsWith( '.js' ) || name.endsWith( '.css' ), 114 | map: ( file ) => { 115 | // Add hash details on production for cache busting. 116 | return { 117 | name: file.path, 118 | path: isProduction ? `${ file.path }?id=${ file.chunk.hash }` : file.path, 119 | }; 120 | }, 121 | } ), 122 | 123 | // Extract CSS into individual files. 124 | new MiniCssExtractPlugin( { 125 | filename: settings.outputs.css, 126 | chunkFilename: '[id].css', 127 | } ), 128 | 129 | // Copy static assets to the `public` folder. 130 | new CopyWebpackPlugin( 131 | [ { 132 | from: '**/*.{jpg,jpeg,png,gif,svg,eot,ttf,woff,woff2}', 133 | to: '[path][name].[ext]', 134 | context: path.resolve( process.cwd(), settings.paths.assets ), 135 | } ], 136 | { 137 | copyUnmodified: true, 138 | } 139 | ), 140 | 141 | // Fancy WebpackBar. 142 | new WebpackBar(), 143 | ], 144 | }; 145 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Travis CI (MIT License) configuration file for the WordPress theme. 2 | # @link https://travis-ci.org/ 3 | 4 | # For use with the WordPress theme. 5 | # @link https://github.com/samikeijonen/uuups 6 | 7 | # Ditch sudo and use containers. 8 | # @link https://docs.travis-ci.com/user/migrating-from-legacy/#Why-migrate-to-container-based-infrastructure%3F 9 | # @link https://docs.travis-ci.com/user/workers/container-based-infrastructure/#Routing-your-build-to-container-based-infrastructure 10 | sudo: false 11 | dist: trusty 12 | 13 | # Declare project language. 14 | # @link https://about.travis-ci.org/docs/user/languages/php/ 15 | language: php 16 | 17 | # Declare versions of PHP to use. Use one decimal max. 18 | # @link https://docs.travis-ci.com/user/build-configuration/ 19 | matrix: 20 | fast_finish: true 21 | 22 | include: 23 | # aliased to a recent 5.6.x version 24 | - php: '5.6' 25 | env: SNIFF=1 26 | # aliased to a recent 7.0.x version 27 | - php: '7.0' 28 | # aliased to a recent 7.2.x version 29 | - php: '7.2' 30 | # bleeding edge PHP 31 | - php: 'nightly' 32 | 33 | allow_failures: 34 | - php: 'nightly' 35 | 36 | # Use this to prepare the system to install prerequisites or dependencies. 37 | # e.g. sudo apt-get update. 38 | # Failures in this section will result in build status 'errored'. 39 | before_install: 40 | - npm install -g npm@latest 41 | 42 | # Use this to prepare your build for testing. 43 | # e.g. copy database configurations, environment variables, etc. 44 | # Failures in this section will result in build status 'errored'. 45 | before_script: 46 | # Speed up build time by disabling Xdebug. 47 | - phpenv config-rm xdebug.ini || echo 'No xdebug config.' 48 | # Set up temporary paths. 49 | - export PHPCS_DIR=/tmp/phpcs 50 | - export WPCS_DIR=/tmp/wpcs 51 | - export PHPCOMPAT_DIR=/tmp/phpcompatibility 52 | # Install CodeSniffer for WordPress Coding Standards checks. 53 | - if [[ "$SNIFF" == "1" ]]; then git clone -b master --depth 1 https://github.com/squizlabs/PHP_CodeSniffer.git $PHPCS_DIR; fi 54 | # Install WordPress Coding Standards. 55 | - if [[ "$SNIFF" == "1" ]]; then git clone -b master --depth 1 https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git $WPCS_DIR; fi 56 | # Install PHP Compatibility sniffs. 57 | - if [[ "$SNIFF" == "1" ]]; then git clone -b master --depth 1 https://github.com/wimg/PHPCompatibility.git $PHPCOMPAT_DIR; fi 58 | # Set install path for PHPCS sniffs. 59 | # @link https://github.com/squizlabs/PHP_CodeSniffer/blob/4237c2fc98cc838730b76ee9cee316f99286a2a7/CodeSniffer.php#L1941 60 | - if [[ "$SNIFF" == "1" ]]; then $PHPCS_DIR/bin/phpcs --config-set installed_paths $WPCS_DIR,$PHPCOMPAT_DIR; fi 61 | # After CodeSniffer install you should refresh your path. 62 | - if [[ "$SNIFF" == "1" ]]; then phpenv rehash; fi 63 | # Install eslint. 64 | # @link https://eslint.org/ 65 | - if [[ "$SNIFF" == "1" ]]; then npm install -g eslint eslint-config-wordpress; fi 66 | # Install stylelint. 67 | # @link https://stylelint.io/ 68 | - if [[ "$SNIFF" == "1" ]]; then npm install -g stylelint stylelint-config-wordpress; fi 69 | 70 | # Run test script commands. 71 | # Default is specific to project language. 72 | # All commands must exit with code 0 on success. Anything else is considered failure. 73 | script: 74 | # Search for PHP syntax errors. 75 | - find -L . -name '*.php' -print0 | xargs -0 -n 1 -P 4 php -l 76 | # Run the theme through ESLint. 77 | - if [[ "$SNIFF" == "1" ]]; then eslint './resources/js/**/*.js' --config ./.eslintrc.js .; fi 78 | # Run the theme through stylelint. 79 | - if [[ "$SNIFF" == "1" ]]; then stylelint './resources/scss/**/*.scss' --syntax scss --config node_modules/stylelint-config-wordpress/scss.js .; fi 80 | # WordPress Coding Standards. 81 | # @link https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards 82 | # @link https://pear.php.net/package/PHP_CodeSniffer/ 83 | # Uses a custom ruleset based on WordPress. This ruleset is automatically 84 | # picked up by PHPCS as it's named `phpcs.xml(.dist)`. 85 | - if [[ "$SNIFF" == "1" ]]; then $PHPCS_DIR/bin/phpcs --runtime-set ignore_warnings_on_exit 1; fi 86 | 87 | # Receive notifications for build results. 88 | # @link https://docs.travis-ci.com/user/notifications/#Email-notifications 89 | notifications: 90 | email: false 91 | -------------------------------------------------------------------------------- /phpcs.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A custom set of code standard rules to check for WordPress themes. 10 | 11 | 12 | 18 | 19 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | . 35 | 36 | */node_modules/* 37 | */vendor/* 38 | 39 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 55 | 56 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /resources/scss/screen.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * This is the primary stylesheet. We don"t actually write any styles here. 3 | * Instead, we import all of our styles from partials within the sub-folders. 4 | * This file is set up based on the Inverted Triangle CSS (ITCSS) system, 5 | * which gets more specific as we drill down each layer. This keeps your 6 | * style code lean and organized. 7 | * 8 | * The bulk of your code should be within the `/components` folder. By 9 | * default, we follow the Block-Element-Modifier (BEM) system in our HTML. 10 | * Each "block" is a "component" in our CSS. 11 | */ 12 | 13 | // Settings. 14 | // 15 | // Settings handle the configuration and don"t output CSS. This is a good 16 | // place to define things like variables. 17 | 18 | @import "settings/global"; 19 | @import "settings/colors"; 20 | 21 | 22 | // Tools. 23 | // 24 | // These are used throughout the code but don"t output CSS on their own. 25 | // Things like mixins and extensions go here. 26 | 27 | @import "~nth-grid/sass/nth-grid"; 28 | @import "~sass-mq/mq"; 29 | @import "tools/units"; 30 | @import "tools/clearfix"; 31 | @import "tools/hidden"; 32 | @import "tools/button"; 33 | @import "tools/font-size"; 34 | @import "tools/vr"; 35 | @import "tools/responsive-embed"; 36 | @import "tools/wrapper"; 37 | 38 | 39 | // Generic. 40 | // 41 | // This is the first point that real CSS is output. Resets, normalization, 42 | // fonts, etc. are best handled here. These are the base styles that other 43 | // styles will build upon. 44 | 45 | @import "generic/box-sizing"; 46 | @import "generic/normalize"; 47 | @import "generic/reset"; 48 | 49 | 50 | // Elements. 51 | // 52 | // Elements are (or should be) class-less designs for the base 53 | // HTML elements. 54 | 55 | @import "elements/page"; 56 | @import "elements/headings"; 57 | @import "elements/links"; 58 | @import "elements/blockquote"; 59 | @import "elements/lists"; 60 | @import "elements/hr"; 61 | @import "elements/tables"; 62 | @import "elements/media"; 63 | @import "elements/code"; 64 | @import "elements/forms"; 65 | @import "elements/misc"; 66 | 67 | 68 | // Objects. 69 | // 70 | // Components make up the bulk of the actual theme design. Nearly 71 | // every piece of the design is some type of component, whether it"s 72 | // a one-off or reusable block of code. 73 | 74 | @import "objects/animations"; 75 | @import "objects/layout"; 76 | @import "objects/media"; 77 | @import "objects/wrapper"; 78 | 79 | 80 | // Components. 81 | // 82 | // Components make up the bulk of the actual theme design. Nearly 83 | // every piece of the design is some type of component, whether it"s 84 | // a one-off or reusable block of code. 85 | 86 | @import "components/app"; 87 | @import "components/app-header"; 88 | @import "components/app-content"; 89 | @import "components/app-main"; 90 | @import "components/app-footer"; 91 | @import "components/archive-header"; 92 | @import "components/button"; 93 | @import "components/comments"; 94 | @import "components/comment"; 95 | @import "components/entry"; 96 | @import "components/form"; 97 | @import "components/gallery"; 98 | @import "components/menu"; 99 | @import "components/pagination"; 100 | @import "components/sidebar"; 101 | @import "components/svg"; 102 | @import "components/table"; 103 | @import "components/widget"; 104 | 105 | // Blocks. 106 | // 107 | // Blocks are styles for specific editor blocks. 108 | // 109 | 110 | @import "blocks/wp-block-audio"; 111 | @import "blocks/wp-block-button"; 112 | @import "blocks/wp-block-categories"; 113 | @import "blocks/wp-block-code"; 114 | @import "blocks/wp-block-columns"; 115 | @import "blocks/wp-block-cover"; 116 | @import "blocks/wp-block-embed"; 117 | @import "blocks/wp-block-file"; 118 | @import "blocks/wp-block-gallery"; 119 | @import "blocks/wp-block-image"; 120 | @import "blocks/wp-block-latest-posts"; 121 | @import "blocks/wp-block-media-text"; 122 | @import "blocks/wp-block-preformatted"; 123 | @import "blocks/wp-block-pullquote"; 124 | @import "blocks/wp-block-quote"; 125 | @import "blocks/wp-block-separator"; 126 | @import "blocks/wp-block-table"; 127 | @import "blocks/wp-block-verse"; 128 | 129 | 130 | // Vendor. 131 | // 132 | // Vendor files handle code for specific plugins and third-party 133 | // scripts that would overwrite earlier styles. 134 | 135 | // @import "vendor/index"; 136 | 137 | 138 | // Utilities. 139 | // 140 | // Utilities are helper classes and overrides. This gets loaded last. 141 | // If necessary, this is the only place where `!important` rules should 142 | // go, but only if necessary. 143 | 144 | @import "utilities/alignment"; 145 | @import "utilities/clearfix"; 146 | @import "utilities/color-palette"; 147 | @import "utilities/headings"; 148 | @import "utilities/hide"; 149 | -------------------------------------------------------------------------------- /app/functions-setup.php: -------------------------------------------------------------------------------- 1 | 15 | * @copyright Copyright (c) 2018, Brett Mason 16 | * @link https://github.com/brettsmason/luxe/ 17 | * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 18 | */ 19 | 20 | namespace Luxe; 21 | 22 | /** 23 | * Set up theme support. This is where calls to `add_theme_support()` happen. 24 | * 25 | * @link https://developer.wordpress.org/reference/functions/add_theme_support/ 26 | * @link https://developer.wordpress.org/themes/basics/theme-functions/ 27 | * @link https://developer.wordpress.org/reference/functions/load_theme_textdomain/ 28 | * @since 1.0.0 29 | * @access public 30 | * @return void 31 | */ 32 | add_action( 'after_setup_theme', function() { 33 | 34 | // Set content width. 35 | $GLOBALS['content_width'] = 1024; 36 | 37 | // Load theme translations. 38 | load_theme_textdomain( 'luxe', get_parent_theme_file_path( 'resources/lang' ) ); 39 | 40 | // Automatically add feed links to ``. 41 | add_theme_support( 'automatic-feed-links' ); 42 | 43 | // Outputs HTML5 markup for core features. 44 | add_theme_support( 'html5', [ 45 | 'caption', 46 | 'comment-form', 47 | 'comment-list', 48 | 'gallery', 49 | 'search-form', 50 | ] ); 51 | 52 | // Add title tag support. 53 | add_theme_support( 'title-tag' ); 54 | 55 | // Adds featured image support. 56 | add_theme_support( 'post-thumbnails' ); 57 | 58 | // Add selective refresh for widgets. 59 | add_theme_support( 'customize-selective-refresh-widgets' ); 60 | 61 | // Add support for editor color palette. 62 | add_theme_support( 'editor-color-palette', [ 63 | [ 64 | 'name' => __( 'Primary', 'luxe' ), 65 | 'slug' => 'primary', 66 | 'color' => '#544882', 67 | ], 68 | [ 69 | 'name' => __( 'Secondary', 'luxe' ), 70 | 'slug' => 'secondary', 71 | 'color' => '#292f36', 72 | ], 73 | [ 74 | 'name' => __( 'White', 'luxe' ), 75 | 'slug' => 'white', 76 | 'color' => '#fff', 77 | ], 78 | [ 79 | 'name' => __( 'Black', 'luxe' ), 80 | 'slug' => 'black', 81 | 'color' => '#000', 82 | ], 83 | ] ); 84 | 85 | // Editor stylesheet. 86 | add_theme_support( 'editor-styles' ); 87 | add_editor_style( 'public/css/editor.css' ); 88 | 89 | // Disable custom colors in block color palettes. 90 | add_theme_support( 'disable-custom-colors' ); 91 | 92 | // Add support for align wide blocks. 93 | add_theme_support( 'align-wide' ); 94 | 95 | // Add support for custom logo. 96 | add_theme_support( 'custom-logo', [ 97 | 'width' => 300, 98 | 'height' => 200, 99 | 'flex-height' => true, 100 | 'flex-width' => true, 101 | 'header-text' => [ 'app-header__title', 'app-header__description' ], 102 | ] ); 103 | }, 5 ); 104 | 105 | /** 106 | * Register menus. 107 | * 108 | * @link https://developer.wordpress.org/reference/functions/register_nav_menus/ 109 | * @since 1.0.0 110 | * @access public 111 | * @return void 112 | */ 113 | add_action( 'init', function() { 114 | 115 | register_nav_menus( [ 116 | 'primary' => esc_html_x( 'Primary', 'nav menu location', 'luxe' ), 117 | 'subsidiary' => esc_html_x( 'Subsidiary', 'nav menu location', 'luxe' ), 118 | ] ); 119 | 120 | }, 5 ); 121 | 122 | /** 123 | * Register image sizes. 124 | * 125 | * @since 1.0.0 126 | * @access public 127 | * @return void 128 | */ 129 | add_action( 'init', function() { 130 | 131 | // Set the `post-thumbnail` size. 132 | set_post_thumbnail_size( 739, 493, true ); 133 | }, 5 ); 134 | 135 | /** 136 | * Register sidebars. 137 | * 138 | * @link https://developer.wordpress.org/reference/functions/register_sidebar/ 139 | * @since 1.0.0 140 | * @access public 141 | * @return void 142 | */ 143 | add_action( 'widgets_init', function() { 144 | $args = [ 145 | 'before_widget' => '
', 146 | 'after_widget' => '
', 147 | 'before_title' => '

', 148 | 'after_title' => '

', 149 | ]; 150 | 151 | register_sidebar( [ 152 | 'id' => 'primary', 153 | 'name' => esc_html_x( 'Primary', 'sidebar', 'luxe' ), 154 | ] + $args ); 155 | 156 | register_sidebar( [ 157 | 'id' => 'subsidiary', 158 | 'name' => esc_html_x( 'Subsidiary', 'sidebar', 'luxe' ), 159 | ] + $args ); 160 | }, 5 ); 161 | -------------------------------------------------------------------------------- /resources/scss/components/_menu.scss: -------------------------------------------------------------------------------- 1 | .menu { 2 | 3 | // The base