Compare commits

...

103 Commits
5.4.1 ... main

Author SHA1 Message Date
4710ac85d6
Merge pull request #11 from spaytac/v5.6.0
Some checks reported warnings
NodeJS with Gulp / build (18.x) (push) Has been cancelled
NodeJS with Gulp / release (push) Has been cancelled
V5.6.0
2023-08-04 10:49:45 +02:00
92bd3eb4a7 **update** merged with origin 2023-08-04 10:46:35 +02:00
0bd5d16246 Merge branch 'main' into v5.6.0
# Conflicts:
#	LICENSE
#	README.md
#	assets/built/global.css
#	assets/built/global.css.map
#	assets/built/screen.css
#	assets/built/screen.css.map
#	assets/css/global.css
#	package.json
#	page.hbs
2023-08-04 09:54:52 +02:00
bae9f5f49b **update** merged with origin 2023-08-04 09:50:27 +02:00
John O'Nolan
592226b75e
2023 2023-08-03 20:38:12 +01:00
Steve Larson
9f9348544e v5.6.0 2023-07-31 13:51:45 -05:00
Sodbileg Gansukh
840b1b9c50 Switched from padding to margin for page card spacing 2023-07-24 16:58:30 +08:00
Sodbileg Gansukh
cc3fca004f Fixed cards not having space below 2023-07-22 00:08:12 +08:00
Sodbileg Gansukh
f8b34f9786 Fixed article header spacing on post template 2023-07-19 19:05:22 +08:00
Sodbileg Gansukh
b9f5d591d3 Rebuilt assets 2023-07-19 10:14:41 +08:00
Sanne de Vries
a60e3e976a
Updated hiding page title and feature image implementation (#946)
https://github.com/TryGhost/Product/issues/3568
2023-07-17 20:31:26 +08:00
Sanne de Vries
d9c9390e17
Removed padding between navigation and full width content (#944) 2023-07-17 16:26:18 +08:00
Sanne de Vries
84f201d293 Updated class to 'kg-card-hascaption'
Refs https://github.com/TryGhost/Product/issues/3589
2023-07-13 18:32:48 +08:00
Sanne de Vries
c7fdfb7479 Removed spacing between full-width cards
Refs https://github.com/TryGhost/Product/issues/3589
2023-07-13 18:32:48 +08:00
Sanne de Vries
d3483498d4
Added support for hidden title and feature image on pages (#943)
* Added support for hidden title and feature image on pages

Refs https://github.com/TryGhost/Product/issues/3568

* Switched from match to if helper for show_title_and_feature_image

Refs https://github.com/TryGhost/Product/issues/3568
2023-07-10 12:19:00 +02:00
Sodbileg Gansukh
4ae190c1a6 v5.5.3 2023-07-06 09:46:25 +08:00
Sodbileg Gansukh
22c83f9128 Fixed tag and author description character limit 2023-07-06 09:46:03 +08:00
Sodbileg Gansukh
10fd2f3a1c v5.5.2 2023-07-03 18:52:41 +08:00
Sodbileg Gansukh
b1a10873ff Fixed nested list spacing 2023-07-03 18:03:47 +08:00
Sodbileg Gansukh
0e76b5abef Removed unnecessary JS hack for nested list 2023-07-03 17:37:39 +08:00
Sodbileg Gansukh
d75ffc78ac Added nested list support 2023-06-28 18:25:13 +08:00
Sodbileg Gansukh
fa76f77006 Consistent syntax 2023-06-27 13:01:12 +08:00
Rafael Corrêa Gomes
dda827ded3 Head > Adding preload 2023-06-27 12:59:56 +08:00
Sanne de Vries
bdf150658e v5.5.1 2023-06-22 21:19:57 +02:00
Sanne de Vries
2fafe722d1 Added grid to full width cards with wide content
Refs https://github.com/TryGhost/Team/issues/3459
2023-06-22 21:17:03 +02:00
Sodbileg Gansukh
0721600075 v5.5.0 2023-06-22 17:17:43 +08:00
Sodbileg Gansukh
a18367200f Updated post content grid for additional widths 2023-06-22 16:37:59 +08:00
Sodbileg Gansukh
294b1e30e5 v5.4.12 2023-06-20 12:09:25 +08:00
Sodbileg Gansukh
aa8ca0794b Fixed main nav background color in dark mode
closes https://github.com/TryGhost/Casper/issues/942
2023-06-20 12:09:08 +08:00
6fbaffb998
Merge pull request #10 from spaytac/v5.4.11
V5.4.11
2023-06-07 14:59:29 +02:00
01b04e59da
Merge branch 'main' into v5.4.11 2023-06-07 14:56:41 +02:00
5ba628d1a3 **update** merged with origin 2023-06-07 14:51:10 +02:00
6abe0a1e25 **update** 2023-06-07 12:48:56 +00:00
2fa6b68cc3 **update** merged with origin 2023-06-07 14:48:08 +02:00
Sodbileg Gansukh
ba0b3d08cc v5.4.11 2023-05-09 13:30:12 +08:00
Sodbileg Gansukh
50d5727f77 Fixed mobile menu background in dark mode
no issues

- when there's no publication cover and the color scheme is in dark mode, the mobile menu had white background
- this fixes the issue by adding explicit dark mode rules to the styles
2023-05-09 13:27:37 +08:00
Sodbileg Gansukh
23f7c30365 v5.4.10 2023-04-21 09:49:57 +01:00
Sodbileg Gansukh
8ff3c6fcf1 Fixed main nav to make it work with the announcement bar 2023-04-21 09:49:37 +01:00
78b58e47dd
Merge pull request #9 from spaytac/v5.4.9
Some checks failed
release
build (18.x)
V5.4.9
2023-04-12 09:55:07 +02:00
14c5d004f4 **update** merged with origin 2023-04-12 09:54:04 +02:00
d1595f421a Merge remote-tracking branch 'origin/v5.4.9' into v5.4.9
# Conflicts:
#	assets/built/casper.js.map
#	assets/built/screen.css
#	assets/built/screen.css.map
#	assets/css/screen.css
#	assets/js/dropdown.js
#	package.json
2023-04-11 11:41:57 +02:00
Sodbileg Gansukh
5c7fb39df9 v5.4.9 2023-04-10 13:42:17 +08:00
Sodbileg Gansukh
4851606d9d Rebuilt assets 2023-04-10 13:41:59 +08:00
Rob Leslie
afca9cb27e Fix problem showing dropdown after window resize
When the browser window is resized, a new click event listener is added
to the window but the old one is not removed. The old one ends up
preventing the newly-made dropdown from opening.

Fix this by remembering the click event listener function added to the
window, and remove it before making the new dropdown after a window
resize.
2023-04-10 13:40:33 +08:00
Sodbileg Gansukh
b56bec2cb8 Fixed header action background color for smaller screens
closes #934

- the accent color is used for the header background, so we don't need to add explicit dark mode color to the action on mobile screens
2023-04-10 13:24:11 +08:00
ed555444ff **update** github actions 2023-03-31 10:57:01 +02:00
c9ff48c131 **update** github actions 2023-03-31 10:54:20 +02:00
34493249e2 **update** github actions 2023-03-31 10:11:07 +02:00
4e27a49fcf **update** github actions 2023-03-31 10:08:13 +02:00
92de638579
Merge pull request #8 from spaytac/feature/cr-github-actions
Create yarn-gulp.yml
2023-03-31 09:49:07 +02:00
37d5139f22
Create yarn-gulp.yml 2023-03-31 09:46:59 +02:00
210f2fa112
Merge pull request #7 from spaytac/v5.4.8
V5.4.8
2023-03-30 13:37:07 +02:00
a462835afc Merge branch 'v5.4.8' of github.com:spaytac/Casper into v5.4.8
# Conflicts:
#	default.hbs
#	package.json
#	yarn.lock
2023-03-29 17:08:20 +02:00
Sodbileg Gansukh
0c4164c5bd v5.4.8 2023-03-28 16:01:50 +08:00
Sodbileg Gansukh
e6326eadf9 Added a class name to the powered by text
no issues

- our other themes have this class, and this makes it consistent across over all offcial themes
2023-03-28 16:01:24 +08:00
renovate[bot]
3ed94d68fa Update dependency gscan to v4.36.1 2023-03-07 09:25:32 +01:00
c1571e5a4e
Merge pull request #6 from spaytac/v5.4.7
V5.4.7
2023-03-06 12:27:15 +01:00
db6a864b90 **update** minor changes for tag page 2023-03-06 12:26:13 +01:00
3e4aba10fe **update** merged with changes from orig repo v547 2023-03-06 11:17:13 +00:00
88bdc1fc4b Merge branch 'main' into v5.4.7
# Conflicts:
#	assets/built/screen.css
#	assets/built/screen.css.map
#	error.hbs
#	package.json
2023-03-06 12:08:46 +01:00
50991c37ca **update** minor changes for tag page 2023-03-06 12:07:13 +01:00
Sodbileg Gansukh
505503a63b v5.4.7 2023-03-01 13:54:29 +08:00
Sodbileg Gansukh
bd3fc7c2af Fixed textarea color in dark mode 2023-03-01 13:53:58 +08:00
Sodbileg Gansukh
5e0f765852 v5.4.6 2023-02-28 13:57:36 +08:00
Sodbileg Gansukh
4293dab0a7 Fixed burger menu icon visibility on dark mode
refs #925
2023-02-28 13:57:05 +08:00
Cory
f00918589f Update comment grammar 2023-02-27 17:13:31 +08:00
Nicholas Fasching
0200889148 Fix Table of Contents Numbering in screen.css 2023-02-27 15:39:25 +08:00
Mark Stosberg
248c122f86 re-add aria-label to search button for screen readers
This was added by https://github.com/TryGhost/Casper/pull/896 

but then appears to have been accidentally reverted in the merge of https://github.com/TryGhost/Casper/pull/906
2023-02-27 15:10:09 +08:00
acf3b0383d
Merge pull request #5 from spaytac/v5.5.5
V5.5.5
2023-02-07 11:57:08 +01:00
4f0e6e92e1 **update** minor changes for tag page 2023-02-07 11:55:12 +01:00
5f396d1b98 Merge remote-tracking branch 'origin/v5.5.5' into v5.5.5
# Conflicts:
#	author.hbs
#	package.json
2023-02-07 11:48:45 +01:00
Daniel Lockyer
a007415d89
v5.4.5 2023-01-20 09:50:01 +01:00
Peter Zimon
31188ce3c0 Fixed author's cover image not showing up
no refs.

The author's cover image didn't show up on the theme because the author template used `feature_image` instead of `cover_image`.
2023-01-19 09:51:08 +01:00
716a1a749f
Merge pull request #4 from spaytac/v5.4.4
V5.4.4
2022-12-21 11:05:22 +01:00
f6128d473c Merge branch 'pre544' into v5.4.4
# Conflicts:
#	assets/built/casper.js.map
#	assets/built/screen.css
#	assets/built/screen.css.map
#	package.json
2022-12-20 17:40:55 +01:00
37132a168a **update** minor changes for tag page 2022-12-20 17:39:36 +01:00
Sodbileg Gansukh
e1967f8546 v5.4.4 2022-12-16 12:35:19 +08:00
Sodbileg Gansukh
5259d551f5 Fixed mobile navbar height 2022-12-16 12:33:11 +08:00
Sodbileg Gansukh
115d1d820c Fixed sign in link placement on mobile screen
fixes #913
2022-12-16 12:12:22 +08:00
Sodbileg Gansukh
81e4dfd52d Minor spacing adjustment 2022-12-16 12:02:08 +08:00
Sodbileg Gansukh
cc4d828575 Fixed logo visibility when the header is hidden 2022-12-16 11:57:59 +08:00
11d5eacc72 Merge branch 'pre543' into v5.4.3 2022-12-15 15:34:07 +01:00
beaacb4bcb **update** minor changes for tag page 2022-12-15 15:33:49 +01:00
d3bf2b05d2 **update** minor changes for tag page 2022-12-15 15:32:04 +01:00
28bdf273f3 Merge remote-tracking branch 'origin/v5.4.3' into pre543
# Conflicts:
#	assets/built/casper.js.map
#	assets/built/screen.css
#	assets/built/screen.css.map
#	assets/css/screen.css
#	assets/js/dropdown.js
#	default.hbs
#	package.json
2022-12-15 14:54:33 +01:00
ad518db147 **update** minor changes for tag page 2022-12-15 14:49:15 +01:00
91ed758fc9 **update** minor changes for tag page 2022-12-15 14:47:29 +01:00
b7bbd91565 **update** pre543 2022-12-15 13:38:09 +00:00
Sodbileg Gansukh
ebb2538215 v5.4.3 2022-12-15 10:12:38 +08:00
Sodbileg Gansukh
3767e3d994 Adjusted the pagination to dark mode 2022-12-15 10:00:58 +08:00
Sodbileg Gansukh
6d290485dc Fixed account button background 2022-12-15 09:55:41 +08:00
Sodbileg Gansukh
7da41d344f Added sign in link to the navbar 2022-12-14 16:42:46 +08:00
2d9ba902b4 **update** merge with 5.4.2 from origin 2022-12-12 10:36:25 +01:00
3c2814775b **update** merged with origin 2022-12-12 10:31:35 +01:00
a5eba98b08 Merge branch 'TryGhost-main' into v5.4.2-merge 2022-12-12 09:30:32 +00:00
1572dda395 Updated 2022-12-12 09:23:27 +00:00
3f9d47ae65 Merge branch 'main' of github.com:TryGhost/Casper into TryGhost-main 2022-12-12 09:22:09 +00:00
Sodbileg Gansukh
55a90a9252 v5.4.2 2022-12-12 14:55:31 +08:00
Sodbileg Gansukh
b20dceae22 Rebuilt assets 2022-12-12 14:55:02 +08:00
Sodbileg Gansukh
88ca182a58 Added regular pagination option
Casper comes with infinite scrolling by default. This update makes it possible to go with the default pagination style when the <html> element has a class no-infinite-scroll.
2022-12-08 12:50:24 +08:00
4510d7144b Merge branch 'main' of github.com:spaytac/Casper
# Conflicts:
#	assets/built/screen.css
#	assets/built/screen.css.map
2022-12-07 10:06:17 +01:00
91f3621491 **update** minor changes for tag page 2022-12-07 10:03:33 +01:00
Sodbileg Gansukh
140632b885 fixes #910
When the publication cover is turned off and the header style is set to hidden, the header section shouldn't be taking much space like it does regularly.
2022-12-07 15:29:23 +08:00
42 changed files with 7226 additions and 7030 deletions

View File

@ -1,14 +1,14 @@
# [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18, 16, 14, 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster
ARG VARIANT=16-bullseye
FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT}
# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>
# [Optional] Uncomment if you want to install an additional version of node using nvm
# ARG EXTRA_NODE_VERSION=10
# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}"
# [Optional] Uncomment if you want to install more global node modules
# RUN su node -c "npm install -g <your-package-list-here>"
# [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18, 16, 14, 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster
ARG VARIANT=16-bullseye
FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT}
# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>
# [Optional] Uncomment if you want to install an additional version of node using nvm
# ARG EXTRA_NODE_VERSION=10
# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}"
# [Optional] Uncomment if you want to install more global node modules
# RUN su node -c "npm install -g <your-package-list-here>"

View File

@ -1,55 +1,55 @@
# [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster
ARG VARIANT=16-bullseye
FROM node:${VARIANT}
# [Option] Install zsh
ARG INSTALL_ZSH="true"
# [Option] Upgrade OS packages to their latest versions
ARG UPGRADE_PACKAGES="true"
# Install needed packages, yarn, nvm and setup non-root user. Use a separate RUN statement to add your own dependencies.
ARG USERNAME=node
ARG USER_UID=1000
ARG USER_GID=$USER_UID
ARG NPM_GLOBAL=/usr/local/share/npm-global
ENV NVM_DIR=/usr/local/share/nvm
ENV NVM_SYMLINK_CURRENT=true \
PATH=${NPM_GLOBAL}/bin:${NVM_DIR}/current/bin:${PATH}
COPY library-scripts/*.sh library-scripts/*.env /tmp/library-scripts/
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# Remove imagemagick due to https://security-tracker.debian.org/tracker/CVE-2019-10131
&& apt-get purge -y imagemagick imagemagick-6-common \
# Install common packages, non-root user, update yarn and install nvm
&& bash /tmp/library-scripts/common-debian.sh "${INSTALL_ZSH}" "${USERNAME}" "${USER_UID}" "${USER_GID}" "${UPGRADE_PACKAGES}" "true" "true" \
# Install yarn, nvm
&& rm -rf /opt/yarn-* /usr/local/bin/yarn /usr/local/bin/yarnpkg \
&& bash /tmp/library-scripts/node-debian.sh "${NVM_DIR}" "none" "${USERNAME}" \
# Configure global npm install location, use group to adapt to UID/GID changes
&& if ! cat /etc/group | grep -e "^npm:" > /dev/null 2>&1; then groupadd -r npm; fi \
&& usermod -a -G npm ${USERNAME} \
&& umask 0002 \
&& mkdir -p ${NPM_GLOBAL} \
&& touch /usr/local/etc/npmrc \
&& chown ${USERNAME}:npm ${NPM_GLOBAL} /usr/local/etc/npmrc \
&& chmod g+s ${NPM_GLOBAL} \
&& npm config -g set prefix ${NPM_GLOBAL} \
&& sudo -u ${USERNAME} npm config -g set prefix ${NPM_GLOBAL} \
# Install eslint
&& su ${USERNAME} -c "umask 0002 && npm install -g eslint" \
&& npm cache clean --force > /dev/null 2>&1 \
# Install python-is-python3 on bullseye to prevent node-gyp regressions
&& . /etc/os-release \
&& if [ "${VERSION_CODENAME}" = "bullseye" ]; then apt-get -y install --no-install-recommends python-is-python3; fi \
# Clean up
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /root/.gnupg /tmp/library-scripts
# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>
# [Optional] Uncomment if you want to install an additional version of node using nvm
# ARG EXTRA_NODE_VERSION=10
# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}"
# [Optional] Uncomment if you want to install more global node modules
# [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster
ARG VARIANT=16-bullseye
FROM node:${VARIANT}
# [Option] Install zsh
ARG INSTALL_ZSH="true"
# [Option] Upgrade OS packages to their latest versions
ARG UPGRADE_PACKAGES="true"
# Install needed packages, yarn, nvm and setup non-root user. Use a separate RUN statement to add your own dependencies.
ARG USERNAME=node
ARG USER_UID=1000
ARG USER_GID=$USER_UID
ARG NPM_GLOBAL=/usr/local/share/npm-global
ENV NVM_DIR=/usr/local/share/nvm
ENV NVM_SYMLINK_CURRENT=true \
PATH=${NPM_GLOBAL}/bin:${NVM_DIR}/current/bin:${PATH}
COPY library-scripts/*.sh library-scripts/*.env /tmp/library-scripts/
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# Remove imagemagick due to https://security-tracker.debian.org/tracker/CVE-2019-10131
&& apt-get purge -y imagemagick imagemagick-6-common \
# Install common packages, non-root user, update yarn and install nvm
&& bash /tmp/library-scripts/common-debian.sh "${INSTALL_ZSH}" "${USERNAME}" "${USER_UID}" "${USER_GID}" "${UPGRADE_PACKAGES}" "true" "true" \
# Install yarn, nvm
&& rm -rf /opt/yarn-* /usr/local/bin/yarn /usr/local/bin/yarnpkg \
&& bash /tmp/library-scripts/node-debian.sh "${NVM_DIR}" "none" "${USERNAME}" \
# Configure global npm install location, use group to adapt to UID/GID changes
&& if ! cat /etc/group | grep -e "^npm:" > /dev/null 2>&1; then groupadd -r npm; fi \
&& usermod -a -G npm ${USERNAME} \
&& umask 0002 \
&& mkdir -p ${NPM_GLOBAL} \
&& touch /usr/local/etc/npmrc \
&& chown ${USERNAME}:npm ${NPM_GLOBAL} /usr/local/etc/npmrc \
&& chmod g+s ${NPM_GLOBAL} \
&& npm config -g set prefix ${NPM_GLOBAL} \
&& sudo -u ${USERNAME} npm config -g set prefix ${NPM_GLOBAL} \
# Install eslint
&& su ${USERNAME} -c "umask 0002 && npm install -g eslint" \
&& npm cache clean --force > /dev/null 2>&1 \
# Install python-is-python3 on bullseye to prevent node-gyp regressions
&& . /etc/os-release \
&& if [ "${VERSION_CODENAME}" = "bullseye" ]; then apt-get -y install --no-install-recommends python-is-python3; fi \
# Clean up
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /root/.gnupg /tmp/library-scripts
# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>
# [Optional] Uncomment if you want to install an additional version of node using nvm
# ARG EXTRA_NODE_VERSION=10
# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}"
# [Optional] Uncomment if you want to install more global node modules
# RUN su node -c "npm install -g <your-package-list-here>""

View File

@ -1,32 +1,32 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/javascript-node
{
"name": "Node.js",
"build": {
"dockerfile": "Dockerfile",
// Update 'VARIANT' to pick a Node version: 18, 16, 14.
// Append -bullseye or -buster to pin to an OS version.
// Use -bullseye variants on local arm64/Apple Silicon.
"args": { "VARIANT": "16-bullseye" }
},
// Configure tool-specific properties.
"customizations": {
// Configure properties specific to VS Code.
"vscode": {
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"dbaeumer.vscode-eslint"
]
}
},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "yarn install",
// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "node"
}
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/javascript-node
{
"name": "Node.js",
"build": {
"dockerfile": "Dockerfile",
// Update 'VARIANT' to pick a Node version: 18, 16, 14.
// Append -bullseye or -buster to pin to an OS version.
// Use -bullseye variants on local arm64/Apple Silicon.
"args": { "VARIANT": "16-bullseye" }
},
// Configure tool-specific properties.
"customizations": {
// Configure properties specific to VS Code.
"vscode": {
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"dbaeumer.vscode-eslint"
]
}
},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "yarn install",
// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "node"
}

44
.github/workflows/yarn-gulp.yml vendored Normal file
View File

@ -0,0 +1,44 @@
name: NodeJS with Gulp
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
# node-version: [14.x, 16.x, 18.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
- name: Install dependencies
run: yarn
- name: Theme Test
run: yarn test
- name: Build & zip package
run: yarn zip
release:
runs-on: ubuntu-latest
needs: [build]
steps:
- uses: actions/checkout@master
- name: Create release
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
files: dist/casper-aytac.zip
draft: true
env:
GITHUB_TOKEN: ${{ secrets.GST_TOKEN }}

56
.gitignore vendored
View File

@ -1,28 +1,28 @@
b-cov
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz
pids
logs
results
npm-debug.log
node_modules
package-lock.json
.idea/*
*.iml
projectFilesBackup
.DS_Store
dist/
config.json
changelog.md
changelog.md.bk
b-cov
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz
pids
logs
results
npm-debug.log
node_modules
package-lock.json
.idea/*
*.iml
projectFilesBackup
.DS_Store
dist/
config.json
changelog.md
changelog.md.bk

View File

@ -1,4 +1,4 @@
Copyright (c) 2013-2022 Ghost Foundation
Copyright (c) 2013-2023 Ghost Foundation
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -89,17 +89,10 @@ video {
body {
line-height: 1;
}
ol,
ul {
list-style: none;
}
blockquote,
q {
quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
@ -107,18 +100,15 @@ q:after {
content: "";
content: none;
}
table {
border-spacing: 0;
border-collapse: collapse;
}
img {
display: block;
max-width: 100%;
height: auto;
}
html {
box-sizing: border-box;
font-family: sans-serif;
@ -126,42 +116,34 @@ html {
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
a {
background-color: transparent;
}
a:active,
a:hover {
outline: 0;
}
b,
strong {
font-weight: bold;
}
i,
em,
dfn {
font-style: italic;
}
h1 {
margin: 0.67em 0;
font-size: 2em;
}
small {
font-size: 80%;
}
sub,
sup {
position: relative;
@ -169,27 +151,21 @@ sup {
line-height: 0;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
img {
border: 0;
}
svg:not(:root) {
overflow: hidden;
}
mark {
background-color: #fdffb6;
}
code,
kbd,
pre,
@ -197,7 +173,6 @@ samp {
font-family: monospace, monospace;
font-size: 1em;
}
kbd {
padding: 3px 5px;
font-family: var(--font-mono);
@ -207,109 +182,81 @@ kbd {
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,
select,
textarea {
margin: 0;
/* 3 */
color: inherit;
/* 1 */
font: inherit;
/* 2 */
margin: 0; /* 3 */
color: inherit; /* 1 */
font: inherit; /* 2 */
}
button {
overflow: visible;
border: none;
}
button,
select {
text-transform: none;
}
button,
html input[type="button"],
/* 1 */
input[type="reset"],
input[type="submit"] {
cursor: pointer;
/* 3 */
cursor: pointer; /* 3 */
-webkit-appearance: button;
/* 2 */
-webkit-appearance: button; /* 2 */
}
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;
/* 1 */
padding: 0;
/* 2 */
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
height: auto;
}
input[type="search"] {
box-sizing: content-box;
/* 2 */
box-sizing: content-box; /* 2 */
-webkit-appearance: textfield;
/* 1 */
-webkit-appearance: textfield; /* 1 */
}
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
legend {
padding: 0;
/* 2 */
border: 0;
/* 1 */
padding: 0; /* 2 */
border: 0; /* 1 */
}
textarea {
overflow: auto;
}
table {
border-spacing: 0;
border-collapse: collapse;
}
td,
th {
padding: 0;
@ -324,7 +271,6 @@ html {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
body {
color: var(--color-darkgrey);
font-family: var(--font-sans);
@ -415,7 +361,7 @@ li {
line-height: 1.6em;
}
li+li {
li + li {
margin-top: 0.5em;
}
@ -445,7 +391,6 @@ blockquote small {
font-size: 0.9em;
opacity: 0.8;
}
/* Quotation marks */
blockquote small:before {
content: "\2014 \00A0";
@ -454,7 +399,6 @@ blockquote small:before {
blockquote cite {
font-weight: bold;
}
blockquote cite a {
font-weight: normal;
}
@ -483,7 +427,6 @@ h1 {
font-weight: 700;
letter-spacing: -0.015em;
}
@media (max-width: 600px) {
h1 {
font-size: 2.8rem;
@ -495,7 +438,6 @@ h2 {
font-size: 2.8rem;
font-weight: 700;
}
@media (max-width: 600px) {
h2 {
font-size: 2.3rem;
@ -507,7 +449,6 @@ h3 {
font-size: 2.4rem;
font-weight: 600;
}
@media (max-width: 600px) {
h3 {
font-size: 1.7rem;
@ -518,7 +459,6 @@ h4 {
margin: 1.5em 0 0.5em 0;
font-size: 2rem;
}
@media (max-width: 600px) {
h4 {
font-size: 1.7rem;
@ -534,188 +474,3 @@ h6 {
margin: 1.5em 0 0.5em 0;
font-size: 1.8rem;
}
.post-tag-content {
padding: max(8vmin,40px) max(4vmin,20px) max(8vmin,64px);
position: relative;
margin: 0 auto;
max-width: 1200px;
width: 100%;
}
.post-tag-grid {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
column-gap: 30px;
row-gap: 30px;
}
@media screen and (max-width: 1080px) {
.post-tag-grid {
column-gap: 30px;
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
row-gap: 30px;
}
}
@media (max-width: 767px) {
.site-footer .post-tag-content {
max-width: 500px;
grid-template-columns: 1fr;
grid-gap: 0;
text-align: center;
}
.site-footer .copyright,
.site-footer .copyright a {
color: #fff;
font-size: 1.5rem;
}
.site-footer .copyright {
margin-bottom: 16px;
}
}
@media screen and (max-width: 700px) {
.post-tag-grid {
column-gap: 30px;
display: grid;
grid-template-columns: minmax(0,1fr);
row-gap: 30px;
}
}
.post-tag-grid-item {
overflow: hidden;
text-align:center;
}
.post-tag-grid-item-svg{
width: 320px;
height: 180px;
}
.post-tag-grid-item-svg-first{
height: 180px;
width: 80px;
fill: var(--ghost-accent-color);
}
.post-tag-grid-item-svg-first-obj{
height: 28px;
width: 80px;
x:0;
y:80;
}
.post-tag-grid-item-svg-first-obj-text{
color: white;
font-size: 32px;
}
.post-tag-grid-item-svg-second, .post-tag-grid-item-svg-second-obj{
height: 180px;
width: 240px;
x: 80;
y: 0;
}
.post-tag-grid-item-svg-second-obj-inner{
padding: max(0.5vmin,2px);
}
.post-tag-grid-item-svg-second{
fill: black;
}
.post-tag-grid-item-svg-second-obj, .post-tag-grid-item-svg-second-obj-description{
color: white;
}
.post-tag-grid-item h2 {
font-size: 28px;
margin: 0.3em 0;
position: relative;
text-align: center;
text-transform: uppercase;
}
.post-tag-grid-item-subtext:after,
.post-tag-grid-item-subtext:before {
content: " ";
height: 1px;
background: #000;
flex: 1;
}
.post-tag-grid-item-subtext:after {
margin-left: 5px;
}
.post-tag-grid-item-subtext:before {
margin-right: 5px;
}
.post-tags {
margin: 1.2em 0em -1em;
}
.post-tags a {
border-bottom: none !important;
font-size: small;
margin: 0 1% 0 0
}
.post-tags a .post-tag-title::before {
content: '#'
}
.post-tags a .post-tag-title {
margin-top: 2%
}
.post-tags a .post-tag-title:hover {
background-color: var(--color-background-hover);
color: var(--ghost-main-color) !important;
}
@media screen and (max-width: 980px) {
article .post-tags a .post-tag-title {
margin-top: 2%
}
}
.post-tags .post-tags-box-label {
font-size: 1rem;
line-height: 1em;
font-weight: 600;
text-transform: uppercase;
color: --color-content-light
}
.article-share{
margin: 6vmin 0 0;
}
.article-share ul {
list-style: none;
padding-left: 0em;
}
.article-share li {
display: inline;
padding-left: 0em;
}
.article-share li+li {
padding-left: 0.3em;
}
a.social-share-link svg {
height: 32px;
width: 32px;
}
.post-card-title-custom{
text-transform: uppercase;
}

View File

@ -6,20 +6,19 @@ production stylesheet in assets/built/screen.css
1. Global Styles
2. Layout
3. Special Templates
4. Site Header
5. Site Navigation
6. Post Feed
7. Single Post
7.1. Post Byline
7.2. Members Subscribe Form
7.4. Related Posts
7.5. Koenig Styles
7.6 Comments
8. Author Template
3. Site Header
4. Site Navigation
5. Post Feed
6. Single Post
6.1. Post Byline
6.2. Subscribe
6.3. Read More
6.4. Comments
7. Author Template
8. Tag Template
9. Error Template
11. Site Footer
12. Dark Mode
10. Site Footer
11. Dark Mode
*/
@ -64,6 +63,7 @@ production stylesheet in assets/built/screen.css
/* ---------------------------------------------------------- */
.viewport {
position: relative;
display: flex;
flex-direction: column;
min-height: 100vh;
@ -87,7 +87,7 @@ production stylesheet in assets/built/screen.css
}
/* 4. Site Header
/* 3. Site Header
/* ---------------------------------------------------------- */
.site-header {
@ -136,6 +136,7 @@ production stylesheet in assets/built/screen.css
.site-header-content.no-content {
padding-top: 0;
padding-bottom: 2vmin;
}
.site-header-inner {
@ -246,18 +247,18 @@ production stylesheet in assets/built/screen.css
font-size: 3.4rem !important;
}
.site-description {
font-size: 2.8rem !important;
font-size: 2.2rem !important;
}
.site-logo + .site-description {
margin-top: 12px !important;
}
.site-title + .site-description {
margin-top: 4px !important;
margin-top: 12px !important;
}
}
/* 5. Site Navigation
/* 4. Site Navigation
/* ---------------------------------------------------------- */
.gh-head {
@ -265,6 +266,7 @@ production stylesheet in assets/built/screen.css
font-size: 1.6rem;
line-height: 1.3em;
background-color: #fff;
z-index: 150;
}
.has-cover:not(.home-template) .gh-head {
@ -272,7 +274,7 @@ production stylesheet in assets/built/screen.css
color: #fff;
}
.home-template.has-cover .gh-head {
:is(.home-template, .paged:not(.tag-template):not(.author-template)).has-cover .gh-head {
position: absolute;
top: 0;
right: 0;
@ -302,17 +304,17 @@ production stylesheet in assets/built/screen.css
grid-template-columns: auto 1fr auto;
}
.is-head-left-logo.home-template .gh-head-logo {
.is-head-left-logo.home-template .gh-head:not(.is-header-hidden) .gh-head-logo {
display: none;
}
.is-head-left-logo.home-template .gh-head-menu {
.is-head-left-logo.home-template .gh-head:not(.is-header-hidden) .gh-head-menu {
margin-left: -40px;
}
@media (min-width: 992px) {
.is-head-left-logo .gh-head-menu {
margin-right: 32px;
margin-right: 64px;
margin-left: 16px;
}
}
@ -411,7 +413,7 @@ production stylesheet in assets/built/screen.css
}
.gh-head-logo.no-image {
margin-top: -2px;
margin-top: -5px;
}
.has-cover .gh-head-logo {
@ -565,6 +567,17 @@ production stylesheet in assets/built/screen.css
text-align: right;
}
.gh-head-members {
display: flex;
gap: 20px;
align-items: center;
}
.gh-head-link {
font-weight: 500;
color: inherit;
}
.gh-head-button {
display: inline-flex;
justify-content: center;
@ -584,6 +597,14 @@ production stylesheet in assets/built/screen.css
background: #fff;
}
@media (max-width: 767px) {
.gh-head-members {
flex-direction: column-reverse;
gap: 16px;
width: 100%;
}
}
/* Search
/* ---------------------------------------------------------- */
@ -613,13 +634,13 @@ production stylesheet in assets/built/screen.css
margin-right: -4px;
}
@media (max-width: 991px) {
@media (max-width: 767px) {
.gh-head-actions .gh-search {
display: none;
}
}
@media (min-width: 992px) {
@media (min-width: 768px) {
.gh-head-brand .gh-search {
display: none;
}
@ -681,7 +702,7 @@ production stylesheet in assets/built/screen.css
/* ---------------------------------------------------------- */
/* IDs needed to ensure sufficient specificity */
@media (max-width: 991px) {
@media (max-width: 767px) {
#gh-head {
height: 64px;
}
@ -743,6 +764,11 @@ production stylesheet in assets/built/screen.css
transform: translateY(-4px);
}
#gh-head :is(.gh-head-button, .gh-head-link) {
opacity: 0;
transform: translateY(8px);
}
#gh-head .gh-head-button {
width: 100%;
font-size: 1.8rem;
@ -753,10 +779,9 @@ production stylesheet in assets/built/screen.css
.gh-head-open #gh-head {
position: fixed;
right: 0;
left: 0;
inset: 0;
z-index: 3999999;
height: 100vh;
height: 100%;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
@ -793,20 +818,24 @@ production stylesheet in assets/built/screen.css
flex-direction: column;
gap: 12px;
align-items: center;
padding: max(4vmin, 20px) 0;
padding: max(4vmin, 20px) 0 max(4vmin, 28px);
background-color: #fff;
}
.gh-head-open #gh-head .gh-head-button {
.gh-head-open #gh-head :is(.gh-head-button, .gh-head-link) {
opacity: 1;
transition: transform 0.4s, opacity 0.4s;
transition-delay: 0.2s;
transform: translateY(0);
}
.gh-head-open #gh-head .gh-head-link {
transition-delay: 0.4s;
}
}
/* 6. Post Feed
/* 5. Post Feed
/* ---------------------------------------------------------- */
.post-feed {
@ -996,6 +1025,11 @@ production stylesheet in assets/built/screen.css
margin-top: 6px;
}
:is(.tag-template, .author-template) .post-card-large .post-card-excerpt {
display: block;
overflow-y: auto;
}
.post-card-meta {
display: flex;
align-items: center;
@ -1144,25 +1178,59 @@ make sure this only happens on large viewports / desktop-ish devices.
}
}
/* Pagination
/* ---------------------------------------------------------- */
/* 7. Single Post
.pagination {
display: none;
grid-template-columns: 1fr auto 1fr;
align-items: center;
margin-top: 8vmin;
}
html.no-infinite-scroll .pagination {
display: grid;
}
.pagination a {
font-size: 1.7rem;
font-weight: 600;
}
.pagination .page-number {
grid-column-start: 2;
color: var(--color-secondary-text);
}
.pagination .older-posts {
grid-column-start: 3;
text-align: right;
}
@media (max-width: 767px) {
.pagination .page-number {
display: none;
}
}
/* 6. Single Post
/* ---------------------------------------------------------- */
.article {
padding: max(8vmin, 40px) 0 max(8vmin, 64px);
word-break: break-word;
}
.page-template .article {
padding-top: max(12vmin, 64px);
.post-template .article {
padding: max(8vmin, 40px) 0 max(8vmin, 64px);
}
.article-header {
padding: 0 0 max(6.4vmin, 40px) 0;
.post-template .article-header {
padding: 0 0 max(6.4vmin, 40px);
}
.page-template .article-header {
padding-bottom: max(3.2vmin, 28px);
padding: max(12vmin, 64px) 0 max(3.2vmin, 28px);
}
.article-tag {
@ -1231,28 +1299,28 @@ make sure this only happens on large viewports / desktop-ish devices.
is laid out on top of. Canvas just defines the grid, we don't
use it for applying any other styles. */
.gh-canvas {
.gh-canvas,
.kg-width-full.kg-content-wide {
--gap: max(4vmin, 20px);
--main: min(var(--content-width, 720px), 100% - var(--gap) * 2);
--wide: minmax(0, calc((var(--container-width, 1200px) - var(--content-width, 720px)) / 2));
--full: minmax(var(--gap), 1fr);
display: grid;
grid-template-columns:
[full-start]
minmax(max(4vmin, 20px), auto)
[wide-start]
minmax(auto, 240px)
[main-start]
min(720px, calc(100% - max(8vmin, 40px)))
[main-end]
minmax(auto, 240px)
[wide-end]
minmax(max(4vmin, 20px), auto)
[full-end]
;
[full-start] var(--full)
[wide-start] var(--wide)
[main-start] var(--main) [main-end]
var(--wide) [wide-end]
var(--full) [full-end];
}
.gh-canvas > * {
grid-column: main-start / main-end;
}
.kg-width-wide {
.kg-width-wide,
.kg-content-wide > div {
grid-column: wide-start / wide-end;
}
@ -1278,6 +1346,11 @@ headings, text, images and lists. We deal with cards lower down. */
margin-bottom: 0;
}
/* Remove space between full-width cards */
.gh-content > .kg-width-full + .kg-width-full:not(.kg-width-full.kg-card-hascaption + .kg-width-full) {
margin-top: 0;
}
/* [id] represents all headings h1-h6, reset all margins */
.gh-content > [id] {
margin: 0;
@ -1328,6 +1401,14 @@ is the very first element in the post content */
line-height: 1.6em;
}
.page-template .gh-content:only-child > *:first-child:not(.kg-width-full) {
margin-top: max(12vmin, 64px);
}
.page-template .gh-content > *:last-child:not(.kg-width-full) {
margin-bottom: max(12vmin, 64px);
}
.gh-content .kg-callout-card .kg-callout-text,
.gh-content .kg-toggle-card .kg-toggle-content > ol,
.gh-content .kg-toggle-card .kg-toggle-content > ul,
@ -1415,6 +1496,14 @@ is the very first element in the post content */
box-shadow: 0 2px 6px -2px rgba(0,0,0,.1), 0 0 1px rgba(0,0,0,.4);
}
.gh-content ol ol li {
list-style-type: lower-alpha;
}
.gh-content ol ol ol li {
list-style-type: lower-roman;
}
@media (max-width: 650px) {
.gh-content > blockquote:not([class]),
.gh-content > ol,
@ -1452,11 +1541,9 @@ make sure they look good, and are given a bit of extra spacing. */
except for when immediately preceeded by a heading */
.gh-content :not(.kg-card):not([id]) + .kg-card {
margin-top: 6vmin;
margin-bottom: 0;
}
.gh-content .kg-card + :not(.kg-card) {
margin-top: 6vmin;
margin-bottom: 0;
}
/* This keeps small embeds centered */
@ -1624,7 +1711,7 @@ iframe.instagram-media + script + :not([id]) {
}
/* 7.1. Post Byline
/* 6.1. Post Byline
/* ---------------------------------------------------------- */
.article-byline {
@ -1687,7 +1774,7 @@ iframe.instagram-media + script + :not([id]) {
}
/* 7.3. Subscribe
/* 6.2. Subscribe
/* ---------------------------------------------------------- */
.footer-cta {
@ -1737,7 +1824,7 @@ iframe.instagram-media + script + :not([id]) {
}
/* 7.4. Read more
/* 6.3. Read more
/* ---------------------------------------------------------- */
.read-more-wrap {
@ -1776,7 +1863,7 @@ iframe.instagram-media + script + :not([id]) {
}
}
/* 7.6. Comments
/* 6.4. Comments
/* ---------------------------------------------------------- */
.comments {
display: flex;
@ -1814,7 +1901,7 @@ iframe.instagram-media + script + :not([id]) {
}
/* 8. Author Template
/* 7. Author Template
/* ---------------------------------------------------------- */
.author-profile-pic {
@ -1948,7 +2035,7 @@ iframe.instagram-media + script + :not([id]) {
}
/* 11. Site Footer
/* 10. Site Footer
/* ---------------------------------------------------------- */
.site-footer {
@ -1960,6 +2047,10 @@ iframe.instagram-media + script + :not([id]) {
background: color-mod(var(--color-darkgrey) l(-5%));
}
.page-template .site-footer {
margin-top: 0;
}
.site-footer .inner {
display: grid;
grid-gap: 40px;
@ -2035,7 +2126,7 @@ iframe.instagram-media + script + :not([id]) {
}
/* 12. Dark Mode
/* 11. Dark Mode
/* ---------------------------------------------------------- */
html.dark-mode body {
@ -2055,13 +2146,14 @@ html.dark-mode figcaption a {
color: #fff;
}
html.dark-mode .gh-head {
html.dark-mode body:not(.has-cover) .gh-head {
background: var(--color-darkmode);
color: #fff;
}
html.dark-mode .gh-burger-box {
color: #fff;
html.dark-mode .gh-burger::before,
html.dark-mode .gh-burger::after {
background-color: #fff;
}
html.dark-mode .site-header-content {
@ -2072,7 +2164,7 @@ html.dark-mode .post-card-image {
background: var(--color-darkmode);
}
html.dark-mode :is(.post-card-tags, .post-card-meta, .article-tag a, .byline-meta-content) {
html.dark-mode :is(.post-card-tags, .post-card-meta, .article-tag a, .byline-meta-content, .pagination .page-number) {
color: color-mod(var(--color-secondary-text) l(-22%));
}
@ -2088,6 +2180,10 @@ html.dark-mode .post-card-excerpt {
color: var(--color-secondary-text);
}
html.dark-mode .pagination a {
color: #fff;
}
html.dark-mode .author-profile-location {
color: #fff;
}
@ -2191,7 +2287,7 @@ html.dark-mode .gh-content table:not(.gist table) td {
border: color-mod(var(--color-darkmode) l(+8%)) 1px solid;
}
html.dark-mode .gh-content input {
html.dark-mode .gh-content :is(input, textarea) {
color: color-mod(var(--color-midgrey) l(-30%));
}
@ -2217,6 +2313,13 @@ html.dark-mode .footer-cta-title {
color: #fff;
}
@media (max-width: 767px) {
html.dark-mode .gh-head-open:not(.has-cover) #gh-head,
html.dark-mode .gh-head-open:not(.has-cover) #gh-head .gh-head-actions {
background: var(--color-darkmode);
}
}
@media (prefers-color-scheme: dark) {
html.auto-color body {
color: rgba(255, 255, 255, 0.75);
@ -2235,13 +2338,14 @@ html.dark-mode .footer-cta-title {
color: #fff;
}
html.auto-color .gh-head {
html.auto-color body:not(.has-cover) .gh-head {
background: var(--color-darkmode);
color: #fff;
}
html.auto-color .gh-burger-box {
color: #fff;
html.auto-color .gh-burger::before,
html.auto-color .gh-burger::after {
background-color: #fff;
}
html.auto-color .site-header-content {
@ -2252,7 +2356,7 @@ html.dark-mode .footer-cta-title {
background: var(--color-darkmode);
}
html.auto-color :is(.post-card-tags, .post-card-meta, .article-tag a, .byline-meta-content) {
html.auto-color :is(.post-card-tags, .post-card-meta, .article-tag a, .byline-meta-content, .pagination .page-number) {
color: color-mod(var(--color-secondary-text) l(-22%));
}
@ -2268,6 +2372,10 @@ html.dark-mode .footer-cta-title {
color: var(--color-secondary-text);
}
html.auto-color .pagination a {
color: #fff;
}
html.auto-color .author-profile-location {
color: #fff;
}
@ -2371,7 +2479,7 @@ html.dark-mode .footer-cta-title {
border: color-mod(var(--color-darkmode) l(+8%)) 1px solid;
}
html.auto-color .gh-content input {
html.auto-color .gh-content :is(input, textarea) {
color: color-mod(var(--color-midgrey) l(-30%));
}
@ -2396,6 +2504,13 @@ html.dark-mode .footer-cta-title {
html.auto-color .footer-cta-title {
color: #fff;
}
@media (max-width: 767px) {
html.auto-color .gh-head-open:not(.has-cover) #gh-head,
html.auto-color .gh-head-open:not(.has-cover) #gh-head .gh-head-actions {
background: var(--color-darkmode);
}
}
}
/*
@ -2412,3 +2527,4 @@ file to add some of your own styles. Well, you've come to
the right place. Onward!
*/

View File

@ -1,81 +1,85 @@
(function () {
const mediaQuery = window.matchMedia('(max-width: 991px)');
const menu = document.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';
});
}
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');
});
window.addEventListener('click', function (e) {
if (!toggle.contains(e.target) && document.body.classList.contains('is-dropdown-open')) {
document.body.classList.remove('is-dropdown-open');
}
});
}
imagesLoaded(logo, function () {
makeDropdown();
});
window.addEventListener('resize', function () {
setTimeout(function () {
nav.innerHTML = navHTML;
makeDropdown();
}, 1);
});
})();
(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);
});
})();

View File

@ -1,112 +1,114 @@
/* 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) {
// 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);
/* 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);

File diff suppressed because one or more lines are too long

View File

@ -1,89 +1,89 @@
/*jshint browser:true */
/*!
* FitVids 1.3
*
*
* Copyright 2017, Chris Coyier + Dave Rupert + Ghost Foundation
* This is an unofficial release, ported by John O'Nolan
* Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/
* Released under the MIT license
*
*/
;(function( $ ){
'use strict';
$.fn.fitVids = function( options ) {
var settings = {
customSelector: null,
ignore: null
};
if(!document.getElementById('fit-vids-style')) {
// appendStyles: https://github.com/toddmotto/fluidvids/blob/master/dist/fluidvids.js
var head = document.head || document.getElementsByTagName('head')[0];
var css = '.fluid-width-video-container{flex-grow: 1;width:100%;}.fluid-width-video-wrapper{width:100%;position:relative;padding:0;}.fluid-width-video-wrapper iframe,.fluid-width-video-wrapper object,.fluid-width-video-wrapper embed {position:absolute;top:0;left:0;width:100%;height:100%;}';
var div = document.createElement("div");
div.innerHTML = '<p>x</p><style id="fit-vids-style">' + css + '</style>';
head.appendChild(div.childNodes[1]);
}
if ( options ) {
$.extend( settings, options );
}
return this.each(function(){
var selectors = [
'iframe[src*="player.vimeo.com"]',
'iframe[src*="youtube.com"]',
'iframe[src*="youtube-nocookie.com"]',
'iframe[src*="kickstarter.com"][src*="video.html"]',
'object',
'embed'
];
if (settings.customSelector) {
selectors.push(settings.customSelector);
}
var ignoreList = '.fitvidsignore';
if(settings.ignore) {
ignoreList = ignoreList + ', ' + settings.ignore;
}
var $allVideos = $(this).find(selectors.join(','));
$allVideos = $allVideos.not('object object'); // SwfObj conflict patch
$allVideos = $allVideos.not(ignoreList); // Disable FitVids on this video.
$allVideos.each(function(){
var $this = $(this);
if($this.parents(ignoreList).length > 0) {
return; // Disable FitVids on this video.
}
if (this.tagName.toLowerCase() === 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; }
if ((!$this.css('height') && !$this.css('width')) && (isNaN($this.attr('height')) || isNaN($this.attr('width'))))
{
$this.attr('height', 9);
$this.attr('width', 16);
}
var height = ( this.tagName.toLowerCase() === 'object' || ($this.attr('height') && !isNaN(parseInt($this.attr('height'), 10))) ) ? parseInt($this.attr('height'), 10) : $this.height(),
width = !isNaN(parseInt($this.attr('width'), 10)) ? parseInt($this.attr('width'), 10) : $this.width(),
aspectRatio = height / width;
if(!$this.attr('name')){
var videoName = 'fitvid' + $.fn.fitVids._count;
$this.attr('name', videoName);
$.fn.fitVids._count++;
}
$this.wrap('<div class="fluid-width-video-container"><div class="fluid-width-video-wrapper"></div></div>').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+'%');
$this.removeAttr('height').removeAttr('width');
});
});
};
// Internal counter for unique video names.
$.fn.fitVids._count = 0;
// Works with either jQuery or Zepto
})( window.jQuery || window.Zepto );
/*jshint browser:true */
/*!
* FitVids 1.3
*
*
* Copyright 2017, Chris Coyier + Dave Rupert + Ghost Foundation
* This is an unofficial release, ported by John O'Nolan
* Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/
* Released under the MIT license
*
*/
;(function( $ ){
'use strict';
$.fn.fitVids = function( options ) {
var settings = {
customSelector: null,
ignore: null
};
if(!document.getElementById('fit-vids-style')) {
// appendStyles: https://github.com/toddmotto/fluidvids/blob/master/dist/fluidvids.js
var head = document.head || document.getElementsByTagName('head')[0];
var css = '.fluid-width-video-container{flex-grow: 1;width:100%;}.fluid-width-video-wrapper{width:100%;position:relative;padding:0;}.fluid-width-video-wrapper iframe,.fluid-width-video-wrapper object,.fluid-width-video-wrapper embed {position:absolute;top:0;left:0;width:100%;height:100%;}';
var div = document.createElement("div");
div.innerHTML = '<p>x</p><style id="fit-vids-style">' + css + '</style>';
head.appendChild(div.childNodes[1]);
}
if ( options ) {
$.extend( settings, options );
}
return this.each(function(){
var selectors = [
'iframe[src*="player.vimeo.com"]',
'iframe[src*="youtube.com"]',
'iframe[src*="youtube-nocookie.com"]',
'iframe[src*="kickstarter.com"][src*="video.html"]',
'object',
'embed'
];
if (settings.customSelector) {
selectors.push(settings.customSelector);
}
var ignoreList = '.fitvidsignore';
if(settings.ignore) {
ignoreList = ignoreList + ', ' + settings.ignore;
}
var $allVideos = $(this).find(selectors.join(','));
$allVideos = $allVideos.not('object object'); // SwfObj conflict patch
$allVideos = $allVideos.not(ignoreList); // Disable FitVids on this video.
$allVideos.each(function(){
var $this = $(this);
if($this.parents(ignoreList).length > 0) {
return; // Disable FitVids on this video.
}
if (this.tagName.toLowerCase() === 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; }
if ((!$this.css('height') && !$this.css('width')) && (isNaN($this.attr('height')) || isNaN($this.attr('width'))))
{
$this.attr('height', 9);
$this.attr('width', 16);
}
var height = ( this.tagName.toLowerCase() === 'object' || ($this.attr('height') && !isNaN(parseInt($this.attr('height'), 10))) ) ? parseInt($this.attr('height'), 10) : $this.height(),
width = !isNaN(parseInt($this.attr('width'), 10)) ? parseInt($this.attr('width'), 10) : $this.width(),
aspectRatio = height / width;
if(!$this.attr('name')){
var videoName = 'fitvid' + $.fn.fitVids._count;
$this.attr('name', videoName);
$.fn.fitVids._count++;
}
$this.wrap('<div class="fluid-width-video-container"><div class="fluid-width-video-wrapper"></div></div>').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+'%');
$this.removeAttr('height').removeAttr('width');
});
});
};
// Internal counter for unique video names.
$.fn.fitVids._count = 0;
// Works with either jQuery or Zepto
})( window.jQuery || window.Zepto );

View File

@ -1,70 +1,76 @@
{{!< 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="post-feed inner">
{{#author}}
<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">
{{#if profile_image}}
<img class="author-profile-pic" src="{{profile_image}}" alt="{{name}}" />
{{/if}}
<header class="post-card-header">
<h2 class="post-card-title">{{name}}</h2>
</header>
{{#if bio}}
<div class="post-card-excerpt">{{bio}}</div>
{{/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>
</div>
</section>
{{/author}}
{{#foreach posts}}
{{!-- The tag below includes the markup for each post - partials/post-card.hbs --}}
{{> "post-card"}}
{{/foreach}}
</div>
</main>
{{!< 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>
{{/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}}" />
{{/if}}
<header class="post-card-header">
<h2 class="post-card-title">{{name}}</h2>
</header>
{{#if bio}}
<div class="post-card-excerpt">{{bio}}</div>
{{/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>
</div>
</section>
{{/author}}
{{#foreach posts}}
{{!-- The tag below includes the markup for each post - partials/post-card.hbs --}}
{{> "post-card"}}
{{/foreach}}
</div>
{{pagination}}
</div>
</main>

View File

@ -8,6 +8,10 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<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 --}}
@ -21,17 +25,17 @@
<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">
<header id="gh-head" class="gh-head outer">
<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" href="{{@site.url}}">
<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" data-ghost-search>{{> "icons/search"}}</button>
<button class="gh-search gh-icon-btn" aria-label="Search this site" data-ghost-search>{{> "icons/search"}}</button>
<button class="gh-burger"></button>
</div>
@ -39,7 +43,7 @@
{{navigation}}
{{#unless @site.members_enabled}}
{{#match @custom.navigation_layout "Stacked"}}
<button class="gh-search gh-icon-btn" data-ghost-search>{{> "icons/search"}}</button>
<button class="gh-search gh-icon-btn" aria-label="Search this site" data-ghost-search>{{> "icons/search"}}</button>
{{/match}}
{{/unless}}
</nav>
@ -51,15 +55,18 @@
{{/match}}
{{else}}
<button class="gh-search gh-icon-btn" data-ghost-search>{{> "icons/search"}}</button>
{{#unless @member}}
{{#unless @site.members_invite_only}}
<a class="gh-head-button" href="#/portal/signup" data-portal="signup">Subscribe</a>
<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/signin" data-portal="signin">Login</a>
<a class="gh-head-button" href="#/portal/account" data-portal="account">Account</a>
{{/unless}}
{{else}}
<a class="gh-head-button" href="#/portal/account" data-portal="account">Account</a>
{{/unless}}
</div>
{{/unless}}
</div>
</div>
@ -77,7 +84,7 @@
<nav class="site-footer-nav">
{{navigation type="secondary"}}
</nav>
<div><a href="https://ghost.org/" target="_blank" rel="noopener">Powered by Ghost</a></div>
<div class="gh-powered-by"><a href="https://ghost.org/" target="_blank" rel="noopener">Powered by Ghost</a></div>
</div>
</footer>

View File

@ -1,37 +1,37 @@
{{!< 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!
--}}
<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>
{{!-- 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}}
{{/get}}
</div>
{{!< 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!
--}}
<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>
{{!-- 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}}
{{/get}}
</div>
</aside>

148
error.hbs
View File

@ -1,74 +1,74 @@
{{!--
There are two error files in this theme, one for 404s and one for all other errors.
This file is the latter, and handle all 400/500 errors that might occur.
Because 500 errors in particular usuall 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!
--}}
<!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>
<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>
</div>
</header>
<main 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>
{{#if errorDetails}}
<section class="error-stack">
<h3>Theme errors</h3>
<ul class="error-stack-list">
{{#foreach errorDetails}}
<li>
<em class="error-stack-function">{{{rule}}}</em>
{{#foreach failures}}
<p><span class="error-stack-file">Ref: {{ref}}</span></p>
<p><span class="error-stack-file">Message: {{message}}</span></p>
{{/foreach}}
</li>
{{/foreach}}
</ul>
</section>
{{/if}}
</div>
</main>
</div>
</body>
</html>
{{!--
There are two error files in this theme, one for 404s and one for all other errors.
This file is the latter, and handle all 400/500 errors that might occur.
Because 500 errors in particular usuall 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!
--}}
<!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>
<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>
</div>
</header>
<main 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>
{{#if errorDetails}}
<section class="error-stack">
<h3>Theme errors</h3>
<ul class="error-stack-list">
{{#foreach errorDetails}}
<li>
<em class="error-stack-function">{{{rule}}}</em>
{{#foreach failures}}
<p><span class="error-stack-file">Ref: {{ref}}</span></p>
<p><span class="error-stack-file">Message: {{message}}</span></p>
{{/foreach}}
</li>
{{/foreach}}
</ul>
</section>
{{/if}}
</div>
</main>
</div>
</body>
</html>

View File

@ -1,176 +1,178 @@
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');
// 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');
// postcss plugins
const autoprefixer = require('autoprefixer');
const colorFunction = require('postcss-color-mod-function');
const cssnano = require('cssnano');
const 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);
};
};
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);
}
};
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');
// 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');
// postcss plugins
const autoprefixer = require('autoprefixer');
const colorFunction = require('postcss-color-mod-function');
const cssnano = require('cssnano');
const 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);
};
};
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;
const repo_readonly = process.env.REPO_READONLY ?? REPO_READONLY;
const repo = process.env.REPO ?? REPO;
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);
}
};

106
index.hbs
View File

@ -1,52 +1,54 @@
{{!< default}}
{{!-- 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}}">
{{else}}
<h1 class="site-title">{{@site.title}}</h1>
{{/if}}
{{/match}}
{{#if @site.description}}
<p class="site-description">{{@site.description}}</p>
{{/if}}
</div>
{{/match}}
</div>
{{!-- The main content area --}}
<main id="site-main" class="site-main outer">
<div class="inner posts">
<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>
{{!< default}}
{{!-- 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}}">
{{else}}
<h1 class="site-title">{{@site.title}}</h1>
{{/if}}
{{/match}}
{{#if @site.description}}
<p class="site-description">{{@site.description}}</p>
{{/if}}
</div>
{{/match}}
</div>
{{!-- The main content area --}}
<main id="site-main" class="site-main outer">
<div class="inner posts">
<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>

View File

@ -2,7 +2,7 @@
"name": "casper-aytac",
"description": "A clean, minimal default theme for the Ghost publishing platform with little modifications by Aytac",
"demo": "https://aytac.kirmizi.online",
"version": "5.4.1",
"version": "5.6.0",
"engines": {
"ghost": ">=5.0.0"
},
@ -49,7 +49,7 @@
"autoprefixer": "10.4.7",
"beeper": "2.1.0",
"cssnano": "5.1.12",
"gscan": "4.34.0",
"gscan": "4.36.1",
"gulp": "4.0.2",
"gulp-concat": "2.6.1",
"gulp-livereload": "4.0.2",

View File

@ -1,11 +1,11 @@
{{!< default}}
<section class="post-content post-tag-content">
<div class="post-tag-grid">
{{#get 'tags' limit='15' include='count.posts' order='count.posts desc'}}
{{#foreach tags}}
{{> "tag-card"}}
{{/foreach}}
{{/get}}
</div>
{{!< default}}
<section class="post-content post-tag-content">
<div class="post-tag-grid">
{{#get 'tags' limit='15' include='count.posts' order='count.posts desc'}}
{{#foreach tags}}
{{> "tag-card"}}
{{/foreach}}
{{/get}}
</div>
</section>

View File

@ -10,30 +10,32 @@ into the {body} tag of the default.hbs template --}}
<main id="site-main" class="site-main">
<article class="article {{post_class}}">
<header class="article-header gh-canvas">
{{#match @page.show_title_and_feature_image}}
<header class="article-header gh-canvas">
<h1 class="article-title">{{title}}</h1>
<h1 class="article-title">{{title}}</h1>
{{#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>
{{/if}}
{{#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>
{{/if}}
</header>
</header>
{{/match}}
<section class="gh-content gh-canvas">
{{content}}

View File

@ -1 +1 @@
<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>
<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

After

Width:  |  Height:  |  Size: 309 B

View File

@ -1,3 +1,3 @@
<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 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

After

Width:  |  Height:  |  Size: 540 B

View File

@ -1,11 +1,11 @@
<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 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

After

Width:  |  Height:  |  Size: 933 B

View File

@ -1,5 +1,5 @@
<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 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

After

Width:  |  Height:  |  Size: 936 B

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="6.18" cy="17.82" r="2.18"/><path d="M4 4.44v2.83c7.03 0 12.73 5.7 12.73 12.73h2.83c0-8.59-6.97-15.56-15.56-15.56zm0 5.66v2.83c3.9 0 7.07 3.17 7.07 7.07h2.83c0-5.47-4.43-9.9-9.9-9.9z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="6.18" cy="17.82" r="2.18"/><path d="M4 4.44v2.83c7.03 0 12.73 5.7 12.73 12.73h2.83c0-8.59-6.97-15.56-15.56-15.56zm0 5.66v2.83c3.9 0 7.07 3.17 7.07 7.07h2.83c0-5.47-4.43-9.9-9.9-9.9z"/></svg>

Before

Width:  |  Height:  |  Size: 263 B

After

Width:  |  Height:  |  Size: 264 B

View File

@ -1,38 +1,38 @@
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 485 485" style="enable-background:new 0 0 485 485;" xml:space="preserve">
<g>
<path d="M200.767,400h65.266V242.413h43.798c0,0,4.104-25.428,6.103-53.235h-49.647v-36.264c0-5.416,7.109-12.696,14.153-12.696
h35.564V85h-48.366c-68.478,0-66.872,53.082-66.872,61.009v43.356h-31.771v53.029h31.771V400z"/>
<path d="M0,0v485h485V0H0z M455,455H30V30h425V455z"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 485 485" style="enable-background:new 0 0 485 485;" xml:space="preserve">
<g>
<path d="M200.767,400h65.266V242.413h43.798c0,0,4.104-25.428,6.103-53.235h-49.647v-36.264c0-5.416,7.109-12.696,14.153-12.696
h35.564V85h-48.366c-68.478,0-66.872,53.082-66.872,61.009v43.356h-31.771v53.029h31.771V400z"/>
<path d="M0,0v485h485V0H0z M455,455H30V30h425V455z"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 642 B

After

Width:  |  Height:  |  Size: 679 B

View File

@ -1,25 +1,25 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1000" height="1000" viewBox="0 0 1000 1000" xml:space="preserve">
<desc>Created with Fabric.js 3.5.0</desc>
<defs>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="#ffffff"/>
<g transform="matrix(39.5346 0 0 39.5346 516.0819 516.0819)" id="295699">
<g style="" vector-effect="non-scaling-stroke">
<g transform="matrix(1 0 0 1 -0.5 -0.0005)" id="Layer_1">
<rect style="stroke: rgb(0,0,0); stroke-width: 1.913; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 10; is-custom-font: none; font-file-url: none; fill: none; fill-rule: nonzero; opacity: 1;" x="-11" y="-10.5215" rx="0" ry="0" width="22" height="21.043"/>
</g>
<g transform="matrix(1 0 0 1 1.413 1.9135)" id="Layer_1">
<path style="stroke: rgb(0,0,0); stroke-width: 1.913; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 10; is-custom-font: none; font-file-url: none; fill: none; fill-rule: nonzero; opacity: 1;" transform=" translate(-13.413, -13.9135)" d="M 10.065 18.696 v -6.217 c 0 -1.849 1.499 -3.348 3.348 -3.348 h 0 c 1.849 0 3.348 1.499 3.348 3.348 v 6.217" stroke-linecap="round"/>
</g>
<g transform="matrix(1 0 0 1 -5.761 1.435)" id="Layer_1">
<line style="stroke: rgb(0,0,0); stroke-width: 1.913; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 10; is-custom-font: none; font-file-url: none; fill: none; fill-rule: nonzero; opacity: 1;" x1="0" y1="-5.261000000000001" x2="0" y2="5.261000000000001"/>
</g>
<g transform="matrix(1 0 0 1 -5.761 -5.739)" id="Layer_1">
<circle style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; is-custom-font: none; font-file-url: none; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" cx="0" cy="0" r="0.957"/>
</g>
<g transform="matrix(1 0 0 1 -1.935 -1.4345)" id="Layer_1">
<line style="stroke: rgb(0,0,0); stroke-width: 1.913; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 10; is-custom-font: none; font-file-url: none; fill: none; fill-rule: nonzero; opacity: 1;" x1="0" y1="-2.3915000000000006" x2="0" y2="2.3915000000000006"/>
</g>
</g>
</g>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1000" height="1000" viewBox="0 0 1000 1000" xml:space="preserve">
<desc>Created with Fabric.js 3.5.0</desc>
<defs>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="#ffffff"/>
<g transform="matrix(39.5346 0 0 39.5346 516.0819 516.0819)" id="295699">
<g style="" vector-effect="non-scaling-stroke">
<g transform="matrix(1 0 0 1 -0.5 -0.0005)" id="Layer_1">
<rect style="stroke: rgb(0,0,0); stroke-width: 1.913; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 10; is-custom-font: none; font-file-url: none; fill: none; fill-rule: nonzero; opacity: 1;" x="-11" y="-10.5215" rx="0" ry="0" width="22" height="21.043"/>
</g>
<g transform="matrix(1 0 0 1 1.413 1.9135)" id="Layer_1">
<path style="stroke: rgb(0,0,0); stroke-width: 1.913; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 10; is-custom-font: none; font-file-url: none; fill: none; fill-rule: nonzero; opacity: 1;" transform=" translate(-13.413, -13.9135)" d="M 10.065 18.696 v -6.217 c 0 -1.849 1.499 -3.348 3.348 -3.348 h 0 c 1.849 0 3.348 1.499 3.348 3.348 v 6.217" stroke-linecap="round"/>
</g>
<g transform="matrix(1 0 0 1 -5.761 1.435)" id="Layer_1">
<line style="stroke: rgb(0,0,0); stroke-width: 1.913; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 10; is-custom-font: none; font-file-url: none; fill: none; fill-rule: nonzero; opacity: 1;" x1="0" y1="-5.261000000000001" x2="0" y2="5.261000000000001"/>
</g>
<g transform="matrix(1 0 0 1 -5.761 -5.739)" id="Layer_1">
<circle style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; is-custom-font: none; font-file-url: none; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" cx="0" cy="0" r="0.957"/>
</g>
<g transform="matrix(1 0 0 1 -1.935 -1.4345)" id="Layer_1">
<line style="stroke: rgb(0,0,0); stroke-width: 1.913; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 10; is-custom-font: none; font-file-url: none; fill: none; fill-rule: nonzero; opacity: 1;" x1="0" y1="-2.3915000000000006" x2="0" y2="2.3915000000000006"/>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -1,9 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1000" height="1000" viewBox="0 0 1000 1000" xml:space="preserve">
<desc>Created with Fabric.js 3.5.0</desc>
<defs>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="#ffffff"/>
<g transform="matrix(41.3223 0 0 41.3223 499.9998 499.9998)" id="343141">
<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; is-custom-font: none; font-file-url: none; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-16, -16)" d="M 5 5 L 5 27 L 27 27 L 27 5 L 5 5 z M 7 7 L 25 7 L 25 25 L 13.513672 25 C 13.765525 24.49367 13.992121 23.971433 14.115234 23.496094 C 14.249234 22.982094 15 20.740234 15 20.740234 C 15.357 21.423234 16.402672 22 17.513672 22 C 20.821672 22 23 19.107078 23 15.330078 C 23 11.710078 20.044234 9 16.240234 9 C 11.508234 9 9 12.174766 9 15.634766 C 9 17.241766 9.8566563 19.241859 11.222656 19.880859 C 11.432656 19.978859 11.540844 19.933422 11.589844 19.732422 C 11.625844 19.580422 11.811578 18.836188 11.892578 18.492188 C 11.919578 18.380188 11.905406 18.287688 11.816406 18.179688 C 11.365406 17.629687 11 16.621688 11 15.679688 C 11 13.259688 12.830172 10.919922 15.951172 10.919922 C 18.643172 10.919922 20.53125 12.755859 20.53125 15.380859 C 20.53125 18.344859 19.236156 20.251953 17.285156 20.251953 C 16.209156 20.251953 15.204984 19.510016 15.458984 18.416016 C 15.766984 17.112016 16.365234 15.705672 16.365234 14.763672 C 16.365234 12.397672 12.998047 12.724859 12.998047 15.880859 C 12.998047 16.849859 13.320313 17.509766 13.320312 17.509766 C 12.257514 22.24839 11.955636 23.282208 12.048828 25 L 7 25 L 7 7 z" stroke-linecap="round"/>
</g>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1000" height="1000" viewBox="0 0 1000 1000" xml:space="preserve">
<desc>Created with Fabric.js 3.5.0</desc>
<defs>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="#ffffff"/>
<g transform="matrix(41.3223 0 0 41.3223 499.9998 499.9998)" id="343141">
<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; is-custom-font: none; font-file-url: none; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-16, -16)" d="M 5 5 L 5 27 L 27 27 L 27 5 L 5 5 z M 7 7 L 25 7 L 25 25 L 13.513672 25 C 13.765525 24.49367 13.992121 23.971433 14.115234 23.496094 C 14.249234 22.982094 15 20.740234 15 20.740234 C 15.357 21.423234 16.402672 22 17.513672 22 C 20.821672 22 23 19.107078 23 15.330078 C 23 11.710078 20.044234 9 16.240234 9 C 11.508234 9 9 12.174766 9 15.634766 C 9 17.241766 9.8566563 19.241859 11.222656 19.880859 C 11.432656 19.978859 11.540844 19.933422 11.589844 19.732422 C 11.625844 19.580422 11.811578 18.836188 11.892578 18.492188 C 11.919578 18.380188 11.905406 18.287688 11.816406 18.179688 C 11.365406 17.629687 11 16.621688 11 15.679688 C 11 13.259688 12.830172 10.919922 15.951172 10.919922 C 18.643172 10.919922 20.53125 12.755859 20.53125 15.380859 C 20.53125 18.344859 19.236156 20.251953 17.285156 20.251953 C 16.209156 20.251953 15.204984 19.510016 15.458984 18.416016 C 15.766984 17.112016 16.365234 15.705672 16.365234 14.763672 C 16.365234 12.397672 12.998047 12.724859 12.998047 15.880859 C 12.998047 16.849859 13.320313 17.509766 13.320312 17.509766 C 12.257514 22.24839 11.955636 23.282208 12.048828 25 L 7 25 L 7 7 z" stroke-linecap="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,9 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1000" height="1000" viewBox="0 0 1000 1000" xml:space="preserve">
<desc>Created with Fabric.js 3.5.0</desc>
<defs>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="#ffffff"/>
<g transform="matrix(41.3223 0 0 41.3223 499.9998 499.9998)" id="916324">
<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; is-custom-font: none; font-file-url: none; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-16, -16)" d="M 5 5 L 5 27 L 27 27 L 27 5 L 5 5 z M 7 7 L 25 7 L 25 25 L 7 25 L 7 7 z M 17.058594 8.9941406 C 16.880594 8.9641406 16.704109 9.0817188 16.662109 9.2617188 L 15.798828 13.007812 C 14.128828 13.049812 12.634078 13.601844 11.580078 14.464844 C 11.307078 14.179844 10.926 14 10.5 14 C 9.672 14 9 14.672 9 15.5 C 9 16.172 9.4456875 16.734781 10.054688 16.925781 C 10.022687 17.114781 10 17.305 10 17.5 C 10 19.985 12.686 22 16 22 C 19.314 22 22 19.985 22 17.5 C 22 17.305 21.977312 17.114781 21.945312 16.925781 C 22.554312 16.734781 23 16.172 23 15.5 C 23 14.672 22.328 14 21.5 14 C 21.074 14 20.692922 14.179844 20.419922 14.464844 C 19.431922 13.655844 18.056672 13.117531 16.513672 13.019531 L 17.269531 9.7382812 L 20.039062 10.195312 C 20.132062 10.650313 20.517 11 21 11 C 21.552 11 22 10.552 22 10 C 22 9.448 21.552 9 21 9 C 20.632 9 20.324391 9.2088594 20.150391 9.5058594 L 17.058594 8.9941406 z M 13.091797 15.818359 C 13.694797 15.818359 14.181641 16.305203 14.181641 16.908203 C 14.181641 17.511203 13.693797 18 13.091797 18 C 12.489797 18 12 17.511203 12 16.908203 C 12 16.306203 12.488797 15.818359 13.091797 15.818359 z M 18.908203 15.818359 C 19.511203 15.818359 20 16.306203 20 16.908203 C 20 17.510203 19.511203 18 18.908203 18 C 18.306203 18 17.818359 17.511203 17.818359 16.908203 C 17.818359 16.305203 18.305203 15.818359 18.908203 15.818359 z M 13.472656 19.021484 C 13.562031 19.014609 13.654063 19.042469 13.726562 19.105469 C 14.880562 20.093469 17.117484 20.093469 18.271484 19.105469 C 18.417484 18.980469 18.639625 18.995578 18.765625 19.142578 C 18.891625 19.289578 18.875516 19.510719 18.728516 19.636719 C 18.027516 20.238719 17.033 20.583984 16 20.583984 C 14.967 20.583984 13.973484 20.238719 13.271484 19.636719 C 13.124484 19.510719 13.108375 19.289578 13.234375 19.142578 C 13.297375 19.069078 13.383281 19.028359 13.472656 19.021484 z" stroke-linecap="round"/>
</g>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1000" height="1000" viewBox="0 0 1000 1000" xml:space="preserve">
<desc>Created with Fabric.js 3.5.0</desc>
<defs>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="#ffffff"/>
<g transform="matrix(41.3223 0 0 41.3223 499.9998 499.9998)" id="916324">
<path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; is-custom-font: none; font-file-url: none; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-16, -16)" d="M 5 5 L 5 27 L 27 27 L 27 5 L 5 5 z M 7 7 L 25 7 L 25 25 L 7 25 L 7 7 z M 17.058594 8.9941406 C 16.880594 8.9641406 16.704109 9.0817188 16.662109 9.2617188 L 15.798828 13.007812 C 14.128828 13.049812 12.634078 13.601844 11.580078 14.464844 C 11.307078 14.179844 10.926 14 10.5 14 C 9.672 14 9 14.672 9 15.5 C 9 16.172 9.4456875 16.734781 10.054688 16.925781 C 10.022687 17.114781 10 17.305 10 17.5 C 10 19.985 12.686 22 16 22 C 19.314 22 22 19.985 22 17.5 C 22 17.305 21.977312 17.114781 21.945312 16.925781 C 22.554312 16.734781 23 16.172 23 15.5 C 23 14.672 22.328 14 21.5 14 C 21.074 14 20.692922 14.179844 20.419922 14.464844 C 19.431922 13.655844 18.056672 13.117531 16.513672 13.019531 L 17.269531 9.7382812 L 20.039062 10.195312 C 20.132062 10.650313 20.517 11 21 11 C 21.552 11 22 10.552 22 10 C 22 9.448 21.552 9 21 9 C 20.632 9 20.324391 9.2088594 20.150391 9.5058594 L 17.058594 8.9941406 z M 13.091797 15.818359 C 13.694797 15.818359 14.181641 16.305203 14.181641 16.908203 C 14.181641 17.511203 13.693797 18 13.091797 18 C 12.489797 18 12 17.511203 12 16.908203 C 12 16.306203 12.488797 15.818359 13.091797 15.818359 z M 18.908203 15.818359 C 19.511203 15.818359 20 16.306203 20 16.908203 C 20 17.510203 19.511203 18 18.908203 18 C 18.306203 18 17.818359 17.511203 17.818359 16.908203 C 17.818359 16.305203 18.305203 15.818359 18.908203 15.818359 z M 13.472656 19.021484 C 13.562031 19.014609 13.654063 19.042469 13.726562 19.105469 C 14.880562 20.093469 17.117484 20.093469 18.271484 19.105469 C 18.417484 18.980469 18.639625 18.995578 18.765625 19.142578 C 18.891625 19.289578 18.875516 19.510719 18.728516 19.636719 C 18.027516 20.238719 17.033 20.583984 16 20.583984 C 14.967 20.583984 13.973484 20.238719 13.271484 19.636719 C 13.124484 19.510719 13.108375 19.289578 13.234375 19.142578 C 13.297375 19.069078 13.383281 19.028359 13.472656 19.021484 z" stroke-linecap="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1,44 +1,44 @@
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 485 485" style="enable-background:new 0 0 485 485;" xml:space="preserve">
<g>
<path d="M85,341.458c28.599,18.34,62.568,29.037,99.065,29.037c118.871,0,183.873-98.473,183.873-183.876
c0-2.799-0.063-5.587-0.186-8.36c12.629-9.111,23.585-20.493,32.249-33.453c-11.59,5.14-24.045,8.616-37.118,10.178
c13.344-8,23.591-20.662,28.415-35.754c-12.488,7.404-26.319,12.785-41.038,15.681c-11.788-12.56-28.584-20.406-47.173-20.406
c-35.688,0-64.626,28.935-64.626,64.623c0,5.065,0.574,9.997,1.677,14.729c-53.71-2.698-101.33-28.424-133.203-67.526
c-5.564,9.547-8.751,20.647-8.751,32.492c0,22.419,11.406,42.201,28.748,53.79c-10.595-0.336-20.56-3.245-29.271-8.084
c-0.006,0.271-0.006,0.541-0.006,0.814c0,31.311,22.278,57.429,51.841,63.368c-5.423,1.474-11.133,2.268-17.027,2.268
c-4.164,0-8.213-0.406-12.161-1.163c8.225,25.676,32.093,44.361,60.373,44.88c-22.119,17.336-49.984,27.668-80.262,27.668
C95.199,342.365,90.056,342.059,85,341.458z"/>
<path d="M0,0v485h485V0H0z M455,455H30V30h425V455z"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 485 485" style="enable-background:new 0 0 485 485;" xml:space="preserve">
<g>
<path d="M85,341.458c28.599,18.34,62.568,29.037,99.065,29.037c118.871,0,183.873-98.473,183.873-183.876
c0-2.799-0.063-5.587-0.186-8.36c12.629-9.111,23.585-20.493,32.249-33.453c-11.59,5.14-24.045,8.616-37.118,10.178
c13.344-8,23.591-20.662,28.415-35.754c-12.488,7.404-26.319,12.785-41.038,15.681c-11.788-12.56-28.584-20.406-47.173-20.406
c-35.688,0-64.626,28.935-64.626,64.623c0,5.065,0.574,9.997,1.677,14.729c-53.71-2.698-101.33-28.424-133.203-67.526
c-5.564,9.547-8.751,20.647-8.751,32.492c0,22.419,11.406,42.201,28.748,53.79c-10.595-0.336-20.56-3.245-29.271-8.084
c-0.006,0.271-0.006,0.541-0.006,0.814c0,31.311,22.278,57.429,51.841,63.368c-5.423,1.474-11.133,2.268-17.027,2.268
c-4.164,0-8.213-0.406-12.161-1.163c8.225,25.676,32.093,44.361,60.373,44.88c-22.119,17.336-49.984,27.668-80.262,27.668
C95.199,342.365,90.056,342.059,85,341.458z"/>
<path d="M0,0v485h485V0H0z M455,455H30V30h425V455z"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1,78 +1,78 @@
{{!-- 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}}">
{{#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>
{{/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>
</header>
{{#if excerpt}}
<div class="post-card-excerpt">{{excerpt}}</div>
{{/if}}
</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}}
</footer>
</div>
</article>
{{!-- 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}}">
{{#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>
{{/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>
</header>
{{#if excerpt}}
<div class="post-card-excerpt">{{excerpt}}</div>
{{/if}}
</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}}
</footer>
</div>
</article>

View File

@ -1,28 +1,28 @@
<div class="post-tag-grid-item">
<a href='{{ url }}'>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="post-tag-grid-item-svg">
{{#if accent_color}}
<rect x="0" y="0" style="fill: {{accent_color}}" class="post-tag-grid-item-svg-first"></rect>
{{else}}
<rect x="0" y="0" class="post-tag-grid-item-svg-first"></rect>
{{/if}}
<foreignObject class="post-tag-grid-item-svg-first-obj">
<div class="post-tag-grid-item-svg-first-obj-text">{{ count.posts }}</div>
</foreignObject>
<rect class="post-tag-grid-item-svg-second"></rect>
<foreignObject class="post-tag-grid-item-svg-second-obj">
<div class="post-tag-grid-item-svg-second-obj-inner">
{{#if accent_color}}
<h2 style="color:{{accent_color}};">{{ name }}</h2>
{{else}}
<h2>{{ name }}</h2>
{{/if}}
{{#if description}}
<p class="post-tag-grid-item-svg-second-obj-description">{{description}}</p>
{{/if}}
</div>
</foreignObject>
</svg>
</a>
<div class="post-tag-grid-item">
<a href='{{ url }}'>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="post-tag-grid-item-svg">
{{#if accent_color}}
<rect x="0" y="0" style="fill: {{accent_color}}" class="post-tag-grid-item-svg-first"></rect>
{{else}}
<rect x="0" y="0" class="post-tag-grid-item-svg-first"></rect>
{{/if}}
<foreignObject class="post-tag-grid-item-svg-first-obj">
<div class="post-tag-grid-item-svg-first-obj-text">{{ count.posts }}</div>
</foreignObject>
<rect class="post-tag-grid-item-svg-second"></rect>
<foreignObject class="post-tag-grid-item-svg-second-obj">
<div class="post-tag-grid-item-svg-second-obj-inner">
{{#if accent_color}}
<h2 style="color:{{accent_color}};">{{ name }}</h2>
{{else}}
<h2>{{ name }}</h2>
{{/if}}
{{#if description}}
<p class="post-tag-grid-item-svg-second-obj-description">{{description}}</p>
{{/if}}
</div>
</foreignObject>
</svg>
</a>
</div>

328
post.hbs
View File

@ -1,165 +1,165 @@
{{!< default}}
{{!-- The tag above means: insert everything in this file
into the {body} tag of the default.hbs template --}}
{{#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}}">
<header class="article-header gh-canvas">
<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>
<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">&bull;</span> {{reading_time}}</span>
{{/if}}
</div>
</div>
</section>
</div>
{{#if tags}}
<div class="post-tags">
<div class="post-tags-box-label">Tags</div>
{{#foreach tags}}
<a href="{{url}}">
{{#if accent_color}}
<span class="post-tag-title" style="color:{{accent_color}};">{{name}}</span>
{{else}}
<span class="post-tag-title" style="color:var(--ghost-accent-color);">{{name}}</span>
{{/if}}
</a>
{{/foreach}}
</div>
{{/if}}
{{#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}}
</figure>
{{/if}}
{{/match}}
</header>
<section class="gh-content gh-canvas">
{{content}}
</section>
<section class="article-share gh-canvas">
<h2 class="text-[2.8rem] font-bold tracking-tight dark:text-[rgba(255,255,255,0.85)]"><span class="hidden sm:inline">Share </span><span class="capitalize sm:normal-case">this</span></h2>
<ul>
<li><a href="http://twitter.com/share?text={{encode title}}&amp;url={{url absolute="true"}}" onclick="window.open(this.href, 'twitter-share', 'width=550,height=235');return false;" title="Twitter" class="social-share-link">{{> "icons/share-twitter"}}</a></li>
<li><a href="https://www.facebook.com/sharer/sharer.php?u={{url absolute="true"}}" onclick="window.open(this.href, 'facebook-share','width=580,height=296');return false;" title="Facebook" class="social-share-link">{{> "icons/share-facebook"}}</a></li>
<li><a href="http://www.reddit.com/submit?url={{url absolute="true"}}&amp;title={{encode title}}" onclick="window.open(this.href, 'reddit-share', 'width=490,height=530');return false;" title="Reddit" class="social-share-link">{{> "icons/share-reddit"}}</a></li>
<li><a href="http://www.linkedin.com/shareArticle?mini=true&amp;url={{url absolute="true"}}&amp;title={{encode title}}" onclick="window.open(this.href, 'linkedin-share', 'width=490,height=530');return false;" title="LinkedIn" class="social-share-link">{{> "icons/share-linkedin"}}</a></li>
<li><a href="http://pinterest.com/pin/create/button/?url={{url absolute="true"}}&amp;description={{encode title}}" onclick="window.open(this.href, 'pinterest-share', 'width=490,height=530');return false;" title="Pinterest" class="social-share-link">{{> "icons/share-pinterest"}}</a></li>
</ul>
</section>
{{#if comments}}
<section class="article-comments gh-canvas">
{{comments}}
</section>
{{/if}}
</article>
</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>
</div>
</section>
{{/if}}
{{/unless}}
{{/unless}}
{{/if}}
{{!-- 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.
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|}}
{{#if more_posts}}
<aside class="read-more-wrap outer">
<div class="read-more inner">
{{#foreach more_posts}}
{{> "post-card"}}
{{/foreach}}
</div>
</aside>
{{/if}}
{{/get}}
{{/if}}
{{!< default}}
{{!-- The tag above means: insert everything in this file
into the {body} tag of the default.hbs template --}}
{{#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}}">
<header class="article-header gh-canvas">
<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>
<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">&bull;</span> {{reading_time}}</span>
{{/if}}
</div>
</div>
</section>
</div>
{{#if tags}}
<div class="post-tags">
<div class="post-tags-box-label">Tags</div>
{{#foreach tags}}
<a href="{{url}}">
{{#if accent_color}}
<span class="post-tag-title" style="color:{{accent_color}};">{{name}}</span>
{{else}}
<span class="post-tag-title" style="color:var(--ghost-accent-color);">{{name}}</span>
{{/if}}
</a>
{{/foreach}}
</div>
{{/if}}
{{#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}}
</figure>
{{/if}}
{{/match}}
</header>
<section class="gh-content gh-canvas">
{{content}}
</section>
<section class="article-share gh-canvas">
<h2 class="text-[2.8rem] font-bold tracking-tight dark:text-[rgba(255,255,255,0.85)]"><span class="hidden sm:inline">Share </span><span class="capitalize sm:normal-case">this</span></h2>
<ul>
<li><a href="http://twitter.com/share?text={{encode title}}&amp;url={{url absolute="true"}}" onclick="window.open(this.href, 'twitter-share', 'width=550,height=235');return false;" title="Twitter" class="social-share-link">{{> "icons/share-twitter"}}</a></li>
<li><a href="https://www.facebook.com/sharer/sharer.php?u={{url absolute="true"}}" onclick="window.open(this.href, 'facebook-share','width=580,height=296');return false;" title="Facebook" class="social-share-link">{{> "icons/share-facebook"}}</a></li>
<li><a href="http://www.reddit.com/submit?url={{url absolute="true"}}&amp;title={{encode title}}" onclick="window.open(this.href, 'reddit-share', 'width=490,height=530');return false;" title="Reddit" class="social-share-link">{{> "icons/share-reddit"}}</a></li>
<li><a href="http://www.linkedin.com/shareArticle?mini=true&amp;url={{url absolute="true"}}&amp;title={{encode title}}" onclick="window.open(this.href, 'linkedin-share', 'width=490,height=530');return false;" title="LinkedIn" class="social-share-link">{{> "icons/share-linkedin"}}</a></li>
<li><a href="http://pinterest.com/pin/create/button/?url={{url absolute="true"}}&amp;description={{encode title}}" onclick="window.open(this.href, 'pinterest-share', 'width=490,height=530');return false;" title="Pinterest" class="social-share-link">{{> "icons/share-pinterest"}}</a></li>
</ul>
</section>
{{#if comments}}
<section class="article-comments gh-canvas">
{{comments}}
</section>
{{/if}}
</article>
</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>
</div>
</section>
{{/if}}
{{/unless}}
{{/unless}}
{{/if}}
{{!-- 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.
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|}}
{{#if more_posts}}
<aside class="read-more-wrap outer">
<div class="read-more inner">
{{#foreach more_posts}}
{{> "post-card"}}
{{/foreach}}
</div>
</aside>
{{/if}}
{{/get}}
{{/if}}
{{/post}}

71
tag.hbs
View File

@ -1,34 +1,37 @@
{{!< 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">
<div class="post-card-content">
<div class="post-card-content-link">
<header class="post-card-header">
<h2 class="post-card-title post-card-title-custom">{{name}}</h2>
</header>
<div class="post-card-excerpt">
{{#if description}}
{{description}}
{{/if}}
... A collection of {{plural ../pagination.total empty='zero posts' singular='% post' plural='% posts'}}
</div>
</div>
</div>
</section>
{{/tag}}
{{#foreach posts}}
{{!-- The tag below includes the markup for each post - partials/post-card.hbs --}}
{{> "post-card"}}
{{/foreach}}
</div>
</div>
</main>
{{!< 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">
<div class="post-card-content">
<div class="post-card-content-link">
<header class="post-card-header">
<h2 class="post-card-title post-card-title-custom">{{name}}</h2>
</header>
<div class="post-card-excerpt">
{{#if description}}
{{description}}
{{/if}}
... A collection of {{plural ../pagination.total empty='zero posts' singular='% post' plural='% posts'}}
</div>
</div>
</div>
</section>
{{/tag}}
{{#foreach posts}}
{{!-- The tag below includes the markup for each post - partials/post-card.hbs --}}
{{> "post-card"}}
{{/foreach}}
</div>
{{pagination}}
</div>
</main>

11023
yarn.lock

File diff suppressed because it is too large Load Diff