1318 lines
33 KiB
HTML
1318 lines
33 KiB
HTML
<!doctype html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
|
<title>domain and site setup | hello hello</title>
|
|
<meta name="description" content="Lee Cattarin... on the internet!">
|
|
<link rel="alternate" href="/feed.xml" type="application/atom+xml" title="hello hello">
|
|
|
|
<meta property="og:title" content="domain and site setup">
|
|
<meta property="og:type" content="website">
|
|
<meta property="og:description" content="Lee Cattarin... on the internet!">
|
|
<meta property="og:site_name" content="hello hello">
|
|
|
|
<meta property="og:image" content="/img/crinkly-mushrooms.jpg">
|
|
<meta property="og:image:alt" content="Picture unrelated to post. Some crinkly brown-orange mushrooms in vibrant green grass.">
|
|
|
|
|
|
<meta name="generator" content="Eleventy v3.1.2">
|
|
|
|
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="">
|
|
<link href="https://fonts.googleapis.com/css2?family=Atkinson+Hyperlegible+Mono:ital,wght@0,200..800;1,200..800&family=Atkinson+Hyperlegible+Next:ital,wght@0,200..800;1,200..800&display=swap" rel="stylesheet">
|
|
|
|
|
|
<script src="https://kit.fontawesome.com/884dded219.js" crossorigin="anonymous"></script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<style>.post-metadata {
|
|
display: flex;
|
|
flex-flow: row wrap;
|
|
justify-content: space-between;
|
|
align-items: baseline;
|
|
margin: 1.5rem 0 .5rem;
|
|
}
|
|
|
|
.post-metadata p {
|
|
font-size: .9rem;
|
|
margin: 0;
|
|
}
|
|
|
|
.post-tags {
|
|
display: flex;
|
|
flex-flow: row wrap;
|
|
gap: .5rem;
|
|
list-style: none;
|
|
margin: 0;
|
|
}
|
|
|
|
.post-tags li {
|
|
margin: 0;
|
|
}
|
|
|
|
.post-tags li a {
|
|
text-decoration: none;
|
|
color: var(--color-teal);
|
|
padding: 0 .5rem;
|
|
border-radius: 1rem;
|
|
box-shadow: .15rem .15rem var(--color-shadow);
|
|
border: .08rem solid var(--color-teal);
|
|
line-height: 2;
|
|
/* Click animation handling */
|
|
position: relative;
|
|
top: 0;
|
|
left: 0;
|
|
transition: top .1s ease-in, left .1s ease-in;
|
|
}
|
|
|
|
.post-tags li a:focus-visible {
|
|
outline: none;
|
|
background-color: var(--color-teal);
|
|
color: var(--color-bg);
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
.post-tags li a:hover {
|
|
outline: none;
|
|
background-color: var(--color-teal);
|
|
color: var(--color-bg);
|
|
}
|
|
}
|
|
|
|
@media (forced-colors: active) {
|
|
.post-tags li a:focus-visible {
|
|
outline-offset: .08rem;
|
|
outline: .08rem solid;
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
.post-tags li a:hover {
|
|
outline-offset: .08rem;
|
|
outline: .08rem solid;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Click animation */
|
|
.post-tags li a:active {
|
|
top: .1rem;
|
|
left: .1rem;
|
|
box-shadow: .05rem .05rem var(--color-shadow);
|
|
}
|
|
/* Adapted from PrismJS 1.30.0 Tomorrow Night theme
|
|
https://prismjs.com/download
|
|
*/
|
|
code,
|
|
pre,
|
|
code[class*=language-],
|
|
pre[class*=language-] {
|
|
font-family: var(--font-family-code);
|
|
background-color: var(--color-bg-alt);
|
|
font-size: .9rem;
|
|
text-shadow: 0 1px var(--color-shadow);
|
|
-moz-tab-size: 4;
|
|
-o-tab-size: 4;
|
|
tab-size: 4;
|
|
-webkit-hyphens: none;
|
|
-moz-hyphens: none;
|
|
-ms-hyphens: none;
|
|
hyphens: none;
|
|
}
|
|
|
|
pre,
|
|
pre[class*=language-] {
|
|
margin: 1rem 0;
|
|
padding: 1rem;
|
|
line-height: 1.5;
|
|
white-space: pre-wrap;
|
|
word-break: break-word;
|
|
overflow-wrap: break-word;
|
|
border-radius: .5rem;
|
|
overflow: auto;
|
|
}
|
|
|
|
:not(pre)>code,
|
|
:not(pre)>code[class*=language-] {
|
|
padding: .2rem;
|
|
border-radius: .25rem;
|
|
white-space: normal;
|
|
}
|
|
|
|
/* Selected text */
|
|
code ::-moz-selection,
|
|
code::-moz-selection,
|
|
pre ::-moz-selection,
|
|
pre::-moz-selection,
|
|
code[class*=language-] ::-moz-selection,
|
|
code[class*=language-]::-moz-selection,
|
|
pre[class*=language-] ::-moz-selection,
|
|
pre[class*=language-]::-moz-selection,
|
|
code ::selection,
|
|
code::selection,
|
|
pre ::selection,
|
|
pre::selection,
|
|
code[class*=language-] ::selection,
|
|
code[class*=language-]::selection,
|
|
pre[class*=language-] ::selection,
|
|
pre[class*=language-]::selection {
|
|
text-shadow: none;
|
|
background-color: var(--color-bg);
|
|
}
|
|
|
|
/* Syntax highlighting */
|
|
.token.namespace {
|
|
opacity: .7;
|
|
}
|
|
|
|
.token.bold,
|
|
.token.important {
|
|
font-weight:700
|
|
}
|
|
|
|
.token.italic {
|
|
font-style:italic
|
|
}
|
|
|
|
.token.block-comment,
|
|
.token.cdata,
|
|
.token.comment,
|
|
.token.doctype,
|
|
.token.prolog,
|
|
.token.punctuation {
|
|
color: var(--color-grey);
|
|
}
|
|
|
|
.token.attr-name,
|
|
.token.deleted,
|
|
.token.namespace,
|
|
.token.tag {
|
|
color: var(--color-red);
|
|
}
|
|
|
|
.token.boolean,
|
|
.token.function,
|
|
.token.number {
|
|
color: var(--color-orange);
|
|
}
|
|
|
|
.token.class-name,
|
|
.token.constant,
|
|
.token.property,
|
|
.token.symbol {
|
|
color: var(--color-yellow);
|
|
}
|
|
|
|
.token.attr-value,
|
|
.token.char,
|
|
.token.regex,
|
|
.token.string,
|
|
.token.variable,
|
|
.token.inserted {
|
|
color: var(--color-green);
|
|
}
|
|
|
|
.token.entity,
|
|
.token.operator,
|
|
.token.url,
|
|
.token.function-name {
|
|
color:var(--color-blue);
|
|
}
|
|
|
|
.token.atrule,
|
|
.token.builtin,
|
|
.token.important,
|
|
.token.keyword,
|
|
.token.selector {
|
|
color: var(--color-purple);
|
|
}
|
|
:root {
|
|
color-scheme: light dark;
|
|
|
|
--font-family: 'Atkinson Hyperlegible Next', sans-serif;
|
|
--font-family-code: 'Atkinson Hyperlegible Mono', monospace;
|
|
|
|
--color-dark: #2e303e;
|
|
--color-dark-alt: #3c3f52;
|
|
--color-light: #ebeeef;
|
|
--color-light-alt: #dbe1e3;
|
|
|
|
--color-teal-dark: #18737b;
|
|
--color-teal-light: #25b0bc;
|
|
--color-pink-dark: #94195d;
|
|
--color-pink-light: #ee9fcb;
|
|
|
|
--color-shadow: rgba(2, 10, 40, .25);
|
|
|
|
/* Used for syntax highlighting */
|
|
--color-red-light: #e95678;
|
|
--color-orange-light: #fab795;
|
|
--color-yellow-light: #fbe6bc;
|
|
--color-green-light: #29d398;
|
|
--color-blue-light: #26bbd9;
|
|
--color-purple-light: #ddaeea;
|
|
--color-grey-light: #b9c3c6;
|
|
|
|
--color-red-dark: #991433;
|
|
--color-orange-dark: #883206;
|
|
--color-yellow-dark: #6a4906;
|
|
--color-green-dark: #125940;
|
|
--color-blue-dark: #125663;
|
|
--color-purple-dark: #722999;
|
|
--color-grey-dark: #4a4b64;
|
|
|
|
--color-text: light-dark(var(--color-dark), var(--color-light));
|
|
--color-bg: light-dark(var(--color-light), var(--color-dark));
|
|
|
|
--color-text-alt: light-dark(var(--color-dark-alt), var(--color-light-alt));
|
|
--color-bg-alt: light-dark(var(--color-light-alt), var(--color-dark-alt));
|
|
|
|
--color-teal: light-dark(var(--color-teal-dark), var(--color-teal-light));
|
|
--color-pink: light-dark(var(--color-pink-dark), var(--color-pink-light));
|
|
|
|
--color-red: light-dark(var(--color-red-dark), var(--color-red-light));
|
|
--color-orange: light-dark(var(--color-orange-dark), var(--color-orange-light));
|
|
--color-yellow: light-dark(var(--color-yellow-dark), var(--color-yellow-light));
|
|
--color-green: light-dark(var(--color-green-dark), var(--color-green-light));
|
|
--color-blue: light-dark(var(--color-blue-dark), var(--color-blue-light));
|
|
--color-purple: light-dark(var(--color-purple-dark), var(--color-purple-light));
|
|
--color-grey: light-dark(var(--color-grey-dark), var(--color-grey-light));
|
|
|
|
--header-offset: 3.1rem;
|
|
}
|
|
|
|
/* Base */
|
|
|
|
* {
|
|
box-sizing: border-box;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
body {
|
|
font-family: var(--font-family);
|
|
color: var(--color-text);
|
|
background-color: var(--color-bg);
|
|
}
|
|
|
|
main {
|
|
width: 60vw;
|
|
max-width: 1000px;
|
|
margin: 0 auto;
|
|
scroll-margin-top: var(--header-offset);
|
|
}
|
|
|
|
@media (max-width: 1050px) {
|
|
main {
|
|
width: 75vw;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 650px) {
|
|
main {
|
|
width: 92vw;
|
|
}
|
|
}
|
|
|
|
/* Headers */
|
|
h1, h2, h3, h4, h5, h6 {
|
|
line-height: 1.25;
|
|
color: var(--color-teal);
|
|
scroll-margin-top: var(--header-offset);
|
|
}
|
|
|
|
h1 {
|
|
margin-top: 3rem;
|
|
font-size: 3.5rem;
|
|
text-align: center;
|
|
}
|
|
|
|
h2 {
|
|
margin-top: 2rem;
|
|
font-size: 2.2rem;
|
|
}
|
|
|
|
h3 {
|
|
margin-top: 1.5rem;
|
|
font-size: 1.6rem;
|
|
}
|
|
|
|
@media (max-width: 650px) {
|
|
h1 { font-size: 2.8rem; }
|
|
h2 { font-size: 1.8rem; }
|
|
h3 { font-size: 1.35rem; }
|
|
}
|
|
|
|
h4, h5, h6 {
|
|
margin-top: 1rem;
|
|
font-size: 1.2rem;
|
|
}
|
|
|
|
/* Images */
|
|
img {
|
|
display: block;
|
|
max-width: 100%;
|
|
height: auto;
|
|
border-radius: 1rem;
|
|
}
|
|
|
|
/* Paragraphs */
|
|
p {
|
|
margin: 1.25rem 0;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
strong,
|
|
b {
|
|
font-weight: 900;
|
|
}
|
|
|
|
/* Links */
|
|
a {
|
|
color: var(--color-text);
|
|
border-radius: .25rem;
|
|
text-decoration: underline;
|
|
text-decoration-style: solid;
|
|
text-decoration-thickness: .2em;
|
|
text-decoration-color: var(--color-teal);
|
|
transition: text-decoration-thickness .5s;
|
|
}
|
|
|
|
a:focus-visible {
|
|
text-decoration: none;
|
|
outline: .15rem solid var(--color-teal);
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
a:hover {
|
|
text-decoration-thickness: .4em;
|
|
}
|
|
}
|
|
|
|
a:active {
|
|
text-decoration-thickness: .4em;
|
|
}
|
|
|
|
/* Heading anchors */
|
|
a.ha,
|
|
span.ha-placeholder {
|
|
color: var(--color-pink);
|
|
}
|
|
span.ha-placeholder {
|
|
opacity: .55;
|
|
}
|
|
|
|
|
|
/* Lists */
|
|
::marker {
|
|
color: var(--color-pink);
|
|
}
|
|
|
|
ul, ol, dl, li {
|
|
margin-left: 1rem;
|
|
}
|
|
|
|
li {
|
|
line-height: 1.2 5;
|
|
margin-top: .65rem;
|
|
margin-bottom: .65rem;
|
|
}
|
|
|
|
li ul, li ol {
|
|
margin: .5rem 0;
|
|
}
|
|
|
|
dt {
|
|
font-weight: 900;
|
|
margin-top: .5rem;
|
|
}
|
|
|
|
dd {
|
|
margin-left: 2rem;
|
|
margin-bottom: .75rem;
|
|
}
|
|
|
|
/* Blockquotes */
|
|
blockquote {
|
|
margin: .5rem 0;
|
|
padding: 0 1rem;
|
|
border-radius: .25rem 1rem 1rem .25rem;
|
|
line-height: 1.25;
|
|
border-left: .5rem solid var(--color-pink);
|
|
}
|
|
|
|
blockquote,
|
|
blockquote p,
|
|
blockquote ol,
|
|
blockquote ul {
|
|
background-color: var(--color-bg-alt);
|
|
padding: .5rem;
|
|
}
|
|
|
|
blockquote p {
|
|
margin: 0;
|
|
}
|
|
|
|
/* Tables */
|
|
table {
|
|
width: 100%;
|
|
border-spacing: 0; /* border collapse doesn't play nice with radii */
|
|
border-radius: .3rem;
|
|
border: thin solid var(--color-pink);
|
|
}
|
|
|
|
th {
|
|
color: var(--color-bg);
|
|
background-color: var(--color-pink);
|
|
}
|
|
|
|
th code {
|
|
color: var(--color-text); /* Yes, I actually do this somewhere */
|
|
}
|
|
|
|
th, td {
|
|
padding: .5rem;
|
|
text-align: left;
|
|
}
|
|
|
|
tr:nth-child(even) { background-color: var(--color-bg-alt); }
|
|
th:not(:first-child) { border-left: thin solid var(--color-bg); }
|
|
th:first-child { border-top-left-radius: .25rem; }
|
|
th:last-child { border-top-right-radius: .25rem; }
|
|
td:not(:first-child) { border-left: thin solid var(--color-pink); }
|
|
|
|
/* Times */
|
|
time {
|
|
color: var(--color-grey);
|
|
}
|
|
|
|
/* Horizontal rules */
|
|
hr {
|
|
color: var(--color-teal);
|
|
border: .25rem solid var(--color-teal);
|
|
margin: 2rem 0;
|
|
}
|
|
hr:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
/* Used on home, reference, gallery pages */
|
|
.centered {
|
|
text-align: center;
|
|
}
|
|
|
|
/* Currently only used for resume, but it's generalizable */
|
|
.upper {
|
|
text-transform: uppercase;
|
|
}
|
|
/* Header */
|
|
header {
|
|
position: sticky;
|
|
top: 0;
|
|
background-color: var(--color-bg);
|
|
box-shadow: 0 .25rem .15rem var(--color-shadow);
|
|
padding: .75rem 0;
|
|
z-index: 10;
|
|
}
|
|
|
|
/* Header links, pagination links */
|
|
header a,
|
|
.pagination a,
|
|
.webring ul a {
|
|
border-radius: 1rem;
|
|
border: .125rem solid var(--color-pink);
|
|
color: var(--color-pink);
|
|
text-decoration: none;
|
|
padding: 0 .25rem;
|
|
box-shadow: .15rem .15rem var(--color-shadow);
|
|
font-size: 1.2rem;
|
|
/* Click animation handling */
|
|
position: relative;
|
|
top: 0;
|
|
left: 0;
|
|
transition: top .05s ease-in, left .05s ease-in;
|
|
}
|
|
|
|
header a,
|
|
.pagination .older a,
|
|
.webring .prev a,
|
|
.webring .rand a {
|
|
padding-right: .35rem;
|
|
}
|
|
|
|
.pagination .newer a,
|
|
.webring .next a,
|
|
.webring .rand a {
|
|
padding-left: .35rem;
|
|
}
|
|
|
|
header a:focus-visible,
|
|
.pagination a:focus-visible,
|
|
.webring ul a:focus-visible {
|
|
color: var(--color-bg);
|
|
border-color: var(--color-pink);
|
|
background-color: var(--color-pink);
|
|
outline: none;
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
header a:hover,
|
|
.pagination a:hover,
|
|
.webring ul a:hover {
|
|
color: var(--color-bg);
|
|
border-color: var(--color-pink);
|
|
background-color: var(--color-pink);
|
|
}
|
|
}
|
|
|
|
@media (forced-colors: active) {
|
|
header a:focus-visible,
|
|
.pagination a:focus-visible,
|
|
.webring ul a:focus-visible {
|
|
outline-offset: .125rem;
|
|
outline: .125rem solid;
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
header a:hover,
|
|
.pagination a:hover,
|
|
.webring ul a:hover {
|
|
outline-offset: .125rem;
|
|
outline: .125rem solid;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Click animation */
|
|
header a:active,
|
|
.pagination a:active,
|
|
.webring ul a:active {
|
|
top: .1rem;
|
|
left: .1rem;
|
|
box-shadow: .05rem .05rem var(--color-shadow);
|
|
}
|
|
|
|
/* Current page */
|
|
header a[aria-current="page"] {
|
|
border-color: var(--color-teal);
|
|
color: var(--color-teal);
|
|
}
|
|
|
|
header a[aria-current="page"]:focus-visible {
|
|
color: var(--color-bg);
|
|
border-color: var(--color-teal);
|
|
background-color: var(--color-teal);
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
header a[aria-current="page"]:hover {
|
|
color: var(--color-bg);
|
|
background-color: var(--color-teal);
|
|
border-color: var(--color-teal);
|
|
}
|
|
}
|
|
|
|
/* Header link icons, pagination icons */
|
|
header i,
|
|
.pagination i,
|
|
.webring ul i {
|
|
color: var(--color-teal);
|
|
}
|
|
|
|
header i,
|
|
.pagination .older i,
|
|
.webring .prev i,
|
|
.webring .rand i:nth-child(1) {
|
|
padding-left: .25rem;
|
|
}
|
|
|
|
.pagination .newer i,
|
|
.webring .next i,
|
|
.webring .rand i:nth-child(2) {
|
|
padding-right: .25rem;
|
|
}
|
|
|
|
header a[aria-current="page"] i {
|
|
color: var(--color-pink);
|
|
}
|
|
|
|
header a:focus-visible i,
|
|
a[aria-current="page"] a:focus-visible i,
|
|
.pagination a:focus-visible i,
|
|
.webring ul a:focus-visible i {
|
|
color: var(--color-bg);
|
|
}
|
|
|
|
@media (any-hover: hover) {
|
|
header a:hover i,
|
|
header a[aria-current="page"]:hover i,
|
|
.pagination a:hover i,
|
|
.webring ul a:hover i {
|
|
color: var(--color-bg);
|
|
}
|
|
}
|
|
|
|
/* Skip link */
|
|
#skip {
|
|
left: -999px;
|
|
position: absolute;
|
|
top: auto;
|
|
width: 1px;
|
|
height: 1px;
|
|
overflow: hidden;
|
|
z-index: -99;
|
|
}
|
|
|
|
#skip:focus-visible {
|
|
display: inline-block;
|
|
left: auto;
|
|
top: auto;
|
|
width: auto;
|
|
height: auto;
|
|
overflow: auto;
|
|
margin: 0 10%;
|
|
z-index: 999;
|
|
}
|
|
|
|
/* Nav */
|
|
header ul {
|
|
display: flex;
|
|
list-style: none;
|
|
gap: 1rem;
|
|
justify-content: center;
|
|
}
|
|
|
|
header ul,
|
|
header li {
|
|
margin: 0;
|
|
}
|
|
|
|
@media (max-width: 650px) {
|
|
.menu-text {
|
|
display: none; /* Icons only on small screens */
|
|
}
|
|
|
|
header a {
|
|
padding: .15rem .5rem;
|
|
}
|
|
|
|
header i {
|
|
padding: 0;
|
|
}
|
|
}
|
|
|
|
/* Footer */
|
|
footer {
|
|
padding: 1rem 0;
|
|
font-size: .9rem;
|
|
}
|
|
|
|
footer ul {
|
|
display: flex;
|
|
list-style: none;
|
|
gap: .5rem;
|
|
justify-content: center;
|
|
margin: 0;
|
|
}
|
|
|
|
footer li {
|
|
margin: 0;
|
|
}
|
|
|
|
footer li:nth-child(2)::before,
|
|
footer li:nth-child(2)::after {
|
|
content: " ● " / "";
|
|
color: var(--color-teal);
|
|
}
|
|
|
|
@media (max-width: 650px) {
|
|
footer ul {
|
|
flex-flow: column;
|
|
text-align: center;
|
|
}
|
|
|
|
footer li:nth-child(2)::before,
|
|
footer li:nth-child(2)::after {
|
|
content: none;
|
|
}
|
|
}
|
|
|
|
footer a {
|
|
text-decoration-color: var(--color-pink);
|
|
}
|
|
|
|
footer a:focus-visible {
|
|
outline-color: var(--color-pink);
|
|
}
|
|
|
|
/* Pagination */
|
|
.pagination,
|
|
.pagination li {
|
|
margin: 0;
|
|
}
|
|
|
|
.pagination {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, 1fr);
|
|
grid-template-areas: "older newer";
|
|
list-style: none;
|
|
margin-top: 3rem;
|
|
}
|
|
|
|
@media (max-width: 650px) {
|
|
.post-pagination {
|
|
grid-template-columns: 1fr;
|
|
grid-template-areas:
|
|
"older"
|
|
"newer";
|
|
gap: .75rem;
|
|
}
|
|
}
|
|
|
|
.pagination .older {
|
|
grid-area: older;
|
|
}
|
|
|
|
.pagination .newer {
|
|
grid-area: newer;
|
|
text-align: right;
|
|
}
|
|
|
|
/* webring navigation */
|
|
.webring {
|
|
margin-bottom: 3rem;
|
|
}
|
|
|
|
.webring ul {
|
|
display: flex;
|
|
flex-flow: row wrap;
|
|
list-style: none;
|
|
justify-content: space-around;
|
|
gap: .35rem;
|
|
}
|
|
|
|
.webring ul,
|
|
.webring li {
|
|
margin-left: 0;
|
|
}
|
|
@media print {
|
|
/* Nav elements */
|
|
header,
|
|
footer,
|
|
nav {
|
|
display: none !important;
|
|
}
|
|
|
|
/* Base */
|
|
body {
|
|
background-color: #fff;
|
|
color: #000;
|
|
}
|
|
|
|
main {
|
|
width: 95vw;
|
|
}
|
|
|
|
h1,h2,h3,h4,h5,h6 {
|
|
color: #000;
|
|
}
|
|
|
|
/* Links */
|
|
/* Hover is not really necessary, but it's annoying when testing otherwise */
|
|
a,
|
|
a:hover {
|
|
text-decoration-style: dotted;
|
|
text-decoration-thickness: .1rem;
|
|
text-decoration-color: #000;
|
|
}
|
|
|
|
a::after{
|
|
content: " (" attr(href) ")";
|
|
}
|
|
|
|
|
|
/* Code */
|
|
code,
|
|
pre,
|
|
code[class*=language-],
|
|
pre[class*=language-] {
|
|
text-shadow: none;
|
|
background-color: var(--color-light);
|
|
color: #000 !important;
|
|
}
|
|
|
|
.token.namespace {
|
|
opacity: 1;
|
|
}
|
|
|
|
.token.block-comment,
|
|
.token.cdata,
|
|
.token.comment,
|
|
.token.doctype,
|
|
.token.prolog,
|
|
.token.punctuation,
|
|
.token.attr-name,
|
|
.token.deleted,
|
|
.token.namespace,
|
|
.token.tag,
|
|
.token.boolean,
|
|
.token.function,
|
|
.token.number,
|
|
.token.class-name,
|
|
.token.constant,
|
|
.token.property,
|
|
.token.symbol,
|
|
.token.attr-value,
|
|
.token.char,
|
|
.token.regex,
|
|
.token.string,
|
|
.token.variable,
|
|
.token.inserted,
|
|
.token.entity,
|
|
.token.operator,
|
|
.token.url,
|
|
.token.function-name,
|
|
.token.atrule,
|
|
.token.builtin,
|
|
.token.important,
|
|
.token.keyword,
|
|
.token.selector {
|
|
color: #000;
|
|
}
|
|
}</style>
|
|
|
|
<script type="module">// Thank you to https://github.com/daviddarnes/heading-anchors
|
|
// Thank you to https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
|
|
|
|
let globalInstanceIndex = 0;
|
|
|
|
class HeadingAnchors extends HTMLElement {
|
|
static register(tagName = "heading-anchors", registry = window.customElements) {
|
|
if(registry && !registry.get(tagName)) {
|
|
registry.define(tagName, this);
|
|
}
|
|
}
|
|
|
|
static attributes = {
|
|
exclude: "data-ha-exclude",
|
|
prefix: "prefix",
|
|
content: "content",
|
|
}
|
|
|
|
static classes = {
|
|
anchor: "ha",
|
|
placeholder: "ha-placeholder",
|
|
srOnly: "ha-visualhide",
|
|
}
|
|
|
|
static defaultSelector = "h2,h3,h4,h5,h6";
|
|
|
|
static css = `
|
|
.${HeadingAnchors.classes.srOnly} {
|
|
clip: rect(0 0 0 0);
|
|
height: 1px;
|
|
overflow: hidden;
|
|
position: absolute;
|
|
width: 1px;
|
|
}
|
|
.${HeadingAnchors.classes.anchor} {
|
|
position: absolute;
|
|
left: var(--ha_offsetx);
|
|
top: var(--ha_offsety);
|
|
text-decoration: none;
|
|
opacity: 0;
|
|
}
|
|
.${HeadingAnchors.classes.placeholder} {
|
|
opacity: .3;
|
|
}
|
|
.${HeadingAnchors.classes.anchor}:is(:focus-within, :hover) {
|
|
opacity: 1;
|
|
}
|
|
.${HeadingAnchors.classes.anchor},
|
|
.${HeadingAnchors.classes.placeholder} {
|
|
display: inline-block;
|
|
padding: 0 .25em;
|
|
|
|
/* Disable selection of visually hidden label */
|
|
-webkit-user-select: none;
|
|
user-select: none;
|
|
}
|
|
|
|
@supports (anchor-name: none) {
|
|
.${HeadingAnchors.classes.anchor} {
|
|
position: absolute;
|
|
left: anchor(left);
|
|
top: anchor(top);
|
|
}
|
|
}`;
|
|
|
|
get supports() {
|
|
return "replaceSync" in CSSStyleSheet.prototype;
|
|
}
|
|
|
|
get supportsAnchorPosition() {
|
|
return CSS.supports("anchor-name: none");
|
|
}
|
|
|
|
constructor() {
|
|
super();
|
|
|
|
if(!this.supports) {
|
|
return;
|
|
}
|
|
|
|
let sheet = new CSSStyleSheet();
|
|
sheet.replaceSync(HeadingAnchors.css);
|
|
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
|
|
|
|
this.headingStyles = {};
|
|
this.instanceIndex = globalInstanceIndex++;
|
|
}
|
|
|
|
connectedCallback() {
|
|
if (!this.supports) {
|
|
return;
|
|
}
|
|
|
|
this.headings.forEach((heading, index) => {
|
|
if(!heading.hasAttribute(HeadingAnchors.attributes.exclude)) {
|
|
let anchor = this.getAnchorElement(heading);
|
|
let placeholder = this.getPlaceholderElement();
|
|
|
|
// Prefers anchor position approach for better accessibility
|
|
// https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
|
|
if(this.supportsAnchorPosition) {
|
|
let anchorName = `--ha_${this.instanceIndex}_${index}`;
|
|
placeholder.style.setProperty("anchor-name", anchorName);
|
|
anchor.style.positionAnchor = anchorName;
|
|
}
|
|
|
|
heading.appendChild(placeholder);
|
|
heading.after(anchor);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Polyfill-only
|
|
positionAnchorFromPlaceholder(placeholder) {
|
|
if(!placeholder) {
|
|
return;
|
|
}
|
|
|
|
let heading = placeholder.closest("h1,h2,h3,h4,h5,h6");
|
|
if(!heading.nextElementSibling) {
|
|
return;
|
|
}
|
|
|
|
// TODO next element could be more defensive
|
|
this.positionAnchor(heading.nextElementSibling);
|
|
}
|
|
|
|
// Polyfill-only
|
|
positionAnchor(anchor) {
|
|
if(!anchor || !anchor.previousElementSibling) {
|
|
return;
|
|
}
|
|
|
|
// TODO previous element could be more defensive
|
|
let heading = anchor.previousElementSibling;
|
|
this.setFontProp(heading, anchor);
|
|
|
|
if(this.supportsAnchorPosition) {
|
|
// quit early
|
|
return;
|
|
}
|
|
|
|
let placeholder = heading.querySelector(`.${HeadingAnchors.classes.placeholder}`);
|
|
if(placeholder) {
|
|
anchor.style.setProperty("--ha_offsetx", `${placeholder.offsetLeft}px`);
|
|
anchor.style.setProperty("--ha_offsety", `${placeholder.offsetTop}px`);
|
|
}
|
|
}
|
|
|
|
setFontProp(heading, anchor) {
|
|
let placeholder = heading.querySelector(`.${HeadingAnchors.classes.placeholder}`);
|
|
if(placeholder) {
|
|
let style = getComputedStyle(placeholder);
|
|
let props = ["font-weight", "font-size", "line-height", "font-family"];
|
|
let [weight, size, lh, family] = props.map(name => style.getPropertyValue(name));
|
|
anchor.style.setProperty("font", `${weight} ${size}/${lh} ${family}`);
|
|
let vars = style.getPropertyValue("font-variation-settings");
|
|
if(vars) {
|
|
anchor.style.setProperty("font-variation-settings", vars);
|
|
}
|
|
}
|
|
}
|
|
|
|
getAccessibleTextPrefix() {
|
|
// Useful for i18n
|
|
return this.getAttribute(HeadingAnchors.attributes.prefix) || "Jump to section titled";
|
|
}
|
|
|
|
getContent() {
|
|
if(this.hasAttribute(HeadingAnchors.attributes.content)) {
|
|
return this.getAttribute(HeadingAnchors.attributes.content);
|
|
}
|
|
return "#";
|
|
}
|
|
|
|
// Placeholder nests inside of heading
|
|
getPlaceholderElement() {
|
|
let ph = document.createElement("span");
|
|
ph.setAttribute("aria-hidden", true);
|
|
ph.classList.add(HeadingAnchors.classes.placeholder);
|
|
let content = this.getContent();
|
|
if(content) {
|
|
ph.innerHTML = content; // CHANGED HERE
|
|
}
|
|
|
|
ph.addEventListener("mouseover", (e) => {
|
|
let placeholder = e.target.closest(`.${HeadingAnchors.classes.placeholder}`);
|
|
if(placeholder) {
|
|
this.positionAnchorFromPlaceholder(placeholder);
|
|
}
|
|
});
|
|
|
|
return ph;
|
|
}
|
|
|
|
getAnchorElement(heading) {
|
|
let anchor = document.createElement("a");
|
|
anchor.href = `#${heading.id}`;
|
|
anchor.classList.add(HeadingAnchors.classes.anchor);
|
|
|
|
let content = this.getContent();
|
|
anchor.innerHTML = `<span class="${HeadingAnchors.classes.srOnly}">${this.getAccessibleTextPrefix()}: ${heading.textContent}</span>${content ? `<span aria-hidden="true">${content}</span>` : ""}`;
|
|
|
|
anchor.addEventListener("focus", e => {
|
|
let anchor = e.target.closest(`.${HeadingAnchors.classes.anchor}`);
|
|
if(anchor) {
|
|
this.positionAnchor(anchor);
|
|
}
|
|
});
|
|
|
|
anchor.addEventListener("mouseover", (e) => {
|
|
// when CSS anchor positioning is supported, this is only used to set the font
|
|
let anchor = e.target.closest(`.${HeadingAnchors.classes.anchor}`);
|
|
this.positionAnchor(anchor);
|
|
});
|
|
|
|
return anchor;
|
|
}
|
|
|
|
get headings() {
|
|
return this.querySelectorAll(this.selector.split(",").map(entry => `${entry.trim()}[id]`));
|
|
}
|
|
|
|
get selector() {
|
|
return this.getAttribute("selector") || HeadingAnchors.defaultSelector;
|
|
}
|
|
}
|
|
|
|
HeadingAnchors.register();
|
|
|
|
export { HeadingAnchors }</script>
|
|
</head>
|
|
<body>
|
|
<header>
|
|
|
|
<a href="#main" id="skip" title="skip to main content" aria-label="skip to main content">
|
|
<i class="fa-solid fa-forward" aria-hidden="true"></i> skip
|
|
</a>
|
|
|
|
<nav aria-label="main navigation">
|
|
<ul>
|
|
|
|
<li>
|
|
<a href="/reference/" title="read reference posts" aria-label="read reference posts">
|
|
<i class="fa-regular fa-folder-open" aria-hidden="true"></i>
|
|
<span class="menu-text">reference</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/gallery/" title="view the gallery" aria-label="view the gallery">
|
|
<i class="fa-regular fa-images" aria-hidden="true"></i>
|
|
<span class="menu-text">gallery</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/" title="" aria-label="">
|
|
<i class="fa fa-solid fa-crow" aria-hidden="true"></i>
|
|
<span class="menu-text">home</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/about/" title="about Lee" aria-label="about Lee">
|
|
<i class="fa-regular fa-user" aria-hidden="true"></i>
|
|
<span class="menu-text">about</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/contact/" title="contact Lee" aria-label="contact Lee">
|
|
<i class="fa-solid fa-envelope-open-text" aria-hidden="true"></i>
|
|
<span class="menu-text">contact</span>
|
|
</a>
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</header>
|
|
|
|
|
|
<main id="main">
|
|
|
|
|
|
|
|
|
|
<heading-anchors content="<i class='fa-solid fa-anchor'></i>">
|
|
<article>
|
|
<h1 id="domain-and-site-setup">domain and site setup</h1>
|
|
|
|
<div class="post-metadata">
|
|
<p>
|
|
posted on
|
|
<time datetime="2023-11-07">November 7, 2023</time>
|
|
by Lee Cattarin
|
|
</p>
|
|
|
|
|
|
<ul class="post-tags">
|
|
|
|
<li>
|
|
|
|
<a href="/tags/software/">software</a>
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
|
|
<img src="/img/crinkly-mushrooms.jpg" alt="Picture unrelated to post. Some crinkly brown-orange mushrooms in vibrant green grass." loading="lazy" decoding="async" width="1000" height="750">
|
|
|
|
|
|
<p>This was written as a skill share for the Artisans Cooperative blog.</p>
|
|
<p>In this writeup, I will walk through one (of many!) ways to set up and utilize a custom domain and website.</p>
|
|
<h2 id="audience">Audience</h2>
|
|
<p>This is aimed at a non-technical audience, but my own perspective is technical and some of the articles I link to will get technical. Because of this, it's possible that I will miss things that you have questions on - please reach out to me and ask questions!</p>
|
|
<h2 id="outcome">Outcome</h2>
|
|
<p>After following this writeup, you should have:</p>
|
|
<ul>
|
|
<li>a <strong>domain name</strong>: domain names identify internet locations with an easier-to-remember string than an IP (Internet Protocol) address.</li>
|
|
<li>a <strong>static website</strong>: <em>static</em> means that the site has fixed, pre-built assets that remain the same regardless of who is viewing them (or the time of day, or the weather, or...). A static site can still vary widely in complexity! I created my static site using <a href="https://pages.github.com/" target="_blank" rel="external">GitHub Pages</a>, a free offering that requires some technical skill to configure, but I'll mention some alternate routes that require less technical know-how, including simply letting your domain name point to an existing site you don't control - like your <a href="https://artisans.coop/" :target="_blank">Artisans Cooperative</a> storefront.</li>
|
|
</ul>
|
|
<p>This writeup will <em>not</em> cover every possible route to getting your own home on the web - there's far too many options out there. It's just meant to give you a starting point and a few ideas.</p>
|
|
<h2 id="domain-name">Domain name</h2>
|
|
<h3 id="top-level-domains-tlds">Top-level domains (TLDs)</h3>
|
|
<p>I started planning my domain name by reviewing the list of TLDs - things like ".org" or ".com". ICANN (the Internet Corporation for Assigned Names and Numbers) maintains a <a href="https://www.icann.org/resources/pages/tlds-2012-02-25-en" target="_blank" rel="external">list of all TLDs</a> - it's long! Reviewing this list can help you think of potential domain names. You can also look at a list like <a href="https://en.wikipedia.org/wiki/List_of_Internet_top-level_domains" :target="_blank">this one Wikipedia maintains</a> - it has more detail and can tell you if a specific TLD is for a given country, reserved for specific uses, or (what you probably want) for general use.</p>
|
|
<p>Personally, I narrowed it down to two - ".art" or ".gay". From there, it's off to the domain registrars! These are companies that offer domain names for sale. Here's <a href="https://www.forbes.com/advisor/business/software/best-domain-registrar/" target="_blank" rel="external">an article from Forbes Advisor reviewing some of the major names in the space</a>. I use Namecheap, but don't let that bias you. Look around at pricing (pay attention to the rate for year 2 onward - domain registrars often offer super low year 1 rates to hook customers) and consider other features, like support availability.</p>
|
|
<h3 id="decide-on-a-full-domain-name">Decide on a full domain name</h3>
|
|
<p>Narrowing down a TLD isn't the only choice - you also need to decide what goes in front of that! Some things to think about:</p>
|
|
<ul>
|
|
<li><strong>memorable:</strong> Shorter domain names and domain names with clearly recognizable words are helpful for both you and your audience. If you're anything like me, your site might end up as a repository for all sorts of knowledge and references, and being able to quickly type up or relay a URL is a plus.</li>
|
|
<li><strong>distinct:</strong> Is it unique? Avoid domains that are only a character off from more commonly visited websites or that sound particularly generic.</li>
|
|
<li><strong>constant:</strong> While you <em>can</em> change domains frequently if you wish (and might want to if you're tight on cash - again, year 1 offers are cheap!), reprinting all your marketing materials is no fun. Aim to pick something that has staying power, like your own or your business' name.</li>
|
|
</ul>
|
|
<p>In my case, I went with <a href="/">leecat.art</a>. The ".art" TLD was cheaper than the ".gay" option long-term, and I shortened my full, somewhat hard to spell name to a quick two syllables, 3 characters each.</p>
|
|
<h3 id="buy-your-domain">Buy your domain</h3>
|
|
<p>Pick a domain registrar that offers the domain name you want, and pay (usually for a year). Next, we'll talk about some uses for this domain name.</p>
|
|
<h2 id="using-your-domain-name">Using your domain name</h2>
|
|
<h3 id="option-1-simple-redirect">Option 1: simple redirect</h3>
|
|
<p>The easiest way to utilize a domain name is to have it redirect to another URL. I'm not going to go through how to set up a domain redirect with every possible provider, but if you search up "[your domain registrar] redirect" you should find useful documentation.</p>
|
|
<h3 id="option-1-but-better-redirect-to-a-link-tree">Option 1, but better: redirect to a link tree</h3>
|
|
<p>Link trees (popularized by <a href="https://linktr.ee/" target="_blank" rel="external">linktree</a>) are a single page with a collection of links maintained by an owner. You can use linktree or check out this <a href="https://www.wired.com/story/link-in-bio-linktree-alternatives/" :target="_blank">WIRED article with alternatives</a>. Some are paid, usually small monthly fees, and some are free.</p>
|
|
<h3 id="option-2-static-site-with-github-pages">Option 2: static site with GitHub Pages</h3>
|
|
<h4 id="wait-whats-github">Wait, what's GitHub?</h4>
|
|
<p><a href="https://github.com/" target="_blank" rel="external">GitHub</a> - wait, no.</p>
|
|
<p>First, let's talk about <a href="https://git-scm.com/" target="_blank" rel="external">git</a>. Git is a <em>version control system</em>, a type of software that manages changes to a set of files. This allows the owner(s) of those files to do things like revert changes or compare current and historical versions of files. It also allows for multiple people to work on the same shared file repository without creating conflicts.</p>
|
|
<p>GitHub is a centralized source for many, many git repositories. It essentially allows you to back up both your code and the log of all changes to the cloud (someone else's computer). It also supports <a href="https://pages.github.com/" target="_blank" rel="external">GitHub Pages</a>, a free way to host a static site of your own.</p>
|
|
<p>To get started with GitHub, you'll first need to <a href="https://github.com/signup" target="_blank" rel="external">create an account</a> if you don't have one. If you want to learn some GitHub basics, the GitHub team has created this handy <a href="https://github.com/skills/introduction-to-github" :target="_blank">introduction to GitHub</a> that walks you through some basic git and GitHub concepts.</p>
|
|
<h3 id="now-that-we-know-what-github-is">Now that we know what GitHub is...</h3>
|
|
<p>The GitHub documentation is pretty thorough, so let's point to some articles over there.</p>
|
|
<ul>
|
|
<li><a href="https://docs.github.com/en/pages/getting-started-with-github-pages/creating-a-github-pages-site" target="_blank" rel="external">Creating a GitHub Pages site</a> walks you through getting a repository set up and automatically publishing to a URL like "your-github-username.github.io" (don't worry, we'll get that custom domain name attached soon!)
|
|
<ul>
|
|
<li>there's also this handy <a href="https://docs.github.com/en/pages/quickstart" target="_blank" rel="external">GitHub Pages Quickstart</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll/adding-a-theme-to-your-github-pages-site-using-jekyll" target="_blank" rel="external">Adding a theme to your GitHub Pages site using Jekyll</a> will show you how to use pre-created website themes to customize your site.
|
|
<ul>
|
|
<li>I suggest using one of the <a href="https://pages.github.com/themes/" target="_blank" rel="external">supported themes</a> as they will be the easiest to work with.</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/managing-a-custom-domain-for-your-github-pages-site" target="_blank" rel="external">Managing a custom domain for your GitHub Pages site</a> will allow you to use that domain name you bought earlier for your new website!</li>
|
|
<li>GitHub Pages is powered by <a href="https://jekyllrb.com/" target="_blank" rel="external">Jekyll</a>, a tool for generating static sites from Markdown (.md) files. <a href="https://jekyllrb.com/docs/structure/" :target="_blank">Learn more about a Jekyll project's file directory structure</a></li>
|
|
</ul>
|
|
|
|
</article>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<nav aria-label="pagination">
|
|
<ol class="pagination post-pagination">
|
|
|
|
<li class="older">
|
|
<a href="/x-acto-knife-sheath/">
|
|
<i class="fa-solid fa-hand-point-left" aria-hidden="true"></i> x-acto knife sheath
|
|
</a>
|
|
</li>
|
|
|
|
|
|
<li class="newer">
|
|
<a href="/artists-conk/">
|
|
artists conk! <i class="fa-solid fa-hand-point-right" aria-hidden="true"></i>
|
|
</a>
|
|
</li>
|
|
|
|
</ol>
|
|
</nav>
|
|
|
|
|
|
</heading-anchors>
|
|
|
|
|
|
<hr>
|
|
</main>
|
|
|
|
<footer>
|
|
<ul>
|
|
<li>
|
|
<a href="/colophon" title="colophon" aria-label="colophon">
|
|
colophon
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/" title="go home" aria-label="go home | hello hello from Lee Cattarin in 2026">
|
|
hello hello from Lee Cattarin in 2026</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="https://heckin.technology/inherentlee/leecat.art" title="source code" aria-label="source code" target="_blank" rel="external">
|
|
src
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</footer>
|
|
|
|
|
|
<!-- This page `/domain-and-site-setup/` was built on 2026-02-20T16:02:10.545Z -->
|
|
<body>
|
|
</body></body> |