mirror of
https://github.com/Patiun/com.gregkilmer.www.git
synced 2026-11-08 04:08:24 +00:00
Domain update
This commit is contained in:
+3
-3
@@ -11,7 +11,7 @@ PORT=4321
|
|||||||
HOST=0.0.0.0
|
HOST=0.0.0.0
|
||||||
|
|
||||||
# Canonical site URL (used for absolute metadata URLs and API responses).
|
# Canonical site URL (used for absolute metadata URLs and API responses).
|
||||||
SITE_URL=https://patiun.com
|
SITE_URL=https://gregkilmer.com
|
||||||
|
|
||||||
# --- Contact form -> /api/contact -------------------------------------------
|
# --- Contact form -> /api/contact -------------------------------------------
|
||||||
# Two delivery modes. If SMTP is configured, email is sent. Otherwise, if a webhook
|
# Two delivery modes. If SMTP is configured, email is sent. Otherwise, if a webhook
|
||||||
@@ -23,8 +23,8 @@ SITE_URL=https://patiun.com
|
|||||||
# SMTP_PORT=587
|
# SMTP_PORT=587
|
||||||
# SMTP_USER=
|
# SMTP_USER=
|
||||||
# SMTP_PASS=
|
# SMTP_PASS=
|
||||||
# CONTACT_TO=greg@patiun.com
|
# CONTACT_TO=greg@gregkilmer.com
|
||||||
# SMTP_FROM="Greg's Site <no-reply@patiun.com>"
|
# SMTP_FROM="Greg's Site <no-reply@gregkilmer.com>"
|
||||||
|
|
||||||
# Optional webhook fallback (JSON POST).
|
# Optional webhook fallback (JSON POST).
|
||||||
# CONTACT_WEBHOOK_URL=
|
# CONTACT_WEBHOOK_URL=
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ RUN npm ci --no-audit --no-fund || npm install --no-audit --no-fund --legacy-pee
|
|||||||
|
|
||||||
# Copy source and build. SITE_URL can be overridden at build time.
|
# Copy source and build. SITE_URL can be overridden at build time.
|
||||||
COPY . .
|
COPY . .
|
||||||
ARG SITE_URL=https://patiun.com
|
ARG SITE_URL=https://gregkilmer.com
|
||||||
ENV SITE_URL=$SITE_URL
|
ENV SITE_URL=$SITE_URL
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
|
|||||||
+116
-66
@@ -4,15 +4,18 @@
|
|||||||
|
|
||||||
> **Design Philosophy:** The site should feel like two wings of the same house — the professional side is polished and precise; the personal side is warm and inviting. They share a consistent design language (typography, color palette, spacing) but differ in tone. Navigation makes it easy to cross between them without confusion.
|
> **Design Philosophy:** The site should feel like two wings of the same house — the professional side is polished and precise; the personal side is warm and inviting. They share a consistent design language (typography, color palette, spacing) but differ in tone. Navigation makes it easy to cross between them without confusion.
|
||||||
|
|
||||||
> **Human Voice:** Do not use emojis, use mdi icons when appropriate. Do not use em-dashes.
|
> **Human Voice:** Do not use emojis, use mdi icons when appropriate. Do not use em-dashes.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. Global Structure & Navigation
|
## 1. Global Structure & Navigation
|
||||||
|
|
||||||
### Domain
|
### Domain
|
||||||
- `patiun.com`
|
|
||||||
|
- `gregkilmer.com`
|
||||||
|
|
||||||
### Site Map
|
### Site Map
|
||||||
|
|
||||||
```
|
```
|
||||||
Home (Landing)
|
Home (Landing)
|
||||||
├── About Me
|
├── About Me
|
||||||
@@ -31,15 +34,17 @@ Home (Landing)
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Navigation Design
|
### Navigation Design
|
||||||
|
|
||||||
- **Primary nav:** Horizontal top bar with two visual groupings separated by a subtle divider:
|
- **Primary nav:** Horizontal top bar with two visual groupings separated by a subtle divider:
|
||||||
- **Left group:** Home, About
|
- **Left group:** Home, About
|
||||||
- **Right group:** Professional, Interests, Contact
|
- **Right group:** Professional, Interests, Contact
|
||||||
- The grouping signals "who I am" vs. "what I do" without labeling them that way explicitly.
|
- The grouping signals "who I am" vs. "what I do" without labeling them that way explicitly.
|
||||||
- **Persistent:** Nav remains fixed on scroll with a slight background blur on scroll.
|
- **Persistent:** Nav remains fixed on scroll with a slight background blur on scroll.
|
||||||
- **Mobile:** Hamburger menu with the same two-group structure.
|
- **Mobile:** Hamburger menu with the same two-group structure.
|
||||||
- A subtle tagline appears under the nav or in the logo area: *"Developer. Maker. Storyteller."*
|
- A subtle tagline appears under the nav or in the logo area: _"Developer. Maker. Storyteller."_
|
||||||
|
|
||||||
### Color Palette Suggestion
|
### Color Palette Suggestion
|
||||||
|
|
||||||
- **Primary:** Deep slate or charcoal (#1E293B) — professional confidence
|
- **Primary:** Deep slate or charcoal (#1E293B) — professional confidence
|
||||||
- **Accent:** Warm amber/gold (#F59E0B) — ties to the making/creative side
|
- **Accent:** Warm amber/gold (#F59E0B) — ties to the making/creative side
|
||||||
- **Secondary:** Soft Teal (#699a94) — favorite color group and works with gold and charcoal
|
- **Secondary:** Soft Teal (#699a94) — favorite color group and works with gold and charcoal
|
||||||
@@ -47,6 +52,7 @@ Home (Landing)
|
|||||||
- The palette works equally for a dark-mode resume page and a warm-toned interests page.
|
- The palette works equally for a dark-mode resume page and a warm-toned interests page.
|
||||||
|
|
||||||
### Typography
|
### Typography
|
||||||
|
|
||||||
- Headings: A geometric sans-serif (e.g., Inter, Plus Jakarta Sans)
|
- Headings: A geometric sans-serif (e.g., Inter, Plus Jakarta Sans)
|
||||||
- Body: Same family or a readable serif for longer-form reading content
|
- Body: Same family or a readable serif for longer-form reading content
|
||||||
- Accent/quotes: A monospace or display font sparingly for pull quotes or section numbers
|
- Accent/quotes: A monospace or display font sparingly for pull quotes or section numbers
|
||||||
@@ -58,6 +64,7 @@ Home (Landing)
|
|||||||
**Purpose:** First impression. A brief, compelling snapshot that makes visitors want to explore both the professional and personal sides.
|
**Purpose:** First impression. A brief, compelling snapshot that makes visitors want to explore both the professional and personal sides.
|
||||||
|
|
||||||
### Hero Section
|
### Hero Section
|
||||||
|
|
||||||
- Full-width hero with a subtle animated or gradient background (dark charcoal to warm amber at edges).
|
- Full-width hero with a subtle animated or gradient background (dark charcoal to warm amber at edges).
|
||||||
- **Headline:** `Greg Kilmer`
|
- **Headline:** `Greg Kilmer`
|
||||||
- **Subheadline:** `Software Developer • Maker • Tabletop Gamemaster`
|
- **Subheadline:** `Software Developer • Maker • Tabletop Gamemaster`
|
||||||
@@ -70,23 +77,25 @@ Home (Landing)
|
|||||||
- **Secondary (outlined):** "Explore My Interests" → links to `/interests`
|
- **Secondary (outlined):** "Explore My Interests" → links to `/interests`
|
||||||
|
|
||||||
### Below the Fold — Snapshot Grid
|
### Below the Fold — Snapshot Grid
|
||||||
|
|
||||||
A 3-column grid of cards giving a teaser for each major section. Each card has an icon, a short description, and a "Learn more →" link.
|
A 3-column grid of cards giving a teaser for each major section. Each card has an icon, a short description, and a "Learn more →" link.
|
||||||
|
|
||||||
| Card | Icon | Teaser Copy |
|
| Card | Icon | Teaser Copy |
|
||||||
|------|------|-------------|
|
| ---------------- | ---- | --------------------------------------------------------------------------------------------------------------- |
|
||||||
| **Professional** | 💼 | From SAP-adjacent cloud apps to full-stack mobile — a decade of building software that businesses actually use. |
|
| **Professional** | 💼 | From SAP-adjacent cloud apps to full-stack mobile — a decade of building software that businesses actually use. |
|
||||||
| **Tabletop** | 🎲 | Currently running two campaigns in Foundry VTT and playtesting MCDM's Crows. Always rolling dice. |
|
| **Tabletop** | 🎲 | Currently running two campaigns in Foundry VTT and playtesting MCDM's Crows. Always rolling dice. |
|
||||||
| **Making** | 🎨 | Resin dice, 3D prints, and whatever else catches my eye. If it involves layers and precision, I'm in. |
|
| **Making** | 🎨 | Resin dice, 3D prints, and whatever else catches my eye. If it involves layers and precision, I'm in. |
|
||||||
|
|
||||||
A fourth card spans the bottom or sits as a wider strip:
|
A fourth card spans the bottom or sits as a wider strip:
|
||||||
|
|
||||||
| Card | Teaser Copy |
|
| Card | Teaser Copy |
|
||||||
|------|-------------|
|
| ------------------- | ------------------------------------------------------------------------------------------- |
|
||||||
| **Reading & Media** | Deep in the Cosmere, catching up on anime, and always three books ahead on my to-read list. |
|
| **Reading & Media** | Deep in the Cosmere, catching up on anime, and always three books ahead on my to-read list. |
|
||||||
|
|
||||||
### Footer
|
### Footer
|
||||||
|
|
||||||
- Minimal footer with social links (GitHub, LinkedIn, Discord) and copyright.
|
- Minimal footer with social links (GitHub, LinkedIn, Discord) and copyright.
|
||||||
- Subtle: *"Built with intention. Powered by caffeine."*
|
- Subtle: _"Built with intention. Powered by caffeine."_
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -95,25 +104,30 @@ A fourth card spans the bottom or sits as a wider strip:
|
|||||||
**Purpose:** The human story. Who Greg is beyond the resume and the hobby list. This bridges the professional and personal sides.
|
**Purpose:** The human story. Who Greg is beyond the resume and the hobby list. This bridges the professional and personal sides.
|
||||||
|
|
||||||
### Section 1: The Short Version
|
### Section 1: The Short Version
|
||||||
|
|
||||||
> I'm Greg — a software developer based in Philadelphia who spends his free time running tabletop RPGs, making resin dice, 3D printing miniatures and props, and reading his way through fantasy series at an alarming rate. I live with my partner Krystina, our mini dachshund Kashi, and more board games than any reasonable apartment should hold.
|
> I'm Greg — a software developer based in Philadelphia who spends his free time running tabletop RPGs, making resin dice, 3D printing miniatures and props, and reading his way through fantasy series at an alarming rate. I live with my partner Krystina, our mini dachshund Kashi, and more board games than any reasonable apartment should hold.
|
||||||
|
|
||||||
### Section 2: The Longer Arc
|
### Section 2: The Longer Arc
|
||||||
> I grew up surrounded by books and games, and not much has changed. Technology pulled me into a career building cloud and mobile applications, but I never stopped collecting dice, designing campaigns, or losing weekends to Sanderson rereads. I'm currently expanding into SAP's Business Technology Platform, exploring AI and machine learning, and trying to convince my group that yes, we *can* fit one more board game into game night.
|
|
||||||
|
> I grew up surrounded by books and games, and not much has changed. Technology pulled me into a career building cloud and mobile applications, but I never stopped collecting dice, designing campaigns, or losing weekends to Sanderson rereads. I'm currently expanding into SAP's Business Technology Platform, exploring AI and machine learning, and trying to convince my group that yes, we _can_ fit one more board game into game night.
|
||||||
>
|
>
|
||||||
> I believe the best work happens when curiosity isn't compartmentalized. The same system-thinking that makes a good developer makes a good gamemaster. The patience that produces a clean resin cast is the same patience that debugs a stubborn deployment. This site is where I don't have to pretend those things are separate.
|
> I believe the best work happens when curiosity isn't compartmentalized. The same system-thinking that makes a good developer makes a good gamemaster. The patience that produces a clean resin cast is the same patience that debugs a stubborn deployment. This site is where I don't have to pretend those things are separate.
|
||||||
|
|
||||||
### Section 3: Quick Facts (Sidebar or Inline Grid)
|
### Section 3: Quick Facts (Sidebar or Inline Grid)
|
||||||
|
|
||||||
- 📍 Philadelphia, PA
|
- 📍 Philadelphia, PA
|
||||||
- 💼 Software Developer at Implico Inc.
|
- 💼 Software Developer at Implico Inc.
|
||||||
- 🐕 Dog dad to Kashi the mini dachshund
|
- 🐕 Dog dad to Kashi the mini dachshund
|
||||||
- 🎲 Running D&D & Daggerheart campaigns
|
- 🎲 Running D&D & Daggerheart campaigns
|
||||||
- 📚 Currently reading: *Heir of Fire* by Sarah J. Maas
|
- 📚 Currently reading: _Heir of Fire_ by Sarah J. Maas
|
||||||
- 🍵 Fueled by loose-leaf Chinese tea and Mountain Dew
|
- 🍵 Fueled by loose-leaf Chinese tea and Mountain Dew
|
||||||
|
|
||||||
### Flow: About → Professional & Interests
|
### Flow: About → Professional & Interests
|
||||||
|
|
||||||
The About page ends with a soft transition: a split section with two directional paths:
|
The About page ends with a soft transition: a split section with two directional paths:
|
||||||
- Left: *"See where I apply that curiosity professionally →"* (links to Professional)
|
|
||||||
- Right: *"See where it takes me outside of work →"* (links to Interests)
|
- Left: _"See where I apply that curiosity professionally →"_ (links to Professional)
|
||||||
|
- Right: _"See where it takes me outside of work →"_ (links to Interests)
|
||||||
|
|
||||||
This reinforces that the two sides are connected, not siloed.
|
This reinforces that the two sides are connected, not siloed.
|
||||||
|
|
||||||
@@ -132,22 +146,24 @@ This reinforces that the two sides are connected, not siloed.
|
|||||||
Presented as a vertical timeline with expandable detail.
|
Presented as a vertical timeline with expandable detail.
|
||||||
|
|
||||||
**Implico Inc. — Software Developer / Lead Developer / Team Lead**
|
**Implico Inc. — Software Developer / Lead Developer / Team Lead**
|
||||||
- *Focus:* Cloud and mobile application development, SAP-adjacent solutions
|
|
||||||
- *Current expansion:* SAP Business Technology Platform (BTP)
|
- _Focus:_ Cloud and mobile application development, SAP-adjacent solutions
|
||||||
- *Key bullets (template — fill in specifics):*
|
- _Current expansion:_ SAP Business Technology Platform (BTP)
|
||||||
|
- _Key bullets (template — fill in specifics):_
|
||||||
- Lead development on [cloud/mobile project], delivering [specific outcome]
|
- Lead development on [cloud/mobile project], delivering [specific outcome]
|
||||||
- Architect and maintain [system/platform], supporting [X users/clients]
|
- Architect and maintain [system/platform], supporting [X users/clients]
|
||||||
- Collaborate with cross-functional teams to translate business requirements into technical solutions
|
- Collaborate with cross-functional teams to translate business requirements into technical solutions
|
||||||
- Mentor junior developers and establish coding standards and review practices
|
- Mentor junior developers and establish coding standards and review practices
|
||||||
- Drive adoption of new technologies and frameworks within the team
|
- Drive adoption of new technologies and frameworks within the team
|
||||||
|
|
||||||
*(Note: Greg should fill in specific projects, metrics, and dates here. The structure is ready.)*
|
_(Note: Greg should fill in specific projects, metrics, and dates here. The structure is ready.)_
|
||||||
|
|
||||||
### Section 3: Skills & Technologies
|
### Section 3: Skills & Technologies
|
||||||
|
|
||||||
Organized in visual skill bars or a categorized grid. Three tiers:
|
Organized in visual skill bars or a categorized grid. Three tiers:
|
||||||
|
|
||||||
**Core Competencies**
|
**Core Competencies**
|
||||||
|
|
||||||
- Cloud Architecture & Development
|
- Cloud Architecture & Development
|
||||||
- Mobile Application Development
|
- Mobile Application Development
|
||||||
- SAP Business Technology Platform (BTP)
|
- SAP Business Technology Platform (BTP)
|
||||||
@@ -155,13 +171,15 @@ Organized in visual skill bars or a categorized grid. Three tiers:
|
|||||||
- Cross-functional Communication
|
- Cross-functional Communication
|
||||||
|
|
||||||
**Technical Stack**
|
**Technical Stack**
|
||||||
- *Languages:* [Fill in — likely JavaScript/TypeScript, Python, Java, ABAP given SAP focus]
|
|
||||||
- *Frameworks:* [Fill in]
|
- _Languages:_ [Fill in — likely JavaScript/TypeScript, Python, Java, ABAP given SAP focus]
|
||||||
- *Cloud Platforms:* SAP BCP, [others]
|
- _Frameworks:_ [Fill in]
|
||||||
- *Tools:* Git, CI/CD pipelines, [fill in]
|
- _Cloud Platforms:_ SAP BCP, [others]
|
||||||
- *AI/ML:* Hands-on experience with machine learning frameworks and LLM integration
|
- _Tools:_ Git, CI/CD pipelines, [fill in]
|
||||||
|
- _AI/ML:_ Hands-on experience with machine learning frameworks and LLM integration
|
||||||
|
|
||||||
**Emerging & Exploring**
|
**Emerging & Exploring**
|
||||||
|
|
||||||
- SAP BTP deep-dive (active expansion)
|
- SAP BTP deep-dive (active expansion)
|
||||||
- AI-powered development tooling
|
- AI-powered development tooling
|
||||||
- Advanced automation and workflow engineering
|
- Advanced automation and workflow engineering
|
||||||
@@ -171,17 +189,19 @@ Organized in visual skill bars or a categorized grid. Three tiers:
|
|||||||
A card grid of notable projects. Each card:
|
A card grid of notable projects. Each card:
|
||||||
|
|
||||||
**Project Card Template:**
|
**Project Card Template:**
|
||||||
|
|
||||||
- **Title:** [Project Name]
|
- **Title:** [Project Name]
|
||||||
- **Role:** [Role — e.g., "Lead Developer", "Solo Developer"]
|
- **Role:** [Role — e.g., "Lead Developer", "Solo Developer"]
|
||||||
- **Tech:** [Tag pills — e.g., React, Node.js, SAP BTP]
|
- **Tech:** [Tag pills — e.g., React, Node.js, SAP BTP]
|
||||||
- **Summary:** 2-3 sentence description of what the project does and Greg's contribution.
|
- **Summary:** 2-3 sentence description of what the project does and Greg's contribution.
|
||||||
- **Links:** GitHub repo, live demo (if public), or case study.
|
- **Links:** GitHub repo, live demo (if public), or case study.
|
||||||
|
|
||||||
*(Greg should populate with 3-6 projects. Placeholder cards can be used initially.)*
|
_(Greg should populate with 3-6 projects. Placeholder cards can be used initially.)_
|
||||||
|
|
||||||
### Section 5: Education & Certifications
|
### Section 5: Education & Certifications
|
||||||
|
|
||||||
*(To be filled by Greg)*
|
_(To be filled by Greg)_
|
||||||
|
|
||||||
- Education history
|
- Education history
|
||||||
- Relevant certifications (SAP, cloud, etc.)
|
- Relevant certifications (SAP, cloud, etc.)
|
||||||
|
|
||||||
@@ -193,7 +213,9 @@ A card grid of notable projects. Each card:
|
|||||||
- **Availability note:** "Open to opportunities in cloud development, SAP BTP, and technical leadership."
|
- **Availability note:** "Open to opportunities in cloud development, SAP BTP, and technical leadership."
|
||||||
|
|
||||||
### Flow Within Professional Page
|
### Flow Within Professional Page
|
||||||
|
|
||||||
The sections read as a narrative:
|
The sections read as a narrative:
|
||||||
|
|
||||||
1. **Summary** → "Here's who I am professionally"
|
1. **Summary** → "Here's who I am professionally"
|
||||||
2. **Experience** → "Here's where I've proven it"
|
2. **Experience** → "Here's where I've proven it"
|
||||||
3. **Skills** → "Here's what I bring to the table"
|
3. **Skills** → "Here's what I bring to the table"
|
||||||
@@ -210,6 +232,7 @@ Each section subtly references the last. For example, the Skills section can hig
|
|||||||
**Purpose:** This is the fun wing. It should feel warmer, more visual, and personality-driven than the professional side. It's where Greg's passions live — not as a list, but as stories and collections.
|
**Purpose:** This is the fun wing. It should feel warmer, more visual, and personality-driven than the professional side. It's where Greg's passions live — not as a list, but as stories and collections.
|
||||||
|
|
||||||
### Overall Tone for Interest Pages
|
### Overall Tone for Interest Pages
|
||||||
|
|
||||||
- More relaxed formatting — shorter paragraphs, more images, visual hierarchy through cards and grids
|
- More relaxed formatting — shorter paragraphs, more images, visual hierarchy through cards and grids
|
||||||
- Each interest page follows a consistent template but adapts to the content type:
|
- Each interest page follows a consistent template but adapts to the content type:
|
||||||
- **Header:** Title + tagline
|
- **Header:** Title + tagline
|
||||||
@@ -221,80 +244,87 @@ Each section subtly references the last. For example, the Skills section can hig
|
|||||||
|
|
||||||
### 5a. TTRPGs & Tabletop
|
### 5a. TTRPGs & Tabletop
|
||||||
|
|
||||||
**Header Tagline:** *"Three campaigns, two systems, one rolling table."*
|
**Header Tagline:** _"Three campaigns, two systems, one rolling table."_
|
||||||
|
|
||||||
**Overview:**
|
**Overview:**
|
||||||
|
|
||||||
> Tabletop gaming isn't a hobby for me — it's a practice. I run Dungeons & Dragons and Daggerheart campaigns that span years of real-time play, maintaining worlds, NPCs, and narrative threads that my players remember years later. I host everything on Foundry VTT, which lets me build the kind of dynamic, visually rich experiences that keep players invested session after session.
|
> Tabletop gaming isn't a hobby for me — it's a practice. I run Dungeons & Dragons and Daggerheart campaigns that span years of real-time play, maintaining worlds, NPCs, and narrative threads that my players remember years later. I host everything on Foundry VTT, which lets me build the kind of dynamic, visually rich experiences that keep players invested session after session.
|
||||||
>
|
>
|
||||||
> Right now, I'm also playtesting MCDM's *Crows* — Matt Colville's forthcoming RPG built around hex-crawling, faction play, and hard travel rules. The playtest has already influenced how I think about overland encounters in my own campaigns.
|
> Right now, I'm also playtesting MCDM's _Crows_ — Matt Colville's forthcoming RPG built around hex-crawling, faction play, and hard travel rules. The playtest has already influenced how I think about overland encounters in my own campaigns.
|
||||||
|
|
||||||
**Highlights (Card Grid):**
|
**Highlights (Card Grid):**
|
||||||
|
|
||||||
| Card | Content |
|
| Card | Content |
|
||||||
|------|---------|
|
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| 🐉 **Dungeons & Dragons** | Long-running campaign on Foundry VTT. Focus on rich worldbuilding, meaningful NPC relationships, and player-driven narrative. |
|
| 🐉 **Dungeons & Dragons** | Long-running campaign on Foundry VTT. Focus on rich worldbuilding, meaningful NPC relationships, and player-driven narrative. |
|
||||||
| 🗡️ **Daggerheart** | Darrington Press's dice-building RPG. Currently running a campaign — exploring how its mechanics create different story rhythms than D&D. |
|
| 🗡️ **Daggerheart** | Darrington Press's dice-building RPG. Currently running a campaign — exploring how its mechanics create different story rhythms than D&D. |
|
||||||
| 🐦 **Crows (Playtest)** | MCDM's tactical RPG in active playtest. Hex-based travel, revised travel roles, Miasma mechanics. Contributing playtest feedback. |
|
| 🐦 **Crows (Playtest)** | MCDM's tactical RPG in active playtest. Hex-based travel, revised travel roles, Miasma mechanics. Contributing playtest feedback. |
|
||||||
| 🖥️ **Foundry VTT** | Self-hosted on my home server (Cosmos Lenovo Tiny). Building custom modules, maps, and automation for campaigns. |
|
| 🖥️ **Foundry VTT** | Self-hosted on my home server (Cosmos Lenovo Tiny). Building custom modules, maps, and automation for campaigns. |
|
||||||
| 🎯 **Draw Steel** | MCDM's upcoming tactical combat game. Interested in running it when it releases. |
|
| 🎯 **Draw Steel** | MCDM's upcoming tactical combat game. Interested in running it when it releases. |
|
||||||
|
|
||||||
**Currently Playing/Running:**
|
**Currently Playing/Running:**
|
||||||
|
|
||||||
- [Campaign 1 name] — D&D, [day of week]s
|
- [Campaign 1 name] — D&D, [day of week]s
|
||||||
- [Campaign 2 name] — Daggerheart, [day of week]s
|
- [Campaign 2 name] — Daggerheart, [day of week]s
|
||||||
- Crows playtest sessions — ongoing
|
- Crows playtest sessions — ongoing
|
||||||
|
|
||||||
**Board Games Section (within TTRPGs page or as a sub-section):**
|
**Board Games Section (within TTRPGs page or as a sub-section):**
|
||||||
|
|
||||||
> Beyond RPGs, I maintain a growing board and card game collection. Favorites span strategy, deck-building, and social deduction. Game night is a regular event — and yes, there's always room for one more.
|
> Beyond RPGs, I maintain a growing board and card game collection. Favorites span strategy, deck-building, and social deduction. Game night is a regular event — and yes, there's always room for one more.
|
||||||
|
|
||||||
*(Consider a visual "shelf" or gallery showing box art for favorite games if images are available.)*
|
_(Consider a visual "shelf" or gallery showing box art for favorite games if images are available.)_
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 5b. Gaming
|
### 5b. Gaming
|
||||||
|
|
||||||
**Header Tagline:** *"If it has a screen or a controller, I've probably played it."*
|
**Header Tagline:** _"If it has a screen or a controller, I've probably played it."_
|
||||||
|
|
||||||
**Overview:**
|
**Overview:**
|
||||||
|
|
||||||
> Gaming is my other constant. I span console generations with a PlayStation 5, Nintendo Switch 2, and a Steam library that has gotten politely out of hand. I'm particularly drawn to RPGs, strategy games, and anything with a deeply layered world. If a game has lore compendiums, I'm reading them.
|
> Gaming is my other constant. I span console generations with a PlayStation 5, Nintendo Switch 2, and a Steam library that has gotten politely out of hand. I'm particularly drawn to RPGs, strategy games, and anything with a deeply layered world. If a game has lore compendiums, I'm reading them.
|
||||||
|
|
||||||
**Platforms:**
|
**Platforms:**
|
||||||
|
|
||||||
| Card | Content |
|
| Card | Content |
|
||||||
|------|---------|
|
| --------------------------------- | -------------------------------------------------------------------- |
|
||||||
| 🎮 **PlayStation 5** | Main console for AAA titles and exclusives. |
|
| 🎮 **PlayStation 5** | Main console for AAA titles and exclusives. |
|
||||||
| 🔴 **Nintendo Switch / Switch 2** | Handheld and docked. Nintendo first-party plus indie gems. |
|
| 🔴 **Nintendo Switch / Switch 2** | Handheld and docked. Nintendo first-party plus indie gems. |
|
||||||
| 💻 **Steam** | The primary PC library. Strategy, RPGs, and an ever-growing backlog. |
|
| 💻 **Steam** | The primary PC library. Strategy, RPGs, and an ever-growing backlog. |
|
||||||
|
|
||||||
**Favorite Genres:**
|
**Favorite Genres:**
|
||||||
|
|
||||||
- RPGs (both Western and JRPG)
|
- RPGs (both Western and JRPG)
|
||||||
- Strategy and tactics
|
- Strategy and tactics
|
||||||
- Open-world exploration
|
- Open-world exploration
|
||||||
- Indie darlings
|
- Indie darlings
|
||||||
|
|
||||||
**Currently Playing:** *(Greg to fill in)*
|
**Currently Playing:** _(Greg to fill in)_
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 5c. Reading & Media
|
### 5c. Reading & Media
|
||||||
|
|
||||||
**Header Tagline:** *"Perpetually three books ahead of my to-read list."*
|
**Header Tagline:** _"Perpetually three books ahead of my to-read list."_
|
||||||
|
|
||||||
**Overview:**
|
**Overview:**
|
||||||
|
|
||||||
> I read like it's a competitive sport. Fantasy is my native language — Brandon Sanderson's Cosmere is fully consumed and eagerly awaiting the next era. Frank Herbert's Dune trilogy shaped how I think about worldbuilding. Douglas Preston & Lincoln Child's Pendergast saga is my comfort reread. And I'm currently working through Sarah J. Maas's Throne of Glass series.
|
> I read like it's a competitive sport. Fantasy is my native language — Brandon Sanderson's Cosmere is fully consumed and eagerly awaiting the next era. Frank Herbert's Dune trilogy shaped how I think about worldbuilding. Douglas Preston & Lincoln Child's Pendergast saga is my comfort reread. And I'm currently working through Sarah J. Maas's Throne of Glass series.
|
||||||
>
|
>
|
||||||
> Beyond novels, I read light novels, comic books, manhwa, and manga. I watch anime and film extensively. If a story exists in any format, I'm probably consuming it.
|
> Beyond novels, I read light novels, comic books, manhwa, and manga. I watch anime and film extensively. If a story exists in any format, I'm probably consuming it.
|
||||||
|
|
||||||
**Reading Highlights (Card Grid):**
|
**Reading Highlights (Card Grid):**
|
||||||
|
|
||||||
| Card | Status |
|
| Card | Status |
|
||||||
|------|--------|
|
| --------------------------------------------------- | ----------------------------------------------------------- |
|
||||||
| ✅ **Brandon Sanderson — Cosmere** | Complete. Every novel, every era. The gold standard for me. |
|
| ✅ **Brandon Sanderson — Cosmere** | Complete. Every novel, every era. The gold standard for me. |
|
||||||
| ✅ **Frank Herbert — Dune** | Books 1-3 complete. |
|
| ✅ **Frank Herbert — Dune** | Books 1-3 complete. |
|
||||||
| 🔄 **Douglas Preston & Lincoln Child — Pendergast** | Currently rereading. Up to *Reliquary*. |
|
| 🔄 **Douglas Preston & Lincoln Child — Pendergast** | Currently rereading. Up to _Reliquary_. |
|
||||||
| 🔄 **Sarah J. Maas — Throne of Glass** | Currently on *Heir of Fire* (Book 3). |
|
| 🔄 **Sarah J. Maas — Throne of Glass** | Currently on _Heir of Fire_ (Book 3). |
|
||||||
| 🆕 **Wistoria: Wand and Sword** | Recently added to the reading list. |
|
| 🆕 **Wistoria: Wand and Sword** | Recently added to the reading list. |
|
||||||
|
|
||||||
**Anime Favorites (visual list with small banners or icons):**
|
**Anime Favorites (visual list with small banners or icons):**
|
||||||
|
|
||||||
- One Piece
|
- One Piece
|
||||||
- Bleach
|
- Bleach
|
||||||
- Gundam (all series)
|
- Gundam (all series)
|
||||||
@@ -304,44 +334,49 @@ Each section subtly references the last. For example, the Skills section can hig
|
|||||||
- Overlord
|
- Overlord
|
||||||
|
|
||||||
**Movies & TV:**
|
**Movies & TV:**
|
||||||
|
|
||||||
> Watches extensively across genres. Particularly drawn to sci-fi, fantasy, and animated film.
|
> Watches extensively across genres. Particularly drawn to sci-fi, fantasy, and animated film.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 5d. Making & Creating
|
### 5d. Making & Creating
|
||||||
|
|
||||||
**Header Tagline:** *"If it involves layers and precision, I'm in."*
|
**Header Tagline:** _"If it involves layers and precision, I'm in."_
|
||||||
|
|
||||||
**Overview:**
|
**Overview:**
|
||||||
|
|
||||||
> Making is how I decompress. I cast resin dice using pressure pots and custom molds, print miniatures and props on my Elegoo Mars 4 (resin) and Bambu Labs P1S (FDM), and generally fill my workspace with projects-in-progress. There's something deeply satisfying about taking raw material through a process and holding the finished piece — whether that's a perfect polyhedral set or a printed terrain piece for the next game session.
|
> Making is how I decompress. I cast resin dice using pressure pots and custom molds, print miniatures and props on my Elegoo Mars 4 (resin) and Bambu Labs P1S (FDM), and generally fill my workspace with projects-in-progress. There's something deeply satisfying about taking raw material through a process and holding the finished piece — whether that's a perfect polyhedral set or a printed terrain piece for the next game session.
|
||||||
|
|
||||||
**Equipment:**
|
**Equipment:**
|
||||||
|
|
||||||
| Card | Details |
|
| Card | Details |
|
||||||
|------|---------|
|
| ------------------------ | ----------------------------------------------------------------------------------------------------------- |
|
||||||
| 🎨 **Resin Dice Making** | Custom molds, pressure pot curing, pigment experimentation. Producing dice sets for personal use and gifts. |
|
| 🎨 **Resin Dice Making** | Custom molds, pressure pot curing, pigment experimentation. Producing dice sets for personal use and gifts. |
|
||||||
| 🖨️ **Elegoo Mars 4** | Resin 3D printer. Miniatures, terrain, and high-detail props. |
|
| 🖨️ **Elegoo Mars 4** | Resin 3D printer. Miniatures, terrain, and high-detail props. |
|
||||||
| 🖨️ **Bambu Labs P1S** | FDM 3D printer. Functional prints, terrain pieces, and larger prototypes. |
|
| 🖨️ **Bambu Labs P1S** | FDM 3D printer. Functional prints, terrain pieces, and larger prototypes. |
|
||||||
| 🛠️ **General Making** | Always experimenting. If there's a new technique or material, I want to try it. |
|
| 🛠️ **General Making** | Always experimenting. If there's a new technique or material, I want to try it. |
|
||||||
|
|
||||||
**Gallery Section:**
|
**Gallery Section:**
|
||||||
> *(Placeholder for photo gallery of completed projects — dice sets, prints, terrain. Highly recommended for visual impact.)*
|
|
||||||
|
> _(Placeholder for photo gallery of completed projects — dice sets, prints, terrain. Highly recommended for visual impact.)_
|
||||||
|
|
||||||
**Connection to TTRPGs:**
|
**Connection to TTRPGs:**
|
||||||
Include a subtle callout: *"Much of what I make ends up on the virtual table — custom tokens, terrain, and props for Foundry VTT campaigns."* This creates a natural link back to the TTRPGs page.
|
Include a subtle callout: _"Much of what I make ends up on the virtual table — custom tokens, terrain, and props for Foundry VTT campaigns."_ This creates a natural link back to the TTRPGs page.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 5e. Pokémon
|
### 5e. Pokémon
|
||||||
|
|
||||||
**Header Tagline:** *"Metagross supremacy. This is not up for debate."*
|
**Header Tagline:** _"Metagross supremacy. This is not up for debate."_
|
||||||
|
|
||||||
**Overview:**
|
**Overview:**
|
||||||
|
|
||||||
> Pokémon has been a lifelong obsession. From Red and Blue on the original Game Boy to modern competitive formats, I've followed the franchise through every generation. My favorite? Metagross — the iron leg Pokémon. Steel/Psychic, beautiful design, absolutely devastating in battle. No further questions.
|
> Pokémon has been a lifelong obsession. From Red and Blue on the original Game Boy to modern competitive formats, I've followed the franchise through every generation. My favorite? Metagross — the iron leg Pokémon. Steel/Psychic, beautiful design, absolutely devastating in battle. No further questions.
|
||||||
|
|
||||||
**Favorites & Team:**
|
**Favorites & Team:**
|
||||||
|
|
||||||
- **Favorite Pokémon:** Metagross
|
- **Favorite Pokémon:** Metagross
|
||||||
- **Roster:** *(Greg to fill — note: rosters should use standard Pokémon Showdown text format)*
|
- **Roster:** _(Greg to fill — note: rosters should use standard Pokémon Showdown text format)_
|
||||||
|
|
||||||
```
|
```
|
||||||
## Pokémon
|
## Pokémon
|
||||||
@@ -349,12 +384,15 @@ Include a subtle callout: *"Much of what I make ends up on the virtual table —
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Games:**
|
**Games:**
|
||||||
> *(List of mainline and spinoff titles played, if desired)*
|
|
||||||
|
> _(List of mainline and spinoff titles played, if desired)_
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Interests Page Flow
|
### Interests Page Flow
|
||||||
|
|
||||||
The interests pages should interlink naturally:
|
The interests pages should interlink naturally:
|
||||||
|
|
||||||
- **TTRPGs** ↔ **Making** (dice and terrain made for campaigns)
|
- **TTRPGs** ↔ **Making** (dice and terrain made for campaigns)
|
||||||
- **TTRPGs** ↔ **Gaming** (digital RPGs as another expression of the same impulse)
|
- **TTRPGs** ↔ **Gaming** (digital RPGs as another expression of the same impulse)
|
||||||
- **Reading** ↔ **TTRPGs** (worldbuilding inspiration flows both ways)
|
- **Reading** ↔ **TTRPGs** (worldbuilding inspiration flows both ways)
|
||||||
@@ -370,21 +408,25 @@ Each interest page should end with a "You might also like..." section suggesting
|
|||||||
**Purpose:** A single place for all ways to reach Greg — professional and social.
|
**Purpose:** A single place for all ways to reach Greg — professional and social.
|
||||||
|
|
||||||
### Layout
|
### Layout
|
||||||
|
|
||||||
Two columns:
|
Two columns:
|
||||||
|
|
||||||
**Professional:**
|
**Professional:**
|
||||||
|
|
||||||
- Email: [Professional email]
|
- Email: [Professional email]
|
||||||
- LinkedIn: [Link]
|
- LinkedIn: [Link]
|
||||||
- GitHub: [Link]
|
- GitHub: [Link]
|
||||||
- Availability note (if open to opportunities)
|
- Availability note (if open to opportunities)
|
||||||
|
|
||||||
**Personal / Social:**
|
**Personal / Social:**
|
||||||
|
|
||||||
- Discord: [Handle or link]
|
- Discord: [Handle or link]
|
||||||
- Twitter/X: [Link, if applicable]
|
- Twitter/X: [Link, if applicable]
|
||||||
- Pokémon: [Showdown or Trainer name, if shared]
|
- Pokémon: [Showdown or Trainer name, if shared]
|
||||||
- Foundry VTT: [Server link, if public]
|
- Foundry VTT: [Server link, if public]
|
||||||
|
|
||||||
**Closing note:**
|
**Closing note:**
|
||||||
|
|
||||||
> Whether you want to talk cloud architecture, debate the best Gundam series, or need a fourth for game night — reach out.
|
> Whether you want to talk cloud architecture, debate the best Gundam series, or need a fourth for game night — reach out.
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -392,14 +434,16 @@ Two columns:
|
|||||||
## 7. Cross-Page Relationships & User Journey
|
## 7. Cross-Page Relationships & User Journey
|
||||||
|
|
||||||
### For Recruiters / Hiring Managers
|
### For Recruiters / Hiring Managers
|
||||||
|
|
||||||
1. **Home** → sees the split between professional and personal → clicks "See My Work"
|
1. **Home** → sees the split between professional and personal → clicks "See My Work"
|
||||||
2. **Professional → Experience** → understands track record
|
2. **Professional → Experience** → understands track record
|
||||||
3. **Professional → Skills** → evaluates technical fit
|
3. **Professional → Skills** → evaluates technical fit
|
||||||
4. **Professional → Projects** → sees proof of ability
|
4. **Professional → Projects** → sees proof of ability
|
||||||
5. **Professional → Contact** → reaches out
|
5. **Professional → Contact** → reaches out
|
||||||
6. *Optional detour:* **About Me** → gets a sense of personality and culture fit
|
6. _Optional detour:_ **About Me** → gets a sense of personality and culture fit
|
||||||
|
|
||||||
### For Fellow Gamers / Friends
|
### For Fellow Gamers / Friends
|
||||||
|
|
||||||
1. **Home** → clicks "Explore My Interests"
|
1. **Home** → clicks "Explore My Interests"
|
||||||
2. **Interests → TTRPGs** → reads about campaigns and playtest involvement
|
2. **Interests → TTRPGs** → reads about campaigns and playtest involvement
|
||||||
3. **TTRPGs → Making** → sees terrain and dice for campaigns
|
3. **TTRPGs → Making** → sees terrain and dice for campaigns
|
||||||
@@ -407,6 +451,7 @@ Two columns:
|
|||||||
5. **Contact** → connects on Discord
|
5. **Contact** → connects on Discord
|
||||||
|
|
||||||
### For Fellow Makers
|
### For Fellow Makers
|
||||||
|
|
||||||
1. **Home** → clicks **Making** from snapshot grid
|
1. **Home** → clicks **Making** from snapshot grid
|
||||||
2. **Making** → sees equipment, process, gallery
|
2. **Making** → sees equipment, process, gallery
|
||||||
3. **Making → TTRPGs** → sees how making connects to campaigns
|
3. **Making → TTRPGs** → sees how making connects to campaigns
|
||||||
@@ -417,25 +462,30 @@ Two columns:
|
|||||||
## 8. Technical Recommendations
|
## 8. Technical Recommendations
|
||||||
|
|
||||||
### Framework
|
### Framework
|
||||||
|
|
||||||
- Static site generator (Astro, Next.js, or 11ty) for performance and easy hosting
|
- Static site generator (Astro, Next.js, or 11ty) for performance and easy hosting
|
||||||
- MDX or markdown content for blog-like sections (reading reviews, project writeups)
|
- MDX or markdown content for blog-like sections (reading reviews, project writeups)
|
||||||
- Responsive design — mobile-first
|
- Responsive design — mobile-first
|
||||||
|
|
||||||
### Hosting
|
### Hosting
|
||||||
|
|
||||||
- Vercel, Netlify, or Cloudflare Pages (free tier sufficient for a personal site)
|
- Vercel, Netlify, or Cloudflare Pages (free tier sufficient for a personal site)
|
||||||
- Custom domain via the registrar of choice
|
- Custom domain via the registrar of choice
|
||||||
|
|
||||||
### Content Management
|
### Content Management
|
||||||
|
|
||||||
- Markdown files for easy updates
|
- Markdown files for easy updates
|
||||||
- Image optimization (WebP, lazy loading)
|
- Image optimization (WebP, lazy loading)
|
||||||
- Consider a headless CMS (like Sanity or Contentful) only if Greg wants to update frequently without touching code
|
- Consider a headless CMS (like Sanity or Contentful) only if Greg wants to update frequently without touching code
|
||||||
|
|
||||||
### Performance Targets
|
### Performance Targets
|
||||||
|
|
||||||
- Lighthouse score 90+ across all categories
|
- Lighthouse score 90+ across all categories
|
||||||
- Sub-2s initial load
|
- Sub-2s initial load
|
||||||
- Accessible (WCAG 2.1 AA)
|
- Accessible (WCAG 2.1 AA)
|
||||||
|
|
||||||
### Future Expansions (Nice-to-Have)
|
### Future Expansions (Nice-to-Have)
|
||||||
|
|
||||||
- **Blog section:** For longer-form thoughts on tech, game design, or reading reviews
|
- **Blog section:** For longer-form thoughts on tech, game design, or reading reviews
|
||||||
- **Project showcase:** Deeper case studies with screenshots and writeups
|
- **Project showcase:** Deeper case studies with screenshots and writeups
|
||||||
- **Dice shop page:** If Greg ever wants to sell resin dice
|
- **Dice shop page:** If Greg ever wants to sell resin dice
|
||||||
@@ -463,6 +513,6 @@ To populate this site fully, Greg should prepare:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*Document prepared by Aurelius, the Curator 📜*
|
_Document prepared by Aurelius, the Curator 📜_
|
||||||
*Created: July 3, 2026*
|
_Created: July 3, 2026_
|
||||||
*Status: Ready for review and population by Antares*
|
_Status: Ready for review and population by Antares_
|
||||||
|
|||||||
@@ -127,20 +127,20 @@ The site runs as a Node server inside a container. Full walkthrough in
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose up -d --build
|
docker compose up -d --build
|
||||||
# Then point your reverse proxy at port 4321 with TLS for patiun.com.
|
# Then point your reverse proxy at port 4321 with TLS for gregkilmer.com.
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Scripts
|
## Scripts
|
||||||
|
|
||||||
| Script | Description |
|
| Script | Description |
|
||||||
|---|---|
|
| ----------------- | ----------------------------------------------------- |
|
||||||
| `npm run dev` | Dev server with hot reload |
|
| `npm run dev` | Dev server with hot reload |
|
||||||
| `npm run build` | Type-check (`astro check`) then build the Node server |
|
| `npm run build` | Type-check (`astro check`) then build the Node server |
|
||||||
| `npm run serve` | Run the built server (`dist/server/entry.mjs`) |
|
| `npm run serve` | Run the built server (`dist/server/entry.mjs`) |
|
||||||
| `npm run preview` | Preview the build locally |
|
| `npm run preview` | Preview the build locally |
|
||||||
| `npm run check` | Type-check only |
|
| `npm run check` | Type-check only |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ import tailwindcss from '@tailwindcss/vite';
|
|||||||
|
|
||||||
// `SITE_URL` lets us produce absolute URLs in metadata / API responses. Defaults to the
|
// `SITE_URL` lets us produce absolute URLs in metadata / API responses. Defaults to the
|
||||||
// production domain from the spec; override locally or in CI as needed.
|
// production domain from the spec; override locally or in CI as needed.
|
||||||
const SITE_URL = process.env.SITE_URL ?? 'https://patiun.com';
|
const SITE_URL = process.env.SITE_URL ?? 'https://gregkilmer.com';
|
||||||
|
|
||||||
// Astro exposes the configured server host/port to the Node adapter via env at runtime.
|
// Astro exposes the configured server host/port to the Node adapter via env at runtime.
|
||||||
// We read them here only for documentation; the adapter picks them up automatically.
|
// We read them here only for documentation; the adapter picks them up automatically.
|
||||||
|
|||||||
+3
-3
@@ -7,7 +7,7 @@
|
|||||||
# 1. Copy .env.example -> .env and fill in SMTP/contact vars.
|
# 1. Copy .env.example -> .env and fill in SMTP/contact vars.
|
||||||
# 2. `docker compose up -d --build`
|
# 2. `docker compose up -d --build`
|
||||||
# 3. Point your Cosmos reverse proxy (Traefik/Caddy/nginx) at this service on
|
# 3. Point your Cosmos reverse proxy (Traefik/Caddy/nginx) at this service on
|
||||||
# port 4321, with TLS for patiun.com.
|
# port 4321, with TLS for gregkilmer.com.
|
||||||
#
|
#
|
||||||
# See docs/DEPLOYMENT.md for the full walkthrough.
|
# See docs/DEPLOYMENT.md for the full walkthrough.
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -20,7 +20,7 @@ services:
|
|||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
args:
|
args:
|
||||||
# Canonical URL baked in at build time for metadata.
|
# Canonical URL baked in at build time for metadata.
|
||||||
SITE_URL: ${SITE_URL:-https://patiun.com}
|
SITE_URL: ${SITE_URL:-https://gregkilmer.com}
|
||||||
image: greg-profile-site:latest
|
image: greg-profile-site:latest
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
@@ -32,7 +32,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- HOST=0.0.0.0
|
- HOST=0.0.0.0
|
||||||
- PORT=4321
|
- PORT=4321
|
||||||
- SITE_URL=${SITE_URL:-https://patiun.com}
|
- SITE_URL=${SITE_URL:-https://gregkilmer.com}
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:4321/"]
|
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:4321/"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
|
|||||||
+20
-20
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
The site runs as a **Node server inside a container** on your homelab Cosmos
|
The site runs as a **Node server inside a container** on your homelab Cosmos
|
||||||
system, fronted by your reverse proxy (Traefik / Caddy / nginx) with TLS for
|
system, fronted by your reverse proxy (Traefik / Caddy / nginx) with TLS for
|
||||||
`patiun.com`.
|
`gregkilmer.com`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -18,16 +18,16 @@ At minimum, set `SITE_URL` (your canonical public URL). To enable contact-form
|
|||||||
delivery, set **either** SMTP vars **or** `CONTACT_WEBHOOK_URL` (see
|
delivery, set **either** SMTP vars **or** `CONTACT_WEBHOOK_URL` (see
|
||||||
[Contact delivery](#contact-delivery) below). Everything else is optional.
|
[Contact delivery](#contact-delivery) below). Everything else is optional.
|
||||||
|
|
||||||
| Variable | Purpose | Default |
|
| Variable | Purpose | Default |
|
||||||
|---|---|---|
|
| ----------------------------------------------------- | ----------------------------------------- | ------------------------ |
|
||||||
| `PORT` | Port the Node server binds to | `4321` |
|
| `PORT` | Port the Node server binds to | `4321` |
|
||||||
| `HOST` | Bind address (`0.0.0.0` for container) | `0.0.0.0` |
|
| `HOST` | Bind address (`0.0.0.0` for container) | `0.0.0.0` |
|
||||||
| `SITE_URL` | Canonical URL for metadata | `https://patiun.com` |
|
| `SITE_URL` | Canonical URL for metadata | `https://gregkilmer.com` |
|
||||||
| `SMTP_HOST` / `SMTP_PORT` / `SMTP_USER` / `SMTP_PASS` | SMTP relay | unset |
|
| `SMTP_HOST` / `SMTP_PORT` / `SMTP_USER` / `SMTP_PASS` | SMTP relay | unset |
|
||||||
| `SMTP_FROM` | From address for outgoing mail | derived from `SITE_URL` |
|
| `SMTP_FROM` | From address for outgoing mail | derived from `SITE_URL` |
|
||||||
| `CONTACT_TO` | Inbox that receives submissions | `greg@patiun.com` |
|
| `CONTACT_TO` | Inbox that receives submissions | `greg@gregkilmer.com` |
|
||||||
| `CONTACT_WEBHOOK_URL` | JSON webhook fallback (Discord/Slack/n8n) | unset |
|
| `CONTACT_WEBHOOK_URL` | JSON webhook fallback (Discord/Slack/n8n) | unset |
|
||||||
| `CONTACT_RATE_LIMIT` / `CONTACT_RATE_WINDOW_MIN` | Per-IP rate limit | `5` / `15` |
|
| `CONTACT_RATE_LIMIT` / `CONTACT_RATE_WINDOW_MIN` | Per-IP rate limit | `5` / `15` |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -62,23 +62,23 @@ shapes:
|
|||||||
If your Cosmos uses Traefik, add labels to the service in `docker-compose.yml`:
|
If your Cosmos uses Traefik, add labels to the service in `docker-compose.yml`:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
labels:
|
labels:
|
||||||
- "traefik.enable=true"
|
- "traefik.enable=true"
|
||||||
- "traefik.http.routers.greg-site.rule=Host(`patiun.com`)"
|
- "traefik.http.routers.greg-site.rule=Host(`gregkilmer.com`)"
|
||||||
- "traefik.http.routers.greg-site.entrypoints=websecure"
|
- "traefik.http.routers.greg-site.entrypoints=websecure"
|
||||||
- "traefik.http.routers.greg-site.tls.certresolver=your-resolver"
|
- "traefik.http.routers.greg-site.tls.certresolver=your-resolver"
|
||||||
- "traefik.http.services.greg-site.loadbalancer.server.port=4321"
|
- "traefik.http.services.greg-site.loadbalancer.server.port=4321"
|
||||||
```
|
```
|
||||||
|
|
||||||
Then drop the `ports:` mapping and join the Traefik network instead.
|
Then drop the `ports:` mapping and join the Traefik network instead.
|
||||||
|
|
||||||
### Option B — Caddy / nginx
|
### Option B — Caddy / nginx
|
||||||
|
|
||||||
Forward `patiun.com` (HTTPS) to `127.0.0.1:4321`. With Caddy, automatic TLS is a
|
Forward `gregkilmer.com` (HTTPS) to `127.0.0.1:4321`. With Caddy, automatic TLS is a
|
||||||
one-liner:
|
one-liner:
|
||||||
|
|
||||||
```caddyfile
|
```caddyfile
|
||||||
patiun.com {
|
gregkilmer.com {
|
||||||
reverse_proxy 127.0.0.1:4321
|
reverse_proxy 127.0.0.1:4321
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -131,7 +131,7 @@ If you prefer to run Node directly on the host:
|
|||||||
```bash
|
```bash
|
||||||
npm ci
|
npm ci
|
||||||
npm run build
|
npm run build
|
||||||
HOST=0.0.0.0 PORT=4321 SITE_URL=https://patiun.com node ./dist/server/entry.mjs
|
HOST=0.0.0.0 PORT=4321 SITE_URL=https://gregkilmer.com node ./dist/server/entry.mjs
|
||||||
```
|
```
|
||||||
|
|
||||||
Run it under a process manager (systemd, pm2) so it restarts on crash/boot.
|
Run it under a process manager (systemd, pm2) so it restarts on crash/boot.
|
||||||
|
|||||||
@@ -53,13 +53,13 @@ const fullTitle = title
|
|||||||
|
|
||||||
const canonical = new URL(
|
const canonical = new URL(
|
||||||
Astro.url.pathname,
|
Astro.url.pathname,
|
||||||
Astro.site ?? "https://patiun.com",
|
Astro.site ?? "https://gregkilmer.com",
|
||||||
);
|
);
|
||||||
const ogImageUrl = ogImage
|
const ogImageUrl = ogImage
|
||||||
? new URL(ogImage, Astro.site ?? "https://patiun.com").toString()
|
? new URL(ogImage, Astro.site ?? "https://gregkilmer.com").toString()
|
||||||
: new URL(
|
: new URL(
|
||||||
"/images/hero-portrait.jpg",
|
"/images/hero-portrait.jpg",
|
||||||
Astro.site ?? "https://patiun.com",
|
Astro.site ?? "https://gregkilmer.com",
|
||||||
).toString();
|
).toString();
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@ export const siteIdentity = {
|
|||||||
/** Spec tagline; appears beside the logo. */
|
/** Spec tagline; appears beside the logo. */
|
||||||
tagline: 'Developer. Maker. Storyteller.',
|
tagline: 'Developer. Maker. Storyteller.',
|
||||||
/** Spec domain. */
|
/** Spec domain. */
|
||||||
domain: 'patiun.com',
|
domain: 'gregkilmer.com',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -121,16 +121,16 @@ async function deliver(msg: Message): Promise<boolean> {
|
|||||||
});
|
});
|
||||||
const hostname = (() => {
|
const hostname = (() => {
|
||||||
try {
|
try {
|
||||||
return new URL(process.env.SITE_URL ?? 'https://patiun.com').hostname;
|
return new URL(process.env.SITE_URL ?? 'https://gregkilmer.com').hostname;
|
||||||
} catch {
|
} catch {
|
||||||
return 'patiun.com';
|
return 'gregkilmer.com';
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
await transport.sendMail({
|
await transport.sendMail({
|
||||||
from: process.env.SMTP_FROM ?? `Greg's Site <no-reply@${hostname}>`,
|
from: process.env.SMTP_FROM ?? `Greg's Site <no-reply@${hostname}>`,
|
||||||
to: process.env.CONTACT_TO ?? 'greg@patiun.com',
|
to: process.env.CONTACT_TO ?? 'greg@gregkilmer.com',
|
||||||
replyTo: `${msg.name} <${msg.email}>`,
|
replyTo: `${msg.name} <${msg.email}>`,
|
||||||
subject: `New message from ${msg.name} via patiun.com`,
|
subject: `New message from ${msg.name} via gregkilmer.com`,
|
||||||
text: `Name: ${msg.name}\nEmail: ${msg.email}\n\n${msg.message}`,
|
text: `Name: ${msg.name}\nEmail: ${msg.email}\n\n${msg.message}`,
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user