the home site for me: also iteration 3 or 4 of my site

feat: add crt effect and glowing stuff

Changed files
+279 -15
content
sass
static
blog
adding-a-copy-button
js
tags
accessibility
templates
+7 -5
content/_index.md
···
+++
+++
-
<div style="display: flex; justify-content: center;">
-
<img src="/pfps/instsqc-rat-pfp.webp" alt="kieran with an orange cast in a polaroid over a pinkish background" width="512" height="512" class="u-photo"/>
+
<div style="display: flex; justify-content: center; margin: 2rem;">
+
<div class="crt scanlines" style="width: 512px; height: 512px; box-shadow: var(--edge-highlight), var(--shadow-glow);">
+
<img src="/pfps/starry.webp" alt="kieran with a white and gray spotted kitten with a grainy background and star dust" width="512" height="512" class="u-photo"/>
+
</div>
</div>
-
## About me
+
# About me
Erlo! My name is Kieran Klukas and i'm a homeschooled coder who is {{ age(length=0) }} years old and loves film making, fpv, and typescript :)
···
this site has page hits (<code id="visits">0</code> and counting) via [abacus](https://jasoncameron.dev/abacus/) but they are completely anonymous and just http requests!
-
## Want to talk to me?
+
# Want to talk to me?
-
Do you want to hire me? (I will answer immediately :) If you just have a question or want to talk I'll still answer (admittedly more slowly).
+
Do you want to hire me for a project? If you just have a question or want to talk I'll still answer (admittedly more slowly ^-^).
- Email: [me@dunkirk.sh](mailto:me@dunkirk.sh)
- Hackclub Slack: [@krn](https://hackclub.slack.com/team/U062UG485EE) (only if you are a highschooler or younger; [join here](https://hackclub.com/slack/))
+1 -2
sass/css/_copy-button.scss
···
i.icon {
display: inline-block;
mask-size: cover;
-
background-color: currentColor;
+
background-color: var(--accent-text);
width: 1rem;
height: 1rem;
font-style: normal;
···
--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");
-
margin: 1rem 0 1rem;
border-radius: 0.75rem;
.header {
+240
sass/css/_crt.scss
···
+
::root {
+
--edge-highlight: inset 0 0.0625rem 0 rgb(255 255 255 / 0.1);
+
--shadow-glow:
+
0 0 0 0.0625rem var(--accent),
+
0 0.125rem 0.375rem 0.125rem var(--accent),
+
0 0.25rem 1.5rem 0.25rem var(--accent);
+
--crt-bg: var(--gradient-average-light);
+
}
+
+
@media (prefers-color-scheme: light) {
+
::root {
+
--crt-bg: var(--gradient-average-light);
+
}
+
}
+
+
[data-theme="light"] {
+
::root {
+
--crt-bg: var(--gradient-average-light);
+
}
+
}
+
+
@media (prefers-color-scheme: dark) {
+
::root {
+
--crt-bg: color-mix(in oklab, var(--nightshade-violet) 65%, black);
+
}
+
}
+
+
[data-theme="dark"] {
+
::root {
+
--crt-bg: color-mix(in oklab, var(--nightshade-violet) 65%, black);
+
}
+
}
+
+
h1,
+
img,
+
video,
+
iframe[src^="https://www.youtube-nocookie.com"],
+
iframe[src^="https://www.youtube.com"]
+
{
+
border: none;
+
box-shadow: var(--edge-highlight), var(--shadow-glow);
+
animation: flicker 4s alternate infinite;
+
+
@keyframes flicker {
+
2% {
+
opacity: 0.95;
+
}
+
+
4% {
+
opacity: 0.85;
+
}
+
+
7% {
+
opacity: 1;
+
}
+
+
to {
+
opacity: 0.9;
+
}
+
}
+
}
+
+
.text-glow {
+
--text-shadow-1: hsl(from var(--accent) h s l / 0.2);
+
--text-shadow-2: hsl(from var(--accent) h calc(s * 1.2) l);
+
text-shadow:
+
var(--text-shadow-1) 0 0 0.25rem,
+
var(--text-shadow-2) 0 0 0.75rem;
+
+
animation: flicker 4s alternate infinite;
+
+
@keyframes flicker {
+
2% {
+
opacity: 0.95;
+
}
+
+
4% {
+
opacity: 0.85;
+
}
+
+
7% {
+
opacity: 1;
+
}
+
+
to {
+
opacity: 0.9;
+
}
+
}
+
}
+
+
.crt {
+
margin: 1rem 0 1rem;
+
box-shadow:
+
var(--edge-highlight),
+
0 0 0 0.03125rem var(--accent),
+
0 0.0625rem 0.1875rem 0.03125rem var(--accent),
+
0 0.125rem 0.75rem 0.0625rem var(--accent);
+
border-radius: 0.2rem;
+
background-image: radial-gradient(
+
color-mix(in oklab, var(--accent) 25%, var(--crt-bg)),
+
color-mix(in srgb, var(--accent) 10%, var(--crt-bg)) 80%,
+
color-mix(in srgb, var(--accent) 5%, var(--crt-bg))
+
);
+
+
pre {
+
--text-shadow-1: hsl(from var(--accent) h s l / 0.2);
+
--text-shadow-2: hsl(from var(--accent) h calc(s * 1.2) l);
+
animation: flicker 0.3s alternate infinite;
+
margin: 0;
+
box-shadow: none;
+
background-color: transparent !important;
+
padding: 1rem 1rem;
+
color: var(--accent) !important;
+
text-shadow:
+
var(--text-shadow-1) 0 0 0.25rem,
+
var(--text-shadow-2) 0 0 0.75rem;
+
+
@keyframes flicker {
+
25% {
+
opacity: 0.93;
+
}
+
+
50% {
+
opacity: 0.89;
+
}
+
+
75% {
+
opacity: 0.95;
+
}
+
+
to {
+
opacity: 0.9;
+
}
+
}
+
}
+
+
> img {
+
border-radius: 0.2rem;
+
margin: 0;
+
max-width: 100%;
+
}
+
}
+
+
.scanlines,
+
h1 {
+
position: relative;
+
overflow: hidden;
+
+
&::before {
+
display: block;
+
position: absolute;
+
z-index: 2;
+
animation: scanlines 0.1s linear infinite;
+
inset: 0;
+
background-image: repeating-linear-gradient(
+
to bottom,
+
rgb(0 0 0 / 0.15),
+
rgb(0 0 0 / 0.15) 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) r g b / 0.03);
+
display: block;
+
position: absolute;
+
z-index: 2;
+
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);
+
}
+
}
+
}
+
}
+
+
.scanlines {
+
&::before {
+
opacity: 0.8;
+
}
+
+
&::after {
+
opacity: 0.5;
+
}
+
}
+
+
@media (prefers-color-scheme: light) {
+
.scanlines {
+
&::before {
+
opacity: 0.35;
+
}
+
+
&::after {
+
opacity: 0.4;
+
}
+
}
+
}
+
+
[data-theme="light"] {
+
.scanlines {
+
&::before {
+
opacity: 0.35;
+
}
+
+
&::after {
+
opacity: 0.4;
+
}
+
}
+
}
+
+
.cursor {
+
animation: cursor-blink 1s infinite;
+
+
@keyframes cursor-blink {
+
50% {
+
opacity: 0;
+
}
+
}
+
}
+1
sass/css/main.scss
···
@use "mods";
@use "copy-button";
+
@use "crt";
+1 -2
sass/css/suCSS.css
···
iframe[src^="https://www.youtube-nocookie.com"],
iframe[src^="https://www.youtube.com"] {
max-width: 90%;
+
margin: 1rem;
height: auto;
-
padding: 0.125rem;
border: dashed 2px var(--accent);
border-radius: 15px;
-
z-index: 1;
opacity: 0.95;
}
static/blog/adding-a-copy-button/og.png

This is a binary file and will not be displayed.

+16 -1
static/js/copy-button.js
···
if (navigator.clipboard) {
// Code block header title
const title = document.createElement("span");
+
title.style.color = "var(--accent-text)";
const lang = block.getAttribute("data-lang");
const comment =
block.previousElementSibling &&
···
// Container that holds header and the code block itself
const container = document.createElement("div");
-
container.classList.add("pre-container");
+
container.classList.add("pre-container", "crt", "scanlines");
container.appendChild(header);
+
+
const code = block.querySelector("code");
+
const cursor = document.createElement("span");
+
cursor.classList.add("cursor");
+
cursor.setAttribute("style", "display: inline;");
+
cursor.innerHTML = "█";
+
const lastline = code.lastChild;
+
const spans = lastline.getElementsByTagName("span");
+
const lastspan = spans[spans.length - 1];
+
if (lastspan) {
+
lastspan.appendChild(cursor);
+
} else {
+
lastline.appendChild(cursor);
+
}
// Move code block into the container
block.parentNode.insertBefore(container, block);
static/tags/accessibility/og.png

This is a binary file and will not be displayed.

+4 -2
templates/blog-page.html
···
By
<a
rel="author"
-
class="accent-data p-author h-card"
+
class="accent-data p-author h-card text-glow"
href="https://dunkirk.sh"
>{{config.extra.author}}</a
>
···
<p class="tags-data">
{% if page.taxonomies.tags %} {% for tag in page.taxonomies.tags %}
-
<a href="/tags/{{ tag | slugify }}" class="p-category">|{{ tag }}|</a>
+
<a href="/tags/{{ tag | slugify }}" class="p-category text-glow"
+
>|{{ tag }}|</a
+
>
{% endfor %} {% endif %}
</p>
</article>
+7 -2
templates/blog.html
···
%}
<li>
{{ page.date | split(pat="T") | first }} &mdash;
-
<a href="{{ page.permalink | safe }}">{{ page.title }}</a>
+
<a href="{{ page.permalink | safe }}" class="text-glow"
+
>{{ page.title }}</a
+
>
</li>
{% endif %} {% endfor %}
</ul>
···
{% for page in section.pages %} {% if "archival" in page.taxonomies.tags %}
<li>
{{ page.date }} &mdash;
-
<a href="{{ page.permalink | safe }}">{{ page.title }}</a> (archival)
+
<a href="{{ page.permalink | safe }}" class="text-glow"
+
>{{ page.title }}</a
+
>
+
(archival)
</li>
{% endif %} {% endfor %}
</ul>
+1 -1
templates/header.html
···
{% for nav_item in config.extra.header_nav %}
<a
href="{{ nav_item.url }}"
-
class="{% if nav_item.url == current_url %}active{% endif %}"
+
class="{% if nav_item.url == current_url %}active{% endif %} text-glow"
>
{{ nav_item.name }}
</a>
+1
templates/shortcodes/crt.html
···
+
<div class="crt scanlines" aria-hidden="true">{{ body | markdown | safe }}</div>