init
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "themes/duckquill"]
|
||||||
|
path = themes/duckquill
|
||||||
|
url = https://codeberg.org/daudix/duckquill.git
|
94
config.toml
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
base_url = "https://studio-umzu.de/"
|
||||||
|
title = "Studio UMZU"
|
||||||
|
|
||||||
|
compile_sass = true
|
||||||
|
minify_html = true
|
||||||
|
generate_feeds = true
|
||||||
|
feed_filenames = ["rss.xml", "atom.xml"]
|
||||||
|
build_search_index = true
|
||||||
|
author = "Aron Petau"
|
||||||
|
hard_link_static = false
|
||||||
|
|
||||||
|
taxonomies = [{ name = "tags", feed = true, paginate_by = 10 }]
|
||||||
|
theme = "duckquill"
|
||||||
|
default_language = "en"
|
||||||
|
|
||||||
|
[languages.de]
|
||||||
|
title = "Studio UMZU"
|
||||||
|
description = "Spielerisches Lernen mit Technikdidaktik"
|
||||||
|
generate_feeds = true
|
||||||
|
build_search_index = true
|
||||||
|
taxonomies = [{ name = "tags", feed = true, paginate_by = 10 }]
|
||||||
|
|
||||||
|
[slugify]
|
||||||
|
paths = "off"
|
||||||
|
taxonomies = "on"
|
||||||
|
anchors = "off"
|
||||||
|
paths_keep_dates = false
|
||||||
|
|
||||||
|
[search]
|
||||||
|
index_format = "fuse_json"
|
||||||
|
|
||||||
|
[extra]
|
||||||
|
styles = [
|
||||||
|
"/css/timeline.css",
|
||||||
|
"/css/mermaid.css",
|
||||||
|
"/css/skills.css",
|
||||||
|
"/css/gallery.css",
|
||||||
|
]
|
||||||
|
|
||||||
|
bundled_fonts = false
|
||||||
|
issues_url = "https://forgejo.petau.net/aron/awebsite/issues"
|
||||||
|
source_url = "https://forgejo.petau.net/aron/awebsite"
|
||||||
|
default_theme = "light"
|
||||||
|
accent_color = "#b12633"
|
||||||
|
accent_color_dark = "#c54854"
|
||||||
|
toc = true
|
||||||
|
toc_sidebar = true
|
||||||
|
toc_inline = true
|
||||||
|
card = true
|
||||||
|
favicon = "/logo.png"
|
||||||
|
apple_touch_icon = "/logo.png"
|
||||||
|
go_to_top = true
|
||||||
|
show_copy_button = true
|
||||||
|
show_reading_time = true
|
||||||
|
show_share_button = true
|
||||||
|
show_backlinks = true
|
||||||
|
|
||||||
|
[extra.nav]
|
||||||
|
auto_hide = false
|
||||||
|
show_feed = true
|
||||||
|
show_theme_switcher = true
|
||||||
|
show_repo = true
|
||||||
|
links = [
|
||||||
|
{ url = "@/_index.md", name = "Projects" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[extra.footer]
|
||||||
|
links = [
|
||||||
|
{ url = "@/_index.md", name = "Projects" },
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
socials = [
|
||||||
|
{ url = "https://github.com/arontaupe", name = "GitHub", icon = "%3Csvg role='img' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Ctitle%3EGitHub%3C/title%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E" },
|
||||||
|
{ url = "https://www.printables.com/@arontaupe", name = "Printables", icon = "%3Csvg%20role%3D%22img%22%20viewBox%3D%220%200%2024%2024%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Ctitle%3EPrintables%3C%2Ftitle%3E%3Cpath%20d%3D%22M3.678%204.8%2012%209.6v9.6l8.322-4.8V4.8L12%200ZM12%2019.2l-8.322-4.8V24Z%22%2F%3E%3C%2Fsvg%3E" },
|
||||||
|
{ url = "https://www.etsy.com/de-en/shop/reprintedservices", name = "Etsy", icon = "%3Csvg%20role%3D%22img%22%20viewBox%3D%220%200%2024%2024%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Ctitle%3EEtsy%3C%2Ftitle%3E%3Cpath%20d%3D%22M8.559%202.445c0-.325.033-.52.59-.52h7.465c1.3%200%202.02%201.11%202.54%203.193l.42%201.666h1.27c.23-4.728.43-6.784.43-6.784s-3.196.36-5.09.36H6.635L1.521.196v1.37l1.725.326c1.21.24%201.5.496%201.6%201.606%200%200%20.11%203.27.11%208.64%200%205.385-.09%208.61-.09%208.61%200%20.973-.39%201.333-1.59%201.573l-1.722.33V24l5.13-.165h8.55c1.935%200%206.39.165%206.39.165.105-1.17.75-6.48.855-7.064h-1.2l-1.284%202.91c-1.005%202.28-2.476%202.445-4.11%202.445h-4.906c-1.63%200-2.415-.64-2.415-2.05V12.8s3.62%200%204.79.096c.912.064%201.463.325%201.76%201.598l.39%201.695h1.41l-.09-4.278.192-4.305h-1.391l-.45%201.89c-.283%201.244-.48%201.47-1.754%201.6-1.666.17-4.815.14-4.815.14V2.45h-.05z%22%2F%3E%3C%2Fsvg%3E" },
|
||||||
|
{ url = "https://mastodon.online/@reprintedAron", name = "Mastodon", icon = "%3Csvg role='img' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Ctitle%3EMastodon%3C/title%3E%3Cpath d='M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z'/%3E%3C/svg%3E" },
|
||||||
|
]
|
||||||
|
show_copyright = true
|
||||||
|
show_powered_by = false
|
||||||
|
show_source = true
|
||||||
|
|
||||||
|
[extra.comments]
|
||||||
|
host = "mastodon.online"
|
||||||
|
user = "reprintedAron"
|
||||||
|
show_qr = true
|
||||||
|
|
||||||
|
[extra.goatcounter]
|
||||||
|
#host = ""
|
||||||
|
user = "awebsite"
|
||||||
|
|
||||||
|
[extra.debug]
|
||||||
|
layout = false
|
||||||
|
no_styles = false
|
167
content/_index.de.md
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
+++
|
||||||
|
title = "Werkraum - Making Workshops"
|
||||||
|
description = "Die Zukunft gestalten — mit Händen, Köpfen und Code. Buchen Sie uns für Ihren nächsten Digital- oder Handwerksworkshop."
|
||||||
|
draft=false
|
||||||
|
|
||||||
|
[extra]
|
||||||
|
show_copyright = false
|
||||||
|
show_shares = true
|
||||||
|
show_source = false
|
||||||
|
show_toc = true
|
||||||
|
inline_toc = true
|
||||||
|
|
||||||
|
[extra.footer]
|
||||||
|
copyright = "© Test"
|
||||||
|
show_copyright = false
|
||||||
|
+++
|
||||||
|
|
||||||
|
{% alert(note=true) %}
|
||||||
|
Dies ist ein Work in Progress.
|
||||||
|
Die hier bereitgestellten Informationen können sich noch ändern.
|
||||||
|
{% end %}
|
||||||
|
|
||||||
|
## Euer Kreativ-Workshop-Team
|
||||||
|
|
||||||
|
Wir sind Aron Petau und Friedrich Weber Goizel — Maker, Pädagogen und leidenschaftliche Tüftler. Wir entwickeln und veranstalten Workshops in Berlin.
|
||||||
|
|
||||||
|
Wir bringen die Welt des Machens in Bibliotheken, Schulen und Jugendzentren. Unsere Workshops sind praxisnah und darauf ausgelegt, Kreativität, Neugier und technische Fähigkeiten zu fördern.
|
||||||
|
|
||||||
|
Egal, ob ihr schon einen Makerspace mit 3D-Druckern, Lasercuttern oder Plottern habt oder ganz am Anfang steht — wir passen uns an.
|
||||||
|
Wir bieten sowohl mobile Vorführungen und Einführungsveranstaltungen als auch vertiefende Workshops, die auf eurer bestehenden Ausstattung aufbauen.
|
||||||
|
Jeder Workshop wird individuell auf eure Bedürfnisse, euer Publikum und euren Raum zugeschnitten.
|
||||||
|
|
||||||
|
- Workshops zu 3D-Druck, Lasercutting, Plotten, Robotik und 3D-Design
|
||||||
|
- Flexible Durchführung: auf eurem Equipment oder mit unseren mobilen Demo-Setups
|
||||||
|
- Erfahrung mit Schulklassen, Bibliotheken und öffentlichem Publikum
|
||||||
|
- Maßgeschneiderte Workshop-Konzepte passend zu euren Zielen und Teilnehmenden
|
||||||
|
- Wir helfen euch sogar bei der Planung, Gestaltung und dem Aufbau neuer Makerspaces!
|
||||||
|
|
||||||
|
Lasst uns gemeinsam einen Raum schaffen, in dem Handwerk auf Code, Analoges auf Digitales und Ideen auf Leben treffen.
|
||||||
|
Ihr könnt uns für einmalige Veranstaltungen oder laufende Programme kontaktieren.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Kontakt
|
||||||
|
|
||||||
|
Wir freuen uns, von euch zu hören!
|
||||||
|
Für Anfragen, Buchungen oder um über einen individuellen Workshop zu sprechen, schreibt uns:
|
||||||
|
|
||||||
|
[aron@petau.net + f.goizel@yahoo.com](mailto:aron@petau.net,f.goizel@yahoo.com?subject=[Workshop])
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Referenzen & Erfahrung
|
||||||
|
|
||||||
|
Wir haben Workshops durchgeführt und zusammengearbeitet mit:
|
||||||
|
|
||||||
|
- [Junge Tüftler*innen, Berlin](https://junge-tueftler.de)
|
||||||
|
- [Futurium, Berlin](https://futurium.de)
|
||||||
|
- [Gabriele von Bülow Gymnasium, Berlin](https://www.gvb-berlin.de)
|
||||||
|
- [studio einszwovier](https://www.gvb-berlin.de/unterricht-plus/arbeitsgemeinschaften/maker-space-studio-einszwovier/)
|
||||||
|
- [inküle](https://inkuele.de), Innovationen für die künstlerische Lehre an der UdK
|
||||||
|
- Unterstützt vom Masterprogramm [*New Practice in Design and Technology*](https://www.newpractice.net)
|
||||||
|
- [Friedrich Weber @ New Practice](https://www.newpractice.net/author/friedrich-weber-goizel)
|
||||||
|
- [Aron Petau @ New Practice](https://www.newpractice.net/author/aron-petau)
|
||||||
|
- [Stadtteilbibliothek Karow](https://www.berlin.de/stadtbibliothek-pankow/bibliotheken/stadtteilbibliothek-karow/)
|
||||||
|
|
||||||
|
## Unsere Profile
|
||||||
|
|
||||||
|
### Aron
|
||||||
|
|
||||||
|
<aside>
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
Aron hat einen Hintergrund in Kognitionswissenschaften, KI und Mediendidaktik.
|
||||||
|
Er liebt knifflige Software-Probleme und denkt gerne über Plastik als Werkstoff jenseits des Druckers nach.
|
||||||
|
|
||||||
|
Hier gibt’s eine ausführliche [Bio](/pages/cv):
|
||||||
|
|
||||||
|
### Friedrich
|
||||||
|
|
||||||
|
<aside>
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
#### Ausbildung:
|
||||||
|
|
||||||
|
2014–2015 Studium der Freien Kunst, Hochschule der Künste Braunschweig, Skulptur
|
||||||
|
|
||||||
|
2015–2019 Studium der Freien Kunst, Universität der Künste Berlin, Konzept und Neue Medien
|
||||||
|
|
||||||
|
2019 Master of Fine Arts
|
||||||
|
|
||||||
|
2018–2021 Studium humanoide Robotik, Berliner Hochschule für Technik
|
||||||
|
|
||||||
|
2022 Studium Design & Computation, Technische Universität Berlin & Universität der Künste Berlin
|
||||||
|
|
||||||
|
#### Beruf:
|
||||||
|
|
||||||
|
2019–2021 Besucherservice im Futurium Berlin
|
||||||
|
|
||||||
|
2021–2022 Besucherservice und Ausstellungsaufsicht im GID Berlin (Futurium)
|
||||||
|
|
||||||
|
2022 Künstlerisches Forschungsstipendium „KuRoBi4all“ (Kunst, Robotik, Bibliothek für alle); Hochschule für Wirtschaft und Recht Berlin, Stadtbibliotheken Pankow Berlin, Artspring Berlin
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Unsere kombinierten Workshop-Skills
|
||||||
|
|
||||||
|
{% skills() %}
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "3D-Design & Slicing",
|
||||||
|
"skills": [
|
||||||
|
{ "name": "<abbr title=\"Eine intuitive 3D-Modellierungs-App für druckbare Formen.\">Shapr3D</abbr>", "icon": "fas fa-drafting-compass", "link": "https://www.shapr3d.com" },
|
||||||
|
{ "name": "<abbr title=\"Ein professionelles CAD-Tool zur Konstruktion mechanischer Teile und Produkte.\">Fusion 360</abbr>", "icon": "fas fa-project-diagram", "link": "https://www.autodesk.com/products/fusion-360" },
|
||||||
|
{ "name": "<abbr title=\"Eine einsteigerfreundliche Web-App für einfache 3D-Modelle.\">Tinkercad</abbr>", "icon": "fas fa-cubes", "link": "https://www.tinkercad.com" },
|
||||||
|
{ "name": "<abbr title=\"Ein Programm, das 3D-Modelle für den Druck auf Prusa-Maschinen vorbereitet.\">PrusaSlicer</abbr>", "icon": "fas fa-cut", "link": "https://www.prusa3d.com/page/prusaslicer_424" },
|
||||||
|
{ "name": "<abbr title=\"Eine beliebte Slicer-Software zur Vorbereitung von 3D-Druckaufträgen.\">Cura</abbr>", "icon": "fas fa-layer-group", "link": "https://ultimaker.com/software/ultimaker-cura/" },
|
||||||
|
{ "name": "<abbr title=\"Eine Slicer-Software, optimiert für viele moderne 3D-Drucker.\">OrcaSlicer</abbr>", "icon": "fas fa-fish", "link": "https://orcaslicer.com" },
|
||||||
|
{ "name": "<abbr title=\"Ein webbasierter Slicer und CAM-Tool für 3D-Druck und CNC.\">Kiri:Moto</abbr>", "icon": "fas fa-network-wired", "link": "https://grid.space/kiri/" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Grafikdesign",
|
||||||
|
"skills": [
|
||||||
|
{ "name": "<abbr title=\"Ein Vektor-Design-Tool für Grafiken und Illustrationen.\">Affinity Designer</abbr>", "icon": "fas fa-pencil-ruler", "link": "https://affinity.serif.com/designer/" },
|
||||||
|
{ "name": "<abbr title=\"Ein kostenloses Open-Source-Tool für Vektorgrafiken.\">Inkscape</abbr>", "icon": "fas fa-palette", "link": "https://inkscape.org" },
|
||||||
|
{ "name": "<abbr title=\"Eine Inkscape-Erweiterung für Stickmuster.\">Ink/Stitch</abbr>", "icon": "fas fa-needle", "link": "https://inkstitch.org" },
|
||||||
|
{ "name": "<abbr title=\"Eine Online-Plattform für einfaches Grafikdesign, Poster und mehr.\">Canva</abbr>", "icon": "fas fa-paint-brush", "link": "https://www.canva.com" },
|
||||||
|
{ "name": "<abbr title=\"Eine 3D-Umgebungsplattform, in der Kinder interaktive virtuelle Welten bauen.\">CoSpaces Edu</abbr>", "icon": "fas fa-vr-cardboard", "link": "https://cospaces.io/edu/" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Bildungstechnologien",
|
||||||
|
"skills": [
|
||||||
|
{ "name": "<abbr title=\"Winzige Roboter, die Kindern spielerisch Programmieren beibringen.\">Ozobot</abbr>", "icon": "fas fa-robot", "link": "https://ozobot.com" },
|
||||||
|
{ "name": "<abbr title=\"Ein einfacher Bodenroboter, der jungen Lernenden grundlegendes Programmieren vermittelt.\">Blue-Bot</abbr>", "icon": "fas fa-car-side", "link": "https://www.tts-group.co.uk/blue-bot-bluetooth-programmable-floor-robot/1015267.html" },
|
||||||
|
{ "name": "<abbr title=\"Ein Mikrocontroller-Board zum Lehren von Programmierung und Elektronik.\">Calliope mini</abbr>", "icon": "fas fa-microchip", "link": "https://calliope.cc" },
|
||||||
|
{ "name": "<abbr title=\"Ein LEGO-Roboterbausatz für praxisnahes STEM-Lernen.\">LEGO Spike</abbr>", "icon": "fas fa-cog", "link": "https://education.lego.com/en-us/products/lego-education-spike-prime-set-/45678" },
|
||||||
|
{ "name": "<abbr title=\"Ein LEGO-Set, das Kindern Robotik und Technik näherbringt.\">LEGO WeDo</abbr>", "icon": "fas fa-cogs", "link": "https://education.lego.com/en-us/products/lego-education-wedo-2-0-core-set-/45300" },
|
||||||
|
{ "name": "<abbr title=\"Kleine Drohnen für Luftaufnahmen und praktische Flugdemos.\">DJI Drones</abbr>", "icon": "fas fa-drone", "link": "https://www.dji.com" },
|
||||||
|
{ "name": "<abbr title=\"Programmierbare Roboterarme wie in der Industrie.\">Industrieroboterarme</abbr>", "icon": "fas fa-hand-paper", "link": "#" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "3D-Druck-Hardware",
|
||||||
|
"skills": [
|
||||||
|
{ "name": "<abbr title=\"Drucker, die mit Flüssigharz und UV-Licht hochdetaillierte Drucke erstellen.\">Resindrucker</abbr>", "icon": "fas fa-vial", "link": "#" },
|
||||||
|
{ "name": "<abbr title=\"Drucker, die mit geschmolzenem Kunststofffilament 3D-Objekte erzeugen.\">Filamentdrucker</abbr>", "icon": "fas fa-cube", "link": "#" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Programmierung",
|
||||||
|
"skills": [
|
||||||
|
{ "name": "<abbr title=\"Eine visuelle, blockbasierte Programmierplattform für Kinder und Einsteiger.\">Scratch</abbr>", "icon": "fas fa-cat", "link": "https://scratch.mit.edu" },
|
||||||
|
{ "name": "<abbr title=\"Ein Erfinder-Set, das Alltagsobjekte mit Computerprogrammen verbindet.\">Makey Makey</abbr>", "icon": "fas fa-plug", "link": "https://makeymakey.com" },
|
||||||
|
{ "name": "<abbr title=\"Eine beliebte, einsteigerfreundliche Programmiersprache.\">Python</abbr>", "icon": "fab fa-python", "link": "https://www.python.org" },
|
||||||
|
{ "name": "<abbr title=\"Das Erstellen und Gestalten von Webseiten und Webanwendungen.\">Webentwicklung</abbr>", "icon": "fas fa-code", "link": "#" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
{% end %}
|
174
content/_index.md
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
+++
|
||||||
|
title = "Werkraum - Making Workshops"
|
||||||
|
description = "Crafting the future — hands, minds, and code. Book us for your next digital / crafts workshop"
|
||||||
|
draft=false
|
||||||
|
|
||||||
|
[extra]
|
||||||
|
show_copyright = false
|
||||||
|
show_shares = true
|
||||||
|
show_source = false
|
||||||
|
show_toc = true
|
||||||
|
inline_toc = true
|
||||||
|
[extra.footer]
|
||||||
|
copyright = "© Test"
|
||||||
|
show_copyright = false
|
||||||
|
|
||||||
|
|
||||||
|
+++
|
||||||
|
|
||||||
|
{% alert(note=true) %}
|
||||||
|
This is a work in Progress.
|
||||||
|
Informations on here are subject to change.
|
||||||
|
{% end %}
|
||||||
|
|
||||||
|
## Your Creative Workshop Team
|
||||||
|
|
||||||
|
We are Aron Petau and Friedrich Weber Goizel — makers, educators, and passionate tinkerers conceptualizing and making workshops for a living in Berlin.
|
||||||
|
|
||||||
|
We bring the world of making to libraries, schools, and youth centers, offering hands-on workshops designed to spark creativity, curiosity, and technical skill.
|
||||||
|
|
||||||
|
Whether you already have a makerspace with 3D printers, laser cutters, or plotters, or you’re just starting out — we are adapting.
|
||||||
|
We can offer both portable showcases and introductory sessions as well as deep-dive workshops that build on your existing equipment.
|
||||||
|
We tailor every workshop to your needs, audience, and space.
|
||||||
|
|
||||||
|
- Workshops in 3D printing, laser cutting, plotting, robotics, and 3D design
|
||||||
|
- Flexible delivery: on your equipment or with our portable demo setups
|
||||||
|
- Experience with school groups, libraries, and public audiences
|
||||||
|
- Custom workshop concepts to match your goals and participants
|
||||||
|
- We even help design, curate, and build out new maker spaces!
|
||||||
|
|
||||||
|
Let’s co-create a space where craft meets code, analog meets digital, and ideas come alive.
|
||||||
|
We’d love to help turn your place into a hub of creativity and learning.
|
||||||
|
You can contact us for one-time events or ongoing programs.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Contact
|
||||||
|
|
||||||
|
We’d love to hear from you!
|
||||||
|
For inquiries, bookings, or to discuss a custom workshop, reach out to us via email at:
|
||||||
|
|
||||||
|
[aron@petau.net + f.goizel@yahoo.com](mailto:aron@petau.net,f.goizel@yahoo.com?subject=[Workshop])
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### References & Experience
|
||||||
|
|
||||||
|
We’ve run workshops and collaborated with:
|
||||||
|
|
||||||
|
- [Junge Tüftler*innen, Berlin](https://junge-tueftler.de)
|
||||||
|
- [Futurium, Berlin](https://futurium.de)
|
||||||
|
- [Gabriele von Bülow Gymnasium, Berlin](https://www.gvb-berlin.de)
|
||||||
|
- [studio einszwovier](https://www.gvb-berlin.de/unterricht-plus/arbeitsgemeinschaften/maker-space-studio-einszwovier/)
|
||||||
|
- [inküle](https://inkuele.de), Innovationen für die künstlerische Lehre an der UdK
|
||||||
|
- Backed by the [*New Practice in Design and Technology*](https://www.newpractice.net) master’s program
|
||||||
|
- [Friedrich Weber @ New Practice](https://www.newpractice.net/author/friedrich-weber-goizel)
|
||||||
|
- [Aron Petau @ New Practice](https://www.newpractice.net/author/aron-petau)
|
||||||
|
- [Stadtteilbibliothek Karow](https://www.berlin.de/stadtbibliothek-pankow/bibliotheken/stadtteilbibliothek-karow/)
|
||||||
|
|
||||||
|
|
||||||
|
## Our Profiles
|
||||||
|
|
||||||
|
### Aron
|
||||||
|
|
||||||
|
<aside>
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
Aron has a background in Cognitive sciences, AI and Media Didactics.
|
||||||
|
He loves tricky software problems and likes to think of plastics as a material for making beyond the printer.
|
||||||
|
|
||||||
|
Read up a full [bio](/pages/cv) here:
|
||||||
|
|
||||||
|
|
||||||
|
### Friedrich
|
||||||
|
|
||||||
|
<aside>
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
#### Education:
|
||||||
|
|
||||||
|
2014-2015 Studies of Fine Arts, Hochschule der Künste Braunschweig, sculpture
|
||||||
|
|
||||||
|
2015-2019 Studies of Fine Arts, Universität der Künste Berlin, Concept and New Media
|
||||||
|
|
||||||
|
2019 Master of Fine Arts
|
||||||
|
|
||||||
|
2018-2021 Studies of humanoid Robotics, Berliner Hochschule für Technik
|
||||||
|
|
||||||
|
2022 Studies of Design & Computation, Technische Universität Berlin & Universität der Künste Berlin
|
||||||
|
|
||||||
|
#### Work:
|
||||||
|
|
||||||
|
2019-2021 Visitor service at Futurium Berlin
|
||||||
|
|
||||||
|
2021-2022 Visitor service and exhibition supervisor at GID Berlin (Futurium)
|
||||||
|
|
||||||
|
2022 Artistic Research Scholarship "KuRoBi4all" (Art, Robotics, Library for all); Hochschule für Wirtschaft und Recht Berlin, Stadtbibliotheken Pankow Berlin, Artspring Berlin
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
## Our combined workshop skills
|
||||||
|
|
||||||
|
{% skills() %}
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "3D Design & Slicing",
|
||||||
|
"skills": [
|
||||||
|
{ "name": "<abbr title=\"An intuitive 3D modeling app for creating printable shapes.\">Shapr3D</abbr>", "icon": "fas fa-drafting-compass", "link": "https://www.shapr3d.com" },
|
||||||
|
{ "name": "<abbr title=\"A professional CAD tool used for designing mechanical parts and products.\">Fusion 360</abbr>", "icon": "fas fa-project-diagram", "link": "https://www.autodesk.com/products/fusion-360" },
|
||||||
|
{ "name": "<abbr title=\"A beginner-friendly web app for building simple 3D models.\">Tinkercad</abbr>", "icon": "fas fa-cubes", "link": "https://www.tinkercad.com" },
|
||||||
|
{ "name": "<abbr title=\"A program that prepares 3D models for printing on Prusa machines.\">PrusaSlicer</abbr>", "icon": "fas fa-cut", "link": "https://www.prusa3d.com/page/prusaslicer_424" },
|
||||||
|
{ "name": "<abbr title=\"A popular slicer software for preparing 3D print jobs.\">Cura</abbr>", "icon": "fas fa-layer-group", "link": "https://ultimaker.com/software/ultimaker-cura/" },
|
||||||
|
{ "name": "<abbr title=\"A slicer program optimized for many modern 3D printers.\">OrcaSlicer</abbr>", "icon": "fas fa-fish", "link": "https://orcaslicer.com" },
|
||||||
|
{ "name": "<abbr title=\"A web-based slicer and CAM tool for 3D printing and CNC.\">Kiri:Moto</abbr>", "icon": "fas fa-network-wired", "link": "https://grid.space/kiri/" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Graphic Design",
|
||||||
|
"skills": [
|
||||||
|
{ "name": "<abbr title=\"A vector design tool for creating graphics and illustrations.\">Affinity Designer</abbr>", "icon": "fas fa-pencil-ruler", "link": "https://affinity.serif.com/designer/" },
|
||||||
|
{ "name": "<abbr title=\"A free, open-source tool for creating vector drawings.\">Inkscape</abbr>", "icon": "fas fa-palette", "link": "https://inkscape.org" },
|
||||||
|
{ "name": "<abbr title=\"An embroidery design extension for Inkscape, used for preparing stitching patterns.\">Ink/Stitch</abbr>", "icon": "fas fa-needle", "link": "https://inkstitch.org" },
|
||||||
|
{ "name": "<abbr title=\"An online design platform for easy graphics, posters, and more.\">Canva</abbr>", "icon": "fas fa-paint-brush", "link": "https://www.canva.com" },
|
||||||
|
{ "name": "<abbr title=\"A 3D creation platform where kids can build interactive virtual worlds.\">CoSpaces Edu</abbr>", "icon": "fas fa-vr-cardboard", "link": "https://cospaces.io/edu/" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Educational Technology",
|
||||||
|
"skills": [
|
||||||
|
{ "name": "<abbr title=\"Tiny robots that help kids learn coding through play.\">Ozobot</abbr>", "icon": "fas fa-robot", "link": "https://ozobot.com" },
|
||||||
|
{ "name": "<abbr title=\"A simple floor robot that teaches young learners basic programming.\">Blue-Bot</abbr>", "icon": "fas fa-car-side", "link": "https://www.tts-group.co.uk/blue-bot-bluetooth-programmable-floor-robot/1015267.html" },
|
||||||
|
{ "name": "<abbr title=\"A microcontroller board used for teaching coding and electronics.\">Calliope mini</abbr>", "icon": "fas fa-microchip", "link": "https://calliope.cc" },
|
||||||
|
{ "name": "<abbr title=\"A LEGO robotics kit for hands-on STEM learning.\">LEGO Spike</abbr>", "icon": "fas fa-cog", "link": "https://education.lego.com/en-us/products/lego-education-spike-prime-set-/45678" },
|
||||||
|
{ "name": "<abbr title=\"A LEGO kit designed to teach kids about robotics and engineering.\">LEGO WeDo</abbr>", "icon": "fas fa-cogs", "link": "https://education.lego.com/en-us/products/lego-education-wedo-2-0-core-set-/45300" },
|
||||||
|
{ "name": "<abbr title=\"Small drones used for aerial photography and hands-on flying demos.\">DJI Drones</abbr>", "icon": "fas fa-drone", "link": "https://www.dji.com" },
|
||||||
|
{ "name": "<abbr title=\"Programmable robot arms like those used in factories.\">Industrial Robot Arms</abbr>", "icon": "fas fa-hand-paper", "link": "#" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "3D Printing Hardware",
|
||||||
|
"skills": [
|
||||||
|
{ "name": "<abbr title=\"Printers that use liquid resin and UV light to make detailed prints.\">Resin Printers</abbr>", "icon": "fas fa-vial", "link": "#" },
|
||||||
|
{ "name": "<abbr title=\"Printers that use melted plastic filament to create 3D objects.\">Filament Printers</abbr>", "icon": "fas fa-cube", "link": "#" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Programming",
|
||||||
|
"skills": [
|
||||||
|
{ "name": "<abbr title=\"A visual block-based coding platform for kids and beginners.\">Scratch</abbr>", "icon": "fas fa-cat", "link": "https://scratch.mit.edu" },
|
||||||
|
{ "name": "<abbr title=\"An invention kit that connects everyday objects to computer programs.\">Makey Makey</abbr>", "icon": "fas fa-plug", "link": "https://makeymakey.com" },
|
||||||
|
{ "name": "<abbr title=\"A popular, beginner-friendly programming language.\">Python</abbr>", "icon": "fab fa-python", "link": "https://www.python.org" },
|
||||||
|
{ "name": "<abbr title=\"The practice of building and designing websites and web applications.\">Web Development</abbr>", "icon": "fas fa-code", "link": "#" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
{% end %}
|
||||||
|
|
76
i18n/de.toml
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
language_name = "Deutsch"
|
||||||
|
date_format = "%d. %m. %Y"
|
||||||
|
date_locale = "de_DE"
|
||||||
|
Projects = "Projekte"
|
||||||
|
Contact = "Kontakt"
|
||||||
|
CV = "Vita"
|
||||||
|
About = "Über mich"
|
||||||
|
|
||||||
|
all_tags = "Zeige alle Schlagwörter"
|
||||||
|
archived = "Archiviert"
|
||||||
|
author = "Autor"
|
||||||
|
author_conjunction = " und "
|
||||||
|
author_separator = ", "
|
||||||
|
backlinks = "Rücklink"
|
||||||
|
blog_post_author = "Autor des Blogbeitrags"
|
||||||
|
boosts_from = "Boosts von $INSTANCE"
|
||||||
|
by_author = "Von $AUTHOR"
|
||||||
|
caution = "Vorsicht"
|
||||||
|
comments = "Kommentar"
|
||||||
|
comments_description = "Du kannst diesen Blog-Beitrag kommentieren, indem du mit einem Mastodon- oder einem anderen ActivityPub/Fediverse-Konto öffentlich auf diesen Beitrag antwortest. Bekannte nicht-private Antworten werden unten angezeigt."
|
||||||
|
comments_noscript = "Das Laden von Kommentaren basiert auf JavaScript. Versuche, JavaScript zu aktivieren und neu zu laden, oder besuchen den Originalbeitrag auf Mastodon"
|
||||||
|
comments_qr = "QR code zu einem Mastodon-Beitrag"
|
||||||
|
copy_code = "Code kopieren"
|
||||||
|
disclaimer = "Haftungsausschluss"
|
||||||
|
drafted = "Entworfen"
|
||||||
|
faves_from = "Favoriten von $INSTANCE"
|
||||||
|
featured = "Herausgestellt"
|
||||||
|
feed = "Feed"
|
||||||
|
file_an_issue = "Ein Issue erstellen"
|
||||||
|
filter_by_tag = "Nach Tag filtern"
|
||||||
|
first = "Zuerst"
|
||||||
|
go_to_top = "Nach Oben gehen"
|
||||||
|
hot = "Heiß"
|
||||||
|
important = "Wichtig"
|
||||||
|
language = "Sprache"
|
||||||
|
last = "Zuletzt"
|
||||||
|
load_comments = "Kommentare laden"
|
||||||
|
loading = "Lädt"
|
||||||
|
many_minutes_read = "$NUMBER Minuten gelesen"
|
||||||
|
many_posts = "$NUMBER Beiträge insgesamt"
|
||||||
|
many_tags = "$NUMBER Schlagwörter insgesamt"
|
||||||
|
minutes_read = "$NUMBER gelesene Minuten"
|
||||||
|
more_matches = "$MATCHES mehr Treffer"
|
||||||
|
next = "Nächstes"
|
||||||
|
no_comments = "Noch keine Kommentare :/"
|
||||||
|
note = "Anmerkung"
|
||||||
|
one_posts = "$NUMBER Beitrag insgesamt"
|
||||||
|
one_tags = "$NUMBER Schlagwort insgesamt"
|
||||||
|
open_post = "Beitrag öffnen"
|
||||||
|
poor = "Schlecht"
|
||||||
|
posts = "$NUMBER Beiträge insgesamt"
|
||||||
|
posts_with_tag = "Beiträge mit Tag $TAG"
|
||||||
|
powered_by = "Gemacht mit $ZOLA und $DUCKQUILL"
|
||||||
|
previous = "Vorherige"
|
||||||
|
published = "Veröffentlicht am"
|
||||||
|
reload = "Neu laden"
|
||||||
|
repo = "Repository"
|
||||||
|
search = "Suche"
|
||||||
|
search_for = "Suche nach"
|
||||||
|
sensitive = "Heikler Inhalt"
|
||||||
|
share = "Teilen"
|
||||||
|
skip_to_content = "Zum Hauptinhalt springen"
|
||||||
|
source = "Website-Quelle"
|
||||||
|
table_of_contents = "Inhaltsverzeichnis"
|
||||||
|
tags = "Schlagwörter"
|
||||||
|
tags_title = "Schlagwörter"
|
||||||
|
theme = "Thema"
|
||||||
|
theme_dark = "Zum dunklen Thema wechseln"
|
||||||
|
theme_light = "Zum hellen Thema wechseln"
|
||||||
|
theme_system = "Systemthema nutzen"
|
||||||
|
tip = "Tipp"
|
||||||
|
trigger_warning = "Inhaltswarnung"
|
||||||
|
updated = "Aktualisiert am"
|
||||||
|
view_comment = "Kommentar anzeigen auf"
|
||||||
|
view_profile = "Profil anzeigen auf"
|
||||||
|
warning = "Warnung"
|
16
old_config.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# The URL the site will be built for
|
||||||
|
base_url = "https://studio-umzu.de"
|
||||||
|
|
||||||
|
# Whether to automatically compile all Sass files in the sass directory
|
||||||
|
compile_sass = true
|
||||||
|
|
||||||
|
# Whether to build a search index to be used later on by a JavaScript library
|
||||||
|
build_search_index = true
|
||||||
|
|
||||||
|
[markdown]
|
||||||
|
# Whether to do syntax highlighting
|
||||||
|
# Theme can be customised by setting the `highlight_theme` variable to a theme supported by Zola
|
||||||
|
highlight_code = true
|
||||||
|
|
||||||
|
[extra]
|
||||||
|
# Put all your custom variables here
|
BIN
public/404.gif
Normal file
After Width: | Height: | Size: 4 KiB |
2
public/404.html
Normal file
BIN
public/404.png
Normal file
After Width: | Height: | Size: 340 B |
BIN
public/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 28 KiB |
9
public/atom.xml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
|
||||||
|
<title>Studio UMZU</title>
|
||||||
|
<link rel="self" type="application/atom+xml" href="https://studio-umzu.de/atom.xml"/>
|
||||||
|
<link rel="alternate" type="text/html" href="https://studio-umzu.de/"/>
|
||||||
|
<generator uri="https://www.getzola.org/">Zola</generator>
|
||||||
|
|
||||||
|
<id>https://studio-umzu.de/atom.xml</id>
|
||||||
|
</feed>
|
1
public/auto-render.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("katex")):"function"==typeof define&&define.amd?define(["katex"],t):"object"==typeof exports?exports.renderMathInElement=t(require("katex")):e.renderMathInElement=t(e.katex)}("undefined"!=typeof self?self:this,(function(e){return function(){"use strict";var t={771:function(t){t.exports=e}},n={};function r(e){var o=n[e];if(void 0!==o)return o.exports;var i=n[e]={exports:{}};return t[e](i,i.exports,r),i.exports}r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,{a:t}),t},r.d=function(e,t){for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)};var o={};return function(){r.d(o,{default:function(){return d}});var e=r(771),t=r.n(e);const n=function(e,t,n){let r=n,o=0;const i=e.length;for(;r<t.length;){const n=t[r];if(o<=0&&t.slice(r,r+i)===e)return r;"\\"===n?r++:"{"===n?o++:"}"===n&&o--,r++}return-1},i=/^\\begin{/;var a=function(e,t){let r;const o=[],a=new RegExp("("+t.map((e=>e.left.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"))).join("|")+")");for(;r=e.search(a),-1!==r;){r>0&&(o.push({type:"text",data:e.slice(0,r)}),e=e.slice(r));const a=t.findIndex((t=>e.startsWith(t.left)));if(r=n(t[a].right,e,t[a].left.length),-1===r)break;const l=e.slice(0,r+t[a].right.length),s=i.test(l)?l:e.slice(t[a].left.length,r);o.push({type:"math",data:s,rawData:l,display:t[a].display}),e=e.slice(r+t[a].right.length)}return""!==e&&o.push({type:"text",data:e}),o};const l=function(e,n){const r=a(e,n.delimiters);if(1===r.length&&"text"===r[0].type)return null;const o=document.createDocumentFragment();for(let e=0;e<r.length;e++)if("text"===r[e].type)o.appendChild(document.createTextNode(r[e].data));else{const i=document.createElement("span");let a=r[e].data;n.displayMode=r[e].display;try{n.preProcess&&(a=n.preProcess(a)),t().render(a,i,n)}catch(i){if(!(i instanceof t().ParseError))throw i;n.errorCallback("KaTeX auto-render: Failed to parse `"+r[e].data+"` with ",i),o.appendChild(document.createTextNode(r[e].rawData));continue}o.appendChild(i)}return o},s=function(e,t){for(let n=0;n<e.childNodes.length;n++){const r=e.childNodes[n];if(3===r.nodeType){let o=r.textContent,i=r.nextSibling,a=0;for(;i&&i.nodeType===Node.TEXT_NODE;)o+=i.textContent,i=i.nextSibling,a++;const s=l(o,t);if(s){for(let e=0;e<a;e++)r.nextSibling.remove();n+=s.childNodes.length-1,e.replaceChild(s,r)}else n+=a}else if(1===r.nodeType){const e=" "+r.className+" ";-1===t.ignoredTags.indexOf(r.nodeName.toLowerCase())&&t.ignoredClasses.every((t=>-1===e.indexOf(" "+t+" ")))&&s(r,t)}}};var d=function(e,t){if(!e)throw new Error("No element provided to render");const n={};for(const e in t)t.hasOwnProperty(e)&&(n[e]=t[e]);n.delimiters=n.delimiters||[{left:"$$",right:"$$",display:!0},{left:"\\(",right:"\\)",display:!1},{left:"\\begin{equation}",right:"\\end{equation}",display:!0},{left:"\\begin{align}",right:"\\end{align}",display:!0},{left:"\\begin{alignat}",right:"\\end{alignat}",display:!0},{left:"\\begin{gather}",right:"\\end{gather}",display:!0},{left:"\\begin{CD}",right:"\\end{CD}",display:!0},{left:"\\[",right:"\\]",display:!0}],n.ignoredTags=n.ignoredTags||["script","noscript","style","textarea","pre","code","option"],n.ignoredClasses=n.ignoredClasses||[],n.errorCallback=n.errorCallback||console.error,n.macros=n.macros||{},s(e,n)}}(),o=o.default}()}));
|
BIN
public/card.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
27
public/closable.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
const closable = document.querySelectorAll("details.closable");
|
||||||
|
|
||||||
|
closable.forEach((detail) => {
|
||||||
|
detail.addEventListener("toggle", () => {
|
||||||
|
if (detail.open) setTargetDetail(detail);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function setTargetDetail(targetDetail) {
|
||||||
|
closable.forEach((detail) => {
|
||||||
|
if (detail !== targetDetail) {
|
||||||
|
detail.open = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("click", function (event) {
|
||||||
|
const isClickInsideDetail = [...closable].some((detail) =>
|
||||||
|
detail.contains(event.target)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isClickInsideDetail) {
|
||||||
|
closable.forEach((detail) => {
|
||||||
|
detail.open = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
406
public/comments.js
Normal file
|
@ -0,0 +1,406 @@
|
||||||
|
// Taken from https://carlschwan.eu/2020/12/29/adding-comments-to-your-static-blog-with-mastodon/
|
||||||
|
// Attachment, card, and spoiler code taken from https://github.com/cassidyjames/cassidyjames.github.io/blob/99782788a7e3ba3cc52d6803010873abd1b02b9e/_includes/comments.html#L251-L296
|
||||||
|
|
||||||
|
let blogPostAuthorText = document.getElementById("blog-post-author-text").textContent;
|
||||||
|
let boostsFromText = document.getElementById("boosts-from-text").textContent;
|
||||||
|
let dateLocale = document.getElementById("date-locale").textContent;
|
||||||
|
let favesFromText = document.getElementById("faves-from-text").textContent;
|
||||||
|
let host = document.getElementById("host").textContent;
|
||||||
|
let id = document.getElementById("id").textContent;
|
||||||
|
let lazyAsyncImage = document.getElementById("lazy-async-image").textContent;
|
||||||
|
let loadingText = document.getElementById("loading-text").textContent;
|
||||||
|
let noCommentsText = document.getElementById("no-comments-text").textContent;
|
||||||
|
let relAttributes = document.getElementById("rel-attributes").textContent;
|
||||||
|
let reloadText = document.getElementById("reload-text").textContent;
|
||||||
|
let sensitiveText = document.getElementById("sensitive-text").textContent;
|
||||||
|
let user = document.getElementById("user").textContent;
|
||||||
|
let viewCommentText = document.getElementById("view-comment-text").textContent;
|
||||||
|
let viewProfileText = document.getElementById("view-profile-text").textContent;
|
||||||
|
|
||||||
|
document.getElementById("load-comments").addEventListener("click", loadComments);
|
||||||
|
|
||||||
|
function escapeHtml(unsafe) {
|
||||||
|
return unsafe
|
||||||
|
.replace(/&/g, "&")
|
||||||
|
.replace(/</g, "<")
|
||||||
|
.replace(/>/g, ">")
|
||||||
|
.replace(/"/g, """)
|
||||||
|
.replace(/'/g, "'");
|
||||||
|
}
|
||||||
|
function emojify(input, emojis) {
|
||||||
|
let output = input;
|
||||||
|
|
||||||
|
emojis.forEach((emoji) => {
|
||||||
|
let picture = document.createElement("picture");
|
||||||
|
|
||||||
|
let source = document.createElement("source");
|
||||||
|
source.setAttribute("srcset", escapeHtml(emoji.url));
|
||||||
|
source.setAttribute("media", "(prefers-reduced-motion: no-preference)");
|
||||||
|
|
||||||
|
let img = document.createElement("img");
|
||||||
|
img.className = "emoji";
|
||||||
|
img.setAttribute("src", escapeHtml(emoji.static_url));
|
||||||
|
img.setAttribute("alt", `:${emoji.shortcode}:`);
|
||||||
|
img.setAttribute("title", `:${emoji.shortcode}:`);
|
||||||
|
if (lazyAsyncImage == "true") {
|
||||||
|
img.setAttribute("decoding", "async");
|
||||||
|
img.setAttribute("loading", "lazy");
|
||||||
|
}
|
||||||
|
|
||||||
|
picture.appendChild(source);
|
||||||
|
picture.appendChild(img);
|
||||||
|
|
||||||
|
output = output.replace(`:${emoji.shortcode}:`, picture.outerHTML);
|
||||||
|
});
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadComments() {
|
||||||
|
let commentsWrapper = document.getElementById("comments-wrapper");
|
||||||
|
commentsWrapper.innerHTML = "";
|
||||||
|
|
||||||
|
let loadCommentsButton = document.getElementById("load-comments");
|
||||||
|
loadCommentsButton.innerHTML = loadingText;
|
||||||
|
loadCommentsButton.disabled = true;
|
||||||
|
|
||||||
|
fetch(`https://${host}/api/v1/statuses/${id}/context`)
|
||||||
|
.then(function (response) {
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(function (data) {
|
||||||
|
let descendants = data["descendants"];
|
||||||
|
if (
|
||||||
|
descendants &&
|
||||||
|
Array.isArray(descendants) &&
|
||||||
|
descendants.length > 0
|
||||||
|
) {
|
||||||
|
commentsWrapper.innerHTML = "";
|
||||||
|
|
||||||
|
descendants.forEach(function (status) {
|
||||||
|
console.log(descendants);
|
||||||
|
if (status.account.display_name.length > 0) {
|
||||||
|
status.account.display_name = escapeHtml(
|
||||||
|
status.account.display_name
|
||||||
|
);
|
||||||
|
status.account.display_name = emojify(
|
||||||
|
status.account.display_name,
|
||||||
|
status.account.emojis
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
status.account.display_name = status.account.username;
|
||||||
|
}
|
||||||
|
|
||||||
|
let instance = "";
|
||||||
|
if (status.account.acct.includes("@")) {
|
||||||
|
instance = status.account.acct.split("@")[1];
|
||||||
|
} else {
|
||||||
|
instance = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isReply = status.in_reply_to_id !== id;
|
||||||
|
|
||||||
|
let op = false;
|
||||||
|
if (status.account.acct == user) {
|
||||||
|
op = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
status.content = emojify(status.content, status.emojis);
|
||||||
|
|
||||||
|
let comment = document.createElement("article");
|
||||||
|
comment.id = `comment-${status.id}`;
|
||||||
|
comment.className = isReply ? "comment comment-reply" : "comment";
|
||||||
|
comment.setAttribute("itemprop", "comment");
|
||||||
|
comment.setAttribute("itemtype", "http://schema.org/Comment");
|
||||||
|
|
||||||
|
let avatarSource = document.createElement("source");
|
||||||
|
avatarSource.setAttribute(
|
||||||
|
"srcset",
|
||||||
|
escapeHtml(status.account.avatar)
|
||||||
|
);
|
||||||
|
avatarSource.setAttribute(
|
||||||
|
"media",
|
||||||
|
"(prefers-reduced-motion: no-preference)"
|
||||||
|
);
|
||||||
|
|
||||||
|
let avatarImg = document.createElement("img");
|
||||||
|
avatarImg.className = "avatar";
|
||||||
|
avatarImg.setAttribute(
|
||||||
|
"src",
|
||||||
|
escapeHtml(status.account.avatar_static)
|
||||||
|
);
|
||||||
|
avatarImg.setAttribute(
|
||||||
|
"alt",
|
||||||
|
`@${status.account.username}@${instance} avatar`
|
||||||
|
);
|
||||||
|
if (lazyAsyncImage == "true") {
|
||||||
|
avatarImg.setAttribute("decoding", "async");
|
||||||
|
avatarImg.setAttribute("loading", "lazy");
|
||||||
|
}
|
||||||
|
|
||||||
|
let avatarPicture = document.createElement("picture");
|
||||||
|
avatarPicture.appendChild(avatarSource);
|
||||||
|
avatarPicture.appendChild(avatarImg);
|
||||||
|
|
||||||
|
let avatar = document.createElement("a");
|
||||||
|
avatar.className = "avatar-link";
|
||||||
|
avatar.setAttribute("href", status.account.url);
|
||||||
|
avatar.setAttribute("rel", relAttributes);
|
||||||
|
avatar.setAttribute(
|
||||||
|
"title",
|
||||||
|
`${viewProfileText} @${status.account.username}@${instance}`
|
||||||
|
);
|
||||||
|
avatar.appendChild(avatarPicture);
|
||||||
|
comment.appendChild(avatar);
|
||||||
|
|
||||||
|
let instanceBadge = document.createElement("a");
|
||||||
|
instanceBadge.className = "instance";
|
||||||
|
instanceBadge.setAttribute("href", status.account.url);
|
||||||
|
instanceBadge.setAttribute(
|
||||||
|
"title",
|
||||||
|
`@${status.account.username}@${instance}`
|
||||||
|
);
|
||||||
|
instanceBadge.setAttribute("rel", relAttributes);
|
||||||
|
instanceBadge.textContent = instance;
|
||||||
|
|
||||||
|
let display = document.createElement("span");
|
||||||
|
display.className = "display";
|
||||||
|
display.setAttribute("itemprop", "author");
|
||||||
|
display.setAttribute("itemtype", "http://schema.org/Person");
|
||||||
|
display.innerHTML = status.account.display_name;
|
||||||
|
|
||||||
|
let header = document.createElement("header");
|
||||||
|
header.className = "author";
|
||||||
|
header.appendChild(display);
|
||||||
|
header.appendChild(instanceBadge);
|
||||||
|
comment.appendChild(header);
|
||||||
|
|
||||||
|
let permalink = document.createElement("a");
|
||||||
|
permalink.setAttribute("href", status.url);
|
||||||
|
permalink.setAttribute("itemprop", "url");
|
||||||
|
permalink.setAttribute("title", `${viewCommentText} ${instance}`);
|
||||||
|
permalink.setAttribute("rel", relAttributes);
|
||||||
|
permalink.textContent = new Date(
|
||||||
|
status.created_at
|
||||||
|
).toLocaleString(dateLocale, {
|
||||||
|
dateStyle: "long",
|
||||||
|
timeStyle: "short",
|
||||||
|
});
|
||||||
|
|
||||||
|
let timestamp = document.createElement("time");
|
||||||
|
timestamp.setAttribute("datetime", status.created_at);
|
||||||
|
timestamp.appendChild(permalink);
|
||||||
|
permalink.classList.add("external");
|
||||||
|
comment.appendChild(timestamp);
|
||||||
|
|
||||||
|
let main = document.createElement("main");
|
||||||
|
main.setAttribute("itemprop", "text");
|
||||||
|
|
||||||
|
if (status.sensitive == true || status.spoiler_text != "") {
|
||||||
|
let summary = document.createElement("summary");
|
||||||
|
if (status.spoiler_text == "") {
|
||||||
|
status.spoiler_text == sensitiveText;
|
||||||
|
}
|
||||||
|
summary.innerHTML = status.spoiler_text;
|
||||||
|
|
||||||
|
let spoiler = document.createElement("details");
|
||||||
|
spoiler.appendChild(summary);
|
||||||
|
spoiler.innerHTML += status.content;
|
||||||
|
|
||||||
|
main.appendChild(spoiler);
|
||||||
|
} else {
|
||||||
|
main.innerHTML = status.content;
|
||||||
|
}
|
||||||
|
comment.appendChild(main);
|
||||||
|
|
||||||
|
let attachments = status.media_attachments;
|
||||||
|
let SUPPORTED_MEDIA = ["image", "video", "gifv", "audio"];
|
||||||
|
let media = document.createElement("div");
|
||||||
|
media.className = "attachments";
|
||||||
|
if (
|
||||||
|
attachments &&
|
||||||
|
Array.isArray(attachments) &&
|
||||||
|
attachments.length > 0
|
||||||
|
) {
|
||||||
|
attachments.forEach((attachment) => {
|
||||||
|
if (SUPPORTED_MEDIA.includes(attachment.type)) {
|
||||||
|
|
||||||
|
let mediaElement;
|
||||||
|
switch (attachment.type) {
|
||||||
|
case "image":
|
||||||
|
mediaElement = document.createElement("img");
|
||||||
|
mediaElement.setAttribute("src", attachment.preview_url);
|
||||||
|
|
||||||
|
if (attachment.description != null) {
|
||||||
|
mediaElement.setAttribute("alt", attachment.description);
|
||||||
|
mediaElement.setAttribute("title", attachment.description);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lazyAsyncImage == "true") {
|
||||||
|
mediaElement.setAttribute("decoding", "async");
|
||||||
|
mediaElement.setAttribute("loading", "lazy");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status.sensitive == true) {
|
||||||
|
mediaElement.classList.add("spoiler");
|
||||||
|
}
|
||||||
|
|
||||||
|
media.appendChild(mediaElement);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "video":
|
||||||
|
mediaElement = document.createElement("video");
|
||||||
|
mediaElement.setAttribute("src", attachment.url);
|
||||||
|
mediaElement.setAttribute("controls", "");
|
||||||
|
|
||||||
|
if (attachment.description != null) {
|
||||||
|
mediaElement.setAttribute("aria-title", attachment.description);
|
||||||
|
mediaElement.setAttribute("title", attachment.description);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status.sensitive == true) {
|
||||||
|
mediaElement.classList.add("spoiler");
|
||||||
|
}
|
||||||
|
|
||||||
|
media.appendChild(mediaElement);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "gifv":
|
||||||
|
mediaElement = document.createElement("video");
|
||||||
|
mediaElement.setAttribute("src", attachment.url);
|
||||||
|
mediaElement.setAttribute("autoplay", "");
|
||||||
|
mediaElement.setAttribute("playsinline", "");
|
||||||
|
mediaElement.setAttribute("loop", "");
|
||||||
|
|
||||||
|
if (attachment.description != null) {
|
||||||
|
mediaElement.setAttribute("aria-title", attachment.description);
|
||||||
|
mediaElement.setAttribute("title", attachment.description);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status.sensitive == true) {
|
||||||
|
mediaElement.classList.add("spoiler");
|
||||||
|
}
|
||||||
|
|
||||||
|
media.appendChild(mediaElement);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "audio":
|
||||||
|
mediaElement = document.createElement("audio");
|
||||||
|
mediaElement.setAttribute("src", attachment.url);
|
||||||
|
mediaElement.setAttribute("controls", "");
|
||||||
|
|
||||||
|
if (attachment.description != null) {
|
||||||
|
mediaElement.setAttribute("aria-title", attachment.description);
|
||||||
|
mediaElement.setAttribute("title", attachment.description);
|
||||||
|
}
|
||||||
|
|
||||||
|
media.appendChild(mediaElement);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mediaLink = document.createElement("a");
|
||||||
|
mediaLink.setAttribute("href", attachment.url);
|
||||||
|
mediaLink.setAttribute("rel", relAttributes);
|
||||||
|
mediaLink.appendChild(mediaElement);
|
||||||
|
|
||||||
|
media.appendChild(mediaLink);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
comment.appendChild(media);
|
||||||
|
}
|
||||||
|
|
||||||
|
let interactions = document.createElement("footer");
|
||||||
|
|
||||||
|
let boosts = document.createElement("a");
|
||||||
|
boosts.className = "boosts";
|
||||||
|
boosts.setAttribute("href", `${status.url}/reblogs`);
|
||||||
|
boosts.setAttribute("title", `${boostsFromText}`.replace("$INSTANCE", instance));
|
||||||
|
|
||||||
|
let boostsIcon = document.createElement("i");
|
||||||
|
boostsIcon.className = "icon";
|
||||||
|
boosts.appendChild(boostsIcon);
|
||||||
|
boosts.insertAdjacentHTML('beforeend', ` ${status.reblogs_count}`);
|
||||||
|
interactions.appendChild(boosts);
|
||||||
|
|
||||||
|
let faves = document.createElement("a");
|
||||||
|
faves.className = "faves";
|
||||||
|
faves.setAttribute("href", `${status.url}/favourites`);
|
||||||
|
faves.setAttribute("title", `${favesFromText}`.replace("$INSTANCE", instance));
|
||||||
|
|
||||||
|
let favesIcon = document.createElement("i");
|
||||||
|
favesIcon.className = "icon";
|
||||||
|
faves.appendChild(favesIcon);
|
||||||
|
faves.insertAdjacentHTML('beforeend', ` ${status.favourites_count}`);
|
||||||
|
interactions.appendChild(faves);
|
||||||
|
comment.appendChild(interactions);
|
||||||
|
|
||||||
|
if (status.card != null) {
|
||||||
|
let cardFigure = document.createElement("figure");
|
||||||
|
|
||||||
|
if (status.card.image != null) {
|
||||||
|
let cardImg = document.createElement("img");
|
||||||
|
cardImg.setAttribute("src", status.card.image);
|
||||||
|
cardImg.classList.add("no-hover");
|
||||||
|
cardFigure.appendChild(cardImg);
|
||||||
|
}
|
||||||
|
|
||||||
|
let cardCaption = document.createElement("figcaption");
|
||||||
|
|
||||||
|
let cardTitle = document.createElement("strong");
|
||||||
|
cardTitle.innerHTML = status.card.title;
|
||||||
|
cardCaption.appendChild(cardTitle);
|
||||||
|
|
||||||
|
if (status.card.description != null && status.card.description.length > 0) {
|
||||||
|
let cardDescription = document.createElement("p");
|
||||||
|
cardDescription.innerHTML = status.card.description;
|
||||||
|
cardCaption.appendChild(cardDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
cardFigure.appendChild(cardCaption);
|
||||||
|
|
||||||
|
let card = document.createElement("a");
|
||||||
|
card.className = "card";
|
||||||
|
card.setAttribute("href", status.card.url);
|
||||||
|
card.setAttribute("rel", relAttributes);
|
||||||
|
card.appendChild(cardFigure);
|
||||||
|
|
||||||
|
comment.appendChild(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op === true) {
|
||||||
|
comment.classList.add("op");
|
||||||
|
|
||||||
|
avatar.classList.add("op");
|
||||||
|
avatar.setAttribute(
|
||||||
|
"title",
|
||||||
|
`${blogPostAuthorText}: ` + avatar.getAttribute("title")
|
||||||
|
);
|
||||||
|
|
||||||
|
instanceBadge.classList.add("op");
|
||||||
|
instanceBadge.setAttribute(
|
||||||
|
"title",
|
||||||
|
`${blogPostAuthorText}: ` + instanceBadge.getAttribute("title")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
commentsWrapper.innerHTML += comment.outerHTML;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
var statusText = document.createElement("p");
|
||||||
|
statusText.innerHTML = noCommentsText;
|
||||||
|
statusText.setAttribute("id", "comments-status");
|
||||||
|
commentsWrapper.appendChild(statusText);
|
||||||
|
}
|
||||||
|
|
||||||
|
loadCommentsButton.innerHTML = reloadText;
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
console.error('Error loading comments:', error);
|
||||||
|
})
|
||||||
|
.finally(function () {
|
||||||
|
loadCommentsButton.disabled = false;
|
||||||
|
});
|
||||||
|
}
|
57
public/copy-button.js
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
// Based on https://www.roboleary.net/2022/01/13/copy-code-to-clipboard-blog.html
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
let blocks = document.querySelectorAll("pre[class^='language-']");
|
||||||
|
|
||||||
|
blocks.forEach((block) => {
|
||||||
|
if (navigator.clipboard) {
|
||||||
|
// Code block header title
|
||||||
|
let title = document.createElement("span");
|
||||||
|
let lang = block.getAttribute("data-lang");
|
||||||
|
title.innerHTML = lang;
|
||||||
|
|
||||||
|
// Copy button icon
|
||||||
|
let icon = document.createElement("i");
|
||||||
|
icon.classList.add("icon");
|
||||||
|
|
||||||
|
// Copy button
|
||||||
|
let button = document.createElement("button");
|
||||||
|
let copyCodeText = document.getElementById("copy-code-text").textContent;
|
||||||
|
button.setAttribute("title", copyCodeText)
|
||||||
|
button.appendChild(icon);
|
||||||
|
|
||||||
|
// Code block header
|
||||||
|
let header = document.createElement("div");
|
||||||
|
header.classList.add("header");
|
||||||
|
header.appendChild(title);
|
||||||
|
header.appendChild(button);
|
||||||
|
|
||||||
|
// Container that holds header and the code block itself
|
||||||
|
let container = document.createElement("div");
|
||||||
|
container.classList.add("pre-container");
|
||||||
|
container.appendChild(header);
|
||||||
|
|
||||||
|
// Move code block into the container
|
||||||
|
block.parentNode.insertBefore(container, block);
|
||||||
|
container.appendChild(block);
|
||||||
|
|
||||||
|
button.addEventListener("click", async () => {
|
||||||
|
await copyCode(block, header, button); // Pass the button here
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
async function copyCode(block, header, button) {
|
||||||
|
let code = block.querySelector("code");
|
||||||
|
let text = code.innerText;
|
||||||
|
|
||||||
|
await navigator.clipboard.writeText(text);
|
||||||
|
|
||||||
|
header.classList.add("active");
|
||||||
|
button.setAttribute("disabled", true);
|
||||||
|
|
||||||
|
header.addEventListener("animationend", () => {
|
||||||
|
header.classList.remove("active");
|
||||||
|
button.removeAttribute("disabled");
|
||||||
|
}, { once: true });
|
||||||
|
}
|
||||||
|
});
|
271
public/count.js
Normal file
|
@ -0,0 +1,271 @@
|
||||||
|
// GoatCounter: https://www.goatcounter.com
|
||||||
|
// This file is released under the ISC license: https://opensource.org/licenses/ISC
|
||||||
|
;(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
if (window.goatcounter && window.goatcounter.vars) // Compatibility with very old version; do not use.
|
||||||
|
window.goatcounter = window.goatcounter.vars
|
||||||
|
else
|
||||||
|
window.goatcounter = window.goatcounter || {}
|
||||||
|
|
||||||
|
// Load settings from data-goatcounter-settings.
|
||||||
|
var s = document.querySelector('script[data-goatcounter]')
|
||||||
|
if (s && s.dataset.goatcounterSettings) {
|
||||||
|
try { var set = JSON.parse(s.dataset.goatcounterSettings) }
|
||||||
|
catch (err) { console.error('invalid JSON in data-goatcounter-settings: ' + err) }
|
||||||
|
for (var k in set)
|
||||||
|
if (['no_onload', 'no_events', 'allow_local', 'allow_frame', 'path', 'title', 'referrer', 'event'].indexOf(k) > -1)
|
||||||
|
window.goatcounter[k] = set[k]
|
||||||
|
}
|
||||||
|
|
||||||
|
var enc = encodeURIComponent
|
||||||
|
|
||||||
|
// Get all data we're going to send off to the counter endpoint.
|
||||||
|
var get_data = function(vars) {
|
||||||
|
var data = {
|
||||||
|
p: (vars.path === undefined ? goatcounter.path : vars.path),
|
||||||
|
r: (vars.referrer === undefined ? goatcounter.referrer : vars.referrer),
|
||||||
|
t: (vars.title === undefined ? goatcounter.title : vars.title),
|
||||||
|
e: !!(vars.event || goatcounter.event),
|
||||||
|
s: [window.screen.width, window.screen.height, (window.devicePixelRatio || 1)],
|
||||||
|
b: is_bot(),
|
||||||
|
q: location.search,
|
||||||
|
}
|
||||||
|
|
||||||
|
var rcb, pcb, tcb // Save callbacks to apply later.
|
||||||
|
if (typeof(data.r) === 'function') rcb = data.r
|
||||||
|
if (typeof(data.t) === 'function') tcb = data.t
|
||||||
|
if (typeof(data.p) === 'function') pcb = data.p
|
||||||
|
|
||||||
|
if (is_empty(data.r)) data.r = document.referrer
|
||||||
|
if (is_empty(data.t)) data.t = document.title
|
||||||
|
if (is_empty(data.p)) data.p = get_path()
|
||||||
|
|
||||||
|
if (rcb) data.r = rcb(data.r)
|
||||||
|
if (tcb) data.t = tcb(data.t)
|
||||||
|
if (pcb) data.p = pcb(data.p)
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a value is "empty" for the purpose of get_data().
|
||||||
|
var is_empty = function(v) { return v === null || v === undefined || typeof(v) === 'function' }
|
||||||
|
|
||||||
|
// See if this looks like a bot; there is some additional filtering on the
|
||||||
|
// backend, but these properties can't be fetched from there.
|
||||||
|
var is_bot = function() {
|
||||||
|
// Headless browsers are probably a bot.
|
||||||
|
var w = window, d = document
|
||||||
|
if (w.callPhantom || w._phantom || w.phantom)
|
||||||
|
return 150
|
||||||
|
if (w.__nightmare)
|
||||||
|
return 151
|
||||||
|
if (d.__selenium_unwrapped || d.__webdriver_evaluate || d.__driver_evaluate)
|
||||||
|
return 152
|
||||||
|
if (navigator.webdriver)
|
||||||
|
return 153
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Object to urlencoded string, starting with a ?.
|
||||||
|
var urlencode = function(obj) {
|
||||||
|
var p = []
|
||||||
|
for (var k in obj)
|
||||||
|
if (obj[k] !== '' && obj[k] !== null && obj[k] !== undefined && obj[k] !== false)
|
||||||
|
p.push(enc(k) + '=' + enc(obj[k]))
|
||||||
|
return '?' + p.join('&')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show a warning in the console.
|
||||||
|
var warn = function(msg) {
|
||||||
|
if (console && 'warn' in console)
|
||||||
|
console.warn('goatcounter: ' + msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the endpoint to send requests to.
|
||||||
|
var get_endpoint = function() {
|
||||||
|
var s = document.querySelector('script[data-goatcounter]')
|
||||||
|
if (s && s.dataset.goatcounter)
|
||||||
|
return s.dataset.goatcounter
|
||||||
|
return (goatcounter.endpoint || window.counter) // counter is for compat; don't use.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current path.
|
||||||
|
var get_path = function() {
|
||||||
|
var loc = location,
|
||||||
|
c = document.querySelector('link[rel="canonical"][href]')
|
||||||
|
if (c) { // May be relative or point to different domain.
|
||||||
|
var a = document.createElement('a')
|
||||||
|
a.href = c.href
|
||||||
|
if (a.hostname.replace(/^www\./, '') === location.hostname.replace(/^www\./, ''))
|
||||||
|
loc = a
|
||||||
|
}
|
||||||
|
return (loc.pathname + loc.search) || '/'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run function after DOM is loaded.
|
||||||
|
var on_load = function(f) {
|
||||||
|
if (document.body === null)
|
||||||
|
document.addEventListener('DOMContentLoaded', function() { f() }, false)
|
||||||
|
else
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter some requests that we (probably) don't want to count.
|
||||||
|
goatcounter.filter = function() {
|
||||||
|
if ('visibilityState' in document && document.visibilityState === 'prerender')
|
||||||
|
return 'visibilityState'
|
||||||
|
if (!goatcounter.allow_frame && location !== parent.location)
|
||||||
|
return 'frame'
|
||||||
|
if (!goatcounter.allow_local && location.hostname.match(/(localhost$|^127\.|^10\.|^172\.(1[6-9]|2[0-9]|3[0-1])\.|^192\.168\.|^0\.0\.0\.0$)/))
|
||||||
|
return 'localhost'
|
||||||
|
if (!goatcounter.allow_local && location.protocol === 'file:')
|
||||||
|
return 'localfile'
|
||||||
|
if (localStorage && localStorage.getItem('skipgc') === 't')
|
||||||
|
return 'disabled with #toggle-goatcounter'
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get URL to send to GoatCounter.
|
||||||
|
window.goatcounter.url = function(vars) {
|
||||||
|
var data = get_data(vars || {})
|
||||||
|
if (data.p === null) // null from user callback.
|
||||||
|
return
|
||||||
|
data.rnd = Math.random().toString(36).substr(2, 5) // Browsers don't always listen to Cache-Control.
|
||||||
|
|
||||||
|
var endpoint = get_endpoint()
|
||||||
|
if (!endpoint)
|
||||||
|
return warn('no endpoint found')
|
||||||
|
|
||||||
|
return endpoint + urlencode(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count a hit.
|
||||||
|
window.goatcounter.count = function(vars) {
|
||||||
|
var f = goatcounter.filter()
|
||||||
|
if (f)
|
||||||
|
return warn('not counting because of: ' + f)
|
||||||
|
var url = goatcounter.url(vars)
|
||||||
|
if (!url)
|
||||||
|
return warn('not counting because path callback returned null')
|
||||||
|
|
||||||
|
if (!navigator.sendBeacon(url)) {
|
||||||
|
// This mostly fails due to being blocked by CSP; try again with an
|
||||||
|
// image-based fallback.
|
||||||
|
var img = document.createElement('img')
|
||||||
|
img.src = url
|
||||||
|
img.style.position = 'absolute' // Affect layout less.
|
||||||
|
img.style.bottom = '0px'
|
||||||
|
img.style.width = '1px'
|
||||||
|
img.style.height = '1px'
|
||||||
|
img.loading = 'eager'
|
||||||
|
img.setAttribute('alt', '')
|
||||||
|
img.setAttribute('aria-hidden', 'true')
|
||||||
|
|
||||||
|
var rm = function() { if (img && img.parentNode) img.parentNode.removeChild(img) }
|
||||||
|
img.addEventListener('load', rm, false)
|
||||||
|
document.body.appendChild(img)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a query parameter.
|
||||||
|
window.goatcounter.get_query = function(name) {
|
||||||
|
var s = location.search.substr(1).split('&')
|
||||||
|
for (var i = 0; i < s.length; i++)
|
||||||
|
if (s[i].toLowerCase().indexOf(name.toLowerCase() + '=') === 0)
|
||||||
|
return s[i].substr(name.length + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Track click events.
|
||||||
|
window.goatcounter.bind_events = function() {
|
||||||
|
if (!document.querySelectorAll) // Just in case someone uses an ancient browser.
|
||||||
|
return
|
||||||
|
|
||||||
|
var send = function(elem) {
|
||||||
|
return function() {
|
||||||
|
goatcounter.count({
|
||||||
|
event: true,
|
||||||
|
path: (elem.dataset.goatcounterClick || elem.name || elem.id || ''),
|
||||||
|
title: (elem.dataset.goatcounterTitle || elem.title || (elem.innerHTML || '').substr(0, 200) || ''),
|
||||||
|
referrer: (elem.dataset.goatcounterReferrer || elem.dataset.goatcounterReferral || ''),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.prototype.slice.call(document.querySelectorAll("*[data-goatcounter-click]")).forEach(function(elem) {
|
||||||
|
if (elem.dataset.goatcounterBound)
|
||||||
|
return
|
||||||
|
var f = send(elem)
|
||||||
|
elem.addEventListener('click', f, false)
|
||||||
|
elem.addEventListener('auxclick', f, false) // Middle click.
|
||||||
|
elem.dataset.goatcounterBound = 'true'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a "visitor counter" frame or image.
|
||||||
|
window.goatcounter.visit_count = function(opt) {
|
||||||
|
on_load(function() {
|
||||||
|
opt = opt || {}
|
||||||
|
opt.type = opt.type || 'html'
|
||||||
|
opt.append = opt.append || 'body'
|
||||||
|
opt.path = opt.path || get_path()
|
||||||
|
opt.attr = opt.attr || {width: '200', height: (opt.no_branding ? '60' : '80')}
|
||||||
|
|
||||||
|
opt.attr['src'] = get_endpoint() + 'er/' + enc(opt.path) + '.' + enc(opt.type) + '?'
|
||||||
|
if (opt.no_branding) opt.attr['src'] += '&no_branding=1'
|
||||||
|
if (opt.style) opt.attr['src'] += '&style=' + enc(opt.style)
|
||||||
|
if (opt.start) opt.attr['src'] += '&start=' + enc(opt.start)
|
||||||
|
if (opt.end) opt.attr['src'] += '&end=' + enc(opt.end)
|
||||||
|
|
||||||
|
var tag = {png: 'img', svg: 'img', html: 'iframe'}[opt.type]
|
||||||
|
if (!tag)
|
||||||
|
return warn('visit_count: unknown type: ' + opt.type)
|
||||||
|
|
||||||
|
if (opt.type === 'html') {
|
||||||
|
opt.attr['frameborder'] = '0'
|
||||||
|
opt.attr['scrolling'] = 'no'
|
||||||
|
}
|
||||||
|
|
||||||
|
var d = document.createElement(tag)
|
||||||
|
for (var k in opt.attr)
|
||||||
|
d.setAttribute(k, opt.attr[k])
|
||||||
|
|
||||||
|
var p = document.querySelector(opt.append)
|
||||||
|
if (!p)
|
||||||
|
return warn('visit_count: append not found: ' + opt.append)
|
||||||
|
p.appendChild(d)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make it easy to skip your own views.
|
||||||
|
if (location.hash === '#toggle-goatcounter') {
|
||||||
|
if (localStorage.getItem('skipgc') === 't') {
|
||||||
|
localStorage.removeItem('skipgc', 't')
|
||||||
|
alert('GoatCounter tracking is now ENABLED in this browser.')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
localStorage.setItem('skipgc', 't')
|
||||||
|
alert('GoatCounter tracking is now DISABLED in this browser until ' + location + ' is loaded again.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!goatcounter.no_onload)
|
||||||
|
on_load(function() {
|
||||||
|
// 1. Page is visible, count request.
|
||||||
|
// 2. Page is not yet visible; wait until it switches to 'visible' and count.
|
||||||
|
// See #487
|
||||||
|
if (!('visibilityState' in document) || document.visibilityState === 'visible')
|
||||||
|
goatcounter.count()
|
||||||
|
else {
|
||||||
|
var f = function(e) {
|
||||||
|
if (document.visibilityState !== 'visible')
|
||||||
|
return
|
||||||
|
document.removeEventListener('visibilitychange', f)
|
||||||
|
goatcounter.count()
|
||||||
|
}
|
||||||
|
document.addEventListener('visibilitychange', f)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!goatcounter.no_events)
|
||||||
|
goatcounter.bind_events()
|
||||||
|
})
|
||||||
|
})();
|
48
public/css/gallery.css
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
#image-gallery {
|
||||||
|
margin: 2rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery {
|
||||||
|
column-count: 3;
|
||||||
|
column-gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-item {
|
||||||
|
break-inside: avoid;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
text-align: center;
|
||||||
|
list-style: none; /* ← important! */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.gallery-item img {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||||
|
transition: transform 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-item img:hover {
|
||||||
|
transform: scale(1.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.caption {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
margin-bottom: 0; /* ← just in case */
|
||||||
|
color: var(--fg-color);
|
||||||
|
list-style: none; /* ← extra-safe */
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.gallery {
|
||||||
|
column-count: 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.gallery {
|
||||||
|
column-count: 1;
|
||||||
|
}
|
||||||
|
}
|
28
public/css/mermaid.css
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
.mermaid {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 1.5em;
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
padding: 1em;
|
||||||
|
border-radius: 0.5em;
|
||||||
|
background-color: var(--code-bg);
|
||||||
|
font-family: var(--code-font, monospace);
|
||||||
|
font-size: 0.9rem;
|
||||||
|
overflow-x: auto;
|
||||||
|
max-width: 100%;
|
||||||
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mermaid strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mermaid svg {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.mermaid {
|
||||||
|
background-color: var(--code-bg-dark, #2d2d2d);
|
||||||
|
}
|
||||||
|
}
|
72
public/css/skills.css
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
/* Basic Layout for Skills List */
|
||||||
|
#skills-content {
|
||||||
|
margin: 2rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#skills-content .category {
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#skills-content .category h3 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: regular;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skills container for single-line display */
|
||||||
|
#skills-content .skills-list {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
display: flex; /* Use flexbox for single-line display */
|
||||||
|
flex-wrap: wrap; /* Allow skills to wrap if needed */
|
||||||
|
gap: 1rem; /* Spacing between skills */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skill List Item */
|
||||||
|
#skills-content .skills-list .skill {
|
||||||
|
display: inline-flex; /* Ensures each skill is aligned inline */
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer; /* Show pointer cursor on hover */
|
||||||
|
text-decoration: none; /* Remove underline from links */
|
||||||
|
color: inherit; /* Inherit color from parent */
|
||||||
|
transition: background-color 0.3s, color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Skill Name */
|
||||||
|
#skills-content .skills-list .skill span {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skill Icon */
|
||||||
|
#skills-content .skills-list .skill .skill-icon {
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
color: var(--accent-color);
|
||||||
|
font-size: 1.4rem;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hover Effects for Skills */
|
||||||
|
#skills-content .skills-list .skill:hover::before {
|
||||||
|
background: var(--accent-color-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
#skills-content .skills-list .skill:hover {
|
||||||
|
background-color: var(--accent-color-alpha);
|
||||||
|
color: var(--fg-color); /* Change text color on hover */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skill Category Hover Effect */
|
||||||
|
#skills-content .skills-list .skill:hover span {
|
||||||
|
color: var(--fg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Optional: Customize Icon Color on Hover */
|
||||||
|
#skills-content .skills-list .skill:hover .skill-icon {
|
||||||
|
color: var(--fg-color);
|
||||||
|
}
|
91
public/css/timeline.css
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
/* Basic Layout */
|
||||||
|
#timeline-content {
|
||||||
|
position: relative;
|
||||||
|
margin: 2rem 0;
|
||||||
|
padding-left: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#timeline-content ul.timeline {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#timeline-content ul.timeline::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: -30px;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 2px;
|
||||||
|
background: var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Event List Item */
|
||||||
|
#timeline-content li.event {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Event Circle */
|
||||||
|
#timeline-content li.event::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: -39px;
|
||||||
|
top: 5px;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: var(--bg-color);
|
||||||
|
border: 2px solid white;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* From + To Label — styled exactly like old date label */
|
||||||
|
#timeline-content li.event::after {
|
||||||
|
content: attr(data-from) "\A" attr(data-to);
|
||||||
|
white-space: pre; /* ensures newline works */
|
||||||
|
position: absolute;
|
||||||
|
left: -160px;
|
||||||
|
width: 100px;
|
||||||
|
text-align: right;
|
||||||
|
color: var(--fg-color);
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
line-height: 1.3;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Event Heading */
|
||||||
|
#timeline-content li.event h3 {
|
||||||
|
margin: 0 0 0.5rem 0;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Event Description */
|
||||||
|
#timeline-content li.event p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Timeline Icon */
|
||||||
|
#timeline-content .timeline-icon {
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
color: var(--accent-color);
|
||||||
|
font-size: 1.2rem;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hover Effects */
|
||||||
|
#timeline-content li.event:hover::before {
|
||||||
|
background: var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
#timeline-content li.event:hover {
|
||||||
|
background-color: var(--accent-color-alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* From + To Label Hover Effect */
|
||||||
|
#timeline-content li.event:hover::after {
|
||||||
|
color: var(--accent-color);
|
||||||
|
}
|
10
public/de/atom.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
|
||||||
|
<title>Studio UMZU</title>
|
||||||
|
<subtitle>Spielerisches Lernen mit Technikdidaktik</subtitle>
|
||||||
|
<link rel="self" type="application/atom+xml" href="https://studio-umzu.de/de/atom.xml"/>
|
||||||
|
<link rel="alternate" type="text/html" href="https://studio-umzu.de/"/>
|
||||||
|
<generator uri="https://www.getzola.org/">Zola</generator>
|
||||||
|
|
||||||
|
<id>https://studio-umzu.de/de/atom.xml</id>
|
||||||
|
</feed>
|
2
public/de/index.html
Normal file
BIN
public/favicon.png
Normal file
After Width: | Height: | Size: 548 B |
1
public/fonts.css
Normal file
|
@ -0,0 +1 @@
|
||||||
|
@font-face{font-style:normal;font-weight:100 900;src:url("fonts/InterVariable.woff2") format("woff2");font-family:"Inter Variable";font-display:swap}@font-face{font-style:italic;font-weight:100 900;src:url("fonts/InterVariable-Italic.woff2") format("woff2");font-family:"Inter Variable";font-display:swap}@font-face{font-style:normal;font-weight:100 900;src:url("fonts/JetBrainsMono.woff2") format("woff2");font-family:"JetBrains Mono";font-display:swap}@font-face{font-style:italic;font-weight:100 900;src:url("fonts/JetBrainsMono-Italic.woff2") format("woff2");font-family:"JetBrains Mono";font-display:swap}body{font-family:"Inter Variable",var(--font-system-ui),var(--font-emoji)}h1,h2,h3,h4,h5,h6{font-weight:bold;font-family:"Inter Variable",var(--font-system-ui),var(--font-emoji)}h1{font-weight:900}pre,code,kbd,samp{font-family:"JetBrains Mono",var(--font-monospace-code)}
|
BIN
public/fonts/InterVariable-Italic.woff2
Normal file
BIN
public/fonts/InterVariable.woff2
Normal file
BIN
public/fonts/JetBrainsMono-Italic.woff2
Normal file
BIN
public/fonts/JetBrainsMono.woff2
Normal file
BIN
public/fonts/KaTeX_AMS-Regular.woff2
Normal file
BIN
public/fonts/KaTeX_Caligraphic-Bold.woff2
Normal file
BIN
public/fonts/KaTeX_Caligraphic-Regular.woff2
Normal file
BIN
public/fonts/KaTeX_Fraktur-Bold.woff2
Normal file
BIN
public/fonts/KaTeX_Fraktur-Regular.woff2
Normal file
BIN
public/fonts/KaTeX_Main-Bold.woff2
Normal file
BIN
public/fonts/KaTeX_Main-BoldItalic.woff2
Normal file
BIN
public/fonts/KaTeX_Main-Italic.woff2
Normal file
BIN
public/fonts/KaTeX_Main-Regular.woff2
Normal file
BIN
public/fonts/KaTeX_Math-BoldItalic.woff2
Normal file
BIN
public/fonts/KaTeX_Math-Italic.woff2
Normal file
BIN
public/fonts/KaTeX_SansSerif-Bold.woff2
Normal file
BIN
public/fonts/KaTeX_SansSerif-Italic.woff2
Normal file
BIN
public/fonts/KaTeX_SansSerif-Regular.woff2
Normal file
BIN
public/fonts/KaTeX_Script-Regular.woff2
Normal file
BIN
public/fonts/KaTeX_Size1-Regular.woff2
Normal file
BIN
public/fonts/KaTeX_Size2-Regular.woff2
Normal file
BIN
public/fonts/KaTeX_Size3-Regular.woff2
Normal file
BIN
public/fonts/KaTeX_Size4-Regular.woff2
Normal file
BIN
public/fonts/KaTeX_Typewriter-Regular.woff2
Normal file
9
public/fuse.js
Normal file
2
public/index.html
Normal file
8
public/katex-init.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
renderMathInElement(document.body, {
|
||||||
|
delimiters: [
|
||||||
|
{ left: "$$", right: "$$", display: true },
|
||||||
|
{ left: "$", right: "$", display: false },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
1209
public/katex.css
Normal file
1
public/katex.min.js
vendored
Normal file
BIN
public/logo.png
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
public/processed_images/banner.11b1c6ec8721de53.webp
Normal file
After Width: | Height: | Size: 96 B |
BIN
public/processed_images/banner.d26f9911a4551316.jpg
Normal file
After Width: | Height: | Size: 103 KiB |
4
public/robots.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
User-agent: *
|
||||||
|
Disallow:
|
||||||
|
Allow: /
|
||||||
|
Sitemap: https://studio-umzu.de/sitemap.xml
|
12
public/rss.xml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
|
||||||
|
<channel>
|
||||||
|
<title>Studio UMZU</title>
|
||||||
|
<link>https://studio-umzu.de/</link>
|
||||||
|
<description></description>
|
||||||
|
<generator>Zola</generator>
|
||||||
|
<language>en</language>
|
||||||
|
<atom:link href="https://studio-umzu.de/rss.xml" rel="self" type="application/rss+xml"/>
|
||||||
|
|
||||||
|
</channel>
|
||||||
|
</rss>
|
209
public/search-elasticlunr.js
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
// Based on https://github.com/getzola/zola/blob/1ac1231de1e342bbaf4d7a51a8a9a40ea152e246/docs/static/search.js
|
||||||
|
function debounce(func, wait) {
|
||||||
|
var timeout;
|
||||||
|
|
||||||
|
return function () {
|
||||||
|
var context = this;
|
||||||
|
var args = arguments;
|
||||||
|
clearTimeout(timeout);
|
||||||
|
|
||||||
|
timeout = setTimeout(function () {
|
||||||
|
timeout = null;
|
||||||
|
func.apply(context, args);
|
||||||
|
}, wait);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Taken from mdbook
|
||||||
|
// The strategy is as follows:
|
||||||
|
// First, assign a value to each word in the document:
|
||||||
|
// Words that correspond to search terms (stemmer aware): 40
|
||||||
|
// Normal words: 2
|
||||||
|
// First word in a sentence: 8
|
||||||
|
// Then use a sliding window with a constant number of words and count the
|
||||||
|
// sum of the values of the words within the window. Then use the window that got the
|
||||||
|
// maximum sum. If there are multiple maximas, then get the last one.
|
||||||
|
// Enclose the terms in <b>.
|
||||||
|
function makeTeaser(body, terms) {
|
||||||
|
var TERM_WEIGHT = 40;
|
||||||
|
var NORMAL_WORD_WEIGHT = 2;
|
||||||
|
var FIRST_WORD_WEIGHT = 8;
|
||||||
|
var TEASER_MAX_WORDS = 30;
|
||||||
|
|
||||||
|
var stemmedTerms = terms.map(function (w) {
|
||||||
|
return elasticlunr.stemmer(w.toLowerCase());
|
||||||
|
});
|
||||||
|
var termFound = false;
|
||||||
|
var index = 0;
|
||||||
|
var weighted = []; // contains elements of ["word", weight, index_in_document]
|
||||||
|
|
||||||
|
// split in sentences, then words
|
||||||
|
var sentences = body.toLowerCase().split(". ");
|
||||||
|
|
||||||
|
for (var i in sentences) {
|
||||||
|
var words = sentences[i].split(" ");
|
||||||
|
var value = FIRST_WORD_WEIGHT;
|
||||||
|
|
||||||
|
for (var j in words) {
|
||||||
|
var word = words[j];
|
||||||
|
|
||||||
|
if (word.length > 0) {
|
||||||
|
for (var k in stemmedTerms) {
|
||||||
|
if (elasticlunr.stemmer(word).startsWith(stemmedTerms[k])) {
|
||||||
|
value = TERM_WEIGHT;
|
||||||
|
termFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
weighted.push([word, value, index]);
|
||||||
|
value = NORMAL_WORD_WEIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
index += word.length;
|
||||||
|
index += 1; // ' ' or '.' if last word in sentence
|
||||||
|
}
|
||||||
|
|
||||||
|
index += 1; // because we split at a two-char boundary '. '
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weighted.length === 0) {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
var windowWeights = [];
|
||||||
|
var windowSize = Math.min(weighted.length, TEASER_MAX_WORDS);
|
||||||
|
// We add a window with all the weights first
|
||||||
|
var curSum = 0;
|
||||||
|
for (var i = 0; i < windowSize; i++) {
|
||||||
|
curSum += weighted[i][1];
|
||||||
|
}
|
||||||
|
windowWeights.push(curSum);
|
||||||
|
|
||||||
|
for (var i = 0; i < weighted.length - windowSize; i++) {
|
||||||
|
curSum -= weighted[i][1];
|
||||||
|
curSum += weighted[i + windowSize][1];
|
||||||
|
windowWeights.push(curSum);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we didn't find the term, just pick the first window
|
||||||
|
var maxSumIndex = 0;
|
||||||
|
if (termFound) {
|
||||||
|
var maxFound = 0;
|
||||||
|
// backwards
|
||||||
|
for (var i = windowWeights.length - 1; i >= 0; i--) {
|
||||||
|
if (windowWeights[i] > maxFound) {
|
||||||
|
maxFound = windowWeights[i];
|
||||||
|
maxSumIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var teaser = [];
|
||||||
|
var startIndex = weighted[maxSumIndex][2];
|
||||||
|
for (var i = maxSumIndex; i < maxSumIndex + windowSize; i++) {
|
||||||
|
var word = weighted[i];
|
||||||
|
if (startIndex < word[2]) {
|
||||||
|
// missing text from index to start of `word`
|
||||||
|
teaser.push(body.substring(startIndex, word[2]));
|
||||||
|
startIndex = word[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
// add <strong> around search terms
|
||||||
|
if (word[1] === TERM_WEIGHT) {
|
||||||
|
teaser.push("<strong>");
|
||||||
|
}
|
||||||
|
startIndex = word[2] + word[0].length;
|
||||||
|
teaser.push(body.substring(word[2], startIndex));
|
||||||
|
|
||||||
|
if (word[1] === TERM_WEIGHT) {
|
||||||
|
teaser.push("</strong>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
teaser.push("…");
|
||||||
|
return teaser.join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatSearchResultItem(item, terms) {
|
||||||
|
return '<div class="item">'
|
||||||
|
+ `<a href="${item.ref}">${item.doc.title}</a>`
|
||||||
|
+ `<span>${makeTeaser(item.doc.body, terms)}</span>`
|
||||||
|
+ '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function initSearch() {
|
||||||
|
var searchBar = document.getElementById("search-bar");
|
||||||
|
var searchContainer = document.getElementById("search-container");
|
||||||
|
var searchResults = document.getElementById("search-results");
|
||||||
|
var MAX_ITEMS = 10;
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
bool: "AND",
|
||||||
|
fields: {
|
||||||
|
title: { boost: 2 },
|
||||||
|
body: { boost: 1 },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var currentTerm = "";
|
||||||
|
var index;
|
||||||
|
|
||||||
|
var initIndex = async function () {
|
||||||
|
if (index === undefined) {
|
||||||
|
let searchIndex = document.getElementById("search-index").textContent;
|
||||||
|
index = fetch(searchIndex)
|
||||||
|
.then(
|
||||||
|
async function (response) {
|
||||||
|
return await elasticlunr.Index.load(await response.json());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let res = await index;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
searchBar.addEventListener("keyup", debounce(async function () {
|
||||||
|
var term = searchBar.value.trim();
|
||||||
|
if (term === currentTerm) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
searchResults.style.display = term === "" ? "none" : "flex";
|
||||||
|
searchResults.innerHTML = "";
|
||||||
|
currentTerm = term;
|
||||||
|
if (term === "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var results = (await initIndex()).search(term, options);
|
||||||
|
if (results.length === 0) {
|
||||||
|
searchResults.style.display = "none";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < Math.min(results.length, MAX_ITEMS); i++) {
|
||||||
|
searchResults.innerHTML += formatSearchResultItem(results[i], term.split(" "));
|
||||||
|
}
|
||||||
|
}, 150));
|
||||||
|
|
||||||
|
document.addEventListener("keydown", function (event) {
|
||||||
|
if (event.key === "/") {
|
||||||
|
event.preventDefault();
|
||||||
|
toggleSearch();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById("search-toggle").addEventListener("click", toggleSearch);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleSearch() {
|
||||||
|
var searchContainer = document.getElementById("search-container");
|
||||||
|
var searchBar = document.getElementById("search-bar");
|
||||||
|
searchContainer.classList.toggle("active");
|
||||||
|
searchBar.toggleAttribute("disabled");
|
||||||
|
searchBar.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.readyState === "complete" ||
|
||||||
|
(document.readyState !== "loading" && !document.documentElement.doScroll)
|
||||||
|
) {
|
||||||
|
initSearch();
|
||||||
|
} else {
|
||||||
|
document.addEventListener("DOMContentLoaded", initSearch);
|
||||||
|
}
|
127
public/search-fuse.js
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
// Based on https://codeberg.org/daudix/duckquill/issues/101#issuecomment-2377169
|
||||||
|
let searchSetup = false;
|
||||||
|
let fuse;
|
||||||
|
|
||||||
|
async function initIndex() {
|
||||||
|
if (searchSetup) return;
|
||||||
|
|
||||||
|
const url = document.getElementById("search-index").textContent;
|
||||||
|
const response = await fetch(url);
|
||||||
|
|
||||||
|
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
includeScore: false,
|
||||||
|
includeMatches: true,
|
||||||
|
ignoreLocation: true,
|
||||||
|
threshold: 0.15,
|
||||||
|
keys: [
|
||||||
|
{ name: "title", weight: 3 },
|
||||||
|
{ name: "description", weight: 2 },
|
||||||
|
{ name: "body", weight: 1 }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
fuse = new Fuse(await response.json(), options);
|
||||||
|
searchSetup = true;
|
||||||
|
|
||||||
|
console.log("Search index initialized successfully");
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleSearch() {
|
||||||
|
initIndex();
|
||||||
|
const searchBar = document.getElementById("search-bar");
|
||||||
|
const searchContainer = document.getElementById("search-container");
|
||||||
|
const searchResults = document.getElementById("search-results");
|
||||||
|
searchContainer.classList.toggle("active");
|
||||||
|
searchBar.toggleAttribute("disabled");
|
||||||
|
searchBar.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
function debounce(actual_fn, wait) {
|
||||||
|
let timeoutId;
|
||||||
|
|
||||||
|
return (...args) => {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
|
||||||
|
timeoutId = setTimeout(() => {
|
||||||
|
actual_fn(...args);
|
||||||
|
}, wait);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function initSearch() {
|
||||||
|
const searchBar = document.getElementById("search-bar");
|
||||||
|
const searchResults = document.getElementById("search-results");
|
||||||
|
const searchContainer = document.getElementById("search-container");
|
||||||
|
const MAX_ITEMS = 10;
|
||||||
|
const MAX_RESULTS = 4;
|
||||||
|
|
||||||
|
let currentTerm = "";
|
||||||
|
|
||||||
|
searchBar.addEventListener("keyup", (e) => {
|
||||||
|
const searchVal = searchBar.value.trim();
|
||||||
|
const results = fuse.search(searchVal, { limit: MAX_ITEMS });
|
||||||
|
|
||||||
|
let html = "";
|
||||||
|
for (const result of results) {
|
||||||
|
html += makeTeaser(result, searchVal);
|
||||||
|
}
|
||||||
|
searchResults.innerHTML = html;
|
||||||
|
|
||||||
|
if (html) {
|
||||||
|
searchResults.style.display = "flex";
|
||||||
|
} else {
|
||||||
|
searchResults.style.display = "none";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function makeTeaser(result, searchVal) {
|
||||||
|
const TEASER_SIZE = 20;
|
||||||
|
let output = `<div class="search-result item"><a class="result-title" href=${result.item.url}>${result.item.title}</a>`;
|
||||||
|
|
||||||
|
for (const match of result.matches) {
|
||||||
|
if (match.key === "title") continue;
|
||||||
|
|
||||||
|
const indices = match.indices.sort((a, b) => Math.abs(a[1] - a[0] - searchVal.length) - Math.abs(b[1] - b[0] - searchVal.length)).slice(0, MAX_RESULTS);
|
||||||
|
const value = match.value;
|
||||||
|
|
||||||
|
for (const ind of indices) {
|
||||||
|
const start = Math.max(0, ind[0] - TEASER_SIZE);
|
||||||
|
const end = Math.min(value.length - 1, ind[1] + TEASER_SIZE);
|
||||||
|
output += "<span>"
|
||||||
|
+ value.substring(start, ind[0])
|
||||||
|
+ `<strong>${value.substring(ind[0], ind[1] + 1)}</strong>`
|
||||||
|
+ value.substring(ind[1] + 1, end)
|
||||||
|
+ "</span>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match.indices.length > 4) {
|
||||||
|
const moreMatchesText = document.getElementById("more-matches-text").textContent;
|
||||||
|
output += `<span class="more-matches">${moreMatchesText}</span>`.replace("$MATCHES", `+${match.indices.length - MAX_RESULTS}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output + "</div>";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*window.addEventListener("click", function (event) {
|
||||||
|
if (searchSetup && searchBar.getAttribute("disabled") === null && !searchContainer.contains(event.target)) {
|
||||||
|
toggleSearch();
|
||||||
|
}
|
||||||
|
}, { passive: true });*/
|
||||||
|
|
||||||
|
document.addEventListener("keydown", function(event) {
|
||||||
|
if (event.key === "/") {
|
||||||
|
event.preventDefault();
|
||||||
|
toggleSearch();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById("search-toggle").addEventListener("click", toggleSearch);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.readyState === "complete" ||
|
||||||
|
(document.readyState !== "loading" && !document.documentElement.doScroll))
|
||||||
|
initSearch();
|
||||||
|
else
|
||||||
|
document.addEventListener("DOMContentLoaded", initSearch);
|
1
public/search_index.de.json
Normal file
1
public/search_index.en.json
Normal file
15
public/sitemap.xml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
|
<url>
|
||||||
|
<loc>https://studio-umzu.de/</loc>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://studio-umzu.de/de/</loc>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://studio-umzu.de/de/tags/</loc>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://studio-umzu.de/tags/</loc>
|
||||||
|
</url>
|
||||||
|
</urlset>
|
5
public/style.css
Normal file
283
public/syntax-theme-dark.css
Normal file
|
@ -0,0 +1,283 @@
|
||||||
|
/*
|
||||||
|
* theme "Solarized (dark)" generated by syntect
|
||||||
|
*/
|
||||||
|
|
||||||
|
.z-code {
|
||||||
|
color: #839496;
|
||||||
|
background-color: #002b36;
|
||||||
|
}
|
||||||
|
|
||||||
|
.z-comment, .z-meta.z-documentation {
|
||||||
|
color: #586e75;
|
||||||
|
}
|
||||||
|
.z-string {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-string.z-regexp {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-constant.z-character.z-escape {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-constant.z-numeric {
|
||||||
|
color: #6c71c4;
|
||||||
|
}
|
||||||
|
.z-variable {
|
||||||
|
color: #268bd2;
|
||||||
|
}
|
||||||
|
.z-variable.z-function {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-variable.z-language {
|
||||||
|
color: #d33682;
|
||||||
|
}
|
||||||
|
.z-keyword {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-meta.z-import .z-keyword, .z-keyword.z-control.z-import, .z-keyword.z-control.z-import.z-from, .z-keyword.z-other.z-import, .z-keyword.z-control.z-at-rule.z-include, .z-keyword.z-control.z-at-rule.z-import {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.z-keyword.z-operator.z-comparison, .z-keyword.z-operator.z-assignment, .z-keyword.z-operator.z-arithmetic {
|
||||||
|
color: #657b83;
|
||||||
|
}
|
||||||
|
.z-storage {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-storage.z-modifier {
|
||||||
|
color: #93a1a1;
|
||||||
|
}
|
||||||
|
.z-keyword.z-control.z-class, .z-entity.z-name, .z-entity.z-name.z-class, .z-entity.z-name.z-type.z-class {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-entity.z-other.z-inherited-class {
|
||||||
|
color: #268bd2;
|
||||||
|
}
|
||||||
|
.z-entity.z-other.z-attribute-name {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-support, .z-support.z-type, .z-support.z-class {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-entity.z-name.z-function {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-punctuation.z-definition.z-variable {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-constant, .z-constant.z-language, .z-meta.z-preprocessor {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-entity.z-name.z-section {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.z-support.z-function.z-construct, .z-keyword.z-other.z-new {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-constant.z-character, .z-constant.z-other {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.z-entity.z-name.z-tag {
|
||||||
|
color: #268bd2;
|
||||||
|
}
|
||||||
|
.z-punctuation.z-definition.z-tag.z-html, .z-punctuation.z-definition.z-tag.z-begin, .z-punctuation.z-definition.z-tag.z-end {
|
||||||
|
color: #586e75;
|
||||||
|
}
|
||||||
|
.z-support.z-function {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-punctuation.z-separator.z-continuation {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-storage.z-type {
|
||||||
|
color: #268bd2;
|
||||||
|
}
|
||||||
|
.z-support.z-type.z-exception {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.z-keyword.z-other.z-special-method {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.z-invalid {
|
||||||
|
background-color: #6e2e32;
|
||||||
|
}
|
||||||
|
.z-string.z-quoted.z-double, .z-string.z-quoted.z-single {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-punctuation.z-definition.z-string {
|
||||||
|
color: #839496;
|
||||||
|
}
|
||||||
|
.z-meta.z-brace.z-square, .z-punctuation.z-section.z-brackets {
|
||||||
|
color: #268bd2;
|
||||||
|
}
|
||||||
|
.z-meta.z-brace.z-round, .z-meta.z-brace.z-curly, .z-punctuation.z-section, .z-punctuation.z-section.z-block, .z-punctuation.z-definition.z-parameters, .z-punctuation.z-section.z-group {
|
||||||
|
color: #657b83;
|
||||||
|
}
|
||||||
|
.z-support.z-constant.z-color, .z-invalid.z-deprecated.z-color.z-w3c-non-standard-color-name.z-scss {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-meta.z-selector.z-css {
|
||||||
|
color: #657b83;
|
||||||
|
}
|
||||||
|
.z-entity.z-name.z-tag.z-css, .z-entity.z-name.z-tag.z-scss, .z-source.z-less .z-keyword.z-control.z-html.z-elements, .z-source.z-sass .z-keyword.z-control.z-untitled {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-entity.z-other.z-attribute-name.z-class {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-entity.z-other.z-attribute-name.z-id {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-entity.z-other.z-attribute-name.z-pseudo-element, .z-entity.z-other.z-attribute-name.z-tag.z-pseudo-element, .z-entity.z-other.z-attribute-name.z-pseudo-class, .z-entity.z-other.z-attribute-name.z-tag.z-pseudo-class {
|
||||||
|
color: #268bd2;
|
||||||
|
}
|
||||||
|
.z-text.z-html.z-basic .z-meta.z-tag.z-other.z-html, .z-text.z-html.z-basic .z-meta.z-tag.z-any.z-html, .z-text.z-html.z-basic .z-meta.z-tag.z-block.z-any, .z-text.z-html.z-basic .z-meta.z-tag.z-inline.z-any, .z-text.z-html.z-basic .z-meta.z-tag.z-structure.z-any.z-html, .z-text.z-html.z-basic .z-source.z-js.z-embedded.z-html, .z-punctuation.z-separator.z-key-value.z-html {
|
||||||
|
color: #657b83;
|
||||||
|
}
|
||||||
|
.z-text.z-html.z-basic .z-entity.z-other.z-attribute-name.z-html, .z-meta.z-tag.z-xml .z-entity.z-other.z-attribute-name {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-keyword.z-other.z-special-method.z-ruby {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-variable.z-other.z-constant.z-ruby {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-constant.z-other.z-symbol.z-ruby {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-keyword.z-other.z-special-method.z-ruby {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.z-meta.z-array .z-support.z-function.z-construct.z-php {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-entity.z-name.z-function.z-preprocessor.z-c, .z-meta.z-preprocessor.z-c.z-include, .z-meta.z-preprocessor.z-macro.z-c {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.z-meta.z-preprocessor.z-c.z-include .z-string.z-quoted.z-other.z-lt-gt.z-include.z-c, .z-meta.z-preprocessor.z-c.z-include .z-punctuation.z-definition.z-string.z-begin.z-c, .z-meta.z-preprocessor.z-c.z-include .z-punctuation.z-definition.z-string.z-end.z-c {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-other.z-package.z-exclude, .z-other.z-remove {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-other.z-add {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-punctuation.z-section.z-group.z-tex, .z-punctuation.z-definition.z-arguments.z-begin.z-latex, .z-punctuation.z-definition.z-arguments.z-end.z-latex, .z-punctuation.z-definition.z-arguments.z-latex {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-meta.z-group.z-braces.z-tex {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-string.z-other.z-math.z-tex {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-variable.z-parameter.z-function.z-latex {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.z-punctuation.z-definition.z-constant.z-math.z-tex {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-text.z-tex.z-latex .z-constant.z-other.z-math.z-tex, .z-constant.z-other.z-general.z-math.z-tex, .z-constant.z-other.z-general.z-math.z-tex, .z-constant.z-character.z-math.z-tex {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-string.z-other.z-math.z-tex {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-punctuation.z-definition.z-string.z-begin.z-tex, .z-punctuation.z-definition.z-string.z-end.z-tex {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-keyword.z-control.z-label.z-latex, .z-text.z-tex.z-latex .z-constant.z-other.z-general.z-math.z-tex {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-variable.z-parameter.z-definition.z-label.z-latex {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-support.z-function.z-be.z-latex {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-support.z-function.z-section.z-latex {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.z-support.z-function.z-general.z-tex {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-keyword.z-control.z-ref.z-latex {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-storage.z-type.z-class.z-python, .z-storage.z-type.z-function.z-python, .z-storage.z-modifier.z-global.z-python {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-support.z-type.z-exception.z-python {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-meta.z-scope.z-for-in-loop.z-shell, .z-variable.z-other.z-loop.z-shell {
|
||||||
|
color: #93a1a1;
|
||||||
|
}
|
||||||
|
.z-meta.z-scope.z-case-block.z-shell, .z-meta.z-scope.z-case-body.z-shell {
|
||||||
|
color: #93a1a1;
|
||||||
|
}
|
||||||
|
.z-punctuation.z-definition.z-logical-expression.z-shell {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-storage.z-modifier.z-c++ {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-support.z-function.z-perl {
|
||||||
|
color: #268bd2;
|
||||||
|
}
|
||||||
|
.z-meta.z-diff, .z-meta.z-diff.z-header {
|
||||||
|
color: #586e75;
|
||||||
|
}
|
||||||
|
.z-meta.z-diff.z-range {
|
||||||
|
color: #268bd2;
|
||||||
|
}
|
||||||
|
.z-markup.z-deleted {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-markup.z-changed {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-markup.z-inserted {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-markup.z-warning {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-markup.z-error {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-markup.z-heading, .z-punctuation.z-definition.z-heading.z-markdown {
|
||||||
|
color: #b58900;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.z-markup.z-quote {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-markup.z-italic {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
.z-markup.z-bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.z-markup.z-underline.z-link.z-markdown, .z-meta.z-link.z-reference .z-constant.z-other.z-reference.z-link.z-markdown {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-constant.z-other.z-reference.z-link.z-markdown {
|
||||||
|
color: #6c71c4;
|
||||||
|
}
|
||||||
|
.z-meta.z-paragraph.z-markdown .z-meta.z-dummy.z-line-break {
|
||||||
|
background-color: #586e75;
|
||||||
|
}
|
||||||
|
.z-brackethighlighter.z-all {
|
||||||
|
color: #586e75;
|
||||||
|
}
|
||||||
|
.z-entity.z-name.z-filename.z-find-in-files {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-constant.z-numeric.z-line-number.z-find-in-files {
|
||||||
|
color: #586e75;
|
||||||
|
}
|
||||||
|
.z-variable.z-other.z-readwrite.z-js, .z-variable.z-other.z-object.z-js, .z-variable.z-other.z-constant.z-js {
|
||||||
|
color: #839496;
|
||||||
|
}
|
283
public/syntax-theme-light.css
Normal file
|
@ -0,0 +1,283 @@
|
||||||
|
/*
|
||||||
|
* theme "Solarized (light)" generated by syntect
|
||||||
|
*/
|
||||||
|
|
||||||
|
.z-code {
|
||||||
|
color: #657b83;
|
||||||
|
background-color: #fdf6e3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.z-comment, .z-meta.z-documentation {
|
||||||
|
color: #93a1a1;
|
||||||
|
}
|
||||||
|
.z-string {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-string.z-regexp {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-constant.z-character.z-escape {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-constant.z-numeric {
|
||||||
|
color: #6c71c4;
|
||||||
|
}
|
||||||
|
.z-variable {
|
||||||
|
color: #268bd2;
|
||||||
|
}
|
||||||
|
.z-variable.z-function {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-variable.z-language {
|
||||||
|
color: #d33682;
|
||||||
|
}
|
||||||
|
.z-keyword {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-meta.z-import .z-keyword, .z-keyword.z-control.z-import, .z-keyword.z-control.z-import.z-from, .z-keyword.z-other.z-import, .z-keyword.z-control.z-at-rule.z-include, .z-keyword.z-control.z-at-rule.z-import {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.z-keyword.z-operator.z-comparison, .z-keyword.z-operator.z-assignment, .z-keyword.z-operator.z-arithmetic {
|
||||||
|
color: #657b83;
|
||||||
|
}
|
||||||
|
.z-storage {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-storage.z-modifier {
|
||||||
|
color: #586e75;
|
||||||
|
}
|
||||||
|
.z-keyword.z-control.z-class, .z-entity.z-name, .z-entity.z-name.z-class, .z-entity.z-name.z-type.z-class {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-entity.z-other.z-inherited-class {
|
||||||
|
color: #268bd2;
|
||||||
|
}
|
||||||
|
.z-entity.z-other.z-attribute-name {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-support, .z-support.z-type, .z-support.z-class {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-entity.z-name.z-function {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-punctuation.z-definition.z-variable {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-constant, .z-constant.z-language, .z-meta.z-preprocessor {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-entity.z-name.z-section {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.z-support.z-function.z-construct, .z-keyword.z-other.z-new {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-constant.z-character, .z-constant.z-other {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.z-entity.z-name.z-tag {
|
||||||
|
color: #268bd2;
|
||||||
|
}
|
||||||
|
.z-punctuation.z-definition.z-tag.z-html, .z-punctuation.z-definition.z-tag.z-begin, .z-punctuation.z-definition.z-tag.z-end {
|
||||||
|
color: #93a1a1;
|
||||||
|
}
|
||||||
|
.z-support.z-function {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-punctuation.z-separator.z-continuation {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-storage.z-type {
|
||||||
|
color: #268bd2;
|
||||||
|
}
|
||||||
|
.z-support.z-type.z-exception {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.z-keyword.z-other.z-special-method {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.z-invalid {
|
||||||
|
background-color: #ec9489;
|
||||||
|
}
|
||||||
|
.z-string.z-quoted.z-double, .z-string.z-quoted.z-single {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-punctuation.z-definition.z-string {
|
||||||
|
color: #839496;
|
||||||
|
}
|
||||||
|
.z-meta.z-brace.z-square, .z-punctuation.z-section.z-brackets {
|
||||||
|
color: #268bd2;
|
||||||
|
}
|
||||||
|
.z-meta.z-brace.z-round, .z-meta.z-brace.z-curly, .z-punctuation.z-section, .z-punctuation.z-section.z-block, .z-punctuation.z-definition.z-parameters, .z-punctuation.z-section.z-group {
|
||||||
|
color: #657b83;
|
||||||
|
}
|
||||||
|
.z-support.z-constant.z-color, .z-invalid.z-deprecated.z-color.z-w3c-non-standard-color-name.z-scss {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-meta.z-selector.z-css {
|
||||||
|
color: #657b83;
|
||||||
|
}
|
||||||
|
.z-entity.z-name.z-tag.z-css, .z-entity.z-name.z-tag.z-scss, .z-source.z-less .z-keyword.z-control.z-html.z-elements, .z-source.z-sass .z-keyword.z-control.z-untitled {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-entity.z-other.z-attribute-name.z-class {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-entity.z-other.z-attribute-name.z-id {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-entity.z-other.z-attribute-name.z-pseudo-element, .z-entity.z-other.z-attribute-name.z-tag.z-pseudo-element, .z-entity.z-other.z-attribute-name.z-pseudo-class, .z-entity.z-other.z-attribute-name.z-tag.z-pseudo-class {
|
||||||
|
color: #268bd2;
|
||||||
|
}
|
||||||
|
.z-text.z-html.z-basic .z-meta.z-tag.z-other.z-html, .z-text.z-html.z-basic .z-meta.z-tag.z-any.z-html, .z-text.z-html.z-basic .z-meta.z-tag.z-block.z-any, .z-text.z-html.z-basic .z-meta.z-tag.z-inline.z-any, .z-text.z-html.z-basic .z-meta.z-tag.z-structure.z-any.z-html, .z-text.z-html.z-basic .z-source.z-js.z-embedded.z-html, .z-punctuation.z-separator.z-key-value.z-html {
|
||||||
|
color: #657b83;
|
||||||
|
}
|
||||||
|
.z-text.z-html.z-basic .z-entity.z-other.z-attribute-name.z-html, .z-meta.z-tag.z-xml .z-entity.z-other.z-attribute-name {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-keyword.z-other.z-special-method.z-ruby {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-variable.z-other.z-constant.z-ruby {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-constant.z-other.z-symbol.z-ruby {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-keyword.z-other.z-special-method.z-ruby {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.z-meta.z-array .z-support.z-function.z-construct.z-php {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-entity.z-name.z-function.z-preprocessor.z-c, .z-meta.z-preprocessor.z-c.z-include, .z-meta.z-preprocessor.z-macro.z-c {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.z-meta.z-preprocessor.z-c.z-include .z-string.z-quoted.z-other.z-lt-gt.z-include.z-c, .z-meta.z-preprocessor.z-c.z-include .z-punctuation.z-definition.z-string.z-begin.z-c, .z-meta.z-preprocessor.z-c.z-include .z-punctuation.z-definition.z-string.z-end.z-c {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-other.z-package.z-exclude, .z-other.z-remove {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-other.z-add {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-punctuation.z-section.z-group.z-tex, .z-punctuation.z-definition.z-arguments.z-begin.z-latex, .z-punctuation.z-definition.z-arguments.z-end.z-latex, .z-punctuation.z-definition.z-arguments.z-latex {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-meta.z-group.z-braces.z-tex {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-string.z-other.z-math.z-tex {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-variable.z-parameter.z-function.z-latex {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.z-punctuation.z-definition.z-constant.z-math.z-tex {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-text.z-tex.z-latex .z-constant.z-other.z-math.z-tex, .z-constant.z-other.z-general.z-math.z-tex, .z-constant.z-other.z-general.z-math.z-tex, .z-constant.z-character.z-math.z-tex {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-string.z-other.z-math.z-tex {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-punctuation.z-definition.z-string.z-begin.z-tex, .z-punctuation.z-definition.z-string.z-end.z-tex {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-keyword.z-control.z-label.z-latex, .z-text.z-tex.z-latex .z-constant.z-other.z-general.z-math.z-tex {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-variable.z-parameter.z-definition.z-label.z-latex {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-support.z-function.z-be.z-latex {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-support.z-function.z-section.z-latex {
|
||||||
|
color: #cb4b16;
|
||||||
|
}
|
||||||
|
.z-support.z-function.z-general.z-tex {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-keyword.z-control.z-ref.z-latex {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-storage.z-type.z-class.z-python, .z-storage.z-type.z-function.z-python, .z-storage.z-modifier.z-global.z-python {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-support.z-type.z-exception.z-python {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-meta.z-scope.z-for-in-loop.z-shell, .z-variable.z-other.z-loop.z-shell {
|
||||||
|
color: #586e75;
|
||||||
|
}
|
||||||
|
.z-meta.z-scope.z-case-block.z-shell, .z-meta.z-scope.z-case-body.z-shell {
|
||||||
|
color: #586e75;
|
||||||
|
}
|
||||||
|
.z-punctuation.z-definition.z-logical-expression.z-shell {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-storage.z-modifier.z-c++ {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-support.z-function.z-perl {
|
||||||
|
color: #268bd2;
|
||||||
|
}
|
||||||
|
.z-meta.z-diff, .z-meta.z-diff.z-header {
|
||||||
|
color: #93a1a1;
|
||||||
|
}
|
||||||
|
.z-meta.z-diff.z-range {
|
||||||
|
color: #268bd2;
|
||||||
|
}
|
||||||
|
.z-markup.z-deleted {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-markup.z-changed {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-markup.z-inserted {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-markup.z-warning {
|
||||||
|
color: #b58900;
|
||||||
|
}
|
||||||
|
.z-markup.z-error {
|
||||||
|
color: #dc322f;
|
||||||
|
}
|
||||||
|
.z-markup.z-heading, .z-punctuation.z-definition.z-heading.z-markdown {
|
||||||
|
color: #b58900;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.z-markup.z-quote {
|
||||||
|
color: #859900;
|
||||||
|
}
|
||||||
|
.z-markup.z-italic {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
.z-markup.z-bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.z-markup.z-underline.z-link.z-markdown, .z-meta.z-link.z-reference .z-constant.z-other.z-reference.z-link.z-markdown {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-constant.z-other.z-reference.z-link.z-markdown {
|
||||||
|
color: #6c71c4;
|
||||||
|
}
|
||||||
|
.z-meta.z-paragraph.z-markdown .z-meta.z-dummy.z-line-break {
|
||||||
|
background-color: #eee8d5;
|
||||||
|
}
|
||||||
|
.z-brackethighlighter.z-all {
|
||||||
|
color: #93a1a1;
|
||||||
|
}
|
||||||
|
.z-entity.z-name.z-filename.z-find-in-files {
|
||||||
|
color: #2aa198;
|
||||||
|
}
|
||||||
|
.z-constant.z-numeric.z-line-number.z-find-in-files {
|
||||||
|
color: #93a1a1;
|
||||||
|
}
|
||||||
|
.z-variable.z-other.z-readwrite.z-js, .z-variable.z-other.z-object.z-js, .z-variable.z-other.z-constant.z-js {
|
||||||
|
color: #657b83;
|
||||||
|
}
|
104
public/theme-switcher.js
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
// Theme Initialization
|
||||||
|
(function () {
|
||||||
|
// Get the default theme from the HTML data-theme attribute.
|
||||||
|
const defaultTheme = document.documentElement.getAttribute("data-theme");
|
||||||
|
|
||||||
|
// Set the data-default-theme attribute only if defaultTheme is not null.
|
||||||
|
if (defaultTheme) {
|
||||||
|
document.documentElement.setAttribute("data-default-theme", defaultTheme);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to retrieve the current theme from the browser's local storage.
|
||||||
|
const storedTheme = localStorage.getItem("theme");
|
||||||
|
|
||||||
|
if (storedTheme && storedTheme !== "system") {
|
||||||
|
document.documentElement.setAttribute("data-theme", storedTheme);
|
||||||
|
} else if (defaultTheme && storedTheme !== "system") {
|
||||||
|
document.documentElement.setAttribute("data-theme", defaultTheme);
|
||||||
|
} else {
|
||||||
|
// If no theme is found in local storage and no default theme is set, hand over control to the CSS.
|
||||||
|
document.documentElement.removeAttribute("data-theme");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expose defaultTheme to the outer scope.
|
||||||
|
window.defaultTheme = defaultTheme;
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Icon Update and Theme Switching
|
||||||
|
function setTheme(theme, saveToLocalStorage = false) {
|
||||||
|
if (theme === "system") {
|
||||||
|
document.documentElement.removeAttribute("data-theme");
|
||||||
|
} else {
|
||||||
|
document.documentElement.setAttribute("data-theme", theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saveToLocalStorage) {
|
||||||
|
localStorage.setItem("theme", theme);
|
||||||
|
} else {
|
||||||
|
localStorage.removeItem("theme");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update icon class based on the selected theme.
|
||||||
|
updateIconClass(theme);
|
||||||
|
|
||||||
|
// Update the active button based on the selected theme.
|
||||||
|
updateActiveButton(theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetTheme() {
|
||||||
|
// Reset the theme to the default or system preference if no default is set.
|
||||||
|
setTheme(window.defaultTheme || "system");
|
||||||
|
}
|
||||||
|
|
||||||
|
function switchTheme(theme) {
|
||||||
|
if (theme === "system") {
|
||||||
|
resetTheme();
|
||||||
|
} else {
|
||||||
|
setTheme(theme, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateIconClass(theme) {
|
||||||
|
const iconElement = document.querySelector("#theme-switcher summary .icon");
|
||||||
|
|
||||||
|
// Remove any existing theme classes
|
||||||
|
iconElement.classList.remove("light", "dark");
|
||||||
|
|
||||||
|
// Add the appropriate class based on the selected theme
|
||||||
|
if (theme === "light") {
|
||||||
|
iconElement.classList.add("light");
|
||||||
|
} else if (theme === "dark") {
|
||||||
|
iconElement.classList.add("dark");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateActiveButton(theme) {
|
||||||
|
// Remove .active class from all buttons
|
||||||
|
document.querySelectorAll('#theme-switcher button').forEach(button => {
|
||||||
|
button.classList.remove('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add .active class to the button corresponding to the current theme
|
||||||
|
const activeButton = document.querySelector(`#theme-${theme}`);
|
||||||
|
if (activeButton) {
|
||||||
|
activeButton.classList.add('active');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById("theme-light").addEventListener("click", function () {
|
||||||
|
switchTheme("light");
|
||||||
|
});
|
||||||
|
document.getElementById("theme-dark").addEventListener("click", function () {
|
||||||
|
switchTheme("dark");
|
||||||
|
});
|
||||||
|
document.getElementById("theme-system").addEventListener("click", function () {
|
||||||
|
switchTheme("system");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update icon class on page load based on current theme
|
||||||
|
const currentTheme = localStorage.getItem("theme") || window.defaultTheme || "system";
|
||||||
|
updateIconClass(currentTheme);
|
||||||
|
updateActiveButton(currentTheme);
|
||||||
|
|
||||||
|
// Make the switchTheme function accessible globally
|
||||||
|
window.switchTheme = switchTheme;
|
81
sass/_alerts.scss
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
blockquote {
|
||||||
|
&.note {
|
||||||
|
border-inline-start: 0.25rem solid var(--blue-fg);
|
||||||
|
|
||||||
|
.alert-title,
|
||||||
|
li::marker {
|
||||||
|
color: var(--blue-fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-title .icon {
|
||||||
|
-webkit-mask-image: var(--icon-info);
|
||||||
|
mask-image: var(--icon-info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.tip {
|
||||||
|
border-inline-start: 0.25rem solid var(--green-fg);
|
||||||
|
|
||||||
|
.alert-title,
|
||||||
|
li::marker {
|
||||||
|
color: var(--green-fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-title .icon {
|
||||||
|
-webkit-mask-image: var(--icon-lightbulb);
|
||||||
|
mask-image: var(--icon-lightbulb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.important {
|
||||||
|
border-inline-start: 0.25rem solid var(--purple-fg);
|
||||||
|
|
||||||
|
.alert-title,
|
||||||
|
li::marker {
|
||||||
|
color: var(--purple-fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-title .icon {
|
||||||
|
-webkit-mask-image: var(--icon-important);
|
||||||
|
mask-image: var(--icon-important);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
border-inline-start: 0.25rem solid var(--yellow-fg);
|
||||||
|
|
||||||
|
.alert-title,
|
||||||
|
li::marker {
|
||||||
|
color: var(--yellow-fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-title .icon {
|
||||||
|
-webkit-mask-image: var(--icon-warning);
|
||||||
|
mask-image: var(--icon-warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.caution {
|
||||||
|
border-inline-start: 0.25rem solid var(--red-fg);
|
||||||
|
|
||||||
|
.alert-title,
|
||||||
|
li::marker {
|
||||||
|
color: var(--red-fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-title .icon {
|
||||||
|
-webkit-mask-image: var(--icon-caution);
|
||||||
|
mask-image: var(--icon-caution);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-title {
|
||||||
|
margin-block-end: -0.75rem;
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
vertical-align: -0.125em;
|
||||||
|
margin-inline-end: 0.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
445
sass/_article-list.scss
Normal file
|
@ -0,0 +1,445 @@
|
||||||
|
#article-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-block-start: 2rem;
|
||||||
|
|
||||||
|
article {
|
||||||
|
--bg-overlay: var(--accent-color-alpha);
|
||||||
|
position: relative;
|
||||||
|
transition: var(--transition);
|
||||||
|
box-shadow: var(--edge-highlight), var(--shadow-glass);
|
||||||
|
border-radius: var(--rounded-corner);
|
||||||
|
border-start-end-radius: 2.125rem;
|
||||||
|
border-end-end-radius: 1.8125rem;
|
||||||
|
background-image: linear-gradient(var(--bg-overlay), var(--bg-overlay)),
|
||||||
|
linear-gradient(var(--glass-bg), var(--glass-bg)), var(--blurnail);
|
||||||
|
background-position: center;
|
||||||
|
background-size: cover;
|
||||||
|
background-color: var(--bg-overlay);
|
||||||
|
padding: 1rem;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
h3::after {
|
||||||
|
transform: none;
|
||||||
|
opacity: 1;
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active:not(:has(.tag:active)) {
|
||||||
|
transform: var(--active);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:has(> a:focus-visible) {
|
||||||
|
animation: focus-in var(--transition);
|
||||||
|
outline: 0.125rem solid var(--accent-color);
|
||||||
|
outline-offset: 0.125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@supports not selector(:focus-visible) {
|
||||||
|
&:has(> a:focus) {
|
||||||
|
animation: focus-in var(--transition);
|
||||||
|
outline: 0.125rem solid var(--accent-color);
|
||||||
|
outline-offset: 0.125rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > a {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
border-radius: var(--rounded-corner);
|
||||||
|
border-start-end-radius: 2.125rem;
|
||||||
|
border-end-end-radius: 1.8125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--accent-color);
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 1;
|
||||||
|
font-family: var(--font-system-ui);
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
-webkit-mask-image: var(--icon-right);
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
transform: translateX(-0.25rem);
|
||||||
|
opacity: 0;
|
||||||
|
mask-image: var(--icon-right);
|
||||||
|
transition: var(--transition);
|
||||||
|
margin-inline-start: 0.25rem;
|
||||||
|
background-color: currentColor;
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
pointer-events: none;
|
||||||
|
content: "";
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
transform: scaleX(-1) translateX(-0.25rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags {
|
||||||
|
position: relative;
|
||||||
|
justify-content: flex-end;
|
||||||
|
z-index: 1;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
a {
|
||||||
|
background-color: var(--accent-color-alpha);
|
||||||
|
color: var(--accent-color);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
color: var(--contrast-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.draft,
|
||||||
|
&.archive,
|
||||||
|
&.featured,
|
||||||
|
&.hot,
|
||||||
|
&.poor {
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
opacity: var(--disabled-opacity);
|
||||||
|
mask-size: cover;
|
||||||
|
transition: var(--transition-longer);
|
||||||
|
inset-block-start: 50%;
|
||||||
|
inset-inline-end: -3rem;
|
||||||
|
width: 12rem;
|
||||||
|
height: 12rem;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover::before {
|
||||||
|
transform: translateY(-50%) rotate(-10deg) scale(1.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[dir*="rtl"] &:hover::before {
|
||||||
|
transform: translateY(-50%) rotate(10deg) scale(1.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.draft {
|
||||||
|
--bg-overlay: var(--fg-muted-1);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
-webkit-mask-image: var(--icon-pencil);
|
||||||
|
mask-image: var(--icon-pencil);
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
color: var(--fg-muted-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
-webkit-mask-image: var(--icon-pencil);
|
||||||
|
mask-image: var(--icon-pencil);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags a {
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--fg-muted-5);
|
||||||
|
color: var(--fg-contrast);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.archive {
|
||||||
|
--bg-overlay: var(--purple-bg);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
-webkit-mask-image: var(--icon-archive);
|
||||||
|
mask-image: var(--icon-archive);
|
||||||
|
background-color: var(--purple-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
color: var(--purple-fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
background-color: var(--purple-bg);
|
||||||
|
color: var(--purple-fg);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
-webkit-mask-image: var(--icon-archive);
|
||||||
|
mask-image: var(--icon-archive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags a {
|
||||||
|
background-color: var(--purple-bg);
|
||||||
|
color: var(--purple-fg);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--purple-fg);
|
||||||
|
color: var(--fg-contrast);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.featured {
|
||||||
|
--bg-overlay: var(--yellow-bg);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
-webkit-mask-image: var(--icon-star);
|
||||||
|
mask-image: var(--icon-star);
|
||||||
|
background-color: var(--yellow-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
&::before {
|
||||||
|
transform: translateY(-50%) rotate(62deg) scale(1.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[dir*="rtl"] &::before {
|
||||||
|
transform: translateY(-50%) rotate(-62deg) scale(1.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
color: var(--yellow-fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
background-color: var(--yellow-bg);
|
||||||
|
color: var(--yellow-fg);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
-webkit-mask-image: var(--icon-star);
|
||||||
|
mask-image: var(--icon-star);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags a {
|
||||||
|
background-color: var(--yellow-bg);
|
||||||
|
color: var(--yellow-fg);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--yellow-fg);
|
||||||
|
color: var(--fg-contrast);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.hot {
|
||||||
|
--bg-overlay: var(--red-bg);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
-webkit-mask-image: var(--icon-fire);
|
||||||
|
mask-image: var(--icon-fire);
|
||||||
|
background-color: var(--red-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
color: var(--red-fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
background-color: var(--red-bg);
|
||||||
|
color: var(--red-fg);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
-webkit-mask-image: var(--icon-fire);
|
||||||
|
mask-image: var(--icon-fire);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags a {
|
||||||
|
background-color: var(--red-bg);
|
||||||
|
color: var(--red-fg);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--red-fg);
|
||||||
|
color: var(--fg-contrast);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.poor {
|
||||||
|
--bg-overlay: var(--brown-bg);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
-webkit-mask-image: var(--icon-poop);
|
||||||
|
mask-image: var(--icon-poop);
|
||||||
|
background-color: var(--brown-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
color: var(--brown-fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
background-color: var(--brown-bg);
|
||||||
|
color: var(--brown-fg);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
-webkit-mask-image: var(--icon-poop);
|
||||||
|
mask-image: var(--icon-poop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags a {
|
||||||
|
background-color: var(--brown-bg);
|
||||||
|
color: var(--brown-fg);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--brown-fg);
|
||||||
|
color: var(--fg-contrast);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
float: inline-end;
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: 999px;
|
||||||
|
padding: 0.375rem 0.75rem;
|
||||||
|
height: fit-content;
|
||||||
|
font-weight: bold;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
vertical-align: -0.125em;
|
||||||
|
margin-inline-end: 0.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.details {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.25rem;
|
||||||
|
margin-block-start: 1rem;
|
||||||
|
border-block-start: max(1px, 0.0625rem) solid var(--fg-muted-2);
|
||||||
|
padding-block-start: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#paginator {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.25rem;
|
||||||
|
margin-block-start: 4rem;
|
||||||
|
|
||||||
|
#paginator-first,
|
||||||
|
#paginator-previous,
|
||||||
|
#paginator-next,
|
||||||
|
#paginator-last {
|
||||||
|
display: inline-block;
|
||||||
|
transition: var(--transition);
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: 1rem;
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
padding: 0.5rem;
|
||||||
|
color: var(--fg-muted-4);
|
||||||
|
line-height: 0;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
transition: var(--transition);
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a#paginator-first,
|
||||||
|
a#paginator-previous,
|
||||||
|
a#paginator-next,
|
||||||
|
a#paginator-last {
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--fg-muted-2);
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: var(--active);
|
||||||
|
border-radius: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
span#paginator-first,
|
||||||
|
span#paginator-previous,
|
||||||
|
span#paginator-next,
|
||||||
|
span#paginator-last {
|
||||||
|
opacity: var(--disabled-opacity);
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
#paginator-previous {
|
||||||
|
border-start-end-radius: var(--rounded-corner-small);
|
||||||
|
border-end-end-radius: var(--rounded-corner-small);
|
||||||
|
}
|
||||||
|
|
||||||
|
#paginator-next {
|
||||||
|
border-start-start-radius: var(--rounded-corner-small);
|
||||||
|
border-end-start-radius: var(--rounded-corner-small);
|
||||||
|
}
|
||||||
|
|
||||||
|
#paginator-first .icon {
|
||||||
|
-webkit-mask-image: var(--icon-first);
|
||||||
|
mask-image: var(--icon-first);
|
||||||
|
}
|
||||||
|
|
||||||
|
#paginator-previous .icon {
|
||||||
|
-webkit-mask-image: var(--icon-previous);
|
||||||
|
mask-image: var(--icon-previous);
|
||||||
|
}
|
||||||
|
|
||||||
|
#paginator-next .icon {
|
||||||
|
-webkit-mask-image: var(--icon-next);
|
||||||
|
mask-image: var(--icon-next);
|
||||||
|
}
|
||||||
|
|
||||||
|
#paginator-last .icon {
|
||||||
|
-webkit-mask-image: var(--icon-last);
|
||||||
|
mask-image: var(--icon-last);
|
||||||
|
}
|
||||||
|
|
||||||
|
#paginator-counter {
|
||||||
|
display: inline-block;
|
||||||
|
transition: var(--transition);
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: var(--rounded-corner-small);
|
||||||
|
background-color: var(--accent-color-alpha);
|
||||||
|
padding: 0.5rem 0.625rem;
|
||||||
|
color: var(--accent-color);
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 1;
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:has(a#paginator-previous:active) #paginator-counter {
|
||||||
|
border-start-start-radius: 1rem;
|
||||||
|
border-end-start-radius: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:has(a#paginator-next:active) #paginator-counter {
|
||||||
|
border-start-end-radius: 1rem;
|
||||||
|
border-end-end-radius: 1rem;
|
||||||
|
}
|
||||||
|
}
|
248
sass/_article.scss
Normal file
|
@ -0,0 +1,248 @@
|
||||||
|
#banner-container {
|
||||||
|
--mask: linear-gradient(black, transparent);
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-webkit-mask-image: var(--mask);
|
||||||
|
position: absolute;
|
||||||
|
z-index: -1;
|
||||||
|
mask-image: var(--mask);
|
||||||
|
inset-block-start: 0;
|
||||||
|
inset-inline-start: 0;
|
||||||
|
aspect-ratio: 2 / 1;
|
||||||
|
width: 100%;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
#banner {
|
||||||
|
position: fixed;
|
||||||
|
transition: none;
|
||||||
|
margin: 0;
|
||||||
|
inset-block-start: 0;
|
||||||
|
inset-inline-start: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
& + #heading {
|
||||||
|
margin-block-start: calc(50vw - 7rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 480px) {
|
||||||
|
body:has(&) #site-nav:not(#handle + #site-nav) {
|
||||||
|
margin-block-start: calc(50vw + 1rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#heading {
|
||||||
|
margin: 2rem 0 1rem;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
margin: 0;
|
||||||
|
background-image: linear-gradient(
|
||||||
|
to right,
|
||||||
|
var(--fg-muted-4),
|
||||||
|
var(--fg-color),
|
||||||
|
var(--fg-muted-4)
|
||||||
|
);
|
||||||
|
background-clip: text;
|
||||||
|
color: transparent;
|
||||||
|
|
||||||
|
& + p {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags {
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-block-start: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#buttons-container {
|
||||||
|
display: flex;
|
||||||
|
position: fixed;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
inset-block-end: 1rem;
|
||||||
|
inset-inline-end: 1rem;
|
||||||
|
|
||||||
|
@media only screen and (max-width: 720px) {
|
||||||
|
position: static;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
// justify-content: center;
|
||||||
|
margin-block-start: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
summary,
|
||||||
|
#go-to-top,
|
||||||
|
#share,
|
||||||
|
#issue {
|
||||||
|
display: inline-block;
|
||||||
|
transition: var(--transition);
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: 999px;
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
padding: 0.5rem;
|
||||||
|
color: var(--fg-muted-4);
|
||||||
|
line-height: 0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--fg-muted-2);
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: var(--active);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
transition: var(--transition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
details {
|
||||||
|
position: relative;
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
&[open] summary ~ * {
|
||||||
|
transform-origin: bottom right;
|
||||||
|
animation: button-dropdown-open var(--transition);
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
transform-origin: bottom left;
|
||||||
|
animation: button-dropdown-open-rtl var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes button-dropdown-open {
|
||||||
|
from {
|
||||||
|
transform: scale(0.5) translate(1rem, 1rem);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes button-dropdown-open-rtl {
|
||||||
|
from {
|
||||||
|
transform: scale(0.5) translate(-1rem, 1rem);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
summary {
|
||||||
|
&::before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
summary + div {
|
||||||
|
-webkit-backdrop-filter: var(--blur);
|
||||||
|
display: flex;
|
||||||
|
position: absolute;
|
||||||
|
flex-direction: column;
|
||||||
|
z-index: 1;
|
||||||
|
backdrop-filter: var(--blur);
|
||||||
|
inset-block-end: 0;
|
||||||
|
inset-inline-end: 3rem;
|
||||||
|
box-shadow: var(--edge-highlight), var(--shadow-glass);
|
||||||
|
border-radius: var(--rounded-corner);
|
||||||
|
background-color: var(--glass-bg);
|
||||||
|
padding: 1rem;
|
||||||
|
width: min(calc(var(--container-width) / 3), calc(90vw - 3rem));
|
||||||
|
max-height: 50vh;
|
||||||
|
|
||||||
|
@media only screen and (max-width: 720px) {
|
||||||
|
inset-inline-end: 2.5rem;
|
||||||
|
width: min(calc(var(--container-width) / 3), calc(90vw - 2.5rem));
|
||||||
|
}
|
||||||
|
|
||||||
|
strong.title {
|
||||||
|
color: var(--fg-muted-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
--mask: linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
transparent,
|
||||||
|
black 1rem,
|
||||||
|
black calc(100% - 1rem),
|
||||||
|
transparent
|
||||||
|
);
|
||||||
|
-webkit-mask-image: var(--mask);
|
||||||
|
flex: 1;
|
||||||
|
mask-image: var(--mask);
|
||||||
|
margin: 0 -1rem -1rem;
|
||||||
|
padding: 1rem;
|
||||||
|
padding-block-start: 0;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol,
|
||||||
|
ul {
|
||||||
|
margin: 0;
|
||||||
|
padding-inline-start: 0.75rem;
|
||||||
|
font-size: var(--font-size-small);
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
margin-block-start: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
li::marker {
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#toc .icon {
|
||||||
|
-webkit-mask-image: var(--icon-toc);
|
||||||
|
mask-image: var(--icon-toc);
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#backlinks {
|
||||||
|
.icon {
|
||||||
|
-webkit-mask-image: var(--icon-backlink);
|
||||||
|
mask-image: var(--icon-backlink);
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
summary + div {
|
||||||
|
width: min(calc(var(--container-width) / 3), calc(90vw - 5rem));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#go-to-top {
|
||||||
|
@media only screen and (max-width: 720px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
-webkit-mask-image: var(--icon-top);
|
||||||
|
mask-image: var(--icon-top);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#share .icon {
|
||||||
|
-webkit-mask-image: var(--icon-share);
|
||||||
|
mask-image: var(--icon-share);
|
||||||
|
}
|
||||||
|
|
||||||
|
#issue .icon {
|
||||||
|
-webkit-mask-image: var(--icon-bug);
|
||||||
|
mask-image: var(--icon-bug);
|
||||||
|
}
|
||||||
|
}
|
72
sass/_buttons.scss
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
.buttons {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-block-start: 4rem;
|
||||||
|
|
||||||
|
&.centered {
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
appearance: none;
|
||||||
|
cursor: pointer;
|
||||||
|
border: none;
|
||||||
|
font-family: inherit;
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a,
|
||||||
|
button {
|
||||||
|
transition: var(--transition);
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: var(--rounded-corner);
|
||||||
|
background-color: var(--fg-muted-1) !important;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: var(--font-size-small);
|
||||||
|
line-height: 1;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--fg-muted-3) !important;
|
||||||
|
color: var(--fg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: var(--active);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.colored {
|
||||||
|
box-shadow: none;
|
||||||
|
background-color: transparent;
|
||||||
|
color: var(--accent-color);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
background-color: var(--accent-color-alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.big {
|
||||||
|
border-radius: 999px;
|
||||||
|
padding: 1rem 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
74
sass/_code.scss
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
// CODE
|
||||||
|
pre,
|
||||||
|
code,
|
||||||
|
kbd,
|
||||||
|
samp {
|
||||||
|
font-family: var(--font-monospace-code);
|
||||||
|
}
|
||||||
|
|
||||||
|
code:not(pre code) {
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: var(--rounded-corner-small);
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
padding: 0.125rem 0.375rem;
|
||||||
|
color: var(--red-fg);
|
||||||
|
font-size: var(--font-size-small-em);
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
margin: 1rem 0 1rem;
|
||||||
|
box-shadow: var(--edge-highlight), var(--shadow);
|
||||||
|
border-radius: var(--rounded-corner);
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
padding: 1rem;
|
||||||
|
max-width: 100vw;
|
||||||
|
overflow: auto;
|
||||||
|
line-height: normal;
|
||||||
|
|
||||||
|
table {
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
table-layout: auto;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
tr {
|
||||||
|
&:nth-child(even) {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background-color: transparent;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The line number cells
|
||||||
|
table td:nth-of-type(1) {
|
||||||
|
-webkit-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
mark {
|
||||||
|
display: block;
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 0; // Unset code block border radius
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
padding: 0; // Unset mark padding
|
||||||
|
color: var(
|
||||||
|
--fg-color
|
||||||
|
); // Unset mark color from accent color to text color
|
||||||
|
}
|
||||||
|
|
||||||
|
// The line numbers already provide some kind of left/right padding
|
||||||
|
&[data-linenos] {
|
||||||
|
padding: 1rem 0;
|
||||||
|
}
|
||||||
|
}
|
471
sass/_comments.scss
Normal file
|
@ -0,0 +1,471 @@
|
||||||
|
#comments {
|
||||||
|
#qrcode {
|
||||||
|
float: inline-end;
|
||||||
|
transform-origin: right;
|
||||||
|
box-sizing: content-box;
|
||||||
|
margin-inline-start: 1rem;
|
||||||
|
margin-block-start: 3rem;
|
||||||
|
margin-block-end: 0;
|
||||||
|
background-color: white;
|
||||||
|
padding: 0.75rem;
|
||||||
|
width: 7.8125rem; // 125px
|
||||||
|
height: 7.8125rem; // 125px
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
transform-origin: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 720px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttons {
|
||||||
|
justify-content: start;
|
||||||
|
gap: 0.25rem;
|
||||||
|
margin-block-start: 2rem;
|
||||||
|
|
||||||
|
#load-comments:disabled {
|
||||||
|
--shimmer: rgb(
|
||||||
|
from var(--accent-color) r g b / calc(var(--color-opacity) * 2)
|
||||||
|
);
|
||||||
|
animation: loading-shimmer var(--transition-long) ease-in-out
|
||||||
|
alternate infinite;
|
||||||
|
transition: none;
|
||||||
|
background-image: linear-gradient(
|
||||||
|
to right,
|
||||||
|
var(--fg-muted-1) 50%,
|
||||||
|
var(--shimmer) 75%,
|
||||||
|
var(--fg-muted-1) 100%
|
||||||
|
);
|
||||||
|
background-size: 200%;
|
||||||
|
background-color: transparent;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes loading-shimmer {
|
||||||
|
to {
|
||||||
|
background-position-x: -200%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#comments-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2rem;
|
||||||
|
margin-block-start: 2rem;
|
||||||
|
|
||||||
|
#comments-status {
|
||||||
|
color: var(--fg-muted-4);
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: var(--font-size-x-large);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: min-content;
|
||||||
|
grid-template-areas:
|
||||||
|
"avatar name "
|
||||||
|
"avatar time "
|
||||||
|
"avatar post "
|
||||||
|
"...... media "
|
||||||
|
"...... card "
|
||||||
|
"...... interactions";
|
||||||
|
column-gap: 1rem;
|
||||||
|
justify-items: start;
|
||||||
|
|
||||||
|
&.comment-reply {
|
||||||
|
position: relative;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
border-inline-start: 0.25rem solid var(--fg-muted-2);
|
||||||
|
padding-inline-start: 1rem;
|
||||||
|
|
||||||
|
&:has(+ .comment-reply) {
|
||||||
|
border-end-start-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
& + .comment-reply {
|
||||||
|
margin-block-start: -2rem;
|
||||||
|
border-start-start-radius: 0;
|
||||||
|
padding-block-start: 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-link {
|
||||||
|
position: relative;
|
||||||
|
grid-area: avatar;
|
||||||
|
width: 4rem;
|
||||||
|
height: 4rem;
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
transition: var(--transition);
|
||||||
|
margin: 0;
|
||||||
|
background-size: cover;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: rotate(10deg) var(--hover);
|
||||||
|
border-radius: var(--rounded-corner);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: var(--active);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.author {
|
||||||
|
display: flex;
|
||||||
|
grid-area: name;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.25rem;
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
.instance {
|
||||||
|
transition: var(--transition);
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: 999px;
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
padding: 0.375rem 0.75rem;
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
font-size: var(--font-size-small);
|
||||||
|
line-height: 1;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--fg-muted-5);
|
||||||
|
color: var(--fg-contrast);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: var(--active);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.op {
|
||||||
|
background-color: var(--accent-color-alpha);
|
||||||
|
padding-inline-start: 0.4375rem;
|
||||||
|
color: var(--accent-color);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
color: var(--contrast-color);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
background-color: var(--contrast-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
-webkit-mask-image: var(--icon-verified);
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: -0.1875rem;
|
||||||
|
mask-image: var(--icon-verified);
|
||||||
|
mask-size: cover;
|
||||||
|
transition: var(--transition);
|
||||||
|
margin-inline-end: 0.25rem;
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
padding: 0.375rem 0.5rem 0.375rem 0.75rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mention {
|
||||||
|
display: inline-block;
|
||||||
|
transition: var(--transition);
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: var(--rounded-corner-small);
|
||||||
|
background-color: var(--accent-color-alpha);
|
||||||
|
padding: 0.25rem 0.375rem;
|
||||||
|
line-height: 1;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
color: var(--contrast-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: var(--active);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.hashtag {
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--fg-muted-5);
|
||||||
|
color: var(--fg-contrast);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
time {
|
||||||
|
grid-area: time;
|
||||||
|
margin-block-start: 0.5rem;
|
||||||
|
font-size: var(--font-size-small);
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
background-color: var(--fg-muted-5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
details {
|
||||||
|
&[open] {
|
||||||
|
border-radius: var(--rounded-corner-small);
|
||||||
|
background-image: linear-gradient(
|
||||||
|
to right,
|
||||||
|
transparent,
|
||||||
|
transparent 0.5rem,
|
||||||
|
var(--fg-muted-1) 0.5rem,
|
||||||
|
var(--fg-muted-1) calc(100% - 0.5rem),
|
||||||
|
transparent calc(100% - 0.5rem),
|
||||||
|
transparent
|
||||||
|
),
|
||||||
|
linear-gradient(
|
||||||
|
to right,
|
||||||
|
transparent,
|
||||||
|
transparent 0.5rem,
|
||||||
|
var(--bg-color) 0.5rem,
|
||||||
|
var(--bg-color) calc(100% - 0.5rem),
|
||||||
|
transparent calc(100% - 0.5rem),
|
||||||
|
transparent
|
||||||
|
),
|
||||||
|
repeating-linear-gradient(
|
||||||
|
45deg,
|
||||||
|
var(--contrast-color),
|
||||||
|
var(--contrast-color) 0.25rem,
|
||||||
|
var(--accent-color) 0.25rem,
|
||||||
|
var(--accent-color) 0.5rem
|
||||||
|
);
|
||||||
|
|
||||||
|
summary {
|
||||||
|
border-radius: 0;
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
summary {
|
||||||
|
border-radius: var(--rounded-corner-small);
|
||||||
|
background-image: linear-gradient(
|
||||||
|
to right,
|
||||||
|
transparent,
|
||||||
|
transparent 0.5rem,
|
||||||
|
var(--fg-muted-1) 0.5rem,
|
||||||
|
var(--fg-muted-1) calc(100% - 0.5rem),
|
||||||
|
transparent calc(100% - 0.5rem),
|
||||||
|
transparent
|
||||||
|
),
|
||||||
|
linear-gradient(
|
||||||
|
to right,
|
||||||
|
transparent,
|
||||||
|
transparent 0.5rem,
|
||||||
|
var(--bg-color) 0.5rem,
|
||||||
|
var(--bg-color) calc(100% - 0.5rem),
|
||||||
|
transparent calc(100% - 0.5rem),
|
||||||
|
transparent
|
||||||
|
),
|
||||||
|
repeating-linear-gradient(
|
||||||
|
45deg,
|
||||||
|
var(--contrast-color),
|
||||||
|
var(--contrast-color) 0.25rem,
|
||||||
|
var(--accent-color) 0.25rem,
|
||||||
|
var(--accent-color) 0.5rem
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
grid-area: post;
|
||||||
|
margin: 1rem 0 0;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
:first-child {
|
||||||
|
margin-block-start: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:last-child {
|
||||||
|
margin-block-end: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachments {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
|
||||||
|
grid-area: media;
|
||||||
|
gap: 0.5rem;
|
||||||
|
margin-block-start: 1rem;
|
||||||
|
|
||||||
|
img,
|
||||||
|
video {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
grid-area: card;
|
||||||
|
transition: var(--transition);
|
||||||
|
margin-block-start: 1rem;
|
||||||
|
width: min(calc(var(--container-width) / 2), 100%);
|
||||||
|
font-weight: normal;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover:not(:active) {
|
||||||
|
img {
|
||||||
|
transform: var(--hover);
|
||||||
|
box-shadow: var(--edge-highlight), var(--shadow-raised);
|
||||||
|
border-radius: var(--rounded-corner-small);
|
||||||
|
}
|
||||||
|
|
||||||
|
figcaption {
|
||||||
|
border-radius: var(--rounded-corner);
|
||||||
|
background-color: var(--fg-muted-2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: var(--active);
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.25rem;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin: 0;
|
||||||
|
border-radius: var(--rounded-corner)
|
||||||
|
var(--rounded-corner) var(--rounded-corner-small)
|
||||||
|
var(--rounded-corner-small);
|
||||||
|
aspect-ratio: 16 / 9;
|
||||||
|
object-fit: cover;
|
||||||
|
|
||||||
|
& + figcaption {
|
||||||
|
border-radius: var(--rounded-corner-small)
|
||||||
|
var(--rounded-corner-small)
|
||||||
|
var(--rounded-corner) var(--rounded-corner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
figcaption {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.25rem;
|
||||||
|
transition: var(--transition);
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: var(--rounded-corner);
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
padding: 1rem;
|
||||||
|
color: var(--fg-color);
|
||||||
|
font-size: var(--font-size-medium);
|
||||||
|
text-align: start;
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
font-size: var(--font-size-small);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
display: flex;
|
||||||
|
grid-area: interactions;
|
||||||
|
gap: 0.25rem;
|
||||||
|
margin-block-start: 1rem;
|
||||||
|
|
||||||
|
.boosts,
|
||||||
|
.faves {
|
||||||
|
transition: var(--transition);
|
||||||
|
border-radius: 999px;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 0.5rem 0.75rem;
|
||||||
|
padding-inline-start: 0.625rem;
|
||||||
|
line-height: 1;
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
vertical-align: -0.125em;
|
||||||
|
transition: var(--transition-longer);
|
||||||
|
margin-inline-end: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: var(--active);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.boosts {
|
||||||
|
color: var(--purple-fg);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--purple-bg);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
transform: scaleX(-1) rotate(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
-webkit-mask-image: var(--icon-boosts);
|
||||||
|
mask-image: var(--icon-boosts);
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.faves {
|
||||||
|
color: var(--yellow-fg);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--yellow-bg);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
transform: rotate(72deg);
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
transform: rotate(-72deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
-webkit-mask-image: var(--icon-star);
|
||||||
|
mask-image: var(--icon-star);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
104
sass/_crt.scss
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
.crt {
|
||||||
|
margin: 1rem 0 1rem;
|
||||||
|
box-shadow: var(--edge-highlight), var(--shadow-glow);
|
||||||
|
border-radius: var(--rounded-corner);
|
||||||
|
background-image: radial-gradient(
|
||||||
|
color-mix(in srgb, var(--accent-color) 30%, black),
|
||||||
|
color-mix(in srgb, var(--accent-color) 10%, black) 80%,
|
||||||
|
color-mix(in srgb, var(--accent-color) 5%, black)
|
||||||
|
);
|
||||||
|
|
||||||
|
pre {
|
||||||
|
--text-shadow-1: hsl(from var(--accent-color) h s l / 0.5);
|
||||||
|
--text-shadow-2: hsl(from var(--accent-color) h calc(s * 2) l);
|
||||||
|
animation: flicker 0.25s alternate infinite;
|
||||||
|
margin: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
background-color: transparent !important;
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
color: var(--accent-color) !important;
|
||||||
|
text-shadow:
|
||||||
|
var(--text-shadow-1) 0 0 0.25rem,
|
||||||
|
var(--text-shadow-2) 0 0 0.75rem;
|
||||||
|
|
||||||
|
@keyframes flicker {
|
||||||
|
25% {
|
||||||
|
opacity: 0.95;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
opacity: 0.85;
|
||||||
|
}
|
||||||
|
|
||||||
|
75% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.scanlines {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
animation: scanlines 0.1s linear infinite;
|
||||||
|
inset: 0;
|
||||||
|
background-image: repeating-linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
rgb(0 0 0 / 0.25),
|
||||||
|
rgb(0 0 0 / 0.25) 0.125rem,
|
||||||
|
transparent 0.125rem,
|
||||||
|
transparent 0.25rem
|
||||||
|
);
|
||||||
|
pointer-events: none;
|
||||||
|
content: "";
|
||||||
|
|
||||||
|
@keyframes scanlines {
|
||||||
|
to {
|
||||||
|
background-position-y: 0.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
--scanline-color: rgb(from var(--accent-color) r g b / 0.05);
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
animation: scanline 5s linear infinite;
|
||||||
|
inset: 0;
|
||||||
|
background-image: linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
transparent,
|
||||||
|
var(--scanline-color) 16rem
|
||||||
|
);
|
||||||
|
background-size: auto 16rem;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position-y: -16rem;
|
||||||
|
pointer-events: none;
|
||||||
|
content: "";
|
||||||
|
|
||||||
|
@keyframes scanline {
|
||||||
|
to {
|
||||||
|
background-position-y: calc(100% + 16rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cursor {
|
||||||
|
animation: cursor-blink 1s infinite;
|
||||||
|
|
||||||
|
@keyframes cursor-blink {
|
||||||
|
50% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
sass/_emoji.scss
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
.emoji {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: bottom;
|
||||||
|
transition: var(--transition);
|
||||||
|
cursor: zoom-in;
|
||||||
|
margin: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
width: 1.5em;
|
||||||
|
height: 1.5em;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: scale(2);
|
||||||
|
}
|
||||||
|
}
|
16
sass/_external.scss
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
a.external::after {
|
||||||
|
-webkit-mask-image: var(--icon-external);
|
||||||
|
display: inline-block;
|
||||||
|
opacity: var(--dim-opacity);
|
||||||
|
mask-image: var(--icon-external);
|
||||||
|
mask-size: cover;
|
||||||
|
margin-inline-start: 0.25rem;
|
||||||
|
background-color: currentColor;
|
||||||
|
width: max(0.75rem, 0.75em);
|
||||||
|
height: max(0.75rem, 0.75em);
|
||||||
|
content: "";
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
}
|
12
sass/_feed.scss
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
h1 a:has(.icon.feed) {
|
||||||
|
color: currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 .icon.feed {
|
||||||
|
-webkit-mask-image: var(--icon-feed);
|
||||||
|
vertical-align: -0.375rem;
|
||||||
|
mask-image: var(--icon-feed);
|
||||||
|
margin-inline-start: 0.5rem;
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
}
|
137
sass/_footer.scss
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
#site-footer {
|
||||||
|
grid-area: footer;
|
||||||
|
margin-block-end: 2rem;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
nav {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 auto 1rem;
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: 1.375rem;
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
padding: 0.25rem;
|
||||||
|
max-width: 90%;
|
||||||
|
|
||||||
|
ul {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.25rem;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: flex;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
@media only screen and (max-width: 480px) {
|
||||||
|
flex: 0 0 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
flex: 1;
|
||||||
|
transition: var(--transition);
|
||||||
|
border-radius: 999px;
|
||||||
|
padding: 0.375rem 0.75rem;
|
||||||
|
color: var(--fg-muted-4);
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
background-color: var(--accent-color-alpha);
|
||||||
|
color: var(--accent-color);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
color: var(--contrast-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: var(--active);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#socials {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
margin: 1rem auto 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
transition: var(--transition);
|
||||||
|
border-radius: 999px;
|
||||||
|
padding: 0.5rem;
|
||||||
|
color: var(--fg-muted-4);
|
||||||
|
line-height: 0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: var(--active);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
-webkit-mask-image: var(--icon);
|
||||||
|
mask-image: var(--icon);
|
||||||
|
transition: var(--transition);
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 1rem auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link {
|
||||||
|
display: inline-block;
|
||||||
|
transition: var(--transition);
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: var(--rounded-corner-small);
|
||||||
|
background-color: var(--accent-color-alpha);
|
||||||
|
padding: 0.25rem 0.375rem;
|
||||||
|
line-height: 1;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
color: var(--contrast-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: var(--active);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
sass/_footnotes-list.scss
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
.footnotes-list {
|
||||||
|
p {
|
||||||
|
margin-block-start: 0;
|
||||||
|
margin-block-end: 0;
|
||||||
|
}
|
||||||
|
}
|
140
sass/_general.scss
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
scrollbar-color: var(--accent-color) transparent;
|
||||||
|
accent-color: var(--accent-color);
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
text-wrap: pretty;
|
||||||
|
display: grid; // Put footer at the bottom for short pages, such as the 404
|
||||||
|
grid-template-rows: auto minmax(auto, 1fr) auto; // Header, stuff, footer
|
||||||
|
grid-template-areas:
|
||||||
|
"nav"
|
||||||
|
"main"
|
||||||
|
"footer";
|
||||||
|
margin: 0;
|
||||||
|
background-color: var(--bg-color);
|
||||||
|
min-height: 100vh;
|
||||||
|
color: var(--fg-color);
|
||||||
|
line-height: 1.5;
|
||||||
|
font-family: var(--font-system-ui), var(--font-emoji);
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
|
||||||
|
&:has(#sidebar) {
|
||||||
|
grid-template-columns: 1fr min(var(--container-width), 90%) 1fr;
|
||||||
|
grid-template-areas:
|
||||||
|
"nav nav nav"
|
||||||
|
"sidebar main ."
|
||||||
|
"footer footer footer";
|
||||||
|
@media only screen and (max-width: 1200px) {
|
||||||
|
grid-template-areas:
|
||||||
|
"nav nav nav"
|
||||||
|
". sidebar ."
|
||||||
|
". main ."
|
||||||
|
"footer footer footer";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Style text selection to use accent color
|
||||||
|
::selection {
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
color: var(--contrast-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make focused anchor not get covered by nav,
|
||||||
|
// and flash it with accent color when jumping to it
|
||||||
|
:target:not(#main-content) {
|
||||||
|
transition:
|
||||||
|
all var(--transition),
|
||||||
|
scroll-margin-block-start 0s;
|
||||||
|
scroll-margin-block-start: 15vh;
|
||||||
|
color: var(--accent-color);
|
||||||
|
text-shadow: var(--text-shadow-glow);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom focus indicator
|
||||||
|
:focus-visible {
|
||||||
|
animation: focus-in var(--transition);
|
||||||
|
outline: 0.125rem solid var(--accent-color);
|
||||||
|
outline-offset: 0.125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback for older browsers
|
||||||
|
@supports not selector(:focus-visible) {
|
||||||
|
:focus {
|
||||||
|
animation: focus-in var(--transition);
|
||||||
|
outline: 0.125rem solid var(--accent-color);
|
||||||
|
outline-offset: 0.125rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes focus-in {
|
||||||
|
from {
|
||||||
|
outline: 0.5rem solid transparent;
|
||||||
|
outline-offset: 0.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
margin: 4.25rem auto 4rem;
|
||||||
|
width: min(var(--container-width), 90%);
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar {
|
||||||
|
display: flex;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
grid-area: sidebar;
|
||||||
|
opacity: 0.2;
|
||||||
|
transition: var(--transition);
|
||||||
|
height: 100vh;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1200px) {
|
||||||
|
position: static;
|
||||||
|
opacity: 1;
|
||||||
|
margin-block-start: 4.25rem;
|
||||||
|
margin-block-end: -4.25rem;
|
||||||
|
padding: 0;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
--mask: linear-gradient(to bottom,
|
||||||
|
transparent,
|
||||||
|
black 1rem,
|
||||||
|
black calc(100% - 1rem),
|
||||||
|
transparent);
|
||||||
|
-webkit-mask-image: var(--mask);
|
||||||
|
mask-image: var(--mask);
|
||||||
|
padding: 1rem;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
& + main {
|
||||||
|
grid-area: main;
|
||||||
|
margin: 0;
|
||||||
|
margin-block-start: 4.25rem;
|
||||||
|
margin-block-end: 4rem;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion) {
|
||||||
|
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
animation-duration: 0s !important;
|
||||||
|
transition-duration: 0s !important;
|
||||||
|
}
|
||||||
|
}
|
4
sass/_hidden.scss
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
11
sass/_icon.scss
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
i.icon {
|
||||||
|
display: inline-block;
|
||||||
|
mask-size: cover;
|
||||||
|
background-color: currentColor;
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
font-style: normal;
|
||||||
|
font-variant: normal;
|
||||||
|
line-height: 0;
|
||||||
|
text-rendering: auto;
|
||||||
|
}
|
30
sass/_iframe.scss
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
iframe {
|
||||||
|
display: block;
|
||||||
|
margin: 1rem auto;
|
||||||
|
box-shadow: var(--edge-highlight), var(--shadow);
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--rounded-corner);
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
|
||||||
|
&.mastodon-embed {
|
||||||
|
aspect-ratio: 3 / 4;
|
||||||
|
width: min(calc(var(--container-width) / 2), 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.vimeo-embed,
|
||||||
|
&.youtube-embed {
|
||||||
|
aspect-ratio: 16 / 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:fullscreen {
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:-webkit-full-screen {
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
203
sass/_input.scss
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
input[type="radio"],
|
||||||
|
input[type="checkbox"],
|
||||||
|
input[type="color"] {
|
||||||
|
position: relative;
|
||||||
|
appearance: none;
|
||||||
|
transition: var(--transition);
|
||||||
|
cursor: pointer;
|
||||||
|
border: 0.15rem solid var(--fg-muted-2);
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--fg-muted-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
opacity: var(--disabled-opacity);
|
||||||
|
cursor: not-allowed;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
|
||||||
|
&:checked {
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="radio"],
|
||||||
|
input[type="checkbox"] {
|
||||||
|
&::before {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
transform: scale(0.5);
|
||||||
|
opacity: 0;
|
||||||
|
transition: var(--transition);
|
||||||
|
background-color: var(--contrast-color);
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
&:checked {
|
||||||
|
border: 0.15rem solid transparent;
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="radio"] {
|
||||||
|
vertical-align: -0.1875em;
|
||||||
|
border-radius: 50%;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
inset-block-start: 0.125rem;
|
||||||
|
inset-inline-start: 0.125rem;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 0.5rem;
|
||||||
|
height: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="checkbox"] {
|
||||||
|
vertical-align: -0.1875em;
|
||||||
|
border-radius: calc(var(--rounded-corner-small) / 2);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
-webkit-mask-image: var(--icon-checkmark);
|
||||||
|
transform-origin: bottom left;
|
||||||
|
mask-image: var(--icon-checkmark);
|
||||||
|
mask-size: cover;
|
||||||
|
inset-block-start: -0.125rem;
|
||||||
|
inset-inline-start: -0.125rem;
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.switch {
|
||||||
|
vertical-align: -0.375rem;
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border: none;
|
||||||
|
border-radius: 999px;
|
||||||
|
width: 2.5rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
|
||||||
|
&.big {
|
||||||
|
vertical-align: -0.625rem;
|
||||||
|
width: 3rem;
|
||||||
|
height: 2rem;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
transform: none;
|
||||||
|
transform-origin: center;
|
||||||
|
opacity: 1;
|
||||||
|
mask-image: none;
|
||||||
|
transition: var(--transition);
|
||||||
|
inset-block-start: 0.25rem;
|
||||||
|
inset-inline-start: 0.25rem;
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: white;
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:checked {
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
transform: translateX(1rem);
|
||||||
|
background-color: var(--contrast-color);
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
transform: translateX(-1rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
&::before {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="color"] {
|
||||||
|
vertical-align: -0.375em;
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--rounded-corner-small);
|
||||||
|
padding: 0.25rem;
|
||||||
|
width: 3rem;
|
||||||
|
height: 2rem;
|
||||||
|
|
||||||
|
&::-moz-color-swatch {
|
||||||
|
border: none;
|
||||||
|
border-radius: calc(var(--rounded-corner-small) - 0.25rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-color-swatch-wrapper {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-color-swatch {
|
||||||
|
border-radius: calc(var(--rounded-corner-small) - 0.25rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="range"] {
|
||||||
|
appearance: none;
|
||||||
|
transition: var(--transition);
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: 999px;
|
||||||
|
background: var(--accent-color);
|
||||||
|
width: 100%;
|
||||||
|
height: 0.5rem;
|
||||||
|
|
||||||
|
&::-webkit-slider-thumb {
|
||||||
|
appearance: none;
|
||||||
|
filter: brightness(0.9);
|
||||||
|
transition: var(--transition);
|
||||||
|
cursor: grab;
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
border-radius: 999px;
|
||||||
|
background-color: white;
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: var(--active);
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-moz-range-thumb {
|
||||||
|
appearance: none;
|
||||||
|
transition: var(--transition);
|
||||||
|
cursor: grab;
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
border: none;
|
||||||
|
border-radius: 999px;
|
||||||
|
background-color: white;
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: var(--active);
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
164
sass/_media.scss
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
img,
|
||||||
|
video {
|
||||||
|
display: block;
|
||||||
|
margin: 1rem auto;
|
||||||
|
box-shadow: var(--edge-highlight), var(--shadow);
|
||||||
|
border-radius: var(--rounded-corner);
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
max-width: 100%;
|
||||||
|
|
||||||
|
&.full,
|
||||||
|
&[src*="#full"] {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.full-bleed,
|
||||||
|
&[src*="#full-bleed"] {
|
||||||
|
margin-inline-start: calc((-100vw + 100%) / 2);
|
||||||
|
margin-inline-end: calc((-100vw + 100%) / 2);
|
||||||
|
width: 100vw;
|
||||||
|
max-width: 100vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.start,
|
||||||
|
&.end,
|
||||||
|
&[src*="#start"],
|
||||||
|
&[src*="#end"] {
|
||||||
|
margin: 0;
|
||||||
|
width: 30%;
|
||||||
|
|
||||||
|
@media only screen and (max-width: 720px) {
|
||||||
|
float: none;
|
||||||
|
margin-inline-start: 0;
|
||||||
|
margin-inline-end: 0;
|
||||||
|
margin-block-start: 1rem;
|
||||||
|
margin-block-end: 1rem;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.start,
|
||||||
|
&[src*="#start"] {
|
||||||
|
float: inline-start;
|
||||||
|
transform-origin: left;
|
||||||
|
margin-inline-end: 1rem;
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
transform-origin: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.end,
|
||||||
|
&[src*="#end"] {
|
||||||
|
float: inline-end;
|
||||||
|
transform-origin: right;
|
||||||
|
margin-inline-start: 1rem;
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
transform-origin: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.pixels,
|
||||||
|
&[src*="#pixels"] {
|
||||||
|
image-rendering: pixelated;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.transparent,
|
||||||
|
&.full-bleed,
|
||||||
|
&[src*="#transparent"],
|
||||||
|
&[src*="#full-bleed"] {
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.spoiler,
|
||||||
|
&[src*="#spoiler"] {
|
||||||
|
opacity: var(--dim-opacity);
|
||||||
|
clip-path: inset(0 0 0 0 round var(--rounded-corner));
|
||||||
|
filter: blur(1rem);
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:active {
|
||||||
|
opacity: 1;
|
||||||
|
clip-path: inset(
|
||||||
|
-0.75rem -0.75rem -0.75rem -0.75rem round
|
||||||
|
var(--rounded-corner-small)
|
||||||
|
);
|
||||||
|
filter: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.solid,
|
||||||
|
&[src*="#solid"] {
|
||||||
|
clip-path: none;
|
||||||
|
filter: brightness(0) contrast(0.5);
|
||||||
|
box-shadow: none;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:active {
|
||||||
|
filter: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
transition: var(--transition-longer);
|
||||||
|
|
||||||
|
&:not(
|
||||||
|
.no-hover,
|
||||||
|
.full-bleed,
|
||||||
|
[src*="#no-hover"],
|
||||||
|
[src*="#full-bleed"],
|
||||||
|
.emoji
|
||||||
|
) {
|
||||||
|
cursor: zoom-in;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
position: relative;
|
||||||
|
transform: var(--hover);
|
||||||
|
z-index: 1;
|
||||||
|
box-shadow: var(--edge-highlight), var(--shadow-raised);
|
||||||
|
border-radius: var(--rounded-corner-small);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.start,
|
||||||
|
&.end,
|
||||||
|
&[src*="#start"],
|
||||||
|
&[src*="#end"] {
|
||||||
|
&:hover {
|
||||||
|
transform: scale(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 720px) {
|
||||||
|
transform-origin: center;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: var(--hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.transparent,
|
||||||
|
&[src*="#transparent"] {
|
||||||
|
&:hover {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a img:not(.no-hover, .full-bleed, [src*="#no-hover"], [src*="#full-bleed"]) {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
video:fullscreen {
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
video:-webkit-full-screen {
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
478
sass/_nav.scss
Normal file
|
@ -0,0 +1,478 @@
|
||||||
|
#handle {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 999;
|
||||||
|
transition: var(--transition);
|
||||||
|
margin: 0 auto;
|
||||||
|
inset-block-start: 0;
|
||||||
|
inset-inline-end: 0;
|
||||||
|
inset-inline-start: 0;
|
||||||
|
width: min(var(--container-width), 90%);
|
||||||
|
height: 4.25rem;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
transition: var(--transition);
|
||||||
|
margin: 0 auto;
|
||||||
|
inset-block-start: 0.5rem;
|
||||||
|
inset-inline-end: 0;
|
||||||
|
inset-inline-start: 0;
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: 999px;
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
width: min(calc(var(--container-width) / 4), 100%);
|
||||||
|
height: 0.5rem;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover::before,
|
||||||
|
&:has(+ #site-nav:hover)::before,
|
||||||
|
&:has(+ #site-nav *:focus-visible, + #site-nav *:focus)::before {
|
||||||
|
transform: translateY(-1rem) scale(0.5);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover + #site-nav,
|
||||||
|
& + #site-nav:hover,
|
||||||
|
& + #site-nav:has(*:focus-visible, *:focus) {
|
||||||
|
transform: none;
|
||||||
|
opacity: 1;
|
||||||
|
pointer-events: auto;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
-webkit-backdrop-filter: var(--blur);
|
||||||
|
backdrop-filter: var(--blur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& + #site-nav {
|
||||||
|
position: fixed;
|
||||||
|
transform: translateY(-1rem) scale(0.5);
|
||||||
|
transform-origin: top;
|
||||||
|
opacity: 0;
|
||||||
|
transition: var(--transition);
|
||||||
|
margin: 0 auto;
|
||||||
|
width: max-content;
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
-webkit-backdrop-filter: saturate(1) blur(0);
|
||||||
|
backdrop-filter: saturate(1) blur(0);
|
||||||
|
transition: var(--transition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#site-nav {
|
||||||
|
position: sticky;
|
||||||
|
grid-area: nav;
|
||||||
|
z-index: 999;
|
||||||
|
margin: 1rem auto 0;
|
||||||
|
inset-block-start: 1rem;
|
||||||
|
inset-inline-end: 0;
|
||||||
|
inset-inline-start: 0;
|
||||||
|
border-radius: 1.625rem;
|
||||||
|
max-width: min(var(--container-width), 90%);
|
||||||
|
|
||||||
|
@media only screen and (max-width: 480px) {
|
||||||
|
position: relative;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
-webkit-backdrop-filter: var(--blur);
|
||||||
|
position: absolute;
|
||||||
|
z-index: -1;
|
||||||
|
backdrop-filter: var(--blur);
|
||||||
|
inset: 0;
|
||||||
|
box-shadow: var(--edge-highlight), var(--shadow-glass);
|
||||||
|
border-radius: 1.625rem;
|
||||||
|
background-color: var(--glass-bg);
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
nav {
|
||||||
|
padding: 0.5rem;
|
||||||
|
|
||||||
|
& > a {
|
||||||
|
-webkit-backdrop-filter: var(--blur);
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
opacity: 0;
|
||||||
|
z-index: 999;
|
||||||
|
backdrop-filter: var(--blur);
|
||||||
|
transition: var(--transition);
|
||||||
|
inset-block-start: 0;
|
||||||
|
box-shadow: var(--edge-highlight), var(--shadow-glass);
|
||||||
|
border-radius: 999px;
|
||||||
|
background-color: var(--glass-bg);
|
||||||
|
padding: 0.625rem 0.75rem;
|
||||||
|
pointer-events: none;
|
||||||
|
line-height: 1;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
opacity: 1;
|
||||||
|
inset-block-start: calc(100% + 0.5rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.25rem;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: flex;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
@media only screen and (max-width: 480px) {
|
||||||
|
&:not(:has(.circle)) {
|
||||||
|
flex: 0 0 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a,
|
||||||
|
summary {
|
||||||
|
flex: 1;
|
||||||
|
transition: var(--transition);
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 999px;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 0.625rem 0.75rem;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 1;
|
||||||
|
list-style: none;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.active {
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
background-color: var(--accent-color-alpha);
|
||||||
|
color: var(--accent-color);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
color: var(--contrast-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#home a {
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
font-weight: 800;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--fg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: var(--accent-color);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--contrast-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
-webkit-mask-image: var(--icon-home);
|
||||||
|
vertical-align: -0.125em;
|
||||||
|
mask-image: var(--icon-home);
|
||||||
|
transition: var(--transition);
|
||||||
|
margin-inline-end: 0.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider {
|
||||||
|
align-self: stretch;
|
||||||
|
margin: 0 0.25rem;
|
||||||
|
background-color: var(--fg-muted-2);
|
||||||
|
width: max(1px, 0.0625em);
|
||||||
|
|
||||||
|
@media only screen and (max-width: 480px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a,
|
||||||
|
#search button,
|
||||||
|
#language-switcher summary,
|
||||||
|
#theme-switcher summary,
|
||||||
|
#theme-switcher button,
|
||||||
|
summary {
|
||||||
|
color: var(--fg-muted-4);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: var(--active);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle {
|
||||||
|
padding: 0.625rem 0.625rem;
|
||||||
|
line-height: 0;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
vertical-align: -0.125em;
|
||||||
|
transition: var(--transition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
appearance: none;
|
||||||
|
transition: var(--transition);
|
||||||
|
cursor: pointer;
|
||||||
|
border: none;
|
||||||
|
border-radius: 999px;
|
||||||
|
background-color: transparent;
|
||||||
|
font-size: var(--font-size-medium);
|
||||||
|
}
|
||||||
|
|
||||||
|
details {
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
flex: 1;
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
&[open] ul {
|
||||||
|
animation: dropdown-open var(--transition);
|
||||||
|
|
||||||
|
@keyframes dropdown-open {
|
||||||
|
from {
|
||||||
|
transform: scale(0.5) translate(-50%, -1rem);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
-webkit-backdrop-filter: var(--blur);
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
flex-direction: column;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
transform-origin: top left;
|
||||||
|
z-index: 1;
|
||||||
|
backdrop-filter: var(--blur);
|
||||||
|
inset-block-start: 3.25rem;
|
||||||
|
box-shadow: var(--edge-highlight), var(--shadow-glass);
|
||||||
|
border-radius: calc(var(--rounded-corner) + 0.25rem);
|
||||||
|
background-color: var(--glass-bg);
|
||||||
|
padding: 0.25rem;
|
||||||
|
|
||||||
|
li {
|
||||||
|
width: 100%;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
a {
|
||||||
|
border-radius: var(--rounded-corner);
|
||||||
|
text-align: start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 480px) {
|
||||||
|
&:has(summary:not(.circle)) ul {
|
||||||
|
inset-block-start: 2.75rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#search .icon {
|
||||||
|
-webkit-mask-image: var(--icon-search);
|
||||||
|
mask-image: var(--icon-search);
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#feed .icon {
|
||||||
|
-webkit-mask-image: var(--icon-feed);
|
||||||
|
mask-image: var(--icon-feed);
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#repo .icon {
|
||||||
|
-webkit-mask-image: var(--icon-git);
|
||||||
|
mask-image: var(--icon-git);
|
||||||
|
}
|
||||||
|
|
||||||
|
#language-switcher .icon {
|
||||||
|
-webkit-mask-image: var(--icon-languages);
|
||||||
|
mask-image: var(--icon-languages);
|
||||||
|
}
|
||||||
|
|
||||||
|
#theme-switcher {
|
||||||
|
ul {
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
border-radius: 999px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
background-color: var(--accent-color-alpha);
|
||||||
|
color: var(--accent-color);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
color: var(--contrast-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#theme-system .icon,
|
||||||
|
.icon {
|
||||||
|
-webkit-mask-image: var(--icon-theme-system);
|
||||||
|
mask-image: var(--icon-theme-system);
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#theme-light .icon,
|
||||||
|
.icon.light {
|
||||||
|
-webkit-mask-image: var(--icon-theme-light);
|
||||||
|
mask-image: var(--icon-theme-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
#theme-dark .icon,
|
||||||
|
.icon.dark {
|
||||||
|
-webkit-mask-image: var(--icon-theme-dark);
|
||||||
|
mask-image: var(--icon-theme-dark);
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-container {
|
||||||
|
transform: scale(0.5) translateY(-2.75rem);
|
||||||
|
opacity: 0;
|
||||||
|
transition: var(--transition);
|
||||||
|
padding: 0 0.5rem 0;
|
||||||
|
height: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
transform: none;
|
||||||
|
opacity: 1;
|
||||||
|
padding: 0 0.5rem 0.5rem;
|
||||||
|
height: 2.75rem;
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-bar {
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border: none;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: var(--fg-muted-1);
|
||||||
|
padding: 0 0.75rem;
|
||||||
|
width: 100%;
|
||||||
|
height: 2.25rem;
|
||||||
|
color: inherit;
|
||||||
|
font-size: var(--font-size-medium);
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
opacity: 1;
|
||||||
|
color: var(--fg-muted-4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-results-container {
|
||||||
|
-webkit-backdrop-filter: var(--blur);
|
||||||
|
display: flex;
|
||||||
|
position: absolute;
|
||||||
|
backdrop-filter: var(--blur);
|
||||||
|
inset-block-start: calc(100% + 0.5rem);
|
||||||
|
inset-inline-start: 0;
|
||||||
|
box-shadow: var(--edge-highlight), var(--shadow-glass);
|
||||||
|
border-radius: calc(var(--rounded-corner) + 0.5rem);
|
||||||
|
background-color: var(--glass-bg);
|
||||||
|
width: 100%;
|
||||||
|
max-height: 50vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-results {
|
||||||
|
--mask: linear-gradient(to bottom,
|
||||||
|
transparent,
|
||||||
|
black 1rem,
|
||||||
|
black calc(100% - 1rem),
|
||||||
|
transparent);
|
||||||
|
-webkit-mask-image: var(--mask);
|
||||||
|
display: none;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
mask-image: var(--mask);
|
||||||
|
padding: 0.5rem;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: column;
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: var(--rounded-corner);
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
padding: 0.5rem;
|
||||||
|
|
||||||
|
a {
|
||||||
|
width: fit-content;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: " →";
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
content: " ←";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
|
||||||
|
&:first-of-type,
|
||||||
|
&.more-matches {
|
||||||
|
margin-block-start: 0.5rem;
|
||||||
|
border-block-start: max(1px, 0.0625rem) solid var(--fg-muted-2);
|
||||||
|
padding-block-start: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.more-matches {
|
||||||
|
font-size: var(--font-size-small);
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
color: var(--fg-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
276
sass/_normalize.scss
Normal file
|
@ -0,0 +1,276 @@
|
||||||
|
// Document
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
//
|
||||||
|
// 1. Correct the line height in all browsers.
|
||||||
|
// 2. Prevent adjustments of font size after orientation changes in iOS.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(html) {
|
||||||
|
-webkit-text-size-adjust: 100%; // 2
|
||||||
|
text-size-adjust: 100%; // 2
|
||||||
|
line-height: 1.15; // 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sections
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
//
|
||||||
|
// Correct the font size and margin on `h1` elements within `section` and
|
||||||
|
// `article` contexts in Chrome, Edge, Firefox, and Safari.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(h1) {
|
||||||
|
margin-block-start: 0.67em;
|
||||||
|
margin-block-end: 0.67em;
|
||||||
|
font-size: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grouping content
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove the margin on nested lists in Chrome, Edge, and Safari.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(dl, ol, ul) :where(dl, ol, ul) {
|
||||||
|
margin-block-start: 0;
|
||||||
|
margin-block-end: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 1. Add the correct box sizing in Firefox.
|
||||||
|
// 2. Correct the inheritance of border color in Firefox.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(hr) {
|
||||||
|
box-sizing: content-box; // 1
|
||||||
|
height: 0; // 1
|
||||||
|
color: inherit; // 2
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text-level semantics
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add the correct text decoration in Safari.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(abbr[title]) {
|
||||||
|
text-decoration: underline;
|
||||||
|
text-decoration: underline dotted;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add the correct font weight in Chrome, Edge, and Safari.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(b, strong) {
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 1. Correct the inheritance and scaling of font size in all browsers.
|
||||||
|
// 2. Correct the odd `em` font sizing in all browsers.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(code, kbd, pre, samp) {
|
||||||
|
font-size: 1em; // 2
|
||||||
|
font-family: monospace, monospace; // 1
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add the correct font size in all browsers.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(small) {
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tabular data
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
//
|
||||||
|
// 1. Correct table border color in Chrome, Edge, and Safari.
|
||||||
|
// 2. Remove text indentation from table contents in Chrome, Edge, and Safari.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(table) {
|
||||||
|
border-color: currentColor; // 1
|
||||||
|
text-indent: 0; // 2
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forms
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove the margin on controls in Safari.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(button, input, select) {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove the inheritance of text transform in Firefox.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(button) {
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Correct the inability to style buttons in iOS and Safari.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(
|
||||||
|
button,
|
||||||
|
input:is([type="button" i], [type="reset" i], [type="submit" i])
|
||||||
|
) {
|
||||||
|
-webkit-appearance: button;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add the correct vertical alignment in Chrome, Edge, and Firefox.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(progress) {
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove the inheritance of text transform in Firefox.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(select) {
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove the margin in Firefox and Safari.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(textarea) {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 1. Correct the odd appearance in Chrome, Edge, and Safari.
|
||||||
|
// 2. Correct the outline style in Safari.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(input[type="search" i]) {
|
||||||
|
-webkit-appearance: textfield; // 1
|
||||||
|
outline-offset: -2px; // 2
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Correct the cursor style of increment and decrement buttons in Safari.
|
||||||
|
//
|
||||||
|
|
||||||
|
::-webkit-inner-spin-button,
|
||||||
|
::-webkit-outer-spin-button {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Correct the text style of placeholders in Chrome, Edge, and Safari.
|
||||||
|
//
|
||||||
|
|
||||||
|
::-webkit-input-placeholder {
|
||||||
|
opacity: 0.54;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove the inner padding in Chrome, Edge, and Safari on macOS.
|
||||||
|
//
|
||||||
|
|
||||||
|
::-webkit-search-decoration {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 1. Correct the inability to style upload buttons in iOS and Safari.
|
||||||
|
// 2. Change font properties to `inherit` in Safari.
|
||||||
|
//
|
||||||
|
|
||||||
|
::-webkit-file-upload-button {
|
||||||
|
-webkit-appearance: button; // 1
|
||||||
|
font: inherit; // 2
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove the inner border and padding of focus outlines in Firefox.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(
|
||||||
|
button,
|
||||||
|
input:is(
|
||||||
|
[type="button" i],
|
||||||
|
[type="color" i],
|
||||||
|
[type="reset" i],
|
||||||
|
[type="submit" i]
|
||||||
|
)
|
||||||
|
)::-moz-focus-inner {
|
||||||
|
border-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Restore the focus outline styles unset by the previous rule in Firefox.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(
|
||||||
|
button,
|
||||||
|
input:is(
|
||||||
|
[type="button" i],
|
||||||
|
[type="color" i],
|
||||||
|
[type="reset" i],
|
||||||
|
[type="submit" i]
|
||||||
|
)
|
||||||
|
)::-moz-focusring {
|
||||||
|
outline: 1px dotted ButtonText;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove the additional :invalid styles in Firefox.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(:-moz-ui-invalid) {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interactive
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add the correct styles in Safari.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(dialog) {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
margin: auto;
|
||||||
|
border: solid;
|
||||||
|
background-color: white;
|
||||||
|
padding: 1em;
|
||||||
|
width: -moz-fit-content;
|
||||||
|
width: fit-content;
|
||||||
|
height: -moz-fit-content;
|
||||||
|
height: fit-content;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
:where(dialog:not([open])) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add the correct display in all browsers.
|
||||||
|
//
|
||||||
|
|
||||||
|
:where(summary) {
|
||||||
|
display: list-item;
|
||||||
|
}
|
3
sass/_not-found.scss
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#not-found {
|
||||||
|
width: min(calc(var(--container-width) / 5), 100%);
|
||||||
|
}
|
69
sass/_post-nav.scss
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
#post-nav {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 0.25rem;
|
||||||
|
|
||||||
|
@media only screen and (max-width: 720px) {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-nav-item {
|
||||||
|
flex: 1;
|
||||||
|
transition: var(--transition);
|
||||||
|
border-radius: var(--rounded-corner);
|
||||||
|
padding: 1rem;
|
||||||
|
padding-block-end: 0.75rem;
|
||||||
|
min-width: 0;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
background-color: var(--accent-color-alpha);
|
||||||
|
|
||||||
|
.post-title {
|
||||||
|
color: var(--accent-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: var(--active);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.post-nav-prev .nav-arrow::before {
|
||||||
|
content: "← ";
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
content: "→ ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.post-nav-next {
|
||||||
|
text-align: end;
|
||||||
|
|
||||||
|
.nav-arrow::after {
|
||||||
|
content: " →";
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
content: " ←";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-arrow {
|
||||||
|
margin-block-end: 0.75rem;
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-title {
|
||||||
|
display: block;
|
||||||
|
transition: var(--transition);
|
||||||
|
max-width: 90vw;
|
||||||
|
overflow: hidden;
|
||||||
|
color: var(--fg-color);
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
98
sass/_pre-container.scss
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
.pre-container {
|
||||||
|
margin: 1rem 0 1rem;
|
||||||
|
box-shadow: var(--edge-highlight), var(--shadow);
|
||||||
|
border-radius: var(--rounded-corner);
|
||||||
|
|
||||||
|
.header {
|
||||||
|
--shimmer: rgb(
|
||||||
|
from var(--accent-color) r g b / calc(var(--color-opacity) * 2)
|
||||||
|
);
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: var(--rounded-corner) var(--rounded-corner) 0 0;
|
||||||
|
background-image: linear-gradient(
|
||||||
|
to right,
|
||||||
|
var(--fg-muted-1) 50%,
|
||||||
|
var(--shimmer) 75%,
|
||||||
|
var(--fg-muted-1) 100%
|
||||||
|
);
|
||||||
|
background-size: 200%;
|
||||||
|
padding: 0.25rem;
|
||||||
|
height: 2.5rem;
|
||||||
|
|
||||||
|
span {
|
||||||
|
margin-inline-start: 0.75rem;
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
appearance: none;
|
||||||
|
transition: var(--transition);
|
||||||
|
cursor: pointer;
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--rounded-corner-small);
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 0.5rem;
|
||||||
|
color: var(--fg-muted-4);
|
||||||
|
line-height: 0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: var(--active);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
-webkit-mask-image: var(--icon-copy);
|
||||||
|
mask-image: var(--icon-copy);
|
||||||
|
transition: var(--transition);
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
animation: active-shimmer var(--transition-long);
|
||||||
|
|
||||||
|
button {
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
background-color: var(--accent-color-alpha);
|
||||||
|
color: var(--accent-color);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
-webkit-mask-image: var(--icon-done);
|
||||||
|
mask-image: var(--icon-done);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes active-shimmer {
|
||||||
|
to {
|
||||||
|
background-position-x: -200%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
margin: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 0 0 var(--rounded-corner) var(--rounded-corner);
|
||||||
|
}
|
||||||
|
}
|
26
sass/_sparkline.scss
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
.sparkline {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: flex-end;
|
||||||
|
float: inline-end;
|
||||||
|
gap: 0.25rem;
|
||||||
|
margin: 1rem 0;
|
||||||
|
width: 6rem;
|
||||||
|
height: 2rem;
|
||||||
|
|
||||||
|
div {
|
||||||
|
flex: 1;
|
||||||
|
transform-origin: bottom;
|
||||||
|
transition: var(--transition);
|
||||||
|
background-image: linear-gradient(
|
||||||
|
to top,
|
||||||
|
var(--accent-color) var(--bar-height),
|
||||||
|
transparent var(--bar-height)
|
||||||
|
);
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
height: 200%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
sass/_spoiler.scss
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
span.spoiler {
|
||||||
|
filter: blur(0.25rem);
|
||||||
|
transition: var(--transition);
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:active {
|
||||||
|
filter: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.solid {
|
||||||
|
filter: none;
|
||||||
|
border-radius: var(--rounded-corner-small);
|
||||||
|
background-color: var(--fg-muted-4);
|
||||||
|
color: transparent;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:active {
|
||||||
|
background-color: transparent;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
60
sass/_statements.scss
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
.statement-container {
|
||||||
|
margin: 1rem 0;
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: var(--rounded-corner);
|
||||||
|
padding: 1rem;
|
||||||
|
|
||||||
|
:last-child {
|
||||||
|
margin-block-end: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > :nth-child(2) {
|
||||||
|
margin-block-start: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
li::marker {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: inherit;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
margin-inline-end: 0.375rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.archive {
|
||||||
|
background-color: var(--purple-bg);
|
||||||
|
color: var(--purple-fg);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
-webkit-mask-image: var(--icon-archive);
|
||||||
|
mask-image: var(--icon-archive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disclaimer {
|
||||||
|
background-color: var(--red-bg);
|
||||||
|
color: var(--red-fg);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
-webkit-mask-image: var(--icon-warning);
|
||||||
|
mask-image: var(--icon-warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.trigger {
|
||||||
|
background-color: var(--yellow-bg);
|
||||||
|
color: var(--yellow-fg);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
-webkit-mask-image: var(--icon-warning);
|
||||||
|
mask-image: var(--icon-warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
sass/_table.scss
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
table {
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: var(--rounded-corner);
|
||||||
|
border-collapse: collapse;
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
tr {
|
||||||
|
&:nth-child(even) {
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background-color: var(--fg-muted-2);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
69
sass/_tags.scss
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
.tags {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.25rem;
|
||||||
|
margin: 0;
|
||||||
|
margin-block-start: 2rem;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: flex;
|
||||||
|
transition: var(--transition);
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: var(--active);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
transition: var(--transition);
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: 999px;
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
padding: 0.375rem 0.75rem;
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
font-size: var(--font-size-small);
|
||||||
|
line-height: 1;
|
||||||
|
text-decoration: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--accent-color-alpha);
|
||||||
|
color: var(--accent-color);
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
.count {
|
||||||
|
background-color: var(--accent-color-alpha);
|
||||||
|
color: var(--accent-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:has(.tag) {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag {
|
||||||
|
display: inline-block;
|
||||||
|
padding-inline-start: 0.75rem;
|
||||||
|
padding-inline-end: 0.5rem;
|
||||||
|
padding-block-start: 0.375rem;
|
||||||
|
padding-block-end: 0.375rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.count {
|
||||||
|
display: inline-block;
|
||||||
|
transition: var(--transition);
|
||||||
|
border-start-end-radius: 999px;
|
||||||
|
border-end-end-radius: 999px;
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
padding-inline-start: 0.5rem;
|
||||||
|
padding-inline-end: 0.625rem;
|
||||||
|
padding-block-start: 0.375rem;
|
||||||
|
padding-block-end: 0.375rem;
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
5
sass/_title.scss
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
strong.title {
|
||||||
|
color: var(--accent-color);
|
||||||
|
font-size: var(--font-size-x-large);
|
||||||
|
line-height: 1;
|
||||||
|
}
|
312
sass/_typography.scss
Normal file
|
@ -0,0 +1,312 @@
|
||||||
|
// HEADINGS
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
text-wrap: balance;
|
||||||
|
margin: 2rem 0 1rem;
|
||||||
|
font-weight: lighter;
|
||||||
|
line-height: normal;
|
||||||
|
font-family: var(--font-antique);
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: var(--font-size-xxx-large);
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: var(--font-size-xx-large);
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: var(--font-size-x-large);
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: var(--font-size-large);
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-size: var(--font-size-medium);
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
font-size: var(--font-size-small);
|
||||||
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
font-size: var(--font-size-small-em);
|
||||||
|
}
|
||||||
|
|
||||||
|
abbr[title] {
|
||||||
|
cursor: help;
|
||||||
|
text-decoration: underline;
|
||||||
|
text-decoration-style: dotted;
|
||||||
|
text-decoration-thickness: max(1px, 0.0625em);
|
||||||
|
}
|
||||||
|
|
||||||
|
figcaption {
|
||||||
|
color: var(--fg-muted-4);
|
||||||
|
font-size: var(--font-size-small-em);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
border-inline-start: 0.25rem solid var(--accent-color);
|
||||||
|
padding-inline-start: 0.75rem;
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
}
|
||||||
|
|
||||||
|
mark,
|
||||||
|
del,
|
||||||
|
ins,
|
||||||
|
samp,
|
||||||
|
q {
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: var(--rounded-corner-small);
|
||||||
|
padding: 0.125rem 0.375rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
mark {
|
||||||
|
background-color: var(--accent-color-alpha);
|
||||||
|
color: var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
del {
|
||||||
|
background-color: var(--red-bg);
|
||||||
|
color: var(--red-fg);
|
||||||
|
text-decoration: line-through;
|
||||||
|
text-decoration-thickness: max(1px, 0.0625em);
|
||||||
|
}
|
||||||
|
|
||||||
|
ins {
|
||||||
|
background-color: var(--green-bg);
|
||||||
|
color: var(--green-fg);
|
||||||
|
text-decoration: underline;
|
||||||
|
text-decoration-thickness: max(1px, 0.0625em);
|
||||||
|
}
|
||||||
|
|
||||||
|
samp {
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
font-size: var(--font-size-small-em);
|
||||||
|
}
|
||||||
|
|
||||||
|
q {
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
u {
|
||||||
|
text-decoration: underline;
|
||||||
|
text-decoration-style: wavy;
|
||||||
|
text-decoration-color: var(--red-fg);
|
||||||
|
text-decoration-thickness: max(1px, 0.0625em);
|
||||||
|
}
|
||||||
|
|
||||||
|
progress {
|
||||||
|
appearance: none;
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border: none;
|
||||||
|
border-radius: 999px;
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
width: 100%;
|
||||||
|
height: 0.5rem;
|
||||||
|
color: var(--accent-color);
|
||||||
|
|
||||||
|
&:indeterminate {
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:indeterminate::-moz-progress-bar {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-progress-bar {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-moz-progress-bar {
|
||||||
|
border-radius: 999px;
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-progress-value {
|
||||||
|
border-radius: 999px;
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kbd {
|
||||||
|
display: inline-block;
|
||||||
|
transition: var(--transition);
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow:
|
||||||
|
var(--edge-highlight),
|
||||||
|
inset 0 -0.125rem 0 var(--fg-muted-2);
|
||||||
|
border-radius: var(--rounded-corner-small);
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
padding: 0.125rem 0.375rem;
|
||||||
|
font-size: var(--font-size-small-em);
|
||||||
|
|
||||||
|
// Small nice thingy, keys can be pressed!
|
||||||
|
&:active {
|
||||||
|
transform: translateY(0.125rem);
|
||||||
|
box-shadow: inset 0 0.0625rem 0 var(--fg-muted-2);
|
||||||
|
background-color: var(--fg-muted-2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--accent-color);
|
||||||
|
font-weight: bold;
|
||||||
|
text-decoration-thickness: max(1px, 0.0625em);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration-style: wavy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
margin: 2rem auto;
|
||||||
|
border: none;
|
||||||
|
border-block-start: 0.1875rem double var(--fg-muted-2);
|
||||||
|
overflow: visible;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
position: relative;
|
||||||
|
inset-block-start: -1.25rem;
|
||||||
|
content: "❦";
|
||||||
|
color: var(--fg-muted-4);
|
||||||
|
font-size: var(--font-size-x-large);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dt {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
margin-inline-start: 1.5rem;
|
||||||
|
margin-block-end: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside {
|
||||||
|
float: right;
|
||||||
|
margin-inline-start: 1rem;
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: var(--rounded-corner);
|
||||||
|
background-color: var(--accent-color-alpha);
|
||||||
|
padding: 1rem;
|
||||||
|
width: 30%;
|
||||||
|
|
||||||
|
:root[dir*="rtl"] & {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 720px) {
|
||||||
|
float: none;
|
||||||
|
margin-inline-start: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
:first-child {
|
||||||
|
margin-block-start: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:last-child {
|
||||||
|
margin-block-end: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
details {
|
||||||
|
summary {
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: var(--rounded-corner);
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
padding: 1rem;
|
||||||
|
color: var(--fg-muted-5);
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 1;
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
&::marker,
|
||||||
|
&::-webkit-details-marker {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
-webkit-mask-image: var(--icon-down);
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: -0.125em;
|
||||||
|
mask-image: var(--icon-down);
|
||||||
|
transition: var(--transition);
|
||||||
|
margin-inline-end: 0.25rem;
|
||||||
|
background-color: currentColor;
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:last-child {
|
||||||
|
margin-block-end: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[open] {
|
||||||
|
box-shadow: var(--edge-highlight);
|
||||||
|
border-radius: var(--rounded-corner);
|
||||||
|
background-color: var(--fg-muted-1);
|
||||||
|
padding: 1rem;
|
||||||
|
|
||||||
|
summary {
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
transform: scaleY(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
& ~ * {
|
||||||
|
animation: details-open var(--transition);
|
||||||
|
|
||||||
|
@keyframes details-open {
|
||||||
|
from {
|
||||||
|
transform: translateY(-1rem);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
margin-inline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol,
|
||||||
|
ul {
|
||||||
|
padding-inline-start: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin: 0.125rem 0;
|
||||||
|
padding-inline-start: 0.25rem;
|
||||||
|
|
||||||
|
&::marker {
|
||||||
|
color: var(--accent-color);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
204
sass/_variables.scss
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
@mixin theme-variables {
|
||||||
|
:root {
|
||||||
|
@content ("light");
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] {
|
||||||
|
@content ("dark");
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root:not([data-theme="light"]) {
|
||||||
|
@content ("dark");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include theme-variables using ($theme) {
|
||||||
|
@if $theme == "dark" {
|
||||||
|
// COLORS
|
||||||
|
--bg-color: color-mix(in srgb, var(--accent-color) 10%, black);
|
||||||
|
--bg-overlay: linear-gradient(rgb(0 0 0 / 0.9), rgb(0 0 0 / 0.9));
|
||||||
|
--fg-color: rgb(255 255 255);
|
||||||
|
--fg-contrast: rgb(0 0 0 / 0.8);
|
||||||
|
--fg-muted-1: rgb(255 255 255 / 0.05);
|
||||||
|
--fg-muted-2: rgb(255 255 255 / 0.1);
|
||||||
|
--fg-muted-3: rgb(255 255 255 / 0.2);
|
||||||
|
--fg-muted-4: rgb(255 255 255 / 0.5);
|
||||||
|
--fg-muted-5: rgb(255 255 255 / 0.6);
|
||||||
|
--glass-bg: rgb(25 25 25 / 0.7);
|
||||||
|
--blue-fg: rgb(153 193 241);
|
||||||
|
--brown-fg: rgb(205 171 143);
|
||||||
|
--green-fg: rgb(143 240 164);
|
||||||
|
--purple-fg: rgb(220 138 221);
|
||||||
|
--red-fg: rgb(246 97 81);
|
||||||
|
--yellow-fg: rgb(248 228 92);
|
||||||
|
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
@else {
|
||||||
|
// COLORS
|
||||||
|
--bg-color: color-mix(in srgb, var(--accent-color) 20%, white);
|
||||||
|
--bg-overlay: linear-gradient(rgb(255 255 255 / 0.8), rgb(255 255 255 / 0.8));
|
||||||
|
--fg-color: rgb(0 0 0 / 0.8);
|
||||||
|
--fg-contrast: rgb(255 255 255);
|
||||||
|
--fg-muted-1: rgb(0 0 0 / 0.05);
|
||||||
|
--fg-muted-2: rgb(0 0 0 / 0.1);
|
||||||
|
--fg-muted-3: rgb(0 0 0 / 0.2);
|
||||||
|
--fg-muted-4: rgb(0 0 0 / 0.5);
|
||||||
|
--fg-muted-5: rgb(0 0 0 / 0.6);
|
||||||
|
--glass-bg: rgb(242 242 242 / 0.7);
|
||||||
|
--accent-color-alpha: rgb(from var(--accent-color) r g b / var(--color-opacity));
|
||||||
|
--blue-bg: rgb(from var(--blue-fg) r g b / var(--color-opacity));
|
||||||
|
--blue-fg: rgb(53 132 228);
|
||||||
|
--brown-bg: rgb(from var(--brown-fg) r g b / var(--color-opacity));
|
||||||
|
--brown-fg: rgb(99 69 44);
|
||||||
|
--green-bg: rgb(from var(--green-fg) r g b / var(--color-opacity));
|
||||||
|
--green-fg: rgb(38 162 105);
|
||||||
|
--purple-bg: rgb(from var(--purple-fg) r g b / var(--color-opacity));
|
||||||
|
--purple-fg: rgb(145 65 172);
|
||||||
|
--red-bg: rgb(from var(--red-fg) r g b / var(--color-opacity));
|
||||||
|
--red-fg: rgb(224 27 36);
|
||||||
|
--yellow-bg: rgb(from var(--yellow-fg) r g b / var(--color-opacity));
|
||||||
|
--yellow-fg: rgb(156 110 3);
|
||||||
|
|
||||||
|
// CONTRAST COLOR
|
||||||
|
--l: clamp(0, (l / 0.623 - 1) * -infinity, 1);
|
||||||
|
--a: calc(var(--l) + (var(--dim-opacity) * (1 - var(--l))));
|
||||||
|
--contrast-color: oklch(from var(--accent-color) var(--l) 0 h / var(--a));
|
||||||
|
|
||||||
|
// CONTAINERS
|
||||||
|
--container-width: 1024px;
|
||||||
|
|
||||||
|
// CORNERS
|
||||||
|
--rounded-corner: 0.75rem;
|
||||||
|
--rounded-corner-small: 0.5rem;
|
||||||
|
|
||||||
|
// FILTERS
|
||||||
|
--blur: saturate(1.8) blur(0.75rem);
|
||||||
|
|
||||||
|
// FONT SIZES
|
||||||
|
--font-size-xx-small: 0.625rem;
|
||||||
|
--font-size-x-small: 0.75rem;
|
||||||
|
--font-size-small: 0.875rem;
|
||||||
|
--font-size-medium: 1rem;
|
||||||
|
--font-size-large: 1.25rem;
|
||||||
|
--font-size-x-large: 1.5rem;
|
||||||
|
--font-size-xx-large: 2rem;
|
||||||
|
--font-size-xxx-large: 3rem;
|
||||||
|
|
||||||
|
// FONT SIZES (RELATIVE)
|
||||||
|
--font-size-xx-small-em: 0.625em;
|
||||||
|
--font-size-x-small-em: 0.75em;
|
||||||
|
--font-size-small-em: 0.875em;
|
||||||
|
--font-size-medium-em: 1em;
|
||||||
|
--font-size-large-em: 1.25em;
|
||||||
|
--font-size-x-large-em: 1.5em;
|
||||||
|
--font-size-xx-large-em: 2em;
|
||||||
|
--font-size-xxx-large-em: 3em;
|
||||||
|
|
||||||
|
// FONTS
|
||||||
|
--font-system-ui: system-ui, sans-serif;
|
||||||
|
--font-transitional: Charter, "Bitstream Charter", "Sitka Text", Cambria,
|
||||||
|
serif;
|
||||||
|
--font-old-style: "Iowan Old Style", "Palatino Linotype",
|
||||||
|
"URW Palladio L", P052, serif;
|
||||||
|
--font-humanist: Seravek, "Gill Sans Nova", Ubuntu, Calibri,
|
||||||
|
"DejaVu Sans", source-sans-pro, sans-serif;
|
||||||
|
--font-geometric-humanist: Avenir, Montserrat, Corbel, "URW Gothic",
|
||||||
|
source-sans-pro, sans-serif;
|
||||||
|
--font-classical-humanist: Optima, Candara, "Noto Sans", source-sans-pro,
|
||||||
|
sans-serif;
|
||||||
|
--font-neo-grotesque: Inter, Roboto, "Helvetica Neue", "Arial Nova",
|
||||||
|
"Nimbus Sans", Arial, sans-serif;
|
||||||
|
--font-monospace-slab-serif: "Nimbus Mono PS", "Courier New", monospace;
|
||||||
|
--font-monospace-code: ui-monospace, "Cascadia Code", "Source Code Pro",
|
||||||
|
Menlo, Consolas, "DejaVu Sans Mono", monospace;
|
||||||
|
--font-industrial: Bahnschrift, "DIN Alternate",
|
||||||
|
"Franklin Gothic Medium", "Nimbus Sans Narrow", sans-serif-condensed,
|
||||||
|
sans-serif;
|
||||||
|
--font-rounded-sans: ui-rounded, "Hiragino Maru Gothic ProN", Quicksand,
|
||||||
|
Comfortaa, Manjari, "Arial Rounded MT", "Arial Rounded MT Bold",
|
||||||
|
Calibri, source-sans-pro, sans-serif;
|
||||||
|
--font-slab-serif: Rockwell, "Rockwell Nova", "Roboto Slab",
|
||||||
|
"DejaVu Serif", "Sitka Small", serif;
|
||||||
|
--font-antique: Superclarendon, "Bookman Old Style", "URW Bookman",
|
||||||
|
"URW Bookman L", "Georgia Pro", Georgia, serif;
|
||||||
|
--font-didone: Didot, "Bodoni MT", "Noto Serif Display",
|
||||||
|
"URW Palladio L", P052, Sylfaen, serif;
|
||||||
|
--font-handwritten: "Segoe Print", "Bradley Hand", Chilanka, TSCu_Comic,
|
||||||
|
casual, cursive;
|
||||||
|
--font-emoji: "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
|
||||||
|
"Noto Color Emoji";
|
||||||
|
|
||||||
|
// OPACITY
|
||||||
|
--color-opacity: 0.1;
|
||||||
|
--dim-opacity: 0.8;
|
||||||
|
--disabled-opacity: 0.6;
|
||||||
|
|
||||||
|
// SHADOWS
|
||||||
|
--edge-highlight: inset 0 0.0625rem 0 rgb(255 255 255 / 0.1);
|
||||||
|
--shadow: 0 0 0 0.0625rem rgb(0 0 0 / 0.03),
|
||||||
|
0 0.0625rem 0.1875rem 0.0625rem rgb(0 0 0 / 0.07),
|
||||||
|
0 0.125rem 0.375rem 0.125rem rgb(0 0 0 / 0.03);
|
||||||
|
--shadow-raised: 0 0 0 0.0625rem rgb(0 0 0 / 0.06),
|
||||||
|
0 0.125rem 0.375rem 0.125rem rgb(0 0 0 / 0.14),
|
||||||
|
0 0.25rem 0.75rem 0.25rem rgb(0 0 0 / 0.06);
|
||||||
|
--shadow-glass: 0 0.75rem 1.5rem -1rem rgb(0 0 0 / 0.5);
|
||||||
|
--shadow-glow: 0 0 0 0.0625rem var(--accent-color-alpha),
|
||||||
|
0 0.125rem 0.375rem 0.125rem var(--accent-color-alpha),
|
||||||
|
0 0.25rem 1.5rem 0.25rem var(--accent-color-alpha);
|
||||||
|
--text-shadow-glow: var(--accent-color-alpha) 0 0 0.25rem,
|
||||||
|
var(--accent-color) 0 0 0.75rem;
|
||||||
|
|
||||||
|
// STATES
|
||||||
|
--hover: scale(1.1);
|
||||||
|
--active: scale(0.9);
|
||||||
|
|
||||||
|
// TRANSITIONS
|
||||||
|
--transition: 0.2s;
|
||||||
|
--transition-longer: 0.4s;
|
||||||
|
--transition-long: 0.8s;
|
||||||
|
|
||||||
|
// ICONS (16px)
|
||||||
|
--icon-archive: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M2 1C.89 1 0 1.89 0 3v2c0 .751.41 1.402 1.018 1.744A2 2 0 0 0 1 7v7c0 1.11.89 2 2 2h10c1.11 0 2-.89 2-2V7a2 2 0 0 0-.018-.256A2 2 0 0 0 16 5V3c0-1.11-.89-2-2-2zm0 2h12v2H2zm1 4h10v7H3zm3 1v1h4V8z'/%3E%3C/svg%3E");
|
||||||
|
--icon-backlink: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M5 14a1 1 0 0 1-.707-.293l-4-4a1 1 0 0 1 0-1.414l4-4a1 1 0 1 1 1.414 1.414L3.414 8H12c1.117 0 2-.883 2-2s-.883-2-2-2c-.55 0-1-.45-1-1s.45-1 1-1c2.2 0 4 1.8 4 4s-1.8 4-4 4H3.414l2.293 2.293A1 1 0 0 1 5 14m0 0'/%3E%3C/svg%3E");
|
||||||
|
--icon-boosts: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M8 1v2H4C1.8 3 0 4.8 0 7v2a4 4 0 0 0 1.02 2.672 1 1 0 1 0 1.488-1.336A1.97 1.97 0 0 1 2 9V7c0-1.125.875-2 2-2h4v2h1v-.008a1 1 0 0 0 .707-.285l2-2a1 1 0 0 0 0-1.414l-2-2A1 1 0 0 0 9 1.008V1zm6.29 3a1 1 0 0 0-.72.258.993.993 0 0 0-.078 1.41c.317.355.508.816.508 1.34v2c0 1.125-.875 2-2 2H8V9H7v.008a1 1 0 0 0-.707.285l-2 2a1 1 0 0 0 0 1.414l2 2c.187.184.441.29.707.285V15h1v-1.992h4c2.2 0 4-1.805 4-4v-2a4 4 0 0 0-1.02-2.676A1 1 0 0 0 14.29 4m0 0'/%3E%3C/svg%3E");
|
||||||
|
--icon-bug: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M5 0c-.55 0-1 .45-1 1 0 .691.39 1.285.8 1.605C4.298 3.277 4 4.105 4 5H3V4H1v1c0 .832.563 1.523 1.05 1.77.493.246.95.23.95.23h1v1H1v2h3v1H3s-.457-.016-.95.23C1.563 11.477 1 12.168 1 13v3h2v-3h1.129c.45 1.719 2.016 3 3.871 3s3.422-1.281 3.871-3H13v3h2v-3c0-.832-.562-1.523-1.05-1.77-.493-.246-.95-.23-.95-.23h-1v-1h3V8h-3V7h1s.457.016.95-.23C14.437 6.523 15 5.832 15 5V4h-2v1h-1c0-.895-.297-1.723-.8-2.395.41-.32.8-.914.8-1.605 0-.55-.45-1-1-1s-1 .45-1 1a1 1 0 0 0-.645.238C8.93 1.086 8.473 1 8 1s-.93.086-1.355.238A1 1 0 0 0 6 1c0-.55-.45-1-1-1m2.969 5.031h.062A.97.97 0 0 1 9 6v3.063a.97.97 0 0 1-.969.968H7.97A.97.97 0 0 1 7 9.062V6a.97.97 0 0 1 .969-.969m0 6h.062A.97.97 0 0 1 9 12v.063a.97.97 0 0 1-.969.968H7.97a.97.97 0 0 1-.97-.969V12a.97.97 0 0 1 .969-.969m0 0'/%3E%3C/svg%3E");
|
||||||
|
--icon-caution: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M5 0a1 1 0 0 0-.707.293l-4 4A1 1 0 0 0 0 5v6a1 1 0 0 0 .293.707l4 4A1 1 0 0 0 5 16h6a1 1 0 0 0 .707-.293l4-4A1 1 0 0 0 16 11V5a1 1 0 0 0-.293-.707l-4-4A1 1 0 0 0 11 0zm.414 2h5.172L14 5.414v5.172L10.586 14H5.414L2 10.586V5.414zM8 4c-.554 0-1 .446-1 1v3c0 .554.446 1 1 1s1-.446 1-1V5c0-.554-.446-1-1-1m0 6a1 1 0 0 0-1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0-1-1'/%3E%3C/svg%3E");
|
||||||
|
--icon-checkmark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M13.754 4.668c.176-.2.262-.461.246-.723a1 1 0 0 0-.34-.687 1 1 0 0 0-.726-.246 1 1 0 0 0-.688.34L5.95 10.547 3.707 8.3A1 1 0 0 0 2 9.01a1 1 0 0 0 .293.708l3 3c.195.195.465.3.742.293.278-.012.535-.133.719-.344zm0 0'/%3E%3C/svg%3E");
|
||||||
|
--icon-copy: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' height='16' width='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 3c0-1.645 1.355-3 3-3h5c1.645 0 3 1.355 3 3 0 .55-.45 1-1 1s-1-.45-1-1c0-.57-.43-1-1-1H3c-.57 0-1 .43-1 1v5c0 .57.43 1 1 1 .55 0 1 .45 1 1s-.45 1-1 1c-1.645 0-3-1.355-3-3zm5 5c0-1.645 1.355-3 3-3h5c1.645 0 3 1.355 3 3v5c0 1.645-1.355 3-3 3H8c-1.645 0-3-1.355-3-3zm2 0v5c0 .57.43 1 1 1h5c.57 0 1-.43 1-1V8c0-.57-.43-1-1-1H8c-.57 0-1 .43-1 1m0 0'/%3E%3C/svg%3E");
|
||||||
|
--icon-done: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M7.883 0q-.486.008-.965.074a7.98 7.98 0 0 0-4.602 2.293 8.01 8.01 0 0 0-1.23 9.664 8.015 8.015 0 0 0 9.02 3.684 8 8 0 0 0 5.89-7.75 1 1 0 1 0-2 .008 5.986 5.986 0 0 1-4.418 5.816 5.996 5.996 0 0 1-6.762-2.766 5.99 5.99 0 0 1 .922-7.25 5.99 5.99 0 0 1 7.239-.984 1 1 0 0 0 1.363-.371c.273-.48.11-1.09-.371-1.367A8 8 0 0 0 9.492.14 8 8 0 0 0 7.882 0m7.15 1.998-.1.002a1 1 0 0 0-.687.34L7.95 9.535 5.707 7.29A1 1 0 0 0 4 8a1 1 0 0 0 .293.707l3 3c.195.195.465.3.742.293.277-.012.535-.133.719-.344l7-8A1 1 0 0 0 16 2.934a1 1 0 0 0-.34-.688 1 1 0 0 0-.627-.248'/%3E%3C/svg%3E");
|
||||||
|
--icon-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='m2.293 6.707 5 5a1 1 0 0 0 1.414 0l5-5a1 1 0 1 0-1.414-1.414L8 9.586 3.707 5.293a1 1 0 1 0-1.414 1.414m0 0'/%3E%3C/svg%3E");
|
||||||
|
--icon-feed: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M1.988 1.988V3c.008.547.453.984 1 .988.004-.004.008-.004.012-.004v.028A8.977 8.977 0 0 1 11.988 13a.991.991 0 0 0 1 .984h1V13h-.004c0-.004 0-.004.004-.008C13.984 7.02 9.184 2.148 3.242 2.02A1.004 1.004 0 0 0 3 1.988v-.004zm0 4V7c.008.547.453.984 1 .988.004-.004.008-.004.012-.004V8a4.985 4.985 0 0 1 4.996 4.844 1.002 1.002 0 0 0 .988 1.145c.008-.005.012-.005.016-.005v.004h.984V13H10c0-3.793-3.047-6.898-6.82-6.992 0-.004-.004-.004-.004-.004A.892.892 0 0 0 3 5.988v-.004zm2 4a1.999 1.999 0 1 0-.002 3.998 1.999 1.999 0 0 0 .002-3.998m0 0'%3E%3C/path%3E%3C/svg%3E");
|
||||||
|
--icon-fire: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M9.184.973C4.957 3.113 5.586 6.273 7 9 5.762 7.36 5.016 5.48 5 4 3.375 5 2 7 2 9a6.005 6.005 0 0 0 3.969 5.648c-.492-.84-.367-1.96.703-3.015 2.14-2.11 1.558-2.735 1.558-2.735 2.266 1.149-.32 3.137.418 3.88.563.558 1.758-1.391 1.77-2.184.848.96 1.246 1.676 1.246 2.75q0 .273-.035.52c2.512-1.805 3.273-5.41.46-8.184C8.095 1.742 9.185.973 9.185.973m0 0'/%3E%3C/svg%3E");
|
||||||
|
--icon-first: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M3 2v12h2V8.414l5.293 5.293a1 1 0 1 0 1.414-1.414L7.414 8l4.293-4.293a1 1 0 1 0-1.414-1.414L5 7.586V2zm0 0'/%3E%3C/svg%3E");
|
||||||
|
--icon-git: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M8 0a1 1 0 0 0-.707.293L5.707 1.875l5.238 5.234c.176-.07.364-.109.555-.109A1.5 1.5 0 1 1 10 8.5q0-.276.102-.535L8.05 5.915v4.19a1.5 1.5 0 1 1-1-.035V4.914L4.859 2.727.293 7.293a1 1 0 0 0 0 1.414l7 7a1 1 0 0 0 1.414 0l7-7a1.007 1.007 0 0 0 0-1.414l-7-7A1 1 0 0 0 8 0m0 0'/%3E%3C/svg%3E");
|
||||||
|
--icon-home: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M8 .361a2.2 2.2 0 0 0-1.41.51L2.129 4.59A3.14 3.14 0 0 0 1 7v6c0 1.66 1.34 3 3 3h8c1.66 0 3-1.34 3-3V7c0-.93-.414-1.813-1.129-2.41L9.411.87A2.2 2.2 0 0 0 8 .361m0 2.002a.2.2 0 0 1 .129.047l4.46 3.719c.263.215.411.535.411.871v6c0 .547-.453 1-1 1h-2V9c0-.55-.45-1-1-1H7c-.55 0-1 .45-1 1v5H4c-.547 0-1-.453-1-1V7c0-.336.148-.656.41-.871L7.871 2.41A.2.2 0 0 1 8 2.363'/%3E%3C/svg%3E");
|
||||||
|
--icon-important: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M3 0C1.355 0 0 1.355 0 3v7c0 1.256.893 2.14 2 2.584V15a1 1 0 0 0 1.707.707L6.414 13H13c1.645 0 3-1.355 3-3V3c0-1.645-1.355-3-3-3zm0 2h10c.571 0 1 .429 1 1v7c0 .571-.429 1-1 1H6a1 1 0 0 0-.707.293L4 12.586V12a1 1 0 0 0-1-1c-.571 0-1-.429-1-1V3c0-.571.429-1 1-1m5 1c-.554 0-1 .446-1 1v2c0 .554.446 1 1 1s1-.446 1-1V4c0-.554-.446-1-1-1m0 5a1 1 0 0 0-1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0-1-1'/%3E%3C/svg%3E");
|
||||||
|
--icon-info: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M8 0C3.59 0 0 3.59 0 8s3.59 8 8 8 8-3.59 8-8-3.59-8-8-8m0 2c3.332 0 6 2.668 6 6s-2.668 6-6 6-6-2.668-6-6 2.668-6 6-6m0 1.875a1.125 1.125 0 1 0 0 2.25 1.125 1.125 0 0 0 0-2.25M6.477 7A.5.5 0 0 0 6.5 8H7v3h-.5a.499.499 0 1 0 0 1h3a.499.499 0 1 0 0-1H9V7zm0 0'/%3E%3C/svg%3E");
|
||||||
|
--icon-languages: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M3.98 1v3H1v2h2.947a4.8 4.8 0 0 1-.592 1.871c-.425.758-1.101 1.488-2.062 2.45l1.414 1.413c.92-.92 1.703-1.728 2.283-2.697.38.632.844 1.196 1.377 1.768l.668-2.309a6 6 0 0 1-.41-.625A4.75 4.75 0 0 1 6.033 6h1.53l.511-2H6V1zm5.24 1L6 15h2l.781-3h4.438L14 15h2L12.781 2zm1.562 2h.438l1.5 6H9.28z'/%3E%3C/svg%3E");
|
||||||
|
--icon-last: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M11 2v5.586L5.707 2.293a1 1 0 1 0-1.414 1.414L8.586 8l-4.293 4.293a1 1 0 1 0 1.414 1.414L11 8.414V14h2V2zm0 0'/%3E%3C/svg%3E");
|
||||||
|
--icon-lightbulb: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M7.996 0C5.16 0 2.703 2 2.125 4.777c-.527 2.535.688 5.036 2.871 6.325L5 12a1 1 0 0 0 1 1h4a1 1 0 0 0 1-1v-.898c2.184-1.293 3.402-3.797 2.871-6.332A6.01 6.01 0 0 0 7.996 0m0 2a3.994 3.994 0 0 1 3.918 3.18 3.99 3.99 0 0 1-2.312 4.484 1.01 1.01 0 0 0-.602.914V11H6.996v-.418a1 1 0 0 0-.598-.914 3.994 3.994 0 0 1-2.316-4.484A3.99 3.99 0 0 1 7.996 2m-.998 4a.5.5 0 0 0-.354.852l1 1a.5.5 0 0 0 .708 0l1-1a.5.5 0 0 0 0-.707.507.507 0 0 0-.707 0l-.649.648-.644-.648A.5.5 0 0 0 6.998 6M6 14v1c0 .555.445 1 1 1h2c.555 0 1-.445 1-1v-1z'/%3E%3C/svg%3E");
|
||||||
|
--icon-link: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M4 4C1.8 4 0 5.8 0 8s1.8 4 4 4v-2c-1.125 0-2-.875-2-2s.875-2 2-2h3c1.125 0 2 .875 2 2 0 .84-.496 1.535-1.207 1.84l.785 1.84A4 4 0 0 0 11 8c0-2.2-1.8-4-4-4zm8 2v2c1.125 0 2 .875 2 2s-.875 2-2 2H9c-1.125 0-2-.875-2-2 0-.828.484-1.516 1.184-1.828l-.817-1.828A4.01 4.01 0 0 0 5 10c0 2.2 1.8 4 4 4h3c2.2 0 4-1.8 4-4s-1.8-4-4-4'/%3E%3C/svg%3E");
|
||||||
|
--icon-next: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='m6.707 13.707 5-5a1 1 0 0 0 0-1.414l-5-5a1 1 0 1 0-1.414 1.414L9.586 8l-4.293 4.293a1 1 0 1 0 1.414 1.414m0 0'/%3E%3C/svg%3E");
|
||||||
|
--icon-pencil: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M12.277.832c-.578.008-1.168.23-1.691.754l-9 9A2 2 0 0 0 1 12v3h3c.531 0 1.04-.21 1.414-.586l9-9c1.79-1.789.082-4.39-1.89-4.57-.083-.012-.165-.012-.247-.012M10.5 4.437 11.563 5.5 4.5 12.563 3.438 11.5zm0 0'/%3E%3C/svg%3E");
|
||||||
|
--icon-poop: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M8.963 1.514A4 4 0 0 1 5 5H4c-1.108 0-2 .892-2 2s.892 2 2 2H3c-1.662 0-3 1.338-3 3s1.338 3 3 3h10c1.662 0 3-1.338 3-3s-1.338-3-3-3h-1c1.108 0 2-.892 2-2s-.892-2-2-2h-1a4 4 0 0 0-2.037-3.486'/%3E%3C/svg%3E");
|
||||||
|
--icon-previous: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='m9.293 13.707-5-5a1 1 0 0 1 0-1.414l5-5a1 1 0 1 1 1.414 1.414L6.414 8l4.293 4.293a1 1 0 1 1-1.414 1.414m0 0'/%3E%3C/svg%3E");
|
||||||
|
--icon-right: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='m5.707 1.293 6 6a1 1 0 0 1 0 1.414l-6 6a1 1 0 1 1-1.414-1.414L9.586 8 4.293 2.707a1 1 0 1 1 1.414-1.414m0 0'/%3E%3C/svg%3E");
|
||||||
|
--icon-search: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M6.57.063c-3.578 0-6.5 2.921-6.5 6.5 0 3.578 2.922 6.5 6.5 6.5a6.46 6.46 0 0 0 3.83-1.256l2.975 2.974c.957.938 2.363-.5 1.406-1.437l-2.96-2.961a6.46 6.46 0 0 0 1.25-3.82c0-3.579-2.923-6.5-6.5-6.5m0 2c2.5 0 4.5 2.003 4.5 4.5 0 2.5-2 4.5-4.5 4.5-2.496 0-4.5-2-4.5-4.5 0-2.497 2.004-4.5 4.5-4.5'/%3E%3C/svg%3E");
|
||||||
|
--icon-share: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M8 1a1 1 0 0 0-.5.135 1 1 0 0 0-.207.158l-3 3a1 1 0 0 0 0 1.414 1 1 0 0 0 1.414 0L7 4.414V10a1 1 0 0 0 1 1 1 1 0 0 0 1-1V4.414l1.293 1.293a1 1 0 0 0 1.414 0 1 1 0 0 0 0-1.414L8.738 1.326 8.7 1.287a1 1 0 0 0-.195-.15l-.008-.004a1 1 0 0 0-.236-.098h-.004A1 1 0 0 0 8 1M4 7c-1.645 0-3 1.355-3 3v2c0 1.645 1.355 3 3 3h8c1.645 0 3-1.355 3-3v-2c0-1.645-1.355-3-3-3a1 1 0 0 0 0 2c.564 0 1 .436 1 1v2c0 .564-.436 1-1 1H4c-.564 0-1-.436-1-1v-2c0-.564.436-1 1-1a1 1 0 0 0 0-2'/%3E%3C/svg%3E");
|
||||||
|
--icon-star: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M8 0a1 1 0 0 0-.95.684l-1.448 4.34-4.59-.016C.032 5.004-.371 6.266.43 6.828l3.625 2.555-1.5 4.285c-.317.902.687 1.691 1.492 1.172l4.004-2.594 3.894 2.586c.801.531 1.817-.258 1.5-1.16l-1.504-4.29 3.645-2.577c.789-.563.394-1.809-.574-1.813l-4.66-.015L8.949.69A1 1 0 0 0 8 0m0 0'/%3E%3C/svg%3E");
|
||||||
|
--icon-theme-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M.918 8.004a7.072 7.072 0 0 0 14.102.793 1.01 1.01 0 0 0-.457-.957 1 1 0 0 0-1.063-.004 3.9 3.9 0 0 1-2.031.578 3.89 3.89 0 0 1-3.883-3.883c0-.715.203-1.422.578-2.031a1 1 0 0 0-.004-1.062c-.207-.32-.578-.5-.957-.458A7.07 7.07 0 0 0 .918 8.004M5.586 4.53a5.877 5.877 0 0 0 8.965 5.004l-1.52-.96a5.09 5.09 0 0 1-5.035 4.507 5.09 5.09 0 0 1-5.078-5.078 5.09 5.09 0 0 1 4.508-5.035l-.961-1.52a5.9 5.9 0 0 0-.88 3.082m0 0'/%3E%3C/svg%3E");
|
||||||
|
--icon-theme-light: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M8.004-.008a1 1 0 0 0-1 1v1a1 1 0 1 0 2 0v-1c0-.554-.445-1-1-1M3.053 2.035a1 1 0 0 0-.26.035.994.994 0 0 0-.45 1.672l.708.707a1 1 0 1 0 1.414-1.414l-.707-.707a1 1 0 0 0-.705-.293m9.9.012a1 1 0 0 0-.707.293l-.707.707a1 1 0 1 0 1.414 1.414l.707-.707a1 1 0 0 0-.707-1.707M8 4C5.785 4 4 5.785 4 8s1.785 4 4 4 4-1.785 4-4-1.785-4-4-4m0 2c1.098 0 2 .902 2 2s-.902 2-2 2-2-.902-2-2 .902-2 2-2m-7.004.984a1 1 0 1 0 0 2h1a1 1 0 1 0 0-2zM14 7c-.55 0-1 .45-1 1s.45 1 1 1h1c.55 0 1-.45 1-1s-.45-1-1-1zM3.748 11.234a1 1 0 0 0-.705.293l-.711.707a1.007 1.007 0 0 0 0 1.414c.39.391 1.027.391 1.418 0l.707-.707a1 1 0 0 0-.709-1.707m8.49.006q-.131 0-.261.033a1.01 1.01 0 0 0-.707.711 1 1 0 0 0 .261.965l.707.707a.995.995 0 0 0 1.672-.445 1 1 0 0 0-.258-.969l-.707-.707a1 1 0 0 0-.707-.295m-4.246 1.756c-.554 0-1 .445-1 1v1a1 1 0 1 0 2 0v-1a1 1 0 0 0-1-1'/%3E%3C/svg%3E");
|
||||||
|
--icon-theme-system: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M8 0C3.594 0 0 3.594 0 8s3.594 8 8 8 8-3.594 8-8-3.594-8-8-8m0 1.941c3.36 0 6.059 2.7 6.059 6.059s-2.7 6.059-6.059 6.059zm0 0'/%3E%3C/svg%3E");
|
||||||
|
--icon-toc: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M2 3a1 1 0 1 0 0 2 1 1 0 0 0 0-2m4 0c-.554 0-1 .446-1 1s.446 1 1 1h8c.554 0 1-.446 1-1s-.446-1-1-1ZM2 7a1 1 0 1 0 0 2 1 1 0 0 0 0-2m4 0c-.554 0-1 .446-1 1s.446 1 1 1h8c.554 0 1-.446 1-1s-.446-1-1-1Zm-4 4a1 1 0 1 0 0 2 1 1 0 0 0 0-2m4 0c-.554 0-1 .446-1 1s.446 1 1 1h8c.554 0 1-.446 1-1s-.446-1-1-1z'/%3E%3C/svg%3E");
|
||||||
|
--icon-top: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M1 11a1 1 0 0 1 .293-.707l6-6a1 1 0 0 1 1.414 0l6 6a1 1 0 1 1-1.414 1.414L8 6.414l-5.293 5.293A1 1 0 0 1 1 11m0 0'/%3E%3C/svg%3E");
|
||||||
|
--icon-verified: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M5.21 1.27A3.7 3.7 0 0 1 8 0c1.113 0 2.11.492 2.79 1.27a3.68 3.68 0 0 1 2.866 1.074A3.68 3.68 0 0 1 14.73 5.21C15.54 5.914 16 6.93 16 8s-.46 2.086-1.27 2.79a3.68 3.68 0 0 1-1.074 2.866 3.68 3.68 0 0 1-2.867 1.074C10.086 15.54 9.07 16 8 16s-2.086-.46-2.79-1.27a3.68 3.68 0 0 1-2.866-1.074A3.68 3.68 0 0 1 1.27 10.79 3.7 3.7 0 0 1 0 8c0-1.113.492-2.11 1.27-2.79a3.68 3.68 0 0 1 1.074-2.866A3.68 3.68 0 0 1 5.21 1.27m5.75 5.242a.613.613 0 0 0-.437-.98.61.61 0 0 0-.562.265L7.305 9.512 5.973 8.18a.616.616 0 0 0-.868.87l1.844 1.845a.61.61 0 0 0 .485.18.63.63 0 0 0 .453-.255zm0 0'/%3E%3C/svg%3E");
|
||||||
|
--icon-warning: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M8 .844c-.907 0-1.814.444-2.291 1.334l-.002.002-5.178 9.697C-.45 13.704.928 16.002 3 16h10c2.072.002 3.45-2.296 2.47-4.123L10.294 2.18l-.002-.002C9.814 1.288 8.907.844 8 .844M8 2.77c.201 0 .403.118.53.353l5.177 9.697.002.002c.307.573-.057 1.18-.707 1.178H2.998c-.65.001-1.014-.605-.707-1.178l.002-.002 5.18-9.699c.126-.233.327-.351.527-.351M8 5c-.554 0-1 .446-1 1v3c0 .554.446 1 1 1s1-.446 1-1V6c0-.554-.446-1-1-1m0 6a1 1 0 0 0-1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0-1-1'/%3E%3C/svg%3E");
|
||||||
|
|
||||||
|
// MINI ICONS (12px)
|
||||||
|
--icon-external: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' %3E%3Cpath d='m6 6 5-5M7 1h4v4M4 2H3a2 2 0 0 0-2 2v5a2 2 0 0 0 2 2h5a2 2 0 0 0 2-2V8' style='fill:none;stroke:black;stroke-linejoin:round;stroke-linecap:round;stroke-width:2'/%3E%3C/svg%3E");
|
||||||
|
}
|
||||||
|
}
|
9
sass/_visually-hidden.scss
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
.visually-hidden {
|
||||||
|
clip: rect(0 0 0 0);
|
||||||
|
position: absolute !important;
|
||||||
|
clip-path: inset(100%);
|
||||||
|
width: 1px !important;
|
||||||
|
height: 1px !important;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|