Mostly works, missing some things
15
README.md
|
@ -1,12 +1,10 @@
|
||||||
# Solo
|
# Bifocal
|
||||||
|
|
||||||
Solo is a minimal theme for [Ghost](https://github.com/TryGhost/Ghost) focused on showcasing the work of an individual writer or creator. This theme is highly customizable, with a few simple settings that allow you to quickly apply your own personal style to your site.
|
Bifocal is is a minimal theme for [Ghost](https://github.com/TryGhost/Ghost) based on Solo. It features a two-column layout when screen width allows and displays internal tags to the user.
|
||||||
|
|
||||||
**Demo: https://solo.ghost.io**
|
|
||||||
|
|
||||||
# Instructions
|
# Instructions
|
||||||
|
|
||||||
1. [Download this theme](https://github.com/TryGhost/Solo/archive/main.zip)
|
1. Download this theme
|
||||||
2. Log into Ghost, and go to the `Design` settings area to upload the zip file
|
2. Log into Ghost, and go to the `Design` settings area to upload the zip file
|
||||||
|
|
||||||
# Development
|
# Development
|
||||||
|
@ -29,10 +27,9 @@ The `zip` Gulp task packages the theme files into `dist/solo.zip`, which you can
|
||||||
yarn zip
|
yarn zip
|
||||||
```
|
```
|
||||||
|
|
||||||
# Contribution
|
Note that GIF files processed by Gulp become corrupted, so you will either have to use another file type or replace those files and re-zip manually in order to use GIF images.
|
||||||
|
|
||||||
This repo is synced automatically with [TryGhost/Themes](https://github.com/TryGhost/Themes) monorepo. If you're looking to contribute or raise an issue, head over to the main repository [TryGhost/Themes](https://github.com/TryGhost/Themes) where our official themes are developed.
|
|
||||||
|
|
||||||
## Copyright & License
|
## Copyright & License
|
||||||
|
|
||||||
Copyright (c) 2013-2023 Ghost Foundation - Released under the [MIT license](LICENSE).
|
Copyright (c) 2024 Jean Viscogliosi-Pate - Released under the [MIT license](LICENSE).
|
||||||
|
Original Solo theme relased 2013-2023 Ghost Foundation under the MIT license.
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
@import "@tryghost/shared-theme-assets/assets/css/v1/screen.css";
|
@import "@tryghost/shared-theme-assets/assets/css/v1/screen.css";
|
||||||
@import "fonts.css";
|
@import "fonts.css";
|
||||||
|
@import "tocbot.css"
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--font-sans: Wanted Sans, -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif;
|
--font-sans: Wanted Sans, Century Gothic, Frutiger, Futura, Montserrat, -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif;
|
||||||
--color-primary-text: var(--color-darker-gray);
|
--color-primary-text: var(--color-darker-gray);
|
||||||
--color-secondary-text-dark: rgba(0, 0, 0, 0.4);
|
--color-secondary-text-dark: rgba(0, 0, 0, 0.4);
|
||||||
--color-secondary-text-light: rgba(255, 255, 255, 0.64);
|
--color-secondary-text-light: rgba(255, 255, 255, 0.64);
|
||||||
|
@ -11,8 +12,10 @@
|
||||||
--gap: clamp(24px, 1.7032rem + 1.9355vw, 48px);
|
--gap: clamp(24px, 1.7032rem + 1.9355vw, 48px);
|
||||||
--head-nav-gap: 32px;
|
--head-nav-gap: 32px;
|
||||||
--container-width: 1440px;
|
--container-width: 1440px;
|
||||||
|
--title-font-size: clamp(3.2rem, 2.7rem + 1.5625vw, 5.2rem);
|
||||||
--content-font-size: clamp(1.7rem, 0.38vw + 1.4rem, 2rem);
|
--content-font-size: clamp(1.7rem, 0.38vw + 1.4rem, 2rem);
|
||||||
--header-spacing: clamp(4.8rem, 4rem + 2.5vw, 8rem);
|
--header-spacing: clamp(4.8rem, 4rem + 2.5vw, 8rem);
|
||||||
|
--background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root.has-light-text {
|
:root.has-light-text {
|
||||||
|
@ -141,12 +144,7 @@ hr {
|
||||||
margin-bottom: 40px;
|
margin-bottom: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gh-about-content {
|
|
||||||
word-break: break-word;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gh-about-primary {
|
.gh-about-primary {
|
||||||
max-width: 1200px;
|
|
||||||
font-size: clamp(3.2rem, 2.4452rem + 2.0968vw, 5.8rem);
|
font-size: clamp(3.2rem, 2.4452rem + 2.0968vw, 5.8rem);
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
|
@ -157,14 +155,12 @@ hr {
|
||||||
}
|
}
|
||||||
|
|
||||||
.gh-about-secondary {
|
.gh-about-secondary {
|
||||||
max-width: 840px;
|
|
||||||
font-size: clamp(2.4rem, 0.54vw + 2.14rem, 3rem);
|
font-size: clamp(2.4rem, 0.54vw + 2.14rem, 3rem);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
letter-spacing: -0.008em;
|
letter-spacing: -0.008em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gh-about-primary + .gh-about-secondary {
|
.gh-about-primary + .gh-about-secondary {
|
||||||
max-width: 640px;
|
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
font-size: clamp(2rem, 0.36vw + 1.83rem, 2.4rem);
|
font-size: clamp(2rem, 0.36vw + 1.83rem, 2.4rem);
|
||||||
font-weight: 450;
|
font-weight: 450;
|
||||||
|
@ -174,138 +170,6 @@ hr {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Side by side about section
|
|
||||||
/* ---------------------------------------------------------- */
|
|
||||||
|
|
||||||
.has-side-about .gh-about {
|
|
||||||
margin-top: 48px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.has-side-about .gh-about.no-image {
|
|
||||||
margin-top: 80px;
|
|
||||||
margin-bottom: 48px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.has-side-about .gh-about-inner {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
gap: clamp(4rem, 0.0842rem + 3.9474vw, 6.4rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
.has-side-about .gh-about.no-image .gh-about-inner {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
.has-side-about .gh-about-content-inner {
|
|
||||||
position: sticky;
|
|
||||||
top: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 840px) {
|
|
||||||
.has-side-about .gh-about-inner {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column-reverse;
|
|
||||||
gap: 64px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Large background about section
|
|
||||||
/* ---------------------------------------------------------- */
|
|
||||||
|
|
||||||
.has-background-about .gh-about {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.has-background-about .gh-about::before {
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
content: "";
|
|
||||||
background-color: var(--color-black);
|
|
||||||
transition: opacity 1.5s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.has-background-about .gh-about.initialized::before {
|
|
||||||
opacity: 0.4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.has-background-about .gh-about-inner {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
min-height: var(--about-height, 100vh);
|
|
||||||
}
|
|
||||||
|
|
||||||
.has-background-about .gh-about-image {
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
z-index: -1;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
|
|
||||||
.has-background-about .gh-about-content {
|
|
||||||
position: sticky;
|
|
||||||
bottom: calc(var(--gap) + 24px);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: flex-start;
|
|
||||||
max-width: 50%;
|
|
||||||
margin-top: 200px;
|
|
||||||
margin-bottom: calc(var(--gap) + 24px);
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.has-background-about .gh-about-primary {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.has-background-about .gh-about-secondary {
|
|
||||||
color: #fff;
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.has-background-about .gh-subscribe-input {
|
|
||||||
color: var(--color-secondary-text-dark);
|
|
||||||
background-color: #fff;
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 991px) {
|
|
||||||
.has-background-about .gh-about-content {
|
|
||||||
max-width: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Typographic profile about section
|
|
||||||
/* ---------------------------------------------------------- */
|
|
||||||
|
|
||||||
.has-typographic-about .gh-about {
|
|
||||||
display: flex;
|
|
||||||
min-height: calc(100vh - 110px);
|
|
||||||
padding-top: 64px;
|
|
||||||
padding-bottom: 64px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.has-typographic-about .gh-about-inner {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 48px;
|
|
||||||
justify-content: flex-end;
|
|
||||||
width: 100%;
|
|
||||||
padding-bottom: clamp(2.4rem, 2rem + 1.25vw, 4rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
.has-typographic-about .gh-about-image {
|
|
||||||
width: 128px;
|
|
||||||
height: 128px;
|
|
||||||
border-radius: 50%;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
|
|
||||||
.has-typographic-about .gh-subscribe-input {
|
|
||||||
margin-top: 48px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Post card
|
/* Post card
|
||||||
/* ---------------------------------------------------------- */
|
/* ---------------------------------------------------------- */
|
||||||
|
|
||||||
|
@ -374,16 +238,18 @@ hr {
|
||||||
/* ---------------------------------------------------------- */
|
/* ---------------------------------------------------------- */
|
||||||
.tag-list {
|
.tag-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: row nowrap;
|
flex-flow: row wrap;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
|
column-gap: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag-icon {
|
.tag-icon {
|
||||||
float: left;
|
float: left;
|
||||||
width: 32px;
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,9 +258,26 @@ hr {
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tag-desc {
|
||||||
|
color: var(--color-secondary-text);
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: calc(var(--title-font-size) * 0.7);
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
block-size: var(--title-font-size);
|
||||||
|
}
|
||||||
|
|
||||||
/* Feed
|
/* Feed
|
||||||
/* ---------------------------------------------------------- */
|
/* ---------------------------------------------------------- */
|
||||||
|
|
||||||
|
.feed-cta {
|
||||||
|
display: flex;
|
||||||
|
justify-content: right;
|
||||||
|
padding-bottom: var(--gap);
|
||||||
|
column-gap: 10px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.gh-card.no-image {
|
.gh-card.no-image {
|
||||||
max-width: 1200px;
|
max-width: 1200px;
|
||||||
}
|
}
|
||||||
|
@ -424,7 +307,7 @@ hr {
|
||||||
}
|
}
|
||||||
|
|
||||||
.gh-card-title {
|
.gh-card-title {
|
||||||
font-size: clamp(3.2rem, 2.7rem + 1.5625vw, 5.2rem);
|
font-size: var(--title-font-size);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -624,34 +507,6 @@ hr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Custom CTA
|
|
||||||
/* ---------------------------------------------------------- */
|
|
||||||
|
|
||||||
.gh-cta {
|
|
||||||
position: relative;
|
|
||||||
z-index: 20;
|
|
||||||
grid-column: 1 / span 12 !important;
|
|
||||||
padding: clamp(8rem, 10.71vw + 2.86rem, 20rem) clamp(4.8rem, 4.64vw + 2.57rem, 10rem);
|
|
||||||
margin-top: clamp(8rem, 7.14vw + 4.57rem, 16rem);
|
|
||||||
background-color: var(--color-lighter-gray);
|
|
||||||
transform: translate3d(0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.gh-cta-title {
|
|
||||||
margin-bottom: 24px;
|
|
||||||
font-size: clamp(3rem, 0.71vw + 2.66rem, 3.8rem);
|
|
||||||
font-weight: 800;
|
|
||||||
letter-spacing: -0.03em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gh-cta .gh-btn {
|
|
||||||
height: 48px;
|
|
||||||
padding-right: 24px;
|
|
||||||
padding-left: 24px;
|
|
||||||
font-size: 1.8rem;
|
|
||||||
letter-spacing: -0.005em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Navigation
|
/* Navigation
|
||||||
/* ---------------------------------------------------------- */
|
/* ---------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/* Style from Tocbot */
|
||||||
|
.toc {
|
||||||
|
overflow-y: auto
|
||||||
|
}
|
||||||
|
|
||||||
|
.toc>.toc-list {
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative
|
||||||
|
}
|
||||||
|
|
||||||
|
.toc>.toc-list li {
|
||||||
|
list-style: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.toc-list {
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 10px
|
||||||
|
}
|
||||||
|
|
||||||
|
a.toc-link {
|
||||||
|
color: currentColor;
|
||||||
|
height: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-collapsible {
|
||||||
|
max-height: 1000px;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: all 300ms ease-in-out
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-collapsed {
|
||||||
|
max-height: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-position-fixed {
|
||||||
|
position: fixed !important;
|
||||||
|
top: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-active-link {
|
||||||
|
font-weight: 700
|
||||||
|
}
|
||||||
|
|
||||||
|
.toc-link::before {
|
||||||
|
background-color: #EEE;
|
||||||
|
content: ' ';
|
||||||
|
display: inline-block;
|
||||||
|
height: inherit;
|
||||||
|
left: 0;
|
||||||
|
margin-top: -1px;
|
||||||
|
position: absolute;
|
||||||
|
width: 2px
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-active-link::before {
|
||||||
|
background-color: #54BC4B
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style from Ghost Foundation */
|
||||||
|
.gh-content {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-toc > .toc-list {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toc-list {
|
||||||
|
overflow: hidden;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1300px) {
|
||||||
|
.gh-sidebar {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
margin-top: 4vmin;
|
||||||
|
grid-column: wide-start / main-start; /* Place the TOC to the left of the content */
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-toc {
|
||||||
|
position: sticky; /* On larger screens, TOC will stay in the same spot on the page */
|
||||||
|
top: 4vmin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-toc .is-active-link::before {
|
||||||
|
background-color: var(--ghost-accent-color); /* Defines TOC accent color based on Accent color set in Ghost Admin */
|
||||||
|
}
|
Before Width: | Height: | Size: 547 B After Width: | Height: | Size: 547 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 866 B After Width: | Height: | Size: 866 B |
|
@ -0,0 +1,239 @@
|
||||||
|
// oneko.js: https://github.com/adryd325/oneko.js
|
||||||
|
|
||||||
|
(function oneko() {
|
||||||
|
const isReducedMotion =
|
||||||
|
window.matchMedia(`(prefers-reduced-motion: reduce)`) === true ||
|
||||||
|
window.matchMedia(`(prefers-reduced-motion: reduce)`).matches === true;
|
||||||
|
|
||||||
|
if (isReducedMotion) return;
|
||||||
|
|
||||||
|
const nekoEl = document.createElement("div");
|
||||||
|
|
||||||
|
let nekoPosX = 32;
|
||||||
|
let nekoPosY = 32;
|
||||||
|
|
||||||
|
let mousePosX = 0;
|
||||||
|
let mousePosY = 0;
|
||||||
|
|
||||||
|
let frameCount = 0;
|
||||||
|
let idleTime = 0;
|
||||||
|
let idleAnimation = null;
|
||||||
|
let idleAnimationFrame = 0;
|
||||||
|
|
||||||
|
const nekoSpeed = 10;
|
||||||
|
const spriteSets = {
|
||||||
|
idle: [[-3, -3]],
|
||||||
|
alert: [[-7, -3]],
|
||||||
|
scratchSelf: [
|
||||||
|
[-5, 0],
|
||||||
|
[-6, 0],
|
||||||
|
[-7, 0],
|
||||||
|
],
|
||||||
|
scratchWallN: [
|
||||||
|
[0, 0],
|
||||||
|
[0, -1],
|
||||||
|
],
|
||||||
|
scratchWallS: [
|
||||||
|
[-7, -1],
|
||||||
|
[-6, -2],
|
||||||
|
],
|
||||||
|
scratchWallE: [
|
||||||
|
[-2, -2],
|
||||||
|
[-2, -3],
|
||||||
|
],
|
||||||
|
scratchWallW: [
|
||||||
|
[-4, 0],
|
||||||
|
[-4, -1],
|
||||||
|
],
|
||||||
|
tired: [[-3, -2]],
|
||||||
|
sleeping: [
|
||||||
|
[-2, 0],
|
||||||
|
[-2, -1],
|
||||||
|
],
|
||||||
|
N: [
|
||||||
|
[-1, -2],
|
||||||
|
[-1, -3],
|
||||||
|
],
|
||||||
|
NE: [
|
||||||
|
[0, -2],
|
||||||
|
[0, -3],
|
||||||
|
],
|
||||||
|
E: [
|
||||||
|
[-3, 0],
|
||||||
|
[-3, -1],
|
||||||
|
],
|
||||||
|
SE: [
|
||||||
|
[-5, -1],
|
||||||
|
[-5, -2],
|
||||||
|
],
|
||||||
|
S: [
|
||||||
|
[-6, -3],
|
||||||
|
[-7, -2],
|
||||||
|
],
|
||||||
|
SW: [
|
||||||
|
[-5, -3],
|
||||||
|
[-6, -1],
|
||||||
|
],
|
||||||
|
W: [
|
||||||
|
[-4, -2],
|
||||||
|
[-4, -3],
|
||||||
|
],
|
||||||
|
NW: [
|
||||||
|
[-1, 0],
|
||||||
|
[-1, -1],
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
nekoEl.id = "oneko";
|
||||||
|
nekoEl.ariaHidden = true;
|
||||||
|
nekoEl.style.width = "32px";
|
||||||
|
nekoEl.style.height = "32px";
|
||||||
|
nekoEl.style.position = "fixed";
|
||||||
|
nekoEl.style.pointerEvents = "none";
|
||||||
|
nekoEl.style.imageRendering = "pixelated";
|
||||||
|
nekoEl.style.left = `${nekoPosX - 16}px`;
|
||||||
|
nekoEl.style.top = `${nekoPosY - 16}px`;
|
||||||
|
nekoEl.style.zIndex = Number.MAX_VALUE;
|
||||||
|
|
||||||
|
let nekoFile = "/assets/images/oneko.gif"
|
||||||
|
const curScript = document.currentScript
|
||||||
|
if (curScript && curScript.dataset.cat) {
|
||||||
|
nekoFile = curScript.dataset.cat
|
||||||
|
}
|
||||||
|
nekoEl.style.backgroundImage = `url(${nekoFile})`;
|
||||||
|
|
||||||
|
document.body.appendChild(nekoEl);
|
||||||
|
|
||||||
|
document.addEventListener("mousemove", function (event) {
|
||||||
|
mousePosX = event.clientX;
|
||||||
|
mousePosY = event.clientY;
|
||||||
|
});
|
||||||
|
|
||||||
|
window.requestAnimationFrame(onAnimationFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
let lastFrameTimestamp;
|
||||||
|
|
||||||
|
function onAnimationFrame(timestamp) {
|
||||||
|
// Stops execution if the neko element is removed from DOM
|
||||||
|
if (!nekoEl.isConnected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!lastFrameTimestamp) {
|
||||||
|
lastFrameTimestamp = timestamp;
|
||||||
|
}
|
||||||
|
if (timestamp - lastFrameTimestamp > 100) {
|
||||||
|
lastFrameTimestamp = timestamp
|
||||||
|
frame()
|
||||||
|
}
|
||||||
|
window.requestAnimationFrame(onAnimationFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSprite(name, frame) {
|
||||||
|
const sprite = spriteSets[name][frame % spriteSets[name].length];
|
||||||
|
nekoEl.style.backgroundPosition = `${sprite[0] * 32}px ${sprite[1] * 32}px`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetIdleAnimation() {
|
||||||
|
idleAnimation = null;
|
||||||
|
idleAnimationFrame = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function idle() {
|
||||||
|
idleTime += 1;
|
||||||
|
|
||||||
|
// every ~ 20 seconds
|
||||||
|
if (
|
||||||
|
idleTime > 10 &&
|
||||||
|
Math.floor(Math.random() * 200) == 0 &&
|
||||||
|
idleAnimation == null
|
||||||
|
) {
|
||||||
|
let avalibleIdleAnimations = ["sleeping", "scratchSelf"];
|
||||||
|
if (nekoPosX < 32) {
|
||||||
|
avalibleIdleAnimations.push("scratchWallW");
|
||||||
|
}
|
||||||
|
if (nekoPosY < 32) {
|
||||||
|
avalibleIdleAnimations.push("scratchWallN");
|
||||||
|
}
|
||||||
|
if (nekoPosX > window.innerWidth - 32) {
|
||||||
|
avalibleIdleAnimations.push("scratchWallE");
|
||||||
|
}
|
||||||
|
if (nekoPosY > window.innerHeight - 32) {
|
||||||
|
avalibleIdleAnimations.push("scratchWallS");
|
||||||
|
}
|
||||||
|
idleAnimation =
|
||||||
|
avalibleIdleAnimations[
|
||||||
|
Math.floor(Math.random() * avalibleIdleAnimations.length)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (idleAnimation) {
|
||||||
|
case "sleeping":
|
||||||
|
if (idleAnimationFrame < 8) {
|
||||||
|
setSprite("tired", 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
setSprite("sleeping", Math.floor(idleAnimationFrame / 4));
|
||||||
|
if (idleAnimationFrame > 192) {
|
||||||
|
resetIdleAnimation();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "scratchWallN":
|
||||||
|
case "scratchWallS":
|
||||||
|
case "scratchWallE":
|
||||||
|
case "scratchWallW":
|
||||||
|
case "scratchSelf":
|
||||||
|
setSprite(idleAnimation, idleAnimationFrame);
|
||||||
|
if (idleAnimationFrame > 9) {
|
||||||
|
resetIdleAnimation();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
setSprite("idle", 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
idleAnimationFrame += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function frame() {
|
||||||
|
frameCount += 1;
|
||||||
|
const diffX = nekoPosX - mousePosX;
|
||||||
|
const diffY = nekoPosY - mousePosY;
|
||||||
|
const distance = Math.sqrt(diffX ** 2 + diffY ** 2);
|
||||||
|
|
||||||
|
if (distance < nekoSpeed || distance < 48) {
|
||||||
|
idle();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
idleAnimation = null;
|
||||||
|
idleAnimationFrame = 0;
|
||||||
|
|
||||||
|
if (idleTime > 1) {
|
||||||
|
setSprite("alert", 0);
|
||||||
|
// count down after being alerted before moving
|
||||||
|
idleTime = Math.min(idleTime, 7);
|
||||||
|
idleTime -= 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let direction;
|
||||||
|
direction = diffY / distance > 0.5 ? "N" : "";
|
||||||
|
direction += diffY / distance < -0.5 ? "S" : "";
|
||||||
|
direction += diffX / distance > 0.5 ? "W" : "";
|
||||||
|
direction += diffX / distance < -0.5 ? "E" : "";
|
||||||
|
setSprite(direction, frameCount);
|
||||||
|
|
||||||
|
nekoPosX -= (diffX / distance) * nekoSpeed;
|
||||||
|
nekoPosY -= (diffY / distance) * nekoSpeed;
|
||||||
|
|
||||||
|
nekoPosX = Math.min(Math.max(16, nekoPosX), window.innerWidth - 16);
|
||||||
|
nekoPosY = Math.min(Math.max(16, nekoPosY), window.innerHeight - 16);
|
||||||
|
|
||||||
|
nekoEl.style.left = `${nekoPosX - 16}px`;
|
||||||
|
nekoEl.style.top = `${nekoPosY - 16}px`;
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
|
})();
|
38
author.hbs
|
@ -1,38 +0,0 @@
|
||||||
{{!< default}}
|
|
||||||
|
|
||||||
<main class="gh-main gh-outer">
|
|
||||||
{{#author}}
|
|
||||||
<section class="gh-article gh-inner">
|
|
||||||
<header class="gh-article-header">
|
|
||||||
{{#if profile_image}}
|
|
||||||
<img class="gh-author-image" src="{{img_url profile_image size="s"}}" alt="{{name}}">
|
|
||||||
{{/if}}
|
|
||||||
<h1 class="gh-article-title">{{name}}</h1>
|
|
||||||
{{#if bio}}
|
|
||||||
<p class="gh-article-excerpt">{{bio}}</p>
|
|
||||||
{{/if}}
|
|
||||||
</header>
|
|
||||||
<footer class="gh-author-meta">
|
|
||||||
{{#if location}}
|
|
||||||
<div class="gh-author-location">{{location}}</div>
|
|
||||||
{{/if}}
|
|
||||||
<div class="gh-author-social">
|
|
||||||
{{#if website}}
|
|
||||||
<a class="gh-author-social-link" href="{{website}}" target="_blank" rel="noopener">{{website}}</a>
|
|
||||||
{{/if}}
|
|
||||||
{{#if twitter}}
|
|
||||||
<a class="gh-author-social-link" href="{{twitter_url}}" target="_blank" rel="noopener">{{> "icons/twitter"}}</a>
|
|
||||||
{{/if}}
|
|
||||||
{{#if facebook}}
|
|
||||||
<a class="gh-author-social-link" href="{{facebook_url}}" target="_blank" rel="noopener">{{> "icons/facebook"}}</a>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
</section>
|
|
||||||
{{/author}}
|
|
||||||
<div class="gh-feed{{#match @custom.header_section_layout "!=" "Large background"}} gh-inner{{/match}}">
|
|
||||||
{{#foreach posts}}
|
|
||||||
{{> "loop"}}
|
|
||||||
{{/foreach}}
|
|
||||||
</div>
|
|
||||||
</main>
|
|
29
default.hbs
|
@ -54,41 +54,18 @@
|
||||||
{{@custom.footer_text}}
|
{{@custom.footer_text}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
<div class="social-media">
|
{{> "social-media"}}
|
||||||
{{#if @custom.email_address}}
|
|
||||||
<a class="social-icon" alt="Email" href={{@custom.email_address}}>
|
|
||||||
{{> "icons/email"}}
|
|
||||||
</a>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if @custom.mastodon_link}}
|
|
||||||
<a class="social-icon" alt="Mastodon" href={{@custom.mastodon_link}}>
|
|
||||||
{{> "icons/mastodon"}}
|
|
||||||
</a>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if @custom.matrix_contact}}
|
|
||||||
<a class="social-icon" alt="Matrix" href={{@custom.matrix_contact}}>
|
|
||||||
{{> "icons/matrix"}}
|
|
||||||
</a>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if @custom.linkedin_contact}}
|
|
||||||
<a class="social-icon" alt="LinkedIn" href={{@custom.linkedin_contact}}>
|
|
||||||
{{> "icons/linkedin"}}
|
|
||||||
</a>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#is "post, page"}}
|
{{#is "post, page"}}
|
||||||
{{> "box-info"}}
|
{{> "pswp"}}
|
||||||
{{/is}}
|
{{/is}}
|
||||||
|
|
||||||
<script src="{{asset "built/main.min.js"}}"></script>
|
<script src="{{asset "built/main.min.js"}}"></script>
|
||||||
|
<script src="{{asset "js/oneko.js"}}"></script>
|
||||||
|
|
||||||
{{ghost_foot}}
|
{{ghost_foot}}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
Copyright (c) 2024 Jean Viscogliosi-Pate
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person
|
||||||
|
obtaining a copy of this software and associated documentation
|
||||||
|
files (the "Software"), to deal in the Software without
|
||||||
|
restriction, including without limitation the rights to use,
|
||||||
|
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following
|
||||||
|
conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,35 @@
|
||||||
|
# Bifocal
|
||||||
|
|
||||||
|
Bifocal is is a minimal theme for [Ghost](https://github.com/TryGhost/Ghost) based on Solo. It features a two-column layout when screen width allows and displays internal tags to the user.
|
||||||
|
|
||||||
|
# Instructions
|
||||||
|
|
||||||
|
1. Download this theme
|
||||||
|
2. Log into Ghost, and go to the `Design` settings area to upload the zip file
|
||||||
|
|
||||||
|
# Development
|
||||||
|
|
||||||
|
Edition styles are compiled using Gulp/PostCSS to polyfill future CSS spec. You'll need [Node](https://nodejs.org/), [Yarn](https://yarnpkg.com/) and [Gulp](https://gulpjs.com) installed globally. After that, from the theme's root directory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install
|
||||||
|
yarn
|
||||||
|
|
||||||
|
# Run build & watch for changes
|
||||||
|
yarn dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you can edit `/assets/css/` files, which will be compiled to `/assets/built/` automatically.
|
||||||
|
|
||||||
|
The `zip` Gulp task packages the theme files into `dist/solo.zip`, which you can then upload to your site.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn zip
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that GIF files processed by Gulp become corrupted, so you will either have to use another file type or replace those files and re-zip manually in order to use GIF images.
|
||||||
|
|
||||||
|
## Copyright & License
|
||||||
|
|
||||||
|
Copyright (c) 2024 Jean Viscogliosi-Pate - Released under the [MIT license](LICENSE).
|
||||||
|
Original Solo theme relased 2013-2023 Ghost Foundation under the MIT license.
|
|
@ -0,0 +1,49 @@
|
||||||
|
@font-face {
|
||||||
|
font-family: "Wanted Sans";
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 1000;
|
||||||
|
src: local("Wanted Sans ExtraBlack"), url("../fonts/WantedSans-ExtraBlack.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Wanted Sans";
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 900;
|
||||||
|
src: local("Wanted Sans Black"), url("../fonts/WantedSans-Black.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Wanted Sans";
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 800;
|
||||||
|
src: local("Wanted Sans ExtraBold"), url("../fonts/WantedSans-ExtraBold.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Wanted Sans";
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 700;
|
||||||
|
src: local("Wanted Sans Bold"), url("../fonts/WantedSans-Bold.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Wanted Sans";
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 600;
|
||||||
|
src: local("Wanted Sans SemiBold"), url("../fonts/WantedSans-SemiBold.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Wanted Sans";
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 500;
|
||||||
|
src: local("Wanted Sans Medium"), url("../fonts/WantedSans-Medium.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Wanted Sans";
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 400;
|
||||||
|
src: local("Wanted Sans Regular"), url("../fonts/WantedSans-Regular.woff2") format("woff2");
|
||||||
|
}
|
|
@ -0,0 +1,552 @@
|
||||||
|
@import "@tryghost/shared-theme-assets/assets/css/v1/screen.css";
|
||||||
|
@import "fonts.css";
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--font-sans: Wanted Sans, Century Gothic, Frutiger, Futura, Montserrat, -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif;
|
||||||
|
--color-primary-text: var(--color-darker-gray);
|
||||||
|
--color-secondary-text-dark: rgba(0, 0, 0, 0.4);
|
||||||
|
--color-secondary-text-light: rgba(255, 255, 255, 0.64);
|
||||||
|
--color-secondary-text: var(--color-secondary-text-dark);
|
||||||
|
--color-border: rgba(0, 0, 0, 0.08);
|
||||||
|
--gap: clamp(24px, 1.7032rem + 1.9355vw, 48px);
|
||||||
|
--head-nav-gap: 32px;
|
||||||
|
--container-width: 1440px;
|
||||||
|
--title-font-size: clamp(3.2rem, 2.7rem + 1.5625vw, 5.2rem);
|
||||||
|
--content-font-size: clamp(1.7rem, 0.38vw + 1.4rem, 2rem);
|
||||||
|
--header-spacing: clamp(4.8rem, 4rem + 2.5vw, 8rem);
|
||||||
|
--background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root.has-light-text {
|
||||||
|
--color-lighter-gray: rgba(0, 0, 0, 0.1);
|
||||||
|
--color-darker-gray: #fff;
|
||||||
|
--color-secondary-text: var(--color-secondary-text-light);
|
||||||
|
--color-border: rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: var(--background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-main {
|
||||||
|
padding-top: clamp(4.8rem, 4rem + 2.5vw, 8rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
figcaption {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kg-width-full figcaption {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
background-color: var(--color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-content h2 {
|
||||||
|
font-size: 2.25em;
|
||||||
|
letter-spacing: -0.03em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-content h3 {
|
||||||
|
font-size: 1.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-canvas {
|
||||||
|
grid-template-columns: repeat(12, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-canvas > * {
|
||||||
|
grid-column: 4 / span 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-canvas > .kg-width-wide {
|
||||||
|
grid-column: 4 / span 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-canvas > .kg-width-full,
|
||||||
|
.gh-canvas > .kg-gallery-card.kg-width-wide {
|
||||||
|
position: relative;
|
||||||
|
z-index: 20;
|
||||||
|
grid-column: 1 / span 12;
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 991px) {
|
||||||
|
.gh-canvas > * {
|
||||||
|
grid-column: 3 / span 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-canvas > .kg-width-wide {
|
||||||
|
grid-column: 3 / span 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.gh-canvas > * {
|
||||||
|
grid-column: 2 / span 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-canvas > .kg-width-wide {
|
||||||
|
grid-column: 1 / span 12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.gh-canvas > * {
|
||||||
|
grid-column: 1 / span 12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header
|
||||||
|
/* ---------------------------------------------------------- */
|
||||||
|
|
||||||
|
.gh-head {
|
||||||
|
font-size: 1.6rem;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-head-logo {
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-head-logo img {
|
||||||
|
max-height: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-head-menu,
|
||||||
|
.gh-head-link {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-head-stacked .gh-head-menu::before,
|
||||||
|
.is-head-stacked .gh-head-menu::after {
|
||||||
|
background-color: var(--color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-head-menu a {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 991px) {
|
||||||
|
.is-head-open:not(.is-head-brand):not(.is-head-dark):not(.is-head-transparent) :is(#gh-head, #gh-head .gh-head-actions) {
|
||||||
|
background-color: var(--background-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* About section
|
||||||
|
/* ---------------------------------------------------------- */
|
||||||
|
|
||||||
|
.gh-about {
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-about-primary {
|
||||||
|
font-size: clamp(3.2rem, 2.4452rem + 2.0968vw, 5.8rem);
|
||||||
|
font-weight: 800;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-about-primary a {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-about-secondary {
|
||||||
|
font-size: clamp(2.4rem, 0.54vw + 2.14rem, 3rem);
|
||||||
|
font-weight: 500;
|
||||||
|
letter-spacing: -0.008em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-about-primary + .gh-about-secondary {
|
||||||
|
margin-top: 20px;
|
||||||
|
font-size: clamp(2rem, 0.36vw + 1.83rem, 2.4rem);
|
||||||
|
font-weight: 450;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-about-secondary a {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Post card
|
||||||
|
/* ---------------------------------------------------------- */
|
||||||
|
|
||||||
|
.gh-card-link:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-card-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-card-title {
|
||||||
|
font-weight: 800;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-card-link:hover .gh-card-title {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-card-meta {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 16px;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--color-secondary-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-card-meta > * {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-card-meta > * + *:not(script):not(.gh-card-access)::before {
|
||||||
|
width: 2px;
|
||||||
|
height: 2px;
|
||||||
|
content: "";
|
||||||
|
background-color: currentColor;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-card-access {
|
||||||
|
padding: 0 10px 0 8px;
|
||||||
|
margin-left: 4px;
|
||||||
|
background-color: var(--color-border);
|
||||||
|
border-radius: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.has-parallax-feed .gh-card-access {
|
||||||
|
color: var(--color-darker-gray);
|
||||||
|
background-color: var(--color-white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-card-access svg {
|
||||||
|
margin-right: -5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tag display
|
||||||
|
/* ---------------------------------------------------------- */
|
||||||
|
.tag-list {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
justify-content: space-around;
|
||||||
|
list-style: none;
|
||||||
|
align-items: center;
|
||||||
|
padding-left: 0;
|
||||||
|
column-gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-icon {
|
||||||
|
float: left;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-text {
|
||||||
|
overflow: auto;
|
||||||
|
line-height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-desc {
|
||||||
|
color: var(--color-secondary-text);
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: calc(var(--title-font-size) * 0.7);
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
block-size: var(--title-font-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Feed
|
||||||
|
/* ---------------------------------------------------------- */
|
||||||
|
|
||||||
|
.feed-cta {
|
||||||
|
display: flex;
|
||||||
|
justify-content: right;
|
||||||
|
padding-bottom: var(--gap);
|
||||||
|
column-gap: 10px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-card.no-image {
|
||||||
|
max-width: 1200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-card-image {
|
||||||
|
position: relative;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-card-image::before {
|
||||||
|
display: block;
|
||||||
|
padding-bottom: 18.75%;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-image .gh-card-image {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-card-image img {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-card-title {
|
||||||
|
font-size: var(--title-font-size);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-card-excerpt {
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kg-width-full .gh-card-title {
|
||||||
|
font-size: clamp(3.2rem, 2.4rem + 2.5vw, 6.4rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-feed {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
column-gap: var(--gap);
|
||||||
|
row-gap: calc(var(--gap) * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 991px) {
|
||||||
|
.gh-feed {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
row-gap: calc(var(--gap) * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Article
|
||||||
|
/* ---------------------------------------------------------- */
|
||||||
|
|
||||||
|
.gh-article-meta {
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 10;
|
||||||
|
grid-row-start: 1;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-article-meta-inner {
|
||||||
|
position: sticky;
|
||||||
|
top: 48px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-article-meta .gh-author-image {
|
||||||
|
width: 72px;
|
||||||
|
height: 72px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-article-meta .gh-author-name {
|
||||||
|
font-size: 1.9rem;
|
||||||
|
letter-spacing: -0.01em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-article-meta .gh-author-name a {
|
||||||
|
color: var(--color-darker-gray);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-article-date {
|
||||||
|
margin-top: 4px;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
font-weight: 480;
|
||||||
|
color: var(--color-secondary-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-article-tag {
|
||||||
|
width: fit-content;
|
||||||
|
padding: 2px 12px;
|
||||||
|
margin-top: 20px;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--tag-color, var(--color-darker-gray)) !important;
|
||||||
|
text-decoration: none !important;
|
||||||
|
letter-spacing: -0.01em;
|
||||||
|
border: 2px solid var(--color-border);
|
||||||
|
border-radius: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-content .gh-article-header {
|
||||||
|
grid-row-start: 1;
|
||||||
|
grid-column: 4 / span 9;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: clamp(4.8rem, 1.43vw + 4.11rem, 6.4rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-article-title {
|
||||||
|
grid-column: 1 / span 9;
|
||||||
|
font-size: clamp(4rem, 2.86vw + 2.63rem, 7.2rem);
|
||||||
|
font-weight: 800;
|
||||||
|
line-height: 1;
|
||||||
|
letter-spacing: -0.03em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-template .no-image .gh-article-title {
|
||||||
|
grid-column: 4 / span 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-article-excerpt {
|
||||||
|
grid-column: 1 / span 9;
|
||||||
|
max-width: 840px;
|
||||||
|
font-size: clamp(1.8rem, 0.54vw + 1.54rem, 2.4rem);
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.45;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-template .no-image .gh-article-excerpt {
|
||||||
|
grid-column: 4 / span 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-article-excerpt .emoji {
|
||||||
|
color: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-article-image {
|
||||||
|
grid-column: 1 / span 12;
|
||||||
|
margin-top: clamp(4rem, 3rem + 3.125vw, 8rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-content {
|
||||||
|
--content-spacing-multiplier: 1.5;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
margin-top: clamp(4rem, 3rem + 3.125vw, 8rem);
|
||||||
|
line-height: 1.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
:is(.post-template, .page-template) .no-image .gh-content {
|
||||||
|
margin-top: clamp(4rem, 2.14vw + 2.97rem, 6.4rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-content > [id] {
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-content > :is(p, ul, ol) {
|
||||||
|
font-weight: 480;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-article-footer {
|
||||||
|
margin-top: clamp(6.4rem, 3rem + 10.625vw, 20rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
.gh-article-meta {
|
||||||
|
position: absolute;
|
||||||
|
grid-column: 1 / span 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 991px) {
|
||||||
|
:is(.gh-article-title, .gh-article-excerpt),
|
||||||
|
.gh-content > .gh-article-header {
|
||||||
|
grid-column: 1 / span 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-article-meta {
|
||||||
|
margin-bottom: 32px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-image .gh-article-meta {
|
||||||
|
grid-row-start: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-article-meta-inner {
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-article-meta .gh-author-image {
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
margin-right: 12px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-article-meta-wrapper {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-article-tag {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
:is(.gh-article-title, .gh-article-excerpt),
|
||||||
|
.gh-content > .gh-article-header {
|
||||||
|
grid-column: 1 / span 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-content {
|
||||||
|
font-size: var(--content-font-size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Navigation
|
||||||
|
/* ---------------------------------------------------------- */
|
||||||
|
|
||||||
|
.gh-navigation {
|
||||||
|
grid-column: 1 / span 12;
|
||||||
|
font-size: clamp(2rem, 1.7rem + 0.9375vw, 3.2rem);
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Footer
|
||||||
|
/* ---------------------------------------------------------- */
|
||||||
|
|
||||||
|
.gh-foot {
|
||||||
|
padding-top: clamp(8rem, 4.55vw + 6.18rem, 12rem);
|
||||||
|
padding-bottom: clamp(8rem, 4.55vw + 6.18rem, 12rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-foot-inner {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 24px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-foot-menu {
|
||||||
|
font-size: 1.6rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gh-copyright {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-media {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
column-gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-icon {
|
||||||
|
height: 32px;
|
||||||
|
width: 32px;
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
Copyright 2024 The Wanted Sans Project Authors (https://github.com/wanteddev/wanted-sans)
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
https://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@ -0,0 +1,5 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="30" height="30" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-mail" id="email">
|
||||||
|
<title>Mail</title>
|
||||||
|
<path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path>
|
||||||
|
<polyline points="22,6 12,13 2,6"></polyline>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 401 B |
|
@ -0,0 +1,13 @@
|
||||||
|
<svg id="linkedin" fill="currentColor" height="800px" width="800px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
viewBox="0 0 310 310" xml:space="preserve">
|
||||||
|
<g id="XMLID_801_">
|
||||||
|
<path id="XMLID_802_" d="M72.16,99.73H9.927c-2.762,0-5,2.239-5,5v199.928c0,2.762,2.238,5,5,5H72.16c2.762,0,5-2.238,5-5V104.73
|
||||||
|
C77.16,101.969,74.922,99.73,72.16,99.73z"/>
|
||||||
|
<path id="XMLID_803_" d="M41.066,0.341C18.422,0.341,0,18.743,0,41.362C0,63.991,18.422,82.4,41.066,82.4
|
||||||
|
c22.626,0,41.033-18.41,41.033-41.038C82.1,18.743,63.692,0.341,41.066,0.341z"/>
|
||||||
|
<path id="XMLID_804_" d="M230.454,94.761c-24.995,0-43.472,10.745-54.679,22.954V104.73c0-2.761-2.238-5-5-5h-59.599
|
||||||
|
c-2.762,0-5,2.239-5,5v199.928c0,2.762,2.238,5,5,5h62.097c2.762,0,5-2.238,5-5v-98.918c0-33.333,9.054-46.319,32.29-46.319
|
||||||
|
c25.306,0,27.317,20.818,27.317,48.034v97.204c0,2.762,2.238,5,5,5H305c2.762,0,5-2.238,5-5V194.995
|
||||||
|
C310,145.43,300.549,94.761,230.454,94.761z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 979 B |
|
@ -0,0 +1,5 @@
|
||||||
|
<svg id="mastodon" role="img" viewBox="0 0 24 24" width="30" height="30" xmlns="http://www.w3.org/2000/svg" fill="currentColor">
|
||||||
|
<title>Mastodon</title>
|
||||||
|
<path
|
||||||
|
d="M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,5 @@
|
||||||
|
<svg id="matrix" role="img" viewBox="0 0 24 24" width="30" height="30" xmlns="http://www.w3.org/2000/svg" fill="currentColor">
|
||||||
|
<title>Matrix</title>
|
||||||
|
<path
|
||||||
|
d="M.632.55v22.9H2.28V24H0V0h2.28v.55zm7.043 7.26v1.157h.033c.309-.443.683-.784 1.117-1.024.433-.245.936-.365 1.5-.365.54 0 1.033.107 1.481.314.448.208.785.582 1.02 1.108.254-.374.6-.706 1.034-.992.434-.287.95-.43 1.546-.43.453 0 .872.056 1.26.167.388.11.716.286.993.53.276.245.489.559.646.951.152.392.23.863.23 1.417v5.728h-2.349V11.52c0-.286-.01-.559-.032-.812a1.755 1.755 0 0 0-.18-.66 1.106 1.106 0 0 0-.438-.448c-.194-.11-.457-.166-.785-.166-.332 0-.6.064-.803.189a1.38 1.38 0 0 0-.48.499 1.946 1.946 0 0 0-.231.696 5.56 5.56 0 0 0-.06.785v4.768h-2.35v-4.8c0-.254-.004-.503-.018-.752a2.074 2.074 0 0 0-.143-.688 1.052 1.052 0 0 0-.415-.503c-.194-.125-.476-.19-.854-.19-.111 0-.259.024-.439.074-.18.051-.36.143-.53.282-.171.138-.319.337-.439.595-.12.259-.18.6-.18 1.02v4.966H5.46V7.81zm15.693 15.64V.55H21.72V0H24v24h-2.28v-.55z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1015 B |
After Width: | Height: | Size: 547 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg width="264" height="88" viewBox="0 0 264 88" xmlns="http://www.w3.org/2000/svg"><title>default-skin 2</title><g fill="none" fill-rule="evenodd"><g><path d="M67.002 59.5v3.768c-6.307.84-9.184 5.75-10.002 9.732 2.22-2.83 5.564-5.098 10.002-5.098V71.5L73 65.585 67.002 59.5z" id="Shape" fill="#fff"/><g fill="#fff"><path d="M13 29v-5h2v3h3v2h-5zM13 15h5v2h-3v3h-2v-5zM31 15v5h-2v-3h-3v-2h5zM31 29h-5v-2h3v-3h2v5z" id="Shape"/></g><g fill="#fff"><path d="M62 24v5h-2v-3h-3v-2h5zM62 20h-5v-2h3v-3h2v5zM70 20v-5h2v3h3v2h-5zM70 24h5v2h-3v3h-2v-5z"/></g><path d="M20.586 66l-5.656-5.656 1.414-1.414L22 64.586l5.656-5.656 1.414 1.414L23.414 66l5.656 5.656-1.414 1.414L22 67.414l-5.656 5.656-1.414-1.414L20.586 66z" fill="#fff"/><path d="M111.785 65.03L110 63.5l3-3.5h-10v-2h10l-3-3.5 1.785-1.468L117 59l-5.215 6.03z" fill="#fff"/><path d="M152.215 65.03L154 63.5l-3-3.5h10v-2h-10l3-3.5-1.785-1.468L147 59l5.215 6.03z" fill="#fff"/><g><path id="Rectangle-11" fill="#fff" d="M160.957 28.543l-3.25-3.25-1.413 1.414 3.25 3.25z"/><path d="M152.5 27c3.038 0 5.5-2.462 5.5-5.5s-2.462-5.5-5.5-5.5-5.5 2.462-5.5 5.5 2.462 5.5 5.5 5.5z" id="Oval-1" stroke="#fff" stroke-width="1.5"/><path fill="#fff" d="M150 21h5v1h-5z"/></g><g><path d="M116.957 28.543l-1.414 1.414-3.25-3.25 1.414-1.414 3.25 3.25z" fill="#fff"/><path d="M108.5 27c3.038 0 5.5-2.462 5.5-5.5s-2.462-5.5-5.5-5.5-5.5 2.462-5.5 5.5 2.462 5.5 5.5 5.5z" stroke="#fff" stroke-width="1.5"/><path fill="#fff" d="M106 21h5v1h-5z"/><path fill="#fff" d="M109.043 19.008l-.085 5-1-.017.085-5z"/></g></g></g></svg>
|
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 866 B |
|
@ -0,0 +1,54 @@
|
||||||
|
function initParallax() {
|
||||||
|
jarallax(document.querySelectorAll('.has-parallax-feed .gh-card'), {
|
||||||
|
speed: 0.8,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
if (!document.body.classList.contains('has-background-about')) return;
|
||||||
|
|
||||||
|
const about = document.querySelector('.gh-about');
|
||||||
|
if (!about) return;
|
||||||
|
|
||||||
|
const image = about.querySelector('.gh-about-image');
|
||||||
|
|
||||||
|
if (!image.naturalWidth) {
|
||||||
|
imagesLoaded(image, function () {
|
||||||
|
about.style.setProperty('--about-height', image.clientWidth * image.naturalHeight / image.naturalWidth + 'px');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
initParallax();
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
const toggle = document.querySelector('[data-toggle-comments]');
|
||||||
|
if (!toggle) return;
|
||||||
|
|
||||||
|
toggle.addEventListener('click', function () {
|
||||||
|
document.body.classList.toggle('comments-opened');
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
const element = document.querySelector('.gh-article-excerpt');
|
||||||
|
if (!element) return;
|
||||||
|
|
||||||
|
let text = element.textContent;
|
||||||
|
const emojiRE = /\p{EPres}|\p{ExtPict}/gu;
|
||||||
|
|
||||||
|
const emojis = text.match(emojiRE);
|
||||||
|
if (!emojis) return;
|
||||||
|
|
||||||
|
emojis.forEach(function (emoji) {
|
||||||
|
text = text.replace(emoji, `<span class="emoji">${emoji}</span>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
element.innerHTML = text;
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
pagination(true, initParallax);
|
||||||
|
})();
|
|
@ -0,0 +1,239 @@
|
||||||
|
// oneko.js: https://github.com/adryd325/oneko.js
|
||||||
|
|
||||||
|
(function oneko() {
|
||||||
|
const isReducedMotion =
|
||||||
|
window.matchMedia(`(prefers-reduced-motion: reduce)`) === true ||
|
||||||
|
window.matchMedia(`(prefers-reduced-motion: reduce)`).matches === true;
|
||||||
|
|
||||||
|
if (isReducedMotion) return;
|
||||||
|
|
||||||
|
const nekoEl = document.createElement("div");
|
||||||
|
|
||||||
|
let nekoPosX = 32;
|
||||||
|
let nekoPosY = 32;
|
||||||
|
|
||||||
|
let mousePosX = 0;
|
||||||
|
let mousePosY = 0;
|
||||||
|
|
||||||
|
let frameCount = 0;
|
||||||
|
let idleTime = 0;
|
||||||
|
let idleAnimation = null;
|
||||||
|
let idleAnimationFrame = 0;
|
||||||
|
|
||||||
|
const nekoSpeed = 10;
|
||||||
|
const spriteSets = {
|
||||||
|
idle: [[-3, -3]],
|
||||||
|
alert: [[-7, -3]],
|
||||||
|
scratchSelf: [
|
||||||
|
[-5, 0],
|
||||||
|
[-6, 0],
|
||||||
|
[-7, 0],
|
||||||
|
],
|
||||||
|
scratchWallN: [
|
||||||
|
[0, 0],
|
||||||
|
[0, -1],
|
||||||
|
],
|
||||||
|
scratchWallS: [
|
||||||
|
[-7, -1],
|
||||||
|
[-6, -2],
|
||||||
|
],
|
||||||
|
scratchWallE: [
|
||||||
|
[-2, -2],
|
||||||
|
[-2, -3],
|
||||||
|
],
|
||||||
|
scratchWallW: [
|
||||||
|
[-4, 0],
|
||||||
|
[-4, -1],
|
||||||
|
],
|
||||||
|
tired: [[-3, -2]],
|
||||||
|
sleeping: [
|
||||||
|
[-2, 0],
|
||||||
|
[-2, -1],
|
||||||
|
],
|
||||||
|
N: [
|
||||||
|
[-1, -2],
|
||||||
|
[-1, -3],
|
||||||
|
],
|
||||||
|
NE: [
|
||||||
|
[0, -2],
|
||||||
|
[0, -3],
|
||||||
|
],
|
||||||
|
E: [
|
||||||
|
[-3, 0],
|
||||||
|
[-3, -1],
|
||||||
|
],
|
||||||
|
SE: [
|
||||||
|
[-5, -1],
|
||||||
|
[-5, -2],
|
||||||
|
],
|
||||||
|
S: [
|
||||||
|
[-6, -3],
|
||||||
|
[-7, -2],
|
||||||
|
],
|
||||||
|
SW: [
|
||||||
|
[-5, -3],
|
||||||
|
[-6, -1],
|
||||||
|
],
|
||||||
|
W: [
|
||||||
|
[-4, -2],
|
||||||
|
[-4, -3],
|
||||||
|
],
|
||||||
|
NW: [
|
||||||
|
[-1, 0],
|
||||||
|
[-1, -1],
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
nekoEl.id = "oneko";
|
||||||
|
nekoEl.ariaHidden = true;
|
||||||
|
nekoEl.style.width = "32px";
|
||||||
|
nekoEl.style.height = "32px";
|
||||||
|
nekoEl.style.position = "fixed";
|
||||||
|
nekoEl.style.pointerEvents = "none";
|
||||||
|
nekoEl.style.imageRendering = "pixelated";
|
||||||
|
nekoEl.style.left = `${nekoPosX - 16}px`;
|
||||||
|
nekoEl.style.top = `${nekoPosY - 16}px`;
|
||||||
|
nekoEl.style.zIndex = Number.MAX_VALUE;
|
||||||
|
|
||||||
|
let nekoFile = "/assets/images/oneko.gif"
|
||||||
|
const curScript = document.currentScript
|
||||||
|
if (curScript && curScript.dataset.cat) {
|
||||||
|
nekoFile = curScript.dataset.cat
|
||||||
|
}
|
||||||
|
nekoEl.style.backgroundImage = `url(${nekoFile})`;
|
||||||
|
|
||||||
|
document.body.appendChild(nekoEl);
|
||||||
|
|
||||||
|
document.addEventListener("mousemove", function (event) {
|
||||||
|
mousePosX = event.clientX;
|
||||||
|
mousePosY = event.clientY;
|
||||||
|
});
|
||||||
|
|
||||||
|
window.requestAnimationFrame(onAnimationFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
let lastFrameTimestamp;
|
||||||
|
|
||||||
|
function onAnimationFrame(timestamp) {
|
||||||
|
// Stops execution if the neko element is removed from DOM
|
||||||
|
if (!nekoEl.isConnected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!lastFrameTimestamp) {
|
||||||
|
lastFrameTimestamp = timestamp;
|
||||||
|
}
|
||||||
|
if (timestamp - lastFrameTimestamp > 100) {
|
||||||
|
lastFrameTimestamp = timestamp
|
||||||
|
frame()
|
||||||
|
}
|
||||||
|
window.requestAnimationFrame(onAnimationFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSprite(name, frame) {
|
||||||
|
const sprite = spriteSets[name][frame % spriteSets[name].length];
|
||||||
|
nekoEl.style.backgroundPosition = `${sprite[0] * 32}px ${sprite[1] * 32}px`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetIdleAnimation() {
|
||||||
|
idleAnimation = null;
|
||||||
|
idleAnimationFrame = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function idle() {
|
||||||
|
idleTime += 1;
|
||||||
|
|
||||||
|
// every ~ 20 seconds
|
||||||
|
if (
|
||||||
|
idleTime > 10 &&
|
||||||
|
Math.floor(Math.random() * 200) == 0 &&
|
||||||
|
idleAnimation == null
|
||||||
|
) {
|
||||||
|
let avalibleIdleAnimations = ["sleeping", "scratchSelf"];
|
||||||
|
if (nekoPosX < 32) {
|
||||||
|
avalibleIdleAnimations.push("scratchWallW");
|
||||||
|
}
|
||||||
|
if (nekoPosY < 32) {
|
||||||
|
avalibleIdleAnimations.push("scratchWallN");
|
||||||
|
}
|
||||||
|
if (nekoPosX > window.innerWidth - 32) {
|
||||||
|
avalibleIdleAnimations.push("scratchWallE");
|
||||||
|
}
|
||||||
|
if (nekoPosY > window.innerHeight - 32) {
|
||||||
|
avalibleIdleAnimations.push("scratchWallS");
|
||||||
|
}
|
||||||
|
idleAnimation =
|
||||||
|
avalibleIdleAnimations[
|
||||||
|
Math.floor(Math.random() * avalibleIdleAnimations.length)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (idleAnimation) {
|
||||||
|
case "sleeping":
|
||||||
|
if (idleAnimationFrame < 8) {
|
||||||
|
setSprite("tired", 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
setSprite("sleeping", Math.floor(idleAnimationFrame / 4));
|
||||||
|
if (idleAnimationFrame > 192) {
|
||||||
|
resetIdleAnimation();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "scratchWallN":
|
||||||
|
case "scratchWallS":
|
||||||
|
case "scratchWallE":
|
||||||
|
case "scratchWallW":
|
||||||
|
case "scratchSelf":
|
||||||
|
setSprite(idleAnimation, idleAnimationFrame);
|
||||||
|
if (idleAnimationFrame > 9) {
|
||||||
|
resetIdleAnimation();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
setSprite("idle", 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
idleAnimationFrame += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function frame() {
|
||||||
|
frameCount += 1;
|
||||||
|
const diffX = nekoPosX - mousePosX;
|
||||||
|
const diffY = nekoPosY - mousePosY;
|
||||||
|
const distance = Math.sqrt(diffX ** 2 + diffY ** 2);
|
||||||
|
|
||||||
|
if (distance < nekoSpeed || distance < 48) {
|
||||||
|
idle();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
idleAnimation = null;
|
||||||
|
idleAnimationFrame = 0;
|
||||||
|
|
||||||
|
if (idleTime > 1) {
|
||||||
|
setSprite("alert", 0);
|
||||||
|
// count down after being alerted before moving
|
||||||
|
idleTime = Math.min(idleTime, 7);
|
||||||
|
idleTime -= 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let direction;
|
||||||
|
direction = diffY / distance > 0.5 ? "N" : "";
|
||||||
|
direction += diffY / distance < -0.5 ? "S" : "";
|
||||||
|
direction += diffX / distance > 0.5 ? "W" : "";
|
||||||
|
direction += diffX / distance < -0.5 ? "E" : "";
|
||||||
|
setSprite(direction, frameCount);
|
||||||
|
|
||||||
|
nekoPosX -= (diffX / distance) * nekoSpeed;
|
||||||
|
nekoPosY -= (diffY / distance) * nekoSpeed;
|
||||||
|
|
||||||
|
nekoPosX = Math.min(Math.max(16, nekoPosX), window.innerWidth - 16);
|
||||||
|
nekoPosY = Math.min(Math.max(16, nekoPosY), window.innerHeight - 16);
|
||||||
|
|
||||||
|
nekoEl.style.left = `${nekoPosX - 16}px`;
|
||||||
|
nekoEl.style.top = `${nekoPosY - 16}px`;
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
|
})();
|
|
@ -0,0 +1,74 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="{{@site.locale}}">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>{{meta_title}}</title>
|
||||||
|
<link rel="stylesheet" href="{{asset "built/screen.css"}}">
|
||||||
|
|
||||||
|
{{#is "home"}}
|
||||||
|
{{#if @site.cover_image}}
|
||||||
|
<link rel="preload" as="image" href="{{@site.cover_image}}">
|
||||||
|
{{/if}}
|
||||||
|
{{/is}}
|
||||||
|
|
||||||
|
{{ghost_head}}
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="{{body_class}}{{{block "body_class"}}} is-head-{{#match @custom.navigation_layout "Logo on the left"}}left-logo{{else match @custom.navigation_layout "Logo in the middle"}}middle-logo{{else}}stacked{{/match}}">
|
||||||
|
<div class="gh-site">
|
||||||
|
|
||||||
|
<header id="gh-head" class="gh-head gh-outer">
|
||||||
|
<div class="gh-head-inner gh-inner">
|
||||||
|
<div class="gh-head-brand">
|
||||||
|
<div class="gh-head-brand-wrapper">
|
||||||
|
<a class="gh-head-logo" href="{{@site.url}}">
|
||||||
|
{{#if @site.logo}}
|
||||||
|
<img src="{{@site.logo}}" alt="{{@site.title}}">
|
||||||
|
{{else}}
|
||||||
|
{{@site.title}}
|
||||||
|
{{/if}}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<button class="gh-search gh-icon-btn" aria-label="Search this site" data-ghost-search>{{> "icons/search"}}</button>
|
||||||
|
<button class="gh-burger"></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<nav class="gh-head-menu">
|
||||||
|
{{navigation}}
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="gh-head-actions">
|
||||||
|
<button class="gh-search gh-icon-btn" aria-label="Search this site" data-ghost-search>{{> "icons/search"}}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{{{body}}}
|
||||||
|
|
||||||
|
<footer class="gh-foot gh-outer">
|
||||||
|
<div class="gh-foot-inner gh-inner">
|
||||||
|
<div class="gh-copyright">
|
||||||
|
{{#if @custom.footer_text}}
|
||||||
|
{{@custom.footer_text}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{> "social-media"}}
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#is "post, page"}}
|
||||||
|
{{> "pswp"}}
|
||||||
|
{{/is}}
|
||||||
|
|
||||||
|
<script src="{{asset "built/main.min.js"}}"></script>
|
||||||
|
<script src="{{asset "js/oneko.js"}}"></script>
|
||||||
|
|
||||||
|
{{ghost_foot}}
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -0,0 +1,101 @@
|
||||||
|
const {series, parallel, watch, src, dest} = require('gulp');
|
||||||
|
const pump = require('pump');
|
||||||
|
const fs = require('fs');
|
||||||
|
const order = require('ordered-read-streams');
|
||||||
|
|
||||||
|
// gulp plugins and utils
|
||||||
|
const livereload = require('gulp-livereload');
|
||||||
|
const postcss = require('gulp-postcss');
|
||||||
|
const concat = require('gulp-concat');
|
||||||
|
const uglify = require('gulp-uglify');
|
||||||
|
const beeper = require('beeper');
|
||||||
|
const zip = require('gulp-zip');
|
||||||
|
|
||||||
|
// postcss plugins
|
||||||
|
const easyimport = require('postcss-easy-import');
|
||||||
|
const autoprefixer = require('autoprefixer');
|
||||||
|
const cssnano = require('cssnano');
|
||||||
|
|
||||||
|
function serve(done) {
|
||||||
|
livereload.listen();
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
|
||||||
|
function 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/screen.css', {sourcemaps: true}),
|
||||||
|
postcss([
|
||||||
|
easyimport,
|
||||||
|
autoprefixer(),
|
||||||
|
cssnano()
|
||||||
|
]),
|
||||||
|
dest('assets/built/', {sourcemaps: '.'}),
|
||||||
|
livereload()
|
||||||
|
], handleError(done));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getJsFiles(version) {
|
||||||
|
const jsFiles = [
|
||||||
|
src(`node_modules/@tryghost/shared-theme-assets/assets/js/${version}/lib/**/*.js`),
|
||||||
|
src(`node_modules/@tryghost/shared-theme-assets/assets/js/${version}/main.js`),
|
||||||
|
];
|
||||||
|
|
||||||
|
if (fs.existsSync(`assets/js/lib`)) {
|
||||||
|
jsFiles.push(src(`assets/js/lib/*.js`));
|
||||||
|
}
|
||||||
|
|
||||||
|
jsFiles.push(src(`assets/js/main.js`));
|
||||||
|
|
||||||
|
return jsFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
function js(done) {
|
||||||
|
pump([
|
||||||
|
order(getJsFiles('v1'), {sourcemaps: true}),
|
||||||
|
concat('main.min.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'
|
||||||
|
]),
|
||||||
|
zip(filename),
|
||||||
|
dest('dist/')
|
||||||
|
], handleError(done));
|
||||||
|
}
|
||||||
|
|
||||||
|
const hbsWatcher = () => watch(['*.hbs', 'partials/**/*.hbs'], hbs);
|
||||||
|
const cssWatcher = () => watch('assets/css/**/*.css', css);
|
||||||
|
const jsWatcher = () => watch('assets/js/**/*.js', js);
|
||||||
|
const watcher = parallel(hbsWatcher, cssWatcher, jsWatcher);
|
||||||
|
const build = series(css, js);
|
||||||
|
|
||||||
|
exports.build = build;
|
||||||
|
exports.zip = series(build, zipper);
|
||||||
|
exports.default = series(build, serve, watcher);
|
|
@ -0,0 +1,24 @@
|
||||||
|
{{!< default}}
|
||||||
|
|
||||||
|
<section class="gh-about gh-outer">
|
||||||
|
<div class="gh-about-inner gh-inner">
|
||||||
|
{{#if @custom.primary_header}}
|
||||||
|
<h1 class="gh-about-primary">{{{@custom.primary_header}}}</h1>
|
||||||
|
{{/if}}
|
||||||
|
{{#if @custom.secondary_header}}
|
||||||
|
<p class="gh-about-secondary">{{{@custom.secondary_header}}}</p>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<main class="gh-main gh-outer">
|
||||||
|
<div class="gh-feed gh-inner">
|
||||||
|
{{#foreach posts}}
|
||||||
|
{{#if featured}}
|
||||||
|
{{> "loop"}}
|
||||||
|
{{/if}}
|
||||||
|
{{/foreach}}
|
||||||
|
</div>
|
||||||
|
</main>
|
|
@ -0,0 +1,97 @@
|
||||||
|
{
|
||||||
|
"name": "bifocal",
|
||||||
|
"description": "A Ghost theme, based on Solo",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"engines": {
|
||||||
|
"ghost": ">=5.0.0"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"author": {
|
||||||
|
"name": "Jean Viscogliosi-Pate",
|
||||||
|
"email": "jean@viscogliosi-pate.com",
|
||||||
|
"url": "viscogliosi-pate.com"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"ghost",
|
||||||
|
"theme",
|
||||||
|
"ghost-theme"
|
||||||
|
],
|
||||||
|
"config": {
|
||||||
|
"posts_per_page": 6,
|
||||||
|
"image_sizes": {
|
||||||
|
"xs": {
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
"s": {
|
||||||
|
"width": 300
|
||||||
|
},
|
||||||
|
"m": {
|
||||||
|
"width": 720
|
||||||
|
},
|
||||||
|
"l": {
|
||||||
|
"width": 960
|
||||||
|
},
|
||||||
|
"xl": {
|
||||||
|
"width": 1200
|
||||||
|
},
|
||||||
|
"xxl": {
|
||||||
|
"width": 2000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"card_assets": true,
|
||||||
|
"custom": {
|
||||||
|
"navigation_layout": {
|
||||||
|
"type": "select",
|
||||||
|
"options": ["Logo on the left", "Logo in the middle", "Stacked"],
|
||||||
|
"default": "Logo on the left"
|
||||||
|
},
|
||||||
|
"primary_header": {
|
||||||
|
"type": "text",
|
||||||
|
"default": "Hi! Welcome."
|
||||||
|
},
|
||||||
|
"secondary_header": {
|
||||||
|
"type": "text",
|
||||||
|
"default": "I had wondered, \"Why do I continue?\" It must be worth the effort, since I do not hesitate. I now know the answer: because there is ice cream waiting for me."
|
||||||
|
},
|
||||||
|
"footer_text": {
|
||||||
|
"type": "text",
|
||||||
|
"default": "Contact me!"
|
||||||
|
},
|
||||||
|
"email_address": {
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
"mastodon_link": {
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
"matrix_contact": {
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
"linkedin_contact": {
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"dev": "gulp",
|
||||||
|
"test": "gscan .",
|
||||||
|
"zip": "gulp zip"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@tryghost/shared-theme-assets": "2.4.3",
|
||||||
|
"autoprefixer": "10.4.19",
|
||||||
|
"beeper": "2.1.0",
|
||||||
|
"cssnano": "7.0.2",
|
||||||
|
"gscan": "4.43.1",
|
||||||
|
"gulp": "5.0.0",
|
||||||
|
"gulp-concat": "2.6.1",
|
||||||
|
"gulp-livereload": "4.0.2",
|
||||||
|
"gulp-postcss": "10.0.0",
|
||||||
|
"gulp-uglify": "3.0.2",
|
||||||
|
"gulp-zip": "5.1.0",
|
||||||
|
"ordered-read-streams": "2.0.0",
|
||||||
|
"postcss": "8.4.38",
|
||||||
|
"postcss-easy-import": "4.0.0",
|
||||||
|
"pump": "3.0.0"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
{{!< default}}
|
||||||
|
|
||||||
|
{{#post}}
|
||||||
|
|
||||||
|
<main class="gh-main gh-outer">
|
||||||
|
<div class="gh-inner">
|
||||||
|
<article class="gh-article {{post_class}}">
|
||||||
|
{{#match @page.show_title_and_feature_image}}
|
||||||
|
<header class="gh-article-header gh-canvas">
|
||||||
|
<h1 class="gh-article-title">{{title}}</h1>
|
||||||
|
{{#if custom_excerpt}}
|
||||||
|
<p class="gh-article-excerpt">{{custom_excerpt}}</p>
|
||||||
|
{{/if}}
|
||||||
|
</header>
|
||||||
|
{{/match}}
|
||||||
|
|
||||||
|
<section class="gh-content gh-canvas">
|
||||||
|
{{content}}
|
||||||
|
</section>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
{{/post}}
|
|
@ -0,0 +1,18 @@
|
||||||
|
{{#if feature_image}}
|
||||||
|
<figure class="gh-article-image{{#if feature_image_caption}} has-caption{{/if}}">
|
||||||
|
<img
|
||||||
|
srcset="{{img_url feature_image size="s"}} 300w,
|
||||||
|
{{img_url feature_image size="m"}} 720w,
|
||||||
|
{{img_url feature_image size="l"}} 960w,
|
||||||
|
{{img_url feature_image size="xl"}} 1200w,
|
||||||
|
{{img_url feature_image size="xxl"}} 2000w,
|
||||||
|
{{img_url feature_image}}"
|
||||||
|
sizes="(max-width: 1200px) 100vw, 1200px"
|
||||||
|
src="{{img_url feature_image size="xl"}}"
|
||||||
|
alt="{{title}}"
|
||||||
|
>
|
||||||
|
{{#if feature_image_caption}}
|
||||||
|
<figcaption>{{feature_image_caption}}</figcaption>
|
||||||
|
{{/if}}
|
||||||
|
</figure>
|
||||||
|
{{/if}}
|
|
@ -0,0 +1,9 @@
|
||||||
|
{{!-- Outputs the descriptions of ONLY internal tags with NO icon --}}
|
||||||
|
|
||||||
|
{{#if tags}}
|
||||||
|
{{#foreach tags visibility="internal"}}
|
||||||
|
{{^if feature_image}}
|
||||||
|
{{description}}
|
||||||
|
{{/if}}
|
||||||
|
{{/foreach}}
|
||||||
|
{{/if}}
|
|
@ -0,0 +1,19 @@
|
||||||
|
{{!-- Outputs a bullet list of icons and descriptions for ONLY internal tags with an icon --}}
|
||||||
|
|
||||||
|
{{#if tags}}
|
||||||
|
<ul class="tag-list">
|
||||||
|
{{#foreach tags visibility="internal"}}
|
||||||
|
{{#if feature_image}}
|
||||||
|
<li>
|
||||||
|
<svg class="tag-icon" role="img" title="{{meta_title}}" alt="{{meta_title}}">
|
||||||
|
<use href="{{img_url feature_image}}#{{meta_description}}">
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<div class=tag-text>
|
||||||
|
<p>{{description}}</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
{{/foreach}}
|
||||||
|
</ul>
|
||||||
|
{{/if}}
|
|
@ -0,0 +1,5 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="icon icon-tabler icons-tabler-filled icon-tabler-mail">
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||||
|
<path d="M22 7.535v9.465a3 3 0 0 1 -2.824 2.995l-.176 .005h-14a3 3 0 0 1 -2.995 -2.824l-.005 -.176v-9.465l9.445 6.297l.116 .066a1 1 0 0 0 .878 0l.116 -.066l9.445 -6.297z" />
|
||||||
|
<path d="M19 4c1.08 0 2.027 .57 2.555 1.427l-9.555 6.37l-9.555 -6.37a2.999 2.999 0 0 1 2.354 -1.42l.201 -.007h14z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 505 B |
|
@ -0,0 +1,12 @@
|
||||||
|
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 310 310" xml:space="preserve">
|
||||||
|
<g id="XMLID_801_">
|
||||||
|
<path id="XMLID_802_" d="M72.16,99.73H9.927c-2.762,0-5,2.239-5,5v199.928c0,2.762,2.238,5,5,5H72.16c2.762,0,5-2.238,5-5V104.73
|
||||||
|
C77.16,101.969,74.922,99.73,72.16,99.73z"/>
|
||||||
|
<path id="XMLID_803_" d="M41.066,0.341C18.422,0.341,0,18.743,0,41.362C0,63.991,18.422,82.4,41.066,82.4
|
||||||
|
c22.626,0,41.033-18.41,41.033-41.038C82.1,18.743,63.692,0.341,41.066,0.341z"/>
|
||||||
|
<path id="XMLID_804_" d="M230.454,94.761c-24.995,0-43.472,10.745-54.679,22.954V104.73c0-2.761-2.238-5-5-5h-59.599
|
||||||
|
c-2.762,0-5,2.239-5,5v199.928c0,2.762,2.238,5,5,5h62.097c2.762,0,5-2.238,5-5v-98.918c0-33.333,9.054-46.319,32.29-46.319
|
||||||
|
c25.306,0,27.317,20.818,27.317,48.034v97.204c0,2.762,2.238,5,5,5H305c2.762,0,5-2.238,5-5V194.995
|
||||||
|
C310,145.43,300.549,94.761,230.454,94.761z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 938 B |
|
@ -0,0 +1,5 @@
|
||||||
|
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="currentColor">
|
||||||
|
<title>Mastodon</title>
|
||||||
|
<path
|
||||||
|
d="M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1,5 @@
|
||||||
|
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="currentColor">
|
||||||
|
<title>Matrix</title>
|
||||||
|
<path
|
||||||
|
d="M.632.55v22.9H2.28V24H0V0h2.28v.55zm7.043 7.26v1.157h.033c.309-.443.683-.784 1.117-1.024.433-.245.936-.365 1.5-.365.54 0 1.033.107 1.481.314.448.208.785.582 1.02 1.108.254-.374.6-.706 1.034-.992.434-.287.95-.43 1.546-.43.453 0 .872.056 1.26.167.388.11.716.286.993.53.276.245.489.559.646.951.152.392.23.863.23 1.417v5.728h-2.349V11.52c0-.286-.01-.559-.032-.812a1.755 1.755 0 0 0-.18-.66 1.106 1.106 0 0 0-.438-.448c-.194-.11-.457-.166-.785-.166-.332 0-.6.064-.803.189a1.38 1.38 0 0 0-.48.499 1.946 1.946 0 0 0-.231.696 5.56 5.56 0 0 0-.06.785v4.768h-2.35v-4.8c0-.254-.004-.503-.018-.752a2.074 2.074 0 0 0-.143-.688 1.052 1.052 0 0 0-.415-.503c-.194-.125-.476-.19-.854-.19-.111 0-.259.024-.439.074-.18.051-.36.143-.53.282-.171.138-.319.337-.439.595-.12.259-.18.6-.18 1.02v4.966H5.46V7.81zm15.693 15.64V.55H21.72V0H24v24h-2.28v-.55z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 980 B |
|
@ -0,0 +1,5 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-rss">
|
||||||
|
<path d="M4 11a9 9 0 0 1 9 9"></path>
|
||||||
|
<path d="M4 4a16 16 0 0 1 16 16"></path>
|
||||||
|
<circle cx="5" cy="19" r="1"></circle>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 324 B |
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M17.5 17.5L12.5 12.5L17.5 17.5ZM14.1667 8.33333C14.1667 9.09938 14.0158 9.85792 13.7226 10.5657C13.4295 11.2734 12.9998 11.9164 12.4581 12.4581C11.9164 12.9998 11.2734 13.4295 10.5657 13.7226C9.85792 14.0158 9.09938 14.1667 8.33333 14.1667C7.56729 14.1667 6.80875 14.0158 6.10101 13.7226C5.39328 13.4295 4.75022 12.9998 4.20854 12.4581C3.66687 11.9164 3.23719 11.2734 2.94404 10.5657C2.65088 9.85792 2.5 9.09938 2.5 8.33333C2.5 6.78624 3.11458 5.30251 4.20854 4.20854C5.30251 3.11458 6.78624 2.5 8.33333 2.5C9.88043 2.5 11.3642 3.11458 12.4581 4.20854C13.5521 5.30251 14.1667 6.78624 14.1667 8.33333Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 802 B |
|
@ -20,7 +20,14 @@
|
||||||
<div class="post-card-tags">
|
<div class="post-card-tags">
|
||||||
{{> "get-meta-tags"}}
|
{{> "get-meta-tags"}}
|
||||||
</div>
|
</div>
|
||||||
<h2 class="gh-card-title">{{title}}</h2>
|
|
||||||
|
<h2 class="gh-card-title">
|
||||||
|
{{title}}
|
||||||
|
<div class="tag-desc">
|
||||||
|
{{> "get-desc-tags"}}
|
||||||
|
</div>
|
||||||
|
</h2>
|
||||||
|
|
||||||
{{#if custom_excerpt}}
|
{{#if custom_excerpt}}
|
||||||
<p class="gh-card-excerpt">{{excerpt}}</p>
|
<p class="gh-card-excerpt">{{excerpt}}</p>
|
||||||
{{/if}}
|
{{/if}}
|
|
@ -0,0 +1,41 @@
|
||||||
|
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
|
||||||
|
<div class="pswp__bg"></div>
|
||||||
|
|
||||||
|
<div class="pswp__scroll-wrap">
|
||||||
|
<div class="pswp__container">
|
||||||
|
<div class="pswp__item"></div>
|
||||||
|
<div class="pswp__item"></div>
|
||||||
|
<div class="pswp__item"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pswp__ui pswp__ui--hidden">
|
||||||
|
<div class="pswp__top-bar">
|
||||||
|
<div class="pswp__counter"></div>
|
||||||
|
|
||||||
|
<button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
|
||||||
|
<button class="pswp__button pswp__button--share" title="Share"></button>
|
||||||
|
<button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
|
||||||
|
<button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
|
||||||
|
|
||||||
|
<div class="pswp__preloader">
|
||||||
|
<div class="pswp__preloader__icn">
|
||||||
|
<div class="pswp__preloader__cut">
|
||||||
|
<div class="pswp__preloader__donut"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
|
||||||
|
<div class="pswp__share-tooltip"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)"></button>
|
||||||
|
<button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)"></button>
|
||||||
|
|
||||||
|
<div class="pswp__caption">
|
||||||
|
<div class="pswp__caption__center"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<div class="social-media">
|
||||||
|
{{#if @custom.email_address}}
|
||||||
|
<a class="social-icon" alt="Email" href={{@custom.email_address}}>
|
||||||
|
{{> "icons/email"}}
|
||||||
|
</a>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if @custom.mastodon_link}}
|
||||||
|
<a class="social-icon" alt="Mastodon" href={{@custom.mastodon_link}}>
|
||||||
|
{{> "icons/mastodon"}}
|
||||||
|
</a>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if @custom.matrix_contact}}
|
||||||
|
<a class="social-icon" alt="Matrix" href={{@custom.matrix_contact}}>
|
||||||
|
{{> "icons/matrix"}}
|
||||||
|
</a>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if @custom.linkedin_contact}}
|
||||||
|
<a class="social-icon" alt="LinkedIn" href={{@custom.linkedin_contact}}>
|
||||||
|
{{> "icons/linkedin"}}
|
||||||
|
</a>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
|
@ -0,0 +1,34 @@
|
||||||
|
{{!< default}}
|
||||||
|
|
||||||
|
<main class="gh-main gh-outer">
|
||||||
|
<div class="gh-inner">
|
||||||
|
{{#post}}
|
||||||
|
<article class="gh-article {{post_class}}">
|
||||||
|
<div class="post-card-tags">
|
||||||
|
{{> "get-meta-tags"}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#if feature_image}}
|
||||||
|
<header class="gh-article-header gh-canvas">
|
||||||
|
<h1 class="gh-article-title">{{title}}</h1>
|
||||||
|
{{#if custom_excerpt}}
|
||||||
|
<p class="gh-article-excerpt">{{custom_excerpt}}</p>
|
||||||
|
{{/if}}
|
||||||
|
</header>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<section class="gh-content gh-canvas">
|
||||||
|
{{content}}
|
||||||
|
{{#unless feature_image}}
|
||||||
|
<header class="gh-article-header">
|
||||||
|
<h1 class="gh-article-title">{{title}}</h1>
|
||||||
|
{{#if custom_excerpt}}
|
||||||
|
<p class="gh-article-excerpt">{{custom_excerpt}}</p>
|
||||||
|
{{/if}}
|
||||||
|
</header>
|
||||||
|
{{/unless}}
|
||||||
|
</section>
|
||||||
|
</article>
|
||||||
|
{{/post}}
|
||||||
|
</div>
|
||||||
|
</main>
|
|
@ -0,0 +1,112 @@
|
||||||
|
# Blocks AI web scrapers
|
||||||
|
# Crawlers sourced from Dark Visitors and https://github.com/ai-robots-txt/ai.robots.txt
|
||||||
|
|
||||||
|
# Used by Google, for Gemini assistant and Vertex AI
|
||||||
|
User-agent: AdsBot-Google
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: Google-Extended
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: GoogleOther
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
# Used by Anthropic, for Claude
|
||||||
|
User-agent: anthropic-ai
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: Claude-Web
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: ClaudeBot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
# Used by ByteDance for Doubao
|
||||||
|
User-agent: Bytespider
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
# Used by Common Crawl for open source repository of web crawl data
|
||||||
|
User-agent: CCBot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
# Used by OpenAI GPT for updating content and ChatGPT plug-ins
|
||||||
|
User-agent: ChatGPT-User
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: GPTBot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
# Sells crawled data to LLM companies
|
||||||
|
User-agent: Diffbot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
# For speech recognition language models by Meta
|
||||||
|
User-agent: FacebookBot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
# Used by Omigli, sells crawled data to LLM companies
|
||||||
|
User-agent: omgilibot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: omgili
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
|
||||||
|
# Undocumented
|
||||||
|
User-agent: Amazonbot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: Applebot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: AwarioRssBot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: AwarioSmartBot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: cohere-ai
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: DataForSeoBot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: FriendlyCrawler
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: img2dataset
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: ImagesiftBot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: magpie-crawler
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: Meltwater
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: peer39_crawler
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: peer39_crawler/1.0
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: PerplexityBot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: PiplBot
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: Seekr
|
||||||
|
Disallow: /
|
||||||
|
|
||||||
|
User-agent: YouBot
|
||||||
|
Disallow: /
|
|
@ -0,0 +1,21 @@
|
||||||
|
{{!< default}}
|
||||||
|
|
||||||
|
<main class="gh-main gh-outer">
|
||||||
|
<div class="gh-inner">
|
||||||
|
{{#tag}}
|
||||||
|
<h1 class="gh-article-title">{{name}}</h1>
|
||||||
|
<a class="feed-cta" href="feed">
|
||||||
|
<p>Subscribe to updates by RSS</p>
|
||||||
|
<div class="social-icon" alt="RSS">
|
||||||
|
{{> "icons/rss"}}
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
{{/tag}}
|
||||||
|
|
||||||
|
<div class="gh-feed">
|
||||||
|
{{#foreach posts}}
|
||||||
|
{{> "loop"}}
|
||||||
|
{{/foreach}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
17
index.hbs
|
@ -1,9 +1,24 @@
|
||||||
{{!< default}}
|
{{!< default}}
|
||||||
|
|
||||||
|
<section class="gh-about gh-outer">
|
||||||
|
<div class="gh-about-inner gh-inner">
|
||||||
|
{{#if @custom.primary_header}}
|
||||||
|
<h1 class="gh-about-primary">{{{@custom.primary_header}}}</h1>
|
||||||
|
{{/if}}
|
||||||
|
{{#if @custom.secondary_header}}
|
||||||
|
<p class="gh-about-secondary">{{{@custom.secondary_header}}}</p>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
<main class="gh-main gh-outer">
|
<main class="gh-main gh-outer">
|
||||||
<div class="gh-feed gh-inner">
|
<div class="gh-feed gh-inner">
|
||||||
{{#foreach posts}}
|
{{#foreach posts}}
|
||||||
{{> "box-info"}}
|
{{#if featured}}
|
||||||
|
{{> "loop"}}
|
||||||
|
{{/if}}
|
||||||
{{/foreach}}
|
{{/foreach}}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
../autoprefixer/bin/autoprefixer
|
|
|
@ -1 +0,0 @@
|
||||||
../browserslist/cli.js
|
|
|
@ -1 +0,0 @@
|
||||||
../bunyan/bin/bunyan
|
|
|
@ -1 +0,0 @@
|
||||||
../color-support/bin.js
|
|
|
@ -1 +0,0 @@
|
||||||
../@stdlib/utils-convert-path/bin/cli
|
|
|
@ -1 +0,0 @@
|
||||||
../crc-32/bin/crc32.njs
|
|
|
@ -1 +0,0 @@
|
||||||
../js-beautify/js/bin/css-beautify.js
|
|
|
@ -1 +0,0 @@
|
||||||
../cssesc/bin/cssesc
|
|
|
@ -1 +0,0 @@
|
||||||
../@stdlib/process-cwd/bin/cli
|
|
|
@ -1 +0,0 @@
|
||||||
../editorconfig/bin/editorconfig
|
|
|
@ -1 +0,0 @@
|
||||||
../@stdlib/fs-exists/bin/cli
|
|
|
@ -1 +0,0 @@
|
||||||
../extract-zip/cli.js
|
|
|
@ -1 +0,0 @@
|
||||||
../gscan/bin/cli.js
|
|
|
@ -1 +0,0 @@
|
||||||
../gulp/bin/gulp.js
|
|
|
@ -1 +0,0 @@
|
||||||
../handlebars/bin/handlebars
|
|
|
@ -1 +0,0 @@
|
||||||
../@stdlib/assert-has-float32array-support/bin/cli
|
|
|
@ -1 +0,0 @@
|
||||||
../@stdlib/assert-has-float64array-support/bin/cli
|
|
|
@ -1 +0,0 @@
|
||||||
../@stdlib/assert-has-int16array-support/bin/cli
|
|
|
@ -1 +0,0 @@
|
||||||
../@stdlib/assert-has-int32array-support/bin/cli
|
|
|
@ -1 +0,0 @@
|
||||||
../@stdlib/assert-has-int8array-support/bin/cli
|
|
|
@ -1 +0,0 @@
|
||||||
../@stdlib/assert-has-node-buffer-support/bin/cli
|
|
|
@ -1 +0,0 @@
|
||||||
../@stdlib/assert-has-symbol-support/bin/cli
|
|
|
@ -1 +0,0 @@
|
||||||
../@stdlib/assert-has-tostringtag-support/bin/cli
|
|
|
@ -1 +0,0 @@
|
||||||
../@stdlib/assert-has-uint16array-support/bin/cli
|
|
|
@ -1 +0,0 @@
|
||||||
../@stdlib/assert-has-uint32array-support/bin/cli
|
|
|
@ -1 +0,0 @@
|
||||||
../@stdlib/assert-has-uint8array-support/bin/cli
|
|
|
@ -1 +0,0 @@
|
||||||
../@stdlib/assert-has-uint8clampedarray-support/bin/cli
|
|
|
@ -1 +0,0 @@
|
||||||
../js-beautify/js/bin/html-beautify.js
|
|
|
@ -1 +0,0 @@
|
||||||
../@stdlib/assert-is-regexp-string/bin/cli
|
|
|
@ -1 +0,0 @@
|
||||||
../js-beautify/js/bin/js-beautify.js
|
|
|
@ -1 +0,0 @@
|
||||||
../@stdlib/utils-library-manifest/bin/cli
|
|
|
@ -1 +0,0 @@
|
||||||
../@stdlib/string-lowercase/bin/cli
|
|
|
@ -1 +0,0 @@
|
||||||
../mime/cli.js
|
|
|
@ -1 +0,0 @@
|
||||||
../mkdirp/bin/cmd.js
|
|
|
@ -1 +0,0 @@
|
||||||
../nanoid/bin/nanoid.cjs
|
|