From 9587ac8cb2c5319eec39de40130447ce89c15f9a Mon Sep 17 00:00:00 2001 From: Eric Meehan Date: Thu, 22 Oct 2026 16:08:08 -0400 Subject: [PATCH] AI overhaul --- htdocs/common/footer.html | 18 +- htdocs/common/header.html | 37 +- htdocs/common/topnav.html | 15 +- htdocs/index.html | 244 ++++++------ htdocs/robots.txt | 4 + htdocs/sitemap.xml | 6 + htdocs/static/home.css | 805 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 1002 insertions(+), 127 deletions(-) create mode 100755 htdocs/robots.txt create mode 100755 htdocs/sitemap.xml create mode 100755 htdocs/static/home.css diff --git a/htdocs/common/footer.html b/htdocs/common/footer.html index 0214e25..47d9e3e 100644 --- a/htdocs/common/footer.html +++ b/htdocs/common/footer.html @@ -1,11 +1,13 @@ diff --git a/htdocs/common/header.html b/htdocs/common/header.html index f232bc3..96a74e8 100644 --- a/htdocs/common/header.html +++ b/htdocs/common/header.html @@ -1,8 +1,39 @@ + + + + + + + + + + + + + + - - - + + eom.dev — Build your own corner of the internet + diff --git a/htdocs/common/topnav.html b/htdocs/common/topnav.html index 6d490f0..c503986 100644 --- a/htdocs/common/topnav.html +++ b/htdocs/common/topnav.html @@ -1,6 +1,15 @@ -
+
-
+ diff --git a/htdocs/index.html b/htdocs/index.html index e486aab..28e6398 100644 --- a/htdocs/index.html +++ b/htdocs/index.html @@ -2,127 +2,145 @@ -eom.dev - Home -
-
-

Eric O'Neill Meehan

-

- Welcome to Eric's homepage. -

-
-
- -
-
-

Links

- -
-
-

- - Content -

-

- Browse videos on PeerTube and YouTube, or watch live on Owncast. -

+
+
+
+

A practical, independent corner of the internet

+

Build your own corner of the internet.

+

Practical self-hosting, creative coding, and community experiments from Eric Meehan's home lab. Learn from the work, try the projects, and see how they are made.

+ -
+

Independent software, open-source projects, music, and games—made in Raleigh, North Carolina.

+
+ +
-

- - Repositories -

-

- Open-source engineering projects hosted on Gitea. -

+
+
+

Find your starting point

+

Three ways into the lab

+

Pick a path. Each one leads to real projects, recordings, and source code—not just a list of services.

+
+
+
+ 01 / Build +

Make the infrastructure yours

+

Explore self-hosted services, automation, local AI, and the recipes that run this network.

+ Explore the infrastructure +
+
+ 02 / Play +

Join a world or try a game

+

Meet the community in Luanti or see how a small AI-assisted idea became a playable game.

+ Find a game to join +
+
+ 03 / Create +

Listen, watch, and experiment

+

Browse original music, live performances, creative coding, and field recordings.

+ Browse the video library +
+
+
+ + + +
+
+

Built in public

+

Follow the work. Add your voice.

+

Project notes, questions, and community plans live on the forum. Watch live when a stream is on; catch up with the recordings any time.

+
+ +
+ +
+
+ Eric Meehan +
+
+

The person behind the projects

+

Hi, I'm Eric.

+

I'm a software engineer and musician in Raleigh, North Carolina. I use this independently run network to build and share engineering and creative projects—and to document what works, what doesn't, and how you can try it yourself.

+
-
+ -
-
- File Icons +
+
+

Keep the lights on

+

Support the independent work.

+

Contributions help cover the servers, storage, and time behind these projects. If you need hands-on help, you can also book a consultation.

-
-

About

-

- Eric Meehan is a 31-year-old software engineer and musician living in Raleigh, North Carolina. - This website is the homepage for Eric's private computer network, eom.dev. Eric uses this network - to self-host and self-publish his engineering and artistic projects. This content is often documenting - further developments of the network itself, and is usually delivered in an educational tone. There is not - a set schedule for projects, events, or live streams, and Eric tends to pick up many projects. The best - way to stay up-to-date is to join the forum, and the best - way to reach Eric directly is by email. -

- Eric's GPG Key +
+ Become a monthly supporter + Book a free introductory call + Make a one-time contribution +
+ Other ways to support +

Monero contributions can be sent to this public address:

+ 48mFvxYDSCzMy5a3Zaj7ewApbX4GwXVXX9T1JC8mqBC19s9UcrNq8eaKkQ6GKdhHGQGmhdpvMd3mcbjf4eQbP8Yv7KdAREw +

For P2Pool, view the XMRig configuration and replace the example wallet with your own.

+
-
- -
-
-
-
- - - -
-

Donate

-
-

- Make a donation to support Eric's online services, engineering projects, and educational content. -

-
-
-
-

USD

-

- Donate USD through Stripe. -

- - - - -
-
-

XMR

-

Monero donations can be sent to

- 48mFvxYDSCzMy5a3Zaj7ewApbX4GwXVXX9T1JC8mqBC19s9UcrNq8eaKkQ6GKdhHGQGmhdpvMd3mcbjf4eQbP8Yv7KdAREw -
P2Pool
-

- Contribute compute power to the eom.dev mining pool with XMRig. - Update the user field in the ~/.xmrig.json configuration below to your wallet address. - You may use the Monero donation address above if you would like to donate your payouts to eom.dev. -

-
-
- - - -
- + + + diff --git a/htdocs/robots.txt b/htdocs/robots.txt new file mode 100755 index 0000000..d9e1416 --- /dev/null +++ b/htdocs/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / + +Sitemap: https://www.eom.dev/sitemap.xml diff --git a/htdocs/sitemap.xml b/htdocs/sitemap.xml new file mode 100755 index 0000000..6d88248 --- /dev/null +++ b/htdocs/sitemap.xml @@ -0,0 +1,6 @@ + + + + https://www.eom.dev/ + + diff --git a/htdocs/static/home.css b/htdocs/static/home.css new file mode 100755 index 0000000..6d51dc4 --- /dev/null +++ b/htdocs/static/home.css @@ -0,0 +1,805 @@ +:root { + color-scheme: dark; + --page: #1e1e2e; + --page-deep: #181825; + --surface: #242438; + --surface-raised: #292940; + --border: #3c3d56; + --text: #cdd6f4; + --muted: #a6adc8; + --subtle: #7f849c; + --accent: #cba6f7; + --accent-strong: #b4befe; + --blue: #89b4fa; + --green: #a6e3a1; + --red: #f38ba8; + --peach: #fab387; + --header-height: 4.5rem; + font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; +} + +@media (prefers-color-scheme: light) { + :root { + color-scheme: light; + --page: #eff1f5; + --page-deep: #e6e9ef; + --surface: #ffffff; + --surface-raised: #f7f7fb; + --border: #ccd0da; + --text: #4c4f69; + --muted: #5c5f77; + --subtle: #6c6f85; + --accent: #8839ef; + --accent-strong: #7287fd; + --blue: #1e66f5; + --green: #40a02b; + --red: #d20f39; + --peach: #fe640b; + } +} + +*, +*::before, +*::after { + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; + scroll-padding-top: calc(var(--header-height) + 1rem); +} + +body { + margin: 0; + background: var(--page); + color: var(--text); + font-size: 16px; + line-height: 1.7; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; +} + +body, +button, +a { + font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; +} + +a { + color: var(--accent-strong); + text-decoration-thickness: 1px; + text-underline-offset: 0.2em; +} + +a:hover { + color: var(--text); +} + +a:focus-visible, +summary:focus-visible { + outline: 3px solid var(--peach); + outline-offset: 4px; + border-radius: 4px; +} + +h1, +h2, +h3, +p { + margin-top: 0; +} + +h1, +h2, +h3 { + color: var(--text); + line-height: 1.15; + letter-spacing: -0.035em; +} + +h1 { + font-size: clamp(2.8rem, 6.7vw, 5.6rem); +} + +h2 { + font-size: clamp(2rem, 4vw, 3.2rem); +} + +h3 { + font-size: clamp(1.25rem, 2vw, 1.6rem); +} + +p { + color: var(--muted); +} + +.header .home-menu { + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 10; + min-height: var(--header-height); + padding: 0 clamp(1.25rem, 5vw, 5rem); + display: flex; + align-items: center; + justify-content: space-between; + background: color-mix(in srgb, var(--page) 88%, transparent); + border-bottom: 1px solid color-mix(in srgb, var(--border) 75%, transparent); + backdrop-filter: blur(16px); + -webkit-backdrop-filter: blur(16px); +} + +.home-menu .pure-menu-heading { + padding: 0; + color: var(--text); + font-size: 1.25rem; + font-weight: 800; + letter-spacing: -0.06em; + text-transform: none; +} + +.brand-dot { + color: var(--accent); +} + +.home-menu nav { + margin-left: auto; +} + +.home-menu .pure-menu-list { + display: flex; + align-items: center; + gap: clamp(0.1rem, 1.5vw, 1rem); + margin: 0; + padding: 0; + list-style: none; +} + +.home-menu .pure-menu-link { + padding: 0.55rem 0.8rem; + color: var(--muted); + font-size: 0.9rem; + border-radius: 999px; + transition: color 160ms ease, background-color 160ms ease; +} + +.home-menu .pure-menu-link:hover { + color: var(--text); + background: var(--surface-raised); +} + +.home-menu .pure-menu-link.nav-support { + color: var(--page-deep); + background: var(--accent); + font-weight: 700; +} + +.home-menu .pure-menu-link.nav-support:hover { + color: var(--page-deep); + background: var(--accent-strong); +} + +.skip-link { + position: absolute; + top: -5rem; + left: 1rem; + z-index: 20; + padding: 0.6rem 1rem; + color: var(--page-deep); + background: var(--accent); + border-radius: 0.5rem; +} + +.skip-link:focus { + top: 0.7rem; +} + +main { + padding-top: var(--header-height); +} + +.hero { + position: relative; + display: grid; + grid-template-columns: minmax(0, 1.35fr) minmax(15rem, 0.65fr); + align-items: center; + gap: 3rem; + min-height: min(690px, calc(100svh - var(--header-height))); + padding: clamp(4rem, 8vw, 8rem) clamp(1.5rem, 10vw, 10rem); + overflow: hidden; + background: + radial-gradient(ellipse at 83% 48%, color-mix(in srgb, var(--accent) 14%, transparent), transparent 35%), + linear-gradient(135deg, var(--page-deep), var(--page)); + border-bottom: 1px solid var(--border); +} + +.hero-inner { + position: relative; + z-index: 1; + max-width: 780px; +} + +.eyebrow, +.card-kicker { + margin-bottom: 0.8rem; + color: var(--accent); + font-size: 0.74rem; + font-weight: 800; + letter-spacing: 0.14em; + line-height: 1.4; + text-transform: uppercase; +} + +.hero h1 { + max-width: 780px; + margin-bottom: 1.35rem; +} + +.hero-copy { + max-width: 650px; + margin-bottom: 1.8rem; + font-size: clamp(1.08rem, 1.8vw, 1.3rem); + line-height: 1.65; +} + +.hero-actions, +.project-links, +.about-links, +.community-actions, +.support-actions { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.8rem; +} + +.button { + display: inline-flex; + min-height: 3rem; + align-items: center; + justify-content: center; + padding: 0.7rem 1.15rem; + border: 1px solid transparent; + border-radius: 0.75rem; + font-size: 0.92rem; + font-weight: 750; + text-align: center; + text-decoration: none; + transition: transform 160ms ease, background-color 160ms ease, border-color 160ms ease; +} + +.button:hover { + transform: translateY(-2px); + text-decoration: none; +} + +.button-primary { + color: var(--page-deep); + background: var(--accent); +} + +.button-primary:hover { + color: var(--page-deep); + background: var(--accent-strong); +} + +.button-secondary { + color: var(--text); + background: color-mix(in srgb, var(--surface) 74%, transparent); + border-color: var(--border); +} + +.button-secondary:hover { + color: var(--text); + background: var(--surface-raised); + border-color: var(--subtle); +} + +.hero-note { + margin: 1.5rem 0 0; + font-size: 0.85rem; +} + +.hero-art { + position: relative; + width: min(30vw, 350px); + aspect-ratio: 1; + justify-self: center; +} + +.orbit { + position: absolute; + inset: 10%; + border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); + border-radius: 50%; + transform: rotate(-28deg) scaleY(0.72); +} + +.orbit-one { + transform: rotate(-28deg) scaleY(0.72); +} + +.orbit-two { + transform: rotate(32deg) scaleY(0.72); + border-color: color-mix(in srgb, var(--blue) 50%, transparent); +} + +.orbit-three { + inset: 23%; + border-color: color-mix(in srgb, var(--green) 50%, transparent); + transform: rotate(72deg) scaleY(0.72); +} + +.orbit-core { + position: absolute; + inset: 32%; + display: grid; + place-content: center; + color: var(--text); + background: radial-gradient(circle at 35% 30%, var(--surface-raised), var(--page-deep)); + border: 1px solid var(--border); + border-radius: 50%; + box-shadow: 0 0 70px color-mix(in srgb, var(--accent) 20%, transparent), inset 0 0 30px color-mix(in srgb, var(--accent) 8%, transparent); + font-size: clamp(1.1rem, 2vw, 1.7rem); + font-weight: 800; + letter-spacing: -0.07em; + line-height: 1.05; + text-align: center; +} + +.section { + padding: clamp(4rem, 8vw, 7rem) clamp(1.5rem, 9vw, 9rem); +} + +.intro-section, +.featured-section { + max-width: 1600px; + margin-inline: auto; +} + +.section-heading { + max-width: 760px; + margin-bottom: 2.4rem; +} + +.section-heading h2, +.about-copy h2, +.support-copy h2, +.community-band h2 { + margin-bottom: 0.9rem; +} + +.section-heading > p:last-child { + max-width: 650px; + margin-bottom: 0; + font-size: 1.05rem; +} + +.path-grid, +.project-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 1rem; +} + +.path-card, +.project-card { + min-width: 0; + padding: clamp(1.35rem, 2.5vw, 2rem); + background: var(--surface); + border: 1px solid var(--border); + border-radius: 1.1rem; + transition: transform 180ms ease, border-color 180ms ease, background-color 180ms ease; +} + +.path-card:hover, +.project-card:hover { + background: var(--surface-raised); + border-color: color-mix(in srgb, var(--accent) 65%, var(--border)); + transform: translateY(-4px); +} + +.path-card h3, +.project-card h3 { + margin: 0.7rem 0; +} + +.path-card p, +.project-card > p:not(.card-kicker) { + margin-bottom: 1.3rem; +} + +.path-build { + border-top: 3px solid var(--blue); +} + +.path-play { + border-top: 3px solid var(--peach); +} + +.path-create { + border-top: 3px solid var(--green); +} + +.card-kicker { + margin-bottom: 0.4rem; + color: var(--muted); + font-size: 0.68rem; +} + +.text-link { + color: var(--accent-strong); + font-size: 0.91rem; + font-weight: 700; +} + +.text-link:hover { + color: var(--text); +} + +.featured-section { + padding-top: 2rem; +} + +.section-heading-row { + display: flex; + align-items: end; + justify-content: space-between; + gap: 2rem; +} + +.section-heading-row > .text-link { + flex: 0 0 auto; + margin-bottom: 0.5rem; +} + +.project-card { + display: flex; + flex-direction: column; + min-height: 360px; +} + +.project-mark { + display: grid; + width: 3rem; + height: 3rem; + margin-bottom: 1.4rem; + place-items: center; + background: var(--page-deep); + border: 1px solid var(--border); + border-radius: 0.9rem; + font-size: 1.4rem; +} + +.mark-red { + color: var(--red); +} + +.mark-blue { + color: var(--blue); +} + +.mark-green { + color: var(--green); +} + +.project-links { + align-items: flex-start; + gap: 0.55rem 1rem; + margin-top: auto; + padding-top: 0.8rem; +} + +.community-band { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + align-items: center; + gap: 3rem; + padding: clamp(2.5rem, 6vw, 5rem) clamp(1.5rem, 9vw, 9rem); + background: var(--page-deep); + border-top: 1px solid var(--border); + border-bottom: 1px solid var(--border); +} + +.community-band > div:first-child { + max-width: 700px; +} + +.community-band h2 { + font-size: clamp(1.8rem, 3vw, 2.6rem); +} + +.community-band p:not(.eyebrow) { + margin-bottom: 0; +} + +.community-actions { + justify-content: flex-start; +} + +.quiet-link { + color: var(--muted); + font-size: 0.88rem; +} + +.about-section { + display: grid; + grid-template-columns: minmax(200px, 0.55fr) minmax(0, 1.45fr); + align-items: center; + gap: clamp(2rem, 7vw, 7rem); + max-width: 1300px; + margin-inline: auto; +} + +.about-photo { + width: min(100%, 300px); + padding: 0.5rem; + background: linear-gradient(140deg, var(--accent), var(--blue), var(--green)); + border-radius: 1.35rem; +} + +.about-photo img { + display: block; + width: 100%; + height: auto; + aspect-ratio: 1; + object-fit: cover; + border-radius: 1rem; +} + +.about-copy > p:not(.eyebrow) { + max-width: 740px; + font-size: 1.05rem; +} + +.about-links { + gap: 0.55rem 1.4rem; +} + +.support-section { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(300px, 0.9fr); + align-items: start; + gap: clamp(2rem, 7vw, 7rem); + padding: clamp(3.5rem, 7vw, 6rem) clamp(1.5rem, 9vw, 9rem); + background: var(--surface); + border-top: 1px solid var(--border); +} + +.support-copy { + max-width: 620px; +} + +.support-actions { + align-items: flex-start; + flex-direction: column; +} + +.crypto-support { + width: 100%; + margin-top: 0.2rem; + padding: 0.8rem 1rem; + color: var(--muted); + background: var(--page); + border: 1px solid var(--border); + border-radius: 0.8rem; +} + +.crypto-support summary { + color: var(--text); + cursor: pointer; + font-weight: 700; +} + +.wallet-address { + display: block; + overflow-wrap: anywhere; + padding: 0.8rem; + color: var(--text); + background: var(--page-deep); + border: 1px solid var(--border); + border-radius: 0.5rem; + font-size: 0.78rem; + user-select: all; +} + +.footer { + position: static; + bottom: auto; + width: auto; + padding: 2.5rem 1.5rem; + color: var(--muted); + background: var(--page-deep); + text-align: center; +} + +.footer-brand { + color: var(--text); + font-size: 1.1rem; + font-weight: 800; + letter-spacing: -0.05em; + text-decoration: none; +} + +.footer > p { + margin: 0.3rem 0 1rem; + font-size: 0.87rem; +} + +.footer-links { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 0.6rem 1.2rem; + margin: 1rem 0 1.4rem; +} + +.footer-links a, +.footer-credits a { + color: var(--muted); + font-size: 0.86rem; +} + +.footer .footer-credits { + margin: 0; + color: var(--subtle); + font-size: 0.78rem; +} + +@media (max-width: 900px) { + .hero { + grid-template-columns: minmax(0, 1fr) minmax(12rem, 0.55fr); + gap: 1rem; + padding-inline: clamp(1.5rem, 6vw, 4rem); + } + + .path-grid, + .project-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .project-card:last-child { + grid-column: 1 / -1; + } + + .community-band { + grid-template-columns: 1fr; + gap: 1.5rem; + } +} + +@media (max-width: 640px) { + :root { + --header-height: 4rem; + } + + .header .home-menu { + padding-inline: 1rem; + } + + .home-menu .pure-menu-heading { + font-size: 1.05rem; + } + + .home-menu .pure-menu-list { + gap: 0; + } + + .home-menu .pure-menu-link { + padding: 0.5rem 0.45rem; + font-size: 0.76rem; + } + + .home-menu .pure-menu-item:nth-child(3) { + display: none; + } + + .hero { + min-height: auto; + grid-template-columns: 1fr; + padding: 4.5rem 1.35rem 3.5rem; + } + + .hero-art { + position: absolute; + right: -5rem; + bottom: -5rem; + width: 14rem; + opacity: 0.42; + } + + .hero-inner { + z-index: 1; + } + + .hero h1 { + max-width: 12ch; + } + + .hero-copy { + max-width: 34rem; + } + + .hero-actions { + align-items: stretch; + flex-direction: column; + max-width: 22rem; + } + + .hero-note { + max-width: 24rem; + } + + .section { + padding: 3.5rem 1.25rem; + } + + .path-grid, + .project-grid { + grid-template-columns: 1fr; + } + + .project-card:last-child { + grid-column: auto; + } + + .project-card { + min-height: auto; + } + + .section-heading-row { + align-items: flex-start; + flex-direction: column; + gap: 0.5rem; + } + + .community-band { + padding: 3rem 1.25rem; + } + + .community-actions { + align-items: stretch; + flex-direction: column; + } + + .community-actions .button { + width: 100%; + } + + .about-section { + grid-template-columns: 1fr; + gap: 1.75rem; + } + + .about-photo { + width: min(65vw, 240px); + } + + .support-section { + grid-template-columns: 1fr; + gap: 1.5rem; + padding: 3.5rem 1.25rem; + } + + .support-actions .button { + width: 100%; + } +} + +@media (max-width: 380px) { + .home-menu .pure-menu-item:nth-child(2) { + display: none; + } +} + +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + scroll-behavior: auto !important; + transition-duration: 0.01ms !important; + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + } +}