.
-
-Funnily enough, while writing this post I found , which is maybe the most extreme example of this idea.
-The author of that blog publicly lists a giant catalog of possessions which is very cool but also probably not for everyone.
-So make sure to list the tools you use, so I can steal them to improve myself!
diff --git a/content/posts/thoughts_on_rust.md b/content/posts/thoughts_on_rust.md
index 1e27405..ba70e96 100644
--- a/content/posts/thoughts_on_rust.md
+++ b/content/posts/thoughts_on_rust.md
@@ -1,7 +1,7 @@
---
title: "Rust is pretty good (Short thoughts on Rust)"
date: 2024-04-09T21:31:01-04:00
-tags: ['rust', 'Opinions', 'software development']
+topics: ['rust', 'Opinions', 'software development']
---
In my current position I've had to swap to full time Rust development.
diff --git a/content/posts/tmux_and_nvim.md b/content/posts/tmux_and_nvim.md
index 8b43690..c336f25 100644
--- a/content/posts/tmux_and_nvim.md
+++ b/content/posts/tmux_and_nvim.md
@@ -1,7 +1,7 @@
---
title: "My nvim/tmux workflow"
date: 2024-03-04T21:44:00-05:00
-tags: [software development, neovim, tmux]
+topics: [software development, neovim, tmux]
---
At my previous employment I was forced to use a windows system.
diff --git a/content/posts/upvoters.md b/content/posts/upvoters.md
deleted file mode 100644
index e61232e..0000000
--- a/content/posts/upvoters.md
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: "Upvoters - Small rust back-end for anonymous likes on static blogs"
-date: 2026-03-21T22:47:50-04:00
-tags: ["Rust", "Hugo", "Web Design", "Self-Host"]
----
-
-## Long Story Short
-
-I wrote a little system called [upvoters](https://github.com/aselimov/upvoters) in Rust to handle anonymous upvotes, and it's compatible with Hugo!
-In fact, you should see a little chevron at the bottom of this post to upvote if you like it.
-Check it out if you need something like it!
-
-## Motivation
-
-I've been working on some website refactors/design changes lately.
-My taste has been influenced recently.
-I may at some point write something about my taste evolution.
-The tl;dr for that article is that I came across an article on [Armin Ronacher's blog](https://lucumr.pocoo.org/about/) and was hugely affected.
-I've been trying to use my little piece of internet land to serve an aesthetic, technical, and minimal blog and his site is what I wish mine was.
-
-While I don't have all of Armin's experience or skills, I thought I could at least try to give off a similar vibe with my own site.
-I use Hugo to generate my static blog, so my first try was searching through existing Hugo themes to get a starting point.
-The rest of the story I think works better as an enumeration:
-
-1. Came across the [hugo-bearcub theme](https://github.com/clente/hugo-bearcub) by clente.
-2. Looked up [Bear Blog](https://bearblog.dev/).
-3. Looked up the creator of Bear Blog, [Herman Martinus](https://herman.bearblog.dev/).
-4. Read through some of his posts and noticed his little anonymous upvote button.
-5. Thought the anonymous upvote button was super cool and wanted my own.
-
-## Upvoters
-
-I then spent a couple hours putting together `upvoters`, a little Rust web server to handle this functionality.
-I picked postgres for the db because I run this site (and a few other services like email, matrix, [forgejo](https://forge.alexselimov.com), etc...) using a VPS that already had a postgres setup.
-Probably could've just done SQLite to make it easier on everyone but didn't think about that until later.
-
-This service just tracks votes in a single table with the following important variables in the schema:
-
-1. `slug`: A unique identifier for each post that is just created from the URL.
-2. `voter_id`: A unique identifier for each voter.
-
-Since this is just a personal blog, and exact upvote count doesn't matter, the `voter_id` is a UUID assigned to each user as a cookie upon the first vote.
-Obviously all it takes to "break" the system is clearing your cookies.
-This would allow you to upvote the same post multiple times but the only risk there is me getting delusions of grandeur.
-
-## Getting started with it
-
-I wrote some instructions in the [upvoters](https://github.com/aselimov/upvoters) readme, but also feel free to email me if you need help setting it up!
-
diff --git a/content/posts/valgrind-artix-linux.md b/content/posts/valgrind-artix-linux.md
index 3d327a1..78443d3 100644
--- a/content/posts/valgrind-artix-linux.md
+++ b/content/posts/valgrind-artix-linux.md
@@ -1,7 +1,7 @@
---
title: "Gettting Valgrind working on Artix Linux"
date: 2023-08-29T21:38:32-04:00
-tags: ['software development', 'linux', 'Artix']
+topics: ['software development', 'linux', 'Artix']
---
I'm currently working on developing an implementation of the Concurrent Atomistic-Continuum method using C++ and CUDA to accelerate calculations.
diff --git a/content/posts/war_of_art/cover.webp b/content/posts/war_of_art/cover.webp
deleted file mode 100644
index e444182..0000000
Binary files a/content/posts/war_of_art/cover.webp and /dev/null differ
diff --git a/content/posts/war_of_art/index.md b/content/posts/war_of_art/index.md
deleted file mode 100644
index 25d268e..0000000
--- a/content/posts/war_of_art/index.md
+++ /dev/null
@@ -1,126 +0,0 @@
----
-title: "Musings on success from someone seeking (The War of Art review)"
-date: 2026-08-03T23:57:10-04:00
-tags: ["productivity"]
----
-
-
-
-I just finished "The War of Art" by Steven Pressfield and I wanted to collect/formalize my thoughts about it and about achieving success generally.
-While there was a lot of weird spirituality in the book, I did come away feeling motivated to continue working away on my craft.
-It also reinforced some things that I've already believed.
-The main purpose in writing this post is to formalize my thoughts on what success means and how to attain it to hopefully motivate me.
-If it is helpful to you, then that is just the icing on the cake!
-
-## A synopsis of The War of Art
-
-This book makes a strong/motivating core argument that I have summarized below:
-
-* Anytime you try to pursue anything, you will encounter "Resistance." This is a force/entity that attempts to prevent you from achieving your "work."
-* Your "work" is a unique calling you have. The book asserts that each person is meant to bring something into the world, e.g. writings, athletic achievements, software, charitable deeds, etc.
-* "Resistance" uses both internal (fears, anxiety) and external (sickness, family issues, life stressors) attacks as ways to stop you from achieving your work.
-* One's job is to overcome resistance by showing up every day, getting to work, and mastering your craft.
-* Importantly, one's job is **NOT** to attempt to make a slam dunk. Your goal shouldn't be to sit down and make the next Apple. Instead, your goal is to sit down and complete that project that eats at you. If you don't have that (which I don't currently) then you just keep working on whatever projects you can think of until you get it.
-
-That last bullet point is the main reason I'm writing this blog post.
-Let's dive into it a bit more.
-
-## Why success shouldn't be your primary goal
-
-I want to start this section off by saying that I don't consider myself successful, so take these thoughts with a grain of salt.
-To me, success means a few things:
-
-* Being known as an expert in a field.
-* Having the freedom to tackle the problems that you want to tackle (e.g. be your own boss or work a job because you want to not because you need to).
-* Financial security to support yourself and family.
-
-I've been thinking about how to achieve success in those terms for a while.
-The easiest way to measure this is to evaluate some people I consider successful and want to emulate (Andrew Kelly, Mitchell Hashimoto, Jonathon Blow, Paul Sellers) to determine what I can learn.
-It seems to me that those examples aren't as driven by "success" as they are driven by the craft/problem.
-Now don't get me wrong, some of their decisions are probably made to pursue notoriety, freedom, and financial security, but my impression is that the craft/work is always the core.
-
-This is opposed to the usual advice around startups where the focus is fast iteration towards product-market fit.
-Instead of looking for product-market fit[^1], I think you should look for those problems that you are passionate about it.
-This is especially true considering that getting product-market fit is a highly stochastic problem where many parameters have to align.
-Continuing to complete projects gives you more starting seeds when exploring the product-market fit space to improve your chances.
-So instead of optimizing for product-market fit, you should be optimizing for completing meaningful projects, and eventually you will hit the right starting seed.
-The best way to do this is to become a person that finds satisfaction from completing their "work" for the work's sake as opposed to finding satisfaction through users.
-
-I want to analyze Zig in a little bit because hearing its origin story solidified things for me.
-There are many programming languages out there, with new ones being created consistently (just check HN).
-To me, the success of Zig seems almost incidental to the creator's passion for the project.
-If I remember correctly, Andrew Kelly wanted to make some kind of low latency audio software and didn't like any of the languages available, so he wrote his own.
-
-Wow!
-
-Listening to interviews, my impression is that as soon as he had the idea for Zig, it became his mission to bring it to fruition regardless of mainstream adoption or popularity.
-The adoption and popularity did come, but it came because Zig is actually a great language with many good ideas.
-It didn't come because of fast iteration towards product-market fit.
-I want to someday make something like Zig instead of one of the million YC funded AI wrapper companies that get funded and then shutter their doors for one reason or another[^2].
-
-I had these thoughts milling around in my head, but they weren't really an active core belief until I read the War of Art.
-The argument of the book around success is that the great work (which leads to success) comes from outside yourself.
-In his view, you can't just sit down and write the hit, you have to put in the daily work until the hit comes to you.
-Sadly even when the great idea comes, you may not actually recognize that it is a great idea.
-It's probably better to not realize it's a great idea and work away at it for love of your profession regardless.
-We don't have to subscribe to the book's Neoplatonism regarding where ideas originate from and how they are given to us.
-Instead, the key realization for me boils down to two simple statements (one being a quote):
-
-
-> You have to be lucky to be successful
-
-but also:
-
-> The harder I work, the luckier I get\
-> \-\- Samuel Goldwyn
-
-You just have to keep working until you make success inevitable and stop worrying about product-market fit!!
-
-
-## Finish your projects!
-
-Finishing projects is hard, and the difficulty scales the closer you are to being done.
-But finishing your projects (even if they won't be successful) is probably the most important thing you can do.
-I found the video below really puts the importance of this well:
-
-{{< youtube 4jgTCayWlwc >}}
-
-So to put my money where my mouth is...
-
-{{< callout >}}
-I make a formal pledge to whoever reads this blog (probably just me), that I will always be working on a side project and I will always finish it no matter how boring it gets and how long it takes.
-{{< /callout >}}
-
-The book's focus on being a "professional" helps here.
-At work, even if you don't like the project you have to get it done.
-That's the essence of being a pro.
-This mindset is probably something that would be useful to have in personal projects.
-My manager recently told me that **the worst thing when managing a project is to spend eng time on something that doesn't ship**.
-I've definitely wasted a lot of my personal eng time on projects that have never seen the light of day and that should probably stop.
-
-Future side projects are going to be treated more like projects at work.
-Do more upfront analysis of the project, architecting/speccing, and timeline planning prior to giving personal projects the green.
-Once a project gets the green, I plan to complete it regardless of how hard/boring it gets.
-Building the habit of completing projects and never stopping is my best guess at how to achieve success and seems to be supported by the War of Art.
-
-## Weird spirituality (my biggest qualm)
-
-I do want to raise a fair warning that there is a lot of strange new age spirituality in this book.
-The core message is still useful as long as you are careful about taking in some of the other spiritual beliefs.
-This warning is particularly pointed towards fellow Orthodox Christians.
-You should definitely be using discernment if you choose to read this book.
-
-One surprising spiritually beneficial thing that came out of this was the author's mention of his "prayer rule" prior to beginning his work.
-He has this prayer grabbed from Homer used to invoke his "Muse."
-This description shamed me as I generally forget to say a prayer before beginning my work.
-Moving forward I will be saying the Jordanville prayer before starting work in hopes that I will be able to accomplish the duties God has set before me.
-I've copied this prayer below if you would like to use it yourself:
-
->O Lord Jesus Christ, Only-begotten Son of Thine unoriginate Father, Thou hast said with Thy most pure lips: For without Me, ye can do nothing. My Lord, O Lord, in faith having embraced Thy words, I fall down before Thy goodness; help me, a sinner, to complete through Thee Thyself this work which I am about to begin, in the name of the Father, and of the Son, and of the Holy Spirit. Amen.
-
-
-**Thanks for reading and remember to finish your projects!**
-
-[^1]: A relevant quote from the book: "When the hack sits down to work, he doesn't ask himself what's in his own hear. He asks what the market is looking for." Hacks might find wild monetary success, but I still think I rather would not be one.
-
-[^2]: For some reason writing this article, I keep thinking about Delve. Delve is a company that uses AI to automate SOC2 compliance. There supposedly was an insider leak that revealed [Delve was faking compliance reports and auditing](https://techcrunch.com/2026/03/22/delve-accused-of-misleading-customers-with-fake-compliance/). I can't help but think that the founders wanted success at any cost. If they were focused on the craft, I doubt this situation would have happened. I'd like to avoid being like Delve, even though their founders are probably considered as successful in the sense that they are well known, have freedom that comes with being a founder, and probably good income.
diff --git a/content/posts/web_obesity.md b/content/posts/web_obesity.md
index d2af9d8..03f75de 100644
--- a/content/posts/web_obesity.md
+++ b/content/posts/web_obesity.md
@@ -2,7 +2,7 @@
title: "Fighting the web obesity crisis using Hugo and Skeleton CSS"
date: 2023-02-12T12:45:48-05:00
toc: true
-tags: ["css","web design","hugo", 'self-host']
+topics: ["css","web design","hugo", 'self-host']
---
diff --git a/content/projects.md b/content/projects.md
deleted file mode 100644
index a8e1c86..0000000
--- a/content/projects.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "Projects"
-hideDate: true
-hideUpvotes: true
-hideReply: true
----
-
-Here are some of the projects I am working or have worked on:
-
-**Scientific**
-
-- [CAC ← Implementation of the Concurrent Atomistic Continuum method](https://forge.alexselimov.com/aselimov/CAC)
-- [CACmb ← Model builder for CAC (inspired by atomsk)](https://forge.alexselimov.com/aselimov/CACmb)
-
-**Web**
-
-- [upvoters ← Rust backend with postgres to handle anonymous upvotes on this blog](https://forge.alexselimov.com/aselimov/upvoters)
-- [Voting Bear Cub ← Hugo theme that has a bear-blog style with anonymous upvotes using upvoters](https://forge.alexselimov.com/aselimov/hugo-bearcub)
-- [Hugo Unified Git Activity ← Script to pull activity from multiple forges and hugo module to render it on your blog](https://forge.alexselimov.com/aselimov/hugo-unified-git-activity)
-- [Hugo Stack ← Show off your tech stack in hugo using a simple yaml data file](https://forge.alexselimov.com/aselimov/hugo-stack)
-
-**Random**
-
-- [neovim configs](https://forge.alexselimov.com/aselimov/neovim)
-- [PaperPicker ← Use local llms to find relevant arxiv papers](https://github.com/aselimov/PaperPicker.git)
diff --git a/data/stack.yaml b/data/stack.yaml
deleted file mode 100644
index 320e260..0000000
--- a/data/stack.yaml
+++ /dev/null
@@ -1,43 +0,0 @@
-- section: Code Editing
- description: "Full stack tools for editing code"
- items:
- - name: Choc V
- image: "/stack/chocv.webp"
- description: 32% low profile keyboard with Kaihl Choc Silvers and random amazon keycaps
- - name: 3-D Printed + Handwired Atreus
- image: "/stack/atreus.webp"
- description: Homemade 40% keyboard with Glorious Panda switches and MT3 Dusk keycaps
- - name: Nulea M505 Trackball Mouse
- image: "/stack/nulea.webp"
- description: |
- Smooth operation and long battery life
- - name: Ghostty + Tmux + Neovim + Zenwritten theme
- image: "/stack/editor.webp"
- description: Best stack for efficiently working on code. Monochromatic theme surprisingly helps with focus instead of staring at a rainbow all day.
-- section: Programming Languages
- description: "Languages I actually enjoy building in, not all the ones I know"
- items:
- - name: Zig
- description: Main language I'm exploring right now for personal projects.
- - name: Rust
- description: Previous favorite language before trying zig.
-- section: Building Tools
- items:
- - name: Macbook Pro M1 Max 64GB
- image: "/stack/macbook.webp"
- description: "Was gifted this, really missing Linux but getting a high powered Linux laptop in 2026 seems unlikely"
- - name: Onyx Boox Go + Lamy EMR stylus
- image: "/stack/onyx.webp"
- description: "Not as nice as fountain pen + paper but a lot better for organization/reading. I use it for derivations/notes. Be careful with the Onyx though, it phones home a ton. I use mine offline only"
- - name: Ender 3 V2
- image: "/stack/ender.webp"
- description: "Trusty printer that was cheaper than buying a new keyboard. Hoping for an upgrade soon though."
-- section: Fuel
- description: "Focus aids, coffee is daily while cigars are every now and then."
- items:
- - name: Kalita Wave + Fellow Move + TIMEMORE Black Mirror + TIMEMORE Chestnut
- image: "/stack/coffee.webp"
- description: "Favorite pour-over coffee setup using the Scott Rao recipe"
- - name: Warped Serie Gran Reserva 1988
- image: "/stack/warped.webp"
- description: "Nice for improving focus during chill late night code sessions"
diff --git a/favicon.svg b/favicon.svg
deleted file mode 100644
index 54cfd79..0000000
--- a/favicon.svg
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-
-
diff --git a/go.mod b/go.mod
deleted file mode 100644
index 231bb36..0000000
--- a/go.mod
+++ /dev/null
@@ -1,9 +0,0 @@
-module forge.alexselimov.com/aselimov/AlexSelimov.com
-
-go 1.26.5
-
-require (
- forge.alexselimov.com/aselimov/hugo-bearcub v0.0.0-20260815031146-1ef9f05f7d16 // indirect
- forge.alexselimov.com/aselimov/hugo-stack v0.0.0-20260815031034-10f865d1d861 // indirect
- forge.alexselimov.com/aselimov/hugo-unified-git-activity v0.0.0-20260516002153-e07b96c2faf3 // indirect
-)
diff --git a/go.sum b/go.sum
deleted file mode 100644
index 65b0a92..0000000
--- a/go.sum
+++ /dev/null
@@ -1,10 +0,0 @@
-forge.alexselimov.com/aselimov/hugo-bearcub v0.0.0-20260814023021-aa632e351252 h1:T0IQtSzAAOHiRrmabE+dSQxUuU4Xm8GdZP45jYeN+mY=
-forge.alexselimov.com/aselimov/hugo-bearcub v0.0.0-20260814023021-aa632e351252/go.mod h1:L550lxcgzgIei1w3dKvOTnga43J9NBtkzo7i3wl7chc=
-forge.alexselimov.com/aselimov/hugo-bearcub v0.0.0-20260815031146-1ef9f05f7d16 h1:Yj/KUnjciwME66lxunOauz+8WqJRcrs9lcFc7l1wWqY=
-forge.alexselimov.com/aselimov/hugo-bearcub v0.0.0-20260815031146-1ef9f05f7d16/go.mod h1:L550lxcgzgIei1w3dKvOTnga43J9NBtkzo7i3wl7chc=
-forge.alexselimov.com/aselimov/hugo-stack v0.0.0-20260814022948-f4c43cd94f4d h1:oCgO3LU2SuS3bQcdpFdIPLgE1z+IQXjbvbzzRLjGXqc=
-forge.alexselimov.com/aselimov/hugo-stack v0.0.0-20260814022948-f4c43cd94f4d/go.mod h1:UoKXiIrMjWeZdjsAMr1MekS3+hTQ4qXXAphXv8lOIF4=
-forge.alexselimov.com/aselimov/hugo-stack v0.0.0-20260815031034-10f865d1d861 h1:z9n0qsINz0avMnAUdy2aG9GYloRifbhebkdshM0XAfc=
-forge.alexselimov.com/aselimov/hugo-stack v0.0.0-20260815031034-10f865d1d861/go.mod h1:UoKXiIrMjWeZdjsAMr1MekS3+hTQ4qXXAphXv8lOIF4=
-forge.alexselimov.com/aselimov/hugo-unified-git-activity v0.0.0-20260516002153-e07b96c2faf3 h1:9NkGN2Vz1FtztG3lpb2F+MRv7m72Nzno7kRIMvdyau8=
-forge.alexselimov.com/aselimov/hugo-unified-git-activity v0.0.0-20260516002153-e07b96c2faf3/go.mod h1:YcxJyQNzPOmoJ/9LYHlPrZLVqMI25izS4j+lMqJgXH0=
diff --git a/hugo.toml b/hugo.toml
index f8ba6ca..2a85f9b 100644
--- a/hugo.toml
+++ b/hugo.toml
@@ -1,20 +1,17 @@
-baseURL = "https://www.alexselimov.com/"
-locale = "en-US"
-theme = ["forge.alexselimov.com/aselimov/hugo-bearcub"]
-defaultContentLanguage = "en"
-copyright = "© Alex Selimov"
-enableRobotsTXT = true
+baseurl = "https://www.alexselimov.com/"
+languageCode = "en-us"
+theme = "hugo-theme-terminal"
+pagination.pagerSize = 5
-[pagination]
-pagerSize = 10
-
-[markup]
[markup.goldmark.renderer]
unsafe = true
-[markup.highlight]
-lineNos = true
-lineNumbersInTable = false
-noClasses = false
+
+[params]
+contentTypeName = "posts"
+showMenuItems = 5
+postsToShowOnIndex = 3
+fullWidthTheme = false
+centerTheme = true
[taxonomies]
tag = "tags"
@@ -23,55 +20,32 @@ topic = "topics"
[languages]
[languages.en]
title = "Alex Selimov"
-label = "en-US"
-locale = "en-US"
+subtitle = ""
+keywords = ""
+copyright = "© Alex Selimov"
+
+[languages.en.params]
+menuMore = "Show more"
+readMore = "Read more"
+readOtherPosts = "Read other posts"
+
+[languages.en.params.logo]
+logoText = "Alex Selimov"
+logoHomeLink = "/"
+
[languages.en.menu]
[[languages.en.menu.main]]
-identifier = "home"
-name = "Home"
-url = "/"
-weight = 1
-[[languages.en.menu.main]]
-identifier = "projects"
-name = "Projects"
-url = "/projects/"
-weight = 2
-[[languages.en.menu.main]]
identifier = "about"
-name = "About"
-url = "/about/"
-weight = 3
-
-[params.heatmap]
-caption = "This is my unified git heatmap from my Forgejo and Github"
-color_empty_light = "#e8e4dc"
-color_empty_dark = "#2a2a2a"
-color_max = "#7a5010"
-color_high = "#C47E1A"
-color_mid = "#EF9F27"
-color_low = "#F7C46A"
-[params]
-description = "Alex Selimov personal site and blog."
-title = "Alex Selimov"
-favicon = "favicon.png"
-images = ["og-image.png"]
-dateFormat = "2006-01-02"
-hideUntranslated = false
-themeStyle = "herman"
-generateSocialCard = true
-postsToShowOnIndex = 5
-upvotes = true
-upvoteApi = "/api"
-numBest = 5
-
-[params.author]
-name = "Alex Selimov"
-email = "alex@alexselimov.com"
-
-[module]
-[[module.imports]]
-path = 'forge.alexselimov.com/aselimov/hugo-bearcub'
-[[module.imports]]
-path = 'forge.alexselimov.com/aselimov/hugo-unified-git-activity'
-[[module.imports]]
-path = 'forge.alexselimov.com/aselimov/hugo-stack'
+name = "[About Me]"
+url = "/about"
+weight = 10
+[[languages.en.menu.main]]
+identifier = "cv"
+name = "[CV]"
+url = "/cv"
+weight = 10
+[[languages.en.menu.main]]
+identifier = "git"
+name = "[Git]"
+url = "https://forge.alexselimov.com/aselimov"
+weight = 10
diff --git a/layouts/page/presentation.html b/layouts/page/presentation.html
new file mode 100644
index 0000000..9eda755
--- /dev/null
+++ b/layouts/page/presentation.html
@@ -0,0 +1,5 @@
+
diff --git a/layouts/partials/custom_head.html b/layouts/partials/custom_head.html
deleted file mode 100644
index a5e2855..0000000
--- a/layouts/partials/custom_head.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{{ $autoTheme := resources.Get "auto-theme.css" | minify }}
-
-
-
-
diff --git a/layouts/shortcodes/callout.html b/layouts/shortcodes/callout.html
deleted file mode 100644
index 03dbc3f..0000000
--- a/layouts/shortcodes/callout.html
+++ /dev/null
@@ -1 +0,0 @@
-{{ .Inner | markdownify }}
diff --git a/layouts/shortcodes/fontawesome.html b/layouts/shortcodes/fontawesome.html
new file mode 100644
index 0000000..7e68a9c
--- /dev/null
+++ b/layouts/shortcodes/fontawesome.html
@@ -0,0 +1 @@
+
diff --git a/layouts/shortcodes/img.html b/layouts/shortcodes/img.html
new file mode 100644
index 0000000..86148b3
--- /dev/null
+++ b/layouts/shortcodes/img.html
@@ -0,0 +1,6 @@
+
+
+
diff --git a/layouts/shortcodes/presentations.html b/layouts/shortcodes/presentations.html
new file mode 100644
index 0000000..9e7e7d8
--- /dev/null
+++ b/layouts/shortcodes/presentations.html
@@ -0,0 +1,6 @@
+
+ {{ range .Site.Data.presentations }}
+ - {{ .authors }} ({{ .date }}) {{ .title }}. {{ .conference }} {{ with .link }}
+ [Link]{{ end }}
+ {{ end }}
+
diff --git a/layouts/shortcodes/publications.html b/layouts/shortcodes/publications.html
new file mode 100644
index 0000000..ce11be6
--- /dev/null
+++ b/layouts/shortcodes/publications.html
@@ -0,0 +1,5 @@
+
+ {{ range .Site.Data.publications }}
+ - {{ .authors }} ({{ .year }}). {{ .title }}. {{ .journal }} {{ .volume }}, {{ .pages }} {{ with .link }} [Link]{{ end }}
+{{ end }}
+
diff --git a/.hugo_build.lock b/layouts/shortcodes/recent-articles.html
similarity index 100%
rename from .hugo_build.lock
rename to layouts/shortcodes/recent-articles.html
diff --git a/scripts/generate_triangulated_mesh.py b/scripts/generate_triangulated_mesh.py
deleted file mode 100644
index fa36ce1..0000000
--- a/scripts/generate_triangulated_mesh.py
+++ /dev/null
@@ -1,235 +0,0 @@
-#!/usr/bin/env python3
-"""Generate a triangulated mesh graphic as an SVG file.
-
-Example:
- python scripts/generate_triangulated_mesh.py --width 1920 --height 1080 --output mesh.svg
-"""
-
-from __future__ import annotations
-
-import argparse
-import math
-import random
-from dataclasses import dataclass
-from pathlib import Path
-
-
-@dataclass(frozen=True)
-class Point:
- x: float
- y: float
-
-
-def clamp(value: float, low: float, high: float) -> float:
- return max(low, min(high, value))
-
-
-def parse_args() -> argparse.Namespace:
- parser = argparse.ArgumentParser(description="Generate a triangulated mesh SVG.")
- parser.add_argument("--width", type=int, required=True, help="Graphic width in pixels.")
- parser.add_argument("--height", type=int, required=True, help="Graphic height in pixels.")
- parser.add_argument(
- "--output",
- type=Path,
- default=Path("triangulated-mesh.svg"),
- help="Output SVG path (default: triangulated-mesh.svg)",
- )
- parser.add_argument(
- "--cell-size",
- type=float,
- default=120.0,
- help="Approximate grid cell size in pixels when x/y step are not set.",
- )
- parser.add_argument(
- "--x-step",
- type=float,
- default=None,
- help="Horizontal point spacing in pixels (overrides --cell-size on x-axis).",
- )
- parser.add_argument(
- "--y-step",
- type=float,
- default=None,
- help="Vertical point spacing in pixels (overrides --cell-size on y-axis).",
- )
- parser.add_argument(
- "--jitter",
- type=float,
- default=0.35,
- help="Point jitter amount as a fraction of cell size (0.0-0.5).",
- )
- parser.add_argument(
- "--seed",
- type=int,
- default=None,
- help="Random seed for reproducible output.",
- )
- parser.add_argument(
- "--stroke",
- type=float,
- default=1.25,
- help="Edge stroke width in pixels.",
- )
- parser.add_argument(
- "--dot-radius",
- type=float,
- default=1.9,
- help="Vertex dot radius in pixels.",
- )
- parser.add_argument(
- "--line-color",
- type=str,
- default="#334155",
- help="Edge color as hex (default: #334155).",
- )
- parser.add_argument(
- "--dot-color",
- type=str,
- default="#0f172a",
- help="Dot color as hex (default: #0f172a).",
- )
- parser.add_argument(
- "--background",
- type=str,
- default="#f8fafc",
- help="Background color as hex (default: #f8fafc).",
- )
- return parser.parse_args()
-
-
-def build_points(
- width: int,
- height: int,
- x_step: float,
- y_step: float,
- jitter_frac: float,
- rng: random.Random,
-) -> list[list[Point]]:
- cols = max(2, math.ceil(width / x_step) + 1)
- rows = max(2, math.ceil(height / y_step) + 1)
-
- points: list[list[Point]] = []
- jitter = clamp(jitter_frac, 0.0, 0.5) * min(x_step, y_step)
-
- for row in range(rows):
- y = (height * row) / (rows - 1)
- row_points: list[Point] = []
- for col in range(cols):
- x = (width * col) / (cols - 1)
-
- # Keep border anchored to make the mesh fill the canvas cleanly.
- if 0 < row < rows - 1 and 0 < col < cols - 1:
- x += rng.uniform(-jitter, jitter)
- y_jittered = y + rng.uniform(-jitter, jitter)
- else:
- y_jittered = y
-
- row_points.append(Point(x=clamp(x, 0.0, float(width)), y=clamp(y_jittered, 0.0, float(height))))
- points.append(row_points)
-
- return points
-
-
-def generate_triangles(points: list[list[Point]], rng: random.Random) -> list[tuple[Point, Point, Point]]:
- triangles: list[tuple[Point, Point, Point]] = []
- rows = len(points)
- cols = len(points[0]) if rows else 0
-
- for row in range(rows - 1):
- for col in range(cols - 1):
- p00 = points[row][col]
- p10 = points[row][col + 1]
- p01 = points[row + 1][col]
- p11 = points[row + 1][col + 1]
-
- if rng.random() < 0.5:
- triangles.append((p00, p10, p11))
- triangles.append((p00, p11, p01))
- else:
- triangles.append((p00, p10, p01))
- triangles.append((p10, p11, p01))
-
- return triangles
-
-
-def svg_polygon(points: tuple[Point, Point, Point], stroke: str, stroke_width: float) -> str:
- pts = " ".join(f"{p.x:.2f},{p.y:.2f}" for p in points)
- return (
- f''
- )
-
-
-def write_svg(
- width: int,
- height: int,
- triangles: list[tuple[Point, Point, Point]],
- stroke_width: float,
- dot_radius: float,
- line_color: str,
- dot_color: str,
- background: str,
- output: Path,
- points: list[list[Point]],
-) -> None:
- elements: list[str] = []
-
- for tri in triangles:
- elements.append(svg_polygon(tri, stroke=line_color, stroke_width=stroke_width))
-
- circles: list[str] = []
- for row in points:
- for p in row:
- circles.append(f'')
-
- svg = "\n".join(
- [
- '',
- f'",
- ]
- )
-
- output.parent.mkdir(parents=True, exist_ok=True)
- output.write_text(svg, encoding="utf-8")
-
-
-def main() -> None:
- args = parse_args()
-
- if args.width <= 0 or args.height <= 0:
- raise SystemExit("--width and --height must be positive integers")
-
- if args.cell_size <= 1:
- raise SystemExit("--cell-size must be > 1")
-
- x_step = args.x_step if args.x_step is not None else args.cell_size
- y_step = args.y_step if args.y_step is not None else args.cell_size
-
- if x_step <= 1 or y_step <= 1:
- raise SystemExit("--x-step and --y-step must be > 1")
-
- rng = random.Random(args.seed)
- points = build_points(args.width, args.height, x_step, y_step, args.jitter, rng)
- triangles = generate_triangles(points, rng)
- write_svg(
- args.width,
- args.height,
- triangles,
- args.stroke,
- args.dot_radius,
- args.line_color,
- args.dot_color,
- args.background,
- args.output,
- points,
- )
-
- print(f"Generated {len(triangles)} triangles -> {args.output}")
-
-
-if __name__ == "__main__":
- main()
diff --git a/static/favicon.png b/static/favicon.png
index f6b7405..3d9a71a 100644
Binary files a/static/favicon.png and b/static/favicon.png differ
diff --git a/static/presentations/MMM_2022_AlexSelimov.pptx b/static/presentations/MMM_2022_AlexSelimov.pptx
old mode 100755
new mode 100644
diff --git a/static/profile.webp b/static/profile.webp
deleted file mode 100644
index e46ba1b..0000000
Binary files a/static/profile.webp and /dev/null differ
diff --git a/static/public.key b/static/public.key
deleted file mode 100644
index 4af9c07..0000000
--- a/static/public.key
+++ /dev/null
@@ -1,41 +0,0 @@
------BEGIN PGP PUBLIC KEY BLOCK-----
-
-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
-oOzx0x0y7ELQVGJVtpxqVxLcA58xJCE34I+h
-=5X5g
------END PGP PUBLIC KEY BLOCK-----
diff --git a/static/stack/atreus.webp b/static/stack/atreus.webp
deleted file mode 100644
index 219e4bc..0000000
Binary files a/static/stack/atreus.webp and /dev/null differ
diff --git a/static/stack/chocv.webp b/static/stack/chocv.webp
deleted file mode 100644
index 96d76f7..0000000
Binary files a/static/stack/chocv.webp and /dev/null differ
diff --git a/static/stack/coffee.webp b/static/stack/coffee.webp
deleted file mode 100644
index c7f9e36..0000000
Binary files a/static/stack/coffee.webp and /dev/null differ
diff --git a/static/stack/editor.webp b/static/stack/editor.webp
deleted file mode 100644
index 870fa61..0000000
Binary files a/static/stack/editor.webp and /dev/null differ
diff --git a/static/stack/ender.webp b/static/stack/ender.webp
deleted file mode 100644
index 37eb492..0000000
Binary files a/static/stack/ender.webp and /dev/null differ
diff --git a/static/stack/macbook.webp b/static/stack/macbook.webp
deleted file mode 100644
index ebab082..0000000
Binary files a/static/stack/macbook.webp and /dev/null differ
diff --git a/static/stack/nulea.webp b/static/stack/nulea.webp
deleted file mode 100644
index ef702c8..0000000
Binary files a/static/stack/nulea.webp and /dev/null differ
diff --git a/static/stack/onyx.webp b/static/stack/onyx.webp
deleted file mode 100644
index 3d9d9eb..0000000
Binary files a/static/stack/onyx.webp and /dev/null differ
diff --git a/static/stack/warped.webp b/static/stack/warped.webp
deleted file mode 100644
index fa9169f..0000000
Binary files a/static/stack/warped.webp and /dev/null differ
diff --git a/static/terminal.css b/static/terminal.css
new file mode 100644
index 0000000..619e112
--- /dev/null
+++ b/static/terminal.css
@@ -0,0 +1,5 @@
+:root {
+ --background: #191919;
+ --foreground: #eceae5;
+ --accent: #88ae68;
+}
diff --git a/themes/hugo-bearcub b/themes/hugo-bearcub
deleted file mode 160000
index 17c78a6..0000000
--- a/themes/hugo-bearcub
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 17c78a6bcdc956b4cb720bcf23ef483d3f416a62
diff --git a/themes/hugo-theme-terminal b/themes/hugo-theme-terminal
new file mode 160000
index 0000000..4e2b017
--- /dev/null
+++ b/themes/hugo-theme-terminal
@@ -0,0 +1 @@
+Subproject commit 4e2b01779a5d2cc1b869c6bce1edf4676a4684b9