1
0
Fork 0

migrate to CSS modules

This commit is contained in:
Matthias Kretschmann 2021-03-04 01:20:39 +01:00
parent 5c34fabd23
commit 5e11ba6263
Signed by: m
GPG Key ID: 606EEEF3C479A91F
158 changed files with 2672 additions and 4345 deletions

View File

@ -1,4 +1,4 @@
import './src/styles/global.scss'
import './src/global/global.css'
import wrapPageElementWithLayout from './src/helpers/wrapPageElement'
export const wrapPageElement = wrapPageElementWithLayout

View File

@ -86,14 +86,6 @@ module.exports = {
]
}
},
{
resolve: 'gatsby-plugin-sass',
options: {
sassOptions: {
includePaths: [`${__dirname}/node_modules`, `${__dirname}/src/styles`]
}
}
},
{
resolve: 'gatsby-plugin-svgr',
options: {

1370
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -15,9 +15,9 @@
"copy": "cp -R content/media/ public",
"lint": "run-p --continue-on-error lint:js lint:css lint:md",
"lint:js": "eslint --ignore-path .gitignore --ext .js,.jsx,.ts,.tsx .",
"lint:css": "stylelint 'src/**/*.{css,scss}'",
"lint:css": "stylelint 'src/**/*.css'",
"lint:md": "markdownlint './**/*.{md,markdown}' --ignore './{node_modules,public,.cache,.git,coverage}/**/*'",
"format": "prettier --ignore-path .gitignore --write '**/*.{js,jsx,ts,tsx,md,json,css,scss}'",
"format": "prettier --ignore-path .gitignore --write '**/*.{js,jsx,ts,tsx,md,json,css}'",
"tsc": "tsc --noEmit",
"deploy": "./scripts/deploy-s3.sh",
"new": "ts-node ./scripts/new.ts"
@ -51,7 +51,6 @@
"gatsby-plugin-meta-redirect": "^1.1.1",
"gatsby-plugin-offline": "^3.10.2",
"gatsby-plugin-react-helmet": "^3.10.0",
"gatsby-plugin-sass": "^3.2.0",
"gatsby-plugin-sharp": "^2.14.3",
"gatsby-plugin-sitemap": "^2.12.0",
"gatsby-plugin-svgr": "^2.1.0",
@ -105,7 +104,6 @@
"@welldone-software/why-did-you-render": "^6.0.5",
"eslint": "^7.21.0",
"eslint-config-prettier": "^8.1.0",
"eslint-loader": "^4.0.2",
"eslint-plugin-graphql": "^4.0.0",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-prettier": "^3.3.1",
@ -117,7 +115,6 @@
"jest": "^26.6.3",
"markdownlint-cli": "^0.26.0",
"node-iptc": "^1.0.5",
"node-sass": "^5.0.0",
"npm-run-all": "^4.1.5",
"ora": "^5.3.0",
"prettier": "^2.2.1",

View File

@ -6,6 +6,7 @@ export interface ImageProps {
fixed?: FixedObject
alt?: string
original?: { src: string }
className?: string
}
export interface ImageNode {

View File

@ -0,0 +1,44 @@
.content {
padding: 0 var(--spacer);
width: 100%;
max-width: var(--maxWidthContent);
margin-left: auto;
margin-right: auto;
}
/* topbar and footer as fixed
site background
///////////////////////////////////// */
.document {
width: 100%;
padding-top: var(--spacer);
background-color: var(--body-background-color);
border-top: 1px solid var(--border-color);
border-bottom: 1px solid var(--border-color);
padding-bottom: calc(var(--spacer) * 2);
transform: translate3d(0, 0, 0);
transition: 0.4s var(--easing);
transition-property: transform, background;
}
:global(.has-menu-open) .document {
transform: translate3d(0, calc(var(--spacer) * 3.5), 0);
}
@media (min-width: 60rem) {
.document {
padding-top: calc(var(--spacer) * 2);
}
}
@media (min-width: 40rem) and (min-height: 500px) {
.document {
margin-top: calc(var(--spacer) * 2.5);
/* height of footer */
margin-bottom: calc(var(--spacer) * 18);
position: relative;
z-index: 2;
min-height: 500px;
}
}

View File

@ -1,61 +0,0 @@
@import 'variables';
@import 'mixins';
#___gatsby {
// display: flex;
// min-height: 100vh;
// flex-direction: column;
position: relative;
}
.content {
padding: 0 $spacer / $line-height;
width: 100%;
@media (min-width: $screen-sm) {
padding: 0 ($spacer * 2);
}
}
// topbar and footer as fixed
// site background
/////////////////////////////////////
.document {
width: 100%;
padding-top: $spacer;
background-color: $body-background-color;
border-top: 1px solid rgba(255, 255, 255, 0.7);
border-bottom: 1px solid rgba(255, 255, 255, 0.7);
padding-bottom: $spacer * 2;
box-shadow: 0 1px 4px rgba($brand-main, 0.1),
0 -1px 4px rgba($brand-main, 0.2);
transform: translate3d(0, 0, 0);
transition: 0.4s $easing;
transition-property: transform, background;
:global(.has-menu-open) & {
transform: translate3d(0, ($spacer * 3.5), 0);
}
:global(.dark) & {
background-color: $body-background-color--dark;
color: $text-color--dark;
border-top-color: darken($brand-grey, 15%);
border-bottom-color: darken($body-background-color--dark, 3%);
box-shadow: 0 1px 8px rgba(darken($brand-main, 15%), 0.1),
0 -1px 4px darken($brand-main, 15%);
}
@media (min-width: $screen-md) {
padding-top: $spacer * 2;
}
@media (min-width: $screen-sm) and (min-height: 500px) {
margin-top: $spacer * 2.65;
margin-bottom: $spacer * 18; // height of footer
position: relative;
z-index: 2;
min-height: 500px;
}
}

View File

@ -1,9 +1,8 @@
import React, { ReactElement } from 'react'
import Container from './atoms/Container'
import Typekit from './atoms/Typekit'
import Header from './organisms/Header'
import Footer from './organisms/Footer'
import styles from './Layout.module.scss'
import styles from './Layout.module.css'
// if (process.env.NODE_ENV !== 'production') {
// // eslint-disable-next-line
@ -18,9 +17,7 @@ export default function Layout({ children }: { children: any }): ReactElement {
<Header />
<main className={styles.document} id="document">
<div className={styles.content}>
<Container>{children}</Container>
</div>
<div className={styles.content}>{children}</div>
</main>
<Footer />

View File

@ -0,0 +1,11 @@
.breakout {
margin-left: calc(-50vw + 50%);
margin-right: calc(-50vw + 50%);
}
@media (min-width: 70rem) {
.breakout {
margin-left: -7rem;
margin-right: -7rem;
}
}

View File

@ -0,0 +1,88 @@
.title {
margin-top: calc(var(--spacer) * 3);
margin-bottom: 0;
}
.content {
padding-top: var(--spacer);
padding-left: calc(var(--spacer) / 2);
margin-left: calc(var(--spacer) / 2);
border-left: 1px solid var(--border-color);
}
.content h2,
.content h3,
.content h4 {
position: relative;
margin-bottom: calc(var(--spacer) / 4);
}
.content h2::before,
.content h3::before,
.content h4::before {
content: '';
width: 0.5rem;
height: 0.5rem;
border-radius: 50%;
display: inline-block;
background: var(--color-headings);
position: absolute;
left: -1.275rem;
top: calc(var(--font-size-large) / 3);
}
.content h2 + blockquote,
.content h3 + blockquote,
.content h4 + blockquote {
padding-left: 0;
font-size: var(--font-size-small);
}
.content h2 + blockquote::before,
.content h3 + blockquote::before,
.content h4 + blockquote::before {
display: none;
}
.content h2,
.content h3 {
font-size: var(--font-size-large);
background: none;
padding: 0;
margin-left: 0;
margin-top: calc(var(--spacer) / 8);
margin-bottom: calc(var(--spacer) / var(--line-height));
}
.content ul {
font-size: var(--font-size-small);
margin-left: calc(var(--spacer) / 8);
}
.content ul li {
margin-bottom: calc(var(--spacer) / 8);
}
.source {
font-size: var(--font-size-mini);
font-family: var(--font-family-base);
font-weight: var(--font-weight-base);
padding-bottom: calc(var(--spacer) / 2);
}
.source,
.source a {
color: var(--text-color-light);
}
.source a {
margin-left: calc(var(--spacer) / 8);
}
.source code {
font-size: calc(var(--font-size-mini) * 0.9);
}
.source a:hover {
color: var(--link-color);
}

View File

@ -1,92 +0,0 @@
@import 'variables';
.title {
margin-top: $spacer * 3;
margin-bottom: 0;
}
.content {
padding-top: $spacer;
padding-left: $spacer / 2;
margin-left: $spacer / 2;
border-left: 1px solid $brand-grey-dimmed;
:global(.dark) & {
border-left-color: rgba($color-headings--dark, 0.2);
}
h2,
h3,
h4 {
position: relative;
margin-bottom: $spacer / 4;
&::before {
content: '';
width: 0.5rem;
height: 0.5rem;
border-radius: 50%;
display: inline-block;
background: $color-headings;
position: absolute;
left: -($spacer / 1.5);
top: $font-size-large / 3;
:global(.dark) & {
background: $color-headings--dark;
}
}
+ blockquote {
padding-left: 0;
font-size: $font-size-small;
&::before {
display: none;
}
}
}
h2,
h3 {
font-size: $font-size-large;
background: none;
padding: 0;
margin-left: 0;
margin-top: $spacer / 8;
margin-bottom: $spacer / $line-height;
}
ul {
font-size: $font-size-small;
margin-left: $spacer / 8;
li {
margin-bottom: $spacer / 8;
}
}
}
.source {
font-size: $font-size-mini;
font-family: $font-family-base;
font-weight: $font-weight-base;
padding-bottom: $spacer / 2;
&,
a {
color: $brand-grey-light;
}
a {
margin-left: $spacer / 8;
code {
font-size: ($font-size-mini * 0.9);
}
&:hover {
color: $link-color;
}
}
}

View File

@ -2,7 +2,7 @@ import React, { ReactElement } from 'react'
import { graphql, useStaticQuery } from 'gatsby'
import remark from 'remark'
import remarkReact from 'remark-react'
import styles from './Changelog.module.scss'
import styles from './Changelog.module.css'
import { GitHub, GitHubRepo } from '../../@types/GitHub'
export function PureChangelog({
@ -35,15 +35,13 @@ export function PureChangelog({
Changelog
</h2>
<div className={styles.content}>
<p className={styles.source}>
<em>
sourced from{' '}
<a href={filePathUrl}>
<code>{filePathDisplay}</code>
</a>
</em>
</p>
{changelogHtml}
<p className={styles.source}>
sourced from{' '}
<a href={filePathUrl}>
<code>{filePathDisplay}</code>
</a>
</p>
</div>
</div>
)

View File

@ -1,5 +1,5 @@
import React, { ReactElement } from 'react'
import styles from './Container.module.scss'
import styles from './Container.module.css'
export default function Container({
children

View File

@ -0,0 +1,30 @@
.button {
margin: 0;
position: absolute;
right: 0;
top: 0;
bottom: 0;
border: 0;
box-shadow: none;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
background: rgba(var(--brand-grey), 0.3);
padding: calc(var(--spacer) / 3);
}
.button svg {
stroke: var(--text-color-light);
transition: 0.15s ease-out;
}
.button:hover svg {
stroke: var(--text-color-dimmed);
}
.copied {
background: green;
}
.copied svg {
stroke: var(--text-color-dimmed);
}

View File

@ -1,35 +0,0 @@
@import 'variables';
.button {
margin: 0;
position: absolute;
right: 0;
top: 0;
bottom: 0;
border: 0;
box-shadow: none;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
background: rgba($brand-grey, 0.3);
padding: $spacer / 3;
svg {
stroke: $brand-grey-light;
transition: 0.15s ease-out;
}
&:hover {
svg {
stroke: $brand-grey-dimmed;
}
}
}
.copied {
background: green;
// stylelint-disable-next-line no-descending-specificity
svg {
stroke: $brand-grey-dimmed;
}
}

View File

@ -1,6 +1,6 @@
import React, { ReactElement } from 'react'
import loadable from '@loadable/component'
import styles from './Copy.module.scss'
import styles from './Copy.module.css'
import Icon from './Icon'
const Clipboard = loadable(() => import('react-clipboard.js'))

View File

@ -0,0 +1,18 @@
.divider {
position: relative;
border-bottom: 1px dashed var(--border-color);
}
.divider::before {
content: '';
position: absolute;
left: 0;
height: 1px;
bottom: -2px;
width: 100%;
border-bottom: 1px dashed #fff;
}
:global(.dark) .divider::before {
border-bottom-color: var(--brand-grey);
}

View File

@ -0,0 +1,73 @@
.exif {
margin-top: -3rem;
margin-bottom: calc(var(--spacer) * 2);
}
.data {
font-size: var(--font-size-mini);
color: var(--text-color-light);
display: flex;
flex-wrap: wrap;
justify-content: center;
text-align: center;
}
.data span {
display: block;
flex: 1 1 20%;
white-space: nowrap;
padding: var(--spacer);
border-bottom: 1px dashed var(--text-color-dimmed);
}
.data span svg {
display: block;
margin-bottom: calc(var(--spacer) / 8);
opacity: 0.65;
}
.data span:first-child {
flex-basis: 100%;
}
@media (min-width: 40rem) {
.data {
margin-bottom: 0;
font-size: var(--font-size-small);
}
.data span {
border-left: 1px dashed var(--text-color-dimmed);
border-bottom: 0;
}
.data span,
.data span:first-child {
flex: 1 1 auto;
}
.data span:first-child {
border-left: 0;
}
}
.map {
composes: breakout from './Breakout.module.css';
composes: frame from './Image.module.css';
height: 180px;
margin-top: calc(var(--spacer) * 2);
}
@media (min-width: 40rem) {
.map {
margin-top: 0;
}
}
.map img {
border-radius: 0 !important;
}
.map > div:first-child {
background: none !important;
}

View File

@ -1,84 +0,0 @@
@import 'variables';
@import 'mixins';
.exif {
margin-top: -($spacer * $line-height);
margin-bottom: $spacer * 2;
}
.data {
@include breakoutviewport;
font-size: $font-size-mini;
color: $brand-grey-light;
display: flex;
flex-wrap: wrap;
justify-content: center;
text-align: center;
span {
display: block;
flex: 1 1 20%;
white-space: nowrap;
padding: $spacer;
border-bottom: 1px dashed $brand-grey-dimmed;
svg {
display: block;
margin-bottom: $spacer / 8;
opacity: 0.65;
}
&:first-child {
flex-basis: 100%;
}
:global(.dark) & {
border-bottom-color: rgba($brand-grey, 0.6);
}
}
@media (min-width: $screen-sm) {
margin-bottom: 0;
font-size: $font-size-small;
span {
border-left: 1px dashed $brand-grey-dimmed;
border-bottom: 0;
&,
&:first-child {
flex: 1 1 auto;
}
&:first-child {
border-left: 0;
}
:global(.dark) & {
border-left-color: rgba($brand-grey, 0.6);
}
}
}
}
.map {
@include breakoutviewport;
@include media-frame;
overflow: hidden;
height: 220px;
margin-top: $spacer * 2;
@media (min-width: $screen-sm) {
margin-top: 0;
}
img {
border-radius: 0 !important;
}
> div:first-child {
background: none !important;
}
}

View File

@ -1,6 +1,6 @@
import React, { ReactElement } from 'react'
import ExifMap from './ExifMap'
import styles from './Exif.module.scss'
import styles from './Exif.module.css'
import { Exif as ExifMeta } from '../../@types/Image'
import Icon from './Icon'

View File

@ -40,7 +40,7 @@ export default function ExifMap({
<Map
center={[latitude, longitude]}
zoom={zoom}
height={220}
height={180}
dprs={[1, 2]}
attribution={false}
provider={isDarkMode ? providers['dark'] : providers['light']}

View File

@ -0,0 +1,70 @@
.hamburger {
width: 24px;
height: 24px;
display: inline-block;
position: relative;
transform: rotate(0deg);
cursor: pointer;
margin-top: calc(var(--spacer) / 2);
}
.hamburgerLine {
display: block;
position: absolute;
height: 1px;
width: 100%;
border-bottom: var(--stroke-width) solid var(--text-color-light);
opacity: 1;
left: 0;
transform: rotate(0deg);
transition: 0.2s var(--easing);
}
.hamburgerLine::nth-child(1) {
top: 0;
transform-origin: left center;
}
.hamburgerLine::nth-child(2) {
top: 7px;
transform-origin: left center;
}
.hamburgerLine::nth-child(3) {
top: 14px;
transform-origin: left center;
}
/* open state */
:global(.has-menu-open) .hamburgerLine::nth-child(1) {
transform: rotate(45deg);
top: -1px;
}
:global(.has-menu-open) .hamburgerLine::nth-child(2) {
width: 0%;
opacity: 0;
}
:global(.has-menu-open) .hamburgerLine::nth-child(3) {
transform: rotate(-45deg);
top: 16px;
}
.hamburgerButton {
padding: calc(var(--spacer) / 2);
vertical-align: middle;
display: inline-block;
margin: 0;
margin-right: -1rem;
}
.hamburgerButton:hover,
.hamburgerButton:focus {
outline: 0;
}
.hamburgerButton:hover .hamburgerLine,
.hamburgerButton:focus .hamburgerLine {
border-color: var(--link-color);
}

View File

@ -1,75 +0,0 @@
@import 'variables';
@import 'mixins';
.hamburger {
width: 24px;
height: 24px;
display: inline-block;
position: relative;
transform: rotate(0deg);
cursor: pointer;
margin-top: $spacer / 2;
}
.hamburgerLine {
@include transition;
display: block;
position: absolute;
height: 1px;
width: 100%;
border-bottom: $stroke-width solid $brand-grey-light;
opacity: 1;
left: 0;
transform: rotate(0deg);
&:nth-child(1) {
top: 0;
transform-origin: left center;
}
&:nth-child(2) {
top: 7px;
transform-origin: left center;
}
&:nth-child(3) {
top: 14px;
transform-origin: left center;
}
// open state
:global(.has-menu-open) & {
&:nth-child(1) {
transform: rotate(45deg);
top: -1px;
}
&:nth-child(2) {
width: 0%;
opacity: 0;
}
&:nth-child(3) {
transform: rotate(-45deg);
top: 16px;
}
}
}
.hamburgerButton {
padding: $spacer / 2;
vertical-align: middle;
display: inline-block;
margin: 0;
margin-right: -($spacer / 2);
&:hover,
&:focus {
outline: 0;
.hamburgerLine {
border-color: $brand-cyan;
}
}
}

View File

@ -1,5 +1,5 @@
import React, { ReactElement } from 'react'
import styles from './Hamburger.module.scss'
import styles from './Hamburger.module.css'
export default function Hamburger({
onClick

View File

@ -1,10 +1,8 @@
@import 'variables';
.icon {
width: 1em;
height: 1em;
stroke: currentColor;
stroke-width: $stroke-width;
stroke-width: var(--stroke-width);
stroke-linecap: round;
stroke-linejoin: round;
fill: none;

View File

@ -27,7 +27,7 @@ import {
import { ReactComponent as Jsonfeed } from '../../images/jsonfeed.svg'
import { ReactComponent as Bitcoin } from '../../images/bitcoin.svg'
import { ReactComponent as Stopwatch } from '../../images/stopwatch.svg'
import styles from './Icon.module.scss'
import styles from './Icon.module.css'
const components: any = {
Download: ArrowDownCircle,

View File

@ -0,0 +1,64 @@
.imageTitle {
font-size: var(--font-size-h3);
font-family: var(--font-family-headings);
line-height: var(--line-height-headings);
font-weight: var(--font-weight-headings);
font-style: normal;
text-align: left;
margin: 0;
position: absolute;
top: 10%;
padding: calc(var(--spacer) / 3) var(--spacer);
background: var(--link-color);
color: #fff !important;
text-shadow: 0 1px 0 #000;
left: 0;
opacity: 0;
transform: translate3d(0, -20px, 0);
transition: 0.2s var(--easing);
}
.frame {
border-top: 2px solid transparent;
border-bottom: 2px solid transparent;
border-radius: var(--border-radius);
overflow: hidden;
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.1), 0 5px 16px rgba(0, 0, 0, 0.05);
}
:global(.dark) .frame {
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 16px rgba(0, 0, 0, 0.1);
}
.image {
composes: frame;
max-width: none;
margin-top: calc(var(--spacer) * var(--line-height));
margin-bottom: calc(var(--spacer) * var(--line-height));
display: block;
position: relative;
transition: 0.2s var(--easing);
}
@media (min-width: 40rem) {
.image {
border: 2px solid transparent;
}
}
/* single photo post teasers */
.image:only-child {
margin-top: 0;
margin-bottom: 0;
}
a:hover .image,
a:focus .image {
border-color: var(--link-color);
}
a:hover .image .imageTitle,
a:focus .image .imageTitle {
opacity: 1;
transform: translate3d(0, 0, 0);
}

View File

@ -1,54 +0,0 @@
@import 'variables';
@import 'mixins';
.imageTitle {
@include transition();
font-size: $font-size-h3;
font-family: $font-family-headings;
line-height: $line-height-headings;
font-weight: $font-weight-headings;
font-style: normal;
text-align: left;
margin: 0;
position: absolute;
top: 10%;
padding: $spacer / 3 $spacer;
background: rgba($link-color, 0.85);
color: #fff !important;
text-shadow: 0 1px 0 #000;
left: 0;
opacity: 0;
transform: translate3d(0, -20px, 0);
}
.image {
@include media-frame;
@include breakoutviewport;
max-width: none;
margin-top: $spacer * $line-height;
margin-bottom: $spacer * $line-height;
display: block;
a & {
position: relative;
display: block;
}
// single photo post teasers
&:only-child {
margin-top: 0;
margin-bottom: 0;
}
a:hover &,
a:focus & {
border-color: $link-color !important;
.imageTitle {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
}

View File

@ -2,16 +2,20 @@ import React, { ReactElement } from 'react'
import { graphql } from 'gatsby'
import Img from 'gatsby-image'
import { ImageProps } from '../../@types/Image'
import styles from './Image.module.scss'
import styles from './Image.module.css'
export const Image = ({
title,
fluid,
fixed,
alt,
original
original,
className
}: ImageProps): ReactElement => (
<figure className={styles.image} data-original={original && original.src}>
<figure
className={`${styles.image} ${className ? className : ''}`}
data-original={original && original.src}
>
<Img backgroundColor="transparent" fluid={fluid} fixed={fixed} alt={alt} />
{title && <figcaption className={styles.imageTitle}>{title}</figcaption>}
</figure>

View File

@ -0,0 +1,32 @@
.input {
display: block;
width: 100%;
padding: var(--padding-base-vertical) var(--padding-base-horizontal);
font-size: var(--input-font-size);
font-weight: var(--input-font-weight);
line-height: var(--line-height);
color: var(--input-color);
background-color: var(--input-bg);
background-image: none;
border: 0;
border-radius: var(--border-radius);
box-shadow: none;
transition: all ease-in-out 0.15s;
appearance: none;
}
.input:focus {
border-color: var(--input-border-focus);
outline: 0;
}
.input[disabled] {
color: var(--text-color-dimmed);
}
.input::-moz-placeholder,
.input::-webkit-input-placeholder,
.input:-ms-input-placeholder {
color: var(--input-color-placeholder);
opacity: 1;
}

View File

@ -1,36 +0,0 @@
@import 'variables';
@import 'mixins';
.input {
display: block;
width: 100%;
padding: $padding-base-vertical $padding-base-horizontal;
font-size: $input-font-size;
font-weight: $input-font-weight;
line-height: $line-height;
color: $input-color;
background-color: $input-bg;
background-image: none; // Reset unusual Firefox-on-Android default style
border: 0;
border-radius: $input-border-radius;
box-shadow: none;
transition: all ease-in-out 0.15s;
appearance: none;
@include placeholder();
:global(.dark) & {
color: $input-color--dark;
background-color: $input-bg--dark;
@include placeholder($input-color-placeholder--dark);
}
&:focus {
border-color: $input-border-focus;
outline: 0;
}
&[disabled] {
color: $brand-grey-dimmed;
}
}

View File

@ -1,5 +1,5 @@
import React, { ReactElement } from 'react'
import styles from './Input.module.scss'
import styles from './Input.module.css'
export default function Input(props: any): ReactElement {
return <input className={styles.input} {...props} />

View File

@ -0,0 +1,17 @@
.qr {
margin-bottom: calc(var(--spacer) / 2);
}
.code {
margin: 0 auto;
position: relative;
padding: 0;
padding-right: 2rem;
width: fit-content;
}
.code code {
padding: calc(var(--spacer) / 2);
font-size: 0.65rem;
text-align: center;
}

View File

@ -1,19 +0,0 @@
@import 'variables';
.qr {
margin-bottom: $spacer / 2;
}
.code {
margin: 0 auto;
position: relative;
padding: 0;
padding-right: 2rem;
width: fit-content;
code {
padding: $spacer / 2;
font-size: 0.65rem;
text-align: center;
}
}

View File

@ -1,6 +1,6 @@
import React, { ReactElement } from 'react'
import { QRCode } from 'react-qr-svg'
import styles from './Qr.module.scss'
import styles from './Qr.module.css'
import Copy from './Copy'
export default function Qr({

View File

@ -0,0 +1,20 @@
.tag {
color: var(--text-color-light);
margin-left: calc(var(--spacer) / 2);
margin-right: calc(var(--spacer) / 2);
margin-bottom: calc(var(--spacer) / 2);
white-space: nowrap;
display: inline-block;
}
.tag::before {
content: '#';
margin-right: 1px;
opacity: 0.65;
}
.count {
font-size: var(--font-size-small);
margin-left: calc(var(--spacer) / 6);
opacity: 0.65;
}

View File

@ -1,22 +0,0 @@
@import 'variables';
.tag {
color: $brand-grey-light;
margin-left: $spacer / 2;
margin-right: $spacer / 2;
margin-bottom: $spacer / 2;
white-space: nowrap;
display: inline-block;
&::before {
content: '#';
margin-right: 1px;
opacity: 0.65;
}
}
.count {
font-size: $font-size-small;
margin-left: $spacer / 6;
opacity: 0.65;
}

View File

@ -1,6 +1,6 @@
import React, { ReactElement } from 'react'
import { Link } from 'gatsby'
import styles from './Tag.module.scss'
import styles from './Tag.module.css'
export default function Tag({
name,

View File

@ -0,0 +1,62 @@
.menu {
composes: divider from '../atoms/Divider.module.css';
margin-top: 0;
padding-top: calc(var(--spacer) / 2);
position: absolute;
top: calc(100% + calc(var(--spacer) / 1.5));
left: 0;
width: 100%;
}
.menu ul {
margin: 0;
padding: 0;
text-align: center;
overflow-x: auto;
overflow-y: hidden;
-webkit-overflow-scrolling: touch;
white-space: nowrap;
}
.menu li {
list-style: none;
display: inline-block;
}
.menu li::before {
display: none;
}
.menu a {
color: var(--text-color);
line-height: 1;
text-transform: uppercase;
margin: 0 calc(var(--spacer) / 4);
font-size: var(--font-size-small);
text-shadow: 0 1px 0 rgba(255 255 255 0.5);
padding: var(--padding-base-horizontal);
display: block;
text-align: center;
}
/* .menu a:hover,
.menu a:focus {
color: var(--link-color-hover);
} */
/*
:global(.dark) & {
color: $text-color--dark;
text-shadow: 0 -1px 0 rgba(#000, 0.5);
&:hover,
&:focus {
color: $link-color-hover;
} */
.menu::-webkit-scrollbar,
.menu::-moz-scrollbar,
.menu::-webkit-scrollbar-thumb,
.menu::-webkit-scrollbar-track {
display: none;
}

View File

@ -1,66 +0,0 @@
@import 'variables';
@import 'mixins';
.menu {
@include divider-top;
margin-top: 0;
padding-top: $spacer / 2;
position: absolute;
top: calc(100% + #{$spacer / 1.5});
left: 0;
width: 100%;
ul {
margin: 0;
padding: 0;
text-align: center;
overflow-x: auto;
overflow-y: hidden;
-webkit-overflow-scrolling: touch;
white-space: nowrap;
}
li {
list-style: none;
display: inline-block;
&::before {
display: none;
}
}
a {
color: $text-color;
line-height: 1;
text-transform: uppercase;
margin: 0 $spacer / 4;
font-size: $font-size-small;
text-shadow: 0 1px 0 rgba(#fff, 0.5);
padding: $padding-base-horizontal;
display: block;
text-align: center;
&:hover,
&:focus {
color: $link-color-hover;
}
:global(.dark) & {
color: $text-color--dark;
text-shadow: 0 -1px 0 rgba(#000, 0.5);
&:hover,
&:focus {
color: $link-color-hover;
}
}
}
&::-webkit-scrollbar,
&::-moz-scrollbar,
&::-webkit-scrollbar-thumb,
&::-webkit-scrollbar-track {
display: none;
}
}

View File

@ -2,7 +2,7 @@ import React, { ReactElement, useState } from 'react'
import { Helmet } from 'react-helmet'
import { Link } from 'gatsby'
import Hamburger from '../atoms/Hamburger'
import styles from './Menu.module.scss'
import styles from './Menu.module.css'
import { useSiteMetadata } from '../../hooks/use-site-metadata'
import { MenuItem } from '../../@types/Site'

View File

@ -0,0 +1,25 @@
.link {
text-align: center;
width: 2rem;
padding: calc(var(--spacer) / 4);
margin-left: calc(var(--spacer) / 4);
margin-right: calc(var(--spacer) / 4);
display: inline-block;
color: var(--text-color-light);
}
.link:first-child {
margin-left: 0;
}
.link:last-child {
margin-right: 0;
}
.link svg {
width: 24px;
height: 24px;
transition: stroke 0.3s ease-in-out;
display: block;
margin: 0 auto;
}

View File

@ -1,27 +0,0 @@
@import 'variables';
.link {
text-align: center;
width: 2rem;
padding: $spacer / 4;
margin-left: $spacer / 4;
margin-right: $spacer / 4;
display: inline-block;
color: $text-color-light;
&:first-child {
margin-left: 0;
}
&:last-child {
margin-right: 0;
}
svg {
width: 24px;
height: 24px;
transition: stroke 0.3s ease-in-out;
display: block;
margin: 0 auto;
}
}

View File

@ -1,6 +1,6 @@
import React, { ReactElement } from 'react'
import Icon from '../atoms/Icon'
import styles from './Networks.module.scss'
import styles from './Networks.module.css'
function NetworkIcon({ link }: { link: string }) {
let IconComp

View File

@ -0,0 +1,43 @@
.pagination {
margin-top: calc(var(--spacer) * 3);
margin-bottom: var(--spacer);
display: flex;
justify-content: center;
}
.number {
text-align: center;
padding: calc(var(--spacer) / 6) calc(var(--spacer) / 2);
border: 1px solid var(--text-color-dimmed);
font-variant-numeric: lining-nums;
margin-left: -1px;
display: flex;
align-items: center;
justify-content: center;
min-width: 2.5rem;
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8);
color: var(--text-color);
}
.number:hover,
.number:focus {
background: rgba(255, 255, 255, 0.1);
}
.number:first-child {
border-top-left-radius: var(--border-radius);
border-bottom-left-radius: var(--border-radius);
}
.number:last-child {
border-top-right-radius: var(--border-radius);
border-bottom-right-radius: var(--border-radius);
}
.current {
composes: number;
cursor: default;
pointer-events: none;
color: var(--text-color-dimmed);
background: rgba(255, 255, 255, 0.1);
}

View File

@ -1,58 +0,0 @@
@import 'variables';
@import 'mixins';
.pagination {
@include breakoutviewport;
margin-top: $spacer * 3;
margin-bottom: $spacer;
display: flex;
justify-content: center;
}
.number {
text-align: center;
padding: $spacer / 6 $spacer / 2;
border: 1px solid $brand-grey-dimmed;
font-variant-numeric: lining-nums;
margin-left: -1px;
display: flex;
align-items: center;
justify-content: center;
min-width: 2.5rem;
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8);
color: $brand-grey;
:global(.dark) & {
color: $brand-grey-dimmed;
border-color: darken($body-background-color--dark, 5%);
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.1);
}
&:hover,
&:focus {
background: rgba(255, 255, 255, 0.1);
}
&:first-child {
border-top-left-radius: $border-radius;
border-bottom-left-radius: $border-radius;
}
&:last-child {
border-top-right-radius: $border-radius;
border-bottom-right-radius: $border-radius;
}
}
.current {
composes: number;
cursor: default;
pointer-events: none;
color: $brand-grey-dimmed;
background: rgba(255, 255, 255, 0.1);
:global(.dark) & {
color: $brand-grey-light;
}
}

View File

@ -1,6 +1,6 @@
import React, { ReactElement } from 'react'
import { Link } from 'gatsby'
import styles from './Pagination.module.scss'
import styles from './Pagination.module.css'
import shortid from 'shortid'
import { PageContext } from '../../@types/Post'
import Icon from '../atoms/Icon'

View File

@ -0,0 +1,6 @@
.time {
font-style: italic;
font-size: var(--font-size-small);
color: var(--text-color-light);
margin-bottom: calc(var(--spacer) / var(--line-height));
}

View File

@ -1,8 +0,0 @@
@import 'variables';
.time {
font-style: italic;
font-size: $font-size-small;
color: $text-color-light;
margin-bottom: $spacer / $line-height;
}

View File

@ -1,6 +1,6 @@
import React, { ReactElement } from 'react'
import Time from '../atoms/Time'
import styles from './PostDate.module.scss'
import styles from './PostDate.module.css'
export default function PostDate({
date,

View File

@ -1,40 +1,37 @@
@import 'variables';
@import 'mixins';
.title {
padding-left: 0.2rem;
padding-right: 0.2rem;
margin-top: $spacer / 2;
margin-top: calc(var(--spacer) / 3);
margin-bottom: 0;
font-size: $font-size-base;
font-size: var(--font-size-base);
transition: color 0.2s ease-out;
color: $text-color-light;
color: var(--text-color);
}
.post {
display: block;
}
figure {
margin: 0;
}
.post figure {
margin: 0;
}
.time {
font-style: italic;
font-size: $font-size-small;
color: $text-color-light;
font-size: var(--font-size-small);
color: var(--text-color-light);
padding-left: 0.2rem;
padding-right: 0.2rem;
}
.empty {
@include media-frame;
/* @include media-frame; */
display: block;
min-height: 95px;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAACaADAAQAAAABAAAACQAAAAAvQpmhAAAAHElEQVQYGWNgoBL4T8gcggoIGcBA0ASCCmhsBQBhFwX7u70C8QAAAABJRU5ErkJggg==);
a:hover & {
border-color: $link-color;
}
}
a:hover .empty {
border-color: var(--link-color);
}

View File

@ -3,7 +3,7 @@ import { Link, graphql } from 'gatsby'
import { Image } from '../atoms/Image'
import { Post } from '../../@types/Post'
import PostTitle from '../templates/Post/Title'
import styles from './PostTeaser.module.scss'
import styles from './PostTeaser.module.css'
export const postTeaserQuery = graphql`
fragment PostTeaser on MarkdownRemark {

View File

@ -0,0 +1,65 @@
.title {
font-size: var(--font-size-h3);
margin-bottom: var(--spacer);
}
.relatedPosts {
margin-top: -4rem;
}
.relatedPosts ul {
display: grid;
gap: calc(var(--spacer) / 2);
grid-template-columns: repeat(2, 1fr);
padding: 0;
margin: 0;
}
@media (min-width: 40rem) {
.relatedPosts ul {
grid-template-columns: repeat(3, 1fr);
gap: var(--spacer);
}
}
.relatedPosts li {
display: block;
margin: 0;
}
.relatedPosts li::before {
display: none;
}
.relatedPosts figure {
margin: 0;
}
.relatedPosts img {
margin-bottom: 0;
}
.relatedPosts a {
display: block;
}
.relatedPosts a > div {
margin-bottom: 0;
}
.relatedPosts a h4 {
color: var(--text-color-light);
}
.relatedPosts a:hover h4,
.relatedPosts a:focus h4 {
color: var(--link-color);
}
.button {
font-size: var(--font-size-mini);
display: inline-block;
color: var(--text-color-light);
text-transform: uppercase;
margin-left: calc(var(--spacer) / 2);
}

View File

@ -1,72 +0,0 @@
@import 'variables';
@import 'mixins';
.title {
font-size: $font-size-h3;
margin-bottom: $spacer;
}
.relatedPosts {
margin-top: -($spacer * 2);
@media (min-width: $screen-md) {
@include breakoutviewport;
}
ul {
display: grid;
gap: $spacer / 2;
grid-template-columns: repeat(2, 1fr);
padding: 0;
margin: 0;
@media (min-width: $screen-sm) {
grid-template-columns: repeat(3, 1fr);
gap: $spacer;
}
}
li {
display: block;
margin: 0;
&::before {
display: none;
}
}
figure {
margin: 0;
}
img {
margin-bottom: 0;
}
a {
display: block;
> div {
margin-bottom: 0;
}
h4 {
color: $text-color-light;
}
&:hover,
&:focus {
h4 {
color: $link-color;
}
}
}
}
.button {
font-size: $font-size-mini;
display: inline-block;
color: $brand-grey-light;
text-transform: uppercase;
margin-left: $spacer / 2;
}

View File

@ -1,7 +1,7 @@
import React, { ReactElement, useState } from 'react'
import { graphql, useStaticQuery } from 'gatsby'
import PostTeaser from './PostTeaser'
import styles from './RelatedPosts.module.scss'
import styles from './RelatedPosts.module.css'
import { Post, Frontmatter } from '../../@types/Post'
import { PhotoThumb } from '../templates/Photos'

View File

@ -0,0 +1,22 @@
.searchButton {
padding: calc(var(--spacer) / 2);
vertical-align: middle;
display: inline-block;
margin: 0;
margin-right: calc(var(--spacer) / 4);
}
.searchButton:focus {
outline: 0;
}
.searchButton svg {
stroke: var(--text-color-light);
width: 24px;
height: 24px;
}
.searchButton:hover svg,
.searchButton:focus svg {
stroke: var(--link-color);
}

View File

@ -1,32 +0,0 @@
@import 'variables';
.searchButton {
padding: $spacer / 2;
vertical-align: middle;
display: inline-block;
margin: 0;
margin-right: $spacer / 4;
&:focus {
outline: 0;
}
svg {
stroke: $brand-grey-light;
width: 24px;
height: 24px;
}
&:hover,
&:focus {
svg {
stroke: $brand-cyan;
}
}
&:active {
svg {
stroke: darken($brand-cyan, 30%);
}
}
}

View File

@ -1,5 +1,5 @@
import React, { ReactElement } from 'react'
import styles from './SearchButton.module.scss'
import styles from './SearchButton.module.css'
import Icon from '../../atoms/Icon'
const SearchButton = (props: any): ReactElement => (

View File

@ -0,0 +1,20 @@
.searchInput::-webkit-search-cancel-button {
display: none;
}
.searchInputClose {
position: absolute;
right: calc(var(--spacer) / 2);
top: calc(var(--spacer) / 2);
}
.searchInputClose svg {
stroke: var(--brand-grey-light);
width: 24px;
height: 24px;
}
.searchInputClose:hover svg,
.searchInputClose:focus svg {
stroke: var(--link-color);
}

View File

@ -1,28 +0,0 @@
@import 'variables';
.searchInput {
composes: input from '../../atoms/Input.module.scss';
&::-webkit-search-cancel-button {
display: none;
}
}
.searchInputClose {
position: absolute;
right: $spacer / 2;
top: $spacer / 2;
svg {
stroke: $brand-grey-light;
width: 24px;
height: 24px;
}
&:hover,
&:focus {
svg {
stroke: $link-color;
}
}
}

View File

@ -1,7 +1,7 @@
import React, { ReactElement } from 'react'
import Input from '../../atoms/Input'
import Icon from '../../atoms/Icon'
import styles from './SearchInput.module.scss'
import styles from './SearchInput.module.css'
export default function SearchInput({
value,

View File

@ -0,0 +1,71 @@
.searchResults {
position: absolute;
left: 0;
right: 0;
z-index: 10;
top: 0;
bottom: 0;
background: var(--body-background-color);
animation: fadein 0.3s;
overflow: scroll;
-webkit-overflow-scrolling: touch;
height: 91vh;
}
.searchResults ul {
padding: var(--spacer) calc(var(--spacer) / 2);
margin-bottom: 0;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
@media (min-width: 60rem) {
.searchResults ul {
padding-left: 0;
padding-right: 0;
}
}
.searchResults ul li {
display: block;
flex: 0 0 48%;
margin-bottom: var(--spacer);
}
@media (min-width: 40rem) {
.searchResults ul li {
flex-basis: 31%;
}
}
.searchResults ul li::before {
display: none;
}
.searchResults img {
margin-bottom: 0;
}
.searchResults a {
display: block;
}
.searchResults a > div {
margin-bottom: 0;
}
.searchResults a:hover h4,
.searchResults a:focus h4 {
color: var(--link-color);
}
@keyframes fadein {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}

View File

@ -1,79 +0,0 @@
@import 'variables';
@import 'mixins';
.searchResults {
position: absolute;
left: 0;
right: 0;
z-index: 10;
top: 0;
bottom: 0;
background: rgba($body-background-color, 0.95);
backdrop-filter: blur(5px);
animation: fadein 0.3s;
overflow: scroll;
-webkit-overflow-scrolling: touch;
height: 91vh;
:global(.dark) & {
background: rgba($body-background-color--dark, 0.95);
}
ul {
@include breakoutviewport;
padding: $spacer $spacer / 2;
margin-bottom: 0;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
@media (min-width: $screen-md) {
padding-left: 0;
padding-right: 0;
}
li {
display: block;
flex: 0 0 48%;
margin-bottom: $spacer;
@media (min-width: $screen-sm) {
flex-basis: 31%;
}
&::before {
display: none;
}
}
}
img {
margin-bottom: 0;
}
a {
display: block;
> div {
margin-bottom: 0;
}
&:hover,
&:focus {
h4 {
color: $link-color;
}
}
}
}
@keyframes fadein {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}

View File

@ -4,7 +4,7 @@ import { graphql, useStaticQuery } from 'gatsby'
import Container from '../../atoms/Container'
import PostTeaser from '../PostTeaser'
import SearchResultsEmpty from './SearchResultsEmpty'
import styles from './SearchResults.module.scss'
import styles from './SearchResults.module.css'
import { Post } from '../../../@types/Post'
export interface Results {

View File

@ -0,0 +1,33 @@
.empty {
padding-top: 15vh;
display: flex;
justify-content: center;
}
.emptyMessage {
color: var(--text-color-light);
}
.emptyMessageText {
margin-bottom: 0;
position: relative;
}
.emptyMessageText::after {
overflow: hidden;
display: inline-block;
vertical-align: bottom;
animation: ellipsis steps(4, end) 1s infinite;
/* ascii code for the ellipsis character */
content: '\2026';
width: 0;
position: absolute;
left: 101%;
bottom: 0;
}
@keyframes ellipsis {
to {
width: 1rem;
}
}

View File

@ -1,34 +0,0 @@
@import 'variables';
.empty {
padding-top: 15vh;
display: flex;
justify-content: center;
}
.emptyMessage {
color: $brand-grey-light;
}
.emptyMessageText {
margin-bottom: 0;
position: relative;
&::after {
overflow: hidden;
display: inline-block;
vertical-align: bottom;
animation: ellipsis steps(4, end) 1s infinite;
content: '\2026'; // ascii code for the ellipsis character
width: 0;
position: absolute;
left: 101%;
bottom: 0;
}
}
@keyframes ellipsis {
to {
width: 1rem;
}
}

View File

@ -1,5 +1,5 @@
import React, { ReactElement } from 'react'
import styles from './SearchResultsEmpty.module.scss'
import styles from './SearchResultsEmpty.module.css'
import { Results } from './SearchResults'
const SearchResultsEmpty = ({

View File

@ -0,0 +1,46 @@
.search {
position: absolute;
left: calc(var(--spacer) / 2);
right: calc(var(--spacer) / 2);
top: calc(var(--spacer) / 4);
z-index: 10;
}
.search input {
width: 100%;
}
@media (min-width: 40rem) {
.search {
left: 0;
right: 0;
}
}
.appear,
.enter {
opacity: 0.01;
transform: translate3d(0, -100px, 0);
}
.appearActive,
.enterActive {
opacity: 1;
transition: 0.2s ease-out;
transform: translate3d(0, 0, 0);
}
.exit {
opacity: 1;
transform: translate3d(0, 0, 0);
}
.exitActive {
opacity: 0.01;
transition: 0.2s ease-in;
transform: translate3d(0, -100px, 0);
}
:global(.hasSearchOpen) {
overflow: hidden;
}

View File

@ -1,46 +0,0 @@
@import 'variables';
.search {
position: absolute;
left: $spacer / 2;
right: $spacer / 2;
top: $spacer / 4;
z-index: 10;
input {
width: 100%;
}
@media (min-width: $screen-md) {
left: 0;
right: 0;
}
}
.appear,
.enter {
opacity: 0.01;
transform: translate3d(0, -100px, 0);
&.appearActive,
&.enterActive {
opacity: 1;
transition: 0.2s ease-out;
transform: translate3d(0, 0, 0);
}
}
.exit {
opacity: 1;
transform: translate3d(0, 0, 0);
&.exitActive {
opacity: 0.01;
transition: 0.2s ease-in;
transform: translate3d(0, -100px, 0);
}
}
:global(.hasSearchOpen) {
overflow: hidden;
}

View File

@ -4,8 +4,7 @@ import { CSSTransition } from 'react-transition-group'
import SearchInput from './SearchInput'
import SearchButton from './SearchButton'
import SearchResults from './SearchResults'
import styles from './index.module.scss'
import styles from './index.module.css'
export default function Search(): ReactElement {
const [searchOpen, setSearchOpen] = useState(false)

View File

@ -0,0 +1,37 @@
.themeSwitch {
position: relative;
display: inline-block;
vertical-align: middle;
margin-right: calc(var(--spacer) / 4);
}
.themeSwitch svg {
stroke: var(--text-color-light);
width: 24px;
height: 24px;
}
.themeSwitch:hover svg,
.themeSwitch:focus svg {
stroke: var(--link-color);
}
.checkbox {
position: relative;
cursor: pointer;
padding: calc(var(--spacer) / 2);
display: block;
}
/* hide visually */
.checkbox [type='checkbox'],
.checkbox .label {
width: 1px;
height: 1px;
border: 0;
clip: rect(0 0 0 0);
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
}

View File

@ -1,48 +0,0 @@
@import 'variables';
@import 'mixins';
.themeSwitch {
position: relative;
display: inline-block;
vertical-align: middle;
margin-right: $spacer / 4;
svg {
stroke: $brand-grey-light;
width: 24px;
height: 24px;
}
&:hover,
&:focus {
svg {
stroke: $brand-cyan;
}
}
&:active {
svg {
stroke: darken($brand-cyan, 30%);
}
}
}
.checkbox {
position: relative;
cursor: pointer;
padding: $spacer / 2;
display: block;
// hide visually
[type='checkbox'],
.label {
width: 1px;
height: 1px;
border: 0;
clip: rect(0 0 0 0);
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
}
}

View File

@ -1,7 +1,7 @@
import React, { ReactElement } from 'react'
import { Helmet } from 'react-helmet'
import useDarkMode from 'use-dark-mode'
import styles from './ThemeSwitch.module.scss'
import styles from './ThemeSwitch.module.css'
import Icon from '../atoms/Icon'
import { useSiteMetadata } from '../../hooks/use-site-metadata'

View File

@ -0,0 +1,25 @@
.vcard {
margin-bottom: calc(var(--spacer) * 2);
}
.avatar {
/* @include media-frame; */
margin-bottom: calc(var(--spacer) / 3);
}
.avatar,
.avatar img {
border-radius: 50%;
overflow: hidden;
}
.description {
font-size: var(--font-size-h5);
margin-top: 0;
margin-bottom: calc(var(--spacer) / var(--line-height));
}
.description a {
display: block;
}

View File

@ -1,28 +0,0 @@
@import 'variables';
@import 'mixins';
.vcard {
margin-bottom: $spacer * 2;
}
.avatar {
@include media-frame;
margin-bottom: $spacer / 3;
&,
img {
border-radius: 50%;
overflow: hidden;
}
}
.description {
font-size: $font-size-h5;
margin-top: 0;
margin-bottom: ($spacer / $line-height);
a {
display: block;
}
}

View File

@ -2,7 +2,7 @@ import React, { ReactElement } from 'react'
import { graphql, useStaticQuery } from 'gatsby'
import Img from 'gatsby-image'
import IconLinks from './Networks'
import styles from './Vcard.module.scss'
import styles from './Vcard.module.css'
import { useSiteMetadata } from '../../hooks/use-site-metadata'
const query = graphql`

View File

@ -1,10 +1,7 @@
@import 'variables';
@import 'mixins';
.accountWrap {
font-size: $font-size-small;
color: $brand-grey-light;
margin-bottom: $spacer;
font-size: var(--font-size-small);
color: var(--text-color-light);
margin-bottom: var(--spacer);
display: flex;
justify-content: space-between;
}
@ -16,9 +13,9 @@
overflow: hidden;
display: inline-block;
vertical-align: middle;
margin-right: $spacer / 4;
margin-right: calc(var(--spacer) / 4);
}
.balance {
margin-left: $spacer;
margin-left: var(--spacer);
}

View File

@ -2,7 +2,7 @@ import React, { ReactElement, useState, useEffect } from 'react'
import { toDataUrl } from 'ethereum-blockies'
import { formatEther } from '@ethersproject/units'
import useWeb3 from '../../../hooks/use-web3'
import styles from './Account.module.scss'
import styles from './Account.module.css'
export default function Account(): ReactElement {
const { library, account } = useWeb3()

View File

@ -0,0 +1,40 @@
.alert {
font-size: var(--font-size-small);
display: inline-block;
}
.alert:empty {
display: none;
}
.alert::after {
overflow: hidden;
display: inline-block;
vertical-align: bottom;
animation: ellipsis steps(4, end) 1s infinite;
/* ascii code for the ellipsis character */
content: '\2026';
width: 0;
position: absolute;
}
.success {
composes: alert;
color: green;
}
.error {
composes: alert;
color: red;
}
.error::after,
.success::after {
display: none;
}
@keyframes ellipsis {
to {
width: 0.75rem;
}
}

View File

@ -1,49 +0,0 @@
@import 'variables';
@import 'mixins';
.alert {
font-size: $font-size-small;
display: inline-block;
&:empty {
display: none;
}
&::after {
overflow: hidden;
display: inline-block;
vertical-align: bottom;
animation: ellipsis steps(4, end) 1s infinite;
content: '\2026'; // ascii code for the ellipsis character
width: 0;
position: absolute;
}
}
.error {
composes: alert;
color: darken($alert-error, 60%);
:global(.dark) & {
color: darken($alert-error, 40%);
}
&::after {
display: none;
}
}
.success {
composes: alert;
color: darken($alert-success, 60%);
&::after {
display: none;
}
}
@keyframes ellipsis {
to {
width: 0.75rem;
}
}

View File

@ -1,5 +1,5 @@
import React, { ReactElement } from 'react'
import styles from './Alert.module.scss'
import styles from './Alert.module.css'
export function getTransactionMessage(
transactionHash?: string

View File

@ -0,0 +1,12 @@
.conversion {
font-size: var(--font-size-mini);
color: var(--text-color-light);
text-align: left;
margin-top: calc(var(--spacer) / 4);
margin-left: calc(var(--spacer) * 1.4);
animation: fadeIn 0.5s 0.8s ease-out backwards;
}
.conversion span {
margin-left: calc(var(--spacer) / 2);
}

View File

@ -1,14 +0,0 @@
@import 'variables';
.conversion {
font-size: $font-size-mini;
color: $brand-grey-light;
text-align: left;
margin-top: $spacer / 4;
margin-left: $spacer * 1.4;
animation: fadeIn 0.5s 0.8s ease-out backwards;
span {
margin-left: $spacer / 2;
}
}

View File

@ -1,6 +1,6 @@
import React, { useState, useEffect, ReactElement } from 'react'
import fetch from 'node-fetch'
import styles from './Conversion.module.scss'
import styles from './Conversion.module.css'
export async function getFiat(
amount: number

View File

@ -0,0 +1,108 @@
.inputGroup {
max-width: 18rem;
margin: auto;
position: relative;
animation: fadeIn 0.8s ease-out backwards;
}
@media (min-width: 40rem) {
.inputGroup {
display: flex;
flex-wrap: wrap;
}
}
.inputGroup button {
width: 100%;
border-top-left-radius: 0;
border-top-right-radius: 0;
border-color: var(--text-color-light);
}
@media (min-width: 40rem) {
.inputGroup button {
width: 50%;
border-top-right-radius: var(--border-radius);
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-left: 0;
}
}
:global(.dark) .inputGroup button {
border-color: #000;
}
.input {
position: relative;
}
@media (min-width: 40rem) {
.input {
width: 50%;
}
}
.input input {
text-align: center;
border: 1px solid var(--text-color-light);
font-size: var(--font-size-large);
padding: calc(var(--spacer) / 3) calc(var(--spacer) / 3)
calc(var(--spacer) / 3) calc(var(--spacer) * 1.7);
border-bottom: 0;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
@media (min-width: 40rem) {
.input input {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-bottom-left-radius: var(--border-radius);
border-bottom: 1px solid var(--text-color-light);
border-right: 0;
}
}
.input input::-webkit-inner-spin-button {
margin-left: -1rem;
}
:global(.dark) .input input {
border-color: #000;
color: var(--text-color-dimmed);
}
.currency {
position: absolute;
top: 1px;
bottom: 1px;
left: 1px;
font-size: var(--font-size-small);
padding: calc(var(--spacer) / 3);
color: var(--brand-grey-light);
background: var(--brand-light);
border-right: 1px solid var(--text-color-light);
border-top-left-radius: var(--border-radius);
border-bottom-left-radius: var(--border-radius);
display: flex;
align-items: center;
}
:global(.dark) .currency {
border-right-color: #000;
}
.message {
composes: message from './index.module.css';
}
@keyframes fadeIn {
from {
opacity: 0.01;
}
to {
opacity: 1;
}
}

View File

@ -1,103 +0,0 @@
@import 'variables';
@import 'mixins';
.inputGroup {
max-width: 18rem;
margin: auto;
position: relative;
animation: fadeIn 0.8s ease-out backwards;
@media (min-width: $screen-sm) {
display: flex;
flex-wrap: wrap;
}
button {
width: 100%;
border-top-left-radius: 0;
border-top-right-radius: 0;
border-color: lighten($brand-grey-light, 10%);
@media (min-width: $screen-sm) {
width: 50%;
border-top-right-radius: $border-radius;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-left: 0;
}
:global(.dark) & {
border-color: #000;
}
}
}
.input {
position: relative;
@media (min-width: $screen-sm) {
width: 50%;
}
input {
text-align: center;
border: 1px solid lighten($brand-grey-light, 20%);
font-size: $font-size-large;
padding: $spacer / 3 $spacer / 3 $spacer / 3 $spacer * 1.7;
border-bottom: 0;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
@media (min-width: $screen-sm) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-bottom-left-radius: $border-radius;
border-bottom: 1px solid lighten($brand-grey-light, 20%);
border-right: 0;
}
&::-webkit-inner-spin-button {
margin-left: -($spacer / 2);
}
:global(.dark) & {
border-color: #000;
color: $brand-grey-dimmed;
}
}
}
.currency {
position: absolute;
top: 1px;
bottom: 1px;
left: 1px;
font-size: $font-size-small;
padding: $spacer / 3;
color: $brand-grey-light;
background: $brand-light;
border-right: 1px solid rgba($brand-grey-light, 0.4);
border-top-left-radius: $border-radius;
border-bottom-left-radius: $border-radius;
display: flex;
align-items: center;
:global(.dark) & {
background: $body-background-color--dark;
border-right-color: #000;
}
}
.message {
composes: message from './index.module.scss';
}
@keyframes fadeIn {
from {
opacity: 0.01;
}
to {
opacity: 1;
}
}

View File

@ -2,7 +2,7 @@ import React, { ReactElement, useState } from 'react'
import Input from '../../atoms/Input'
import Account from './Account'
import Conversion from './Conversion'
import styles from './InputGroup.module.scss'
import styles from './InputGroup.module.css'
export default function InputGroup({
sendTransaction

View File

@ -0,0 +1,43 @@
.web3 {
min-height: 77px;
display: flex;
align-items: center;
justify-content: center;
}
.web3:empty {
display: none;
}
.message {
font-size: var(--font-size-small);
position: relative;
}
.message::after {
overflow: hidden;
display: inline-block;
vertical-align: bottom;
animation: ellipsis steps(4, end) 1s infinite;
/* ascii code for the ellipsis character */
content: '\2026';
width: 0;
position: absolute;
left: 100%;
bottom: 0;
}
.success {
composes: message;
color: green;
}
.success::after {
display: none;
}
@keyframes ellipsis {
to {
width: 0.75rem;
}
}

View File

@ -1,44 +0,0 @@
@import 'variables';
.web3 {
min-height: 77px;
display: flex;
align-items: center;
justify-content: center;
&:empty {
display: none;
}
}
.message {
font-size: $font-size-small;
position: relative;
&::after {
overflow: hidden;
display: inline-block;
vertical-align: bottom;
animation: ellipsis steps(4, end) 1s infinite;
content: '\2026'; // ascii code for the ellipsis character
width: 0;
position: absolute;
left: 100%;
bottom: 0;
}
}
.success {
composes: message;
color: green;
&::after {
display: none;
}
}
@keyframes ellipsis {
to {
width: 0.75rem;
}
}

View File

@ -3,7 +3,7 @@ import { parseEther } from '@ethersproject/units'
import useWeb3, { connectors, getErrorMessage } from '../../../hooks/use-web3'
import InputGroup from './InputGroup'
import Alert, { getTransactionMessage } from './Alert'
import styles from './index.module.scss'
import styles from './index.module.css'
export default function Web3Donation({
address

View File

@ -0,0 +1,79 @@
.footer {
text-align: center;
padding-top: calc(var(--spacer) * 2);
color: var(--text-color-light);
line-height: var(--spacer);
}
@media (min-width: 40rem) and (min-height: 500px) {
.footer {
position: fixed;
width: 100%;
border: 0;
will-change: transform;
z-index: 0;
bottom: 0;
box-shadow: none;
}
}
.theme {
margin: var(--spacer) auto;
}
.theme p {
text-align: center;
margin: 0;
}
.themeTitle {
font-size: var(--font-size-h5);
margin-bottom: calc(var(--spacer) / 2);
}
.copyright {
padding-top: var(--spacer);
padding-bottom: var(--spacer);
}
.copyright p {
margin-bottom: 0;
font-size: var(--font-size-mini);
}
.copyright a,
.copyright button code {
color: var(--text-color-light);
}
.copyright a:hover,
.copyright button code {
color: var(--link-color);
}
.copyright a,
.copyright button {
margin-left: var(--spacer);
}
.copyright a:first-child,
.copyright button:first-child {
margin-left: 0;
}
.copyright svg {
width: var(--font-size-small);
height: var(--font-size-small);
margin-right: calc(var(--spacer) / 8);
margin-bottom: -0.15rem;
display: inline-block;
stroke: var(--text-color-light);
opacity: 0.7;
}
.btc code {
font-size: 0.6rem;
background: none;
color: var(--link-color);
padding: 0;
}

View File

@ -1,83 +0,0 @@
// stylelint-disable no-descending-specificity
@import 'variables';
@import 'mixins';
.footer {
text-align: center;
padding-top: $spacer * 2;
color: $text-color-light;
line-height: $spacer;
@media (min-width: $screen-sm) and (min-height: 500px) {
position: fixed;
width: 100%;
border: 0;
will-change: transform;
z-index: 0;
bottom: 0;
box-shadow: none;
}
}
.theme {
margin: $spacer auto;
p {
text-align: center;
margin: 0;
}
}
.themeTitle {
font-size: $font-size-h5;
margin-bottom: $spacer / 2;
}
.copyright {
padding-top: $spacer;
padding-bottom: $spacer;
p {
margin-bottom: 0;
font-size: $font-size-mini;
}
a,
button code {
color: $text-color-light;
&:hover,
&:focus {
color: $link-color;
}
}
a,
button {
margin-left: $spacer;
&:first-child {
margin-left: 0;
}
}
svg {
width: $font-size-small;
height: $font-size-small;
margin-right: $spacer / 8;
margin-bottom: -0.15rem;
display: inline-block;
stroke: $text-color-light;
opacity: 0.7;
}
}
.btc {
code {
font-size: 0.6rem;
background: none;
color: $link-color;
padding: 0;
}
}

View File

@ -4,7 +4,7 @@ import Container from '../atoms/Container'
import Icon from '../atoms/Icon'
import Vcard from '../molecules/Vcard'
import { useSiteMetadata } from '../../hooks/use-site-metadata'
import styles from './Footer.module.scss'
import styles from './Footer.module.css'
function Copyright() {
const { name, uri, github } = useSiteMetadata().author

View File

@ -0,0 +1,76 @@
.header {
padding: 0 calc(var(--spacer) / var(--line-height));
}
@media (min-width: 40rem) {
.header {
padding: 0 calc(var(--spacer) * 2);
}
}
@media (min-width: 40rem) and (min-height: 500px) {
.header {
position: fixed;
width: 100%;
z-index: 1;
top: 0;
border: 0;
will-change: transform;
}
}
.headerContent {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
}
@media (min-width: 40rem) {
.headerContent {
padding: 0;
}
}
/* Logo
///////////////////////////////////// */
.title {
margin: 0;
}
.title a {
display: block;
font: 0/0 a;
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0;
width: 60px;
overflow: hidden;
}
@media (min-width: 40rem) {
.title a {
width: 212px;
}
}
.title a:hover svg,
.title a:focus svg {
fill: var(--link-color);
}
.logo {
width: 191px;
height: 36px;
max-width: unset;
fill: var(--text-color-light);
margin: 0;
transition: 0.2s var(--easing);
}
.nav {
display: inline-block;
}

View File

@ -1,66 +0,0 @@
@import 'variables';
@import 'mixins';
.header {
@media (min-width: $screen-sm) and (min-height: 500px) {
position: fixed;
width: 100%;
z-index: 1;
top: 0;
border: 0;
will-change: transform;
}
}
.headerContent {
@include breakoutviewport;
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 $spacer;
@media (min-width: $screen-md) {
padding: 0;
}
}
// Logo
/////////////////////////////////////
.title {
margin: 0;
a {
display: block;
@include hide-text;
width: 60px;
overflow: hidden;
@media (min-width: $screen-sm) {
width: 212px;
}
&:hover,
&:focus {
svg {
fill: $brand-cyan;
}
}
}
}
.logo {
width: 191px;
height: 36px;
max-width: unset;
fill: $brand-grey-light;
margin: 0;
transition: 0.2s $easing;
}
.nav {
display: inline-block;
}

View File

@ -1,32 +1,28 @@
import React, { ReactElement, PureComponent } from 'react'
import { Link } from 'gatsby'
import Container from '../atoms/Container'
import Search from '../molecules/Search'
import Menu from '../molecules/Menu'
import ThemeSwitch from '../molecules/ThemeSwitch'
import { ReactComponent as Logo } from '../../images/logo.svg'
import styles from './Header.module.scss'
import styles from './Header.module.css'
export default class Header extends PureComponent {
render(): ReactElement {
return (
<header role="banner" className={styles.header}>
<Container>
<div className={styles.headerContent}>
<h1 className={styles.title}>
<Link to="/">
<Logo className={styles.logo} /> kremalicious
</Link>
</h1>
<div className={styles.headerContent}>
<h1 className={styles.title}>
<Link to="/">
<Logo className={styles.logo} /> kremalicious
</Link>
</h1>
<nav role="navigation" className={styles.nav}>
<ThemeSwitch />
<Search />
<Menu />
</nav>
</div>
</Container>
<nav role="navigation" className={styles.nav}>
<ThemeSwitch />
<Search />
<Menu />
</nav>
</div>
</header>
)
}

View File

@ -0,0 +1,14 @@
.posts {
display: grid;
gap: calc(var(--spacer) * 2);
}
@media (min-width: 40rem) {
.posts {
grid-template-columns: repeat(2, 1fr);
}
}
.posts h1 {
font-size: var(--font-size-h4);
}

View File

@ -1,17 +0,0 @@
@import 'variables';
@import 'mixins';
.posts {
display: grid;
gap: $spacer * 2;
@media (min-width: $screen-sm) {
@include breakoutviewport;
grid-template-columns: repeat(2, 1fr);
}
}
.posts h1 {
font-size: $font-size-h4;
}

View File

@ -2,7 +2,7 @@ import React, { ReactElement } from 'react'
import { graphql } from 'gatsby'
import { Post, PageContext } from '../../@types/Post'
import Pagination from '../molecules/Pagination'
import styles from './Archive.module.scss'
import styles from './Archive.module.css'
import PostTeaser from '../molecules/PostTeaser'
import Page from './Page'

Some files were not shown because too many files have changed in this diff Show More