diff --git a/.gitignore b/.gitignore
index 9ce39b7..60e6ff8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,6 @@
.jekyll-metadata
Gemfile.lock
_site
+source/_pages/*
+!source/_pages/index.html
+source/.jekyll-image-optim-cache
diff --git a/Gemfile b/Gemfile
index 9eaef9b..30d05b9 100644
--- a/Gemfile
+++ b/Gemfile
@@ -2,7 +2,10 @@
source "https://rubygems.org"
+gem "jekyll-toc", "~> 0.17.1"
gem "jekyll", "~> 4.2"
gem "kramdown-math-katex", "~> 1.0"
gem "rouge", "~> 3.27"
gem "webrick", "~> 1.7"
+gem "image_optim", "~> 0.25"
+gem "image_optim_pack", "~> 0.5.1"
diff --git a/_config.yml b/_config.yml
index 14d1b62..e7c02f0 100644
--- a/_config.yml
+++ b/_config.yml
@@ -1,5 +1,39 @@
+timezone: Europe/Berlin
+
source: 'source'
+layouts_dir: _layouts
keep_files: ['cv.pdf']
+
+collections:
+ pages:
+ output: true
+ permalink: /:collection/:title/
+ order:
+ - Links.md
+
+defaults:
+ -
+ scope:
+ path: "_pages/*.md"
+ values:
+ layout: "page"
+ toc: true
+
+plugins:
+ - jekyll-toc
+
+toc:
+ max_level: 1
+
+jekyll_image_optim:
+ image_optim:
+ allow_lossy: true
+ advpng:
+ level: 2
+ pngout: false
+ svgo: false
+ oxipng: false
+
kramdown:
syntax_highlighter: rouge
syntax_highlighter_opts:
diff --git a/source/404.html b/source/404.html
new file mode 100644
index 0000000..f508179
--- /dev/null
+++ b/source/404.html
@@ -0,0 +1,17 @@
+---
+title: Page not found
+layout: null
+---
+
+
+
+
+ {% include header.html %}
+
+
+
+
+ This page was lost in the vampire castle...
+ Return
+
+
diff --git a/source/_includes/header.html b/source/_includes/header.html
new file mode 100644
index 0000000..f3a95de
--- /dev/null
+++ b/source/_includes/header.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/source/_layouts/page.html b/source/_layouts/page.html
new file mode 100644
index 0000000..a1feeb3
--- /dev/null
+++ b/source/_layouts/page.html
@@ -0,0 +1,63 @@
+
+
+
+ {% include header.html %}
+
+
+
+
+
+ {{ page.title }}
+
+
+
+
+
+ {% if page.title%}
+
{{page.title}}
+ {% endif %} {{ content | safe | inject_anchors }}
+
+
+
+
+ {% capture toc %} {% toc %} {% endcapture %}
+
+ {% if toc contains "toc-entry" %}
+
+ {% endif %}
+
+
Other Pages
+
+ {% for page in site.pages %} {% if page.hide != true %}
+ -
+ {{ page.title }}
+
+ {% endif %} {% endfor %}
+
+
+
+
+
diff --git a/source/_pages/index.html b/source/_pages/index.html
new file mode 100644
index 0000000..b0dd547
--- /dev/null
+++ b/source/_pages/index.html
@@ -0,0 +1,28 @@
+---
+title: Page List
+layout: null
+hide: true
+permalink: /:collection/index.html
+---
+
+
+
+
+ {% include header.html %}
+
+ Pages
+
+
+
+ Page List
+
+
+ {% for page in site.pages %} {% if page.hide != true %} {% if page.title
+ != "Page List"%}
+ -
+ {{ page.title }}
+
+ {% endif %} {% endif %} {% endfor %}
+
+
+
diff --git a/source/_plugins/jekyll-image-optim.rb b/source/_plugins/jekyll-image-optim.rb
new file mode 100644
index 0000000..1e83f3a
--- /dev/null
+++ b/source/_plugins/jekyll-image-optim.rb
@@ -0,0 +1,71 @@
+# Copyright 2018 Shane F. Carr
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+require "digest"
+require "fileutils"
+require "image_optim"
+require "yaml"
+
+Jekyll::Hooks.register :site, :pre_render do |site|
+ # Load configuration options
+ config = YAML::load_file("_config.yml")
+ config = config["jekyll_image_optim"] || {}
+ image_optim_options = config["image_optim"] || {}
+ cache_relative_dir = config["cache_dir"] || ".jekyll-image-optim-cache"
+ cache_dir = File.join(site.source, cache_relative_dir)
+ out_dir = File.join(cache_dir, "out")
+ index_yaml_path = File.join(cache_dir, "index.yml")
+ FileUtils.mkdir_p(cache_dir)
+ FileUtils.mkdir_p(out_dir)
+ FileUtils.touch(index_yaml_path)
+ cache_index = YAML::load_file(index_yaml_path) || {}
+
+ # Exclude the cache directory from the jekyll watch
+ site.exclude << cache_relative_dir
+
+ # Process the images
+ image_optim = ImageOptim.new(image_optim_options)
+ site.static_files.map! do |static_file|
+ if not image_optim.optimizable?(static_file.path)
+ # Not an image file; no change necessary
+ next static_file
+ end
+
+ relative_path = static_file.relative_path
+ new_path = File.join(out_dir, relative_path)
+ cc = cache_index[relative_path]
+ image_md5 = Digest::MD5.file(static_file.path).hexdigest
+
+ if not cc or not File.exists?(new_path) or cc[:md5] != image_md5 or cc[:options] != image_optim_options
+ # Need to compute the optimized image
+ puts "Optimizing image: #{relative_path}"
+ FileUtils.mkdir_p(File.dirname(new_path))
+ FileUtils.cp(static_file.path, new_path)
+ image_optim.optimize_image!(new_path)
+ cache_index[relative_path] = { md5: image_md5, options: image_optim_options }
+
+ # Save the cache index file (do this for every image to allow restart after an interrupt)
+ File.open(index_yaml_path, "w") { |f| f.write(cache_index.to_yaml) }
+ end
+
+ # Replace the Jekyll::StaticFile to point to the new location
+ next Jekyll::StaticFile.new(site, out_dir, File.dirname(relative_path), File.basename(relative_path))
+ end
+end
diff --git a/source/_plugins/kramdown-image.rb b/source/_plugins/kramdown-image.rb
new file mode 100644
index 0000000..ed2ffe0
--- /dev/null
+++ b/source/_plugins/kramdown-image.rb
@@ -0,0 +1,12 @@
+# https://github.com/gettalong/kramdown/issues/98#issuecomment-495169800
+
+require 'kramdown/converter/html'
+
+module StandaloneImages
+ def convert_p(el, indent)
+ return super unless el.children.size == 1 && (el.children.first.type == :img || (el.children.first.type == :html_element && el.children.first.value == "img"))
+ convert(el.children.first, indent)
+ end
+end
+
+Kramdown::Converter::Html.prepend StandaloneImages
\ No newline at end of file
diff --git a/source/assets/agatha-dark.png b/source/assets/agatha-dark.png
index 5c202c9..1e63d8a 100644
Binary files a/source/assets/agatha-dark.png and b/source/assets/agatha-dark.png differ
diff --git a/source/assets/agatha-light.png b/source/assets/agatha-light.png
new file mode 100644
index 0000000..79ad57a
Binary files /dev/null and b/source/assets/agatha-light.png differ
diff --git a/source/assets/anchor-light.svg b/source/assets/anchor-light.svg
new file mode 100644
index 0000000..6a4ea26
--- /dev/null
+++ b/source/assets/anchor-light.svg
@@ -0,0 +1 @@
+
diff --git a/source/assets/anchor.svg b/source/assets/anchor.svg
new file mode 100644
index 0000000..743357b
--- /dev/null
+++ b/source/assets/anchor.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/source/assets/bg-noise-dark.png b/source/assets/bg-noise-dark.png
index 85968ae..6557d29 100644
Binary files a/source/assets/bg-noise-dark.png and b/source/assets/bg-noise-dark.png differ
diff --git a/source/assets/bg-noise-light.png b/source/assets/bg-noise-light.png
new file mode 100644
index 0000000..e9a706f
Binary files /dev/null and b/source/assets/bg-noise-light.png differ
diff --git a/source/css/404.css b/source/css/404.css
new file mode 100644
index 0000000..f72284d
--- /dev/null
+++ b/source/css/404.css
@@ -0,0 +1,76 @@
+body {
+ padding-left: 5em;
+ padding-top: 5em;
+ max-width: 70%;
+}
+
+h1 {
+ color: var(--accent-dark);
+ font-family: "Cinzel Decorative";
+ font-size: 40px;
+ font-weight: normal;
+ line-height: 1;
+
+ max-width: 600px;
+
+ padding-bottom: 25px;
+ margin-bottom: 30px;
+
+ border-bottom: 1px solid var(--accent);
+}
+
+h1::first-letter {
+ font-size: 55px;
+}
+
+a {
+ font-family: "Crimson";
+ font-weight: normal;
+ text-decoration: none;
+ font-size: 1.8em;
+
+ color: var(--url);
+}
+
+a::before {
+ content: "◆";
+ font-size: 0.5em;
+ padding-right: 3px;
+ position: relative;
+ bottom: 4px;
+}
+
+a:hover {
+ animation: glow 0.2s ease-in-out both;
+}
+html {
+ height: 100%;
+ box-shadow: inset 0 0 100px #02020470;
+}
+
+* {
+ filter: drop-shadow(20px 0 3px rgba(95, 95, 153, 0.36));
+}
+
+/* animations */
+
+@keyframes glow {
+ from {
+ font-weight: normal;
+ }
+
+ to {
+ filter: drop-shadow(0.5px 0.5px 2px);
+ }
+}
+
+/* small screens */
+
+@media (max-width: 600px) {
+ body {
+ padding-top: 5%;
+ padding-left: 5%;
+ padding-right: 5%;
+ max-width: unset;
+ }
+}
diff --git a/source/css/common.css b/source/css/common.css
index 607c6f0..a52eaa9 100644
--- a/source/css/common.css
+++ b/source/css/common.css
@@ -1,71 +1,79 @@
/* Fonts */
@font-face {
- font-family: "Cinzel Decorative";
- src: url(../fonts/CinzelDecorative-Regular.ttf);
- font-weight: normal;
+ font-family: "Cinzel Decorative";
+ src: url(../fonts/CinzelDecorative-Regular.ttf);
+ font-weight: normal;
}
@font-face {
- font-family: "Cinzel Decorative";
- src: url(../fonts/CinzelDecorative-Bold.ttf);
- font-weight: bold;
+ font-family: "Cinzel Decorative";
+ src: url(../fonts/CinzelDecorative-Bold.ttf);
+ font-weight: bold;
}
@font-face {
- font-family: "Crimson";
- src: url(../fonts/Crimson-Roman.otf);
- font-weight: normal;
- font-style: normal;
+ font-family: "Crimson";
+ src: url(../fonts/Crimson-Roman.otf);
+ font-weight: normal;
+ font-style: normal;
}
@font-face {
- font-family: "Crimson";
- src: url(../fonts/Crimson-Bold.otf);
- font-weight: bold;
- font-style: normal;
+ font-family: "Crimson";
+ src: url(../fonts/Crimson-Bold.otf);
+ font-weight: bold;
+ font-style: normal;
}
@font-face {
- font-family: "Crimson";
- src: url(../fonts/Crimson-Italic.otf);
- font-weight: normal;
- font-style: italic;
+ font-family: "Crimson";
+ src: url(../fonts/Crimson-Italic.otf);
+ font-weight: normal;
+ font-style: italic;
}
@font-face {
- font-family: "Crimson";
- src: url(../fonts/Crimson-BoldItalic.otf);
- font-weight: bold;
- font-style: italic;
+ font-family: "Crimson";
+ src: url(../fonts/Crimson-BoldItalic.otf);
+ font-weight: bold;
+ font-style: italic;
}
/* Colors */
+html {
+ scrollbar-color: var(--accent) var(--bg);
+ background: url(../assets/bg-noise-dark.png) repeat;
+ background-color: var(--bg);
+}
+
:root {
- --bg: #19121F;
- --accent: #9AA6CB;
- --accent-dark: #747E9D;
- --text: #D5D6E8;
- --url: #F5E8C9;
+ --bg: #16121f;
+ --bg-code: #110e18;
+ --accent: #9aa6cb;
+ --accent-dark: #747e9d;
+ --text: #d5d6e8;
+ --url: var(--accent);
}
@media (prefers-color-scheme: light) {
- :root {
+ :root {
+ --bg: #b6b7d4;
+ --bg-code: #a5a6c5;
+ --accent: #555a84;
+ --accent-dark: #464b73;
+ --text: #16121f;
+ --url: var(--accent);
+ }
- }
-
- html {
-
- }
-}
-
-html {
- background: url(../assets/bg-noise-dark.png) repeat;
+ html {
+ background: url(../assets/bg-noise-light.png);
background-color: var(--bg);
+ }
}
::selection {
- color: var(--bg);
- background: var(--accent);
-}
\ No newline at end of file
+ color: var(--bg);
+ background: var(--accent);
+}
diff --git a/source/css/index.css b/source/css/index.css
index ae7f6e3..98645f3 100644
--- a/source/css/index.css
+++ b/source/css/index.css
@@ -1,185 +1,187 @@
.centered {
- position: absolute;
- display: flex;
- left: 50%;
- top: 50%;
- -webkit-transform: translate(-50%, -50%);
- transform: translate(-50%, -50%);
+ position: absolute;
+ display: flex;
+ left: 50%;
+ top: 50%;
+ -webkit-transform: translate(-50%, -50%);
+ transform: translate(-50%, -50%);
}
.text {
- margin-top: 5em;
- width: 400px;
+ margin-top: 5em;
+ width: 400px;
}
h1 {
- font-family: 'Cinzel Decorative';
- color: var(--accent);
- width: min-content;
- font-size: 55px;
- font-weight: normal;
- line-height: 1;
- margin-bottom: 0;
+ font-family: "Cinzel Decorative";
+ color: var(--accent);
+ width: min-content;
+ font-size: 55px;
+ font-weight: normal;
+ line-height: 1;
+ margin-bottom: 0;
}
h1 span {
- font-size: 75px;
+ font-size: 75px;
}
-h3, p {
- font-family: 'Crimson';
- font-weight: normal;
+h3,
+p {
+ font-family: "Crimson";
+ font-weight: normal;
}
h3 {
- color: var(--accent-dark);
- font-size: 30px;
- margin-top: 0.2em;
+ color: var(--accent-dark);
+ font-size: 30px;
+ margin-top: 0.2em;
}
p {
- margin-top: 2em;
- font-size: 25px;
- line-height: 1.1;
- color: var(--text);
+ margin-top: 2em;
+ font-size: 25px;
+ line-height: 1.1;
+ color: var(--text);
}
abbr {
- text-decoration: none;
- font-style: italic;
- animation: blink 5s linear infinite;
+ text-decoration: none;
+ font-style: italic;
+ animation: blink 5s linear infinite;
}
picture img {
- height: 700px;
+ height: 700px;
}
/* Links menu */
details {
- margin-top: 1.5em;
- width: max-content;
+ margin-top: 1.5em;
+ width: max-content;
}
details a {
- opacity: 0;
- margin: 0 8px;
+ opacity: 0;
+ margin: 0 8px;
}
details * {
- display: inline-block;
+ display: inline-block;
}
details[open] a {
- opacity: 100;
- transition: opacity 0.2s ease-in-out;
+ opacity: 100;
+ transition: opacity 0.2s ease-in-out;
}
-details, details * {
- font-family: 'Crimson';
- font-weight: normal;
- font-size: 26px;
- text-decoration: none;
+details,
+details * {
+ font-family: "Crimson";
+ font-weight: normal;
+ font-size: 26px;
+ text-decoration: none;
- color: var(--url);
+ color: var(--url);
- height: min-content;
- cursor: pointer;
- user-select: none;
+ height: min-content;
+ cursor: pointer;
+ user-select: none;
}
details summary::before {
- content: '⦿ ';
- filter: drop-shadow(0 0 5px);
+ content: "⦿ ";
+ filter: drop-shadow(0 0 5px);
}
details[open] > summary {
- visibility: hidden;
- font-size: 0;
+ visibility: hidden;
+ font-size: 0;
}
details[open] > summary::after {
- content: '←';
- visibility: visible;
- font-size: 26px;
+ content: "←";
+ visibility: visible;
+ font-size: 26px;
- position: relative;
- top: -2px;
+ position: relative;
+ top: -2px;
}
details *:hover {
- animation: glow 0.2s ease-in-out both;
+ animation: glow 0.2s ease-in-out both;
}
/* animations */
@keyframes glow {
- from {
- font-weight: normal;
- }
- to {
- filter: drop-shadow(0.5px 0.5px 2px) ;
- }
+ from {
+ font-weight: normal;
+ }
+ to {
+ filter: drop-shadow(0.5px 0.5px 2px);
+ }
}
@keyframes blink {
- 80% {
- filter: drop-shadow(0 0 1px) opacity(80%);
- }
+ 80% {
+ filter: drop-shadow(0 0 1px) opacity(80%);
+ }
}
/* mobile screens */
@media (max-width: 880px) {
- .centered {
- display: block;
- top: -20px;
- -webkit-transform: translate(-50%, 0);
- transform: translate(-50%, 0);
- }
+ .centered {
+ display: block;
+ top: -20px;
+ -webkit-transform: translate(-50%, 0);
+ transform: translate(-50%, 0);
+ }
- .text {
- margin-top: unset;
- position: absolute;
- left: 50%;
- -webkit-transform: translate(-50%, -60%);
- transform: translate(-50%, -60%);
+ .text {
+ margin-top: unset;
+ position: absolute;
+ left: 50%;
+ -webkit-transform: translate(-50%, -60%);
+ transform: translate(-50%, -60%);
- width: 320px;
- padding-bottom: 4em;
- }
- h1 {
- filter: drop-shadow(5px 5px 5px var(--bg));
- }
+ width: 320px;
+ padding-bottom: 4em;
+ }
+ h1 {
+ filter: drop-shadow(5px 5px 5px var(--bg));
+ }
}
@media (max-width: 500px) {
- picture img {
- max-width: 100vw;
- height: auto;
- }
+ picture img {
+ max-width: 100vw;
+ height: auto;
+ }
}
@media (max-width: 360px) {
- .text {
- position: unset;
- left: unset;
- -webkit-transform: translate(0, -60%);
- transform: translate(0, -60%);
+ .text {
+ position: unset;
+ left: unset;
+ -webkit-transform: translate(0, -60%);
+ transform: translate(0, -60%);
- width: fit-content;
- margin-left: 2em;
- }
+ width: fit-content;
+ margin-left: 2em;
+ }
- h1 {
- font-size: 40px;
- }
+ h1 {
+ font-size: 40px;
+ }
- h1 span {
- font-size: 60px;
- }
+ h1 span {
+ font-size: 60px;
+ }
- details {
- width: fit-content;
- }
-}
\ No newline at end of file
+ details {
+ width: fit-content;
+ }
+}
diff --git a/source/css/page.css b/source/css/page.css
new file mode 100644
index 0000000..3e6cbb3
--- /dev/null
+++ b/source/css/page.css
@@ -0,0 +1,295 @@
+@font-face {
+ font-family: "Iosevka Gothic";
+ src: url(../fonts/iosevka-gothic-regular.woff2);
+ font-weight: normal;
+}
+
+body {
+ position: absolute;
+ display: flex;
+ left: 50%;
+ -webkit-transform: translate(-50%, 0);
+ transform: translate(-50%, 0);
+
+ padding-top: 2em;
+ padding-bottom: 2em;
+}
+
+/* headers */
+
+#mainheader {
+ font-size: 2.6em;
+}
+
+#mainheader::first-letter {
+ font-size: 1.2em;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ color: var(--accent);
+ font-family: "Cinzel Decorative";
+ font-weight: normal;
+ line-height: 1;
+}
+
+h1 {
+ font-size: 35px;
+}
+
+h1::first-letter {
+ font-size: 40px;
+}
+
+h2 {
+ font-size: 25px;
+}
+
+h3 {
+ font-size: 20px;
+}
+
+/* common text */
+
+p,
+ul,
+ol,
+table {
+ color: var(--text);
+ font-family: "Crimson", serif;
+ font-size: 1.2rem;
+ max-width: 1000px;
+}
+
+strong {
+ font-weight: bolder;
+ text-shadow: 0 0.5px;
+}
+
+/* why'd you leave the keys upon the table */
+
+table {
+ border-collapse: collapse;
+ max-width: 700px;
+ padding: 5px;
+ border: 2px solid var(--border);
+}
+
+td {
+ border: 2px solid var(--border);
+ padding: 0 5px;
+}
+
+/* code blocks */
+
+code * {
+ font-size: 1rem;
+ font-family: "Iosevka Gothic";
+}
+
+:not(pre) > code {
+ padding: 2px;
+ border-radius: 3px;
+ font-family: "Iosevka Gothic";
+}
+
+img {
+ display: block;
+ margin: 5px auto;
+ border-radius: 2px;
+ border: 15px solid var(--bg-code);
+ filter: drop-shadow(0 0 5px var(--bg));
+}
+
+pre {
+ overflow-x: auto;
+}
+
+.lineno {
+ user-select: none;
+ -webkit-user-select: none;
+}
+
+.highlight {
+ padding: 0 5px;
+ border-radius: 5px;
+ background-color: var(--bg-code);
+}
+
+/* header anchors */
+
+a[class="anchor"]::before {
+ display: none;
+}
+
+a[class="anchor"] span {
+ content: url(../assets/anchor.svg);
+ margin-right: 5px;
+ margin-left: -25px;
+ margin-bottom: 2px;
+ opacity: 0%;
+ transition: opacity 0.2s ease-in-out;
+ user-select: none;
+ -webkit-user-select: none;
+}
+
+@media (prefers-color-scheme: light) {
+ a[class="anchor"] span {
+ content: url(../assets/anchor-light.svg);
+ }
+}
+
+:is(h1, h2, h3, h4, h5, h6):hover a[class="anchor"] span {
+ opacity: 80%;
+ transition: opacity 0.2s ease-in-out;
+}
+
+a {
+ font-family: "Crimson";
+ font-weight: normal;
+ text-decoration: none;
+
+ color: var(--url);
+}
+
+.contents a::before {
+ content: "◆";
+ font-size: 0.5em;
+ padding-right: 3px;
+ position: relative;
+ bottom: 4px;
+}
+
+a:hover {
+ animation: glow 0.2s ease-in-out both;
+}
+
+/* animations */
+
+@keyframes glow {
+ from {
+ font-weight: normal;
+ }
+
+ to {
+ filter: drop-shadow(0.5px 0.5px 2px);
+ }
+}
+
+/* sidebar */
+
+.side p {
+ font-size: 1.5em;
+ margin-bottom: 0;
+}
+
+.side a,
+footer a {
+ color: var(--text);
+ filter: brightness(90%);
+ text-decoration: none;
+}
+
+.side a:hover {
+ animation: none;
+ text-decoration: underline;
+}
+
+.side ul {
+ padding-left: 18px;
+ margin-top: 6px;
+}
+
+.side li {
+ list-style: none;
+}
+
+#toc {
+ padding-bottom: 20px;
+ width: 85%;
+ border-bottom: 1px solid var(--text);
+}
+
+.contents {
+ min-height: calc(100vh - 230px);
+}
+
+footer {
+ display: flex;
+ justify-content: space-between;
+ width: 100%;
+ margin-top: 2em;
+ padding-top: 0.5em;
+ border-top: 1px solid var(--text);
+}
+
+footer > * {
+ font-size: 1.2em;
+ margin-top: 1em;
+}
+
+footer div {
+ display: grid;
+ height: min-content;
+}
+
+/* large screens */
+
+@media (min-width: 1330px) {
+ .contents {
+ max-width: 700px;
+ }
+
+ img {
+ max-width: 95%;
+ }
+
+ .side {
+ left: 100%;
+ margin-left: 2em;
+ margin-top: 100px;
+ position: absolute;
+ width: 270px;
+ }
+}
+
+/* small screens */
+
+@media (max-width: 1330px) {
+ body {
+ display: unset;
+ max-width: 800px;
+ }
+
+ img {
+ width: 90%;
+ }
+
+ footer {
+ display: none;
+ }
+}
+
+/* smaller screens */
+
+@media (max-width: 830px) {
+ body {
+ width: 90%;
+ }
+
+ .side {
+ height: auto;
+ margin: auto;
+ position: relative;
+ width: 90%;
+ }
+
+ a[class="anchor"] {
+ float: right;
+ margin-left: 21px;
+ }
+}
diff --git a/source/css/pageindex.css b/source/css/pageindex.css
new file mode 100644
index 0000000..bdf1a85
--- /dev/null
+++ b/source/css/pageindex.css
@@ -0,0 +1,87 @@
+body {
+ padding-left: 5em;
+ padding-top: 5em;
+ max-width: 70%;
+}
+
+h1 {
+ color: var(--accent-dark);
+ font-family: "Cinzel Decorative";
+ font-size: 40px;
+ font-weight: normal;
+ line-height: 1;
+
+ max-width: 600px;
+
+ padding-bottom: 25px;
+ margin-bottom: 30px;
+
+ border-bottom: 1px solid var(--accent);
+}
+
+h1::first-letter {
+ font-size: 60px;
+}
+
+p,
+ul,
+ol {
+ color: var(--text);
+ font-family: "Crimson", serif;
+ font-size: 1.2rem;
+ max-width: 1000px;
+}
+
+ul {
+ list-style: none;
+ padding: unset;
+ margin: unset;
+}
+
+strong {
+ font-weight: bolder;
+ text-shadow: 0 0.5px;
+}
+
+a {
+ font-family: "Crimson";
+ font-weight: normal;
+ text-decoration: none;
+
+ color: var(--url);
+}
+
+a::before {
+ content: "◆";
+ font-size: 0.5em;
+ padding-right: 3px;
+ position: relative;
+ bottom: 4px;
+}
+
+a:hover {
+ animation: glow 0.2s ease-in-out both;
+}
+
+/* animations */
+
+@keyframes glow {
+ from {
+ font-weight: normal;
+ }
+
+ to {
+ filter: drop-shadow(0.5px 0.5px 2px);
+ }
+}
+
+/* small screens */
+
+@media (max-width: 600px) {
+ body {
+ padding-top: 5%;
+ padding-left: 5%;
+ padding-right: 5%;
+ max-width: unset;
+ }
+}
diff --git a/source/css/paramount-light.css b/source/css/paramount-light.css
index 4317068..1fc11c5 100644
--- a/source/css/paramount-light.css
+++ b/source/css/paramount-light.css
@@ -5,7 +5,7 @@ td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #ffffff; }
-.highlight .c { color: #a8a8a8; font-style: italic } /* Comment */
+.highlight .c { color: #797979; font-style: italic } /* Comment */
.highlight .err { color: #ffffff; background-color: #c30771 } /* Error */
.highlight .g { color: #767676 } /* Generic */
.highlight .k { color: #767676 } /* Keyword */
diff --git a/source/fonts/iosevka-gothic-bold.woff2 b/source/fonts/iosevka-gothic-bold.woff2
new file mode 100644
index 0000000..e61a50d
Binary files /dev/null and b/source/fonts/iosevka-gothic-bold.woff2 differ
diff --git a/source/fonts/iosevka-gothic-bolditalic.woff2 b/source/fonts/iosevka-gothic-bolditalic.woff2
new file mode 100644
index 0000000..1fdd66d
Binary files /dev/null and b/source/fonts/iosevka-gothic-bolditalic.woff2 differ
diff --git a/source/fonts/iosevka-gothic-italic.woff2 b/source/fonts/iosevka-gothic-italic.woff2
new file mode 100644
index 0000000..f219d22
Binary files /dev/null and b/source/fonts/iosevka-gothic-italic.woff2 differ
diff --git a/source/fonts/iosevka-gothic-regular.woff2 b/source/fonts/iosevka-gothic-regular.woff2
new file mode 100644
index 0000000..49db565
Binary files /dev/null and b/source/fonts/iosevka-gothic-regular.woff2 differ
diff --git a/source/index.html b/source/index.html
index 708e411..98344bd 100644
--- a/source/index.html
+++ b/source/index.html
@@ -1,22 +1,18 @@
+---
+---
-
-
-
+ {% include header.html %}
-
-
-
-
Agatha V. Lovelace