├── .babelrc ├── .eleventy.js ├── .gitignore ├── .htaccess ├── README.md ├── gulpfile.babel.js ├── package-lock.json ├── package.json └── src ├── _data ├── products.json └── site.json ├── _includes ├── assets │ ├── css │ │ └── main.min.css │ ├── images │ │ ├── 01.jpg │ │ ├── 02.jpg │ │ ├── 03.jpg │ │ ├── 04.jpg │ │ ├── 05.jpg │ │ ├── 06.jpg │ │ ├── alexander-andrews-RU0KVBUqBLk-unsplash.jpg │ │ ├── alexander-andrews-soLEw77Napo-unsplash.jpg │ │ ├── ezgif.com-gif-to-mp4.mp4 │ │ └── ezgif.mp4 │ └── scripts │ │ └── main.min.js ├── layouts │ ├── base.njk │ └── post.njk └── partials │ ├── metas.njk │ ├── nav.njk │ ├── sitefooter.njk │ └── siteheader.njk ├── blog.njk ├── images ├── 01.jpg ├── 02.jpg ├── 03.jpg ├── 04.jpg ├── 05.jpg ├── 06.jpg └── ezgif.mp4 ├── index.njk ├── posts ├── bienvenue.md └── second-article.md ├── product-page.njk ├── scripts └── app.js ├── scss ├── layouts │ ├── _header.scss │ └── _snipcart.scss ├── pages │ ├── _blog.scss │ ├── _home.scss │ ├── _product.scss │ └── _shop.scss ├── style.scss ├── theme │ ├── _buttons.scss │ ├── _core.scss │ ├── _frame.scss │ └── _grid.scss └── utils │ ├── _animation.scss │ ├── _easings.scss │ └── _helpers.scss └── shop.njk /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ "@babel/preset-env" ] 3 | } -------------------------------------------------------------------------------- /.eleventy.js: -------------------------------------------------------------------------------- 1 | const { DateTime } = require("luxon"); 2 | 3 | module.exports = function(eleventyConfig) { 4 | // copy assets folder 5 | eleventyConfig.addPassthroughCopy({'src/_includes/assets/css/main.min.css': 'css/main.min.css'}); 6 | eleventyConfig.addPassthroughCopy({'src/_includes/assets/scripts/main.min.js': 'scripts/main.min.js'}); 7 | eleventyConfig.addPassthroughCopy({'src/_includes/assets/images/': 'images/'}); 8 | 9 | eleventyConfig.addFilter("readableDate", dateObj => { 10 | return DateTime.fromJSDate(dateObj, {zone: 'utc'}).toFormat("dd LLL yyyy"); 11 | }); 12 | 13 | // https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-date-string 14 | eleventyConfig.addFilter('htmlDateString', (dateObj) => { 15 | return DateTime.fromJSDate(dateObj, {zone: 'utc'}).toFormat('yyyy-LL-dd'); 16 | }); 17 | 18 | // posts collection 19 | eleventyConfig.addCollection("posts", function(collection) { 20 | return collection.getFilteredByGlob("./src/posts/*.md").reverse(); 21 | }); 22 | 23 | // Base config 24 | return { 25 | passthroughFileCopy: true, 26 | dir: { 27 | input: "src", 28 | output: "dist", 29 | } 30 | }; 31 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | # One year for image files 2 | 3 | Header set Cache-Control "max-age=31536000, public" 4 | 5 | # One month for css and js 6 | 7 | Header set Cache-Control "max-age=2628000, public" 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # eleventy-snipcart-shop 2 | An eleventy + snipcart shop demo. 3 | You can read [my post](https://lea-tortay.com/journal/eleventy-and-snipcart-shop/) about how you can add a snipcart checkout. 4 | 5 | ## Install 6 | ``` 7 | git clone git@github.com:lea37/eleventy-snipcart-shop.git 8 | cd eleventy-snipcart-shop 9 | npm i 10 | npm run serve 11 | ``` 12 | 13 | 14 | -------------------------------------------------------------------------------- /gulpfile.babel.js: -------------------------------------------------------------------------------- 1 | import gulp from 'gulp'; 2 | import sass from 'gulp-sass'; 3 | import prefix from 'gulp-autoprefixer'; 4 | import babel from 'gulp-babel'; 5 | import concat from 'gulp-concat'; 6 | import uglify from 'gulp-uglify'; 7 | import rename from 'gulp-rename'; 8 | import cleanCSS from 'gulp-clean-css'; 9 | import del from 'del'; 10 | import imagemin from 'gulp-imagemin'; 11 | 12 | const paths = { 13 | styles: { 14 | src: './src/scss/**/*.scss', 15 | dest: './src/_includes/assets/css/' 16 | }, 17 | scripts: { 18 | src: './src/scripts/**/*.js', 19 | dest: './src/_includes/assets/scripts/' 20 | }, 21 | images: { 22 | src: './src/images/*', 23 | dest: './src//_includes/assets/images' 24 | } 25 | }; 26 | 27 | /* 28 | * For small tasks you can export arrow functions 29 | */ 30 | export const clean = () => del([ 'assets' ]); 31 | 32 | /* 33 | * You can also declare named functions and export them as tasks 34 | */ 35 | export function styles() { 36 | return gulp.src(paths.styles.src) 37 | .pipe(sass().on('error', sass.logError)) 38 | .pipe(cleanCSS()) 39 | // pass in options to the stream 40 | .pipe(rename({ 41 | basename: 'main', 42 | suffix: '.min' 43 | })) 44 | .pipe(gulp.dest(paths.styles.dest)); 45 | } 46 | 47 | 48 | export function images() { 49 | return gulp.src(paths.images.src) 50 | .pipe(imagemin()) 51 | .pipe(gulp.dest(paths.images.dest)) 52 | } 53 | 54 | export function scripts() { 55 | return gulp.src(paths.scripts.src, { sourcemaps: true }) 56 | .pipe(babel()) 57 | .pipe(uglify()) 58 | .pipe(concat('main.min.js')) 59 | .pipe(gulp.dest(paths.scripts.dest)); 60 | } 61 | 62 | /* 63 | * You could even use `export as` to rename exported tasks 64 | */ 65 | function watch() { 66 | gulp.watch(paths.scripts.src, gulp.parallel(scripts)); 67 | gulp.watch(paths.styles.src, gulp.parallel(styles)); 68 | gulp.watch(paths.images.src, gulp.parallel(images)); 69 | } 70 | 71 | const build = gulp.series(clean, gulp.parallel(watch)); 72 | /* 73 | * Export a default task 74 | */ 75 | export default build; 76 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eleventy-shop", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "gulp default & eleventy", 8 | "serve": "gulp default & eleventy --serve", 9 | "debug": "DEBUG=* eleventy" 10 | }, 11 | "author": "lea tortay", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "@11ty/eleventy": "^0.10.0", 15 | "@babel/core": "^7.6.4", 16 | "@babel/preset-env": "^7.6.3", 17 | "@babel/register": "^7.6.2", 18 | "babelify": "^10.0.0", 19 | "browser-sync": "^2.26.7", 20 | "del": "^5.1.0", 21 | "gulp": "^4.0.2", 22 | "gulp-autoprefixer": "^7.0.1", 23 | "gulp-babel": "^8.0.0", 24 | "gulp-browserify": "^0.5.1", 25 | "gulp-clean-css": "^4.3.0", 26 | "gulp-concat": "^2.6.1", 27 | "gulp-imagemin": "^7.1.0", 28 | "gulp-rename": "^2.0.0", 29 | "gulp-sass": "^4.0.2", 30 | "gulp-uglify": "^3.0.2" 31 | }, 32 | "dependencies": { 33 | "luxon": "^1.22.2" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/_data/products.json: -------------------------------------------------------------------------------- 1 | { 2 | "products" : [ 3 | { 4 | "id": 1, 5 | "price" : "15", 6 | "currency": "€", 7 | "url": "seylan", 8 | "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", 9 | "image": "https://images.unsplash.com/photo-1504382103100-db7e92322d39?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400", 10 | "name": "Seylan", 11 | "credits": "Photo by Alison Marras on Unsplash" 12 | }, 13 | { 14 | "id": 2, 15 | "price" : "22", 16 | "currency": "€", 17 | "url": "rose-tea", 18 | "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Placerat vestibulum lectus mauris ultrices eros in cursus turpis. Justo eget magna fermentum iaculis.", 19 | "image": "https://images.unsplash.com/photo-1501841580093-a258b1937efe?ixlib=rb-1.2.1&auto=format&fit=crop&w=400", 20 | "name": "Rose tea", 21 | "credits": "Photo by Neven Krcmarek on Unsplash" 22 | }, 23 | { 24 | "id": 3, 25 | "price" : "18", 26 | "currency": "€", 27 | "url": "black-tea", 28 | "description": "Massa sed elementum tempus egestas. Eget nunc lobortis mattis aliquam faucibus purus in massa. Egestas maecenas pharetra convallis posuere morbi leo urna molestie at. Mattis nunc sed blandit libero volutpat sed cras ornare. Sem integer vitae justo eget magna.", 29 | "image": "https://images.unsplash.com/photo-1590434434890-eee41ce7d4e1?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400", 30 | "name": "Black tea", 31 | "credits": "Photo by Jocelyne Flor on Unsplash" 32 | }, 33 | { 34 | "id": 4, 35 | "price" : "20", 36 | "currency": "€", 37 | "url": "earl-grey", 38 | "description": "Sed cras ornare arcu dui vivamus arcu felis bibendum. Nullam ac tortor vitae purus faucibus. Sit amet mauris commodo quis imperdiet massa. Praesent semper feugiat nibh sed. Viverra tellus in hac habitasse.", 39 | "image": "https://images.unsplash.com/photo-1547149617-609fafa00a6b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400", 40 | "name": "Earl grey tea", 41 | "credits": "Photo by Tina Dawson on Unsplash" 42 | }, 43 | { 44 | "id": 5, 45 | "price" : "20", 46 | "currency": "€", 47 | "url": "caramel", 48 | "description": "A erat nam at lectus. Est velit egestas dui id ornare arcu odio ut. Vestibulum lorem sed risus ultricies tristique nulla aliquet.", 49 | "image": "https://images.unsplash.com/photo-1539398100550-fbe9dff24993?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400", 50 | "name": "Caramel tea", 51 | "credits": "Photo by Oriento on Unsplash" 52 | }, 53 | { 54 | "id": 6, 55 | "price" : "35", 56 | "currency": "€", 57 | "url": "flower", 58 | "description": "Risus commodo viverra maecenas accumsan lacus vel facilisis volutpat.", 59 | "image": "https://images.unsplash.com/photo-1467164616789-ce7ae65ab4c9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400", 60 | "name": "Flower tea", 61 | "credits": "Photo by Ornella Binni on Unsplash" 62 | } 63 | ] 64 | } -------------------------------------------------------------------------------- /src/_data/site.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Snipcart & Eleventy demo", 3 | "shortDesc": "A shop create with snipcart and eleventy.", 4 | "url": "https://snipshop.lea-tortay.com", 5 | "authorEmail": "leatortay@gmail.com", 6 | "authorHandle": "@leatortay", 7 | "authorName": "Lea Tortay", 8 | "navItems": [ 9 | { 10 | "name": "Shop", 11 | "url": "/shop", 12 | "external": false 13 | }, 14 | { 15 | "name": "Blog", 16 | "url": "/blog", 17 | "external": false 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /src/_includes/assets/css/main.min.css: -------------------------------------------------------------------------------- 1 | .u-flex{display:flex}.u-between{justify-content:space-between}.u-align-center{align-items:center}.u-flex-wrap{flex-wrap:wrap}.no-underline{text-decoration:none}@media screen and (max-width:45rem){.u-hide-sm{display:none}}@media screen and (min-width:54rem){.t-fade-in{opacity:0;transform:translateZ(0);backface-visibility:hidden;transition:transform .7s cubic-bezier(.455,.03,.515,.955),opacity .7s cubic-bezier(.455,.03,.515,.955)}.t-fade-in.is-visible{opacity:1}.t-translate-down{transform:translate3d(0,15px,0);transition:transform .7s cubic-bezier(.455,.03,.515,.955),opacity .7s cubic-bezier(.455,.03,.515,.955);backface-visibility:hidden}.t-translate-down.t-translate-full{overflow:hidden;transform:translate3d(0,100%,0);transition:transform 1.2s cubic-bezier(.23,1,.32,1),opacity 1.2s cubic-bezier(.23,1,.32,1)}.t-translate-down.t-scale{transform:translate3d(0,15px,0) scaleY(1.2);transform-origin:0 100%}.t-translate-down.is-visible{transform:translate3d(0,0,0)}}body,html{color:#1a1423;font-family:sans-serif;background-color:#efefef;text-rendering:optimizeLegibility;text-shadow:1px 1px 1px rgba(0,0,0,.004);-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;letter-spacing:.02em;line-height:25px;margin:0;padding:0}h1,h2,h3{font-family:Montserrat,sans-serif;letter-spacing:initial;margin:0;font-weight:900}h1{font-size:30px;line-height:48px}@media screen and (min-width:54rem){h1{font-size:50px;line-height:70px}}a{color:#1a1423;text-decoration:underline}ul{margin:0;padding:0}ul li{list-style-type:none}.main{margin-bottom:72px;transition:opacity .4s cubic-bezier(.25,.46,.45,.94);opacity:0}.main.active{opacity:1}.blog .main.active,.shop .main.active{margin-top:8em}.inner{max-width:73rem;margin-left:auto;margin-right:auto;padding-left:1.25rem;padding-right:1.25rem}@media screen and (max-width:54rem){.inner{max-width:54rem}}.frame{--n:1;--d:1;padding-bottom:calc(var(--n)/ var(--d) * 100%);position:relative}.frame>*{overflow:hidden;position:absolute;top:0;right:0;bottom:0;left:0;display:flex;justify-content:center;align-items:center}.frame>iframe,.frame>img,.frame>video{width:100%;height:100%;object-fit:cover}.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(17rem,1fr));grid-gap:5rem}.grid>*{max-width:25rem;margin-left:auto;margin-right:auto}.grid>*+*{margin-top:1rem}@supports (display:grid){.grid>*{max-width:unset;margin:0}}.button,button.button{border:1px solid #000;background:0 0;color:#000;font-size:16px;padding:.5em 1em;transition:all .4s linear;position:relative;display:inline-block}@media screen and (min-width:54rem){.button,button.button{padding:.5em}}.button:before,button.button:before{content:'';position:absolute;z-index:-1;top:0;left:0;width:100%;height:100%;background-color:#000;will-change:transform;transform-origin:bottom;transform:scaleY(0);transition:transform .4s cubic-bezier(.645,.045,.355,1)}@media screen and (min-width:54rem){.button:hover,button.button:hover{cursor:pointer;color:#fff}.button:hover:before,button.button:hover:before{transform:scaleY(1)}}.button--full,button.button--full{background-color:#000;color:#fff}.hero{background:url(https://images.unsplash.com/photo-1458819714733-e5ab3d536722?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1000&q=80);background-size:cover;background-position:100% 60%}.hero-content{position:relative;width:100%;padding:10em 0 8em}.hero .button{margin:2em 0;text-decoration:none}.grid-wrapper h3{margin:1em 0}.grid-wrapper-title{margin:32px 0}.grid-wrapper .grid .card{flex-direction:column;justify-content:space-between}.grid-wrapper .grid .card .button{align-self:flex-start}.grid-wrapper .grid .card .frame{overflow:hidden}.grid-wrapper .grid .card-title{font-size:18px;font-weight:700}@media screen and (max-width:54rem){.single-product .inner{flex-direction:column}}.single-product-content,.single-product-image{width:50%}@media screen and (max-width:54rem){.single-product-content,.single-product-image{width:100%}}@media screen and (min-width:54rem){.product-content{padding-left:2em}}.product-content .title{font-size:30px;line-height:48px;font-weight:900}@media screen and (min-width:54rem){.product-content .title{font-size:50px;line-height:70px}}.product-content .price{font-size:22px;font-weight:700}.postlist-item{justify-content:space-between;padding:16px 0;border-bottom:1px solid #000;transition:.4s}.postlist-item .postlist-link{transition:.4s}.postlist-item:hover{cursor:pointer;background-color:#e2e2e2}.postlist-item:hover .postlist-link{margin-left:.5em}.header{position:absolute;top:0;left:0;width:100%;padding:2em 0;z-index:2}.header .inner{flex-direction:column}@media screen and (min-width:54rem){.header .inner{flex-direction:row;justify-content:space-between}}.header-logo{font-family:Montserrat,sans-serif;font-size:24px;font-weight:900}@media screen and (min-width:25rem){.header-logo{font-size:30px;line-height:45px}}@media screen and (max-width:54rem){.menu{margin-top:32px;justify-content:space-between}}.menu-item{font-family:Montserrat,sans-serif;font-weight:600}@media screen and (max-width:45rem){.menu-item:not(:first-child){margin-left:8px}}@media screen and (min-width:45rem){.menu-item{margin-left:32px}}.menu-item:not(.menu-item-button){position:relative}.menu-item:not(.menu-item-button):after{content:'';position:absolute;bottom:0;left:0;width:100%;height:1px;background-color:#000;will-change:transform;transform-origin:left;transform:scaleX(0);transition:transform .4s cubic-bezier(.645,.045,.355,1)}.menu-item:not(.menu-item-button):hover{cursor:pointer}.menu-item:not(.menu-item-button):hover:after{transform:scaleX(1)}.snipcart-cart-header,.snipcart-cart__content,.snipcart-featured-payment-methods__title,.snipcart-modal,.snipcart-modal__container{background-color:#fff}.snipcart-item-line{border:1px solid #000;margin-bottom:32px}.snipcart-discount-box{background-color:transparent}.snipcart-discount-box__button{border-color:#000} -------------------------------------------------------------------------------- /src/_includes/assets/images/01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lea37/eleventy-snipcart-shop/3ff1282fcfe066aa95f598ad7cf4070c56aed160/src/_includes/assets/images/01.jpg -------------------------------------------------------------------------------- /src/_includes/assets/images/02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lea37/eleventy-snipcart-shop/3ff1282fcfe066aa95f598ad7cf4070c56aed160/src/_includes/assets/images/02.jpg -------------------------------------------------------------------------------- /src/_includes/assets/images/03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lea37/eleventy-snipcart-shop/3ff1282fcfe066aa95f598ad7cf4070c56aed160/src/_includes/assets/images/03.jpg -------------------------------------------------------------------------------- /src/_includes/assets/images/04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lea37/eleventy-snipcart-shop/3ff1282fcfe066aa95f598ad7cf4070c56aed160/src/_includes/assets/images/04.jpg -------------------------------------------------------------------------------- /src/_includes/assets/images/05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lea37/eleventy-snipcart-shop/3ff1282fcfe066aa95f598ad7cf4070c56aed160/src/_includes/assets/images/05.jpg -------------------------------------------------------------------------------- /src/_includes/assets/images/06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lea37/eleventy-snipcart-shop/3ff1282fcfe066aa95f598ad7cf4070c56aed160/src/_includes/assets/images/06.jpg -------------------------------------------------------------------------------- /src/_includes/assets/images/alexander-andrews-RU0KVBUqBLk-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lea37/eleventy-snipcart-shop/3ff1282fcfe066aa95f598ad7cf4070c56aed160/src/_includes/assets/images/alexander-andrews-RU0KVBUqBLk-unsplash.jpg -------------------------------------------------------------------------------- /src/_includes/assets/images/alexander-andrews-soLEw77Napo-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lea37/eleventy-snipcart-shop/3ff1282fcfe066aa95f598ad7cf4070c56aed160/src/_includes/assets/images/alexander-andrews-soLEw77Napo-unsplash.jpg -------------------------------------------------------------------------------- /src/_includes/assets/images/ezgif.com-gif-to-mp4.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lea37/eleventy-snipcart-shop/3ff1282fcfe066aa95f598ad7cf4070c56aed160/src/_includes/assets/images/ezgif.com-gif-to-mp4.mp4 -------------------------------------------------------------------------------- /src/_includes/assets/images/ezgif.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lea37/eleventy-snipcart-shop/3ff1282fcfe066aa95f598ad7cf4070c56aed160/src/_includes/assets/images/ezgif.mp4 -------------------------------------------------------------------------------- /src/_includes/assets/scripts/main.min.js: -------------------------------------------------------------------------------- 1 | "use strict";function _toConsumableArray(e){return _arrayWithoutHoles(e)||_iterableToArray(e)||_unsupportedIterableToArray(e)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(r):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?_arrayLikeToArray(e,t):void 0}}function _iterableToArray(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}function _arrayWithoutHoles(e){if(Array.isArray(e))return _arrayLikeToArray(e)}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r 2 | 3 | 4 | 5 | 6 | 7 | 8 | {% include "partials/metas.njk" %} 9 | 10 | 11 | 12 | 13 | 14 | 15 | {% include "partials/siteheader.njk" %} 16 |
17 | {% block content %}{% endblock %} 18 |
19 | {% include "partials/sitefooter.njk" %} 20 | 21 | -------------------------------------------------------------------------------- /src/_includes/layouts/post.njk: -------------------------------------------------------------------------------- 1 | --- 2 | templateClass: "post" 3 | --- 4 | {% extends "layouts/base.njk" %} 5 | 6 | {% block content %} 7 |
8 |
9 |

← Home

10 |

{{ title }}

11 | {{ content | safe }} 12 |
13 |
14 | {% endblock %} -------------------------------------------------------------------------------- /src/_includes/partials/metas.njk: -------------------------------------------------------------------------------- 1 | {% set pageTitle = title + ' - ' + site.title %} 2 | {% set pageDesc = desc %} 3 | {% set siteTitle = site.title %} 4 | {% set currentUrl = site.url + page.url %} 5 | 6 | {{ pageTitle }} 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | {% if site.authorHandle %} 15 | 16 | {% endif %} 17 | 18 | {% if pageDesc %} 19 | 20 | 21 | 22 | {% endif %} 23 | 24 | {% if socialImage %} 25 | 26 | 27 | 28 | 29 | {% endif %} -------------------------------------------------------------------------------- /src/_includes/partials/nav.njk: -------------------------------------------------------------------------------- 1 | {% if site.navItems %} 2 | 17 | {% endif %} -------------------------------------------------------------------------------- /src/_includes/partials/sitefooter.njk: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/_includes/partials/siteheader.njk: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | {% include "partials/nav.njk" %} 5 |
6 |
-------------------------------------------------------------------------------- /src/blog.njk: -------------------------------------------------------------------------------- 1 | --- 2 | title: Blog 3 | templateClass: "blog" 4 | --- 5 | {% extends "layouts/base.njk" %} 6 | 7 | {% block content %} 8 |
9 |
10 |
    11 | {% for post in collections.posts | reverse %} 12 |
  • 13 | {{ post.data.title }} 14 | 15 |
  • 16 | {% endfor %} 17 |
18 |
19 |
20 | {% endblock %} -------------------------------------------------------------------------------- /src/images/01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lea37/eleventy-snipcart-shop/3ff1282fcfe066aa95f598ad7cf4070c56aed160/src/images/01.jpg -------------------------------------------------------------------------------- /src/images/02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lea37/eleventy-snipcart-shop/3ff1282fcfe066aa95f598ad7cf4070c56aed160/src/images/02.jpg -------------------------------------------------------------------------------- /src/images/03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lea37/eleventy-snipcart-shop/3ff1282fcfe066aa95f598ad7cf4070c56aed160/src/images/03.jpg -------------------------------------------------------------------------------- /src/images/04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lea37/eleventy-snipcart-shop/3ff1282fcfe066aa95f598ad7cf4070c56aed160/src/images/04.jpg -------------------------------------------------------------------------------- /src/images/05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lea37/eleventy-snipcart-shop/3ff1282fcfe066aa95f598ad7cf4070c56aed160/src/images/05.jpg -------------------------------------------------------------------------------- /src/images/06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lea37/eleventy-snipcart-shop/3ff1282fcfe066aa95f598ad7cf4070c56aed160/src/images/06.jpg -------------------------------------------------------------------------------- /src/images/ezgif.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lea37/eleventy-snipcart-shop/3ff1282fcfe066aa95f598ad7cf4070c56aed160/src/images/ezgif.mp4 -------------------------------------------------------------------------------- /src/index.njk: -------------------------------------------------------------------------------- 1 | --- 2 | title: Home 3 | templateClass: "home" 4 | --- 5 | {% extends "layouts/base.njk" %} 6 | 7 | {% block content %} 8 |
9 |
10 |
11 |

Tea time, everywhere

12 |

Find the best tea for your everyday needs and special times.

13 | Discover all tea 14 |
15 |
16 |
17 |
18 |
19 |

Our last products :

20 |
21 | {% for product in products.products %} 22 | {% if loop.index0 < 3 %} 23 | 40 | {% endif %} 41 | {% endfor %} 42 |
43 |
44 |
45 | {% endblock %} -------------------------------------------------------------------------------- /src/posts/bienvenue.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Mon premier article 3 | description: Mon premier article 4 | date: 2020-03-16 5 | layout: layouts/post.njk 6 | --- 7 | 8 | Mon super article -------------------------------------------------------------------------------- /src/posts/second-article.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Mon second article 3 | description: Mon second article 4 | date: 2020-03-27 5 | layout: layouts/post.njk 6 | --- 7 | 8 | Mon super article -------------------------------------------------------------------------------- /src/product-page.njk: -------------------------------------------------------------------------------- 1 | --- 2 | templateClass: "product" 3 | pagination: 4 | data: products.products 5 | size: 1 6 | alias: product 7 | permalink: shop/product/{{product.url}}/index.html 8 | --- 9 | {% extends "layouts/base.njk" %} 10 | 11 | {% block content %} 12 |
13 |
14 |
15 |
16 | {{ product.credits }} 17 |
18 |
19 |
20 |

{{ product.name }}

21 |

{{ product.price }}{{ product.currency }}

22 |

{{ product.description }}

23 | 33 |
34 |
35 |
36 | {% endblock %} -------------------------------------------------------------------------------- /src/scripts/app.js: -------------------------------------------------------------------------------- 1 | function onClick(e) { 2 | e.preventDefault(); 3 | var newLocation = e.currentTarget.href; 4 | document.querySelector(".main").classList.remove("active"); 5 | setTimeout(function(){ 6 | window.location = newLocation; 7 | },400); 8 | } 9 | 10 | function activeOnVisible() { 11 | const elements = [...document.querySelectorAll('.js-active-on-visible')] 12 | 13 | const options = { 14 | rootMargin: '-100px', 15 | threshold: 0.25 16 | } 17 | 18 | const callback = (entries) => { 19 | entries.forEach((entry) => { 20 | const delay = entry.target.getAttribute('data-delay'); 21 | 22 | if (entry.intersectionRatio >= 0.25) { 23 | setTimeout(() => { 24 | entry.target.classList.add("is-visible"); 25 | }, delay) 26 | } 27 | }) 28 | } 29 | 30 | const observer = new IntersectionObserver(callback, options) 31 | 32 | elements.forEach((element, index) => { 33 | observer.observe(element) 34 | }) 35 | } 36 | 37 | 38 | document.addEventListener("DOMContentLoaded", function() { 39 | document.body.classList.add('loaded'); 40 | 41 | // PAGE TRANSITION 42 | setTimeout(function(){ 43 | document.querySelector(".main").classList.add("active"); 44 | }, 1); 45 | 46 | // Play transition before changing page 47 | var links = document.querySelectorAll('.menu__item a'); 48 | for (var i = links.length - 1; i >= 0; i--) { 49 | links[i].addEventListener('click', onClick); 50 | } 51 | 52 | // ACTIVE IN VIEW 53 | if (window.matchMedia("(min-width: 54rem)").matches) { 54 | activeOnVisible(); 55 | } 56 | }); 57 | 58 | -------------------------------------------------------------------------------- /src/scss/layouts/_header.scss: -------------------------------------------------------------------------------- 1 | .header { 2 | position: absolute; 3 | top: 0; 4 | left: 0; 5 | width: 100%; 6 | padding: 2em 0; 7 | z-index: 2; 8 | 9 | .inner { 10 | flex-direction: column; 11 | 12 | @media screen and (min-width: 54rem) { 13 | flex-direction: row; 14 | justify-content: space-between; 15 | } 16 | } 17 | 18 | &-logo { 19 | font-family: 'Montserrat', sans-serif; 20 | font-size: 24px; 21 | font-weight: 900; 22 | 23 | @media screen and (min-width: 25rem) { 24 | font-size: 30px; 25 | line-height: 45px; 26 | } 27 | } 28 | } 29 | 30 | .menu { 31 | @media screen and (max-width: 54rem) { 32 | margin-top: 32px; 33 | justify-content: space-between; 34 | } 35 | 36 | &-item { 37 | font-family: 'Montserrat', sans-serif; 38 | font-weight: 600; 39 | 40 | @media screen and (max-width: 45rem) { 41 | &:not(:first-child) { 42 | margin-left: 8px; 43 | } 44 | } 45 | 46 | @media screen and (min-width: 45rem) { 47 | margin-left: 32px; 48 | } 49 | 50 | &:not(&-button) { 51 | position: relative; 52 | 53 | &:after { 54 | content: ''; 55 | position: absolute; 56 | bottom: 0; 57 | left: 0; 58 | width: 100%; 59 | height: 1px; 60 | background-color: black; 61 | will-change: transform; 62 | transform-origin: left; 63 | transform: scaleX(0); 64 | transition: transform 0.4s cubic-bezier(0.645, 0.045, 0.355, 1); 65 | } 66 | 67 | &:hover { 68 | cursor: pointer; 69 | 70 | &:after { 71 | transform: scaleX(1); 72 | } 73 | } 74 | } 75 | 76 | } 77 | } -------------------------------------------------------------------------------- /src/scss/layouts/_snipcart.scss: -------------------------------------------------------------------------------- 1 | .snipcart-modal__container, 2 | .snipcart-modal, 3 | .snipcart-cart-header, 4 | .snipcart-cart__content, 5 | .snipcart-featured-payment-methods__title { 6 | background-color: #fff; 7 | } 8 | 9 | // item 10 | .snipcart-item-line { 11 | border: 1px solid black; 12 | margin-bottom: 32px; 13 | } 14 | 15 | // promo button 16 | .snipcart-discount-box { 17 | background-color: transparent; 18 | } 19 | .snipcart-discount-box__button { 20 | border-color: black; 21 | } -------------------------------------------------------------------------------- /src/scss/pages/_blog.scss: -------------------------------------------------------------------------------- 1 | .postlist-item { 2 | justify-content: space-between; 3 | padding: 16px 0; 4 | border-bottom: 1px solid black; 5 | transition: 0.4s; 6 | 7 | .postlist-link { 8 | transition: 0.4s; 9 | } 10 | 11 | &:hover { 12 | cursor: pointer; 13 | background-color: darken(#efefef, 5%); 14 | 15 | .postlist-link { 16 | margin-left: 0.5em; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/scss/pages/_home.scss: -------------------------------------------------------------------------------- 1 | .hero { 2 | background: url('https://images.unsplash.com/photo-1458819714733-e5ab3d536722?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1000&q=80'); 3 | background-size: cover; 4 | background-position: 100% 60%; 5 | 6 | &-content { 7 | position: relative; 8 | width: 100%; 9 | padding: 10em 0 8em; 10 | } 11 | 12 | .button { 13 | margin: 2em 0; 14 | text-decoration: none; 15 | } 16 | } -------------------------------------------------------------------------------- /src/scss/pages/_product.scss: -------------------------------------------------------------------------------- 1 | .single-product { 2 | .inner { 3 | @media screen and (max-width: 54rem) { 4 | flex-direction: column; 5 | } 6 | } 7 | 8 | &-image, 9 | &-content { 10 | width: 50%; 11 | 12 | @media screen and (max-width: 54rem) { 13 | width: 100%; 14 | } 15 | } 16 | } 17 | 18 | .product { 19 | &-content { 20 | @media screen and (min-width: 54rem) { 21 | padding-left: 2em; 22 | } 23 | 24 | .title { 25 | font-size: 30px; 26 | line-height: 48px; 27 | font-weight: 900; 28 | 29 | @media screen and (min-width: 54rem) { 30 | font-size: 50px; 31 | line-height: 70px; 32 | } 33 | } 34 | 35 | .price { 36 | font-size: 22px; 37 | font-weight: 700; 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/scss/pages/_shop.scss: -------------------------------------------------------------------------------- 1 | .grid-wrapper { 2 | h3 { 3 | margin: 1em 0; 4 | } 5 | 6 | &-title { 7 | margin: 32px 0; 8 | } 9 | 10 | .grid { 11 | .card { 12 | flex-direction: column; 13 | justify-content: space-between; 14 | 15 | .button { 16 | align-self: flex-start 17 | } 18 | 19 | .frame { 20 | overflow: hidden; 21 | } 22 | 23 | &-title { 24 | font-size: 18px; 25 | font-weight: 700; 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/scss/style.scss: -------------------------------------------------------------------------------- 1 | @import "utils/helpers"; 2 | @import "utils/easings"; 3 | @import "utils/animation"; 4 | 5 | @import "theme/core"; 6 | @import "theme/frame"; 7 | @import "theme/grid"; 8 | @import "theme/buttons"; 9 | 10 | @import "pages/home"; 11 | @import "pages/shop"; 12 | @import "pages/product"; 13 | @import "pages/blog"; 14 | 15 | @import "layouts/header"; 16 | @import "layouts/snipcart"; -------------------------------------------------------------------------------- /src/scss/theme/_buttons.scss: -------------------------------------------------------------------------------- 1 | .button, 2 | button.button { 3 | border: 1px solid black; 4 | background: transparent; 5 | color: black; 6 | font-size: 16px; 7 | padding: 0.5em 1em; 8 | transition: all 0.4s linear; 9 | position: relative; 10 | display: inline-block; 11 | 12 | @media screen and (min-width: 54rem) { 13 | padding: 0.5em; 14 | } 15 | 16 | &:before { 17 | content: ''; 18 | position: absolute; 19 | z-index: -1; 20 | top: 0; 21 | left: 0; 22 | width: 100%; 23 | height: 100%; 24 | background-color: black; 25 | will-change: transform; 26 | transform-origin: bottom; 27 | transform: scaleY(0); 28 | transition: transform 0.4s cubic-bezier(0.645, 0.045, 0.355, 1); 29 | } 30 | 31 | @media screen and (min-width: 54rem) { 32 | &:hover { 33 | cursor: pointer; 34 | color: white; 35 | 36 | &:before { 37 | transform: scaleY(1); 38 | } 39 | } 40 | } 41 | 42 | &--full { 43 | background-color: black; 44 | color: white; 45 | } 46 | } -------------------------------------------------------------------------------- /src/scss/theme/_core.scss: -------------------------------------------------------------------------------- 1 | html, body { 2 | color: #1a1423; 3 | font-family: sans-serif; 4 | background-color: #efefef; 5 | text-rendering: optimizeLegibility; 6 | text-shadow: 1px 1px 1px rgba(0,0,0,.004); 7 | -moz-osx-font-smoothing: grayscale; 8 | -webkit-font-smoothing: antialiased; 9 | letter-spacing: 0.02em; 10 | line-height: 25px; 11 | margin: 0; 12 | padding: 0; 13 | } 14 | 15 | h1, h2, h3 { 16 | font-family: 'Montserrat', sans-serif; 17 | letter-spacing: initial; 18 | margin: 0; 19 | font-weight: 900; 20 | } 21 | 22 | h1 { 23 | font-size: 30px; 24 | line-height: 48px; 25 | 26 | @media screen and (min-width: 54rem) { 27 | font-size: 50px; 28 | line-height: 70px; 29 | } 30 | } 31 | 32 | a { 33 | color: #1a1423; 34 | text-decoration: underline; 35 | } 36 | 37 | ul { 38 | margin: 0; 39 | padding: 0; 40 | } 41 | 42 | ul li { 43 | list-style-type: none; 44 | } 45 | 46 | .main { 47 | margin-bottom: 72px; 48 | transition: opacity 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); 49 | opacity: 0; 50 | 51 | &.active { 52 | opacity: 1; 53 | } 54 | } 55 | 56 | .shop, 57 | .blog { 58 | .main { 59 | &.active { 60 | margin-top: 8em; 61 | } 62 | } 63 | } 64 | 65 | .inner { 66 | max-width: 73rem; 67 | margin-left: auto; 68 | margin-right: auto; 69 | padding-left: 1.25rem; 70 | padding-right: 1.25rem; 71 | } 72 | 73 | @media screen and (max-width: 54rem) { 74 | .inner { 75 | max-width: 54rem; 76 | } 77 | } -------------------------------------------------------------------------------- /src/scss/theme/_frame.scss: -------------------------------------------------------------------------------- 1 | .frame { 2 | --n: 1; 3 | --d: 1; 4 | padding-bottom: calc(var(--n) / var(--d) * 100%); 5 | position: relative; 6 | } 7 | 8 | .frame > * { 9 | overflow: hidden; 10 | position: absolute; 11 | top: 0; 12 | right: 0; 13 | bottom: 0; 14 | left: 0; 15 | display: flex; 16 | justify-content: center; 17 | align-items: center; 18 | } 19 | 20 | .frame > img, 21 | .frame > video, 22 | .frame > iframe { 23 | width: 100%; 24 | height: 100%; 25 | object-fit: cover; 26 | } -------------------------------------------------------------------------------- /src/scss/theme/_grid.scss: -------------------------------------------------------------------------------- 1 | .grid { 2 | display: grid; 3 | grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); 4 | grid-gap: 5rem; 5 | } 6 | 7 | .grid > * { 8 | max-width: 25rem; 9 | margin-left: auto; 10 | margin-right: auto; 11 | } 12 | 13 | .grid > * + * { 14 | margin-top: 1rem; 15 | } 16 | 17 | @supports (display: grid) { 18 | .grid > * { 19 | max-width: unset; 20 | margin: 0; 21 | } 22 | } -------------------------------------------------------------------------------- /src/scss/utils/_animation.scss: -------------------------------------------------------------------------------- 1 | @media screen and (min-width: 54rem) { 2 | .t-fade-in { 3 | opacity: 0; 4 | transform: translateZ(0); 5 | backface-visibility: hidden; 6 | transition: transform .7s $ease-in-out-quad, opacity .7s $ease-in-out-quad; 7 | 8 | &.is-visible { 9 | opacity: 1; 10 | } 11 | } 12 | 13 | .t-translate-down { 14 | transform: translate3d(0, 15px, 0); 15 | transition: transform .7s $ease-in-out-quad, opacity .7s $ease-in-out-quad; 16 | backface-visibility: hidden; 17 | 18 | &.t-translate-full { 19 | overflow: hidden; 20 | transform: translate3d(0, 100%, 0); 21 | transition: transform 1.2s $ease-out-quint, opacity 1.2s $ease-out-quint; 22 | } 23 | 24 | &.t-scale { 25 | transform: translate3d(0, 15px, 0) scaleY(1.2); 26 | transform-origin: 0% 100%; 27 | } 28 | 29 | &.is-visible { 30 | transform: translate3d(0, 0, 0); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/scss/utils/_easings.scss: -------------------------------------------------------------------------------- 1 | $linear : cubic-bezier(0.250, 0.250, 0.750, 0.750); 2 | $ease-in-quad : cubic-bezier(0.550, 0.085, 0.680, 0.530); 3 | $ease-in-cubic : cubic-bezier(0.550, 0.055, 0.675, 0.190); 4 | $ease-in-quart : cubic-bezier(0.895, 0.030, 0.685, 0.220); 5 | $ease-in-quint : cubic-bezier(0.755, 0.050, 0.855, 0.060); 6 | $ease-in-sine : cubic-bezier(0.470, 0.000, 0.745, 0.715); 7 | $ease-in-expo : cubic-bezier(0.950, 0.050, 0.795, 0.035); 8 | $ease-in-circ : cubic-bezier(0.600, 0.040, 0.980, 0.335); 9 | $ease-in-back : cubic-bezier(0.600, -0.280, 0.735, 0.045); 10 | 11 | $ease-out-quad : cubic-bezier(0.250, 0.460, 0.450, 0.940); 12 | $ease-out-cubic : cubic-bezier(0.215, 0.610, 0.355, 1.000); 13 | $ease-out-quart : cubic-bezier(0.165, 0.840, 0.440, 1.000); 14 | $ease-out-quint : cubic-bezier(0.230, 1.000, 0.320, 1.000); 15 | $ease-out-sine : cubic-bezier(0.390, 0.575, 0.565, 1.000); 16 | $ease-out-expo : cubic-bezier(0.190, 1.000, 0.220, 1.000); 17 | $ease-out-circ : cubic-bezier(0.075, 0.820, 0.165, 1.000); 18 | $ease-out-back : cubic-bezier(0.175, 0.885, 0.320, 1.100); 19 | 20 | $ease-in-out-quad : cubic-bezier(0.455, 0.030, 0.515, 0.955); 21 | $ease-in-out-cubic : cubic-bezier(0.645, 0.045, 0.355, 1.000); 22 | $ease-in-out-quart : cubic-bezier(0.770, 0.000, 0.175, 1.000); 23 | $ease-in-out-quint : cubic-bezier(0.860, 0.000, 0.070, 1.000); 24 | $ease-in-out-sine : cubic-bezier(0.445, 0.050, 0.550, 0.950); 25 | $ease-in-out-expo : cubic-bezier(1.000, 0.000, 0.000, 1.000); 26 | $ease-in-out-circ : cubic-bezier(0.785, 0.135, 0.150, 0.860); 27 | $ease-in-out-back : cubic-bezier(0.680, 0, 0.265, 1); 28 | 29 | $ease-zoom : cubic-bezier(.0,.0,.71,.56); 30 | $ease-custom : cubic-bezier(0.645, 0.045, 0.355, 1); -------------------------------------------------------------------------------- /src/scss/utils/_helpers.scss: -------------------------------------------------------------------------------- 1 | .u-flex { 2 | display: flex; 3 | } 4 | 5 | .u-between { 6 | justify-content: space-between; 7 | } 8 | 9 | .u-align-center { 10 | align-items: center; 11 | } 12 | 13 | .u-flex-wrap { 14 | flex-wrap: wrap; 15 | } 16 | 17 | .no-underline { 18 | text-decoration: none; 19 | } 20 | 21 | .u-hide-sm { 22 | @media screen and (max-width: 45rem) { 23 | display: none; 24 | } 25 | } -------------------------------------------------------------------------------- /src/shop.njk: -------------------------------------------------------------------------------- 1 | --- 2 | title: Shop 3 | templateClass: "shop" 4 | --- 5 | {% extends "layouts/base.njk" %} 6 | 7 | {% block content %} 8 |
9 |
10 |

Shop

11 |
12 |
13 | {% for product in products.products %} 14 | 32 | {% endfor %} 33 |
34 |
35 | {% endblock %} --------------------------------------------------------------------------------