summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/OpenMoji.astro15
-rw-r--r--src/content/posts/apr_29_2026.md72
-rw-r--r--src/layouts/BaseLayout.astro50
-rw-r--r--src/pages/index.astro70
-rw-r--r--src/pages/posts/index.astro4
-rw-r--r--src/pages/resume.astro50
-rw-r--r--src/pages/tech.astro25
-rw-r--r--src/styles/index.css259
-rw-r--r--src/styles/post.css1
-rw-r--r--src/styles/resume.css176
-rw-r--r--src/styles/resume.mobile.css12
-rw-r--r--src/styles/sitemap.css68
12 files changed, 426 insertions, 376 deletions
diff --git a/src/components/OpenMoji.astro b/src/components/OpenMoji.astro
new file mode 100644
index 0000000..9fd581d
--- /dev/null
+++ b/src/components/OpenMoji.astro
@@ -0,0 +1,15 @@
+---
+import { readFileSync } from 'fs';
+import { fileURLToPath } from 'url';
+import { join, dirname } from 'path';
+
+interface Props { code: string; alt: string; size?: string; }
+const { code, alt, size = '1.2em' } = Astro.props;
+
+const svgPath = join(
+ dirname(fileURLToPath(import.meta.url)),
+ `../../node_modules/openmoji/color/svg/${code}.svg`
+);
+const svg = readFileSync(svgPath, 'utf-8');
+---
+<span class="openmoji" role="img" aria-label={alt} style={`width:${size};height:${size};display:inline-flex;vertical-align:middle`} set:html={svg} />
diff --git a/src/content/posts/apr_29_2026.md b/src/content/posts/apr_29_2026.md
new file mode 100644
index 0000000..e504ea6
--- /dev/null
+++ b/src/content/posts/apr_29_2026.md
@@ -0,0 +1,72 @@
+---
+title: "Update April 29, 2026"
+date: "2026-04-29"
+tags: ["update"]
+---
+
+## What have I been up to?
+
+Miracle v0.9.0 is released: https://github.com/miracle-wm-org/miracle-wm/releases/tag/v0.9.0 πŸͺ!
+This release was a long, long time in the making, so I am very excited to
+finally get it out the door. It introduces the new WebAssembly-based plugin
+system for window management, configuration and more. I daily drive Miracle and
+feel entirely at home inside of it, and I hope you do too!
+
+On the Mir side of things, I have been busy rewriting our dependency on
+libwayland in [wayland-rs](https://github.com/Smithay/wayland-rs) instead. This
+has been an *absolute whirlwhind* of an exercise, and I'm sure it's something
+that the team will want write about officially later on. https://cxx.rs/ has
+been amazing in the meantime, but the interactions between C++ and Rust -
+especially in terms of lifetime managemen and standard library coherence - are
+quite difficult to deal with.
+
+In Flutter land, all is moving smoothly. The multi-window effort is continuing
+as expected, and we're even starting to land some windowing concepts in the
+Material API, which is exciting. Look out for `showDialog` creating a *true*
+dialog window sometime soon!
+
+## AI, AI, AI...
+
+I've finally been swept up in the mass psychosis that is AI in the software
+industry. Like everyone else, I'm constantly shifting back and forth between
+"Wow, what magic!" and "Why am I trying to coerce this machine into doing
+something that I already know how to do". For straighforward things that are not
+very "interesting" in the technical sense, it's amazing. For example, I prompted
+Claude to convert this website to astro.js in basically a single prompt with a bit
+of hand-holding. That's pretty incredible seeing as I wouldn't have been
+motivated to do that prior to this. On the other hand, Claude has been next to
+useless for my work migrating parts of Mir from C++ to Rust. I am probably one
+of a handful of people in the world doing that on a large product, so it is
+hardly represented in the data set. As a result, Claude takes forever to
+reason about even simple things, and it even tends to get those wrong.
+Especially when it comes to metaprogramming, it tends to fall apart as that
+involves a lot of higher level, abstract thinking.
+
+All this goes to say: AI is generally useful, but I expect to find gainful employment
+for the forseeable future. I think that certain areas of software development
+that are particularly well-represented in the training set will be largely
+automateable. If you've noticed, everybody and their parents are busy building
+new "dashboards" for just about every piece of data under the sun. I don't think
+that this is an accident. Dashboards are probably the most well-represented and
+most straightforward problem to solve in computing currently. Data goes in, it
+gets shown, and maybe it gets compared to other data. That's about it. On the
+other hand, I don't think we'll be seeing any AI-generated MMORPGs anytime soon.
+
+That being said, I'll keep using Claude to find the edges of its capability, but
+I'll keep using my ol' noggin to do the interesting stuff that requires
+second-order thinking.
+
+## One final point: AI Design
+
+I understand that it is tempting to accept the initial design that the AI gives
+you, but it's really starting to bug me. Here are some hallmarks of the design:
+
+- Gradient text with letter-spacing changed
+- Animated Hero with some tech-y feel
+- Gradient box shadow
+- Solid color text on a background of the same color but with opacity
+- Traffic light fake toolbars to make it look like a MacOS app
+
+That probably sums it up poorly, but I know it when I see it. It's turning into
+the Ikea desing of websites: it's not bad, but it makes me think that you're not
+that invested in the long-term quality of your site.
diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro
index 57077ec..a2f0f77 100644
--- a/src/layouts/BaseLayout.astro
+++ b/src/layouts/BaseLayout.astro
@@ -1,5 +1,6 @@
---
import '../styles/index.css';
+import OpenMoji from '../components/OpenMoji.astro';
interface Props {
title: string;
@@ -37,19 +38,32 @@ const {
</script>
</head>
<body>
+ <div id="theme_container">
+ <canvas id="theme_canvas"></canvas>
+ </div>
<header>
- <nav>
+ <button id="hamburger" aria-label="Open menu"><OpenMoji code="1F354" alt="menu" /></button>
+ <nav id="nav-menu">
+ <button id="nav-close" aria-label="Close menu"><OpenMoji code="274C" alt="close" /></button>
<ul>
- <li><a href='/'>&#127969; Home</a></li>
- <li><a href='/resume'>&#128216; CV</a></li>
- <li><a href='/posts'>&#128221; Posts</a></li>
- <li style="margin-left: auto">
- <button id="theme-toggle" aria-label="Toggle color theme">Dark</button>
+ <li><a href='/'><OpenMoji code="1F3E1" alt="home" /> Home</a></li>
+ <li><a href='/resume'><OpenMoji code="1F4D8" alt="cv" /> CV</a></li>
+ <li><a href='/posts'><OpenMoji code="1F4DD" alt="posts" /> Posts</a></li>
+ <li><a href='/tech'><OpenMoji code="1F4BB" alt="laptop" /> Tech</a></li>
+ <li style="margin-left: auto"><button id="theme_button_default"><OpenMoji code="1F642" alt="smiley" /></button></li>
+ <li><button id="theme_button_autumn"><OpenMoji code="1F341" alt="maple leaf" /></button></li>
+ <li><button id="theme_button_winter"><OpenMoji code="26C4" alt="snowman" /></button></li>
+ <li><button id="theme_button_spring"><OpenMoji code="1F426" alt="bird" /></button></li>
+ <li><button id="theme_button_summer"><OpenMoji code="1F33B" alt="sunflower" /></button></li>
+ <li style="margin-left: 1rem">
+ <button id="theme-toggle" aria-label="Toggle color theme"><OpenMoji code="1F317" alt="theme" /> <span id="theme-label">Dark</span></button>
</li>
</ul>
</nav>
+ <div id="nav-overlay"></div>
</header>
<slot />
+ <script is:inline src="/themes/dist/output.js"></script>
<script is:inline>
(function() {
var btn = document.getElementById('theme-toggle');
@@ -68,7 +82,7 @@ const {
}
function updateButton(theme) {
- btn.textContent = theme === 'dark' ? 'πŸŒ— Light' : 'πŸŒ— Dark';
+ document.getElementById('theme-label').textContent = theme === 'dark' ? 'Light' : 'Dark';
}
updateButton(getCurrentTheme());
@@ -78,5 +92,27 @@ const {
});
})();
</script>
+ <script is:inline>
+ (function() {
+ var hamburger = document.getElementById('hamburger');
+ var nav = document.getElementById('nav-menu');
+ var close = document.getElementById('nav-close');
+ var overlay = document.getElementById('nav-overlay');
+
+ function openMenu() {
+ nav.classList.add('open');
+ overlay.classList.add('open');
+ }
+
+ function closeMenu() {
+ nav.classList.remove('open');
+ overlay.classList.remove('open');
+ }
+
+ hamburger.addEventListener('click', openMenu);
+ close.addEventListener('click', closeMenu);
+ overlay.addEventListener('click', closeMenu);
+ })();
+ </script>
</body>
</html>
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 5ef947e..5f7e321 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -1,46 +1,40 @@
---
import BaseLayout from '../layouts/BaseLayout.astro';
+import OpenMoji from '../components/OpenMoji.astro';
---
<BaseLayout title="Matthew Kosarek" description="The personal website of Matthew Kosarek">
- <div id="theme_container">
- <canvas id="theme_canvas"></canvas>
- </div>
-
- <section>
- <h2>About Me</h2>
- <p>
- Hi there 🌊 My name is Matthew Kosarek.
- I am a computer programmer from northern New Jersey and I currently live in Philadelphia, PA. I work at Canonical on
- <a href="https://github.com/canonical/mir">Mir</a> and I am currently building
- <a href="https://github.com/miracle-wm-org/miracle-wm">miracle-wm</a>, a Mir-based tiling window manager.
- </p>
- </section>
- <section>
- <h2>Links</h2>
- <ul>
- <li><a href="https://github.com/mattkae">Github</a>: my personal github with most of my projects</li>
- <li><a href="https://git.matthewkosarek.xyz">CGit</a>: my self-hosted git instance with a few of my projects</li>
- <li style="display: none;"><a href="https://physicsforgames.com">physicsforgames.com</a>: a project that I'm currently working on in my spare time where I explore the world of realtime physics</li>
- <li><a href="https://www.linkedin.com/in/matthew-kosarek/">LinkedIn</a></li>
- </ul>
- </section>
+ <div class="index-layout">
+ <aside class="sidebar">
+ <ul>
+ <li><a href="https://github.com/mattkae">Github</a><span>my personal github with most of my projects</span></li>
+ <li><a href="https://git.matthewkosarek.xyz">CGit</a><span>my self-hosted git instance with a few of my projects</span></li>
+ <li style="display: none;"><a href="https://physicsforgames.com">physicsforgames.com</a><span>a project that I'm currently working on in my spare time where I explore the world of realtime physics</span></li>
+ <li><a href="https://www.linkedin.com/in/matthew-kosarek/">LinkedIn</a><span>corporate goings-ons</span></li>
+ <li><a href="mailto:matthew@matthewkosarek.xyz">Email</a><span>matthew@matthewkosarek.xyz</span></li>
+ </ul>
+ </aside>
- <section id="theme_section">
- <div id="theme_selector">
- <button id="theme_button_default">πŸ™‚<span class="theme_button_text">Default</span></button>
- <button id="theme_button_autumn">🍁<span class="theme_button_text">Autumn</span></button>
- <button id="theme_button_winter">β›„<span class="theme_button_text">Winter</span></button>
- <button id="theme_button_spring">🐦<span class="theme_button_text">Spring</span></button>
- <button id="theme_button_summer">🌻<span class="theme_button_text">Summer</span></button>
+ <div class="index-main">
+ <section>
+ <p>
+ Hi there <OpenMoji code="1F30A" alt="wave" />
+ </p>
+ <p>
+ My name is Matthew Kosarek.
+ I am a computer programmer from northern New Jersey and I currently live in Philadelphia, PA. I work at Canonical on
+ <a href="https://github.com/canonical/mir">Mir</a> and <a href="https://github.com/flutter/flutter">Flutter</a>. I
+ have a strong interest in C++, Computer Graphics, Rust, and Linux.
+ <p/>
+ <p>
+ In my spare time, I work on <a href="https://github.com/miracle-wm-org/miracle-wm">miracle-wm</a>, a Mir-based
+ window manager that features manual tiling and a WebAssembly-powered plugin system for window management and beyond.
+ </p>
+ <p>
+ Off the computer, you can find me surfing, walking my dog, or hanging out with my fiancee and friends in Philly. I
+ also have 3 cats!
+ </p>
+ </section>
</div>
- </section>
-
- <script>
- function main() {
- }
-
- main();
- </script>
- <script is:inline src="/themes/dist/output.js"></script>
+ </div>
</BaseLayout>
diff --git a/src/pages/posts/index.astro b/src/pages/posts/index.astro
index b3ea740..447384c 100644
--- a/src/pages/posts/index.astro
+++ b/src/pages/posts/index.astro
@@ -28,7 +28,9 @@ function formatDate(dateStr: string): string {
<li data-tags={post.data.tags.join(',')}>
<p><a href={`/posts/${post.slug}`}>{post.data.title}</a></p>
<div class="sitemap_date"><p>{formatDate(post.data.date)}</p></div>
- <div class="sitemap_tag"><p>{post.data.tags.join(',')}</p></div>
+ {post.data.tags.map((tag: string) => (
+ <div class="sitemap_tag"><p>{tag}</p></div>
+ ))}
</li>
))}
</ul>
diff --git a/src/pages/resume.astro b/src/pages/resume.astro
index b8bf02b..afe9244 100644
--- a/src/pages/resume.astro
+++ b/src/pages/resume.astro
@@ -8,47 +8,7 @@ import '../styles/resume.mobile.css';
title="Matthew Kosarek - Resume"
description="The hosted resume of Matthew Kosarek"
>
- <script>
- function main() {
- var fullScreenButton = document.getElementById('full_screen_button'),
- resumeContainer = document.getElementById('resume');
-
- fullScreenButton.addEventListener('click', function() {
- resumeContainer.classList.toggle('resume_fullscreen');
- });
- }
-
- window.onload = main;
- </script>
-
<main id='resume'>
- <div id='resume_button_container'>
- <button id='full_screen_button' title='Toggle Fullscreen'>
- &#9974;
- </button>
- <a href='download/cv.pdf' download title='Download as PDF'>
- &#128229;
- </a>
- </div>
- <div id="resume_container">
- <header id="resume_sidebar">
- <div id="resume_header">
- <span class="resume_header_name">Matthew</br> Kosarek</span>
-
- <div id="resume_header_contact">
- <span><i>πŸ–₯️</i> Software Developer</span>
- <span><i>πŸ”—</i> <a href="https://matthewkosarek.xyz">matthewkosarek.xyz</a></span>
- <span>
- <i><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg></i>
- <a href="https://github.com/mattkae">github.com/mattkae</a></span>
- </span>
- <span><i>πŸ“§</i> mkosare1@gmail.com</span>
- <span><i>πŸ‡ΊπŸ‡Έ</i> United States Citizen</span>
- </div>
- </div>
- </header>
-
- <main>
<section class='resume_section'>
<h2>Experience</h2>
<div class="resume_section_content">
@@ -68,7 +28,10 @@ import '../styles/resume.mobile.css';
</div>
<ul>
<li>
- Working on <a href="https://github.com/MirServer/Mir" target="_blank">Mir</a>, a Wayland compositor
+ Contributed exstensively to <a href="https://github.com/MirServer/Mir" target="_blank">Mir</a>, a C++ library for Wayland compositors
+ </li>
+ <li>
+ Implemented multi-window support in <a href="https://github.com/flutter/flutter" target="_blank">Flutter</a> for Win32, Linux, and MacOS
</li>
</ul>
</div>
@@ -213,13 +176,10 @@ import '../styles/resume.mobile.css';
<section class="resume_section">
<h2>Projects</h2>
<ul>
+ <li>Author of <b><a href="https://github.com/miracle-wm-org/miracle-wm">miracle-wm</a></b>, a hackable Wayland window manager</li>
<li>My <b>self-hosted personal website</b> where I do small projects in WebAssembly and OpenGL: <a href="https://matthewkosarek.xyz">matthewkosarek.xyz</a></li>
<li>A <b>game engine</b> that I built in C++ and OpenGL: <a href="https://github.com/mattkae/MatteEngine">github.com/mattkae/MatteEngine</a></li>
- <li>My <b>self-installing emacs configuration</b>: <a href="https://git.matthewkosarek.xyz/emacs_config/">git.matthewkosarek.xyz/emacs_config/</a></li>
- <li>Unfinished website about <b>realtime physics in video games</b>: <a href="https://physicsforgames.com/">physicsforgames.com/</a></li>
</ul>
</section>
- </main>
- </div>
</main>
</BaseLayout>
diff --git a/src/pages/tech.astro b/src/pages/tech.astro
new file mode 100644
index 0000000..1f554aa
--- /dev/null
+++ b/src/pages/tech.astro
@@ -0,0 +1,25 @@
+---
+import BaseLayout from '../layouts/BaseLayout.astro';
+---
+
+<BaseLayout title="Tech I Like - Matthew Kosarek" description="Tech that Matthew Kosarek likes and uses">
+ <div class="index-layout">
+ <div class="index-main">
+ <section>
+ <h2>Things I Use</h2>
+ <h3>For Development</h3>
+ <ul>
+ <li><b>My dotfiles</b>: I use everything in my dotfiles every day, which you can find <a href="https://github.com/mattkae/dotfiles">here</a></li>
+ <li><a href="https://www.gnu.org/software/emacs/">Emacs</a>: I am a long-time Emacs user. You can find my config <a href="https://git.matthewkosarek.xyz/emacs_config/">here</a></li>
+ <li><a href="https://www.jetbrains.com/clion/">Clion</a>: I use this for my coproate life, although it is quite heavy</li>
+ <li><a href="https://astro.build/">astro</a>: super simple SSG that I use constantly</li>
+ </ul>
+ <h3>For Lifestyle</h3>
+ <ul>
+ <li><a href="https://orgmode.org/">Org Mode</a>: for calendar, todo lists, notes, and more!</li>
+ <li><a href="https://newsboat.org/">Newsboat</a>: RSS reader</li>
+ </ul>
+ </section>
+ </div>
+ </div>
+</BaseLayout>
diff --git a/src/styles/index.css b/src/styles/index.css
index 3856449..70c0f1b 100644
--- a/src/styles/index.css
+++ b/src/styles/index.css
@@ -1,7 +1,7 @@
:root {
--bg: transparent;
--color: black;
- --link-color: darkviolet;
+ --link-color: #525dd7;
--image-border: rgba(0, 0, 0, 0.3);
--image-border-hover: rgba(0, 0, 0, 0.7);
--image-overlay: rgba(0, 0, 0, 0.7);
@@ -16,7 +16,7 @@
:root:not([data-theme="light"]) {
--bg: rgba(13, 17, 23, 0.92);
--color: #e6edf3;
- --link-color: #b083f0;
+ --link-color: #848DF0;
--image-border: rgba(255, 255, 255, 0.2);
--image-border-hover: rgba(255, 255, 255, 0.5);
--image-overlay: rgba(0, 0, 0, 0.85);
@@ -43,10 +43,10 @@
}
body {
- width: 50vw;
+ width: 60vw;
height: calc(100vh - 2rem);
font-family: "Noto Sans", 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
- font-size: 14px;
+ font-size: 16px;
background-color: var(--bg);
color: var(--color);
padding: 0;
@@ -67,8 +67,8 @@ header > h1 {
header > nav {
margin-top: 1rem;
- margin-bottom: 1rem;
- padding-left: 0.25rem;
+ padding-bottom: 1rem;
+ border-bottom: 4px dotted var(--theme-btn-border);
}
header > nav > ul {
@@ -85,16 +85,13 @@ header > nav > ul > li {
align-items: center;
}
-header > nav > ul a {
- text-decoration: none;
- color: var(--link-color);
- font-size: 1rem;
- border-bottom: 1px solid transparent;
+nav .openmoji {
+ width: 1.5rem !important;
+ height: 1.5rem !important;
}
-header > nav > ul a:hover {
- opacity: 0.8;
- text-decoration: underline;
+header > nav > ul a {
+ font-size: 1rem;
}
h1 {
@@ -111,6 +108,53 @@ section {
width: 100%;
}
+/* Index page sidebar layout */
+.index-layout {
+ display: flex;
+ gap: 2rem;
+}
+
+.sidebar {
+ margin-top: 1rem;
+ min-width: 140px;
+ max-width: 220px;
+ position: sticky;
+ top: 1rem;
+ align-self: flex-start;
+}
+
+.sidebar h2 {
+ margin-top: 0.5rem;
+ font-size: 1rem;
+}
+
+.sidebar ul {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.sidebar ul li {
+ margin-bottom: 0.5rem;
+}
+
+.sidebar ul li a {
+ font-weight: 600;
+ display: block;
+}
+
+.sidebar ul li span {
+ display: block;
+ font-size: 0.8rem;
+ opacity: 0.7;
+ margin-top: 0.1rem;
+}
+
+.index-main {
+ flex: 1;
+ min-width: 0;
+}
+
p {
text-align: left;
}
@@ -126,12 +170,8 @@ a:hover {
/* Theme toggle button */
#theme-toggle {
background: none;
- border: 1px solid var(--theme-btn-border);
- color: var(--link-color);
- border-radius: 3px;
- padding: 0.1rem 0.5rem;
cursor: pointer;
- font-size: 0.85rem;
+ font-size: 1rem;
font-family: inherit;
}
@@ -232,67 +272,54 @@ input:focus {
z-index: -1;
}
-/* Theme Selector */
-#theme_section {
- position: fixed;
- bottom: 1rem;
- left: 0;
- width: 100%;
- text-align: center;
-}
-
-#theme_selector {
- display: flex;
- align-items: center;
- justify-content: center;
- bottom: 1rem;
- pointer-events: all;
- opacity: 1;
- transition: opacity 150ms linear;
- gap: 2rem;
-}
-
-#theme_selector.hidden {
- pointer-events: none;
- opacity: 0;
-}
-
-#theme_selector > button {
- width: 6rem;
- height: 2rem;
- border-radius: 3px;
- border: 1px solid var(--theme-btn-border);
- color: var(--theme-btn-color);
- background-color: var(--theme-btn-bg);
- cursor: pointer;
- transition: opacity 100ms linear;
-}
-
-#theme_selector > button:hover {
- opacity: 0.8;
-}
-
-#theme_selector > #theme_button_default {
+/* Season theme buttons (in nav) */
+#theme_button_default,
+#theme_button_autumn,
+#theme_button_winter,
+#theme_button_spring,
+#theme_button_summer {
+ background: none;
+ color: var(--theme-btn-color);
+ cursor: pointer;
+ font-size: 1rem;
+ font-family: inherit;
+ transition: opacity 100ms linear;
}
-#theme_selector > #theme_button_autumn {
- background-color: orange;
+#theme_button_default:hover,
+#theme_button_autumn:hover,
+#theme_button_winter:hover,
+#theme_button_spring:hover,
+#theme_button_summer:hover {
+ opacity: 0.8;
}
-#theme_selector > #theme_button_winter {
- background-color: #79C0D7;
-}
-#theme_selector > #theme_button_spring {
- background-color: #00FF7F;
+/* Hamburger menu - hidden on desktop */
+#hamburger {
+ display: none;
+ background: none;
+ border: none;
+ font-size: 1.75rem;
+ cursor: pointer;
+ color: var(--color);
+ padding: 1rem;
+ margin-left: auto;
}
-#theme_selector > #theme_button_summer {
- background-color: yellow;
+#nav-close {
+ display: none;
+ background: none;
+ border: none;
+ font-size: 1.75rem;
+ cursor: pointer;
+ color: var(--color);
+ align-self: flex-end;
+ padding: 1rem;
}
-.theme_button_text {
- margin-left: 0.5rem;
+#nav-overlay {
+ display: none;
}
/* Phone screen adjustments */
@@ -304,23 +331,21 @@ only screen and (max-width:1280px) {
body {
width: 80vw !important;
+ overflow-x: hidden;
}
-}
-@media only screen and (device-width: 960px),
-only screen and (max-width:960px) {
- #theme_selector {
- margin-left: 1rem;
- margin-right: 1rem;
- }
- .theme_button_text {
- display: none;
+ .index-layout {
+ flex-direction: column;
+ gap: 0;
}
- #theme_selector > button {
- width: 100%;
+ .sidebar {
+ position: static;
}
+}
+@media only screen and (device-width: 960px),
+only screen and (max-width:960px) {
.image_item_expanded_container > .image_item {
width: 80vw;
}
@@ -329,4 +354,74 @@ only screen and (max-width:960px) {
font-size: 6rem;
top: calc(50% - 4rem);
}
+
+ #hamburger {
+ display: block;
+ position: fixed;
+ top: 0.5rem;
+ right: 5rem;
+ z-index: 1002;
+ padding: 0.5rem;
+ }
+
+ #nav-close {
+ display: block;
+ }
+
+ #nav-menu {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100vw;
+ height: 100vh;
+ background: var(--theme-btn-bg, white);
+ z-index: 1001;
+ padding: 0 10vw;
+ margin-top: 0;
+ display: flex;
+ flex-direction: column;
+ transform: translateX(100%);
+ transition: transform 0.25s ease;
+ box-sizing: border-box;
+ }
+
+ #nav-menu.open {
+ transform: translateX(0);
+ }
+
+ header:has(#nav-menu.open) #hamburger {
+ display: none;
+ }
+
+ #nav-menu > ul {
+ flex-direction: column;
+ gap: 0.5rem;
+ }
+
+ #nav-menu > ul > li {
+ width: 100%;
+ }
+
+ #nav-menu > ul > li[style*="margin-left: auto"] {
+ margin-left: 0 !important;
+ margin-top: 1rem;
+ }
+
+ #nav-menu > ul > li[style*="margin-left: 1rem"] {
+ margin-left: 0 !important;
+ }
+
+ #nav-menu > ul button,
+ #nav-menu > ul a {
+ width: 100%;
+ text-align: center;
+ }
+
+ header > nav {
+ border-bottom: none;
+ }
+
+ #nav-overlay {
+ display: none;
+ }
}
diff --git a/src/styles/post.css b/src/styles/post.css
index 33b8729..a7e84c9 100644
--- a/src/styles/post.css
+++ b/src/styles/post.css
@@ -60,6 +60,7 @@ code {
}
.org-article-title {
+ margin-top: 1rem;
display: flex;
flex-direction: row;
justify-content: space-between;
diff --git a/src/styles/resume.css b/src/styles/resume.css
index 3cbf769..97e504e 100644
--- a/src/styles/resume.css
+++ b/src/styles/resume.css
@@ -1,127 +1,19 @@
-@font-face {
- font-family: Ubuntu;
- src: url(/fonts/Ubuntu-M.ttf);
- }
-
-:root {
- --resume-bg: white;
- --resume-color: black;
- --resume-link-color: #343231;
- --resume-section-bg: #583759;
- --resume-section-color: white;
- --skills-bar-bg: white;
- --skills-table-border: gray;
- --skills-table-inner-border: lightgray;
- --skills-table-th-color: #2E4C6D;
- --experience-hover-color: #583759;
-}
-
-@media (prefers-color-scheme: dark) {
- :root:not([data-theme="light"]) {
- --resume-bg: #161b22;
- --resume-color: #e6edf3;
- --resume-link-color: #8b949e;
- --resume-section-bg: #3d2b5e;
- --resume-section-color: #e6edf3;
- --skills-bar-bg: #21262d;
- --skills-table-border: #444c56;
- --skills-table-inner-border: #30363d;
- --skills-table-th-color: #79b8ff;
- --experience-hover-color: #b083f0;
- }
-}
-
-[data-theme="dark"] {
- --resume-bg: #161b22;
- --resume-color: #e6edf3;
- --resume-link-color: #8b949e;
- --resume-section-bg: #3d2b5e;
- --resume-section-color: #e6edf3;
- --skills-bar-bg: #21262d;
- --skills-table-border: #444c56;
- --skills-table-inner-border: #30363d;
- --skills-table-th-color: #79b8ff;
- --experience-hover-color: #b083f0;
-}
-
html {
overflow-y: overlay;
font-size: 16px;
}
-header {
- padding-bottom: 1rem;
-}
-
-#actions_container {
- padding-bottom: 1rem;
-
- display: flex;
- flex-direction: row;
- justify-content: flex-end;
-}
-
#resume {
position: relative;
text-align: left;
- background-color: var(--resume-bg);
- color: var(--resume-color);
- font-family: 'Ubuntu', Tahoma, Geneva, Verdana, sans-serif;
+ color: var(--color);
line-height: 1.325rem;
-}
-
-#resume_container {
- display: flex;
- flex-direction: row;
+ margin-top: 1rem;;
+ padding-bottom: 4rem;
}
#resume a {
- color: var(--resume-link-color);
-}
-
-#resume_sidebar {
- width: 13rem;
- margin-right: 1.5rem;
-}
-
-#resume_header {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- flex-direction: column;
- align-items: flex-start;
- margin-bottom: 2rem;
-}
-
-.resume_header_name {
- font-size: 2rem;
- line-height: 2rem;
- font-variant: small-caps;
- word-wrap: break-word;
- padding: 0;
- margin: 0;
- margin-bottom: 1rem;
-}
-
-#resume_header_contact {
- margin-top: 1rem;
- display: flex;
- flex-direction: row;
- flex-direction: column;
-}
-
-#resume_header_contact span {
- margin-bottom: 0.5rem;
- font-size: 1rem;
- display: flex;
- flex-direction: row;
- align-items: center;
-}
-
-#resume_header_contact i {
- margin-right: 0.5rem;
- font-style: normal;
+ color: var(--link-color);
}
.resume_section {
@@ -131,18 +23,17 @@ header {
}
.resume_section > h2 {
- font-size: 1.125rem;
+ font-size: 1.25rem;
font-variant: small-caps;
font-weight: bold;
- padding: 0;
- margin: 0;
- padding: 0.25rem;
- background-color: var(--resume-section-bg);
- color: var(--resume-section-color);
+ margin: 0 0 0.5rem 0;
+ padding: 0 0 0.35rem 0;
+ border-bottom: 2px solid var(--link-color);
+ color: var(--color);
}
.resume_section_content {
- padding: 0.5rem;
+ padding: 0.5rem 0;
}
.experience-header > div {
@@ -151,10 +42,6 @@ header {
justify-content: space-between;
}
-.experience-item:hover {
- color: var(--experience-hover-color);
-}
-
.experience-item ul {
margin-top: 0.5rem;
}
@@ -186,7 +73,7 @@ header {
.skills_table {
width: 100%;
border-spacing: 0;
- border: 1px solid var(--skills-table-border);
+ border: 1px solid var(--theme-btn-border);
border-radius: 2px;
margin-bottom: 2rem;
}
@@ -196,11 +83,11 @@ header {
}
.skills_table th, .skills_table tr:not(:last-child) td {
- border-bottom: 1px solid var(--skills-table-inner-border);
+ border-bottom: 1px solid var(--action-button-border);
}
.skills_table tr th {
- color: var(--skills-table-th-color);
+ color: var(--link-color);
}
.skills_table td, th {
@@ -224,9 +111,9 @@ header {
position: relative;
width: 100%;
height: 1rem;
- background-color: var(--skills-bar-bg);
+ background-color: var(--theme-btn-bg);
border-radius: 3px;
- border: 1px solid var(--skills-table-inner-border);
+ border: 1px solid var(--action-button-border);
}
.skills_section_bar_fill {
@@ -263,37 +150,6 @@ header {
.skills_section_label {
width: 100%;
margin-top: 0.25rem;
- color: var(--resume-color);
+ color: var(--color);
font-size: 1rem;
}
-
-
-/** Web-only **/
-#resume_button_container {
- width: 100%;
- text-align: right;
- margin-right: 1rem;
- margin-bottom: 1rem;
-
-}
-
-#resume_button_container > button {
- border: none;
- background-color: transparent;
- font-size: 20px;
-}
-
-#resume_button_container > button:hover {
- cursor: pointer;
- opacity: 0.8;
-}
-
-#resume.resume_fullscreen {
- position: fixed;
- top: 0;
- left: 0;
- padding: 2rem;
- width: calc(100vw - 4rem);
- height: calc(100vh - 4rem);
- overflow: auto;
-}
diff --git a/src/styles/resume.mobile.css b/src/styles/resume.mobile.css
index 016095b..5e0caf9 100644
--- a/src/styles/resume.mobile.css
+++ b/src/styles/resume.mobile.css
@@ -3,18 +3,6 @@
font-size: 12px;
}
- #resume_container {
- flex-direction: column;
- }
-
- #resume_header {
- flex-direction: row;
- }
-
- #resume_sidebar {
- width: 100%;
- }
-
.skills_table_container {
width: 100%;
justify-content: space-evenly;
diff --git a/src/styles/sitemap.css b/src/styles/sitemap.css
index afe3f6a..316de00 100644
--- a/src/styles/sitemap.css
+++ b/src/styles/sitemap.css
@@ -7,13 +7,14 @@
}
.sitemap_tag {
- padding: 0.25rem 0.75rem;
- background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);
- color: #1976d2;
- border-radius: 4px;
+ padding: 0.2rem;
+ background: transparent;
+ color: var(--color);
+ border-radius: 0;
font-size: 0.7rem;
- font-weight: 500;
- border: 1px solid #90caf9;
+ font-style: italic;
+ border: 1.5px solid var(--theme-btn-border);
+ opacity: 0.7;
}
.sitemap_tag p {
@@ -33,19 +34,21 @@
.org-ul > li {
display: flex;
flex-direction: row;
+ flex-wrap: wrap;
align-items: center;
gap: 0.25rem;
position: relative;
- margin-bottom: 0.25rem;
+ margin-bottom: 1rem;
}
.org-ul > li > p {
margin: 0;
font-size: 0.5rem;
+ width: 100%;
}
.org-ul > li > p > a {
- color: #0066cc;
+ color: var(--link-color);
text-decoration: none;
font-weight: 600;
font-size: 1rem;
@@ -53,12 +56,10 @@
.org-ul > li > p > a:hover {
text-decoration: underline;
- color: #004499;
}
.org-ul > li > p > a:after {
text-decoration: underline;
- color: #004499;
}
.org-article-title {
@@ -74,36 +75,30 @@
}
.tag-filter-item {
- display: flex;
- flex-direction: row;
+ display: inline-flex;
align-items: center;
- padding: 0.35rem;
- border-radius: 2px;
- justify-content: center;
- font-style: italic;
- background: linear-gradient(135deg, purple 0%, darkviolet 100%);
- color: white;
+ padding: 0.2rem 0.6rem;
+ background: transparent;
+ color: var(--color);
font-size: 0.75rem;
- letter-spacing: 0.3px;
- transition: all 0.3s ease;
+ font-style: italic;
+ border: 1.5px solid var(--color);
+ cursor: pointer;
+ user-select: none;
+ transition: opacity 0.15s ease;
}
.tag-filter-item:hover {
- background: linear-gradient(135deg, gray 0%, darkviolet 100%);
- cursor: pointer;
+ opacity: 0.7;
}
.tag-filter-item.disabled {
- background: linear-gradient(135deg, #e0e0e0 0%, #c0c0c0 100%);
- color: #666;
- border-color: #999;
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
- opacity: 0.7;
+ opacity: 0.3;
+ text-decoration: line-through;
}
.tag-filter-item.disabled:hover {
- opacity: 1;
- box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
+ opacity: 0.5;
}
.post-date {
@@ -111,14 +106,21 @@
bottom: 0.75rem;
right: 1rem;
font-size: 0.75rem;
- color: #666;
+ color: var(--color);
+ opacity: 0.6;
font-style: italic;
}
+.org-ul > li > .sitemap_date,
+.org-ul > li > .sitemap_tag {
+ display: inline-flex;
+}
+
.sitemap_date {
font-size: 0.8rem;
- color: #666;
+ color: var(--color);
font-style: italic;
+ opacity: 0.6;
}
.sitemap_date p {
@@ -128,3 +130,7 @@
.sitemap_date p::before {
content: 'created on ';
}
+
+.org-ul > li > .sitemap_date + .sitemap_tag {
+ margin-left: 0.75rem;
+}