Compare commits
No commits in common. "master" and "pages" have entirely different histories.
27 changed files with 2 additions and 584 deletions
42
.github/workflows/deploy.yaml
vendored
42
.github/workflows/deploy.yaml
vendored
|
@ -1,42 +0,0 @@
|
|||
name: Publish
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Deno
|
||||
uses: denoland/setup-deno@v1
|
||||
with:
|
||||
deno-version: v1.x
|
||||
- name: Build site
|
||||
run: |
|
||||
deno task build
|
||||
cp src/static/.domains _site
|
||||
|
||||
- name: Deploy to Codeberg Pages
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
if: github.ref == 'refs/heads/master'
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ./_site
|
||||
force_orphan: true
|
||||
publish_branch: pages
|
||||
- name: Deploy to Deno Deploy
|
||||
uses: samtherapy/deno-deploy@master
|
||||
with:
|
||||
deno_deploy_token: ${{ secrets.DENO_DEPLOY_TOKEN }}
|
||||
entry_point: serve.ts
|
||||
project: samme
|
||||
production: true
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,3 +0,0 @@
|
|||
_site
|
||||
deno.lock
|
||||
_cache
|
0
.nojekyll
Normal file
0
.nojekyll
Normal file
21
LICENSE
21
LICENSE
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2024 Óscar Otero
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
27
README.md
27
README.md
|
@ -1,27 +0,0 @@
|
|||
# Simple Me
|
||||
|
||||
[Lume](https://lume.land) theme to create a Linktree alternative.
|
||||
|
||||
## Install as a remote theme
|
||||
|
||||
The **fastest and easiest** way to use this theme is by importing it as a remote
|
||||
module. It allows to create a blog in seconds and update it at any time just by
|
||||
changing the version number in the import URL. Just add the following code to
|
||||
your `_config.ts` file:
|
||||
|
||||
```ts
|
||||
import lume from "lume/mod.ts";
|
||||
import me from "https://deno.land/x/lume_theme_simple_me/mod.ts";
|
||||
|
||||
const site = lume();
|
||||
|
||||
site.use(me());
|
||||
|
||||
export default site;
|
||||
```
|
||||
|
||||
## Use it as a base template
|
||||
|
||||
To use this theme as a base template for a more customized site, clone this repo
|
||||
and edit the [_config.ts](./_config.ts) file. The source files are in the
|
||||
[src](./src/) folder.
|
83
_cms.ts
83
_cms.ts
|
@ -1,83 +0,0 @@
|
|||
import lumeCMS from "lume/cms/mod.ts";
|
||||
|
||||
const cms = lumeCMS();
|
||||
|
||||
cms.document(
|
||||
"home: The profile page",
|
||||
"src:index.yml",
|
||||
[
|
||||
{
|
||||
type: "hidden",
|
||||
name: "layout",
|
||||
value: "layouts/home.vto",
|
||||
},
|
||||
{
|
||||
type: "object",
|
||||
name: "header",
|
||||
description: "The header of the page",
|
||||
fields: [
|
||||
"title: text",
|
||||
"description: markdown",
|
||||
"avatar: file",
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "object",
|
||||
name: "metas",
|
||||
description: "Data for the meta tags",
|
||||
fields: [
|
||||
"title: text",
|
||||
"description: text",
|
||||
"image: text",
|
||||
"twitter: text",
|
||||
"generator: checkbox",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "links",
|
||||
type: "object-list",
|
||||
description: "The list of links.",
|
||||
fields: [
|
||||
{
|
||||
type: "text",
|
||||
name: "type",
|
||||
description:
|
||||
"The type of link. It uses the icons and colors from https://simpleicons.org/. For example, 'github', 'instagram', etc.",
|
||||
options: [
|
||||
"github",
|
||||
"instagram",
|
||||
"linkedin",
|
||||
"x",
|
||||
"youtube",
|
||||
"facebook",
|
||||
"tiktok",
|
||||
"patreon",
|
||||
"paypal",
|
||||
"mastodon",
|
||||
"discord",
|
||||
"spotify",
|
||||
"opencollective",
|
||||
"twitch",
|
||||
],
|
||||
},
|
||||
"text: text",
|
||||
"href: text",
|
||||
"only_icon: checkbox",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "extra_head",
|
||||
type: "code",
|
||||
description: "Extra content to include in the <head> tag",
|
||||
},
|
||||
{
|
||||
name: "footer",
|
||||
type: "markdown",
|
||||
description: "The footer of the page",
|
||||
},
|
||||
],
|
||||
);
|
||||
|
||||
cms.upload("uploads: Uploaded files", "src:*{.jpg,.svg}");
|
||||
|
||||
export default cms;
|
11
_config.ts
11
_config.ts
|
@ -1,11 +0,0 @@
|
|||
import lume from "lume/mod.ts";
|
||||
import plugins from "./plugins.ts";
|
||||
|
||||
const site = lume({
|
||||
src: "./src",
|
||||
location: new URL("https://samtherapy.net")
|
||||
});
|
||||
|
||||
site.use(plugins());
|
||||
|
||||
export default site;
|
BIN
apple-touch-icon.png
Normal file
BIN
apple-touch-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 144 KiB |
27
deno.json
27
deno.json
|
@ -1,27 +0,0 @@
|
|||
{
|
||||
"imports": {
|
||||
"lume/": "https://deno.land/x/lume@v2.3.2/",
|
||||
"lume/cms/": "https://cdn.jsdelivr.net/gh/lumeland/cms@0.5.10/"
|
||||
},
|
||||
"tasks": {
|
||||
"lume": "echo \"import 'lume/cli.ts'\" | deno run -A -",
|
||||
"build": "deno task lume",
|
||||
"serve": "deno task lume -s"
|
||||
},
|
||||
"compilerOptions": {
|
||||
"types": [
|
||||
"lume/types.ts"
|
||||
]
|
||||
},
|
||||
"exclude": [
|
||||
"./_site"
|
||||
],
|
||||
"deploy": {
|
||||
"project": "bffcfd12-e23c-4402-b99a-335185e60640",
|
||||
"exclude": [
|
||||
"**/node_modules"
|
||||
],
|
||||
"include": [],
|
||||
"entrypoint": "serve.ts"
|
||||
}
|
||||
}
|
BIN
favicon.ico
Normal file
BIN
favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
1
index.html
Normal file
1
index.html
Normal file
File diff suppressed because one or more lines are too long
25
mod.ts
25
mod.ts
|
@ -1,25 +0,0 @@
|
|||
import plugins from "./plugins.ts";
|
||||
|
||||
import "lume/types.ts";
|
||||
|
||||
export default function () {
|
||||
return (site: Lume.Site) => {
|
||||
// Configure the site
|
||||
site.use(plugins());
|
||||
|
||||
// Add remote files
|
||||
const files = [
|
||||
"_includes/css/header.css",
|
||||
"_includes/css/link.css",
|
||||
"_includes/layouts/base.vto",
|
||||
"index.yml",
|
||||
"styles.css",
|
||||
"favicon.svg",
|
||||
"avatar.jpg",
|
||||
];
|
||||
|
||||
for (const file of files) {
|
||||
site.remoteFile(file, import.meta.resolve(`./src/${file}`));
|
||||
}
|
||||
};
|
||||
}
|
45
plugins.ts
45
plugins.ts
|
@ -1,45 +0,0 @@
|
|||
import "lume/types.ts";
|
||||
import favicon from "lume/plugins/favicon.ts"
|
||||
import postcss from "lume/plugins/postcss.ts";
|
||||
import transformImages from "lume/plugins/transform_images.ts";
|
||||
import metas from "lume/plugins/metas.ts";
|
||||
import minifyHTML from "lume/plugins/minify_html.ts";
|
||||
import svgo from "lume/plugins/svgo.ts";
|
||||
import basePath from "lume/plugins/base_path.ts";
|
||||
import * as si from "npm:simple-icons@11.9.0";
|
||||
import type { SimpleIcon } from "npm:simple-icons@11.9.0";
|
||||
import Color from "https://colorjs.io/dist/color.js";
|
||||
|
||||
const icons = Object.values(si) as SimpleIcon[];
|
||||
|
||||
/** Configure the site */
|
||||
export default function () {
|
||||
return (site: Lume.Site) => {
|
||||
site.use(postcss())
|
||||
.use(favicon())
|
||||
.use(metas())
|
||||
.use(svgo())
|
||||
.use(basePath())
|
||||
.mergeKey("extra_head", "stringArray")
|
||||
.use(transformImages())
|
||||
.copy("static", ".")
|
||||
.copy("static/.domains")
|
||||
.use(minifyHTML({
|
||||
extensions: [".css", ".html", ".js"]
|
||||
}));
|
||||
|
||||
site.data("icon", (slug?: string) => {
|
||||
if (!slug) return;
|
||||
return icons.find((icon) => icon.slug === slug);
|
||||
});
|
||||
|
||||
site.data("textColor", (hex: string) => {
|
||||
const color = new Color(`#${hex}`);
|
||||
const onWhite = Math.abs(color.contrastWCAG21("white"));
|
||||
const onBlack = Math.abs(color.contrastWCAG21("black"));
|
||||
return (onWhite + 0.5) > onBlack ? "white" : "black";
|
||||
});
|
||||
|
||||
site.copy([".jpg", ".webp", ".png"]);
|
||||
};
|
||||
}
|
24
serve.ts
24
serve.ts
|
@ -1,24 +0,0 @@
|
|||
import Server from "lume/core/server.ts";
|
||||
import expires from "lume/middlewares/expires.ts"
|
||||
|
||||
const server = new Server({
|
||||
port: 8000,
|
||||
root: `${Deno.cwd()}/_site`,
|
||||
});
|
||||
|
||||
// Set Access-Control-Allow-Origin header to allow all origins
|
||||
server.use(async (request, next) => {
|
||||
// Here you can modify the request before being passed to next middlewares
|
||||
const response = await next(request);
|
||||
|
||||
response.headers.set('Access-Control-Allow-Origin', '*')
|
||||
// Here you can modify the response before being returned to the previous middleware
|
||||
return response;
|
||||
});
|
||||
|
||||
|
||||
server.use(expires())
|
||||
|
||||
server.start();
|
||||
|
||||
console.log("Listening on http://localhost:8000");
|
|
@ -1,36 +0,0 @@
|
|||
.header {
|
||||
font: var(--font-body);
|
||||
margin-bottom: min(5vh, 100px);
|
||||
color: var(--color-text);
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
text-wrap: balance;
|
||||
|
||||
+ p {
|
||||
margin-top: .5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.header-avatar {
|
||||
border-radius: 50%;
|
||||
aspect-ratio: 1;
|
||||
object-fit: cover;
|
||||
object-position: center center;
|
||||
width: 200px;
|
||||
max-width: 50vw;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font: var(--font-title);
|
||||
letter-spacing: var(--font-title-spacing);
|
||||
margin: .5em 0 0;
|
||||
color: var(--color-base);
|
||||
}
|
||||
|
||||
.header-theme {
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
right: 1.5rem;
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
.link-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: grid;
|
||||
row-gap: 10px;
|
||||
|
||||
.button {
|
||||
display: flex;
|
||||
font: var(--font-body-bold);
|
||||
transition: transform 200ms;
|
||||
border: solid 1px #00000022;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 2px 10px -8px #0009;
|
||||
}
|
||||
}
|
||||
|
||||
.button:not(.is-primary) {
|
||||
background: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
fill: currentColor;
|
||||
}
|
||||
}
|
||||
|
||||
[data-theme="dark"] {
|
||||
.link-list .button {
|
||||
border: solid 1px #FFFFFF16;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-list {
|
||||
list-style: none;
|
||||
margin: 0 0 min(5vh, 100px);
|
||||
padding: 0;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
justify-content: center;
|
||||
|
||||
svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: flex;
|
||||
font: var(--font-body-bold);
|
||||
transition: transform 200ms;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 2px 10px -8px #0009;
|
||||
}
|
||||
}
|
||||
|
||||
.button:not(.is-primary) {
|
||||
background: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
<!doctype html>
|
||||
|
||||
<html lang="{{ it.lang }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{ header.title }}</title>
|
||||
|
||||
<meta name="supported-color-schemes" content="light dark">
|
||||
<meta name="theme-color" content="hsl(220, 20%, 100%)" media="(prefers-color-scheme: light)">
|
||||
<meta name="theme-color" content="hsl(220, 20%, 10%)" media="(prefers-color-scheme: dark)">
|
||||
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon.png">
|
||||
<link rel="canonical" href="{{ url |> url(true) }}">
|
||||
|
||||
{{ it.extra_head?.join("\n") }}
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<header class="header">
|
||||
<script>
|
||||
let theme = localStorage.getItem("theme") || (window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||
? "dark"
|
||||
: "light");
|
||||
document.documentElement.dataset.theme = theme;
|
||||
function changeTheme() {
|
||||
theme = theme === "dark" ? "light" : "dark";
|
||||
localStorage.setItem("theme", theme);
|
||||
document.documentElement.dataset.theme = theme;
|
||||
}
|
||||
</script>
|
||||
<button class="button header-theme" onclick="changeTheme()">
|
||||
<span class="icon">◐</span>
|
||||
</button>
|
||||
|
||||
<img class="header-avatar" src="{{ header.avatar }}" alt="Avatar" transform-images="webp avif 200@2">
|
||||
<h1 class="header-title">{{ header.title }}</h1>
|
||||
{{ header.description |> md }}
|
||||
</header>
|
||||
|
||||
{{> const icons = links.filter((link) => link.only_icon) }}
|
||||
|
||||
{{ if icons.length }}
|
||||
<ul class="icon-list">
|
||||
{{ for link of icons }}
|
||||
{{> let i = icon(link.type) }}
|
||||
<li>
|
||||
<a href="{{ link.href }}" rel="me" class="button" style="--bg-color:{{ link.hex || `#${i?.hex || "fff" }` }}; --text-color:{{ link.textColor || textColor(i?.hex || "fff") }}" title="{{ link.text }}">
|
||||
{{ i?.svg }}
|
||||
</a>
|
||||
</li>
|
||||
{{ /for }}
|
||||
</ul>
|
||||
{{ /if }}
|
||||
|
||||
<ul class="link-list">
|
||||
{{ for link of links.filter((link) => !link.only_icon) }}
|
||||
{{> let i = icon(link.type) }}
|
||||
<li>
|
||||
<a href="{{ link.href }}" rel="me" class="button" style="--bg-color:{{ link.hex || `#${i?.hex || "fff" }` }}; --text-color:{{ link.textColor || textColor(i?.hex || "fff") }}">
|
||||
{{ i?.svg }}
|
||||
{{ link.text }}
|
||||
</a>
|
||||
</li>
|
||||
{{ /for }}
|
||||
</ul>
|
||||
</main>
|
||||
{{ if footer }}
|
||||
<footer>
|
||||
{{ footer |> md }}
|
||||
</footer>
|
||||
{{ /if }}
|
||||
</body>
|
||||
</html>
|
|
@ -1,59 +0,0 @@
|
|||
layout: layouts/base.vto
|
||||
header:
|
||||
title: Sam Therapy
|
||||
description: Nowhere ~~and everywhere~~ all at once.
|
||||
avatar: /avatar.png
|
||||
metas:
|
||||
title: =header.title
|
||||
description: =header.description
|
||||
image: =header.avatar
|
||||
generator: true
|
||||
links:
|
||||
- text: Git
|
||||
href: 'https://git.froth.zone/sam'
|
||||
type: forgejo
|
||||
only_icon: false
|
||||
- type: writedotas
|
||||
text: Blog
|
||||
href: 'https://blog.froth.zone/sam'
|
||||
only_icon: false
|
||||
- type: matrix
|
||||
text: Matrix
|
||||
href: 'https://matrix.to/#/@samme:schizo.cafe'
|
||||
only_icon: false
|
||||
- type: xmpp
|
||||
text: XMPP (Not Recommended)
|
||||
href: 'xmpp://sam@samtherapy.net'
|
||||
only_icon: false
|
||||
- type: bluesky
|
||||
text: Bluesky
|
||||
href: 'https://bsky.app/profile/samtherapy.net'
|
||||
only_icon: false
|
||||
- type: nostr
|
||||
text: Nostr (I don't like using it but I have one)
|
||||
href: >-
|
||||
https://njump.me/nprofile1qyfhwumn8ghj7mmxve3ksctfdch8qatz9uq3vamnwvaz7tmjv4kxz7fwd4hhxarj9ec82c30qythwumn8ghj7un9d3shjtnxwfhhg6pw0fhkuef0qqs9gymnvuqhq66973gsat9rnh44v9la7qmss2xk747z5tv263zydzq2nr59m
|
||||
only_icon: false
|
||||
- type: pleroma
|
||||
text: yeah
|
||||
href: 'https://froth.zone/users/sam'
|
||||
only_icon: false
|
||||
- type: github
|
||||
href: 'https://github.com/SamTherapy'
|
||||
only_icon: true
|
||||
text: GitHub
|
||||
- only_icon: true
|
||||
type: gitlab
|
||||
text: GitLab
|
||||
href: 'https://gitlab.com/SamTherapy'
|
||||
- type: codeberg
|
||||
text: Codeberg
|
||||
href: 'https://codeberg.org/sammefishe'
|
||||
only_icon: true
|
||||
- only_icon: true
|
||||
type: sourcehut
|
||||
text: SourceHut
|
||||
href: 'https://sr.ht/~sammefishe/'
|
||||
footer: >-
|
||||
Powered by [Lume](https://lume.land) &
|
||||
[SimpleMe](https://github.com/lumeland/theme-simple-me) theme
|
|
@ -1,39 +0,0 @@
|
|||
/* Lume's design system */
|
||||
@import "https://unpkg.com/@lumeland/ds@0.5.2/ds.css";
|
||||
|
||||
/* Custom components */
|
||||
@import "css/header.css";
|
||||
@import "css/link.css";
|
||||
|
||||
body {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 500px);
|
||||
grid-template-rows: 1fr auto;
|
||||
min-height: 100vh;
|
||||
text-align: center;
|
||||
padding: max(20px, 5vh) 20px;
|
||||
row-gap: 20px;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
main {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
footer {
|
||||
font: var(--font-small);
|
||||
color: var(--color-dim);
|
||||
|
||||
> * {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
> * + * {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
1
styles.css
Normal file
1
styles.css
Normal file
|
@ -0,0 +1 @@
|
|||
@import "https://unpkg.com/@lumeland/ds@0.5.2/ds.css"; /* Lume's design system */ /* Custom components */ .header { font: var(--font-body); margin-bottom: min(5vh, 100px); color: var(--color-text); p { margin: 0; text-wrap: balance; + p { margin-top: .5em; } } } .header-avatar { border-radius: 50%; aspect-ratio: 1; -o-object-fit: cover; object-fit: cover; -o-object-position: center center; object-position: center center; width: 200px; max-width: 50vw; } .header-title { font: var(--font-title); letter-spacing: var(--font-title-spacing); margin: .5em 0 0; color: var(--color-base); } .header-theme { position: absolute; top: 1rem; right: 1.5rem; } .link-list { list-style: none; margin: 0; padding: 0; display: grid; row-gap: 10px; .button { display: flex; font: var(--font-body-bold); transition: transform 200ms; border: solid 1px #00000022; &:hover { transform: scale(1.05); box-shadow: 0 2px 10px -8px #0009; } } .button:not(.is-primary) { background: var(--bg-color); color: var(--text-color); } svg { width: 20px; height: 20px; fill: currentColor; } } [data-theme="dark"] { .link-list .button { border: solid 1px #FFFFFF16; } } .icon-list { list-style: none; margin: 0 0 min(5vh, 100px); padding: 0; display: flex; gap: 10px; justify-content: center; svg { width: 20px; height: 20px; fill: currentColor; } .button { display: flex; font: var(--font-body-bold); transition: transform 200ms; &:hover { transform: scale(1.05); box-shadow: 0 2px 10px -8px #0009; } } .button:not(.is-primary) { background: var(--bg-color); color: var(--text-color); } } body { display: grid; grid-template-columns: minmax(0, 500px); grid-template-rows: 1fr auto; min-height: 100vh; text-align: center; padding: max(20px, 5vh) 20px; row-gap: 20px; justify-content: center; align-content: center; } main { align-self: center; } footer { font: var(--font-small); color: var(--color-dim); > * { margin: 0; } > * + * { margin-top: 1em; } a { color: inherit; } }
|
Loading…
Reference in a new issue