Updated to Next.js 13

This commit is contained in:
Antonello Zanini
2022-11-18 13:54:54 +01:00
commit 0eae94dbe6
40 changed files with 6381 additions and 0 deletions

3
.eslintrc.json Normal file
View File

@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}

37
.gitignore vendored Normal file
View File

@@ -0,0 +1,37 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local
# vercel
.vercel
# IntelliJ IDEA
.idea

34
README.md Normal file
View File

@@ -0,0 +1,34 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
## Getting Started
First, run the development server:
```bash
npm run dev
# or
yarn dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.

42
components/BlogList.js Normal file
View File

@@ -0,0 +1,42 @@
import Link from 'next/link'
import ReactMarkdown from 'react-markdown'
import styles from "../styles/BlogList.module.css"
import Image from "next/image";
function truncateSummary(content) {
return content.slice(0, 200).trimEnd()
}
function reformatDate(fullDate) {
const date = new Date(fullDate)
return date.toDateString().slice(4)
}
const BlogList = ({ allBlogs }) => {
return (
<ul>
{allBlogs.length > 1 &&
allBlogs.map(post => (
<li key={post.slug}>
<Link href={{ pathname: `/blog/${post.slug}` }} className={styles.blog__link}>
<div className={styles.hero_image}>
<Image
width={384}
height={288}
src={post.frontmatter.hero_image}
alt={post.frontmatter.hero_image}
/>
</div>
<div className={styles.blog__info}>
<h2>{post.frontmatter.title}</h2>
<h3>{reformatDate(post.frontmatter.date)}</h3>
<ReactMarkdown disallowedElements={['a']}>{truncateSummary(post.markdownBody)}</ReactMarkdown>
</div>
</Link>
</li>
))}
</ul>
)
}
export default BlogList

26
components/Header.js Normal file
View File

@@ -0,0 +1,26 @@
import Link from "next/link";
import styles from '../styles/Header.module.css'
export default function Header(props) {
const isInfoPage = typeof window !== "undefined" && window.location.pathname === "/info"
return (
<header className={styles.header}>
<nav
className={styles.nav}
role="navigation"
aria-label="main navigation"
>
<Link href="/">
<h1>{props.siteTitle}</h1>
</Link>
<div>
<Link href={isInfoPage ? '/' : '/info'}>
<h1>{isInfoPage ? 'close' : 'info'}</h1>
</Link>
</div>
</nav>
</header>
);
}

22
components/Layout.js Normal file
View File

@@ -0,0 +1,22 @@
import Header from "./Header";
import Meta from './Meta'
import styles from '../styles/Layout.module.css'
export default function Layout(props) {
return (
<section
className={styles.layout}
style={{
backgroundColor: `${props.bgColor && props.bgColor}`,
color: props.pathname === "info" ? 'white' : undefined
}}
>
<Meta
siteTitle={props.siteTitle}
siteDescription={props.siteDescription}
/>
<Header siteTitle={props.siteTitle} />
<div className={styles.content}>{props.children}</div>
</section>
);
}

12
components/Meta.js Normal file
View File

@@ -0,0 +1,12 @@
import Head from 'next/head'
export default function Meta(props) {
return (
<Head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta charSet="utf-8" />
<title>{props.siteTitle}</title>
<meta name="Description" content={props.description}></meta>
</Head>
)
}

5
data/config.json Normal file
View File

@@ -0,0 +1,5 @@
{
"title": "Brevifolia",
"description": "Starter blog using Tina CMS with Next.js.",
"repositoryUrl": "https://github.com/kendallstrautman/brevifolia-next-tinacms"
}

7
data/info.md Normal file
View File

@@ -0,0 +1,7 @@
---
title: info page
background_color: '#AEC4BE'
---
## This blog was created using [NextJS](https://nextjs.org/)
## To get started, read the NextJS [docs](https://nextjs.org/docs) or checkout the [repository](https://github.com/kendallstrautman/brevifolia-nextjs).

9
next.config.js Normal file
View File

@@ -0,0 +1,9 @@
module.exports = {
webpack: function(config) {
config.module.rules.push({
test: /\.md$/,
use: 'raw-loader',
})
return config
},
}

2979
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

24
package.json Normal file
View File

@@ -0,0 +1,24 @@
{
"name": "brevifolia-next",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@next/font": "13.0.4",
"gray-matter": "^4.0.3",
"next": "13.0.4",
"node-glob": "^1.2.0",
"raw-loader": "^4.0.2",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-markdown": "^8.0.3"
},
"devDependencies": {
"eslint": "8.27.0",
"eslint-config-next": "13.0.4"
}
}

18
pages/_app.js Normal file
View File

@@ -0,0 +1,18 @@
import '../styles/globals.css'
import { Work_Sans } from '@next/font/google'
// importing the Inter font with
// the Next.js 13 Font Optimization Feature
const workSans = Work_Sans({
weight: ['400', '700'],
style: ['normal', 'italic'],
subsets: ['latin'],
})
function MyApp({ Component, pageProps }) {
return <main className={workSans.className}>
<Component {...pageProps} />
</main>
}
export default MyApp

5
pages/api/hello.js Normal file
View File

@@ -0,0 +1,5 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
export default function handler(req, res) {
res.status(200).json({ name: 'John Doe' })
}

82
pages/blog/[slug].js Normal file
View File

@@ -0,0 +1,82 @@
import Image from "next/image"
import matter from 'gray-matter'
import ReactMarkdown from 'react-markdown'
import styles from "../../styles/Blog.module.css"
const glob = require('glob')
import Layout from '../../components/Layout'
export default function BlogTemplate({ frontmatter, markdownBody, siteTitle }) {
function reformatDate(fullDate) {
const date = new Date(fullDate)
return date.toDateString().slice(4)
}
// /*
// ** Odd fix to get build to run
// ** It seems like on first go the props
// ** are undefined — could be a Next bug?
// */
//
// if (!frontmatter) return <></>
return (
<Layout siteTitle={siteTitle}>
<article className={styles.blog}>
<figure className={styles.blog__hero}>
<Image
width="1920"
height="1080"
src={frontmatter.hero_image}
alt={`blog_hero_${frontmatter.title}`}
/>
</figure>
<div className={styles.blog__info}>
<h1>{frontmatter.title}</h1>
<h3>{reformatDate(frontmatter.date)}</h3>
</div>
<div className={styles.blog__body}>
<ReactMarkdown>{markdownBody}</ReactMarkdown>
</div>
<h2 className={styles.blog__footer}>Written By: {frontmatter.author}</h2>
</article>
</Layout>
)
}
export async function getStaticProps({ ...ctx }) {
const { slug } = ctx.params
const content = await import(`../../posts/${slug}.md`)
const config = await import(`../../data/config.json`)
const data = matter(content.default)
return {
props: {
siteTitle: config.title,
frontmatter: data.data,
markdownBody: data.content,
},
}
}
export async function getStaticPaths() {
//get all .md files in the posts dir
const blogs = glob.sync('posts/**/*.md')
//remove path and extension to leave filename only
const blogSlugs = blogs.map(file =>
file
.split('/')[1]
.replace(/ /g, '-')
.slice(0, -3)
.trim()
)
// create paths with `slug` param
const paths = blogSlugs.map(slug => `/blog/${slug}`)
return {
paths,
fallback: false,
}
}

64
pages/index.js Normal file
View File

@@ -0,0 +1,64 @@
import matter from 'gray-matter'
import Layout from '../components/Layout'
import BlogList from '../components/BlogList'
const Index = props => {
return (
<Layout
pathname="/"
siteTitle={props.title}
siteDescription={props.description}
>
<section>
<BlogList allBlogs={props.allBlogs} />
</section>
</Layout>
)
}
export default Index
export async function getStaticProps() {
// getting the website config
const siteConfig = await import(`../data/config.json`)
const webpackContext = require.context('../posts', true, /\.md$/)
// the list of file names contained
// inside the "posts" directory
const keys = webpackContext.keys()
const values = keys.map(webpackContext)
// getting the post data from the files contained
// in the "posts" folder
const posts = keys.map((key, index) => {
// dynamically creating the post slug
// from file name
const slug = key
.replace(/^.*[\\\/]/, '')
.split('.')
.slice(0, -1)
.join('.')
// getting the .md file value associated
// with the current file name
const value = values[index]
// parsing the YAML metadata and markdown body
// contained in the .md file
const document = matter(value.default)
return {
frontmatter: document.data,
markdownBody: document.content,
slug,
}
})
return {
props: {
allBlogs: posts,
title: siteConfig.default.title,
description: siteConfig.default.description,
},
}
}

33
pages/info.js Normal file
View File

@@ -0,0 +1,33 @@
import Layout from '../components/Layout'
import matter from 'gray-matter'
import ReactMarkdown from 'react-markdown'
import styles from "../styles/Info.module.css"
export default function Info({ frontmatter, markdownBody, title }) {
return (
<Layout
pathname="info"
bgColor={frontmatter.background_color}
siteTitle={title}
>
<section className={styles.info_blurb}>
<ReactMarkdown>{markdownBody}</ReactMarkdown>
</section>
</Layout>
)
}
export async function getStaticProps() {
const content = await import(`../data/info.md`)
const config = await import(`../data/config.json`)
const data = matter(content.default)
return {
props: {
title: config.title,
frontmatter: data.data,
markdownBody: data.content,
},
}
}

14
posts/bali.md Normal file
View File

@@ -0,0 +1,14 @@
---
author: Siddhartha Mukherjee
date: '2019-07-10T07:00:00.000Z'
hero_image: /alfons-taekema-bali.jpg
title: 'Bali —body, mind & soul'
---
The term **bristlecone pine** covers three [species](https://en.wikipedia.org/wiki/Species 'Species') of [pine](https://en.wikipedia.org/wiki/Pine 'Pine') tree (family [Pinaceae](https://en.wikipedia.org/wiki/Pinaceae 'Pinaceae'), genus [_Pinus_](https://en.wikipedia.org/wiki/Pinus 'Pinus'), subsection _Balfourianae_). All three species are long-lived and highly resilient to harsh weather and bad soils. One of the three species, _Pinus longaeva_, is among the longest-lived life forms on Earth. The oldest _Pinus longaeva_ is more than 5,000 years old,[\[1\]](https://en.wikipedia.org/wiki/Bristlecone_pine#cite_note-oldest-1) making it the oldest known individual of any species.
![bali-monkey](../mahkeo-monkey.jpg)
Despite their potential age and low reproductive rate, bristlecone pines, particularly _Pinus longaeva_, are usually a [first-succession](https://en.wikipedia.org/wiki/Primary_succession 'Primary succession') species, tending to occupy new open ground.[\[2\]](https://en.wikipedia.org/wiki/Bristlecone_pine#cite_note-FEIS-2) They generally compete poorly in less-than-harsh environments, making them hard to cultivate.[\[2\]](https://en.wikipedia.org/wiki/Bristlecone_pine#cite_note-FEIS-2) In gardens, they succumb quickly to root rot.[\[3\]](https://en.wikipedia.org/wiki/Bristlecone_pine#cite_note-3) They do very well, however, where most other plants cannot even grow, such as in rocky [dolomitic](<https://en.wikipedia.org/wiki/Dolomite_(mineral)> 'Dolomite (mineral)') soils in areas with virtually no rainfall.[\[2\]](https://en.wikipedia.org/wiki/Bristlecone_pine#cite_note-FEIS-2)
Bristlecone pines grow in scattered [subalpine](https://en.wikipedia.org/wiki/Subalpine 'Subalpine') groves at high altitude in arid regions of the [Western United States](https://en.wikipedia.org/wiki/Western_United_States 'Western United States'). Bristlecones, along with all related species in class Pinopsida, are [cone-bearing](https://en.wikipedia.org/wiki/Conifer_cone 'Conifer cone') [seed plants](https://en.wikipedia.org/wiki/Seed_plant 'Seed plant') commonly known as [conifers](https://en.wikipedia.org/wiki/Conifer 'Conifer'); the name comes from the prickles on the female cones.[\[4\]](https://en.wikipedia.org/wiki/Bristlecone_pine#cite_note-ARKive-4)

9
posts/iceland.md Normal file
View File

@@ -0,0 +1,9 @@
---
title: A trip to Iceland
author: 'Watson & Crick '
date: '2019-07-10T16:04:44.000Z'
hero_image: /norris-niman-iceland.jpg
---
Pseudotsuga menziesii is an evergreen conifer species in the pine family, Pinaceae. It is native to western North America and is known as Douglas fir,Douglas-fir,Oregon pine,and Columbian pine. There are two varieties: coast Douglas-fir (P. menziesii var. menziesii), and Rocky Mountain Douglas-fir (P. menziesii var. glauca).
Chicharrones kinfolk tumblr narwhal venmo. Iceland cloud bread 8-bit, hashtag single-origin coffee keffiyeh drinking vinegar cray banjo four dollar toast bespoke tbh live-edge celiac. YOLO dreamcatcher hot chicken selvage portland XOXO, single-origin coffee sustainable mustache thundercats fixie pour-over hexagon irony deep v. Farm-to-table ennui mixtape marfa raw denim austin hell of keffiyeh chia prism ethical. Polaroid biodiesel everyday carry VHS hot chicken chartreuse typewriter messenger bag. Cloud bread truffaut street art jean shorts chia.

15
posts/joshua-tree.md Normal file
View File

@@ -0,0 +1,15 @@
---
author: Grace Hopper
date: '2019-07-09T16:04:44.000Z'
hero_image: /johannes-andersson-joshua-tree.jpg
title: An otherworldly desert
---
The Joshua tree is also called _izote de desierto_ (Spanish, "desert dagger").[\[6\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-ITIS-6) It was first formally described in the botanical literature as _Yucca brevifolia_ by [George Engelmann](https://en.m.wikipedia.org/wiki/George_Engelmann "George Engelmann") in 1871 as part of the Geological Exploration of the 100th meridian (or "[Wheeler Survey](https://en.m.wikipedia.org/wiki/Wheeler_Survey "Wheeler Survey")").[\[7\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-IPNI-7)
The name "Joshua tree" is commonly said to have been given by a group of [Mormon](https://en.m.wikipedia.org/wiki/Mormon "Mormon") settlers crossing the Mojave Desert in the mid-19th century: The tree's role in guiding them through the desert combined with its unique shape reminded them of [a biblical story](https://en.m.wikipedia.org/wiki/Conquest_of_Ai "Conquest of Ai") in which [Joshua](https://en.m.wikipedia.org/wiki/Joshua "Joshua") keeps his hands reached out for an extended period of time to guide the Israelites in their conquest of Canaan ([Joshua 8:1826](https://en.wikisource.org/wiki/Bible_(King_James)/Joshua#8:18 "s:Bible (King James)/Joshua")).[\[8\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-jtnp-8)[\[9\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-9)[\[10\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-10) However, no direct or contemporary attestation of this origin exists, and the name Joshua tree is not recorded until after Mormon contact;[\[8\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-jtnp-8)[\[11\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-11) moreover, the physical appearance of the Joshua tree more closely resembles [a similar story](https://en.m.wikipedia.org/wiki/Rephidim "Rephidim") told of [Moses](https://en.m.wikipedia.org/wiki/Moses "Moses").[\[12\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-12)
Ranchers and miners who were contemporary with the Mormon immigrants used the trunks and branches as fencing and for fuel for ore-processing steam engines. They referred to these fallen or collapsed Joshua trees as _tevis_ stumps.\[_[citation needed](https://en.m.wikipedia.org/wiki/Wikipedia:Citation_needed "Wikipedia:Citation needed")_\]
In addition to the [autonymic](https://en.m.wikipedia.org/wiki/Autonym_(botany) "Autonym (botany)") [subspecies](https://en.m.wikipedia.org/wiki/Subspecies "Subspecies") _Yucca brevifolia_ subsp. _brevifolia_, two other subspecies have been described:[\[13\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-13) _Y. b._ subsp. _jaegeriana_ (the Jaeger Joshua tree or Jaeger's Joshua tree or pygmae yucca) and _Y. b._ subsp. _herbertii_ (Webber's yucca or Herbert Joshua tree), though both are sometimes treated as varieties[\[6\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-ITIS-6)[\[14\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-Grandtner2005-14)[\[15\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-15) or forms.[\[16\]](https://en.m.wikipedia.org/wiki/Yucca_brevifolia#cite_note-Egglid2001-16)
##

11
posts/mauritius.md Normal file
View File

@@ -0,0 +1,11 @@
---
title: The hidden paradise
author: Father John Misty
date: '2019-07-08T16:05:29.000Z'
hero_image: /john-o-nolan-mauritius.jpg
---
**Juniperus scopulorum**, the Rocky Mountain juniper, is a species of juniper native to western North America, in Canada in British Columbia and southwest Alberta, in the United States from Washington east to North Dakota, south to Arizona and also locally western Texas, and northernmost Mexico from Sonora east to Coahuila. It grows at altitudes of 5002,700 metres (1,6008,900 ft) on dry soils, often together with other juniper species. "Scopulorum" means "of the mountains.
![Mauritius Drone Shot](../julia-joppien.jpg)
Chicharrones kinfolk tumblr narwhal venmo. Iceland cloud bread 8-bit, hashtag single-origin coffee keffiyeh drinking vinegar cray banjo four dollar toast bespoke tbh live-edge celiac. YOLO dreamcatcher hot chicken selvage portland XOXO, single-origin coffee sustainable mustache thundercats fixie pour-over hexagon irony deep v. Farm-to-table ennui mixtape marfa raw denim austin hell of keffiyeh chia prism ethical. Polaroid biodiesel everyday carry VHS hot chicken chartreuse typewriter messenger bag. Cloud bread truffaut street art jean shorts chia.

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="92" height="32">
<g fill="none" fill-rule="evenodd">
<path fill="#1374EF" fill-rule="nonzero" d="M0 4c0-2.21 1.75-4 3.9-4h84.2C90.25 0 92 1.79 92 4v24c0 2.21-1.75 4-3.9 4H3.9A3.95 3.95 0 0 1 0 28V4z"/>
<path fill="#1269D3" d="M32 32V0h1v32z"/>
<path fill="#FFF" d="M16 10l-.41.76-5.2 9.53L10 21h12l-.39-.71-5.19-9.53L16 10zm51.61 10.59h-1.35v-9.27h1.35v9.27zm-26.26 0v-8.84h3.28c2.7 0 4.27 1.61 4.27 4.4 0 2.8-1.56 4.44-4.27 4.44h-3.28zm3.12-7.66h-1.71v6.47h1.71c1.9 0 3-1.18 3-3.24 0-2.04-1.12-3.23-3-3.23zm9.05 6.7c.82 0 1.38-.29 1.63-.83h1.3c-.29 1.18-1.4 1.91-2.96 1.91-1.97 0-3.17-1.31-3.17-3.44 0-2.11 1.23-3.47 3.16-3.47 1.9 0 3.06 1.27 3.06 3.36v.45H51.7v.06c.04 1.2.74 1.97 1.82 1.97zm1.64-2.97c-.03-1.08-.69-1.78-1.69-1.78s-1.7.7-1.77 1.78h3.46zm6.56-2.84a2.4 2.4 0 0 0-2.15 1.22h-.1v-1.1h-1.3v8.86h1.35v-3.22h.1c.36.7 1.14 1.12 2.11 1.12 1.73 0 2.83-1.34 2.83-3.44 0-2.11-1.1-3.44-2.84-3.44zm-.39 5.75c-1.13 0-1.84-.89-1.84-2.31 0-1.43.71-2.32 1.85-2.32 1.15 0 1.83.87 1.83 2.32 0 1.45-.68 2.31-1.84 2.31zm11.2 1.14c2.01 0 3.24-1.3 3.24-3.45 0-2.15-1.24-3.46-3.23-3.46-2 0-3.24 1.31-3.24 3.46s1.23 3.45 3.24 3.45zm0-1.12c-1.17 0-1.83-.85-1.83-2.33s.66-2.34 1.84-2.34c1.17 0 1.84.86 1.84 2.34s-.67 2.33-1.84 2.33zm7.91 1.3c-.58 1.6-1.23 2.11-2.63 2.11-.1 0-.43-.01-.56-.03v-1.08c.11.02.32.03.44.03.65 0 1.01-.27 1.24-.97l.1-.35-2.48-6.67h1.48l1.72 5.33h.1l1.71-5.33H83l-2.56 6.96z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="207px" height="124px" viewBox="0 0 207 124" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 51.2 (57519) - http://www.bohemiancoding.com/sketch -->
<title>next-black</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Black-Next.js" transform="translate(-247.000000, -138.000000)" fill="#000000" fill-rule="nonzero">
<g id="next-black" transform="translate(247.000000, 138.000000)">
<g id="EXT-+-Type-something">
<path d="M48.9421964,32.6320058 L87.9011585,32.6320058 L87.9011585,35.7136421 L52.5134345,35.7136421 L52.5134345,58.9070103 L85.7908813,58.9070103 L85.7908813,61.9886466 L52.5134345,61.9886466 L52.5134345,87.4526941 L88.306981,87.4526941 L88.306981,90.5343303 L48.9421964,90.5343303 L48.9421964,32.6320058 Z M91.3912326,32.6320058 L95.5306221,32.6320058 L113.8738,58.0960534 L132.622801,32.6320058 L158.124498,0.286809811 L116.22757,60.7722112 L137.817329,90.5343303 L133.51561,90.5343303 L113.8738,63.4483691 L94.1508254,90.5343303 L89.9302715,90.5343303 L111.682358,60.7722112 L91.3912326,32.6320058 Z M139.359455,35.713642 L139.359455,32.6320058 L183.756439,32.6320058 L183.756439,35.7136421 L163.302983,35.7136421 L163.302983,90.5343303 L159.731745,90.5343303 L159.731745,35.7136421 L139.359455,35.713642 Z" id="EXT"></path>
<polygon id="Type-something" points="0.202923647 32.6320058 4.66697141 32.6320058 66.2235778 124.303087 40.785176 90.5343303 3.93649086 37.0111732 3.77416185 90.5343303 0.202923647 90.5343303"></polygon>
</g>
<path d="M183.396622,86.5227221 C184.134938,86.5227221 184.673474,85.9601075 184.673474,85.233037 C184.673474,84.5059658 184.134938,83.9433513 183.396622,83.9433513 C182.666993,83.9433513 182.11977,84.5059658 182.11977,85.233037 C182.11977,85.9601075 182.666993,86.5227221 183.396622,86.5227221 Z M186.905793,83.1297235 C186.905793,85.2763149 188.460599,86.678523 190.727662,86.678523 C193.142388,86.678523 194.601647,85.233037 194.601647,82.7229099 L194.601647,73.8855335 L192.655968,73.8855335 L192.655968,82.7142542 C192.655968,84.1078073 191.952397,84.8521899 190.710289,84.8521899 C189.598473,84.8521899 188.842785,84.1597409 188.816727,83.1297235 L186.905793,83.1297235 Z M197.146664,83.0172011 C197.285642,85.2503478 199.153145,86.678523 201.932686,86.678523 C204.903321,86.678523 206.762139,85.1811034 206.762139,82.792155 C206.762139,80.9138876 205.702439,79.8752151 203.131364,79.2779777 L201.750279,78.9404092 C200.117298,78.5595622 199.457158,78.0488813 199.457158,77.1573541 C199.457158,76.0321243 200.482113,75.296398 202.019547,75.296398 C203.478806,75.296398 204.48639,76.0148135 204.668797,77.1660091 L206.562359,77.1660091 C206.44944,75.0626962 204.590622,73.5825873 202.045605,73.5825873 C199.309495,73.5825873 197.48542,75.0626962 197.48542,77.2871878 C197.48542,79.1221767 198.519063,80.2127835 200.786126,80.7407758 L202.401734,81.1302779 C204.060773,81.5197807 204.790402,82.091051 204.790402,83.0431676 C204.790402,84.1510859 203.643842,84.9560573 202.08035,84.9560573 C200.403939,84.9560573 199.240006,84.2030196 199.074971,83.0172011 L197.146664,83.0172011 Z" id=".JS"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 KiB

BIN
public/julia-joppien.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

BIN
public/mahkeo-monkey.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

4
public/vercel.svg Normal file
View File

@@ -0,0 +1,4 @@
<svg width="283" height="64" viewBox="0 0 283 64" fill="none"
xmlns="http://www.w3.org/2000/svg">
<path d="M141.04 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM248.72 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.45 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM200.24 34c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10zm82.48-29v46h-9V5h9zM36.95 0L73.9 64H0L36.95 0zm92.38 5l-27.71 48L73.91 5H84.3l17.32 30 17.32-30h10.39zm58.91 12v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10V51h-9V17h9v9.2c0-5.08 5.91-9.2 13.2-9.2z" fill="#000"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

126
styles/Blog.module.css Normal file
View File

@@ -0,0 +1,126 @@
.blog h1 {
margin-bottom: 0.7rem;
}
.blog__hero {
max-height: 300px;
width: 100%;
margin: 0;
overflow: hidden;
}
.blog__hero img {
margin-bottom: 0;
object-fit: cover;
min-height: 100%;
min-width: 100%;
object-position: center;
}
.blog__info {
padding: 1.5rem 1.25rem;
width: 100%;
max-width: 768px;
margin: 0 auto;
}
.blog__info h1 {
margin-bottom: 0.66rem;
}
.blog__info h3 {
margin-bottom: 0;
}
.blog__body {
width: 100%;
padding: 0 1.25rem;
margin: 0 auto;
display: flex;
flex-direction: column;
justify-content: center;
}
.blog__body a {
padding-bottom: 1.5rem;
}
.blog__body:last-child {
margin-bottom: 0;
}
.blog__body h1 h2 h3 h4 h5 h6 p {
font-weight: normal;
}
.blog__body p {
color: inherit;
}
.blog__body ul {
list-style: initial;
}
.blog__body ul ol {
margin-left: 1.25rem;
margin-bottom: 1.25rem;
padding-left: 1.45rem;
}
.blog__footer {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1.5rem 1.25rem;
width: 100%;
max-width: 800px;
margin: 0 auto;
}
.blog__footer h2 {
margin-bottom: 0;
}
.blog__footer a {
display: flex;
justify-content: space-between;
align-items: center;
}
.blog__footer a svg {
width: 20px;
}
@media (min-width: 768px) {
.blog {
display: flex;
flex-direction: column;
}
.blog__body {
max-width: 800px;
padding: 0 2rem;
}
.blog__body span {
width: 100%;
margin: 1.5rem auto;
}
.blog__body ul ol {
margin-left: 1.5rem;
margin-bottom: 1.5rem;
}
.blog__hero {
min-height: 600px;
height: 75vh;
}
.blog__info {
text-align: center;
padding: 2rem 0;
}
.blog__info h1 {
max-width: 500px;
margin: 0 auto 0.66rem auto;
}
.blog__footer {
padding: 2.25rem;
}
}
@media (min-width: 1440px) {
.blog__hero {
height: 70vh;
}
.blog__info {
padding: 3rem 0;
}
.blog__footer {
padding: 2rem 2rem 3rem 2rem;
}
}

View File

@@ -0,0 +1,88 @@
.blog__link {
opacity: 0.7;
}
.blog__link:hover {
opacity: 1;
}
li .blog__link:hover div.hero_image img {
opacity: 0.8;
transition: opacity 0.3s ease;
}
li .blog__link:hover .blog__info h2,
li .blog__link:hover .blog__info h3,
li .blog__link:hover .blog__info p {
transform: translateX(10px);
transition: transform 0.5s ease-out;
}
.hero_image {
width: 100%;
height: 33vh;
overflow: hidden;
background-color: #000;
}
.hero_image img {
object-fit: cover;
opacity: 1;
min-height: 100%;
width: 100%;
transition: opacity 0.3s ease;
}
.blog__info {
display: flex;
flex-direction: column;
justify-content: center;
padding: 1.5rem 1.25rem;
transform: translateX(0px);
transition: transform 0.3s ease-in;
border-bottom: 1px solid #ebebeb;
}
.blog__info h2,
.blog__info h3,
.blog__info p {
transform: translateX(0px);
transition: transform 0.5s ease-out;
}
li .blog__link {
opacity: inherit;
display: flex;
justify-content: center;
flex-direction: column;
min-height: 38vh;
margin-bottom: 0;
}
.blog__info h2 {
margin-bottom: 0.5rem;
}
.blog__info h3 {
margin-bottom: 1rem;
}
.blog__info p {
max-width: 900px;
}
@media (min-width: 768px) {
li .blog__link {
min-height: 250px;
height: 33.333vh;
flex-direction: row;
}
.hero_image {
height: 100%;
}
.hero_image img {
min-width: 100%;
height: 100%;
width: auto;
min-height: 0;
}
.blog__info {
min-width: 70%;
}
}
@media (min-width: 1280px) {
.blog__info {
padding: 3rem;
}
.blog__info h3 {
margin-bottom: 1.2rem;
}
}

32
styles/Header.module.css Normal file
View File

@@ -0,0 +1,32 @@
.nav {
padding: 1.5rem 1.25rem;
border-bottom: 1px solid #ebebeb;
display: flex;
justify-content: space-between;
flex-direction: row;
align-items: center;
}
.nav h1 {
margin-bottom: 0;
}
.nav h1:hover {
cursor: pointer;
}
@media (min-width: 768px) {
.header {
height: 100vh;
position: fixed;
left: 0;
top: 0;
}
.nav {
padding: 2rem;
width: 30vw;
height: 100%;
border-right: 1px solid #ebebeb;
border-bottom: none;
flex-direction: column;
align-items: flex-start;
}
}

116
styles/Home.module.css Normal file
View File

@@ -0,0 +1,116 @@
.container {
padding: 0 2rem;
}
.main {
min-height: 100vh;
padding: 4rem 0;
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.footer {
display: flex;
flex: 1;
padding: 2rem 0;
border-top: 1px solid #eaeaea;
justify-content: center;
align-items: center;
}
.footer a {
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
}
.title a {
color: #0070f3;
text-decoration: none;
}
.title a:hover,
.title a:focus,
.title a:active {
text-decoration: underline;
}
.title {
margin: 0;
line-height: 1.15;
font-size: 4rem;
}
.title,
.description {
text-align: center;
}
.description {
margin: 4rem 0;
line-height: 1.5;
font-size: 1.5rem;
}
.code {
background: #fafafa;
border-radius: 5px;
padding: 0.75rem;
font-size: 1.1rem;
font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
Bitstream Vera Sans Mono, Courier New, monospace;
}
.grid {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
max-width: 800px;
}
.card {
margin: 1rem;
padding: 1.5rem;
text-align: left;
color: inherit;
text-decoration: none;
border: 1px solid #eaeaea;
border-radius: 10px;
transition: color 0.15s ease, border-color 0.15s ease;
max-width: 300px;
}
.card:hover,
.card:focus,
.card:active {
color: #0070f3;
border-color: #0070f3;
}
.card h2 {
margin: 0 0 1rem 0;
font-size: 1.5rem;
}
.card p {
margin: 0;
font-size: 1.25rem;
line-height: 1.5;
}
.logo {
height: 1em;
margin-left: 0.5rem;
}
@media (max-width: 600px) {
.grid {
width: 100%;
flex-direction: column;
}
}

16
styles/Info.module.css Normal file
View File

@@ -0,0 +1,16 @@
.info_blurb {
max-width: 800px;
padding: 1.5rem 1.25rem;
}
@media (min-width: 768px) {
.info_blurb {
padding: 2rem;
}
}
@media (min-width: 1440px) {
.info_blurb {
padding: 3rem;
}
}

22
styles/Layout.module.css Normal file
View File

@@ -0,0 +1,22 @@
.layout {
overflow-x: hidden;
display: flex;
flex-direction: column;
min-height: 100vh;
}
.layout .info_page {
color: #ebebeb;
}
.content {
flex-grow: 1;
}
@media (min-width: 768px) {
.layout {
display: block;
}
.content {
flex-grow: none;
width: 70vw;
margin-left: 30vw;
}
}

204
styles/globals.css Normal file
View File

@@ -0,0 +1,204 @@
* {
box-sizing: inherit;
}
html {
box-sizing: border-box;
overflow-y: scroll;
}
body {
margin: 0;
overflow-x: hidden;
color: #000;
font-size: 16px;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
a {
text-decoration: none;
color: inherit;
transition: opacity 0.2s ease;
}
a:hover {
transition: opacity 0.2s ease;
opacity: 0.5;
text-decoration-color: inherit;
}
ul {
list-style: none;
margin: 0;
padding-bottom: 0;
padding-left: 0;
padding-right: 0;
padding-top: 0;
list-style-position: outside;
list-style-image: none;
}
ol {
margin: 0;
padding-bottom: 0;
padding-left: 0;
padding-right: 0;
padding-top: 0;
list-style-position: outside;
list-style-image: none;
}
ul, ol, p {
margin-bottom: 1.45rem;
}
img {
max-width: 100%;
}
img, figure, table, fieldset {
margin-left: 0;
margin-right: 0;
margin-top: 0;
padding-bottom: 0;
padding-left: 0;
padding-right: 0;
padding-top: 0;
margin-bottom: 1.45rem;
}
pre {
margin-left: 0;
margin-right: 0;
margin-top: 0;
margin-bottom: 1.45rem;
font-size: 0.85rem;
line-height: 1.42;
background: hsla(0, 0%, 0%, 0.04);
border-radius: 3px;
overflow: auto;
word-wrap: normal;
padding: 1.45rem;
}
table {
font-size: 1rem;
line-height: 1.45rem;
border-collapse: collapse;
width: 100%;
}
blockquote {
margin-left: 1.45rem;
margin-right: 1.45rem;
margin-top: 0;
padding-bottom: 0;
padding-left: 0;
padding-right: 0;
padding-top: 0;
margin-bottom: 1.45rem;
}
strong {
font-weight: bold;
}
li {
margin-bottom: calc(1.45rem / 2);
}
ol li {
padding-left: 0;
}
ul li {
padding-left: 0;
}
li > ol {
margin-left: 1.45rem;
margin-bottom: calc(1.45rem / 2);
margin-top: calc(1.45rem / 2);
}
li > ul {
margin-left: 1.45rem;
margin-bottom: calc(1.45rem / 2);
margin-top: calc(1.45rem / 2);
}
blockquote *:last-child {
margin-bottom: 0;
}
li *:last-child {
margin-bottom: 0;
}
p *:last-child {
margin-bottom: 0;
}
li > p {
margin-bottom: calc(1.45rem / 2);
}
code {
font-size: 0.85rem;
line-height: 1.45rem;
}
h1,
h2,
h3,
h4,
h5,
h6,
p {
margin-left: 0;
margin-right: 0;
margin-top: 0;
padding-bottom: 0;
padding-left: 0;
padding-right: 0;
padding-top: 0;
margin-bottom: 1.45rem;
color: inherit;
text-rendering: optimizeLegibility;
}
h1,
h2 {
font-weight: 500;
}
h1 {
font-size: 2rem;
letter-spacing: -1px;
line-height: 1.1875;
}
h2 {
font-size: 1.7rem;
letter-spacing: -0.75px;
line-height: 1.2;
}
h3 {
font-size: 1.2rem;
letter-spacing: -0.5px;
line-height: 1.1875;
color: #a0a0a0;
font-weight: normal;
}
p {
font-size: 1.2rem;
letter-spacing: -0.5px;
line-height: 1.5;
color: #464646;
}
@media (min-width: 1280px) {
h1 {
font-size: 2rem;
letter-spacing: -1px;
line-height: 1.1875;
}
h2 {
font-size: 1.5rem;
letter-spacing: -0.75px;
line-height: 1.1667;
}
h3 {
font-size: 1rem;
letter-spacing: -0.5px;
line-height: 1.1875;
color: #a0a0a0;
font-weight: normal;
}
p {
line-height: 1.4375;
}
}

2297
yarn.lock Normal file

File diff suppressed because it is too large Load Diff