🎉 Initial setup
🎉 Initial setup
Setup deployment
20
.editorconfig
Normal file
@@ -0,0 +1,20 @@
|
||||
# EditorConfig helps developers define and maintain consistent
|
||||
# coding styles between different editors and IDEs
|
||||
# editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
|
||||
# Change these settings to your own preference
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
# We recommend you to keep these unchanged
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
42
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
name: build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v1
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Install
|
||||
run: npm ci
|
||||
- name: Build
|
||||
run: npm run prod
|
||||
- name: Predeploy
|
||||
if: success() && github.ref == 'refs/heads/master'
|
||||
run: |
|
||||
# https://github.blog/2009-12-29-bypassing-jekyll-on-github-pages/
|
||||
touch dist/.nojekyll
|
||||
# https://help.github.com/en/articles/managing-a-custom-domain-for-your-github-pages-site
|
||||
echo einundzwanzig.space > dist/CNAME
|
||||
- name: Deploy
|
||||
if: success() && github.ref == 'refs/heads/master'
|
||||
uses: maxheld83/ghpages@v0.2.1
|
||||
env:
|
||||
BUILD_DIR: dist/
|
||||
GH_PAT: ${{ secrets.GH_PAT }}
|
||||
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
/dist
|
||||
/log
|
||||
/node_modules
|
||||
/rev-manifest.json
|
||||
/site-data.json
|
||||
5
.prettierrc.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
26
README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Einundzwanzig Podcast Website
|
||||
|
||||
Die offizielle [Einundzwanzig](https://einundzwanzig.space) website.
|
||||
|
||||

|
||||
|
||||
## Content
|
||||
|
||||
The content can be edited via the JSON files in the [content directory](./content).
|
||||
|
||||
## Local build
|
||||
|
||||
[Node.js](https://nodejs.org/en/) is a prerequisite, the dependencies are managed via npm.
|
||||
Once you have cloned this repo, you can setup the packages:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
Create a build and rebuild on file change:
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
This will bring up the dev server on [localhost:3000](http://localhost:3000).
|
||||
6
browser-sync.config.js
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
open: false,
|
||||
notify: false,
|
||||
ghostMode: false,
|
||||
server: ['./static', './dist'],
|
||||
}
|
||||
8
content/meta.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Einundzwanzig",
|
||||
"description": "Toximalistisches Infotainment für bullishe Bitcoiner.",
|
||||
"keywords": "Bitcoin,Podcast,Lightning Network",
|
||||
"themeColor": "#FFFFFF",
|
||||
"cardImage": "img/card.png",
|
||||
"twitter": "_einundzwanzig_"
|
||||
}
|
||||
37
content/team.json
Normal file
@@ -0,0 +1,37 @@
|
||||
[
|
||||
{
|
||||
"name": "Markus",
|
||||
"twitter": "MarkusTurm",
|
||||
"github": "MarkusTurm",
|
||||
"text": "Bester Mann.",
|
||||
"image": "/img/team/markus.jpg"
|
||||
},
|
||||
{
|
||||
"name": "Gigi",
|
||||
"twitter": "dergigi",
|
||||
"github": "dergigi",
|
||||
"text": "Der Gigi.",
|
||||
"image": "/img/team/gigi.jpg"
|
||||
},
|
||||
{
|
||||
"name": "Fab",
|
||||
"twitter": "fabthefoxx",
|
||||
"url": "http://fabthefox.com",
|
||||
"text": "The Fox 🦊",
|
||||
"image": "/img/team/fab.jpg"
|
||||
},
|
||||
{
|
||||
"name": "Dennis",
|
||||
"twitter": "dennisreimann",
|
||||
"github": "dennisreimann",
|
||||
"url": "https://d11n.net",
|
||||
"text": "d11n",
|
||||
"image": "/img/team/dennis.png"
|
||||
},
|
||||
{
|
||||
"name": "Daniel",
|
||||
"twitter": "danielwingen",
|
||||
"text": "Value Of Bitcoin.",
|
||||
"image": "/img/team/daniel.jpg"
|
||||
}
|
||||
]
|
||||
14
markdown.js
Normal file
@@ -0,0 +1,14 @@
|
||||
// configure markdown-it
|
||||
const transformer = require('jstransformer')
|
||||
const { _tr: mdTransformer } = transformer(require('jstransformer-markdown-it'))
|
||||
|
||||
const config = {
|
||||
typographer: true,
|
||||
}
|
||||
|
||||
// monkey-patch render function to pass custom options
|
||||
const { render: renderMd } = mdTransformer
|
||||
|
||||
mdTransformer.render = str => renderMd(str, config)
|
||||
|
||||
module.exports = mdTransformer.render
|
||||
10648
package-lock.json
generated
Normal file
54
package.json
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"name": "einundzwanzig.space",
|
||||
"description": "Einundzwanzig Podcast Website",
|
||||
"repository": "git@github.com:Einundzwanzig-Podcast/einundzwanzig.space.git",
|
||||
"license": "UNLICENSED",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rm -rf rev-manifest.json site-data.json dist/* && mkdir -p dist",
|
||||
"start": "npm-run-all clean -p start:*",
|
||||
"start:pages": "onchange -i -k 'site-data.json' 'pug.config.js' 'markdown.js' 'src/**/*.pug' 'src/**/*.svg' 'tasks/generate_pages.js' -- npm run build:pages",
|
||||
"start:styles": "onchange -i -k 'src/**/*.css' -- npm run build:styles",
|
||||
"start:data": "onchange -i -k 'content/**/*' -- npm run build:data",
|
||||
"start:serve": "browser-sync start --config browser-sync.config.js --watch",
|
||||
"build": "npm-run-all clean -p build:*",
|
||||
"build:static": "cp -r static/* dist",
|
||||
"build:data": "node tasks/generate_site_data.js",
|
||||
"build:pages": "node tasks/generate_pages.js",
|
||||
"build:styles": "postcss src/css/main.css --output dist/css/main.css",
|
||||
"optimize": "npm-run-all -p optimize:* -s rev",
|
||||
"optimize:styles": "csso dist/css/main.css --output dist/css/main.css",
|
||||
"rev": "node-file-rev --root=dist/ dist/css/* dist/js/* dist/img/*.jpg dist/img/*.png dist/img/*.svg",
|
||||
"prod": "npm-run-all build optimize -s build:pages",
|
||||
"images": "node tasks/optimize_images.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "10.0.1",
|
||||
"browser-sync": "2.26.12",
|
||||
"csso-cli": "3.0.0",
|
||||
"jstransformer-markdown-it": "2.1.0",
|
||||
"markdown-it": "11.0.1",
|
||||
"node-file-rev": "1.1.2",
|
||||
"npm-run-all": "4.1.5",
|
||||
"onchange": "7.0.2",
|
||||
"postcss": "8.1.1",
|
||||
"postcss-calc": "7.0.5",
|
||||
"postcss-cli": "8.0.0",
|
||||
"postcss-custom-media": "7.0.8",
|
||||
"postcss-import": "12.0.1",
|
||||
"postcss-media-variables": "2.0.1",
|
||||
"postcss-nesting": "7.0.1",
|
||||
"pug-cli": "1.0.0-alpha6"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"compress-images": "1.9.5",
|
||||
"gifsicle": "5.1.0",
|
||||
"mozjpeg": "7.0.0",
|
||||
"pngquant-bin": "6.0.0",
|
||||
"svgo": "1.3.2"
|
||||
}
|
||||
}
|
||||
13
postcss.config.js
Normal file
@@ -0,0 +1,13 @@
|
||||
const mediaVariables = require('postcss-media-variables')
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
require('autoprefixer'),
|
||||
require('postcss-import'),
|
||||
require('postcss-nesting'),
|
||||
mediaVariables,
|
||||
require('postcss-custom-media'),
|
||||
require('postcss-calc'),
|
||||
mediaVariables,
|
||||
],
|
||||
}
|
||||
24
pug.config.js
Normal file
@@ -0,0 +1,24 @@
|
||||
// initialize markdown rendering
|
||||
const renderMarkdown = require('./markdown')
|
||||
|
||||
const slugify = str => str.toLowerCase().replace(/\W/, '-')
|
||||
const random = max => Math.floor(Math.random() * Math.floor(max))
|
||||
const linkTarget = url => url.startsWith('http') ? '_blank' : null
|
||||
const assetPath = path => {
|
||||
let revs
|
||||
try { revs = require('./rev-manifest.json') } catch (error) { }
|
||||
return `${(revs && revs[path]) || path}`
|
||||
}
|
||||
const assetUrl = (path, protocol = 'https') => {
|
||||
return `${protocol}://einundzwanzig.space/${assetPath(path)}`
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
basedir: './src/includes',
|
||||
random,
|
||||
slugify,
|
||||
assetUrl,
|
||||
assetPath,
|
||||
linkTarget,
|
||||
renderMarkdown,
|
||||
}
|
||||
114
src/css/base/elements.css
Normal file
@@ -0,0 +1,114 @@
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
box-sizing: border-box;
|
||||
vertical-align: baseline;
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
animation: none !important;
|
||||
transition: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
line-height: 1.5;
|
||||
font-family: var(--font-family-base);
|
||||
font-size: var(--font-size-base);
|
||||
scroll-behavior: smooth;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
color: var(--color-body-text);
|
||||
background-color: var(--color-body-bg);
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-family: var(--font-family-head);
|
||||
line-height: 1.05;
|
||||
|
||||
& a {
|
||||
color: currentColor;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: var(--font-size-xxxl);
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: var(--font-size-xxl);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: var(--font-size-xl);
|
||||
}
|
||||
|
||||
h4, h5, h6 {
|
||||
font-size: var(--font-size-m);
|
||||
}
|
||||
|
||||
a {
|
||||
outline: 0;
|
||||
color: inherit;
|
||||
text-decoration: underline;
|
||||
transition-property: background, color;
|
||||
transition-duration: var(--transition-duration-fast);
|
||||
|
||||
&:hover {
|
||||
@media not all and (hover: none) {
|
||||
color: var(--color-accent);
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
& svg {
|
||||
transition-property: background, color;
|
||||
transition-duration: var(--transition-duration-fast);
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: var(--space-l);
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-left: var(--space-m);
|
||||
margin-bottom: var(--space-l);
|
||||
}
|
||||
|
||||
p,
|
||||
ul {
|
||||
& + h2 {
|
||||
margin-top: var(--space-xl);
|
||||
}
|
||||
|
||||
& + h3,
|
||||
& + h4,
|
||||
& + h5,
|
||||
& + h6 {
|
||||
margin-top: var(--space-l);
|
||||
}
|
||||
}
|
||||
|
||||
img:-moz-loading {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
[aria-hidden="true"] {
|
||||
display: none;
|
||||
}
|
||||
4
src/css/base/fonts.css
Normal file
@@ -0,0 +1,4 @@
|
||||
@font-face {
|
||||
font-family: 'The Bold Font';
|
||||
src: url('../fonts/theboldfont.woff2') format('woff2');
|
||||
}
|
||||
4
src/css/base/footer.css
Normal file
@@ -0,0 +1,4 @@
|
||||
.footer {
|
||||
text-align: center;
|
||||
font-size: var(--font-size-xs);
|
||||
}
|
||||
119
src/css/base/header.css
Normal file
@@ -0,0 +1,119 @@
|
||||
.header {
|
||||
/* position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 10; */
|
||||
color: var(--color-body-text);
|
||||
background-color: var(--color-body-bg);
|
||||
|
||||
@media (--up_to_L) {
|
||||
padding-top: var(--space-l);
|
||||
padding-bottom: var(--space-l);
|
||||
}
|
||||
@media (--L_and_up) {
|
||||
padding-top: var(--space-xl);
|
||||
padding-bottom: var(--space-xl);
|
||||
}
|
||||
|
||||
@nest body.topbar & {
|
||||
box-shadow: 0px 5px 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
@nest body.topbar.topbar--appear & {
|
||||
opacity: 1;
|
||||
transition-property: opacity;
|
||||
transition-duration: var(--transition-duration-fast);
|
||||
}
|
||||
|
||||
& .wrap {
|
||||
@media (--L_and_up) {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
& .brand {
|
||||
display: inline-block;
|
||||
margin-right: var(--space-xl);
|
||||
}
|
||||
|
||||
& .logo {
|
||||
display: block;
|
||||
|
||||
@media (--up_to_M) {
|
||||
height: 27px;
|
||||
width: 300px;
|
||||
}
|
||||
@media (--M_to_L) {
|
||||
height: 45px;
|
||||
width: 500px;
|
||||
}
|
||||
@media (--L_and_up) {
|
||||
height: 63px;
|
||||
width: 700px;
|
||||
}
|
||||
}
|
||||
|
||||
& .nav {
|
||||
position: relative;
|
||||
top: 3px;
|
||||
left: -1px;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
|
||||
@media (--up_to_L) {
|
||||
margin-top: var(--space-m);
|
||||
}
|
||||
@media (--L_and_up) {
|
||||
margin-top: var(--space-l);
|
||||
}
|
||||
|
||||
& a {
|
||||
text-decoration: none;
|
||||
|
||||
&.navItem {
|
||||
text-transform: uppercase;
|
||||
letter-spacing: -0.04em;
|
||||
font-weight: var(--font-weight-bold);
|
||||
margin-right: var(--space-l);
|
||||
line-height: 1;
|
||||
|
||||
@media (--up_to_L) {
|
||||
font-size: var(--font-size-l);
|
||||
}
|
||||
@media (--L_and_up) {
|
||||
font-size: var(--font-size-xl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& .social {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@media (--L_and_up) {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
& a,
|
||||
& svg {
|
||||
display: inline-block;
|
||||
|
||||
@media (--up_to_L) {
|
||||
height: calc(var(--font-size-l) - 0.2rem);
|
||||
width: calc(var(--font-size-l) - 0.2rem);
|
||||
}
|
||||
@media (--L_and_up) {
|
||||
height: calc(var(--font-size-xl) - 0.2rem);
|
||||
width: calc(var(--font-size-xl) - 0.2rem);
|
||||
}
|
||||
}
|
||||
|
||||
& a + a {
|
||||
margin-left: var(--space-l);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
src/css/base/layout.css
Normal file
@@ -0,0 +1,24 @@
|
||||
.wrap {
|
||||
max-width: 1440px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
|
||||
@media (--up_to_M) {
|
||||
padding-left: var(--space-l);
|
||||
padding-right: var(--space-l);
|
||||
}
|
||||
@media (--M_to_L) {
|
||||
padding-left: var(--space-xl);
|
||||
padding-right: var(--space-xl);
|
||||
}
|
||||
@media (--L_and_up) {
|
||||
padding-left: var(--space-xxl);
|
||||
padding-right: var(--space-xxl);
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
flex: 1;
|
||||
padding-top: var(--space-xl);
|
||||
padding-bottom: var(--space-xl);
|
||||
}
|
||||
61
src/css/base/variables.css
Normal file
@@ -0,0 +1,61 @@
|
||||
@custom-media --up_to_M screen and (max-width: 599px);
|
||||
@custom-media --up_to_L screen and (max-width: 839px);
|
||||
@custom-media --M_to_L screen and (min-width: 600px) and (max-width: 839px);
|
||||
@custom-media --M_and_up screen and (min-width: 600px);
|
||||
@custom-media --L_and_up screen and (min-width: 840px);
|
||||
|
||||
:root {
|
||||
--color-neutral-0: #fff;
|
||||
--color-neutral-10: #ddd;
|
||||
--color-neutral-90: #222;
|
||||
|
||||
--color-body-text: var(--color-neutral-90);
|
||||
--color-body-bg: var(--color-neutral-0);
|
||||
--color-accent: #f7931a;
|
||||
--color-derweg: #00B4CF;
|
||||
--color-interview: #151515;
|
||||
|
||||
--space-xs: .125rem;
|
||||
--space-s: .25rem;
|
||||
--space-m: .5rem;
|
||||
--space-l: 1rem;
|
||||
--space-xl: 2rem;
|
||||
--space-xxl: 4rem;
|
||||
|
||||
--transition-duration-fast: 0.25s;
|
||||
--transition-duration-medium: 0.75s;
|
||||
--transition-duration-slow: 1.5s;
|
||||
|
||||
--border-radius: 16px;
|
||||
--opacity-text: 0.7;
|
||||
|
||||
--font-family-base: sans-serif;
|
||||
--font-family-head: 'The Bold Font', var(--font-family-base);
|
||||
|
||||
--font-weight-light: 300;
|
||||
--font-weight-normal: 400;
|
||||
--font-weight-medium: 500;
|
||||
--font-weight-semibold: 600;
|
||||
--font-weight-bold: 700;
|
||||
|
||||
--font-size-base: 18px;
|
||||
--font-size-xs: .7rem;
|
||||
--font-size-s: .85rem;
|
||||
--font-size-m: 1rem;
|
||||
--font-size-l: 1.25rem;
|
||||
--font-size-xl: 1.5rem;
|
||||
--font-size-xxl: 2.5rem;
|
||||
--font-size-xxxl: 4rem;
|
||||
}
|
||||
|
||||
:root[data-theme="dark"] {
|
||||
--color-body-text: var(--color-neutral-0);
|
||||
--color-body-bg: var(--color-neutral-90);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root:not([data-theme="light"]) {
|
||||
--color-body-text: var(--color-neutral-0);
|
||||
--color-body-bg: var(--color-neutral-90);
|
||||
}
|
||||
}
|
||||
11
src/css/main.css
Normal file
@@ -0,0 +1,11 @@
|
||||
/* Base */
|
||||
@import 'base/variables.css';
|
||||
@import 'base/fonts.css';
|
||||
@import 'base/elements.css';
|
||||
@import 'base/layout.css';
|
||||
@import 'base/header.css';
|
||||
@import 'base/footer.css';
|
||||
|
||||
/* Sections */
|
||||
@import 'sections/podcast.css';
|
||||
@import 'sections/team.css';
|
||||
104
src/css/sections/podcast.css
Normal file
@@ -0,0 +1,104 @@
|
||||
#updates {
|
||||
position: relative;
|
||||
padding-top: 120px;
|
||||
|
||||
@media (--M_and_up) {
|
||||
padding-bottom: 180px;
|
||||
}
|
||||
|
||||
& h3 {
|
||||
@media (--up_to_M) {
|
||||
font-size: 36px;
|
||||
margin-bottom: var(--space-l);
|
||||
}
|
||||
@media (--M_and_up) {
|
||||
font-size: 48px;
|
||||
margin-bottom: var(--space-xl);
|
||||
}
|
||||
}
|
||||
|
||||
& .update + .update {
|
||||
margin-top: var(--space-xxl);
|
||||
}
|
||||
|
||||
&:after {
|
||||
display: inline-block;
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -65px;
|
||||
bottom: -80px;
|
||||
z-index: -1;
|
||||
background-image: url(../img/bg/updates.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 100%;
|
||||
background-size: contain;
|
||||
max-width: 55%;
|
||||
width: 369px;
|
||||
height: 344px;
|
||||
|
||||
@media (--up_to_M) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.update {
|
||||
display: block;
|
||||
text-decoration: none !important;
|
||||
|
||||
@media (--M_and_up) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
max-width: 53em;
|
||||
transition-property: background, border, transform;
|
||||
transition-duration: var(--transition-duration-fast);
|
||||
}
|
||||
|
||||
& .image {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: var(--color-neutral-90);
|
||||
box-shadow: 0px 100px 80px rgba(12, 11, 24, 0.15), 0px 41.7776px 33.4221px rgba(12, 11, 24, 0.107828), 0px 22.3363px 17.869px rgba(12, 11, 24, 0.0894161), 0px 12.5216px 10.0172px rgba(12, 11, 24, 0.075), 0px 6.6501px 5.32008px rgba(12, 11, 24, 0.0605839), 0px 2.76726px 2.21381px rgba(12, 11, 24, 0.0421718);
|
||||
border: 3px solid var(--color-neutral-90);
|
||||
border-radius: var(--space-l);
|
||||
|
||||
& img {
|
||||
max-width: 80%;
|
||||
max-height: 80%;
|
||||
}
|
||||
|
||||
@media (--up_to_M) {
|
||||
width: 100%;
|
||||
height: 195px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
@media (--M_and_up) {
|
||||
flex: 1 0 42.5%;
|
||||
height: 275px;
|
||||
margin-right: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
& h4 {
|
||||
margin-bottom: 15px;
|
||||
|
||||
@media (--up_to_M) {
|
||||
font-size: var(--font-size-xl);
|
||||
}
|
||||
}
|
||||
|
||||
& p {
|
||||
opacity: var(--opacity-text);
|
||||
color: var(--color-body-text) !important;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
& .image {
|
||||
@media not all and (hover: none) {
|
||||
border-color: var(--color-accent);
|
||||
background-image: linear-gradient(45deg, #1A136E 29.26%, #0D0AB7 92.45%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
68
src/css/sections/team.css
Normal file
@@ -0,0 +1,68 @@
|
||||
#team {
|
||||
& .members {
|
||||
display: grid;
|
||||
grid-gap: var(--space-xxl);
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
|
||||
@media (--up_to_M) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
@media (--M_to_L) {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
@media (--L_and_up) {
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
& .member {
|
||||
margin: 0;
|
||||
|
||||
& img {
|
||||
display: block;
|
||||
border-radius: 50%;
|
||||
|
||||
@media (--up_to_L) {
|
||||
height: 87px;
|
||||
width: 87px;
|
||||
}
|
||||
@media (--L_and_up) {
|
||||
height: 112px;
|
||||
width: 112px;
|
||||
}
|
||||
}
|
||||
|
||||
& h4 {
|
||||
margin-top: var(--space-m);
|
||||
font-size: 21px;
|
||||
}
|
||||
|
||||
& a {
|
||||
font-size: var(--font-size-xs);
|
||||
text-decoration: none;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
& p {
|
||||
margin: var(--space-s) 0 var(--space-l);
|
||||
font-size: var(--font-size-s);
|
||||
opacity: var(--opacity-text);
|
||||
max-width: 30em;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
& .links {
|
||||
& a,
|
||||
& svg {
|
||||
display: inline-block;
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
}
|
||||
|
||||
& a + a {
|
||||
margin-left: var(--space-m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
67
src/includes/template.pug
Normal file
@@ -0,0 +1,67 @@
|
||||
block vars
|
||||
|
||||
- const pageTitle = title ? `${title} · ${site.title}` : site.meta.title
|
||||
- const pageDescription = description || site.meta.description
|
||||
- const pageKeywords = keywords || site.meta.keywords
|
||||
- const pageCard = cardImage || site.meta.cardImage
|
||||
- const themeColor = '#FFFFFF'
|
||||
|
||||
mixin sprite(id)
|
||||
svg(role="img" title=id)&attributes(attributes)
|
||||
use(xlink:href=`${assetPath("/img/sprite.svg")}#${id}`)
|
||||
|
||||
<!DOCTYPE html>
|
||||
html(lang="en")
|
||||
head
|
||||
meta(charset="UTF-8")
|
||||
meta(http-equiv="X-UA-Compatible" content="ie=edge")
|
||||
meta(name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover")
|
||||
meta(name="keywords" content=pageKeywords)
|
||||
meta(name="description" content=pageDescription)
|
||||
meta(property="og:locale" content="de_DE")
|
||||
meta(property="og:site_name" content=site.title)
|
||||
meta(property="og:title" content=pageTitle)
|
||||
meta(property="og:description" content=pageDescription)
|
||||
meta(property="og:type" content="website")
|
||||
meta(property="og:image" content=assetUrl(pageCard, "http"))
|
||||
meta(property="og:image:secure_url" content=assetUrl(pageCard))
|
||||
meta(property="og:image:width" content=1402)
|
||||
meta(property="og:image:height" content=1402)
|
||||
meta(property="twitter:card" content="summary")
|
||||
meta(property="twitter:title" content=pageTitle)
|
||||
meta(property="twitter:description" content=pageDescription)
|
||||
meta(property="twitter:image" content=assetUrl(pageCard))
|
||||
meta(name="msapplication-TileColor" content=themeColor)
|
||||
meta(name="theme-color" content=themeColor)
|
||||
link(rel="preload" as="font" crossorigin href=assetPath("/fonts/theboldfont.woff2"))
|
||||
link(rel="apple-touch-icon" href=assetPath("/img/einundzwanzig-square.svg"))
|
||||
link(rel="icon" href=assetPath("/img/einundzwanzig-square.svg"))
|
||||
link(rel="manifest" href="/site.webmanifest")
|
||||
link(rel="mask-icon" href=assetPath("/img/favicon/safari-pinned-tab.svg") color=themeColor)
|
||||
link(rel="stylesheet" href=assetPath("/css/main.css"))
|
||||
title= pageTitle
|
||||
body
|
||||
header.header#header
|
||||
.wrap
|
||||
a(href="/").brand
|
||||
+sprite("logo-horizontal").logo
|
||||
nav.nav
|
||||
a.navItem(href="/podcast" sclass=(navCurrent === 'podcast' && 'current')) Podcast
|
||||
a.navItem(href="/team" class=(navCurrent === 'team' && 'current')) Team
|
||||
.social
|
||||
a.twitter(href="https://twitter.com/_einundzwanzig_" target="_blank" title="Twitter")
|
||||
+sprite("twitter")
|
||||
a.telegram(href="https://t.me/einundzwanzigpodcast" target="_blank" title="Telegram")
|
||||
+sprite("telegram")
|
||||
|
||||
#header-anchor
|
||||
|
||||
main.main
|
||||
.wrap
|
||||
block main
|
||||
|
||||
footer#footer.footer
|
||||
.wrap
|
||||
p Craig Wright is a fraud.
|
||||
|
||||
script(src=assetPath("/js/main.js"))
|
||||
9
src/index.pug
Normal file
@@ -0,0 +1,9 @@
|
||||
extends /template.pug
|
||||
|
||||
block main
|
||||
section
|
||||
:markdown-it(html linkify typographer)
|
||||
# Start
|
||||
Content
|
||||
|
||||
- [Shoutouts](https://tallyco.in/s/zfxqtu/)
|
||||
13
src/podcast.pug
Normal file
@@ -0,0 +1,13 @@
|
||||
extends /template.pug
|
||||
|
||||
block main
|
||||
section
|
||||
:markdown-it(html linkify typographer)
|
||||
# Podcast
|
||||
Content
|
||||
|
||||
- [Spotify](https://open.spotify.com/show/10408JFbE1n8MexfrBv33r)
|
||||
- [Apple Podcasts](https://podcasts.apple.com/de/podcast/einundzwanzig-der-bitcoin-podcast/id1488229907)
|
||||
- [Overcast](https://overcast.fm/itunes1488229907/einundzwanzig-der-bitcoin-podcast)
|
||||
- [Anchor](https://anchor.fm/einundzwanzig)
|
||||
- [RSS](https://anchor.fm/s/d8d3c38/podcast/rss)
|
||||
21
src/team.pug
Normal file
@@ -0,0 +1,21 @@
|
||||
extends /template.pug
|
||||
|
||||
block main
|
||||
section#team
|
||||
h1 Team
|
||||
ul.members
|
||||
each m in team
|
||||
li.member
|
||||
img(src=(assetPath(m.image)) alt=m.name loading="lazy")
|
||||
h4=m.name
|
||||
p(style=(m.name.startsWith('Arik') ? 'word-break:break-all;' : null))=m.text
|
||||
.links
|
||||
if m.twitter
|
||||
a(href=(m.twitter.startsWith('https://') ? m.twitter : `https://twitter.com/${m.twitter}`) target="_blank" title=`${m.name} on Twitter`)
|
||||
+sprite("twitter")
|
||||
if m.github
|
||||
a(href=(m.github.startsWith('https://') ? m.github : `https://github.com/${m.github}`) target="_blank" title=`${m.name} on GitHub`)
|
||||
+sprite("github")
|
||||
if m.url
|
||||
a(href=m.url target="_blank")
|
||||
+sprite("url")
|
||||
11
static/browserconfig.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="/img/favicon/mstile-150x150.png"/>
|
||||
<square310x310logo src="/img/favicon/mstile-310x310.png"/>
|
||||
<wide310x150logo src="/img/favicon/mstile-310x150.png"/>
|
||||
<TileColor>#ffffff</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
||||
BIN
static/favicon.ico
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
static/fonts/theboldfont.woff2
Normal file
BIN
static/img/card.png
Normal file
|
After Width: | Height: | Size: 158 KiB |
1
static/img/einundzwanzig-horizontal.svg
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
1
static/img/einundzwanzig-square.svg
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
BIN
static/img/favicon/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
BIN
static/img/favicon/android-chrome-512x512.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
static/img/favicon/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
static/img/favicon/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 975 B |
BIN
static/img/favicon/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
static/img/favicon/mstile-144x144.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
BIN
static/img/favicon/mstile-150x150.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
static/img/favicon/mstile-310x150.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
static/img/favicon/mstile-310x310.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
static/img/favicon/mstile-70x70.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
60
static/img/favicon/safari-pinned-tab.svg
Normal file
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="700.000000pt" height="700.000000pt" viewBox="0 0 700.000000 700.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.11, written by Peter Selinger 2001-2013
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,700.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M622 5983 l3 -748 483 -3 482 -2 0 175 0 175 -310 0 -310 0 0 120 0
|
||||
120 250 0 250 0 0 170 0 170 -250 0 -250 0 0 115 0 115 310 0 310 0 0 170 0
|
||||
170 -485 0 -485 0 2 -747z"/>
|
||||
<path d="M1770 5980 l0 -750 173 2 172 3 3 748 2 747 -175 0 -175 0 0 -750z"/>
|
||||
<path d="M2320 5980 l0 -750 175 0 175 0 2 433 3 434 244 -434 245 -433 188 0
|
||||
188 0 0 750 0 750 -175 0 -175 0 -2 -432 -3 -432 -241 430 -242 429 -191 3
|
||||
-191 2 0 -750z"/>
|
||||
<path d="M3360 4346 l0 -756 169 0 c201 0 296 12 401 49 114 40 184 85 281
|
||||
181 72 71 93 100 132 180 26 52 53 121 61 152 89 353 -92 726 -428 878 -119
|
||||
54 -165 62 -398 67 l-218 5 0 -756z m486 364 c37 -18 81 -51 113 -85 231 -244
|
||||
109 -618 -222 -680 l-37 -7 0 407 0 408 43 -7 c23 -4 69 -20 103 -36z"/>
|
||||
<path d="M650 4583 c0 -412 3 -518 15 -563 66 -247 290 -422 544 -424 108 -1
|
||||
175 16 273 66 147 76 265 229 297 386 7 34 11 230 11 547 l0 495 -175 0 -174
|
||||
0 -3 -504 -3 -504 -30 -44 c-60 -86 -187 -122 -281 -79 -53 24 -109 91 -123
|
||||
146 -7 29 -11 204 -11 514 l0 471 -170 0 -170 0 0 -507z"/>
|
||||
<path d="M2000 4340 l0 -750 170 0 170 0 0 437 c0 240 3 433 7 429 5 -4 116
|
||||
-200 249 -434 l241 -427 186 -3 187 -2 0 750 0 750 -170 0 -170 0 0 -431 c0
|
||||
-245 -4 -428 -9 -425 -5 3 -116 197 -247 431 l-239 425 -187 0 -188 0 0 -750z"/>
|
||||
<path d="M660 3290 l0 -170 271 0 c254 0 271 -1 265 -17 -4 -10 -144 -271
|
||||
-311 -580 -168 -310 -305 -565 -305 -568 0 -3 270 -5 600 -5 l600 0 0 175 0
|
||||
175 -309 2 -310 3 309 570 c170 314 310 573 310 578 0 4 -252 7 -560 7 l-560
|
||||
0 0 -170z"/>
|
||||
<path d="M1832 3448 c3 -7 116 -347 252 -756 l248 -742 171 2 172 3 85 367
|
||||
c46 202 87 365 89 362 3 -3 49 -168 102 -367 l95 -362 171 -3 171 -2 11 32
|
||||
c27 85 431 1462 431 1469 0 5 -81 9 -179 9 -162 0 -180 -2 -185 -17 -3 -10
|
||||
-55 -189 -117 -398 -61 -209 -114 -385 -118 -392 -3 -7 -55 172 -115 398
|
||||
l-109 409 -171 0 -171 0 -94 -410 c-52 -226 -97 -407 -101 -403 -4 4 -68 189
|
||||
-141 411 l-134 402 -183 0 c-143 0 -183 -3 -180 -12z"/>
|
||||
<path d="M4285 3438 c-28 -78 -505 -1475 -505 -1481 0 -4 82 -6 182 -5 l182 3
|
||||
31 88 30 87 239 -2 239 -3 30 -87 29 -88 179 0 c114 0 179 4 179 10 0 9 -302
|
||||
945 -436 1353 l-46 137 -164 0 c-123 0 -166 -3 -169 -12z m226 -780 l55 -173
|
||||
-114 -3 c-63 -1 -117 0 -120 2 -5 6 111 346 119 346 3 0 30 -78 60 -172z"/>
|
||||
<path d="M5210 2700 l0 -750 173 2 172 3 5 427 5 427 241 -427 241 -427 186
|
||||
-3 187 -2 0 750 0 750 -170 0 -170 0 0 -431 c0 -236 -4 -428 -8 -425 -5 3
|
||||
-116 197 -248 431 l-239 425 -187 0 -188 0 0 -750z"/>
|
||||
<path d="M660 1650 l0 -170 271 0 c254 0 271 -1 265 -17 -4 -10 -144 -271
|
||||
-311 -580 -168 -310 -305 -565 -305 -568 0 -3 270 -5 600 -5 l600 0 0 175 0
|
||||
175 -310 2 -309 3 309 570 c170 314 310 573 310 578 0 4 -252 7 -560 7 l-560
|
||||
0 0 -170z"/>
|
||||
<path d="M3100 1809 c-170 -17 -325 -92 -451 -218 -89 -89 -139 -170 -182
|
||||
-296 -29 -83 -31 -100 -32 -225 0 -234 57 -376 217 -538 82 -82 180 -143 298
|
||||
-183 89 -31 103 -33 230 -33 90 1 152 6 188 16 49 14 52 14 52 -3 0 -18 11
|
||||
-19 175 -19 l175 0 0 420 0 420 -325 0 -325 0 0 -170 0 -170 151 0 150 0 -3
|
||||
-42 c-3 -42 -5 -44 -63 -73 -56 -28 -68 -30 -170 -30 -103 0 -114 2 -175 31
|
||||
-169 81 -263 267 -225 445 61 293 399 422 644 246 l48 -35 122 122 123 123
|
||||
-44 37 c-155 133 -364 197 -578 175z"/>
|
||||
<path d="M1992 1063 l3 -748 173 -3 172 -2 0 750 0 750 -175 0 -175 0 2 -747z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
9
static/img/sprite.svg
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
static/img/team/daniel.jpg
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
static/img/team/dennis.png
Normal file
|
After Width: | Height: | Size: 110 KiB |
BIN
static/img/team/fab.jpg
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
static/img/team/gigi.jpg
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
static/img/team/markus.jpg
Normal file
|
After Width: | Height: | Size: 16 KiB |
35
static/js/main.js
Normal file
@@ -0,0 +1,35 @@
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const $body = document.body
|
||||
const $headerAnchor = document.getElementById('header-anchor')
|
||||
|
||||
// Topbar
|
||||
const topbarClass = 'topbar'
|
||||
const topbarAppearClass = 'topbar--appear'
|
||||
const addTopbar = () => {
|
||||
$body.classList.add(topbarClass)
|
||||
window.setTimeout(() => {
|
||||
$body.classList.add(topbarAppearClass)
|
||||
}, 25)
|
||||
}
|
||||
const removeTopbar = () => {
|
||||
$body.classList.remove(topbarClass)
|
||||
$body.classList.remove(topbarAppearClass)
|
||||
}
|
||||
|
||||
if (
|
||||
"IntersectionObserver" in window &&
|
||||
"IntersectionObserverEntry" in window &&
|
||||
"intersectionRatio" in window.IntersectionObserverEntry.prototype
|
||||
) {
|
||||
const headerObserver = new IntersectionObserver(entries => {
|
||||
const { boundingClientRect: { y, height } } = entries[0]
|
||||
if (Math.abs(y) > height) {
|
||||
addTopbar()
|
||||
} else {
|
||||
removeTopbar()
|
||||
}
|
||||
})
|
||||
|
||||
headerObserver.observe($headerAnchor)
|
||||
}
|
||||
})
|
||||
19
static/site.webmanifest
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "Einundzwanzig",
|
||||
"short_name": "Einundzwanzig",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/img/favicon/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/img/favicon/android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#ffffff",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
||||
13
tasks/fetch_feed.js
Normal file
@@ -0,0 +1,13 @@
|
||||
const { writeFileSync } = require('fs')
|
||||
const { join, resolve } = require('path')
|
||||
const Parser = require('rss-parser')
|
||||
|
||||
const dir = resolve(__dirname, '..')
|
||||
const dst = join(dir, 'feed.json')
|
||||
|
||||
;(async () => {
|
||||
const parser = new Parser()
|
||||
const feed = await parser.parseURL('https://anchor.fm/s/d8d3c38/podcast/rss')
|
||||
|
||||
writeFileSync(dst, JSON.stringify(feed, null, 2))
|
||||
})()
|
||||
22
tasks/generate_pages.js
Normal file
@@ -0,0 +1,22 @@
|
||||
const pug = require('pug')
|
||||
const { mkdirSync, writeFileSync } = require('fs')
|
||||
const { dirname, resolve } = require('path')
|
||||
const config = require('../pug.config')
|
||||
const site = require('../site-data')
|
||||
const feed = require('../feed.json')
|
||||
const team = require('../content/team.json')
|
||||
|
||||
const renderPage = (name, out, data = {}) => {
|
||||
const file = resolve(__dirname, '..', `src/${name}.pug`)
|
||||
const options = Object.assign({}, config, { site }, data)
|
||||
const rendered = pug.renderFile(file, options)
|
||||
const dst = resolve(__dirname, '..', 'dist', `${out}.html`)
|
||||
const dir = dirname(dst)
|
||||
|
||||
mkdirSync(dir, { recursive: true })
|
||||
writeFileSync(dst, rendered)
|
||||
}
|
||||
|
||||
renderPage('index', 'index', { navCurrent: 'index' })
|
||||
renderPage('team', 'team/index', { navCurrent: 'team', team })
|
||||
renderPage('podcast', 'podcast/index', { navCurrent: 'podcast', feed })
|
||||
12
tasks/generate_site_data.js
Normal file
@@ -0,0 +1,12 @@
|
||||
const { writeFileSync } = require('fs')
|
||||
const { join, resolve } = require('path')
|
||||
|
||||
const meta = require('../content/meta.json')
|
||||
|
||||
const dir = resolve(__dirname, '..')
|
||||
const dst = join(dir, 'site-data.json')
|
||||
|
||||
const date = (new Date()).toJSON().split('T')[0]
|
||||
const data = { date, meta }
|
||||
|
||||
writeFileSync(dst, JSON.stringify(data, null, 2))
|
||||
14
tasks/optimize_images.js
Normal file
@@ -0,0 +1,14 @@
|
||||
const compress_images = require('compress-images')
|
||||
const input = 'compress/*.{jpg,png,svg,gif}'
|
||||
const output = 'compress/out/'
|
||||
|
||||
compress_images(input, output, { compress_force: true, statistic: true, autoupdate: false }, false,
|
||||
{ jpg: { engine: "mozjpeg", command: ["-quality", "60"] } },
|
||||
{ png: { engine: "pngquant", command: ["--quality=20-50", "-o"] } },
|
||||
{ svg: { engine: "svgo", command: "--multipass" } },
|
||||
{ gif: { engine: "gifsicle", command: ["--colors", "64", "--use-col=web"] } },
|
||||
(error, completed, statistic) => {
|
||||
if (error) console.error(error)
|
||||
if (statistic) console.log(statistic)
|
||||
}
|
||||
)
|
||||