Solo theme (#162)

Added Solo theme
This commit is contained in:
Sodbileg Gansukh 2022-09-12 17:59:12 +08:00 committed by GitHub
commit ebee417482
31 changed files with 1574 additions and 0 deletions

61
assets/css/fonts.css Normal file
View File

@ -0,0 +1,61 @@
@font-face {
font-family: Manrope;
font-weight: 100 1000;
src: url("../fonts/Manrope[wght].woff2") format("woff2-variations");
}
@font-face {
font-family: "Libre Baskerville";
font-style: normal;
font-weight: 400;
src: local(""), url("../fonts/libre-baskerville-v14-latin-regular.woff2") format("woff2");
}
@font-face {
font-family: "Libre Baskerville";
font-style: normal;
font-weight: 700;
src: local(""), url("../fonts/libre-baskerville-v14-latin-700.woff2") format("woff2");
}
@font-face {
font-family: "Libre Baskerville";
font-style: italic;
font-weight: 400;
src: local(""), url("../fonts/libre-baskerville-v14-latin-italic.woff2") format("woff2");
}
@font-face {
font-family: "JetBrains Mono";
font-style: normal;
font-weight: 400;
src: local(""), url("../fonts/jetbrains-mono-v13-latin-regular.woff2") format("woff2");
}
@font-face {
font-family: "JetBrains Mono";
font-style: normal;
font-weight: 700;
src: local(""), url("../fonts/jetbrains-mono-v13-latin-700.woff2") format("woff2");
}
@font-face {
font-family: "JetBrains Mono";
font-style: normal;
font-weight: 800;
src: local(""), url("../fonts/jetbrains-mono-v13-latin-800.woff2") format("woff2");
}
@font-face {
font-family: "JetBrains Mono";
font-style: italic;
font-weight: 400;
src: local(""), url("../fonts/jetbrains-mono-v13-latin-italic.woff2") format("woff2");
}
@font-face {
font-family: "JetBrains Mono";
font-style: italic;
font-weight: 700;
src: local(""), url("../fonts/jetbrains-mono-v13-latin-700italic.woff2") format("woff2");
}

905
assets/css/screen.css Normal file
View File

@ -0,0 +1,905 @@
@import "@tryghost/shared-theme-assets/assets/css/screen.css";
@import "fonts.css";
:root {
--font-sans: Manrope, -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif;
--font-serif: Libre Baskerville, Georgia, Times, serif;
--font-mono: JetBrains Mono, Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace;
--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;
--content-font-size: clamp(1.7rem, 0.38vw + 1.4rem, 2rem);
}
: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;
}
.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-inner {
padding: clamp(24px, 1.9355rem + 1.2903vw, 40px) 0;
}
.gh-head-brand-wrapper {
gap: 32px;
}
.gh-head-logo {
font-weight: 800;
}
.gh-head-logo img {
max-height: 48px;
}
.gh-head-menu {
font-weight: 700;
}
.gh-head-menu a {
color: inherit;
}
.gh-head-btn.gh-btn {
height: 36px;
padding: 0 16px;
font-size: 1.6rem;
font-weight: 700;
}
@media (max-width: 991px) {
.is-head-open:not(.is-head-brand):not(.is-head-dark):not(.is-head-transparent) #gh-head {
background-color: var(--background-color);
}
}
/* About section
/* ---------------------------------------------------------- */
.gh-about {
margin-bottom: 40px;
}
.gh-about-primary {
max-width: 1200px;
font-size: clamp(3.2rem, 2.4452rem + 2.0968vw, 5.8rem);
font-weight: 800;
line-height: 1.2;
}
.has-serif-font .gh-about-primary {
font-family: var(--font-serif);
}
.has-mono-font .gh-about-primary {
font-family: var(--font-mono);
}
.gh-about-primary a {
text-decoration: underline;
}
.gh-about-secondary {
max-width: 840px;
font-size: clamp(2.4rem, 0.54vw + 2.14rem, 3rem);
font-weight: 500;
}
.has-serif-font .gh-about-secondary {
font-family: var(--font-serif);
}
.has-mono-font .gh-about-secondary {
font-family: var(--font-mono);
}
.gh-about-primary + .gh-about-secondary {
max-width: 640px;
margin-top: 20px;
font-size: clamp(2rem, 0.36vw + 1.83rem, 2.4rem);
font-weight: 450;
}
.gh-about-secondary a {
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
/* ---------------------------------------------------------- */
.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;
}
.has-serif-font .gh-card-title {
font-family: var(--font-serif);
}
.has-mono-font .gh-card-title {
font-family: var(--font-mono);
}
.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)::before {
width: 2px;
height: 2px;
content: "";
background-color: currentColor;
border-radius: 50%;
}
.gh-card-access svg {
margin-right: -5px;
}
/* Classic feed
/* ---------------------------------------------------------- */
.has-classic-feed .gh-card + .gh-card {
margin-top: clamp(4.8rem, 4rem + 2.5vw, 8rem);
}
.has-classic-feed .gh-card-link {
display: flex;
flex-direction: row-reverse;
gap: clamp(4rem, 3rem + 3.125vw, 8rem);
}
.has-classic-feed .gh-card-image {
position: relative;
flex: 1;
}
.has-classic-feed .gh-card-image::before {
display: block;
padding-bottom: 56.25%;
content: "";
}
.has-classic-feed .no-image .gh-card-image {
background-color: var(--tag-color, var(--color-lighter-gray));
}
.has-classic-feed .gh-card-image img {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
.has-classic-feed .gh-card-wrapper {
flex: 1;
flex-shrink: 0;
width: 100%;
}
.has-classic-feed .gh-card-title {
font-size: clamp(3.2rem, 2.7rem + 1.5625vw, 5.2rem);
}
.has-classic-feed .kg-width-full .gh-card-title {
font-size: clamp(3.2rem, 2.4rem + 2.5vw, 6.4rem);
}
@media (max-width: 991px) {
.has-classic-feed .gh-card-link {
flex-direction: column;
gap: 32px;
}
}
/* Typographic feed
/* ---------------------------------------------------------- */
.has-typographic-feed.home-template .gh-main {
padding-top: 0;
}
.has-typographic-feed .gh-card {
margin-top: clamp(8rem, 6rem + 6.25vw, 16rem);
}
.has-typographic-feed .gh-card-title {
max-width: 1200px;
font-size: clamp(3.2rem, 2.4rem + 2.5vw, 6.4rem);
line-height: 1.1;
}
.has-typographic-feed .gh-card-excerpt {
max-width: 920px;
margin-top: 16px;
font-size: clamp(1.8rem, 0.27vw + 1.67rem, 2.1rem);
font-weight: 450;
line-height: 1.5;
letter-spacing: -0.005em;
}
.has-serif-font.has-typographic-feed .gh-card-excerpt {
font-family: var(--font-serif);
}
.has-mono-font.has-typographic-feed .gh-card-excerpt {
font-family: var(--font-mono);
}
.has-typographic-feed .gh-card-meta {
margin-top: 16px;
}
/* Parallax feed
/* ---------------------------------------------------------- */
.has-parallax-feed .gh-card {
display: flex;
min-height: 640px;
}
.has-parallax-feed .gh-card.no-image {
background-color: var(--tag-color, var(--color-darker-gray));
}
.has-parallax-feed .kg-width-full .gh-card {
min-height: 800px;
}
.has-parallax-feed .gh-card + .gh-card {
margin-top: 80px;
}
.has-parallax-feed .gh-card-link {
position: relative;
display: flex;
flex-grow: 1;
}
.has-parallax-feed .gh-card:not(.no-image) .gh-card-link::before {
position: absolute;
width: 100%;
height: 100%;
content: "";
background-color: #000;
opacity: 0.6;
transition: opacity 0.4s;
}
.has-parallax-feed .gh-card:not(.no-image):hover .gh-card-link::before {
opacity: 0.4;
}
.has-parallax-feed .gh-card-image {
position: absolute;
z-index: -1;
width: 100%;
height: 100%;
}
.has-parallax-feed .gh-card-wrapper {
position: relative;
justify-content: flex-end;
padding: 64px 48px;
}
.has-parallax-feed .kg-width-full .gh-card-wrapper {
padding: 64px 48px;
}
.has-parallax-feed :is(.gh-card-title, .gh-card-meta) {
color: #fff;
}
.has-parallax-feed .gh-card-title {
font-size: clamp(3.2rem, 2.4rem + 2.5vw, 6.4rem);
line-height: 1.1;
}
.has-parallax-feed .gh-card:not(.no-image) .gh-card-link:hover .gh-card-title {
opacity: 1;
}
.has-parallax-feed .kg-width-full .gh-card-title {
font-size: 6.4rem;
}
.has-parallax-feed .gh-card-meta {
margin-top: 12px;
}
/* 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;
}
.has-serif-font .gh-article-title {
font-family: var(--font-serif);
}
.has-mono-font .gh-article-title {
font-family: var(--font-mono);
}
.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;
}
.has-serif-font .gh-article-excerpt {
font-family: var(--font-serif);
}
.has-mono-font .gh-article-excerpt {
font-family: var(--font-mono);
}
.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;
}
.post-template .no-image .gh-content {
margin-top: 0;
}
.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;
}
.has-serif-font .gh-content > :is([id], p, ul, ol) {
font-family: var(--font-serif);
}
.has-mono-font .gh-content > :is([id], p, ul, ol) {
font-family: var(--font-mono);
}
.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);
}
}
/* 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(6.4rem, 5vw + 4rem, 12rem);
background-color: var(--color-lighter-gray);
transform: translate3d(0, 0, 0);
}
.gh-cta-title {
margin-bottom: 24px;
font-size: clamp(3.6rem, 1.79vw + 2.74rem, 5.6rem);
font-weight: 800;
letter-spacing: -0.03em;
}
.has-serif-font .gh-cta-title {
font-family: var(--font-serif);
}
.has-mono-font .gh-cta-title {
font-family: var(--font-mono);
}
.gh-cta .gh-btn {
height: 48px;
padding-right: 24px;
padding-left: 24px;
font-size: 1.8rem;
letter-spacing: -0.005em;
}
/* 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;
}
.has-serif-font .gh-navigation {
font-family: var(--font-serif);
}
.has-mono-font .gh-navigation {
font-family: var(--font-mono);
}
/* Comments
/* ---------------------------------------------------------- */
.gh-comments {
margin-top: clamp(4.8rem, 4.64vw + 2.57rem, 10rem);
}
.gh-comments .gh-comments-title {
margin-bottom: 48px;
font-weight: 800;
}
.has-serif-font .gh-comments-title {
font-family: var(--font-serif);
}
.has-mono-font .gh-comments-title {
font-family: var(--font-mono);
}
/* Subscribe
/* ---------------------------------------------------------- */
.gh-subscribe-input {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
max-width: 480px;
height: 52px;
padding: 0 8px 0 24px;
margin-top: 40px;
font-size: 1.7rem;
color: var(--color-secondary-text);
cursor: pointer;
background-color: var(--color-border);
border-radius: 72px;
}
.gh-subscribe-input .gh-btn {
font-weight: 700;
}
/* Archive
/* ---------------------------------------------------------- */
:is(.tag-template, .author-template) .gh-article {
margin-bottom: 80px;
}
.gh-author-image {
width: 96px;
height: 96px;
margin-bottom: 24px;
overflow: hidden;
border-radius: 50%;
}
.gh-author-image img {
width: 100%;
height: 100%;
object-fit: cover;
}
.gh-author-meta {
margin-top: 16px;
font-size: 1.8rem;
color: var(--color-secondary-text);
}
.gh-author-location {
margin-bottom: 6px;
}
.gh-author-social {
display: flex;
gap: 12px;
align-items: center;
}
.gh-author-social-link {
line-height: 0;
}
/* 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;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/images/default-skin.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

1
assets/images/default-skin.svg Executable file
View File

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

BIN
assets/images/preloader.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 866 B

7
assets/js/lib/jarallax.min.js vendored Normal file

File diff suppressed because one or more lines are too long

39
assets/js/main.js Normal file
View File

@ -0,0 +1,39 @@
function initParallax() {
jarallax(document.querySelectorAll('.has-parallax-feed .gh-card'), {
speed: 0.8,
});
}
(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);
// })();

38
author.hbs Normal file
View File

@ -0,0 +1,38 @@
{{!< 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>

104
default.hbs Normal file
View File

@ -0,0 +1,104 @@
<!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}}
<style>
:root {
--background-color: {{@custom.background_color}}
}
</style>
<script>
/* The script for calculating the color contrast was taken from
https://gomakethings.com/dynamically-changing-the-text-color-based-on-background-color-contrast-with-vanilla-js/ */
var accentColor = getComputedStyle(document.documentElement).getPropertyValue('--background-color');
accentColor = accentColor.trim().slice(1);
var r = parseInt(accentColor.substr(0, 2), 16);
var g = parseInt(accentColor.substr(2, 2), 16);
var b = parseInt(accentColor.substr(4, 2), 16);
var yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
var textColor = (yiq >= 128) ? 'dark' : 'light';
document.documentElement.className = `has-${textColor}-text`;
</script>
{{ghost_head}}
</head>
<body class="{{body_class}}{{{block "body_class"}}}{{#match @custom.typography "Elegant serif"}} has-serif-font{{/match}}{{#match @custom.typography "Consistent mono"}} has-mono-font{{/match}}{{#match @custom.post_feed_layout "Classic"}} has-classic-feed{{/match}}{{#match @custom.post_feed_layout "Typographic"}} has-typographic-feed{{/match}}{{#match @custom.post_feed_layout "Parallax"}} has-parallax-feed{{/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" 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" data-ghost-search>{{> "icons/search"}}</button>
{{#if @site.members_enabled}}
{{#unless @member}}
{{^is "home"}}
<a class="gh-head-btn gh-btn gh-primary-btn" href="#/portal/signup" data-portal="signup">Subscribe</a>
{{/is}}
{{else}}
<a class="gh-head-btn gh-btn" href="#/portal/account" data-portal="account">Account</a>
{{/unless}}
{{/if}}
</div>
</div>
</header>
{{{body}}}
<footer class="gh-foot gh-outer">
<div class="gh-foot-inner gh-inner">
<nav class="gh-foot-menu">
{{navigation type="secondary"}}
</nav>
<div class="gh-copyright">
{{#unless @custom.footer_text}}
{{@site.title}} © {{date format="YYYY"}}. Powered by <a href="https://ghost.org/" target="_blank" rel="noopener">Ghost</a>
{{else}}
{{@custom.footer_text}}
{{/unless}}
</div>
</div>
</footer>
</div>
{{#is "post, page"}}
{{> "pswp"}}
{{/is}}
<script src="{{asset "built/main.min.js"}}"></script>
{{ghost_foot}}
</body>
</html>

54
index.hbs Normal file
View File

@ -0,0 +1,54 @@
{{!< default}}
<section class="gh-about gh-outer{{#match @custom.header_section_layout "!=" "Typographic profile"}}{{#unless @site.cover_image}} no-image{{/unless}}{{else}}{{#unless @site.icon}} no-image{{/unless}}{{/match}}">
<div class="gh-about-inner gh-inner">
{{#match @custom.header_section_layout "!=" "Typographic profile"}}
{{#if @site.cover_image}}
<img class="gh-about-image" src="{{@site.cover_image}}" alt="{{@site.title}}">
{{/if}}
{{else}}
{{#if @site.icon}}
<img class="gh-about-image" src="{{@site.icon}}" alt="{{@site.title}}">
{{/if}}
{{/match}}
<script>
(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');
about.style.setProperty('--about-height', image.clientWidth * image.naturalHeight / image.naturalWidth + 'px');
about.classList.add('initialized');
})();
</script>
<div class="gh-about-content">
<div class="gh-about-content-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}}
{{#unless @member}}
<div class="gh-subscribe-input" data-portal>
jamie@example.com
<span class="gh-btn gh-primary-btn">Subscribe</span>
</div>
{{/unless}}
</div>
</div>
</div>
</section>
<main class="gh-main gh-outer">
<div class="gh-feed gh-inner">
{{#foreach posts}}
{{> "loop"}}
{{/foreach}}
</div>
</main>
{{#contentFor "body_class"}}{{#match @custom.header_section_layout "Side by side"}} has-side-about{{/match}}{{#match @custom.header_section_layout "Large background"}}{{#if @site.cover_image}} is-head-transparent has-background-about{{else}} has-side-about{{/if}}{{/match}}{{#match @custom.header_section_layout "Typographic profile"}}{{#if @site.icon}} has-typographic-about{{else}} has-side-about{{/if}}{{/match}}{{/contentFor}}

101
package.json Normal file
View File

@ -0,0 +1,101 @@
{
"name": "solo",
"description": "A Ghost theme",
"version": "1.0.0",
"private": true,
"engines": {
"ghost": ">=5.0.0"
},
"license": "MIT",
"author": {
"name": "Ghost Foundation",
"email": "hello@ghost.org",
"url": "https://ghost.org"
},
"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": {
"background_color": {
"type": "color",
"default": "#ffffff"
},
"typography": {
"type": "select",
"options": ["Modern sans-serif", "Elegant serif", "Consistent mono"],
"default": "Modern sans-serif"
},
"footer_text": {
"type": "text"
},
"header_section_layout": {
"type": "select",
"options": ["Side by side", "Large background", "Typographic profile"],
"default": "Side by side",
"group": "homepage"
},
"primary_header": {
"type": "text",
"default": "Welcome to my site",
"group": "homepage"
},
"secondary_header": {
"type": "text",
"default": "Subscribe below to receive my latest posts directly in your inbox",
"group": "homepage"
},
"post_feed_layout": {
"type": "select",
"options": ["Classic", "Typographic", "Parallax"],
"default": "Classic",
"group": "homepage"
}
}
},
"scripts": {
"dev": "gulp",
"test": "gscan .",
"zip": "gulp zip"
},
"devDependencies": {
"@tryghost/shared-theme-assets": "1.1.0",
"autoprefixer": "10.4.8",
"beeper": "2.1.0",
"cssnano": "5.1.12",
"gscan": "4.34.0",
"gulp": "4.0.2",
"gulp-concat": "2.6.1",
"gulp-livereload": "4.0.2",
"gulp-postcss": "9.0.1",
"gulp-uglify": "3.0.2",
"gulp-zip": "5.1.0",
"postcss": "8.4.16",
"postcss-easy-import": "4.0.0",
"pump": "3.0.0"
}
}

23
page.hbs Normal file
View File

@ -0,0 +1,23 @@
{{!< default}}
{{#post}}
<main class="gh-main gh-outer">
<div class="gh-inner">
<article class="gh-article {{post_class}}">
<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}}
{{> "feature-image"}}
</header>
<section class="gh-content gh-canvas">
{{content}}
</section>
</article>
</div>
</main>
{{/post}}

22
partials/content-cta.hbs Normal file
View File

@ -0,0 +1,22 @@
{{{html}}}
<section class="gh-cta">
{{#has visibility="paid"}}
<h4 class="gh-cta-title">This post is for paying subscribers only</h4>
{{/has}}
{{#has visibility="members"}}
<h4 class="gh-cta-title">This post is for subscribers only</h4>
{{/has}}
{{#has visibility="filter"}}
<h4 class="gh-cta-title">This post is for subscribers on the {{tiers}} only</h4>
{{/has}}
<div class="gh-cta-actions">
{{#if @member}}
<button class="gh-btn gh-primary-btn" href="#/portal/account/plans" data-portal="account/plans">Upgrade now</button>
{{else}}
<button class="gh-btn gh-primary-btn" href="#/portal/signup" data-portal="signup">Subscribe now</button>
<span class="gh-cta-link" href="#/portal/signin" data-portal="signin">Already have an account? Sign in.</span>
{{/if}}
</div>
</section>

View File

@ -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}}

View File

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16 8.04865C16 3.63065 12.418 0.048645 8 0.048645C3.582 0.048645 0 3.63065 0 8.04865C0 12.042 2.92533 15.3513 6.75 15.9513V10.3613H4.71867V8.04798H6.75V6.28665C6.75 4.28198 7.94467 3.17398 9.772 3.17398C10.6467 3.17398 11.5627 3.33065 11.5627 3.33065V5.29931H10.5533C9.55933 5.29931 9.24933 5.91598 9.24933 6.54865V8.04865H11.468L11.1133 10.362H9.24933V15.952C13.0747 15.3513 16 12.0413 16 8.04865Z" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 534 B

3
partials/icons/lock.hbs Normal file
View File

@ -0,0 +1,3 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.65654 2.15649C5.01286 1.80017 5.49613 1.59999 6.00004 1.59999C6.50395 1.59999 6.98723 1.80017 7.34355 2.15649C7.69986 2.51281 7.90004 2.99608 7.90004 3.49999V4.89999H4.10004V3.49999C4.10004 2.99608 4.30022 2.51281 4.65654 2.15649ZM2.90004 4.89999V3.49999C2.90004 2.67782 3.22665 1.88933 3.80801 1.30796C4.38937 0.7266 5.17787 0.399994 6.00004 0.399994C6.82221 0.399994 7.61071 0.7266 8.19207 1.30796C8.77344 1.88933 9.10004 2.67782 9.10004 3.49999V4.89999H9.4999C10.3836 4.89999 11.0999 5.61634 11.0999 6.49999V9.99999C11.0999 10.8836 10.3836 11.6 9.4999 11.6H2.4999C1.61625 11.6 0.899902 10.8836 0.899902 9.99999V6.49999C0.899902 5.61634 1.61625 4.89999 2.4999 4.89999H2.90004ZM2.90004 6.09999H2.4999C2.27899 6.09999 2.0999 6.27908 2.0999 6.49999V9.99999C2.0999 10.2209 2.27899 10.4 2.4999 10.4H9.4999C9.72082 10.4 9.8999 10.2209 9.8999 9.99999V6.49999C9.8999 6.27908 9.72082 6.09999 9.4999 6.09999H9.10004H7.90004H4.10004H2.90004Z" fill="currentColor" />
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

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

View File

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15.9687 3.04665C15.3697 3.31039 14.7351 3.48448 14.0853 3.56332C14.7694 3.15215 15.2816 2.50735 15.5273 1.74799C14.8933 2.11799 14.1907 2.38732 13.4427 2.53732C12.9492 2.00961 12.2952 1.6596 11.5824 1.54165C10.8696 1.42371 10.1378 1.54442 9.50062 1.88505C8.86345 2.22567 8.35657 2.76715 8.0587 3.4254C7.76083 4.08365 7.68864 4.82183 7.85333 5.52532C5.12667 5.39665 2.71133 4.08665 1.09333 2.10799C0.799196 2.60786 0.645776 3.178 0.649333 3.75799C0.649333 4.89799 1.22933 5.89999 2.108 6.48865C1.58724 6.47208 1.07798 6.33128 0.622667 6.07799V6.11799C0.622371 6.87558 0.884179 7.60995 1.36367 8.19649C1.84316 8.78304 2.51081 9.18564 3.25333 9.33599C2.7722 9.46491 2.26828 9.48427 1.77867 9.39265C1.98941 10.0447 2.39844 10.6146 2.94868 11.023C3.49891 11.4314 4.1629 11.6578 4.848 11.6707C3.68769 12.5813 2.25498 13.0755 0.78 13.074C0.52 13.074 0.260667 13.0587 0 13.0293C1.50381 13.9922 3.25234 14.5033 5.038 14.502C11.0733 14.502 14.37 9.50465 14.37 5.17865C14.37 5.03865 14.37 4.89865 14.36 4.75865C15.004 4.29523 15.5595 3.71987 16 3.05999L15.9687 3.04665Z" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

53
partials/loop.hbs Normal file
View File

@ -0,0 +1,53 @@
<article class="gh-card {{post_class}}"{{#if primary_tag.accent_color}} style="--tag-color: {{primary_tag.accent_color}};"{{/if}}>
<a class="gh-card-link" href="{{url}}">
{{#match @custom.post_feed_layout "!=" "Typographic"}}
<figure class="gh-card-image">
{{#if feature_image}}
<img
{{#match @custom.post_feed_layout "Parallax"}}class="jarallax-img"{{/match}}
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"
sizes="(max-width: 1200px) 100vw, 1200px"
src="{{img_url feature_image size="m"}}"
alt="{{#if feature_image_alt}}{{feature_image_alt}}{{else}}{{title}}{{/if}}"
>
{{/if}}
</figure>
{{/match}}
<div class="gh-card-wrapper">
<h2 class="gh-card-title">{{title}}</h2>
{{#match @custom.post_feed_layout "Typographic"}}
{{#if custom_excerpt}}
<p class="gh-card-excerpt">{{excerpt}}</p>
{{/if}}
{{/match}}
<footer class="gh-card-meta">
<time class="gh-card-date" datetime="{{date format="YYYY-MM-DD"}}">{{date}}</time>
{{#if reading_time}}
<span class="gh-card-length">{{reading_time}}</span>
{{/if}}
{{#unless access}}
{{^has visibility="public"}}
<span class="gh-card-access">
{{> "icons/lock"}}
{{#has visibility="members"}}
Members
{{else}}
Paid
{{/has}}
</span>
{{/has}}
{{/unless}}
{{#if @site.comments_enabled}}
{{comment_count class="gh-card-comments"}}
{{/if}}
</footer>
</div>
</a>
</article>

41
partials/pswp.hbs Normal file
View File

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

75
post.hbs Normal file
View File

@ -0,0 +1,75 @@
{{!< default}}
<main class="gh-main gh-outer">
<div class="gh-inner">
{{#post}}
<article class="gh-article {{post_class}}">
{{#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}}
{{> "feature-image"}}
</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}}
<aside class="gh-article-meta">
<div class="gh-article-meta-inner">
{{#primary_author}}
{{#if profile_image}}
<figure class="gh-author-image">
<img src="{{profile_image}}" alt="{{name}}">
</figure>
{{/if}}
<div class="gh-article-meta-wrapper">
<h4 class="gh-author-name">
<a href="{{url}}">{{name}}</a>
</h4>
{{/primary_author}}
<time class="gh-article-date" datetime="{{date format="YYYY-MM-DD"}}">{{date}}</time></div>
{{#if primary_tag}}
<a class="gh-article-tag" href="{{primary_tag.url}}" style="--tag-color: {{primary_tag.accent_color}}">{{primary_tag.name}}</a>
{{/if}}
</div>
</aside>
</section>
{{#if comments}}
<div class="gh-comments gh-canvas">
<h2 class="gh-comments-title">{{comment_count empty="" single="comment" plural="comments"}}</h2>
{{comments title="" count=false}}
</div>
{{/if}}
<footer class="gh-article-footer gh-canvas">
<nav class="gh-navigation">
<div class="gh-navigation-previous">
{{#prev_post}}
<a class="gh-navigation-link" href="{{url}}">← Previous</a>
{{/prev_post}}
</div>
<div class="gh-navigation-middle"></div>
<div class="gh-navigation-next">
{{#next_post}}
<a class="gh-navigation-link" href="{{url}}">Next →</a>
{{/next_post}}
</div>
</nav>
</footer>
</article>
{{/post}}
</div>
</main>

20
tag.hbs Normal file
View File

@ -0,0 +1,20 @@
{{!< default}}
<main class="gh-main gh-outer">
{{#tag}}
<section class="gh-article gh-inner">
<header class="gh-article-header">
<h1 class="gh-article-title">{{name}}</h1>
{{#if description}}
<p class="gh-article-excerpt">{{description}}</p>
{{/if}}
{{> "feature-image"}}
</header>
</section>
{{/tag}}
<div class="gh-feed{{#match @custom.header_section_layout "!=" "Large background"}} gh-inner{{/match}}">
{{#foreach posts}}
{{> "loop"}}
{{/foreach}}
</div>
</main>