Compare commits
No commits in common. "master" and "2.0.3" have entirely different histories.
17
.github/workflows/deploy-theme.yml
vendored
@ -1,17 +0,0 @@
|
||||
---
|
||||
name: Deploy Theme
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: TryGhost/action-deploy-theme@v1.4.0
|
||||
with:
|
||||
api-url: ${{ secrets.GHOST_ADMIN_API_URL }}
|
||||
api-key: ${{ secrets.GHOST_ADMIN_API_KEY }}
|
||||
theme-name: "vivid-casper-master"
|
9
.gitignore
vendored
@ -13,16 +13,9 @@ results
|
||||
|
||||
npm-debug.log
|
||||
node_modules
|
||||
package-lock.json
|
||||
|
||||
.idea/*
|
||||
*.iml
|
||||
projectFilesBackup
|
||||
|
||||
.DS_Store
|
||||
|
||||
dist/
|
||||
|
||||
config.json
|
||||
changelog.md
|
||||
changelog.md.bk
|
||||
.DS_Store
|
2
LICENSE
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2013-2022 Ghost Foundation
|
||||
Copyright (c) 2013-2017 Ghost Foundation
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
|
41
README.md
@ -1,10 +1,10 @@
|
||||
# Casper
|
||||
|
||||
The default theme for [Ghost](http://github.com/tryghost/ghost/). This is the latest development version of Casper! If you're just looking to download the latest release, head over to the [releases](https://github.com/TryGhost/Casper/releases) page.
|
||||
The default theme for [Ghost](http://github.com/tryghost/ghost/). This is the latest development version of Casper. If you're just looking to download the latest release, head over to the [releases](https://github.com/TryGhost/Casper/releases) page.
|
||||
|
||||
|
||||
|
||||
![screenshot-desktop](https://user-images.githubusercontent.com/1418797/183329195-8e8f2ee5-a473-4694-a813-a2575491209e.png)
|
||||
![screenshot-desktop](https://user-images.githubusercontent.com/120485/27221326-1e31d326-5280-11e7-866d-82d550a7683b.jpg)
|
||||
|
||||
|
||||
|
||||
@ -12,49 +12,40 @@ The default theme for [Ghost](http://github.com/tryghost/ghost/). This is the la
|
||||
|
||||
Ghost uses a simple templating language called [Handlebars](http://handlebarsjs.com/) for its themes.
|
||||
|
||||
This theme has lots of code comments to help explain what's going on just by reading the code. Once you feel comfortable with how everything works, we also have full [theme API documentation](https://ghost.org/docs/themes/) which explains every possible Handlebars helper and template.
|
||||
We've documented our default theme pretty heavily so that it should be fairly easy to work out what's going on just by reading the code and the comments. Once you feel comfortable with how everything works, we also have full [theme API documentation](https://themes.ghost.org) which explains every possible Handlebars helper and template.
|
||||
|
||||
**The main files are:**
|
||||
|
||||
- `default.hbs` - The parent template file, which includes your global header/footer
|
||||
- `index.hbs` - The main template to generate a list of posts, usually the home page
|
||||
- `post.hbs` - The template used to render individual posts
|
||||
- `default.hbs` - The main template file
|
||||
- `index.hbs` - Used for the home page
|
||||
- `post.hbs` - Used for individual posts
|
||||
- `page.hbs` - Used for individual pages
|
||||
- `tag.hbs` - Used for tag archives, eg. "all posts tagged with `news`"
|
||||
- `author.hbs` - Used for author archives, eg. "all posts written by Jamie"
|
||||
- `tag.hbs` - Used for tag archives
|
||||
- `author.hbs` - Used for author archives
|
||||
|
||||
One neat trick is that you can also create custom one-off templates by adding the slug of a page to a template file. For example:
|
||||
One really neat trick is that you can also create custom one-off templates just by adding the slug of a page to a template file. For example:
|
||||
|
||||
- `page-about.hbs` - Custom template for an `/about/` page
|
||||
- `page-about.hbs` - Custom template for the `/about/` page
|
||||
- `tag-news.hbs` - Custom template for `/tag/news/` archive
|
||||
- `author-ali.hbs` - Custom template for `/author/ali/` archive
|
||||
|
||||
|
||||
# Development
|
||||
|
||||
Casper styles are compiled using Gulp/PostCSS to polyfill future CSS spec. You'll need [Node](https://nodejs.org/), [Yarn](https://yarnpkg.com/) and [Gulp](https://gulpjs.com) installed globally. After that, from the theme's root directory:
|
||||
Casper styles are compiled using Gulp/PostCSS to polyfill future CSS spec. You'll need Node and Gulp installed globally. After that, from the theme's root directory:
|
||||
|
||||
```bash
|
||||
# install dependencies
|
||||
yarn install
|
||||
`$ npm install`
|
||||
|
||||
# run development server
|
||||
yarn dev
|
||||
```
|
||||
`$ gulp`
|
||||
|
||||
Now you can edit `/assets/css/` files, which will be compiled to `/assets/built/` automatically.
|
||||
|
||||
The `zip` Gulp task packages the theme files into `dist/<theme-name>.zip`, which you can then upload to your site.
|
||||
|
||||
```bash
|
||||
# create .zip file
|
||||
yarn zip
|
||||
```
|
||||
|
||||
# PostCSS Features Used
|
||||
|
||||
- Autoprefixer - Don't worry about writing browser prefixes of any kind, it's all done automatically with support for the latest 2 major versions of every browser.
|
||||
- [Color Mod](https://github.com/jonathantneal/postcss-color-mod-function)
|
||||
- Variables - Simple pure CSS variables
|
||||
- [Color Function](https://github.com/postcss/postcss-color-function)
|
||||
|
||||
|
||||
# SVG Icons
|
||||
@ -66,4 +57,4 @@ You can add your own SVG icons in the same manner.
|
||||
|
||||
# Copyright & License
|
||||
|
||||
Copyright (c) 2013-2022 Ghost Foundation - Released under the [MIT license](LICENSE).
|
||||
Copyright (c) 2013-2017 Ghost Foundation - Released under the [MIT license](LICENSE).
|
||||
|
@ -1,2 +1,2 @@
|
||||
a,abbr,acronym,address,applet,article,aside,audio,big,blockquote,body,canvas,caption,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,ul,var,video{border:0;font:inherit;font-size:100%;margin:0;padding:0;vertical-align:baseline}body{line-height:1}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:"";content:none}img{display:block;height:auto;max-width:100%}html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;box-sizing:border-box;font-family:sans-serif}*,:after,:before{box-sizing:inherit}a{background-color:transparent}a:active,a:hover{outline:0}b,strong{font-weight:700}dfn,em,i{font-style:italic}h1{font-size:2em;margin:.67em 0}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}mark{background-color:#fdffb6}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}kbd{background:#f6f8fa;border:1px solid rgba(124,139,154,.25);border-radius:6px;box-shadow:inset 0 -1px 0 rgba(124,139,154,.25);font-family:var(--font-mono);font-size:1.5rem;padding:3px 5px}@media (max-width:600px){kbd{font-size:1.3rem}}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{border:none;overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input:focus{outline:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{border:0;padding:0}textarea{overflow:auto}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}html{-webkit-tap-highlight-color:rgba(0,0,0,0);font-size:62.5%}body{text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-moz-font-feature-settings:"liga" on;background:#fff;color:var(--color-darkgrey);font-family:var(--font-sans);font-size:1.6rem;font-style:normal;font-weight:400;letter-spacing:0;line-height:1.6em}::-moz-selection{background:#daf2fd;text-shadow:none}::selection{background:#daf2fd;text-shadow:none}hr{border:0;border-top:1px solid #f0f0f0;display:block;height:1px;margin:2.5em 0 3.5em;padding:0;position:relative;width:100%}audio,canvas,iframe,img,svg,video{vertical-align:middle}fieldset{border:0;margin:0;padding:0}textarea{resize:vertical}::not(.gh-content) blockquote,::not(.gh-content) dl,::not(.gh-content) ol,::not(.gh-content) p,::not(.gh-content) ul{margin:0 0 1.5em}ol,ul{padding-left:1.3em;padding-right:1.5em}ol ol,ol ul,ul ol,ul ul{margin:.5em 0}ol,ul{max-width:100%}li{line-height:1.6em;padding-left:.3em}li+li{margin-top:.5em}dt{color:#daf2fd;float:left;font-weight:500;margin:0 20px 0 0;text-align:right;width:120px}dd{margin:0 0 5px;text-align:left}blockquote{border-left:#daf2fd;margin:1.5em 0;padding:0 1.6em}blockquote small{display:inline-block;font-size:.9em;margin:.8em 0 .8em 1.5em;opacity:.8}blockquote small:before{content:"\2014 \00A0"}blockquote cite{font-weight:700}blockquote cite a{font-weight:400}a{color:#15171a;text-decoration:none}h1,h2,h3,h4,h5,h6{text-rendering:optimizeLegibility;font-weight:600;letter-spacing:-.01em;line-height:1.15;margin-top:0}h1{font-size:4.8rem;font-weight:700;letter-spacing:-.015em;margin:0 0 .5em}@media (max-width:600px){h1{font-size:2.8rem}}h2{font-size:2.8rem;font-weight:700;margin:1.5em 0 .5em}@media (max-width:600px){h2{font-size:2.3rem}}h3{font-size:2.4rem;font-weight:600;margin:1.5em 0 .5em}@media (max-width:600px){h3{font-size:1.7rem}}h4{font-size:2rem;margin:1.5em 0 .5em}@media (max-width:600px){h4{font-size:1.7rem}}h5{font-size:2rem}h5,h6{margin:1.5em 0 .5em}h6{font-size:1.8rem}
|
||||
/*# sourceMappingURL=global.css.map */
|
||||
a,abbr,acronym,address,applet,article,aside,audio,big,blockquote,body,canvas,caption,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,ul,var,video{margin:0;padding:0;border:0;font:inherit;font-size:100%;vertical-align:baseline}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:"";content:none}img{max-width:100%}html{box-sizing:border-box;font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}*,:after,:before{box-sizing:inherit}a{background-color:transparent}a:active,a:hover{outline:0}b,strong{font-weight:700}dfn,em,i{font-style:italic}h1{margin:.67em 0;font-size:2em}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}mark{background-color:#fdffb6}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;color:inherit;font:inherit}button{overflow:visible;border:none}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input:focus{outline:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{padding:0;border:0}textarea{overflow:auto}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}html{overflow-y:scroll;font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body,html{overflow-x:hidden}body{color:#3c484e;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif;font-size:1.5rem;line-height:1.6em;font-weight:400;font-style:normal;letter-spacing:0;text-rendering:optimizeLegibility;background:#fff;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-moz-font-feature-settings:"liga" on}::-moz-selection{text-shadow:none;background:#cbeafb}::selection{text-shadow:none;background:#cbeafb}hr{position:relative;display:block;width:100%;margin:2.5em 0 3.5em;padding:0;height:1px;border:0;border-top:1px solid #e3e9ed}audio,canvas,iframe,img,svg,video{vertical-align:middle}fieldset{margin:0;padding:0;border:0}textarea{resize:vertical}blockquote,dl,ol,p,ul{margin:0 0 1.5em}ol,ul{padding-left:1em;padding-right:1.5em}ol ol,ol ul,ul ol,ul ul{margin:.5em 0 1em}ul{list-style:disc}ol{list-style:decimal}li{margin:.5em 0;padding-left:.5em;line-height:1.6em}dt{float:left;margin:0 20px 0 0;width:120px;color:#15171a;font-weight:500;text-align:right}dd{margin:0 0 5px;text-align:left}blockquote{margin:1.5em 0;padding:0 1.6em;border-left:.5em solid #e5eff5}blockquote p{margin:.8em 0;font-size:1.2em;font-weight:300}blockquote small{display:inline-block;margin:.8em 0 .8em 1.5em;font-size:.9em;opacity:.8}blockquote small:before{content:"\2014 \00A0"}blockquote cite{font-weight:700}blockquote cite a{font-weight:400}a{color:#26a8ed;text-decoration:none}a:hover{text-decoration:underline}h1,h2,h3,h4,h5,h6{margin-top:0;line-height:1.15;font-weight:700;text-rendering:optimizeLegibility}h1{margin:0 0 .5em;font-size:5rem;font-weight:700}@media (max-width:500px){h1{font-size:2.2rem}}h2{margin:1.5em 0 .5em;font-size:2rem}@media (max-width:500px){h2{font-size:1.8rem}}h3{margin:1.5em 0 .5em;font-size:1.8rem;font-weight:500}@media (max-width:500px){h3{font-size:1.7rem}}h4{margin:1.5em 0 .5em;font-size:1.6rem;font-weight:500}h5,h6{margin:1.5em 0 .5em;font-size:1.4rem;font-weight:500}
|
||||
/*# sourceMappingURL=global.css.map */
|
||||
|
@ -1,2 +0,0 @@
|
||||
code[class*=language-],pre[class*=language-]{word-wrap:normal;background:none;color:#f8f8f2;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;text-align:left;text-shadow:0 1px rgba(0,0,0,.3);white-space:pre;word-break:normal;word-spacing:normal}pre[class*=language-]{border-radius:.3em;margin:.5em 0;overflow:auto;padding:1em}:not(pre)>code[class*=language-],pre[class*=language-]{background:#272822}:not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#f8f8f2}.namespace{opacity:.7}.token.constant,.token.deleted,.token.property,.token.symbol,.token.tag{color:#f92672}.token.boolean,.token.number{color:#ae81ff}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#a6e22e}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f8f8f2}.token.atrule,.token.attr-value,.token.function{color:#e6db74}.token.keyword{color:#66d9ef}.token.important,.token.regex{color:#fd971f}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}
|
||||
/*# sourceMappingURL=prism.css.map */
|
@ -1 +0,0 @@
|
||||
{"version":3,"sources":["prism.css"],"names":[],"mappings":"AAQA,6CAUC,gBAAiB,CAPjB,eAAgB,CADhB,aAAc,CAGd,6DAAsE,CAYtE,oBAAqB,CAGrB,YAAa,CATb,eAAgB,CAEhB,eAAgB,CAChB,aAAc,CACd,UAAW,CATX,eAAgB,CAFhB,gCAAqC,CAGrC,eAAgB,CAEhB,iBAAkB,CADlB,mBAaD,CAGA,sBAIC,kBAAoB,CAFpB,aAAc,CACd,aAAc,CAFd,WAID,CAEA,uDAEC,kBACD,CAGA,iCAEC,kBAAmB,CADnB,YAAa,CAEb,kBACD,CAEA,yDAIC,aACD,CAEA,mBACC,aACD,CAEA,WACC,UACD,CAEA,wEAKC,aACD,CAEA,6BAEC,aACD,CAEA,0FAMC,aACD,CAEA,0GAMC,aACD,CAEA,gDAGC,aACD,CAEA,eACC,aACD,CAEA,8BAEC,aACD,CAEA,6BAEC,eACD,CACA,cACC,iBACD,CAEA,cACC,WACD","file":"prism.css","sourcesContent":["/* PrismJS 1.12.2\nhttp://prismjs.com/download.html#themes=prism-okaidia&languages=markup+clike+javascript+c+bash+cpp+csharp+ruby+docker+go+json+makefile+markdown+properties+python+vim+yaml */\n/**\n * okaidia theme for JavaScript, CSS and HTML\n * Loosely based on Monokai textmate theme by http://www.monokai.nl/\n * @author ocodia\n */\n\ncode[class*=\"language-\"],\npre[class*=\"language-\"] {\n\tcolor: #f8f8f2;\n\tbackground: none;\n\ttext-shadow: 0 1px rgba(0, 0, 0, 0.3);\n\tfont-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;\n\ttext-align: left;\n\twhite-space: pre;\n\tword-spacing: normal;\n\tword-break: normal;\n\tword-wrap: normal;\n\tline-height: 1.5;\n\n\t-moz-tab-size: 4;\n\t-o-tab-size: 4;\n\ttab-size: 4;\n\n\t-webkit-hyphens: none;\n\t-moz-hyphens: none;\n\t-ms-hyphens: none;\n\thyphens: none;\n}\n\n/* Code blocks */\npre[class*=\"language-\"] {\n\tpadding: 1em;\n\tmargin: .5em 0;\n\toverflow: auto;\n\tborder-radius: 0.3em;\n}\n\n:not(pre) > code[class*=\"language-\"],\npre[class*=\"language-\"] {\n\tbackground: #272822;\n}\n\n/* Inline code */\n:not(pre) > code[class*=\"language-\"] {\n\tpadding: .1em;\n\tborder-radius: .3em;\n\twhite-space: normal;\n}\n\n.token.comment,\n.token.prolog,\n.token.doctype,\n.token.cdata {\n\tcolor: slategray;\n}\n\n.token.punctuation {\n\tcolor: #f8f8f2;\n}\n\n.namespace {\n\topacity: .7;\n}\n\n.token.property,\n.token.tag,\n.token.constant,\n.token.symbol,\n.token.deleted {\n\tcolor: #f92672;\n}\n\n.token.boolean,\n.token.number {\n\tcolor: #ae81ff;\n}\n\n.token.selector,\n.token.attr-name,\n.token.string,\n.token.char,\n.token.builtin,\n.token.inserted {\n\tcolor: #a6e22e;\n}\n\n.token.operator,\n.token.entity,\n.token.url,\n.language-css .token.string,\n.style .token.string,\n.token.variable {\n\tcolor: #f8f8f2;\n}\n\n.token.atrule,\n.token.attr-value,\n.token.function {\n\tcolor: #e6db74;\n}\n\n.token.keyword {\n\tcolor: #66d9ef;\n}\n\n.token.regex,\n.token.important {\n\tcolor: #fd971f;\n}\n\n.token.important,\n.token.bold {\n\tfont-weight: bold;\n}\n.token.italic {\n\tfont-style: italic;\n}\n\n.token.entity {\n\tcursor: help;\n}\n\n"]}
|
237
assets/css/.csscomb.json
Normal file
@ -0,0 +1,237 @@
|
||||
{
|
||||
"remove-empty-rulesets": true,
|
||||
"always-semicolon": true,
|
||||
"color-case": "lower",
|
||||
"block-indent": " ",
|
||||
"color-shorthand": true,
|
||||
"element-case": "lower",
|
||||
"eof-newline": true,
|
||||
"leading-zero": true,
|
||||
"quotes": "double",
|
||||
"space-before-colon": "",
|
||||
"space-after-colon": " ",
|
||||
"space-before-combinator": " ",
|
||||
"space-after-combinator": " ",
|
||||
"space-between-declarations": "\n",
|
||||
"space-before-opening-brace": " ",
|
||||
"space-after-opening-brace": "\n",
|
||||
"space-after-selector-delimiter": "\n",
|
||||
"space-before-selector-delimiter": "",
|
||||
"space-before-closing-brace": "\n",
|
||||
"strip-spaces": true,
|
||||
"tab-size": 4,
|
||||
"unitless-zero": true,
|
||||
"sort-order": [ [
|
||||
"content",
|
||||
"visibility",
|
||||
"position",
|
||||
"top",
|
||||
"right",
|
||||
"bottom",
|
||||
"left",
|
||||
"z-index",
|
||||
"order",
|
||||
"flex",
|
||||
"flex-grow",
|
||||
"flex-shrink",
|
||||
"flex-basis",
|
||||
"align-self",
|
||||
"display",
|
||||
"flex-flow",
|
||||
"flex-direction",
|
||||
"flex-wrap",
|
||||
"justify-content",
|
||||
"align-items",
|
||||
"align-content",
|
||||
"flex-order",
|
||||
"flex-pack",
|
||||
"flex-align",
|
||||
"float",
|
||||
"clear",
|
||||
"overflow",
|
||||
"overflow-x",
|
||||
"overflow-y",
|
||||
"-webkit-overflow-scrolling",
|
||||
"clip",
|
||||
"box-sizing",
|
||||
"margin",
|
||||
"margin-top",
|
||||
"margin-right",
|
||||
"margin-bottom",
|
||||
"margin-left",
|
||||
"padding",
|
||||
"padding-top",
|
||||
"padding-right",
|
||||
"padding-bottom",
|
||||
"padding-left",
|
||||
"min-width",
|
||||
"min-height",
|
||||
"max-width",
|
||||
"max-height",
|
||||
"width",
|
||||
"height",
|
||||
"outline",
|
||||
"outline-width",
|
||||
"outline-style",
|
||||
"outline-color",
|
||||
"outline-offset",
|
||||
"border",
|
||||
"border-spacing",
|
||||
"border-collapse",
|
||||
"border-width",
|
||||
"border-style",
|
||||
"border-color",
|
||||
"border-top",
|
||||
"border-top-width",
|
||||
"border-top-style",
|
||||
"border-top-color",
|
||||
"border-right",
|
||||
"border-right-width",
|
||||
"border-right-style",
|
||||
"border-right-color",
|
||||
"border-bottom",
|
||||
"border-bottom-width",
|
||||
"border-bottom-style",
|
||||
"border-bottom-color",
|
||||
"border-left",
|
||||
"border-left-width",
|
||||
"border-left-style",
|
||||
"border-left-color",
|
||||
"border-image",
|
||||
"border-image-source",
|
||||
"border-image-slice",
|
||||
"border-image-width",
|
||||
"border-image-outset",
|
||||
"border-image-repeat",
|
||||
"border-top-image",
|
||||
"border-right-image",
|
||||
"border-bottom-image",
|
||||
"border-left-image",
|
||||
"border-corner-image",
|
||||
"border-top-left-image",
|
||||
"border-top-right-image",
|
||||
"border-bottom-right-image",
|
||||
"border-bottom-left-image",
|
||||
"color",
|
||||
"font",
|
||||
"font-family",
|
||||
"font-size",
|
||||
"line-height",
|
||||
"font-weight",
|
||||
"font-style",
|
||||
"font-variant",
|
||||
"font-size-adjust",
|
||||
"font-stretch",
|
||||
"font-feature-settings",
|
||||
"letter-spacing",
|
||||
"text-rendering",
|
||||
"text-align",
|
||||
"text-align-last",
|
||||
"text-decoration",
|
||||
"text-emphasis",
|
||||
"text-emphasis-position",
|
||||
"text-emphasis-style",
|
||||
"text-emphasis-color",
|
||||
"text-indent",
|
||||
"text-justify",
|
||||
"text-outline",
|
||||
"text-transform",
|
||||
"text-wrap",
|
||||
"text-overflow",
|
||||
"text-overflow-ellipsis",
|
||||
"text-overflow-mode",
|
||||
"text-shadow",
|
||||
"white-space",
|
||||
"word-spacing",
|
||||
"word-wrap",
|
||||
"word-break",
|
||||
"tab-size",
|
||||
"hyphens",
|
||||
"user-select",
|
||||
"fill",
|
||||
"stroke",
|
||||
"background",
|
||||
"filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
|
||||
"background-color",
|
||||
"background-image",
|
||||
"background-attachment",
|
||||
"background-position",
|
||||
"background-position-x",
|
||||
"background-position-y",
|
||||
"background-clip",
|
||||
"background-origin",
|
||||
"background-size",
|
||||
"background-repeat",
|
||||
"border-radius",
|
||||
"border-top-left-radius",
|
||||
"border-top-right-radius",
|
||||
"border-bottom-right-radius",
|
||||
"border-bottom-left-radius",
|
||||
"box-decoration-break",
|
||||
"box-shadow",
|
||||
"table-layout",
|
||||
"caption-side",
|
||||
"empty-cells",
|
||||
"list-style",
|
||||
"list-style-position",
|
||||
"list-style-type",
|
||||
"list-style-image",
|
||||
"quotes",
|
||||
"counter-increment",
|
||||
"counter-reset",
|
||||
"vertical-align",
|
||||
"src",
|
||||
"opacity",
|
||||
"filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
|
||||
"filter",
|
||||
"resize",
|
||||
"cursor",
|
||||
"nav-index",
|
||||
"nav-up",
|
||||
"nav-right",
|
||||
"nav-down",
|
||||
"nav-left",
|
||||
"transition",
|
||||
"transition-delay",
|
||||
"transition-timing-function",
|
||||
"transition-duration",
|
||||
"transition-property",
|
||||
"transform",
|
||||
"transform-origin",
|
||||
"animation",
|
||||
"animation-name",
|
||||
"animation-duration",
|
||||
"animation-play-state",
|
||||
"animation-timing-function",
|
||||
"animation-delay",
|
||||
"animation-iteration-count",
|
||||
"animation-direction",
|
||||
"animation-fill-mode",
|
||||
"pointer-events",
|
||||
"unicode-bidi",
|
||||
"direction",
|
||||
"columns",
|
||||
"column-span",
|
||||
"column-width",
|
||||
"column-count",
|
||||
"column-fill",
|
||||
"column-gap",
|
||||
"column-rule",
|
||||
"column-rule-width",
|
||||
"column-rule-style",
|
||||
"column-rule-color",
|
||||
"break-before",
|
||||
"break-inside",
|
||||
"break-after",
|
||||
"page-break-before",
|
||||
"page-break-inside",
|
||||
"page-break-after",
|
||||
"orphans",
|
||||
"widows",
|
||||
"zoom",
|
||||
"max-zoom",
|
||||
"min-zoom",
|
||||
"user-zoom",
|
||||
"orientation"
|
||||
] ]
|
||||
}
|
240
assets/css/csscomb.json
Normal file
@ -0,0 +1,240 @@
|
||||
{
|
||||
"remove-empty-rulesets": true,
|
||||
"always-semicolon": true,
|
||||
"color-case": "lower",
|
||||
"block-indent": " ",
|
||||
"color-shorthand": true,
|
||||
"element-case": "lower",
|
||||
"eof-newline": true,
|
||||
"leading-zero": true,
|
||||
"quotes": "double",
|
||||
"space-before-colon": "",
|
||||
"space-after-colon": " ",
|
||||
"space-before-combinator": " ",
|
||||
"space-after-combinator": " ",
|
||||
"space-between-declarations": "\n",
|
||||
"space-before-opening-brace": " ",
|
||||
"space-after-opening-brace": "\n",
|
||||
"space-after-selector-delimiter": "\n",
|
||||
"space-before-selector-delimiter": "",
|
||||
"space-before-closing-brace": "\n",
|
||||
"strip-spaces": true,
|
||||
"tab-size": 4,
|
||||
"unitless-zero": true,
|
||||
"sort-order": [ [
|
||||
"content",
|
||||
"visibility",
|
||||
"position",
|
||||
"top",
|
||||
"right",
|
||||
"bottom",
|
||||
"left",
|
||||
"z-index",
|
||||
"order",
|
||||
"flex",
|
||||
"flex-grow",
|
||||
"flex-shrink",
|
||||
"flex-basis",
|
||||
"align-self",
|
||||
"display",
|
||||
"flex-flow",
|
||||
"flex-direction",
|
||||
"justify-content",
|
||||
"align-items",
|
||||
"align-content",
|
||||
"flex-wrap",
|
||||
"flex-order",
|
||||
"flex-pack",
|
||||
"flex-align",
|
||||
"float",
|
||||
"clear",
|
||||
"box-sizing",
|
||||
"width",
|
||||
"height",
|
||||
"min-width",
|
||||
"min-height",
|
||||
"max-width",
|
||||
"max-height",
|
||||
"overflow",
|
||||
"overflow-x",
|
||||
"overflow-y",
|
||||
"clip",
|
||||
"margin",
|
||||
"margin-top",
|
||||
"margin-right",
|
||||
"margin-bottom",
|
||||
"margin-left",
|
||||
"padding",
|
||||
"padding-top",
|
||||
"padding-right",
|
||||
"padding-bottom",
|
||||
"padding-left",
|
||||
"outline",
|
||||
"outline-width",
|
||||
"outline-style",
|
||||
"outline-color",
|
||||
"outline-offset",
|
||||
"border",
|
||||
"border-spacing",
|
||||
"border-collapse",
|
||||
"border-width",
|
||||
"border-style",
|
||||
"border-color",
|
||||
"border-top",
|
||||
"border-top-width",
|
||||
"border-top-style",
|
||||
"border-top-color",
|
||||
"border-right",
|
||||
"border-right-width",
|
||||
"border-right-style",
|
||||
"border-right-color",
|
||||
"border-bottom",
|
||||
"border-bottom-width",
|
||||
"border-bottom-style",
|
||||
"border-bottom-color",
|
||||
"border-left",
|
||||
"border-left-width",
|
||||
"border-left-style",
|
||||
"border-left-color",
|
||||
"border-image",
|
||||
"border-image-source",
|
||||
"border-image-slice",
|
||||
"border-image-width",
|
||||
"border-image-outset",
|
||||
"border-image-repeat",
|
||||
"border-top-image",
|
||||
"border-right-image",
|
||||
"border-bottom-image",
|
||||
"border-left-image",
|
||||
"border-corner-image",
|
||||
"border-top-left-image",
|
||||
"border-top-right-image",
|
||||
"border-bottom-right-image",
|
||||
"border-bottom-left-image",
|
||||
"table-layout",
|
||||
"caption-side",
|
||||
"empty-cells",
|
||||
"list-style",
|
||||
"list-style-position",
|
||||
"list-style-type",
|
||||
"list-style-image",
|
||||
"quotes",
|
||||
"counter-increment",
|
||||
"counter-reset",
|
||||
"vertical-align",
|
||||
"stroke",
|
||||
"fill",
|
||||
"stroke-width",
|
||||
"stroke-opacity",
|
||||
"color",
|
||||
"font",
|
||||
"font-family",
|
||||
"font-size",
|
||||
"line-height",
|
||||
"font-weight",
|
||||
"font-style",
|
||||
"font-variant",
|
||||
"font-size-adjust",
|
||||
"font-stretch",
|
||||
"text-rendering",
|
||||
"font-feature-settings",
|
||||
"letter-spacing",
|
||||
"hyphens",
|
||||
"text-align",
|
||||
"text-align-last",
|
||||
"text-decoration",
|
||||
"text-emphasis",
|
||||
"text-emphasis-position",
|
||||
"text-emphasis-style",
|
||||
"text-emphasis-color",
|
||||
"text-indent",
|
||||
"text-justify",
|
||||
"text-outline",
|
||||
"text-transform",
|
||||
"text-wrap",
|
||||
"text-overflow",
|
||||
"text-overflow-ellipsis",
|
||||
"text-overflow-mode",
|
||||
"text-shadow",
|
||||
"white-space",
|
||||
"word-spacing",
|
||||
"word-wrap",
|
||||
"word-break",
|
||||
"tab-size",
|
||||
"user-select",
|
||||
"src",
|
||||
"resize",
|
||||
"cursor",
|
||||
"nav-index",
|
||||
"nav-up",
|
||||
"nav-right",
|
||||
"nav-down",
|
||||
"nav-left",
|
||||
"background",
|
||||
"filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
|
||||
"background-color",
|
||||
"background-image",
|
||||
"background-size",
|
||||
"background-attachment",
|
||||
"background-position",
|
||||
"background-position-x",
|
||||
"background-position-y",
|
||||
"background-clip",
|
||||
"background-origin",
|
||||
"background-repeat",
|
||||
"border-radius",
|
||||
"border-top-left-radius",
|
||||
"border-top-right-radius",
|
||||
"border-bottom-right-radius",
|
||||
"border-bottom-left-radius",
|
||||
"box-decoration-break",
|
||||
"box-shadow",
|
||||
"opacity",
|
||||
"filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
|
||||
"filter",
|
||||
"transition",
|
||||
"transition-delay",
|
||||
"transition-timing-function",
|
||||
"transition-duration",
|
||||
"transition-property",
|
||||
"transform",
|
||||
"transform-origin",
|
||||
"animation",
|
||||
"animation-name",
|
||||
"animation-duration",
|
||||
"animation-play-state",
|
||||
"animation-timing-function",
|
||||
"animation-delay",
|
||||
"animation-iteration-count",
|
||||
"animation-direction",
|
||||
"animation-fill-mode",
|
||||
"pointer-events",
|
||||
"unicode-bidi",
|
||||
"direction",
|
||||
"columns",
|
||||
"column-span",
|
||||
"column-width",
|
||||
"column-count",
|
||||
"column-fill",
|
||||
"column-gap",
|
||||
"column-rule",
|
||||
"column-rule-width",
|
||||
"column-rule-style",
|
||||
"column-rule-color",
|
||||
"break-before",
|
||||
"break-inside",
|
||||
"break-after",
|
||||
"page-break-before",
|
||||
"page-break-inside",
|
||||
"page-break-after",
|
||||
"orphans",
|
||||
"widows",
|
||||
"zoom",
|
||||
"max-zoom",
|
||||
"min-zoom",
|
||||
"user-zoom",
|
||||
"orientation",
|
||||
"-webkit-overflow-scrolling",
|
||||
"-ms-overflow-scrolling"
|
||||
] ]
|
||||
}
|
@ -1,3 +1,21 @@
|
||||
/* Variables
|
||||
/* ---------------------------------------------------------- */
|
||||
|
||||
:root {
|
||||
/* Colours */
|
||||
--blue: #3eb0ef;
|
||||
--green: #a4d037;
|
||||
--purple: #ad26b4;
|
||||
--yellow: #fecd35;
|
||||
--red: #f05230;
|
||||
--darkgrey: #15171A;
|
||||
--midgrey: #738a94;
|
||||
--lightgrey: #c5d2d9;
|
||||
--whitegrey: #e5eff5;
|
||||
--pink: #fa3a57;
|
||||
--brown: #a3821a;
|
||||
}
|
||||
|
||||
/* Reset
|
||||
/* ---------------------------------------------------------- */
|
||||
|
||||
@ -88,6 +106,10 @@ video {
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
ol,
|
||||
ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote,
|
||||
q {
|
||||
quotes: none;
|
||||
@ -104,9 +126,7 @@ table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
@ -172,20 +192,6 @@ samp {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
kbd {
|
||||
padding: 3px 5px;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 1.5rem;
|
||||
background: #f6f8fa;
|
||||
border: 1px solid rgba(124, 139, 154, 0.25);
|
||||
border-radius: 6px;
|
||||
box-shadow: inset 0 -1px 0 rgba(124, 139, 154, 0.25);
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
kbd {
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
}
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
@ -261,19 +267,23 @@ th {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
/* ==========================================================================
|
||||
Base styles: opinionated defaults
|
||||
========================================================================== */
|
||||
|
||||
html {
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
font-size: 62.5%;
|
||||
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
body {
|
||||
color: var(--color-darkgrey);
|
||||
font-family: var(--font-sans);
|
||||
font-size: 1.6rem;
|
||||
overflow-x: hidden;
|
||||
color: color(var(--midgrey) l(-25%));
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
|
||||
font-size: 1.5rem;
|
||||
line-height: 1.6em;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
@ -288,7 +298,7 @@ body {
|
||||
|
||||
::selection {
|
||||
text-shadow: none;
|
||||
background: #daf2fd;
|
||||
background: color(var(--blue) lightness(+30%));
|
||||
}
|
||||
|
||||
hr {
|
||||
@ -299,7 +309,7 @@ hr {
|
||||
padding: 0;
|
||||
height: 1px;
|
||||
border: 0;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
border-top: 1px solid color(var(--lightgrey) l(+10%));
|
||||
}
|
||||
|
||||
audio,
|
||||
@ -321,17 +331,17 @@ textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
::not(.gh-content) p,
|
||||
::not(.gh-content) ul,
|
||||
::not(.gh-content) ol,
|
||||
::not(.gh-content) dl,
|
||||
::not(.gh-content) blockquote {
|
||||
p,
|
||||
ul,
|
||||
ol,
|
||||
dl,
|
||||
blockquote {
|
||||
margin: 0 0 1.5em 0;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
padding-left: 1.3em;
|
||||
padding-left: 1em;
|
||||
padding-right: 1.5em;
|
||||
}
|
||||
|
||||
@ -339,28 +349,28 @@ ol ol,
|
||||
ul ul,
|
||||
ul ol,
|
||||
ol ul {
|
||||
margin: 0.5em 0;
|
||||
margin: 0.5em 0 1em;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: disc;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
max-width: 100%;
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
li {
|
||||
padding-left: 0.3em;
|
||||
margin: 0.5em 0;
|
||||
padding-left: 0.5em;
|
||||
line-height: 1.6em;
|
||||
}
|
||||
|
||||
li + li {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
dt {
|
||||
float: left;
|
||||
margin: 0 20px 0 0;
|
||||
width: 120px;
|
||||
color: #daf2fd;
|
||||
color: var(--darkgrey);
|
||||
font-weight: 500;
|
||||
text-align: right;
|
||||
}
|
||||
@ -373,7 +383,13 @@ dd {
|
||||
blockquote {
|
||||
margin: 1.5em 0;
|
||||
padding: 0 1.6em 0 1.6em;
|
||||
border-left: #daf2fd;
|
||||
border-left: var(--whitegrey) 0.5em solid;;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
margin: 0.8em 0;
|
||||
font-size: 1.2em;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
blockquote small {
|
||||
@ -395,10 +411,14 @@ blockquote cite a {
|
||||
}
|
||||
|
||||
a {
|
||||
color: #15171A;
|
||||
color: color(var(--blue) l(-5%));
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
@ -407,40 +427,37 @@ h5,
|
||||
h6 {
|
||||
margin-top: 0;
|
||||
line-height: 1.15;
|
||||
font-weight: 600;
|
||||
font-weight: 700;
|
||||
text-rendering: optimizeLegibility;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0 0 0.5em 0;
|
||||
font-size: 4.8rem;
|
||||
font-size: 5rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.015em;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
@media (max-width: 500px) {
|
||||
h1 {
|
||||
font-size: 2.8rem;
|
||||
font-size: 2.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 1.5em 0 0.5em 0;
|
||||
font-size: 2.8rem;
|
||||
font-weight: 700;
|
||||
font-size: 2rem;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
@media (max-width: 500px) {
|
||||
h2 {
|
||||
font-size: 2.3rem;
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 1.5em 0 0.5em 0;
|
||||
font-size: 2.4rem;
|
||||
font-weight: 600;
|
||||
font-size: 1.8rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
@media (max-width: 500px) {
|
||||
h3 {
|
||||
font-size: 1.7rem;
|
||||
}
|
||||
@ -448,20 +465,18 @@ h3 {
|
||||
|
||||
h4 {
|
||||
margin: 1.5em 0 0.5em 0;
|
||||
font-size: 2rem;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
h4 {
|
||||
font-size: 1.7rem;
|
||||
}
|
||||
font-size: 1.6rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
h5 {
|
||||
margin: 1.5em 0 0.5em 0;
|
||||
font-size: 2rem;
|
||||
font-size: 1.4rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
h6 {
|
||||
margin: 1.5em 0 0.5em 0;
|
||||
font-size: 1.8rem;
|
||||
font-size: 1.4rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
@ -1,124 +0,0 @@
|
||||
/* PrismJS 1.12.2
|
||||
http://prismjs.com/download.html#themes=prism-okaidia&languages=markup+clike+javascript+c+bash+cpp+csharp+ruby+docker+go+json+makefile+markdown+properties+python+vim+yaml */
|
||||
/**
|
||||
* okaidia theme for JavaScript, CSS and HTML
|
||||
* Loosely based on Monokai textmate theme by http://www.monokai.nl/
|
||||
* @author ocodia
|
||||
*/
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: #f8f8f2;
|
||||
background: none;
|
||||
text-shadow: 0 1px rgba(0, 0, 0, 0.3);
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
line-height: 1.5;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
:not(pre) > code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #272822;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #f92672;
|
||||
}
|
||||
|
||||
.token.boolean,
|
||||
.token.number {
|
||||
color: #ae81ff;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #a6e22e;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string,
|
||||
.token.variable {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.function {
|
||||
color: #e6db74;
|
||||
}
|
||||
|
||||
.token.keyword {
|
||||
color: #66d9ef;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important {
|
||||
color: #fd971f;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
|
@ -1,85 +0,0 @@
|
||||
(function () {
|
||||
const mediaQuery = window.matchMedia('(max-width: 767px)');
|
||||
|
||||
const head = document.querySelector('.gh-head');
|
||||
const menu = head.querySelector('.gh-head-menu');
|
||||
const nav = menu.querySelector('.nav');
|
||||
if (!nav) return;
|
||||
|
||||
const logo = document.querySelector('.gh-head-logo');
|
||||
const navHTML = nav.innerHTML;
|
||||
|
||||
if (mediaQuery.matches) {
|
||||
const items = nav.querySelectorAll('li');
|
||||
items.forEach(function (item, index) {
|
||||
item.style.transitionDelay = 0.03 * (index + 1) + 's';
|
||||
});
|
||||
}
|
||||
|
||||
var windowClickListener;
|
||||
const makeDropdown = function () {
|
||||
if (mediaQuery.matches) return;
|
||||
const submenuItems = [];
|
||||
|
||||
while ((nav.offsetWidth + 64) > menu.offsetWidth) {
|
||||
if (nav.lastElementChild) {
|
||||
submenuItems.unshift(nav.lastElementChild);
|
||||
nav.lastElementChild.remove();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!submenuItems.length) {
|
||||
document.body.classList.add('is-dropdown-loaded');
|
||||
return;
|
||||
}
|
||||
|
||||
const toggle = document.createElement('button');
|
||||
toggle.setAttribute('class', 'nav-more-toggle');
|
||||
toggle.setAttribute('aria-label', 'More');
|
||||
toggle.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="currentColor"><path d="M21.333 16c0-1.473 1.194-2.667 2.667-2.667v0c1.473 0 2.667 1.194 2.667 2.667v0c0 1.473-1.194 2.667-2.667 2.667v0c-1.473 0-2.667-1.194-2.667-2.667v0zM13.333 16c0-1.473 1.194-2.667 2.667-2.667v0c1.473 0 2.667 1.194 2.667 2.667v0c0 1.473-1.194 2.667-2.667 2.667v0c-1.473 0-2.667-1.194-2.667-2.667v0zM5.333 16c0-1.473 1.194-2.667 2.667-2.667v0c1.473 0 2.667 1.194 2.667 2.667v0c0 1.473-1.194 2.667-2.667 2.667v0c-1.473 0-2.667-1.194-2.667-2.667v0z"></path></svg>';
|
||||
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.setAttribute('class', 'gh-dropdown');
|
||||
|
||||
if (submenuItems.length >= 10) {
|
||||
document.body.classList.add('is-dropdown-mega');
|
||||
wrapper.style.gridTemplateRows = 'repeat(' + Math.ceil(submenuItems.length / 2) + ', 1fr)';
|
||||
} else {
|
||||
document.body.classList.remove('is-dropdown-mega');
|
||||
}
|
||||
|
||||
submenuItems.forEach(function (child) {
|
||||
wrapper.appendChild(child);
|
||||
});
|
||||
|
||||
toggle.appendChild(wrapper);
|
||||
nav.appendChild(toggle);
|
||||
|
||||
document.body.classList.add('is-dropdown-loaded');
|
||||
|
||||
toggle.addEventListener('click', function () {
|
||||
document.body.classList.toggle('is-dropdown-open');
|
||||
});
|
||||
|
||||
windowClickListener = function (e) {
|
||||
if (!toggle.contains(e.target) && document.body.classList.contains('is-dropdown-open')) {
|
||||
document.body.classList.remove('is-dropdown-open');
|
||||
}
|
||||
};
|
||||
window.addEventListener('click', windowClickListener);
|
||||
}
|
||||
|
||||
imagesLoaded(head, function () {
|
||||
makeDropdown();
|
||||
});
|
||||
|
||||
window.addEventListener('resize', function () {
|
||||
setTimeout(function () {
|
||||
window.removeEventListener('click', windowClickListener);
|
||||
nav.innerHTML = navHTML;
|
||||
makeDropdown();
|
||||
}, 1);
|
||||
});
|
||||
})();
|
@ -1,114 +0,0 @@
|
||||
/* eslint-env browser */
|
||||
|
||||
/**
|
||||
* Infinite Scroll
|
||||
* Used on all pages where there is a list of posts (homepage, tag index, etc).
|
||||
*
|
||||
* When the page is scrolled to 300px from the bottom, the next page of posts
|
||||
* is fetched by following the the <link rel="next" href="..."> that is output
|
||||
* by {{ghost_head}}.
|
||||
*
|
||||
* The individual post items are extracted from the fetched pages by looking for
|
||||
* a wrapper element with the class "post-card". Any found elements are appended
|
||||
* to the element with the class "post-feed" in the currently viewed page.
|
||||
*/
|
||||
|
||||
(function (window, document) {
|
||||
if (document.documentElement.classList.contains('no-infinite-scroll')) return;
|
||||
|
||||
// next link element
|
||||
var nextElement = document.querySelector('link[rel=next]');
|
||||
if (!nextElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
// post feed element
|
||||
var feedElement = document.querySelector('.post-feed');
|
||||
if (!feedElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
var buffer = 300;
|
||||
|
||||
var ticking = false;
|
||||
var loading = false;
|
||||
|
||||
var lastScrollY = window.scrollY;
|
||||
var lastWindowHeight = window.innerHeight;
|
||||
var lastDocumentHeight = document.documentElement.scrollHeight;
|
||||
|
||||
function onPageLoad() {
|
||||
if (this.status === 404) {
|
||||
window.removeEventListener('scroll', onScroll);
|
||||
window.removeEventListener('resize', onResize);
|
||||
return;
|
||||
}
|
||||
|
||||
// append contents
|
||||
var postElements = this.response.querySelectorAll('article.post-card');
|
||||
postElements.forEach(function (item) {
|
||||
// document.importNode is important, without it the item's owner
|
||||
// document will be different which can break resizing of
|
||||
// `object-fit: cover` images in Safari
|
||||
feedElement.appendChild(document.importNode(item, true));
|
||||
});
|
||||
|
||||
// set next link
|
||||
var resNextElement = this.response.querySelector('link[rel=next]');
|
||||
if (resNextElement) {
|
||||
nextElement.href = resNextElement.href;
|
||||
} else {
|
||||
window.removeEventListener('scroll', onScroll);
|
||||
window.removeEventListener('resize', onResize);
|
||||
}
|
||||
|
||||
// sync status
|
||||
lastDocumentHeight = document.documentElement.scrollHeight;
|
||||
ticking = false;
|
||||
loading = false;
|
||||
}
|
||||
|
||||
function onUpdate() {
|
||||
// return if already loading
|
||||
if (loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
// return if not scroll to the bottom
|
||||
if (lastScrollY + lastWindowHeight <= lastDocumentHeight - buffer) {
|
||||
ticking = false;
|
||||
return;
|
||||
}
|
||||
|
||||
loading = true;
|
||||
|
||||
var xhr = new window.XMLHttpRequest();
|
||||
xhr.responseType = 'document';
|
||||
|
||||
xhr.addEventListener('load', onPageLoad);
|
||||
|
||||
xhr.open('GET', nextElement.href);
|
||||
xhr.send(null);
|
||||
}
|
||||
|
||||
function requestTick() {
|
||||
ticking || window.requestAnimationFrame(onUpdate);
|
||||
ticking = true;
|
||||
}
|
||||
|
||||
function onScroll() {
|
||||
lastScrollY = window.scrollY;
|
||||
requestTick();
|
||||
}
|
||||
|
||||
function onResize() {
|
||||
lastWindowHeight = window.innerHeight;
|
||||
lastDocumentHeight = document.documentElement.scrollHeight;
|
||||
requestTick();
|
||||
}
|
||||
|
||||
window.addEventListener('scroll', onScroll, {passive: true});
|
||||
window.addEventListener('resize', onResize);
|
||||
|
||||
requestTick();
|
||||
})(window, document);
|
83
assets/js/infinitescroll.js
Normal file
@ -0,0 +1,83 @@
|
||||
// Code snippet inspired by https://github.com/douglasrodrigues5/ghost-blog-infinite-scroll
|
||||
$(function ($) {
|
||||
var currentPage = 1;
|
||||
var pathname = window.location.pathname;
|
||||
var $document = $(document);
|
||||
var $result = $('.post-feed');
|
||||
var buffer = 100;
|
||||
|
||||
var ticking = false;
|
||||
var isLoading = false;
|
||||
|
||||
var lastScrollY = window.scrollY;
|
||||
var lastWindowHeight = window.innerHeight;
|
||||
var lastDocumentHeight = $document.height();
|
||||
|
||||
// remove hash params from pathname
|
||||
pathname = pathname.replace(/#(.*)$/g, '').replace('/\//g', '/');
|
||||
|
||||
function onScroll() {
|
||||
lastScrollY = window.scrollY;
|
||||
requestTick();
|
||||
}
|
||||
|
||||
function onResize() {
|
||||
lastWindowHeight = window.innerHeight;
|
||||
lastDocumentHeight = $document.height();
|
||||
requestTick();
|
||||
}
|
||||
|
||||
function requestTick() {
|
||||
if (!ticking) {
|
||||
requestAnimationFrame(infiniteScroll)
|
||||
}
|
||||
ticking = true;
|
||||
}
|
||||
|
||||
function infiniteScroll () {
|
||||
// return if already loading
|
||||
if (isLoading) {
|
||||
return;
|
||||
}
|
||||
|
||||
// return if not scroll to the bottom
|
||||
if (lastScrollY + lastWindowHeight <= lastDocumentHeight - buffer) {
|
||||
ticking = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// return if currentPage is the last page already
|
||||
if (currentPage === maxPages) {
|
||||
return;
|
||||
}
|
||||
|
||||
isLoading = true;
|
||||
|
||||
// next page
|
||||
currentPage++;
|
||||
|
||||
// Load more
|
||||
var nextPage = pathname + 'page/' + currentPage + '/';
|
||||
|
||||
$.get(nextPage, function (content) {
|
||||
$result.append($(content).find('.post').hide().fadeIn(100));
|
||||
|
||||
}).fail(function (xhr) {
|
||||
// 404 indicates we've run out of pages
|
||||
if (xhr.status === 404) {
|
||||
window.removeEventListener('scroll', onScroll, {passive: true});
|
||||
window.removeEventListener('resize', onResize);
|
||||
}
|
||||
|
||||
}).always(function () {
|
||||
lastDocumentHeight = $document.height();
|
||||
isLoading = false;
|
||||
ticking = false;
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('scroll', onScroll, {passive: true});
|
||||
window.addEventListener('resize', onResize);
|
||||
|
||||
infiniteScroll();
|
||||
});
|
7
assets/js/lib/imagesloaded.pkgd.min.js
vendored
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 102 KiB |
106
author.hbs
@ -1,76 +1,54 @@
|
||||
{{!< default}}
|
||||
{{!-- The tag above means - insert everything in this file into the {body} of the default.hbs template --}}
|
||||
|
||||
<main id="site-main" class="site-main outer">
|
||||
<div class="inner posts">
|
||||
|
||||
<div class="post-feed">
|
||||
|
||||
{{#author}}
|
||||
<section class="post-card post-card-large">
|
||||
|
||||
{{#if cover_image}}
|
||||
<div class="post-card-image-link">
|
||||
{{!-- This is a responsive image, it loads different sizes depending on device
|
||||
https://medium.freecodecamp.org/a-guide-to-responsive-images-with-ready-to-use-templates-c400bd65c433 --}}
|
||||
<img class="post-card-image"
|
||||
srcset="{{img_url cover_image size="s"}} 300w,
|
||||
{{img_url cover_image size="m"}} 600w,
|
||||
{{img_url cover_image size="l"}} 1000w,
|
||||
{{img_url cover_image size="xl"}} 2000w"
|
||||
sizes="(max-width: 1000px) 400px, 800px"
|
||||
src="{{img_url cover_image size="m"}}"
|
||||
alt="{{title}}"
|
||||
/>
|
||||
</div>
|
||||
{{#author}}
|
||||
{{!-- Everything inside the #author tags pulls data from the author --}}
|
||||
<header class="site-header outer {{#if cover_image}}" style="background-image: url({{cover_image}}){{else}}no-cover{{/if}}">
|
||||
<div class="inner">
|
||||
{{> "site-nav"}}
|
||||
<div class="site-header-content">
|
||||
{{#if profile_image}}
|
||||
<img class="author-profile-image" src="{{profile_image}}" alt="{{name}}" />
|
||||
{{/if}}
|
||||
|
||||
<div class="post-card-content">
|
||||
<div class="post-card-content-link">
|
||||
|
||||
{{#if profile_image}}
|
||||
<img class="author-profile-pic" src="{{profile_image}}" alt="{{name}}" />
|
||||
<h1 class="site-title">{{name}}</h1>
|
||||
{{#if bio}}
|
||||
<h2 class="author-bio">{{bio}}</h2>
|
||||
{{/if}}
|
||||
<div class="author-meta">
|
||||
{{#if location}}
|
||||
<div class="author-location">{{location}} <span class="bull">•</span></div>
|
||||
{{/if}}
|
||||
|
||||
<header class="post-card-header">
|
||||
<h2 class="post-card-title">{{name}}</h2>
|
||||
</header>
|
||||
|
||||
{{#if bio}}
|
||||
<div class="post-card-excerpt">{{bio}}</div>
|
||||
<div class="author-stats">
|
||||
{{plural ../pagination.total empty='No posts' singular='% post' plural='% posts'}} <span class="bull">•</span>
|
||||
</div>
|
||||
{{#if website}}
|
||||
<a class="social-link social-link-wb" href="{{website}}" target="_blank">{{> "icons/website"}}</a>
|
||||
{{/if}}
|
||||
|
||||
<footer class="author-profile-footer">
|
||||
{{#if location}}
|
||||
<div class="author-profile-location">{{location}}</div>
|
||||
{{/if}}
|
||||
<div class="author-profile-meta">
|
||||
{{#if website}}
|
||||
<a class="author-profile-social-link" href="{{website}}" target="_blank" rel="noopener">{{website}}</a>
|
||||
{{/if}}
|
||||
{{#if twitter}}
|
||||
<a class="author-profile-social-link" href="{{twitter_url}}" target="_blank" rel="noopener">{{> "icons/twitter"}}</a>
|
||||
{{/if}}
|
||||
{{#if facebook}}
|
||||
<a class="author-profile-social-link" href="{{facebook_url}}" target="_blank" rel="noopener">{{> "icons/facebook"}}</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
{{#if twitter}}
|
||||
<a class="social-link social-link-tw" href="{{twitter_url}}" target="_blank">{{> "icons/twitter"}}</a>
|
||||
{{/if}}
|
||||
{{#if facebook}}
|
||||
<a class="social-link social-link-fb" href="{{facebook_url}}" target="_blank">{{> "icons/facebook"}}</a>
|
||||
{{/if}}
|
||||
<a class="social-link social-link-rss" href="http://cloud.feedly.com/#subscription/feed/{{url absolute="true"}}/rss/" target="_blank">{{> "icons/rss"}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
{{/author}}
|
||||
|
||||
</section>
|
||||
{{/author}}
|
||||
{{!-- The main content area --}}
|
||||
<main id="site-main" class="site-main outer" role="main">
|
||||
<div class="inner">
|
||||
|
||||
{{#foreach posts}}
|
||||
{{!-- The tag below includes the markup for each post - partials/post-card.hbs --}}
|
||||
{{> "post-card"}}
|
||||
{{/foreach}}
|
||||
<div class="post-feed">
|
||||
{{#foreach posts}}
|
||||
|
||||
{{!-- The tag below includes the markup for each post - partials/post-card.hbs --}}
|
||||
{{> "post-card"}}
|
||||
|
||||
{{/foreach}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{pagination}}
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
151
default.hbs
@ -1,127 +1,80 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{@site.locale}}"{{#match @custom.color_scheme "Dark"}} class="dark-mode"{{else match @custom.color_scheme "Auto"}} class="auto-color"{{/match}}>
|
||||
<html>
|
||||
<head>
|
||||
|
||||
{{!-- Basic meta - advanced meta is output with {ghost_head} below --}}
|
||||
<title>{{meta_title}}</title>
|
||||
{{!-- Document Settings --}}
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
||||
{{!-- Base Meta --}}
|
||||
<title>
|
||||
{{#is "post, page"}}
|
||||
{{meta_title}} - {{@site.title}}
|
||||
{{else}}
|
||||
{{meta_title}}
|
||||
{{/is}}
|
||||
</title>
|
||||
<title>{{meta_title}}</title>
|
||||
<meta name="HandheldFriendly" content="True" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
{{!-- Preload scripts --}}
|
||||
<link rel="preload" as="style" href="{{asset "built/screen.css"}}" />
|
||||
<link rel="preload" as="script" href="{{asset "built/casper.js"}}" />
|
||||
|
||||
{{!-- Theme assets - use the {asset} helper to reference styles & scripts,
|
||||
this will take care of caching and cache-busting automatically --}}
|
||||
{{!-- Styles'n'Scripts --}}
|
||||
<link rel="stylesheet" type="text/css" href="{{asset "built/screen.css"}}" />
|
||||
<link rel="stylesheet" type="text/css" href="{{asset "css/prism.css"}}" />
|
||||
|
||||
{{!-- This tag outputs all your advanced SEO meta, structured data, and other important settings,
|
||||
it should always be the last tag before the closing head tag --}}
|
||||
{{!-- This tag outputes SEO meta+structured data and other important settings --}}
|
||||
{{ghost_head}}
|
||||
|
||||
</head>
|
||||
<body class="{{body_class}} is-head-{{#match @custom.navigation_layout "Logo on cover"}}left-logo{{else match @custom.navigation_layout "Logo in the middle"}}middle-logo{{else}}stacked{{/match}}{{#match @custom.title_font "=" "Elegant serif"}} has-serif-title{{/match}}{{#match @custom.body_font "=" "Modern sans-serif"}} has-sans-body{{/match}}{{#if @custom.show_publication_cover}} has-cover{{/if}}">
|
||||
<div class="viewport">
|
||||
<body class="{{body_class}}">
|
||||
|
||||
<header id="gh-head" class="gh-head outer{{#match @custom.header_style "Hidden"}} is-header-hidden{{/match}}">
|
||||
<div class="gh-head-inner inner">
|
||||
<div class="gh-head-brand">
|
||||
<a class="gh-head-logo{{#unless @site.logo}} no-image{{/unless}}" href="{{@site.url}}">
|
||||
{{#if @site.logo}}
|
||||
<img src="{{@site.logo}}" alt="{{@site.title}}">
|
||||
{{else}}
|
||||
{{@site.title}}
|
||||
{{/if}}
|
||||
</a>
|
||||
<button class="gh-search gh-icon-btn" aria-label="Search this site" data-ghost-search>{{> "icons/search"}}</button>
|
||||
<button class="gh-burger"></button>
|
||||
</div>
|
||||
<nav class="gh-head-menu">
|
||||
{{navigation}}
|
||||
{{#unless @site.members_enabled}}
|
||||
{{#match @custom.navigation_layout "Stacked"}}
|
||||
<button class="gh-search gh-icon-btn" aria-label="Search this site" data-ghost-search>{{> "icons/search"}}</button>
|
||||
{{/match}}
|
||||
{{/unless}}
|
||||
</nav>
|
||||
<div class="site-wrapper">
|
||||
|
||||
<div class="gh-head-actions">
|
||||
{{#unless @site.members_enabled}}
|
||||
{{^match @custom.navigation_layout "Stacked"}}
|
||||
<button class="gh-search gh-icon-btn" data-ghost-search>{{> "icons/search"}}</button>
|
||||
{{/match}}
|
||||
{{else}}
|
||||
<button class="gh-search gh-icon-btn" data-ghost-search>{{> "icons/search"}}</button>
|
||||
<div class="gh-head-members">
|
||||
{{#unless @member}}
|
||||
{{#unless @site.members_invite_only}}
|
||||
<a class="gh-head-link" href="#/portal/signin" data-portal="signin">Sign in</a>
|
||||
<a class="gh-head-button" href="#/portal/signup" data-portal="signup">Subscribe</a>
|
||||
{{else}}
|
||||
<a class="gh-head-button" href="#/portal/signin" data-portal="signin">Sign in</a>
|
||||
{{/unless}}
|
||||
{{else}}
|
||||
<a class="gh-head-button" href="#/portal/account" data-portal="account">Account</a>
|
||||
{{/unless}}
|
||||
</div>
|
||||
{{/unless}}
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="site-content">
|
||||
{{!-- All other templates get inserted here, index.hbs, post.hbs, etc --}}
|
||||
{{!-- All the main content gets inserted here, index.hbs, post.hbs, etc --}}
|
||||
{{{body}}}
|
||||
|
||||
{{!-- The footer at the very bottom of the screen --}}
|
||||
<footer class="site-footer outer">
|
||||
<div class="site-footer-content inner">
|
||||
<section class="copyright"><a href="{{@blog.url}}">{{@blog.title}}</a> © {{date format="YYYY"}}</section>
|
||||
<nav class="site-footer-nav">
|
||||
<a href="{{@blog.url}}">Latest Posts</a>
|
||||
{{#if @blog.facebook}}<a href="{{facebook_url @blog.facebook}}" target="_blank">Facebook</a>{{/if}}
|
||||
{{#if @blog.twitter}}<a href="{{twitter_url @blog.twitter}}" target="_blank">Twitter</a>{{/if}}
|
||||
<a href="https://ghost.org" target="_blank">Ghost</a>
|
||||
</nav>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
|
||||
{{!-- The global footer at the very bottom of the screen --}}
|
||||
<footer class="site-footer outer">
|
||||
<div class="inner">
|
||||
<section class="copyright"><a href="{{@site.url}}">{{@site.title}}</a> © {{date format="YYYY"}}</section>
|
||||
<nav class="site-footer-nav">
|
||||
{{navigation type="secondary"}}
|
||||
</nav>
|
||||
<div class="gh-powered-by"><a href="https://ghost.org/" target="_blank" rel="noopener">Powered by Ghost</a></div>
|
||||
{{!-- The big email subscribe modal content --}}
|
||||
{{#if @labs.subscribers}}
|
||||
<div id="subscribe" class="subscribe-overlay">
|
||||
<a class="subscribe-overlay-close" href="#"></a>
|
||||
<div class="subscribe-overlay-content">
|
||||
{{#if @blog.logo}}
|
||||
<img class="subscribe-overlay-logo" src="{{@blog.logo}}" alt="{{@blog.title}}" />
|
||||
{{/if}}
|
||||
<h1 class="subscribe-overlay-title">Subscribe to {{@blog.title}}</h1>
|
||||
<p class="subscribe-overlay-description">Stay up to date! Get all the latest & greatest posts delivered straight to your inbox</p>
|
||||
{{subscribe_form placeholder="youremail@example.com"}}
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
</div>
|
||||
{{!-- /.viewport --}}
|
||||
{{!-- jQuery + Fitvids, which makes all video embeds responsive --}}
|
||||
<script
|
||||
src="https://code.jquery.com/jquery-3.2.1.min.js"
|
||||
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
|
||||
crossorigin="anonymous">
|
||||
</script>
|
||||
<script type="text/javascript" src="{{asset "js/jquery.fitvids.js"}}"></script>
|
||||
|
||||
{{#if pagination.pages}}
|
||||
<script>
|
||||
var maxPages = parseInt('{{pagination.pages}}');
|
||||
</script>
|
||||
<script src="{{asset "js/infinitescroll.js"}}"></script>
|
||||
{{/if}}
|
||||
|
||||
{{!-- Scripts - handle member signups, responsive videos, infinite scroll, floating headers, and galleries --}}
|
||||
<script
|
||||
src="https://code.jquery.com/jquery-3.5.1.min.js"
|
||||
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
|
||||
crossorigin="anonymous">
|
||||
</script>
|
||||
<script src="{{asset "built/casper.js"}}"></script>
|
||||
<script src="{{asset "js/prism.js"}}"></script>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
// Mobile Menu Trigger
|
||||
$('.gh-burger').click(function () {
|
||||
$('body').toggleClass('gh-head-open');
|
||||
});
|
||||
// FitVids - Makes video embeds responsive
|
||||
$(".gh-content").fitVids();
|
||||
});
|
||||
</script>
|
||||
{{!-- The #block helper will pull in data from the #contentFor other template files. In this case, there's some JavaScript which we only want to use in post.hbs, but it needs to be included down here, after jQuery has already loaded. --}}
|
||||
{{{block "scripts"}}}
|
||||
|
||||
{{!-- Ghost outputs required functional scripts with this tag - it should always be the last thing before the closing body tag --}}
|
||||
{{ghost_foot}}
|
||||
{{!-- Ghost outputs important scripts and data with this tag - it should always be the very last thing before the closing body tag --}}
|
||||
{{ghost_foot}}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,37 +1,56 @@
|
||||
{{!< default}}
|
||||
|
||||
{{!--
|
||||
|
||||
There are two error files in this theme, one for 404s and one for all other errors.
|
||||
This file is the former, and handles all 404 Page Not Found errors.
|
||||
|
||||
The 404 error is the most common error that a visitor might see, for example when
|
||||
following a broken link
|
||||
|
||||
Keep this template as lightweight as you can!
|
||||
|
||||
This error template is used for all 404 errors, which might occur on your site.
|
||||
It's a good idea to keep this template as minimal as possible in terms of both file size and complexity.
|
||||
--}}
|
||||
|
||||
<section class="outer error-content">
|
||||
<div class="inner">
|
||||
<section class="error-message">
|
||||
<h1 class="error-code">{{statusCode}}</h1>
|
||||
<p class="error-description">{{message}}</p>
|
||||
<a class="error-link" href="{{@site.url}}">Go to the front page →</a>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>{{meta_title}}</title>
|
||||
<meta name="HandheldFriendly" content="True" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="stylesheet" type="text/css" href="{{asset "built/screen.css"}}" />
|
||||
</head>
|
||||
<body class="error-template">
|
||||
<div class="site-wrapper">
|
||||
|
||||
{{!-- Given that people landing on this page didn't find what they
|
||||
were looking for, let's give them some alternative stuff to read. --}}
|
||||
<aside class="read-more-wrap outer">
|
||||
<div class="read-more inner">
|
||||
{{#get "posts" include="authors" limit="3" as |more_posts|}}
|
||||
{{#if more_posts}}
|
||||
{{#foreach more_posts}}
|
||||
{{> "post-card"}}
|
||||
{{/foreach}}
|
||||
{{/if}}
|
||||
<header class="site-header outer {{#if feature_image}}" style="background-image: url({{feature_image}}){{else}}no-cover{{/if}}">
|
||||
<div class="inner">
|
||||
<nav class="site-nav-center">
|
||||
{{#if @blog.logo}}
|
||||
<a class="site-nav-logo" href="{{@blog.url}}"><img src="{{@blog.logo}}" alt="{{@blog.title}}" /></a>
|
||||
{{else}}
|
||||
<a class="site-nav-logo" href="{{@blog.url}}">{{@blog.title}}</a>
|
||||
{{/if}}
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main id="site-main" class="site-main outer" role="main">
|
||||
<div class="inner">
|
||||
|
||||
<section class="error-message">
|
||||
<h1 class="error-code">{{code}}</h1>
|
||||
<p class="error-description">{{message}}</p>
|
||||
<a class="error-link" href="{{@blog.url}}">Go to the front page →</a>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{{#get "posts" limit="3"}}
|
||||
<aside class="outer">
|
||||
<div class="inner">
|
||||
<div class="post-feed">
|
||||
{{#foreach posts}}
|
||||
{{> "post-card"}}
|
||||
{{/foreach}}
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
{{/get}}
|
||||
|
||||
</div>
|
||||
</aside>
|
||||
</body>
|
||||
</html>
|
||||
|
51
error.hbs
@ -1,15 +1,7 @@
|
||||
{{!--
|
||||
|
||||
There are two error files in this theme, one for 404s and one for all other errors.
|
||||
This file is the latter, and handles all 400/500 errors that might occur.
|
||||
|
||||
Because 500 errors in particular usually happen when a server is struggling, this
|
||||
template is as simple as possible. No template dependencies, no JS, no API calls.
|
||||
This is to prevent rendering the error-page itself compounding the issue causing
|
||||
the error in the first place.
|
||||
|
||||
Keep this template as lightweight as you can!
|
||||
|
||||
This error template is used for all 400/500 errors, except 404, which might occur on your site.
|
||||
It's a good idea to keep this template as minimal as possible in terms of both file size and complexity.
|
||||
You'll notice that we *don't* use any JavsScript, or ghost_head / ghost_foot in this file.
|
||||
--}}
|
||||
|
||||
<!DOCTYPE html>
|
||||
@ -22,47 +14,44 @@ Keep this template as lightweight as you can!
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="stylesheet" type="text/css" href="{{asset "built/screen.css"}}" />
|
||||
</head>
|
||||
<body>
|
||||
<body class="error-template">
|
||||
<div class="site-wrapper">
|
||||
|
||||
<header class="site-header no-image">
|
||||
<div class="site-nav-main outer">
|
||||
<div class="inner">
|
||||
<nav class="site-nav-center">
|
||||
{{#if @site.logo}}
|
||||
<a class="site-nav-logo" href="{{@site.url}}"><img src="{{img_url @site.logo size="xs"}}"
|
||||
alt="{{@site.title}}" /></a>
|
||||
{{else}}
|
||||
<a class="site-nav-logo" href="{{@site.url}}">{{@site.title}}</a>
|
||||
{{/if}}
|
||||
</nav>
|
||||
</div>
|
||||
<header class="site-header outer {{#if feature_image}}" style="background-image: url({{feature_image}}){{else}}no-cover{{/if}}">
|
||||
<div class="inner">
|
||||
<nav class="site-nav-center">
|
||||
{{#if @blog.logo}}
|
||||
<a class="site-nav-logo" href="{{@blog.url}}"><img src="{{@blog.logo}}" alt="{{@blog.title}}" /></a>
|
||||
{{else}}
|
||||
<a class="site-nav-logo" href="{{@blog.url}}">{{@blog.title}}</a>
|
||||
{{/if}}
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="outer error-content">
|
||||
<main id="site-main" class="site-main outer" role="main">
|
||||
<div class="inner">
|
||||
|
||||
<section class="error-message">
|
||||
<h1 class="error-code">{{statusCode}}</h1>
|
||||
<h1 class="error-code">{{code}}</h1>
|
||||
<p class="error-description">{{message}}</p>
|
||||
<a class="error-link" href="{{@site.url}}">Go to the front page →</a>
|
||||
<a class="error-link" href="{{@blog.url}}">Go to the front page →</a>
|
||||
</section>
|
||||
|
||||
{{#if errorDetails}}
|
||||
<section class="error-stack">
|
||||
<h3>Theme errors</h3>
|
||||
<ul class="error-stack-list">
|
||||
{{#foreach errorDetails}}
|
||||
{{#each errorDetails}}
|
||||
<li>
|
||||
<em class="error-stack-function">{{{rule}}}</em>
|
||||
|
||||
{{#foreach failures}}
|
||||
{{#each failures}}
|
||||
<p><span class="error-stack-file">Ref: {{ref}}</span></p>
|
||||
<p><span class="error-stack-file">Message: {{message}}</span></p>
|
||||
{{/foreach}}
|
||||
{{/each}}
|
||||
</li>
|
||||
{{/foreach}}
|
||||
{{/each}}
|
||||
</ul>
|
||||
</section>
|
||||
{{/if}}
|
||||
|
214
gulpfile.js
@ -1,176 +1,54 @@
|
||||
const {series, watch, src, dest, parallel} = require('gulp');
|
||||
const pump = require('pump');
|
||||
const path = require('path');
|
||||
const releaseUtils = require('@tryghost/release-utils');
|
||||
const inquirer = require('inquirer');
|
||||
var gulp = require('gulp');
|
||||
|
||||
// gulp plugins and utils
|
||||
const livereload = require('gulp-livereload');
|
||||
const postcss = require('gulp-postcss');
|
||||
const zip = require('gulp-zip');
|
||||
const concat = require('gulp-concat');
|
||||
const uglify = require('gulp-uglify');
|
||||
const beeper = require('beeper');
|
||||
const fs = require('fs');
|
||||
var gutil = require('gulp-util');
|
||||
var livereload = require('gulp-livereload');
|
||||
var nodemon = require('gulp-nodemon');
|
||||
var postcss = require('gulp-postcss');
|
||||
var sourcemaps = require('gulp-sourcemaps');
|
||||
|
||||
// postcss plugins
|
||||
const autoprefixer = require('autoprefixer');
|
||||
const colorFunction = require('postcss-color-mod-function');
|
||||
const cssnano = require('cssnano');
|
||||
const easyimport = require('postcss-easy-import');
|
||||
var autoprefixer = require('autoprefixer');
|
||||
var colorFunction = require('postcss-color-function');
|
||||
var cssnano = require('cssnano');
|
||||
var customProperties = require('postcss-custom-properties');
|
||||
var easyimport = require('postcss-easy-import');
|
||||
|
||||
const REPO = 'TryGhost/Casper';
|
||||
const REPO_READONLY = 'TryGhost/Casper';
|
||||
const CHANGELOG_PATH = path.join(process.cwd(), '.', 'changelog.md');
|
||||
|
||||
function serve(done) {
|
||||
livereload.listen();
|
||||
done();
|
||||
}
|
||||
|
||||
const handleError = (done) => {
|
||||
return function (err) {
|
||||
if (err) {
|
||||
beeper();
|
||||
}
|
||||
return done(err);
|
||||
};
|
||||
var swallowError = function swallowError(error) {
|
||||
gutil.log(error.toString());
|
||||
gutil.beep();
|
||||
this.emit('end');
|
||||
};
|
||||
|
||||
function hbs(done) {
|
||||
pump([
|
||||
src(['*.hbs', 'partials/**/*.hbs']),
|
||||
livereload()
|
||||
], handleError(done));
|
||||
}
|
||||
|
||||
function css(done) {
|
||||
pump([
|
||||
src('assets/css/*.css', {sourcemaps: true}),
|
||||
postcss([
|
||||
easyimport,
|
||||
colorFunction(),
|
||||
autoprefixer(),
|
||||
cssnano()
|
||||
]),
|
||||
dest('assets/built/', {sourcemaps: '.'}),
|
||||
livereload()
|
||||
], handleError(done));
|
||||
}
|
||||
|
||||
function js(done) {
|
||||
pump([
|
||||
src([
|
||||
// pull in lib files first so our own code can depend on it
|
||||
'assets/js/lib/*.js',
|
||||
'assets/js/*.js'
|
||||
], {sourcemaps: true}),
|
||||
concat('casper.js'),
|
||||
uglify(),
|
||||
dest('assets/built/', {sourcemaps: '.'}),
|
||||
livereload()
|
||||
], handleError(done));
|
||||
}
|
||||
|
||||
function zipper(done) {
|
||||
const filename = require('./package.json').name + '.zip';
|
||||
|
||||
pump([
|
||||
src([
|
||||
'**',
|
||||
'!node_modules', '!node_modules/**',
|
||||
'!dist', '!dist/**',
|
||||
'!yarn-error.log',
|
||||
'!yarn.lock',
|
||||
'!gulpfile.js'
|
||||
]),
|
||||
zip(filename),
|
||||
dest('dist/')
|
||||
], handleError(done));
|
||||
}
|
||||
|
||||
const cssWatcher = () => watch('assets/css/**', css);
|
||||
const jsWatcher = () => watch('assets/js/**', js);
|
||||
const hbsWatcher = () => watch(['*.hbs', 'partials/**/*.hbs'], hbs);
|
||||
const watcher = parallel(cssWatcher, jsWatcher, hbsWatcher);
|
||||
const build = series(css, js);
|
||||
|
||||
exports.build = build;
|
||||
exports.zip = series(build, zipper);
|
||||
exports.default = series(build, serve, watcher);
|
||||
|
||||
exports.release = async () => {
|
||||
// @NOTE: https://yarnpkg.com/lang/en/docs/cli/version/
|
||||
// require(./package.json) can run into caching issues, this re-reads from file everytime on release
|
||||
let packageJSON = JSON.parse(fs.readFileSync('./package.json'));
|
||||
const newVersion = packageJSON.version;
|
||||
|
||||
if (!newVersion || newVersion === '') {
|
||||
console.log(`Invalid version: ${newVersion}`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`\nCreating release for ${newVersion}...`);
|
||||
|
||||
const githubToken = process.env.GST_TOKEN;
|
||||
|
||||
if (!githubToken) {
|
||||
console.log('Please configure your environment with a GitHub token located in GST_TOKEN');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await inquirer.prompt([{
|
||||
type: 'input',
|
||||
name: 'compatibleWithGhost',
|
||||
message: 'Which version of Ghost is it compatible with?',
|
||||
default: '5.0.0'
|
||||
}]);
|
||||
|
||||
const compatibleWithGhost = result.compatibleWithGhost;
|
||||
|
||||
const releasesResponse = await releaseUtils.releases.get({
|
||||
userAgent: 'Casper',
|
||||
uri: `https://api.github.com/repos/${REPO_READONLY}/releases`
|
||||
});
|
||||
|
||||
if (!releasesResponse || !releasesResponse) {
|
||||
console.log('No releases found. Skipping...');
|
||||
return;
|
||||
}
|
||||
|
||||
let previousVersion = releasesResponse[0].tag_name || releasesResponse[0].name;
|
||||
console.log(`Previous version: ${previousVersion}`);
|
||||
|
||||
const changelog = new releaseUtils.Changelog({
|
||||
changelogPath: CHANGELOG_PATH,
|
||||
folder: path.join(process.cwd(), '.')
|
||||
});
|
||||
|
||||
changelog
|
||||
.write({
|
||||
githubRepoPath: `https://github.com/${REPO}`,
|
||||
lastVersion: previousVersion
|
||||
})
|
||||
.sort()
|
||||
.clean();
|
||||
|
||||
const newReleaseResponse = await releaseUtils.releases.create({
|
||||
draft: true,
|
||||
preRelease: false,
|
||||
tagName: 'v' + newVersion,
|
||||
releaseName: newVersion,
|
||||
userAgent: 'Casper',
|
||||
uri: `https://api.github.com/repos/${REPO}/releases`,
|
||||
github: {
|
||||
token: githubToken
|
||||
},
|
||||
content: [`**Compatible with Ghost ≥ ${compatibleWithGhost}**\n\n`],
|
||||
changelogPath: CHANGELOG_PATH
|
||||
});
|
||||
console.log(`\nRelease draft generated: ${newReleaseResponse.releaseUrl}\n`);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
var nodemonServerInit = function () {
|
||||
livereload.listen(1234);
|
||||
};
|
||||
|
||||
gulp.task('build', ['css'], function (/* cb */) {
|
||||
return nodemonServerInit();
|
||||
});
|
||||
|
||||
gulp.task('css', function () {
|
||||
var processors = [
|
||||
easyimport,
|
||||
customProperties,
|
||||
colorFunction(),
|
||||
autoprefixer({browsers: ['last 2 versions']}),
|
||||
cssnano()
|
||||
];
|
||||
gulp.src('assets/css/*.css')
|
||||
.on('error', swallowError)
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(postcss(processors))
|
||||
.pipe(sourcemaps.write('.'))
|
||||
.pipe(gulp.dest('assets/built/'))
|
||||
.pipe(livereload());
|
||||
});
|
||||
|
||||
gulp.task('watch', function () {
|
||||
gulp.watch('assets/css/**', ['css']);
|
||||
});
|
||||
|
||||
gulp.task('default', ['build'], function () {
|
||||
gulp.start('watch');
|
||||
});
|
||||
|
66
index.hbs
@ -2,53 +2,35 @@
|
||||
{{!-- The tag above means: insert everything in this file
|
||||
into the {body} of the default.hbs template --}}
|
||||
|
||||
<div class="site-header-content outer{{#match @custom.header_style "Left aligned"}} left-aligned{{/match}}{{#unless @custom.show_publication_cover}}{{#match @custom.header_style "Hidden"}} no-content{{/match}}{{/unless}}">
|
||||
|
||||
{{#if @custom.show_publication_cover}}
|
||||
{{#if @site.cover_image}}
|
||||
{{!-- This is a responsive image, it loads different sizes depending on device
|
||||
https://medium.freecodecamp.org/a-guide-to-responsive-images-with-ready-to-use-templates-c400bd65c433 --}}
|
||||
<img class="site-header-cover"
|
||||
srcset="{{img_url @site.cover_image size="s"}} 300w,
|
||||
{{img_url @site.cover_image size="m"}} 600w,
|
||||
{{img_url @site.cover_image size="l"}} 1000w,
|
||||
{{img_url @site.cover_image size="xl"}} 2000w"
|
||||
sizes="100vw"
|
||||
src="{{img_url @site.cover_image size="xl"}}"
|
||||
alt="{{@site.title}}"
|
||||
/>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
{{#match @custom.header_style "!=" "Hidden"}}
|
||||
<div class="site-header-inner inner">
|
||||
{{#match @custom.navigation_layout "Logo on cover"}}
|
||||
{{#if @site.logo}}
|
||||
<img class="site-logo" src="{{@site.logo}}" alt="{{@site.title}}">
|
||||
{{!-- The big featured header, it uses blog cover image as a BG if available --}}
|
||||
<header class="site-header outer {{#if @blog.cover_image}}" style="background-image: url({{@blog.cover_image}}){{else}}no-cover{{/if}}">
|
||||
<div class="inner">
|
||||
<div class="site-header-content">
|
||||
<h1 class="site-title">
|
||||
{{#if @blog.logo}}
|
||||
<img class="site-logo" src="{{@blog.logo}}" alt="{{@blog.title}}" />
|
||||
{{else}}
|
||||
<h1 class="site-title">{{@site.title}}</h1>
|
||||
{{@blog.title}}
|
||||
{{/if}}
|
||||
{{/match}}
|
||||
{{#if @site.description}}
|
||||
<p class="site-description">{{@site.description}}</p>
|
||||
{{/if}}
|
||||
</h1>
|
||||
<h2 class="site-description">{{@blog.description}}</h2>
|
||||
</div>
|
||||
{{/match}}
|
||||
|
||||
</div>
|
||||
{{> "site-nav"}}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{{!-- The main content area --}}
|
||||
<main id="site-main" class="site-main outer">
|
||||
<div class="inner posts">
|
||||
<main id="site-main" class="site-main outer" role="main">
|
||||
<div class="inner">
|
||||
|
||||
<div class="post-feed">
|
||||
{{#foreach posts}}
|
||||
|
||||
{{!-- The tag below includes the markup for each post - partials/post-card.hbs --}}
|
||||
{{> "post-card"}}
|
||||
|
||||
{{/foreach}}
|
||||
</div>
|
||||
|
||||
<div class="post-feed">
|
||||
{{#foreach posts}}
|
||||
{{!-- The tag below includes the markup for each post - partials/post-card.hbs --}}
|
||||
{{> "post-card"}}
|
||||
{{/foreach}}
|
||||
</div>
|
||||
|
||||
{{pagination}}
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
172
package.json
@ -1,29 +1,19 @@
|
||||
{
|
||||
"name": "vivid-casper",
|
||||
"description": "Minor tweaks from the default personal blogging theme for Ghost. Beautiful, minimal and responsive.",
|
||||
"name": "casper",
|
||||
"description": "The default personal blogging theme for Ghost. Beautiful, minimal and responsive.",
|
||||
"demo": "https://demo.ghost.io",
|
||||
"version": "5.5.3",
|
||||
"version": "2.0.3",
|
||||
"engines": {
|
||||
"ghost": ">=5.0.0"
|
||||
"ghost": ">=1.2.0"
|
||||
},
|
||||
"license": "MIT",
|
||||
"screenshots": {
|
||||
"desktop": "assets/screenshot-desktop.jpg",
|
||||
"mobile": "assets/screenshot-mobile.jpg"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "gulp",
|
||||
"zip": "gulp zip",
|
||||
"test": "gscan .",
|
||||
"test:ci": "gscan --fatal --verbose .",
|
||||
"pretest": "gulp build",
|
||||
"preship": "yarn test",
|
||||
"ship": "STATUS=$(git status --porcelain); echo $STATUS; if [ -z \"$STATUS\" ]; then yarn version && git push --follow-tags; else echo \"Uncomitted changes found.\" && exit 1; fi",
|
||||
"postship": "git fetch && gulp release"
|
||||
},
|
||||
"author": {
|
||||
"name": "ViViDboarder",
|
||||
"email": "vividboarder@gmail.com",
|
||||
"name": "Ghost Foundation",
|
||||
"email": "hello@ghost.org",
|
||||
"url": "https://ghost.org"
|
||||
},
|
||||
"gpm": {
|
||||
@ -35,145 +25,29 @@
|
||||
},
|
||||
"keywords": [
|
||||
"ghost",
|
||||
"theme",
|
||||
"ghost-theme"
|
||||
"theme"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ViViDboarder/Casper.git"
|
||||
"url": "https://github.com/TryGhost/Casper.git"
|
||||
},
|
||||
"bugs": "https://github.com/ViViDboarder/Casper/issues",
|
||||
"contributors": "https://github.com/ViViDboarder/Casper/graphs/contributors",
|
||||
"bugs": "https://github.com/TryGhost/Casper/issues",
|
||||
"contributors": "https://github.com/TryGhost/Casper/graphs/contributors",
|
||||
"devDependencies": {
|
||||
"@tryghost/release-utils": "0.8.1",
|
||||
"autoprefixer": "10.4.7",
|
||||
"beeper": "2.1.0",
|
||||
"cssnano": "5.1.12",
|
||||
"gscan": "4.36.1",
|
||||
"gulp": "4.0.2",
|
||||
"gulp-concat": "2.6.1",
|
||||
"gulp-livereload": "4.0.2",
|
||||
"gulp-postcss": "9.0.1",
|
||||
"gulp-uglify": "3.0.2",
|
||||
"gulp-zip": "5.1.0",
|
||||
"inquirer": "8.2.4",
|
||||
"postcss": "8.2.13",
|
||||
"postcss-color-mod-function": "3.0.3",
|
||||
"postcss-easy-import": "4.0.0",
|
||||
"pump": "3.0.0"
|
||||
"autoprefixer": "6.3.6",
|
||||
"cssnano": "3.7.1",
|
||||
"gulp": "3.9.1",
|
||||
"gulp-livereload": "3.8.1",
|
||||
"gulp-nodemon": "2.1.0",
|
||||
"gulp-postcss": "6.1.1",
|
||||
"gulp-sourcemaps": "1.6.0",
|
||||
"gulp-util": "3.0.7",
|
||||
"gulp-watch": "4.3.8",
|
||||
"postcss-color-function": "2.0.1",
|
||||
"postcss-custom-properties": "5.0.1",
|
||||
"postcss-easy-import": "1.0.1"
|
||||
},
|
||||
"browserslist": [
|
||||
"defaults"
|
||||
],
|
||||
"config": {
|
||||
"posts_per_page": 25,
|
||||
"image_sizes": {
|
||||
"xxs": {
|
||||
"width": 30
|
||||
},
|
||||
"xs": {
|
||||
"width": 100
|
||||
},
|
||||
"s": {
|
||||
"width": 300
|
||||
},
|
||||
"m": {
|
||||
"width": 600
|
||||
},
|
||||
"l": {
|
||||
"width": 1000
|
||||
},
|
||||
"xl": {
|
||||
"width": 2000
|
||||
}
|
||||
},
|
||||
"card_assets": true,
|
||||
"custom": {
|
||||
"navigation_layout": {
|
||||
"type": "select",
|
||||
"options": [
|
||||
"Logo on cover",
|
||||
"Logo in the middle",
|
||||
"Stacked"
|
||||
],
|
||||
"default": "Logo on cover"
|
||||
},
|
||||
"title_font": {
|
||||
"type": "select",
|
||||
"options": [
|
||||
"Modern sans-serif",
|
||||
"Elegant serif"
|
||||
],
|
||||
"default": "Modern sans-serif"
|
||||
},
|
||||
"body_font": {
|
||||
"type": "select",
|
||||
"options": [
|
||||
"Modern sans-serif",
|
||||
"Elegant serif"
|
||||
],
|
||||
"default": "Elegant serif"
|
||||
},
|
||||
"show_publication_cover": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"group": "homepage"
|
||||
},
|
||||
"header_style": {
|
||||
"type": "select",
|
||||
"options": [
|
||||
"Center aligned",
|
||||
"Left aligned",
|
||||
"Hidden"
|
||||
],
|
||||
"default": "Center aligned",
|
||||
"group": "homepage"
|
||||
},
|
||||
"feed_layout": {
|
||||
"type": "select",
|
||||
"options": [
|
||||
"Classic",
|
||||
"Grid",
|
||||
"List"
|
||||
],
|
||||
"default": "Classic",
|
||||
"group": "homepage"
|
||||
},
|
||||
"color_scheme": {
|
||||
"type": "select",
|
||||
"options": [
|
||||
"Light",
|
||||
"Dark",
|
||||
"Auto"
|
||||
],
|
||||
"default": "Light"
|
||||
},
|
||||
"post_image_style": {
|
||||
"type": "select",
|
||||
"options": [
|
||||
"Wide",
|
||||
"Full",
|
||||
"Small",
|
||||
"Hidden"
|
||||
],
|
||||
"default": "Wide",
|
||||
"group": "post"
|
||||
},
|
||||
"email_signup_text": {
|
||||
"type": "text",
|
||||
"default": "Sign up for more like this.",
|
||||
"group": "post"
|
||||
},
|
||||
"show_recent_posts_footer": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"group": "post"
|
||||
}
|
||||
}
|
||||
},
|
||||
"renovate": {
|
||||
"extends": [
|
||||
"@tryghost:theme"
|
||||
]
|
||||
"posts_per_page": 25
|
||||
}
|
||||
}
|
||||
|
63
page.hbs
@ -1,47 +1,48 @@
|
||||
{{!< default}}
|
||||
|
||||
{{!-- The tag above means: insert everything in this file
|
||||
into the {body} tag of the default.hbs template --}}
|
||||
into the {body} of the default.hbs template --}}
|
||||
|
||||
{{!-- The big featured header, it uses blog cover image as a BG if available --}}
|
||||
<header class="site-header outer">
|
||||
<div class="inner">
|
||||
{{> "site-nav"}}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{{!-- Everything inside the #post tags pulls data from the post --}}
|
||||
{{#post}}
|
||||
{{!-- Everything inside the #post block pulls data from the page --}}
|
||||
|
||||
<main id="site-main" class="site-main">
|
||||
<article class="article {{post_class}}">
|
||||
<main id="site-main" class="site-main outer" role="main">
|
||||
<div class="inner">
|
||||
|
||||
{{#if show_title_and_feature_image}}
|
||||
<header class="article-header gh-canvas">
|
||||
<article class="post-full {{post_class}} {{#unless feature_image}}no-image{{/unless}}">
|
||||
|
||||
<h1 class="article-title">{{title}}</h1>
|
||||
<header class="post-full-header">
|
||||
<h1 class="post-full-title">{{title}}</h1>
|
||||
</header>
|
||||
|
||||
{{#if feature_image}}
|
||||
<figure class="article-image">
|
||||
{{!-- This is a responsive image, it loads different sizes depending on device
|
||||
https://medium.freecodecamp.org/a-guide-to-responsive-images-with-ready-to-use-templates-c400bd65c433 --}}
|
||||
<img
|
||||
srcset="{{img_url feature_image size="s"}} 300w,
|
||||
{{img_url feature_image size="m"}} 600w,
|
||||
{{img_url feature_image size="l"}} 1000w,
|
||||
{{img_url feature_image size="xl"}} 2000w"
|
||||
sizes="(min-width: 1400px) 1400px, 92vw"
|
||||
src="{{img_url feature_image size="xl"}}"
|
||||
alt="{{#if feature_image_alt}}{{feature_image_alt}}{{else}}{{title}}{{/if}}"
|
||||
/>
|
||||
{{#if feature_image_caption}}
|
||||
<figcaption>{{feature_image_caption}}</figcaption>
|
||||
{{/if}}
|
||||
</figure>
|
||||
<figure class="post-full-image" style="background-image: url({{feature_image}})">
|
||||
</figure>
|
||||
{{/if}}
|
||||
|
||||
</header>
|
||||
{{/if}}
|
||||
<section class="post-full-content">
|
||||
{{content}}
|
||||
</section>
|
||||
|
||||
<section class="gh-content gh-canvas">
|
||||
{{content}}
|
||||
</section>
|
||||
</article>
|
||||
|
||||
</article>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{{/post}}
|
||||
{{/post}}
|
||||
|
||||
{{!-- The #contentFor helper here will send everything inside it up to the matching #block helper found in default.hbs --}}
|
||||
{{#contentFor "scripts"}}
|
||||
<script>
|
||||
$(function() {
|
||||
var $postContent = $(".post-full-content");
|
||||
$postContent.fitVids();
|
||||
});
|
||||
</script>
|
||||
{{/contentFor}}
|
||||
|
28
partials/floating-header.hbs
Normal file
@ -0,0 +1,28 @@
|
||||
<div class="floating-header">
|
||||
<div class="floating-header-logo">
|
||||
<a href="{{@blog.url}}">
|
||||
{{#if @blog.icon}}
|
||||
<img src="{{@blog.icon}}" alt="{{@blog.title}} icon" />
|
||||
{{/if}}
|
||||
<span>{{@blog.title}}</span>
|
||||
</a>
|
||||
</div>
|
||||
<span class="floating-header-divider">—</span>
|
||||
<div class="floating-header-title">{{title}}</div>
|
||||
<div class="floating-header-share">
|
||||
<div class="floating-header-share-label">Share this {{> "icons/point"}}</div>
|
||||
<a class="floating-header-share-tw" href="https://twitter.com/share?text={{encode title}}&url={{url absolute="true"}}"
|
||||
onclick="window.open(this.href, 'share-twitter', 'width=550,height=235');return false;">
|
||||
{{> "icons/twitter"}}
|
||||
</a>
|
||||
<a class="floating-header-share-fb" href="https://www.facebook.com/sharer/sharer.php?u={{url absolute="true"}}"
|
||||
onclick="window.open(this.href, 'share-facebook','width=580,height=296');return false;">
|
||||
{{> "icons/facebook"}}
|
||||
</a>
|
||||
</div>
|
||||
<progress class="progress" value="0">
|
||||
<div class="progress-container">
|
||||
<span class="progress-bar"></span>
|
||||
</div>
|
||||
</progress>
|
||||
</div>
|
@ -1 +0,0 @@
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path d="M3.513 18.998C4.749 15.504 8.082 13 12 13s7.251 2.504 8.487 5.998C18.47 21.442 15.417 23 12 23s-6.47-1.558-8.487-4.002zM12 12c2.21 0 4-2.79 4-5s-1.79-4-4-4-4 1.79-4 4 1.79 5 4 5z" fill="#FFF"/></g></svg>
|
Before Width: | Height: | Size: 308 B |
2
partials/icons/facebook.hbs
Normal file → Executable file
@ -1 +1 @@
|
||||
<svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path d="M23.9981 11.9991C23.9981 5.37216 18.626 0 11.9991 0C5.37216 0 0 5.37216 0 11.9991C0 17.9882 4.38789 22.9522 10.1242 23.8524V15.4676H7.07758V11.9991H10.1242V9.35553C10.1242 6.34826 11.9156 4.68714 14.6564 4.68714C15.9692 4.68714 17.3424 4.92149 17.3424 4.92149V7.87439H15.8294C14.3388 7.87439 13.8739 8.79933 13.8739 9.74824V11.9991H17.2018L16.6698 15.4676H13.8739V23.8524C19.6103 22.9522 23.9981 17.9882 23.9981 11.9991Z"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M19 6h5V0h-5c-3.86 0-7 3.14-7 7v3H8v6h4v16h6V16h5l1-6h-6V7c0-.542.458-1 1-1z"/></svg>
|
||||
|
Before Width: | Height: | Size: 531 B After Width: | Height: | Size: 155 B |
@ -1,3 +0,0 @@
|
||||
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4.49365 4.58752C3.53115 6.03752 2.74365 7.70002 2.74365 9.25002C2.74365 10.6424 3.29678 11.9778 4.28134 12.9623C5.26591 13.9469 6.60127 14.5 7.99365 14.5C9.38604 14.5 10.7214 13.9469 11.706 12.9623C12.6905 11.9778 13.2437 10.6424 13.2437 9.25002C13.2437 6.00002 10.9937 3.50002 9.16865 1.68127L6.99365 6.25002L4.49365 4.58752Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
</svg>
|
Before Width: | Height: | Size: 538 B |
1
partials/icons/ghost-logo.hbs
Normal file
@ -0,0 +1 @@
|
||||
<svg class="ghost-svg" viewBox="0 0 493 161" xmlns="http://www.w3.org/2000/svg"><title>Ghost Logo</title><g fill="none" fill-rule="evenodd"><path d="M328.52 37.36c-27.017 0-40.97 19.323-40.97 43.16 0 23.837 13.61 43.162 40.97 43.162s40.968-19.325 40.968-43.163c0-23.84-13.954-43.16-40.97-43.16zm20.438 43.237c-.02 15.328-5.126 27.743-20.44 27.743-15.312 0-20.42-12.414-20.435-27.743v-.078c.016-15.33 5.124-27.74 20.437-27.74 15.312 0 20.42 12.41 20.438 27.74v.07zM207.553 5.19c0-1.103.885-2.124 1.984-2.282 0 0 13.577-1.95 14.784-2.115 1.37-.187 3.19.798 3.19 2.744v44.236c3.23-3.105 6.79-5.608 10.66-7.515 3.88-1.906 8.43-2.86 13.66-2.86 4.53 0 8.53.776 12.03 2.33 3.5 1.55 6.43 3.73 8.77 6.533 2.34 2.81 4.12 6.16 5.33 10.05 1.21 3.9 1.82 8.19 1.82 12.87v51.35c0 1.1-.89 2-2 2h-15.95c-1.1 0-2-.9-2-1.99V69.18c0-5.118-1.17-9.08-3.51-11.888-2.35-2.804-5.86-4.207-10.544-4.207-3.45 0-6.677.79-9.69 2.37-3.02 1.58-5.87 3.73-8.564 6.46v58.617c0 1.102-.894 2-2.002 2h-15.94c-1.11 0-2.005-.895-2.005-2V5.188zm244.007 95.327v-43.68h-13.482c-1.1 0-1.742-.87-1.443-1.916l3-10.49c.262-.9.942-1.87 2.308-2.07l9.597-1.35 3.508-23.49c.163-1.09 1.18-2.1 2.274-2.26 0 0 9.192-1.31 10.963-1.58 1.673-.25 3.19.97 3.19 2.81v24.52h17.565c1.106 0 2.002.9 2.002 2.01v11.82c0 1.11-.89 2.01-2.002 2.01h-17.566v43.08c0 6.02 3.623 8.32 7.095 8.32 2.12 0 5.02-1.14 7.19-2.16 1.34-.62 3.41-.16 3.95 1.73l2.45 8.65c.3 1.07-.25 2.37-1.23 2.86 0 0-7.29 4.37-17.06 4.37-13.73 0-22.33-8.08-22.33-23.16zm-44.584-47.74c-7.084 0-12.657 2.476-12.657 8.433 0 7.44 12.01 9.606 20.23 12.64 5.49 2.027 20.24 5.98 20.24 22.016 0 19.48-16 27.807-33.06 27.807-17.06 0-25.4-5.465-25.4-5.465-.96-.527-1.5-1.822-1.2-2.89 0 0 2.1-7.52 2.64-9.386.48-1.68 2.41-2.27 3.64-1.792 4.39 1.712 12.32 4.092 21.28 4.092 9.07 0 13.46-2.803 13.46-8.777 0-7.95-12.26-10.38-20.36-12.967-5.59-1.78-20.36-5.93-20.36-23.566 0-17.373 15.08-25.524 31.2-25.524 13.64 0 23.5 4.69 23.5 4.69 1.01.427 1.58 1.635 1.28 2.698l-2.658 9.357c-.488 1.74-1.898 2.537-3.666 1.957-3.89-1.277-11.2-3.322-18.15-3.322zm-210.313-15.28c-6.695.775-11.472 3.962-14.562 6.93-6.06-4.81-14.49-7.106-23.94-7.106-18.95 0-33.76 9.26-33.76 29.43 0 11.58 4.88 19.56 12.62 24.26-5.75 2.75-9.57 8.59-9.57 14.34 0 9.61 7.5 12.61 7.5 12.61s-13.11 6.44-13.11 19.32c0 16.49 15.01 23.16 33.34 23.16 26.43 0 44.61-11.04 44.61-31.31 0-12.47-9.44-19.36-30.01-20.18-12.2-.48-20.11-.93-22.07-1.58-2.59-.87-3.86-2.96-3.86-5.28 0-2.55 2.08-4.98 5.35-6.65 2.86.516 5.87.768 8.99.768 18.97 0 33.76-9.223 33.76-29.425 0-4.897-.87-9.15-2.46-12.78 2.79-1.506 8.34-2.25 8.34-2.25 1.09-.17 1.975-1.21 1.974-2.31V40.3c0-1.88-1.59-2.955-3.1-2.78zm-49.13 85.132s9.954.38 19.9.84c11.172.52 14.654 2.96 14.654 8.81 0 7.15-9.71 14.1-23.28 14.1-12.88 0-19.314-4.54-19.314-12.08 0-4.33 2.26-9.18 8.04-11.69zm10.66-40.54c-8.978 0-15.983-4.83-15.983-15.35 0-10.53 7.01-15.35 15.983-15.35 8.974 0 15.984 4.81 15.984 15.34 0 10.53-7.002 15.34-15.984 15.34z" fill="#2D3134"/><g opacity=".6" transform="translate(0 36)" fill="#2E3134"><rect x=".209" y="69.017" width="33.643" height="17.014" rx="4"/><rect x="50.672" y="69.017" width="33.622" height="17.014" rx="4"/><rect x=".184" y="34.99" width="84.121" height="17.014" rx="4"/><rect x=".209" y=".964" width="50.469" height="17.013" rx="4"/><rect x="67.494" y=".964" width="16.821" height="17.013" rx="4"/></g></g></svg>
|
After Width: | Height: | Size: 3.3 KiB |
1
partials/icons/infinity.hbs
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 14.5s2 3 5 3 5.5-2.463 5.5-5.5S21 6.5 18 6.5c-5 0-7 11-12 11C2.962 17.5.5 15.037.5 12S3 6.5 6 6.5s4.5 3.5 4.5 3.5"/></svg>
|
After Width: | Height: | Size: 196 B |
@ -1,11 +0,0 @@
|
||||
<svg version="1.1" id="loader-1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
|
||||
y="0px" width="40px" height="40px" viewBox="0 0 40 40" enable-background="new 0 0 40 40" xml:space="preserve">
|
||||
<path opacity="0.2" fill="#000" d="M20.201,5.169c-8.254,0-14.946,6.692-14.946,14.946c0,8.255,6.692,14.946,14.946,14.946
|
||||
s14.946-6.691,14.946-14.946C35.146,11.861,28.455,5.169,20.201,5.169z M20.201,31.749c-6.425,0-11.634-5.208-11.634-11.634
|
||||
c0-6.425,5.209-11.634,11.634-11.634c6.425,0,11.633,5.209,11.633,11.634C31.834,26.541,26.626,31.749,20.201,31.749z" />
|
||||
<path fill="#000" d="M26.013,10.047l1.654-2.866c-2.198-1.272-4.743-2.012-7.466-2.012h0v3.312h0
|
||||
C22.32,8.481,24.301,9.057,26.013,10.047z">
|
||||
<animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0 20 20" to="360 20 20"
|
||||
dur="0.5s" repeatCount="indefinite" />
|
||||
</path>
|
||||
</svg>
|
Before Width: | Height: | Size: 923 B |
1
partials/icons/location.hbs
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" fill="none"><path d="M19.5 8c0 4.144-7.5 15.5-7.5 15.5S4.5 12.144 4.5 8C4.5 3.858 7.857.5 12 .5c4.142 0 7.5 3.358 7.5 7.5z"/><circle cx="12" cy="8" r="3"/></svg>
|
After Width: | Height: | Size: 329 B |
@ -1,5 +0,0 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M16.25 6.875H3.75C3.40482 6.875 3.125 7.15482 3.125 7.5V16.25C3.125 16.5952 3.40482 16.875 3.75 16.875H16.25C16.5952 16.875 16.875 16.5952 16.875 16.25V7.5C16.875 7.15482 16.5952 6.875 16.25 6.875Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
<path d="M7.1875 6.875V4.0625C7.1875 3.31658 7.48382 2.60121 8.01126 2.07376C8.53871 1.54632 9.25408 1.25 10 1.25C10.7459 1.25 11.4613 1.54632 11.9887 2.07376C12.5162 2.60121 12.8125 3.31658 12.8125 4.0625V6.875" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
<path d="M10 13.125C10.6904 13.125 11.25 12.5654 11.25 11.875C11.25 11.1846 10.6904 10.625 10 10.625C9.30964 10.625 8.75 11.1846 8.75 11.875C8.75 12.5654 9.30964 13.125 10 13.125Z" fill="currentColor"></path>
|
||||
</svg>
|
Before Width: | Height: | Size: 932 B |
3
partials/icons/point.hbs
Normal file
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path d="M7.5 15.5V4a1.5 1.5 0 1 1 3 0v4.5h2a1 1 0 0 1 1 1h2a1 1 0 0 1 1 1H18a1.5 1.5 0 0 1 1.5 1.5v3.099c0 .929-.13 1.854-.385 2.748L17.5 23.5h-9c-1.5-2-5.417-8.673-5.417-8.673a1.2 1.2 0 0 1 1.76-1.605L7.5 15.5zm6-6v2m-3-3.5v3.5m6-1v2"/>
|
||||
</svg>
|
After Width: | Height: | Size: 311 B |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" width="20" height="20"><path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg>
|
Before Width: | Height: | Size: 248 B |
@ -1 +1 @@
|
||||
<svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path d="M23.954 4.569c-.885.389-1.83.654-2.825.775 1.014-.611 1.794-1.574 2.163-2.723-.951.555-2.005.959-3.127 1.184-.896-.959-2.173-1.559-3.591-1.559-2.717 0-4.92 2.203-4.92 4.917 0 .39.045.765.127 1.124C7.691 8.094 4.066 6.13 1.64 3.161c-.427.722-.666 1.561-.666 2.475 0 1.71.87 3.213 2.188 4.096-.807-.026-1.566-.248-2.228-.616v.061c0 2.385 1.693 4.374 3.946 4.827-.413.111-.849.171-1.296.171-.314 0-.615-.03-.916-.086.631 1.953 2.445 3.377 4.604 3.417-1.68 1.319-3.809 2.105-6.102 2.105-.39 0-.779-.023-1.17-.067 2.189 1.394 4.768 2.209 7.557 2.209 9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63.961-.689 1.8-1.56 2.46-2.548l-.047-.02z"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M30.063 7.313c-.813 1.125-1.75 2.125-2.875 2.938v.75c0 1.563-.188 3.125-.688 4.625a15.088 15.088 0 0 1-2.063 4.438c-.875 1.438-2 2.688-3.25 3.813a15.015 15.015 0 0 1-4.625 2.563c-1.813.688-3.75 1-5.75 1-3.25 0-6.188-.875-8.875-2.625.438.063.875.125 1.375.125 2.688 0 5.063-.875 7.188-2.5-1.25 0-2.375-.375-3.375-1.125s-1.688-1.688-2.063-2.875c.438.063.813.125 1.125.125.5 0 1-.063 1.5-.25-1.313-.25-2.438-.938-3.313-1.938a5.673 5.673 0 0 1-1.313-3.688v-.063c.813.438 1.688.688 2.625.688a5.228 5.228 0 0 1-1.875-2c-.5-.875-.688-1.813-.688-2.75 0-1.063.25-2.063.75-2.938 1.438 1.75 3.188 3.188 5.25 4.25s4.313 1.688 6.688 1.813a5.579 5.579 0 0 1 1.5-5.438c1.125-1.125 2.5-1.688 4.125-1.688s3.063.625 4.188 1.813a11.48 11.48 0 0 0 3.688-1.375c-.438 1.375-1.313 2.438-2.563 3.188 1.125-.125 2.188-.438 3.313-.875z"/></svg>
|
||||
|
Before Width: | Height: | Size: 752 B After Width: | Height: | Size: 888 B |
1
partials/icons/website.hbs
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M23.5 11.957c0 6.375-5.163 11.544-11.532 11.544C5.599 23.5.5 18.125.5 11.75.5 5.542 5.37.758 11.505.511l.5-.011C18.374.5 23.5 5.582 23.5 11.957zM11.505.511c-6 6.5-6 14.98 0 22.98m1-22.98c6 6.5 6 14.977 0 22.977M2 17.479h20.063m-19.657-12h19.062m-20.968 6h22.938" stroke="#000" stroke-linejoin="round" stroke-miterlimit="10" fill="none"/></svg>
|
After Width: | Height: | Size: 413 B |
@ -1,78 +1,26 @@
|
||||
{{!-- This is a partial file used to generate a post "card"
|
||||
which templates loop over to generate a list of posts. --}}
|
||||
|
||||
<article class="post-card {{post_class}}{{#match @custom.feed_layout "Classic"}}{{#is "home"}}{{#has index="0"}} post-card-large{{/has}}{{#has index="1,2"}} dynamic{{/has}}{{/is}}{{/match}}{{#match @custom.feed_layout "Grid"}} keep-ratio{{/match}}{{#match @custom.feed_layout "List"}}{{#is "home, paged"}} post-card-large{{/is}}{{/match}}{{#unless access}} post-access-{{visibility}}{{/unless}}">
|
||||
|
||||
<article class="post-card {{post_class}}{{#unless feature_image}} no-image{{/unless}}">
|
||||
{{#if feature_image}}
|
||||
<a class="post-card-image-link" href="{{url}}">
|
||||
|
||||
{{!-- This is a responsive image, it loads different sizes depending on device
|
||||
https://medium.freecodecamp.org/a-guide-to-responsive-images-with-ready-to-use-templates-c400bd65c433 --}}
|
||||
<img class="post-card-image"
|
||||
srcset="{{img_url feature_image size="s"}} 300w,
|
||||
{{img_url feature_image size="m"}} 600w,
|
||||
{{img_url feature_image size="l"}} 1000w,
|
||||
{{img_url feature_image size="xl"}} 2000w"
|
||||
sizes="(max-width: 1000px) 400px, 800px"
|
||||
src="{{img_url feature_image size="m"}}"
|
||||
alt="{{#if feature_image_alt}}{{feature_image_alt}}{{else}}{{title}}{{/if}}"
|
||||
loading="lazy"
|
||||
/>
|
||||
|
||||
{{#unless access}}
|
||||
{{^has visibility="public"}}
|
||||
<div class="post-card-access">
|
||||
{{> "icons/lock"}}
|
||||
{{#has visibility="members"}}
|
||||
Members only
|
||||
{{else}}
|
||||
Paid-members only
|
||||
{{/has}}
|
||||
</div>
|
||||
{{/has}}
|
||||
{{/unless}}
|
||||
|
||||
</a>
|
||||
<a class="post-card-image-link" href="{{url}}">
|
||||
<div class="post-card-image" style="background-image: url({{feature_image}})"></div>
|
||||
</a>
|
||||
{{/if}}
|
||||
|
||||
<div class="post-card-content">
|
||||
|
||||
<a class="post-card-content-link" href="{{url}}">
|
||||
<header class="post-card-header">
|
||||
<div class="post-card-tags">
|
||||
{{#primary_tag}}
|
||||
<span class="post-card-primary-tag">{{name}}</span>
|
||||
{{/primary_tag}}
|
||||
{{#if featured}}
|
||||
<span class="post-card-featured">{{> "icons/fire"}} Featured</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
<h2 class="post-card-title">
|
||||
{{#unless access}}
|
||||
{{^has visibility="public"}}
|
||||
{{#unless feature_image}}
|
||||
{{> "icons/lock"}}
|
||||
{{/unless}}
|
||||
{{/has}}
|
||||
{{/unless}}
|
||||
{{title}}
|
||||
</h2>
|
||||
{{#if primary_tag}}
|
||||
<span class="post-card-tags">{{primary_tag.name}}</span>
|
||||
{{/if}}
|
||||
<h2 class="post-card-title">{{title}}</h2>
|
||||
</header>
|
||||
{{#if excerpt}}
|
||||
<div class="post-card-excerpt">{{excerpt}}</div>
|
||||
{{/if}}
|
||||
<section class="post-card-excerpt">
|
||||
<p>{{excerpt words="33"}}</p>
|
||||
</section>
|
||||
</a>
|
||||
|
||||
<footer class="post-card-meta">
|
||||
<time class="post-card-meta-date" datetime="{{date format="YYYY-MM-DD"}}">{{date}}</time>
|
||||
{{#if reading_time}}
|
||||
<span class="post-card-meta-length">{{reading_time}}</span>
|
||||
{{/if}}
|
||||
{{#if @site.comments_enabled}}
|
||||
{{comment_count}}
|
||||
{{#if author.profile_image}}
|
||||
<img class="author-profile-image" src="{{author.profile_image}}" alt="{{author.name}}" />
|
||||
{{/if}}
|
||||
<span class="post-card-author">{{author}}</span>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
|
||||
</article>
|
||||
|
29
partials/site-nav.hbs
Normal file
@ -0,0 +1,29 @@
|
||||
<nav class="site-nav">
|
||||
<div class="site-nav-left">
|
||||
{{^is "home"}}
|
||||
{{#if @blog.logo}}
|
||||
<a class="site-nav-logo" href="{{@blog.url}}"><img src="{{@blog.logo}}" alt="{{@blog.title}}" /></a>
|
||||
{{else}}
|
||||
<a class="site-nav-logo" href="{{@blog.url}}">{{@blog.title}}</a>
|
||||
{{/if}}
|
||||
{{/is}}
|
||||
{{#if @blog.navigation}}
|
||||
{{navigation}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="site-nav-right">
|
||||
<div class="social-links">
|
||||
{{#if @blog.facebook}}
|
||||
<a class="social-link social-link-fb" href="{{facebook_url @blog.facebook}}" target="_blank">{{> "icons/facebook"}}</a>
|
||||
{{/if}}
|
||||
{{#if @blog.twitter}}
|
||||
<a class="social-link social-link-tw" href="{{twitter_url @blog.twitter}}" target="_blank">{{> "icons/twitter"}}</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{#if @labs.subscribers}}
|
||||
<a class="subscribe-button" href="#subscribe">Subscribe</a>
|
||||
{{else}}
|
||||
<a class="rss-button" href="http://cloud.feedly.com/#subscription/feed/{{@blog.url}}/rss/" target="_blank">{{> "icons/rss"}}</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
</nav>
|
312
post.hbs
@ -1,140 +1,220 @@
|
||||
{{!< default}}
|
||||
|
||||
{{!-- The tag above means: insert everything in this file
|
||||
into the {body} tag of the default.hbs template --}}
|
||||
into the {body} of the default.hbs template --}}
|
||||
|
||||
<header class="site-header outer">
|
||||
<div class="inner">
|
||||
{{> "site-nav"}}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{{!-- Everything inside the #post tags pulls data from the post --}}
|
||||
{{#post}}
|
||||
{{!-- Everything inside the #post block pulls data from the post --}}
|
||||
|
||||
<main id="site-main" class="site-main">
|
||||
<article class="article {{post_class}} {{#match @custom.post_image_style "Full"}}image-full{{else match @custom.post_image_style "=" "Small"}}image-small{{/match}}">
|
||||
<main id="site-main" class="site-main outer" role="main">
|
||||
<div class="inner">
|
||||
|
||||
<header class="article-header gh-canvas">
|
||||
<article class="post-full {{post_class}} {{#unless feature_image}}no-image{{/unless}}">
|
||||
|
||||
<div class="article-tag post-card-tags">
|
||||
{{#primary_tag}}
|
||||
<span class="post-card-primary-tag">
|
||||
<a href="{{url}}">{{name}}</a>
|
||||
</span>
|
||||
{{/primary_tag}}
|
||||
{{#if featured}}
|
||||
<span class="post-card-featured">{{> "icons/fire"}} Featured</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
<header class="post-full-header">
|
||||
<section class="post-full-meta">
|
||||
<time class="post-full-meta-date" datetime="{{date format="YYYY-MM-DD"}}">{{date format="D MMMM YYYY"}}</time>
|
||||
{{#primary_tag}}
|
||||
<span class="date-divider">/</span> <a href="{{url}}">{{name}}</a>
|
||||
{{/primary_tag}}
|
||||
</section>
|
||||
<h1 class="post-full-title">{{title}}</h1>
|
||||
</header>
|
||||
|
||||
<h1 class="article-title">{{title}}</h1>
|
||||
|
||||
{{#if custom_excerpt}}
|
||||
<p class="article-excerpt">{{custom_excerpt}}</p>
|
||||
{{/if}}
|
||||
|
||||
<div class="article-byline">
|
||||
<section class="article-byline-content">
|
||||
|
||||
<ul class="author-list">
|
||||
{{#foreach authors}}
|
||||
<li class="author-list-item">
|
||||
{{#if profile_image}}
|
||||
<a href="{{url}}" class="author-avatar">
|
||||
<img class="author-profile-image" src="{{img_url profile_image size="xs"}}" alt="{{name}}" />
|
||||
</a>
|
||||
{{else}}
|
||||
<a href="{{url}}" class="author-avatar author-profile-image">{{> "icons/avatar"}}</a>
|
||||
{{/if}}
|
||||
</li>
|
||||
{{/foreach}}
|
||||
</ul>
|
||||
|
||||
<div class="article-byline-meta">
|
||||
<h4 class="author-name">{{authors}}</h4>
|
||||
<div class="byline-meta-content">
|
||||
<time class="byline-meta-date" datetime="{{date format="YYYY-MM-DD"}}">{{date}}</time>
|
||||
{{#if reading_time}}
|
||||
<span class="byline-reading-time"><span class="bull">•</span> {{reading_time}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
{{#match @custom.post_image_style "!=" "Hidden"}}
|
||||
{{#if feature_image}}
|
||||
<figure class="article-image">
|
||||
{{!-- This is a responsive image, it loads different sizes depending on device
|
||||
https://medium.freecodecamp.org/a-guide-to-responsive-images-with-ready-to-use-templates-c400bd65c433 --}}
|
||||
<img
|
||||
srcset="{{img_url feature_image size="s"}} 300w,
|
||||
{{img_url feature_image size="m"}} 600w,
|
||||
{{img_url feature_image size="l"}} 1000w,
|
||||
{{img_url feature_image size="xl"}} 2000w"
|
||||
sizes="(min-width: 1400px) 1400px, 92vw"
|
||||
src="{{img_url feature_image size="xl"}}"
|
||||
alt="{{#if feature_image_alt}}{{feature_image_alt}}{{else}}{{title}}{{/if}}"
|
||||
/>
|
||||
{{#if feature_image_caption}}
|
||||
<figcaption>{{feature_image_caption}}</figcaption>
|
||||
{{/if}}
|
||||
{{#if feature_image}}
|
||||
<figure class="post-full-image" style="background-image: url({{feature_image}})">
|
||||
</figure>
|
||||
{{/if}}
|
||||
{{/match}}
|
||||
{{/if}}
|
||||
|
||||
</header>
|
||||
<section class="post-full-content">
|
||||
{{content}}
|
||||
</section>
|
||||
|
||||
<section class="gh-content gh-canvas">
|
||||
{{content}}
|
||||
</section>
|
||||
{{!-- Email subscribe form at the bottom of the page --}}
|
||||
{{#if @labs.subscribers}}
|
||||
<section class="subscribe-form">
|
||||
<h3 class="subscribe-form-title">Subscribe to {{@blog.title}}</h3>
|
||||
<p>Get the latest posts delivered right to your inbox</p>
|
||||
{{subscribe_form placeholder="youremail@example.com"}}
|
||||
</section>
|
||||
{{/if}}
|
||||
|
||||
{{#if comments}}
|
||||
<section class="article-comments gh-canvas">
|
||||
{{comments}}
|
||||
</section>
|
||||
{{/if}}
|
||||
<footer class="post-full-footer">
|
||||
{{!-- Everything inside the #author tags pulls data from the author --}}
|
||||
{{#author}}
|
||||
|
||||
</article>
|
||||
<section class="author-card">
|
||||
{{#if profile_image}}
|
||||
<img class="author-profile-image" src="{{profile_image}}" alt="{{name}}" />
|
||||
{{/if}}
|
||||
<section class="author-card-content">
|
||||
<h4 class="author-card-name"><a href="{{url}}">{{name}}</a></h4>
|
||||
{{#if bio}}
|
||||
<p>{{bio}}</p>
|
||||
{{else}}
|
||||
<p>Read <a href="{{url}}">more posts</a> by this author.</p>
|
||||
{{/if}}
|
||||
</section>
|
||||
</section>
|
||||
<div class="post-full-footer-right">
|
||||
<a class="author-card-button" href="{{url}}">Read More</a>
|
||||
</div>
|
||||
|
||||
{{/author}}
|
||||
</footer>
|
||||
|
||||
{{!--
|
||||
|
||||
If you use Disqus comments, just uncomment this block.
|
||||
The only thing you need to change is "test-apkdzgmqhj" - which
|
||||
should be replaced with your own Disqus site-id.
|
||||
|
||||
<section class="post-full-comments">
|
||||
<div id="disqus_thread"></div>
|
||||
<script>
|
||||
var disqus_config = function () {
|
||||
this.page.url = '{{url absolute="true"}}';
|
||||
this.page.identifier = 'ghost-{{comment_id}}';
|
||||
};
|
||||
(function() {
|
||||
var d = document, s = d.createElement('script');
|
||||
s.src = 'https://test-apkdzgmqhj.disqus.com/embed.js';
|
||||
s.setAttribute('data-timestamp', +new Date());
|
||||
(d.head || d.body).appendChild(s);
|
||||
})();
|
||||
</script>
|
||||
</section>
|
||||
--}}
|
||||
|
||||
</article>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{{!-- A signup call to action is displayed here, unless viewed as a logged-in member --}}
|
||||
{{#if @site.members_enabled}}
|
||||
{{#unless @member}}
|
||||
{{#unless @site.comments_enabled}}
|
||||
{{#if access}}
|
||||
<section class="footer-cta outer">
|
||||
<div class="inner">
|
||||
{{#if @custom.email_signup_text}}<h2 class="footer-cta-title">{{@custom.email_signup_text}}</h2>{{/if}}
|
||||
<a class="footer-cta-button" href="#/portal" data-portal>
|
||||
<div class="footer-cta-input">Enter your email</div>
|
||||
<span>Subscribe</span>
|
||||
</a>
|
||||
{{!-- Links to Previous/Next posts --}}
|
||||
<aside class="read-next outer">
|
||||
<div class="inner">
|
||||
<div class="read-next-feed">
|
||||
|
||||
{{#get "posts" filter="tags:{{primary_tag.slug}}+id:-{{id}}" limit="3" as |related_posts|}}
|
||||
{{#if related_posts}}
|
||||
<article class="read-next-card"
|
||||
{{#if ../primary_tag.feature_image}}
|
||||
style="background-image: url({{../primary_tag.feature_image}})"
|
||||
{{else}}
|
||||
{{#if @blog.cover_image}}
|
||||
style="background-image: url({{@blog.cover_image}})"{{/if}}
|
||||
{{/if}}
|
||||
>
|
||||
<header class="read-next-card-header">
|
||||
<small class="read-next-card-header-sitetitle">— {{@blog.title}} —</small>
|
||||
{{#../primary_tag}}
|
||||
<h3 class="read-next-card-header-title"><a href="{{url}}">{{name}}</a></h3>
|
||||
{{/../primary_tag}}
|
||||
</header>
|
||||
<div class="read-next-divider">{{> "icons/infinity"}}</div>
|
||||
<div class="read-next-card-content">
|
||||
<ul>
|
||||
{{#foreach related_posts}}
|
||||
<li><a href="{{url}}">{{title}}</a></li>
|
||||
{{/foreach}}
|
||||
</ul>
|
||||
</div>
|
||||
<footer class="read-next-card-footer">
|
||||
<a href="{{#../primary_tag}}{{url}}{{/../primary_tag}}">{{plural meta.pagination.total empty='No posts' singular='% post' plural='See all % posts'}} →</a>
|
||||
</footer>
|
||||
</article>
|
||||
{{/if}}
|
||||
{{/get}}
|
||||
|
||||
{{!-- If there's a next post, display it using the same markup included from - partials/post-card.hbs --}}
|
||||
{{#next_post}}
|
||||
{{> "post-card"}}
|
||||
{{/next_post}}
|
||||
|
||||
{{!-- If there's a previous post, display it using the same markup included from - partials/post-card.hbs --}}
|
||||
{{#prev_post}}
|
||||
{{> "post-card"}}
|
||||
{{/prev_post}}
|
||||
|
||||
</div>
|
||||
</section>
|
||||
{{/if}}
|
||||
{{/unless}}
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
{{!-- Floating header which appears on-scroll, included from includes/floating-header.hbs --}}
|
||||
{{> floating-header}}
|
||||
|
||||
{{!-- Read more links, just above the footer --}}
|
||||
{{#if @custom.show_recent_posts_footer}}
|
||||
{{!-- The {#get} helper below fetches some of the latest posts here
|
||||
so that people have something else to read when they finish this one.
|
||||
{{/post}}
|
||||
|
||||
This query gets the latest 3 posts on the site, but adds a filter to
|
||||
exclude the post we're currently on from being included. --}}
|
||||
{{#get "posts" filter="id:-{{id}}" limit="3" as |more_posts|}}
|
||||
{{!-- The #contentFor helper here will send everything inside it up to the matching #block helper found in default.hbs --}}
|
||||
{{#contentFor "scripts"}}
|
||||
<script>
|
||||
|
||||
{{#if more_posts}}
|
||||
<aside class="read-more-wrap outer">
|
||||
<div class="read-more inner">
|
||||
{{#foreach more_posts}}
|
||||
{{> "post-card"}}
|
||||
{{/foreach}}
|
||||
</div>
|
||||
</aside>
|
||||
{{/if}}
|
||||
// NOTE: Scroll performance is poor in Safari
|
||||
// - this appears to be due to the events firing much more slowly in Safari.
|
||||
// Dropping the scroll event and using only a raf loop results in smoother
|
||||
// scrolling but continuous processing even when not scrolling
|
||||
$(document).ready(function () {
|
||||
// Start fitVids
|
||||
var $postContent = $(".post-full-content");
|
||||
$postContent.fitVids();
|
||||
// End fitVids
|
||||
|
||||
{{/get}}
|
||||
{{/if}}
|
||||
var progressBar = document.querySelector('progress');
|
||||
var header = document.querySelector('.floating-header');
|
||||
var title = document.querySelector('.post-full-title');
|
||||
|
||||
{{/post}}
|
||||
var lastScrollY = window.scrollY;
|
||||
var lastWindowHeight = window.innerHeight;
|
||||
var lastDocumentHeight = $(document).height();
|
||||
var ticking = false;
|
||||
|
||||
function onScroll() {
|
||||
lastScrollY = window.scrollY;
|
||||
requestTick();
|
||||
}
|
||||
|
||||
function onResize() {
|
||||
lastWindowHeight = window.innerHeight;
|
||||
lastDocumentHeight = $(document).height();
|
||||
requestTick();
|
||||
}
|
||||
|
||||
function requestTick() {
|
||||
if (!ticking) {
|
||||
requestAnimationFrame(update);
|
||||
}
|
||||
ticking = true;
|
||||
}
|
||||
|
||||
function update() {
|
||||
var trigger = title.getBoundingClientRect().top + window.scrollY;
|
||||
var triggerOffset = title.offsetHeight + 35;
|
||||
var progressMax = lastDocumentHeight - lastWindowHeight;
|
||||
|
||||
// show/hide floating header
|
||||
if (lastScrollY >= trigger + triggerOffset) {
|
||||
header.classList.add('floating-active');
|
||||
} else {
|
||||
header.classList.remove('floating-active');
|
||||
}
|
||||
|
||||
progressBar.setAttribute('max', progressMax);
|
||||
progressBar.setAttribute('value', lastScrollY);
|
||||
|
||||
ticking = false;
|
||||
}
|
||||
|
||||
window.addEventListener('scroll', onScroll, {passive: true});
|
||||
window.addEventListener('resize', onResize, false);
|
||||
|
||||
update();
|
||||
});
|
||||
</script>
|
||||
{{/contentFor}}
|
||||
|
76
tag.hbs
@ -1,55 +1,33 @@
|
||||
{{!< default}}
|
||||
{{!-- The tag above means - insert everything in this file into the {body} of the default.hbs template --}}
|
||||
|
||||
<main id="site-main" class="site-main outer">
|
||||
<div class="inner posts">
|
||||
<div class="post-feed">
|
||||
|
||||
{{#tag}}
|
||||
<section class="post-card post-card-large">
|
||||
|
||||
{{#if feature_image}}
|
||||
<div class="post-card-image-link">
|
||||
{{!-- This is a responsive image, it loads different sizes depending on device
|
||||
https://medium.freecodecamp.org/a-guide-to-responsive-images-with-ready-to-use-templates-c400bd65c433 --}}
|
||||
<img class="post-card-image"
|
||||
srcset="{{img_url feature_image size="s"}} 300w,
|
||||
{{img_url feature_image size="m"}} 600w,
|
||||
{{img_url feature_image size="l"}} 1000w,
|
||||
{{img_url feature_image size="xl"}} 2000w"
|
||||
sizes="(max-width: 1000px) 400px, 800px"
|
||||
src="{{img_url feature_image size="m"}}"
|
||||
alt="{{title}}"
|
||||
/>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="post-card-content">
|
||||
<div class="post-card-content-link">
|
||||
<header class="post-card-header">
|
||||
<h2 class="post-card-title">{{name}}</h2>
|
||||
</header>
|
||||
<div class="post-card-excerpt">
|
||||
{{#if description}}
|
||||
{{description}}
|
||||
{{else}}
|
||||
A collection of {{plural ../pagination.total empty='zero posts' singular='% post' plural='% posts'}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
{{/tag}}
|
||||
|
||||
{{#foreach posts}}
|
||||
{{!-- The tag below includes the markup for each post - partials/post-card.hbs --}}
|
||||
{{> "post-card"}}
|
||||
{{/foreach}}
|
||||
|
||||
{{!-- The big featured header, it uses blog cover image as a BG if available --}}
|
||||
{{#tag}}
|
||||
<header class="site-header outer {{#if feature_image}}" style="background-image: url({{feature_image}}){{else}}no-cover{{/if}}">
|
||||
<div class="inner">
|
||||
{{> "site-nav"}}
|
||||
<div class="site-header-content">
|
||||
<h1 class="site-title">{{name}}</h1>
|
||||
<h2 class="site-description">
|
||||
{{#if description}}
|
||||
{{description}}
|
||||
{{else}}
|
||||
A collection of {{plural ../pagination.total empty='posts' singular='% post' plural='% posts'}}
|
||||
{{/if}}
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
{{/tag}}
|
||||
|
||||
{{pagination}}
|
||||
|
||||
</div>
|
||||
{{!-- The main content area --}}
|
||||
<main id="site-main" class="site-main outer" role="main">
|
||||
<div class="inner">
|
||||
<div class="post-feed">
|
||||
{{#foreach posts}}
|
||||
{{!-- The tag below includes the markup for each post - partials/post-card.hbs --}}
|
||||
{{> "post-card"}}
|
||||
{{/foreach}}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|