diff --git a/README.md b/README.md
index 441c2b6..b9fb975 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,7 @@ A list of things to check once in a while to make sure I haven't broken them ina
- Mobile and web layouts looks ok.
- Dark mode and light mode both look ok.
- OG tags render nicely, use https://www.opengraph.xyz/
+- Check the rss feed https://validator.w3.org/feed/check.cgi?url=https%3A%2F%2Fthomashodson.com%2Ffeed.xml
## Todo
- change the OG image used for the landing page so it's not just my face.
diff --git a/_includes/header.html b/_includes/header.html
index 396d04d..b9da812 100644
--- a/_includes/header.html
+++ b/_includes/header.html
@@ -17,6 +17,13 @@
{% include sidebar.html%}
+
+
{{ include.extra }}
\ No newline at end of file
diff --git a/_layouts/default.html b/_layouts/default.html
index 637d612..eced7a2 100644
--- a/_layouts/default.html
+++ b/_layouts/default.html
@@ -1,5 +1,5 @@
-
+
{% include default_head_tags.html%}
diff --git a/_layouts/post.html b/_layouts/post.html
index b0c5deb..a9f5d2e 100644
--- a/_layouts/post.html
+++ b/_layouts/post.html
@@ -1,5 +1,5 @@
-
+
{% include default_head_tags.html%}
diff --git a/_sass/_vars.scss b/_sass/_vars.scss
index 47408e6..4fe0a30 100644
--- a/_sass/_vars.scss
+++ b/_sass/_vars.scss
@@ -1,7 +1,7 @@
$font_stack: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;
$title_font_stack: Impact, Haettenschweiler, "Franklin Gothic Bold", Charcoal, "Helvetica Inserat", "Bitstream Vera Sans Bold", "Arial Black", "sans serif", HelveticaNeue-CondensedBlack;
-$horizontal_breakpoint: 700px;
+$horizontal_breakpoint: 900px;
$vertical_breakpoint: 500px;
// For the images on the blogroll, projects and highlights pages
diff --git a/_sass/base.scss b/_sass/base.scss
index 74046de..b828b29 100644
--- a/_sass/base.scss
+++ b/_sass/base.scss
@@ -8,227 +8,334 @@
@import "projects"; //Styles for the projects page
@import "cv"; // the CV page
@import "blogroll"; // the summaries of the blogposts
-@import "comments"; //the mastodon comments
+@import "comments"; //the mastodon comments
@import "model_viewer"; //Styles for the 3D model viewer
@import "mastodon_timeline";
+@import "night_mode_toggle";
// The syntax highlighting css
// generated with rougify style bw > code_style_bw.scss
-// @import "code_style_bw";
-@import "code_style_github";
+// @import "code_style_bw";
+@import "code_style_github";
@import "d2";
-
* {
- box-sizing: border-box;
- font-family: $font_stack;
- text-rendering: geometricPrecision;
+ box-sizing: border-box;
+ font-family: $font_stack;
+ text-rendering: geometricPrecision;
+}
+
+:root {
+ --theme-text-color: #222;
+ --theme-bg-color: #fcfcfc;
+ --theme-model-line-color: #222;
+ --theme-model-bg-color: #fcfcfc;
+ --theme-subtle-outline: oklch(90% 0 50);
+ --theme-highlight-color: hsl(338, 75%, 60%);
+ --theme-highlight-color-transparent: hsla(338, 75%, 60%, 33%);
+
+ // constrain width and center
+ --body-max-width: 900px;
+ --body-width: min(100vw, 900px);
+ --body-margin: calc((100vw - var(--body-width)) / 2);
+
+ --color-mode: "light";
+ --color-dark: #141414;
+ --color-dark-alpha: rgba(0, 0, 0, 0.1);
+ --color-light: #efefef;
+ --color-light-alpha: rgba(255, 255, 255, 0.9);
+ --icon-sun: url('data:image/svg+xml,\
+ \
+ \
+ ');
+ --icon-sun-filter: invert(0.75);
+ --icon-moon: url('data:image/svg+xml,\
+ \
+ \
+ ');
+ --icon-moon-filter: invert(0);
+ --background: #efefef;
+ --text-color: #141414;
+ --button-icon: var(--icon-moon);
+ --button-icon-filter: var(--icon-moon-filter);
+ --button-background: var(--color-dark);
+ --button-color: var(--color-light);
+ --border-color: var(--color-dark-alpha);
}
html {
- width: 100vw;
- scroll-behavior: smooth;
+ width: 100vw;
+ scroll-behavior: smooth;
}
body {
- --theme-text-color: #222;
- --theme-bg-color: #fcfcfc;
- --theme-model-line-color: #222;
- --theme-model-bg-color: #fcfcfc;
- --theme-subtle-outline: oklch(90% 0.0 50);
- --theme-highlight-color: hsl(338, 75%, 60%);
- --theme-highlight-color-transparent: hsla(338, 75%, 60%, 33%);
+ background: var(--theme-bg-color);
+ color: var(--theme-text-color);
- background: var(--theme-bg-color);
- color: var(--theme-text-color);
-
- // constrain width and center
- max-width: 900px;
- margin: auto;
+ max-width: var(--body-max-width);
+ margin: auto;
}
// Padding to keep the keep the content to the right of the header
main {
- container: main / inline-size;
+ container: main / inline-size;
- max-width: 560px;
- margin-left: 240px;
- padding-left: 30px;
- padding-right: 30px;
- padding-top: 10vh;
- min-height: 100vh;
+ --main-margin-left: 240px;
+ --main-padding-left: 30px;
+ --main-padding-right: 30px;
+ --main-max-width: 560px;
- display: flex;
- flex-direction: column;
- justify-content: center;
+ max-width: var(--main-max-width);
+ margin-left: var(--main-margin-left);
+ padding-left: var(--main-padding-left);
+ padding-right: var(--main-padding-right);
+ padding-top: 10vh;
+ min-height: 100vh;
- h1 {
- font-size: 2em;
- }
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
- // img that are direct children of p are usually img tags in markdown
- p > img {
- margin-top: 2em;
- margin-bottom: 1em;
- width: 90%;
+ h1 {
+ font-size: 2em;
+ }
- //hack to center images in p tags
- display: block;
- margin-left: auto;
- margin-right: auto;
- }
+ // img that are direct children of p are usually img tags in markdown
+ p > img {
+ margin-top: 2em;
+ margin-bottom: 1em;
+ width: 90%;
+
+ //hack to center images in p tags
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ }
}
:is(h1, h2, h3, h4, .text-balance) {
- text-wrap: balance;
+ text-wrap: balance;
}
-p, figcaption {
- font-size: 1em;
- line-height: 1.3em;
- }
+p,
+figcaption {
+ font-size: 1em;
+ line-height: 1.3em;
+}
-main :is(p,h1,h2,h3,h4,h5,h6) {
- margin-block-end: 0.2em;
- }
+main :is(p, h1, h2, h3, h4, h5, h6) {
+ margin-block-end: 0.2em;
+}
a {
- text-decoration: underline;
- text-underline-offset: 0.25em;
- text-decoration-thickness: 0.5px;
- color: var(--theme-text-color);
+ text-decoration: underline;
+ text-underline-offset: 0.25em;
+ text-decoration-thickness: 0.5px;
+ color: var(--theme-text-color);
}
-header a, nav a {
- text-decoration: none;
- color: var(--theme-text-color);
+header a,
+nav a {
+ text-decoration: none;
+ color: var(--theme-text-color);
}
div.highlight {
- max-width: 100%;
- overflow: auto;
+ max-width: 100%;
+ overflow: auto;
}
p {
- margin-top: 0.7em;
- margin-bottom: 0.7em;
- padding-right: 0;
- vertical-align: baseline;
+ margin-top: 0.7em;
+ margin-bottom: 0.7em;
+ padding-right: 0;
+ vertical-align: baseline;
}
figure {
- container: fig / inline-size;
- width: 100%;
- padding-bottom: 1em;
- margin-left: auto;
- margin-right: auto;
+ container: fig / inline-size;
+ width: 100%;
+ padding-bottom: 1em;
+ margin-left: auto;
+ margin-right: auto;
- figcaption {
- margin-top: 1em;
- text-align: center;
- }
+ figcaption {
+ margin-top: 1em;
+ text-align: center;
+ }
}
-figure > img, figure > svg, figure > canvas {
- width: 100%;
- margin-bottom: 1em;
- border-radius: 10px;
+figure > img,
+figure > svg,
+figure > canvas {
+ width: 100%;
+ margin-bottom: 1em;
+ border-radius: 10px;
}
figure.centered {
- display: flex;
- justify-content: center;
+ display: flex;
+ justify-content: center;
}
section.image-grid-4x4 {
- aspect-ratio: 1 / 1;
- display: grid;
- grid-template-columns: auto auto;
- grid-template-rows: auto auto;
- gap: 2px;
- margin-bottom: 1em;
- place-items: stretch stretch;
+ aspect-ratio: 1 / 1;
+ display: grid;
+ grid-template-columns: auto auto;
+ grid-template-rows: auto auto;
+ gap: 2px;
+ margin-bottom: 1em;
+ place-items: stretch stretch;
-
- * {
- margin: 0;
- padding: 0;
- width: 100%;
- aspect-ratio: auto;
- }
+ * {
+ margin: 0;
+ padding: 0;
+ width: 100%;
+ aspect-ratio: auto;
+ }
}
section.note {
- a {color: purple;}
- p {margin: 0;}
- padding: 1em;
- margin-top: 1em;
- margin-bottom: 1em;
- background-color: var(--theme-highlight-color-transparent);
- border-radius: 10px;
- color: black;
+ a {
+ color: purple;
+ }
+ p {
+ margin: 0;
+ }
+ padding: 1em;
+ margin-top: 1em;
+ margin-bottom: 1em;
+ background-color: var(--theme-highlight-color-transparent);
+ border-radius: 10px;
+ color: black;
}
section.center {
- display: flex;
- justify-content: center;
- margin-top: 1em;
- margin-bottom: 1em;
+ display: flex;
+ justify-content: center;
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+div.CodeRay,
+.wide-outside-parent {
+ // width: 100vw;
+ position: relative;
+ width: calc(
+ 100vw - var(--body-margin) - var(--main-margin-left) -
+ var(--main-padding-left) - var(--main-padding-right)
+ );
+ pre {
+ white-space: pre-wrap;
+ }
+ .line-numbers {
+ // display: none;
+ margin-right: 1em;
+ opacity: 0.3;
+ a {
+ text-decoration: none;
+ }
+ }
}
// If the browser doesn't support web components, hide anything with has-wc class
body.has-wc .no-wc {
- display: none;
+ display: none;
}
// If the browser does support web components, hide anything with no-wc class
body:not(.has-wc) .has-wc {
- display: none;
+ display: none;
}
-@media
- only screen and (max-width: $horizontal_breakpoint),
- only screen and (max-height: $vertical_breakpoint)
- {
- main {
- padding-top: 10px;
- padding-left: 20px;
- padding-right: 20px;
- margin: auto;
- justify-content: flex-start;
- }
-
- article {
- margin-left: 0px; }
-
- h1 {font-size: 1.5em !important;}
- .MathJax {
- font-size: 0.8em !important;
- overflow-x: auto;
- overflow-y: hidden;
- }
-}
-
-// For the 3D model viewer
-model-viewer {
- width: 100%;
- height: 300px;
+@media only screen and (max-width: $horizontal_breakpoint),
+ only screen and (max-height: $vertical_breakpoint) {
+ main {
+ --main-margin-left: 0px;
+ --main-padding-left: 20px;
+ --main-padding-right: 20px;
+ padding-top: 10px;
+ margin: auto;
+ justify-content: flex-start;
}
-
- @media (prefers-color-scheme: dark) {
- body {
- --theme-text-color: #fcfcfc;
- --theme-bg-color: #222;
- --theme-subtle-outline: oklch(50% 0.0 50);
- }
- img {
- opacity: .75;
- transition: opacity .5s ease-in-out;
- }
- svg.invertable, img.invertable{
- opacity: 1;
- filter: invert(1);
- }
- }
\ No newline at end of file
+ article {
+ margin-left: 0px;
+ }
+
+ h1 {
+ font-size: 1.5em !important;
+ }
+ .MathJax {
+ font-size: 0.8em !important;
+ overflow-x: auto;
+ overflow-y: hidden;
+ }
+
+ // Make code a bit smaller so it doesn't wrap as much
+ div.CodeRay {
+ font-size: 0.8rem;
+ }
+}
+
+.visually-hidden {
+ display: block;
+ height: 1px;
+ width: 1px;
+ overflow: hidden;
+ clip: rect(1px 1px 1px 1px);
+ clip: rect(1px, 1px, 1px, 1px);
+ clip-path: inset(1px);
+ white-space: nowrap;
+ position: absolute;
+}
+
+// Add transitions for things that will be affected by night mode
+body {
+ transition: background 500ms ease-in-out, color 200ms ease-in-out;
+}
+img {
+ transition: opacity 500ms ease-in-out;
+}
+svg.invertable,
+img.invertable {
+ transition: filter 500ms ease-in-out;
+}
+
+@mixin night-mode {
+ --background: var(--color-dark);
+ --text-color: var(--color-light);
+ --button-icon: var(--icon-sun);
+ --button-icon-filter: var(--icon-sun-filter);
+ --button-background: var(--color-light);
+ --button-color: var(--color-dark);
+ --border-color: var(--color-light-alpha);
+
+ body {
+ --theme-text-color: #fcfcfc;
+ --theme-bg-color: #222;
+ --theme-subtle-outline: oklch(50% 0 50);
+ }
+ img:not(.invertable) {
+ opacity: 0.75;
+ }
+ svg.invertable,
+ img.invertable {
+ opacity: 1;
+ filter: invert(1);
+ }
+}
+
+@media (prefers-color-scheme: dark) {
+ :root {
+ --color-mode: "dark";
+ }
+
+ :root:not([data-user-color-scheme]) {
+ @include night-mode;
+ }
+}
+
+[data-user-color-scheme="dark"] {
+ @include night-mode;
+}
diff --git a/_sass/blogroll.scss b/_sass/blogroll.scss
index 803053c..1ef5e32 100644
--- a/_sass/blogroll.scss
+++ b/_sass/blogroll.scss
@@ -16,13 +16,22 @@ article.draft {
opacity: 0.5;
}
+section.highlights {
+ margin-bottom: 2rem;
+
+ h1 {
+ margin-bottom: 1rem;
+ }
+}
+
a.highlights-more {
margin-left: $left_pad;
}
-main > h2 {
+h1.highlights {
font-size: 1.75rem;
- margin-left: $left_pad
+ margin-left: $left_pad;
+ margin-bottom: 1em;
}
article.blogroll {
@@ -65,5 +74,8 @@ article.blogroll {
font-size: 1.2em;
}
}
+ a.highlights-more {
+ font-size: 1.25rem;
+ }
}
\ No newline at end of file
diff --git a/_sass/cv.scss b/_sass/cv.scss
index cf1eb26..49befaa 100644
--- a/_sass/cv.scss
+++ b/_sass/cv.scss
@@ -1,123 +1,130 @@
summary.cv {
- margin-bottom: 0.7em;
- margin-top: 0.7em;
+ margin-bottom: 0.7em;
+ margin-top: 0.7em;
- padding-left: 2.2rem;
- position: relative;
+ padding-left: 2.2rem;
+ position: relative;
- display: flex;
- cursor: pointer;
+ display: flex;
+ cursor: pointer;
}
details summary.cv::-webkit-details-marker {
- display:none;
+ display: none;
}
details[open] > summary:before {
- transform: rotate(90deg);
+ transform: rotate(90deg);
}
//A little animation for the details opening
details[open] summary ~ * {
- animation: sweep .5s ease-in-out;
+ animation: sweep 0.5s ease-in-out;
+}
+
+@keyframes sweep {
+ 0% {
+ opacity: 0;
+ transform: translateX(-10px);
}
-
- @keyframes sweep {
- 0% {opacity: 0; transform: translateX(-10px)}
- 100% {opacity: 1; transform: translateX(0)}
+ 100% {
+ opacity: 1;
+ transform: translateX(0);
}
+}
summary.cv:before {
- content: '';
- border-width: .4rem;
- border-style: solid;
- border-color: transparent transparent transparent black;
- position: absolute;
- top: 0.2rem;
- left: 1rem;
- transform: rotate(0);
- transform-origin: .2rem 50%;
- transition: .25s transform ease;
+ content: "";
+ border-width: 0.4rem;
+ border-style: solid;
+ border-color: transparent transparent transparent var(--theme-text-color);
+ position: absolute;
+ top: 0.2rem;
+ left: 1rem;
+ transform: rotate(0);
+ transform-origin: 0.2rem 50%;
+ transition: 0.25s transform ease;
}
summary li {
- margin-bottom: 0em;
+ margin-bottom: 0em;
}
summary time {
- width: 150px;
- flex: 0 0 auto;
+ width: 150px;
+ flex: 0 0 auto;
}
div.details-img {
- padding-right: 20px;
- padding-bottom: 20px;
- width: 150px;
- flex: 0 0 auto;
+ padding-right: 20px;
+ padding-bottom: 20px;
+ width: 150px;
+ flex: 0 0 auto;
}
div.details-text p {
- margin-top: 0px;
- flex: 0 0 auto;
+ margin-top: 0px;
+ flex: 0 0 auto;
}
div.details-img img {
- border-radius: 10px;
- max-width: 100%;
+ border-radius: 10px;
+ max-width: 100%;
}
summary h3 {
- font-size: 1em;
- margin: 0px;
- flex: 0 1 auto;
+ font-size: 1em;
+ margin: 0px;
+ flex: 0 1 auto;
}
button {
- height: 2em;
+ height: 2em;
}
-div.details-container {
- display: flex;
- margin-left: 2.2rem;
+div.details-container {
+ display: flex;
+ margin-left: 2.2rem;
}
.cv-title-container {
- display: flex;
- align-items:baseline;
+ display: flex;
+ align-items: baseline;
}
div.cv-title-container {
- margin-bottom:1em;
- margin-top:1em;
+ margin-bottom: 1em;
+ margin-top: 1em;
+}
+div.cv-title-container h2 {
+ margin: 0px;
}
-div.cv-title-container h2 {margin:0px;}
div.cv-title-container a {
- cursor: pointer;
- margin-left: 3em;
+ cursor: pointer;
+ margin-left: 3em;
- border-style: solid;
- border-radius: 5px;
- border-width: 1px;
- border-color: transparent;
- offset: None;
+ border-style: solid;
+ border-radius: 5px;
+ border-width: 1px;
+ border-color: transparent;
+ offset: None;
- background-color: transparent;
- font-size: 1em;
+ background-color: transparent;
+ font-size: 1em;
}
div.cv-title-container button:hover {
- border-color:black;
+ border-color: black;
}
-@media only screen and (max-width: 900px) {
- div.details-container {
- margin-left:2.2rem;
- flex-direction: column;
- align-items: center;
- }
+@media only screen and (max-width: 900px) {
+ div.details-container {
+ margin-left: 2.2rem;
+ flex-direction: column;
+ align-items: center;
+ }
- summary.cv {
- flex-direction: column;
- }
-
-}
\ No newline at end of file
+ summary.cv {
+ flex-direction: column;
+ }
+}
diff --git a/_sass/header.scss b/_sass/header.scss
index 4e06055..72524d6 100644
--- a/_sass/header.scss
+++ b/_sass/header.scss
@@ -3,141 +3,139 @@
// The header with info about me
// gets displayed on the left in a wide layout and on the top in a narrow layout
header {
- border-right: 2px solid #eee; //make a nice dividing line
- position: fixed;
- width: 240px;
- height: 100vh;
- padding-right: 30px;
- padding-left: 30px;
-
- flex: 0 0 240px;
+ border-right: 2px solid #eee; //make a nice dividing line
+ position: fixed;
+ width: 240px;
+ height: 100vh;
+ padding-right: 30px;
+ padding-left: 30px;
+
+ flex: 0 0 240px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: flex-end;
+ text-align: right;
+ top: 0px;
+
+ //a horizontal dividing line to swap in when we switch to mobile layout
+ hr {
+ border: 0px solid #eee;
+ width: 100%;
+ margin-top: 1em;
+ }
+
+ .profile-pic-name {
+ text-align: center;
+ }
+
+ .avatar {
+ max-width: 175px;
+ border-radius: 50%;
+ padding: 5px;
+ border: 1px solid var(--theme-text-color);
+ }
+
+ h1 {
+ color: var(--theme-highlight-color);
+ font-size: 2em;
+ }
+
+ h1,
+ h2 {
+ font-family: $title_font_stack;
+ }
+
+ a {
+ margin-bottom: 2px;
+ }
+
+ p.professional-links {
display: flex;
flex-direction: column;
- justify-content: center;
- align-items: flex-end;
- text-align: right;
- top: 0px;
- //a horizontal dividing line to swap in when we switch to mobile layout
- hr {
- border:0px solid #eee;
- width: 100%;
- margin-top: 1em;
- }
-
- .profile-pic-name {
- text-align: center;
- }
-
- .avatar {
- max-width: 175px;
- border-radius: 50%;
- padding: 5px;
- border: 1px solid #f2f3f3;
- }
-
- h1 {
- color: var(--theme-highlight-color);
- font-size: 2em;
- }
-
- h1, h2 {
- font-family: $title_font_stack;
+ svg {
+ height: 1em;
+ width: 1em;
+ margin-left: 0.5em;
+ flex: 0 0 auto;
}
a {
- margin-bottom: 2px;
- }
-
- p.professional-links {
- display: flex;
- flex-direction: column;
-
- svg {
- height: 1em;
- width: 1em;
- margin-left: 0.5em;
- flex: 0 0 auto;
- }
-
- a {
- display: flex; //
- align-items: center; // Get the icons centered vertically
- justify-content: right; //Align right
- }
+ display: flex; //
+ align-items: center; // Get the icons centered vertically
+ justify-content: right; //Align right
}
+ }
}
-@media
- only screen and (max-width: $horizontal_breakpoint),
- only screen and (max-height: $vertical_breakpoint)
- {
- header {
- position: relative;
- width: 100%;
- border: 0px;
- text-align: center;
- align-items: center;
- height: auto;
- padding-left: 20px;
- padding-right: 20px;
-
+@media only screen and (max-width: $horizontal_breakpoint),
+ only screen and (max-height: $vertical_breakpoint) {
+ header {
+ position: relative;
+ width: 100%;
+ border: 0px;
+ text-align: center;
+ align-items: center;
+ height: auto;
+ padding-left: 20px;
+ padding-right: 20px;
+
hr {
- border-width:1px;
+ border-width: 1px;
}
.bio {
- span {
- display: inline;
- }
- span:after {
- content: ', ';
- }
- span:last-of-type:after {
- content: '';
- }
+ span {
+ display: inline;
+ }
+ span:after {
+ content: ", ";
+ }
+ span:last-of-type:after {
+ content: "";
+ }
}
// To squish the text together a bit in the mobile view.
p {
- margin-block: 0.25em;
+ margin-block: 0.25em;
}
.avatar {
- margin: auto;
- }
-
+ margin: auto;
+ }
+
p.professional-links {
- flex-direction: row;
- flex-wrap: wrap;
- justify-content: center;
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: center;
- a {
- margin-left: 1em;
- margin-right: 1em;
- flex-wrap: nowrap;
- justify-content: center;
-
- // In the main view, the github/mastodon/rss icons are on the right
- // for the smaller view switch the to the left
- flex-direction: row-reverse;
- }
- svg {
- // Switch the padding side having switched the order
- margin-right: 0.5em;
- margin-left: 0;
- }
- }
-
- }
-
- nav {
- display: flex;
- flex-direction: row;
- justify-content: center;
- flex-wrap: wrap;
- }
- nav a {
+ a {
margin-left: 1em;
+ margin-right: 1em;
+ flex-wrap: nowrap;
+ justify-content: center;
+
+ // In the main view, the github/mastodon/rss icons are on the right
+ // for the smaller view switch the to the left
+ flex-direction: row-reverse;
+ }
+ svg {
+ // Switch the padding side having switched the order
+ margin-right: 0.5em;
+ margin-left: 0;
+ }
}
+ }
+
+ nav {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ flex-wrap: wrap;
+ }
+ nav a {
+ margin-left: 1em;
+ }
}
diff --git a/_sass/model_viewer.scss b/_sass/model_viewer.scss
index f492db8..fbc1cb1 100644
--- a/_sass/model_viewer.scss
+++ b/_sass/model_viewer.scss
@@ -1,84 +1,88 @@
// For fallback images inside custom outline-model-viewer elements
.outline-model-poster {
- width: 100%;
- height: 100%;
+ width: 100%;
+ height: 100%;
}
outline-model-viewer {
- width: 100%;
- min-height: 300px;
- display: flex;
- justify-content: center;
- align-items: center;
- border: var(--theme-subtle-outline) 1px solid;
- border-radius: 10px;
- margin-top: 1em;
- margin-bottom: 1em;
+ width: 100%;
+ min-height: 300px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border: var(--theme-subtle-outline) 1px solid;
+ border-radius: 10px;
+ margin-top: 1em;
+ margin-bottom: 1em;
}
.Hotspot {
- background: #fff;
- border-radius: 32px;
- border: 0;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25);
- box-sizing: border-box;
- cursor: pointer;
- height: 15px;
- padding: 8px;
- position: relative;
- transition: opacity 0.3s;
- width: 15px;
- }
-
- .Hotspot:not([data-visible]) {
- background: transparent;
- border: 4px solid #fff;
- box-shadow: none;
- height: 32px;
- pointer-events: none;
- width: 32px;
- }
-
- .Hotspot:focus {
- border: 4px solid rgb(0, 128, 200);
- height: 32px;
- outline: none;
- width: 32px;
- }
-
- .Hotspot > * {
- opacity: 1;
- transform: translateY(-50%);
- }
-
- .HotspotAnnotation{
- background: #fff;
- border-radius: 4px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25);
- color: rgba(0, 0, 0, 0.8);
- display: block;
- font-family: Futura, Helvetica Neue, sans-serif;
- font-size: 12px;
- font-weight: 700;
- left: calc(100% + 2em);
- max-width: 128px;
- overflow-wrap: break-word;
- padding: 0.5em 1em;
- position: absolute;
- top: 50%;
- width: max-content;
- }
+ background: #fff;
+ border-radius: 32px;
+ border: 0;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25);
+ box-sizing: border-box;
+ cursor: pointer;
+ height: 15px;
+ padding: 8px;
+ position: relative;
+ transition: opacity 0.3s;
+ width: 15px;
+}
- .left.HotspotAnnotation {
- right: calc(100% + 2em);
- left: unset;
- }
-
- .Hotspot:not([data-visible]) > * {
- opacity: 0;
- pointer-events: none;
- transform: translateY(calc(-50% + 4px));
- transition: transform 0.3s, opacity 0.3s;
- }
-
-
\ No newline at end of file
+.Hotspot:not([data-visible]) {
+ background: transparent;
+ border: 4px solid #fff;
+ box-shadow: none;
+ height: 32px;
+ pointer-events: none;
+ width: 32px;
+}
+
+.Hotspot:focus {
+ border: 4px solid rgb(0, 128, 200);
+ height: 32px;
+ outline: none;
+ width: 32px;
+}
+
+.Hotspot > * {
+ opacity: 1;
+ transform: translateY(-50%);
+}
+
+.HotspotAnnotation {
+ background: #fff;
+ border-radius: 4px;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25);
+ color: rgba(0, 0, 0, 0.8);
+ display: block;
+ font-family: Futura, Helvetica Neue, sans-serif;
+ font-size: 12px;
+ font-weight: 700;
+ left: calc(100% + 2em);
+ max-width: 128px;
+ overflow-wrap: break-word;
+ padding: 0.5em 1em;
+ position: absolute;
+ top: 50%;
+ width: max-content;
+}
+
+.left.HotspotAnnotation {
+ right: calc(100% + 2em);
+ left: unset;
+}
+
+.Hotspot:not([data-visible]) > * {
+ opacity: 0;
+ pointer-events: none;
+ transform: translateY(calc(-50% + 4px));
+ transition: transform 0.3s, opacity 0.3s;
+}
+
+// For the 3D model viewer
+model-viewer {
+ width: 100%;
+ height: 300px;
+}
diff --git a/_sass/nav.scss b/_sass/nav.scss
index d784bfd..84cef01 100644
--- a/_sass/nav.scss
+++ b/_sass/nav.scss
@@ -1,31 +1,24 @@
nav {
- display: flex;
- flex-direction: column;
+ display: flex;
+ flex-direction: column;
}
.current {
- color: darkslategray;
- }
-
-@media (prefers-color-scheme: dark) {
- .current {
- color: lightslategray;
- }
+ color: var(--theme-highlight-color);
}
-@media
- only screen and (max-width: $horizontal_breakpoint),
- only screen and (max-height: $vertical_breakpoint)
- {
- nav.page-table-of-contents {
- white-space: normal;
- justify-content: left;
- text-align: left;
- ul {padding-left: 0em;}
- li li {
- padding-right: 0em;
- padding-left: 2em;
- }
-
+@media only screen and (max-width: $horizontal_breakpoint),
+ only screen and (max-height: $vertical_breakpoint) {
+ nav.page-table-of-contents {
+ white-space: normal;
+ justify-content: left;
+ text-align: left;
+ ul {
+ padding-left: 0em;
}
-}
\ No newline at end of file
+ li li {
+ padding-right: 0em;
+ padding-left: 2em;
+ }
+ }
+}
diff --git a/_sass/night_mode_toggle.scss b/_sass/night_mode_toggle.scss
new file mode 100644
index 0000000..61d41b4
--- /dev/null
+++ b/_sass/night_mode_toggle.scss
@@ -0,0 +1,31 @@
+.no-js .user-toggle {
+ display: none;
+}
+
+.user-toggle {
+ padding-top: 0.5rem;
+}
+
+.toggle-button {
+ width: 1.5rem;
+ height: 1.5rem;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 50%;
+ color: var(--theme-text-color);
+ background: var(--theme-background-color);
+ border: 1.5px solid var(--theme-text-color);
+ transition: background 500ms ease-in-out, color 200ms ease;
+}
+
+.toggle-button__icon {
+ background: var(--button-icon);
+ width: 0.9rem;
+ height: 0.9rem;
+ flex-shrink: 0;
+ margin: 0;
+ transform: translateY(0px); /* Optical adjustment */
+ transition: filter 200ms ease-in-out;
+ filter: var(--button-icon-filter);
+}
diff --git a/_sass/projects.scss b/_sass/projects.scss
index aa31647..681f528 100644
--- a/_sass/projects.scss
+++ b/_sass/projects.scss
@@ -1,48 +1,27 @@
article.project {
- display: flex;
- justify-content: flex-start;
- align-items: flex-start;
- flex-wrap: nowrap;
- flex-direction: row;
+ display: flex;
+ justify-content: flex-start;
+ align-items: flex-start;
+ flex-wrap: nowrap;
+ flex-direction: row;
- h2 {margin-top: 0;}
+ h2 {
+ margin-top: 0;
+ }
- a.photo {
- width: $thumbnail_image_size;
- height: $thumbnail_image_size;
- margin-right: 1em;
- }
-
- img {
- max-height: $thumbnail_image_size;
- width: unset;
- aspect-ratio: 1 / 1;
- }
- figure {
- padding: 0;
- justify-content: center;
- }
+ a.photo {
+ width: $thumbnail_image_size;
+ height: $thumbnail_image_size;
+ margin-right: 1em;
+ }
+
+ img {
+ max-height: $thumbnail_image_size;
+ width: unset;
+ aspect-ratio: 1 / 1;
+ }
+ figure {
+ padding: 0;
+ justify-content: center;
+ }
}
-
-// @media
-// only screen and (max-width: $horizontal_breakpoint),
-// only screen and (max-height: $vertical_breakpoint)
-// {
-// main {
-// padding-top: 10px;
-// padding-left: 20px;
-// padding-right: 20px;
-// margin: 0px;
-// }
-
-// article {
-// margin-left: 0px;
-// }
-
-// h1 {font-size: 1.5em !important;}
-// .MathJax {
-// font-size: 0.8em !important;
-// overflow-x: auto;
-// overflow-y: hidden;
-// }
-// }
\ No newline at end of file
diff --git a/assets/js/index.js b/assets/js/index.js
index 8ad0d30..a8a440b 100644
--- a/assets/js/index.js
+++ b/assets/js/index.js
@@ -1,18 +1,79 @@
function toggle_summary_by_class(element, topic) {
- details = document.querySelectorAll(`details.${topic}`);
+ details = document.querySelectorAll(`details.${topic}`);
- if(element.textContent === "Expand all") {
- element.textContent = "Collapse all";
- details.forEach(e => e.open = true);
- } else {
- element.textContent = "Expand all"
- details.forEach(e => e.open = false);
- }
-
+ if (element.textContent === "Expand all") {
+ element.textContent = "Collapse all";
+ details.forEach((e) => (e.open = true));
+ } else {
+ element.textContent = "Expand all";
+ details.forEach((e) => (e.open = false));
+ }
}
+// Signal that we have JS enabled
+document.documentElement.classList.remove("no-js");
+
// This signals to css that we have support for web components
// Allows us to set elements to act as fallbacks when js/web components are disabled.
if (window.customElements) {
- document.querySelector('body').classList.add('has-wc');
-}
\ No newline at end of file
+ document.querySelector("body").classList.add("has-wc");
+}
+
+// run the night mode toggle
+const STORAGE_KEY = "user-color-scheme";
+const COLOR_MODE_KEY = "--color-mode";
+
+const modeToggleButton = document.querySelector(".js-mode-toggle");
+const modeStatusElement = document.querySelector(".js-mode-status");
+
+const getCSSCustomProp = (propKey) => {
+ let response = getComputedStyle(document.documentElement).getPropertyValue(
+ propKey
+ );
+
+ if (response.length) {
+ response = response.replace(/\"/g, "").trim();
+ }
+
+ return response;
+};
+
+const applySetting = (passedSetting) => {
+ let currentSetting = passedSetting || localStorage.getItem(STORAGE_KEY);
+
+ if (currentSetting) {
+ document.documentElement.setAttribute(
+ "data-user-color-scheme",
+ currentSetting
+ );
+ }
+};
+
+const toggleSetting = () => {
+ let currentSetting = localStorage.getItem(STORAGE_KEY);
+
+ switch (currentSetting) {
+ case null:
+ currentSetting =
+ getCSSCustomProp(COLOR_MODE_KEY) === "dark" ? "light" : "dark";
+ break;
+ case "light":
+ currentSetting = "dark";
+ break;
+ case "dark":
+ currentSetting = "light";
+ break;
+ }
+
+ localStorage.setItem(STORAGE_KEY, currentSetting);
+
+ return currentSetting;
+};
+
+modeToggleButton.addEventListener("click", (evt) => {
+ evt.preventDefault();
+
+ applySetting(toggleSetting());
+});
+
+applySetting();
diff --git a/ruff.toml b/ruff.toml
new file mode 100644
index 0000000..aa033d0
--- /dev/null
+++ b/ruff.toml
@@ -0,0 +1 @@
+line-length = 60
\ No newline at end of file