Compare commits
20 Commits
2030ab7f70
...
04277314e5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
04277314e5 | ||
|
|
dbdad57525 | ||
|
|
85c0b4356f | ||
|
|
e78efe933d | ||
|
|
31f6adf354 | ||
|
|
d58a96c2cd | ||
|
|
f0cabcd40d | ||
|
|
5b9e58cbe6 | ||
|
|
d3d6016588 | ||
|
|
7fcf78a7f4 | ||
|
|
5fbc1df91f | ||
|
|
7721471c01 | ||
|
|
5adbee5dd6 | ||
|
|
bb27679d4e | ||
|
|
19e59a0d65 | ||
|
|
467194d0b6 | ||
|
|
f562884b8d | ||
|
|
769fc68bc6 | ||
|
|
61d154e71a | ||
|
|
d1b9cb8668 |
3
.gitmodules
vendored
@ -1,3 +0,0 @@
|
|||||||
[submodule "themes/docsy"]
|
|
||||||
path = themes/docsy
|
|
||||||
url = https://github.com/google/docsy.git
|
|
||||||
11
CLAUDE.md
@ -21,6 +21,8 @@ Shrug.host is a human-scale hosting service for small organizations and projects
|
|||||||
- **Domain:** https://shrug.host/
|
- **Domain:** https://shrug.host/
|
||||||
- **Content structure:** /content/en/ (Docsy requirement)
|
- **Content structure:** /content/en/ (Docsy requirement)
|
||||||
- **Key pages:** Homepage, Hosting Plans, About
|
- **Key pages:** Homepage, Hosting Plans, About
|
||||||
|
- **Styling:** Custom SCSS overrides in assets/scss/ (see branding.md for color palette)
|
||||||
|
- **Logo:** SVG with server rack icon at assets/icons/logo.svg
|
||||||
|
|
||||||
## Services & Pricing
|
## Services & Pricing
|
||||||
- **Essential:** $25/month - Static sites, email, DNS
|
- **Essential:** $25/month - Static sites, email, DNS
|
||||||
@ -50,8 +52,17 @@ Shrug.host is a human-scale hosting service for small organizations and projects
|
|||||||
## Relationship to Shrug PW Consulting
|
## Relationship to Shrug PW Consulting
|
||||||
Operated by Neil Hanlon, same person as shrugpw.com but positioned as complementary business service rather than personal consulting brand.
|
Operated by Neil Hanlon, same person as shrugpw.com but positioned as complementary business service rather than personal consulting brand.
|
||||||
|
|
||||||
|
## Brand Guidelines
|
||||||
|
- **Color Palette:** Electric muted blue (#4f81a3) + green accent (#10b981) + professional grays
|
||||||
|
- **Logo:** Server rack with green status lights, white text for dark backgrounds
|
||||||
|
- **Tone:** Professional but approachable, infrastructure-focused
|
||||||
|
- **Typography:** Clean sans-serif, readable hierarchy
|
||||||
|
|
||||||
## Development Notes
|
## Development Notes
|
||||||
- Use Docsy theme for professional hosting company appearance
|
- Use Docsy theme for professional hosting company appearance
|
||||||
- Focus on service pages and clear pricing
|
- Focus on service pages and clear pricing
|
||||||
- Emphasize reliability and human support over technical complexity
|
- Emphasize reliability and human support over technical complexity
|
||||||
- Maintain cross-referral links to shrugpw.com where appropriate
|
- Maintain cross-referral links to shrugpw.com where appropriate
|
||||||
|
- Hugo dev server: localhost:1313 (can curl for HTML/CSS inspection)
|
||||||
|
- Brand colors implemented via Bootstrap variable overrides in _variables_project.scss
|
||||||
|
- Logo sizing and navbar styling in _styles_project.scss
|
||||||
@ -1,13 +1,14 @@
|
|||||||
FROM ghcr.io/peaceiris/hugo:v0.146.4-full AS hugo-build
|
FROM docker.io/hugomods/hugo:std-exts AS hugo-build
|
||||||
|
|
||||||
ARG SOURCE_COMMIT
|
ARG SOURCE_COMMIT
|
||||||
RUN git clone https://git.shrug.pw/shrug.host/website.git /src
|
RUN git clone https://git.shrug.pw/shrug.host/website.git /src
|
||||||
RUN git -C /src checkout ${SOURCE_COMMIT}
|
RUN git -C /src checkout ${SOURCE_COMMIT}
|
||||||
|
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
|
COPY . .
|
||||||
|
|
||||||
# Install PostCSS dependencies
|
# # Install PostCSS dependencies
|
||||||
RUN npm i -D postcss postcss-cli autoprefixer postcss-import
|
# RUN npm i -D postcss postcss-cli autoprefixer postcss-import
|
||||||
|
|
||||||
# Build the site
|
# Build the site
|
||||||
RUN hugo --minify
|
RUN hugo --minify
|
||||||
|
|||||||
251
PLAN.md
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
# shrug.host Redesign Plan
|
||||||
|
|
||||||
|
> Started: April 2026
|
||||||
|
> Rollback tag: `pre-redesign-docsy`
|
||||||
|
> Status: 🚧 In progress
|
||||||
|
|
||||||
|
## Goals
|
||||||
|
|
||||||
|
1. Replace Docsy (a documentation framework — the wrong tool for a marketing site) with a fully custom Hugo theme
|
||||||
|
2. Establish a green-led color system with proper light/dark mode support
|
||||||
|
3. Build a consistent, distinctive brand asset set (logo, favicon, badge, OG card)
|
||||||
|
4. Launch a Community & Open Source Hosting section featuring GoldenDog Linux as the first partner
|
||||||
|
5. Give the site genuine personality — "Warm Terminal" aesthetic
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Design Decisions (locked)
|
||||||
|
|
||||||
|
### Aesthetic direction: Warm Terminal
|
||||||
|
|
||||||
|
- Monospace headings feel like a server admin built this site. That's intentional.
|
||||||
|
- Serif body type creates contrast — not another sans-on-sans tech site.
|
||||||
|
- The green `●` status dot is the recurring motif. It means "running, live, real."
|
||||||
|
- Film grain on dark sections. Diagonal section breaks. Terminal-flavored accents.
|
||||||
|
- The overall feel: a zine designed by a sysadmin who has taste.
|
||||||
|
|
||||||
|
### Typography
|
||||||
|
|
||||||
|
| Role | Font | Source |
|
||||||
|
|------|------|--------|
|
||||||
|
| Headings, UI, logo wordmark | **Commit Mono** | commitmono.com — self-hosted, OFL |
|
||||||
|
| Body / prose | **Source Serif 4** | Google Fonts — self-hosted |
|
||||||
|
|
||||||
|
Both fonts are self-hosted. No external font requests at runtime.
|
||||||
|
|
||||||
|
### Color system
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* Brand */
|
||||||
|
--brand-green: #10b981; /* primary accent — CTAs, dots, links, icons */
|
||||||
|
--brand-blue: #4f81a3; /* structural chrome — navbar, dark sections */
|
||||||
|
|
||||||
|
/* Light mode */
|
||||||
|
--bg: #ffffff;
|
||||||
|
--bg-surface: #f9fafb;
|
||||||
|
--bg-elevated: #f3f4f6;
|
||||||
|
--text: #1f2937;
|
||||||
|
--text-muted: #6b7280;
|
||||||
|
--border: #e5e7eb;
|
||||||
|
|
||||||
|
/* Dark mode */
|
||||||
|
--bg: #0f1117;
|
||||||
|
--bg-surface: #16181f;
|
||||||
|
--bg-elevated: #1e2028;
|
||||||
|
--text: #f0f0f5;
|
||||||
|
--text-muted: #9ca3af;
|
||||||
|
--border: #2a2a3a;
|
||||||
|
|
||||||
|
/* GoldenDog page only */
|
||||||
|
--gd-gradient: linear-gradient(135deg, #02AA93, #67FF80);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Logo
|
||||||
|
|
||||||
|
- **Logomark**: Refined server rack — thin stroke outline (`currentColor`, adapts to light/dark), 3 green status dots (`#10b981`, always solid). The dots are the dominant element.
|
||||||
|
- **Wordmark**: `shrug` (full weight) + `.host` (lighter weight) in Commit Mono — reads as a domain name
|
||||||
|
- **Tagline**: NOT baked into the SVG. Used freely in hero copy, OG cards, etc.
|
||||||
|
- **Single SVG file** handles both light and dark via `currentColor`
|
||||||
|
|
||||||
|
### Dark mode
|
||||||
|
|
||||||
|
- Toggle in navbar, persisted via `localStorage`
|
||||||
|
- `data-theme="light|dark"` on `<html>`
|
||||||
|
- CSS custom properties swap via `[data-theme="dark"] { ... }`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Brand Asset Checklist
|
||||||
|
|
||||||
|
- [ ] `assets/icons/logo.svg` — full lockup (rack + wordmark), currentColor-aware
|
||||||
|
- [ ] `static/favicon.svg` — icon only (rack + dots, readable at 16px)
|
||||||
|
- [ ] `static/badge-powered-by-light.svg` — `● Powered by shrug.host` for dark backgrounds
|
||||||
|
- [ ] `static/badge-powered-by-dark.svg` — same for light backgrounds
|
||||||
|
- [ ] `static/images/social/og-card.svg` — updated for new color system
|
||||||
|
- [ ] Font files: `static/fonts/CommitMono-*.woff2`
|
||||||
|
- [ ] Font files: `static/fonts/SourceSerif4-*.woff2`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Technical Changes
|
||||||
|
|
||||||
|
### Removing Docsy
|
||||||
|
|
||||||
|
- Remove `github.com/google/docsy` from `go.mod` / `go.sum`
|
||||||
|
- Strip Docsy-specific config from `hugo.toml` (theme modules, navbar params, etc.)
|
||||||
|
- Delete `assets/scss/` (replaced by `assets/css/`)
|
||||||
|
- Remove `postcss.config.js` and related node deps (no longer needed)
|
||||||
|
- All Docsy shortcodes in content files (`{{< blocks/cover >}}` etc.) replaced with plain markdown + new shortcodes
|
||||||
|
|
||||||
|
### New Hugo layout structure
|
||||||
|
|
||||||
|
```
|
||||||
|
layouts/
|
||||||
|
_default/
|
||||||
|
baseof.html ← base template, data-theme toggle
|
||||||
|
single.html ← default single page
|
||||||
|
list.html ← default list
|
||||||
|
partials/
|
||||||
|
head.html ← <head>, fonts, meta, CSS
|
||||||
|
navbar.html ← nav + dark mode toggle
|
||||||
|
footer.html ← footer + cross-family links
|
||||||
|
opengraph.html ← keep existing (adapted)
|
||||||
|
twitter_cards.html ← keep existing (adapted)
|
||||||
|
schema.html ← keep existing (adapted)
|
||||||
|
index.html ← homepage
|
||||||
|
hosting/
|
||||||
|
single.html ← hosting plans layout
|
||||||
|
open-source/
|
||||||
|
single.html ← partner project layout
|
||||||
|
list.html ← open source section index
|
||||||
|
locations/
|
||||||
|
single.html ← adapted from existing
|
||||||
|
list.html ← adapted from existing
|
||||||
|
```
|
||||||
|
|
||||||
|
### New CSS structure
|
||||||
|
|
||||||
|
```
|
||||||
|
assets/css/
|
||||||
|
tokens.css ← custom properties, light/dark tokens, fonts
|
||||||
|
base.css ← reset, typography scale, body styles
|
||||||
|
components.css ← navbar, footer, cards, buttons, badges
|
||||||
|
layouts.css ← page section layouts (hero, feature grid, pricing)
|
||||||
|
```
|
||||||
|
|
||||||
|
Per-page CSS files (`pages/home.css` etc.) were planned but intentionally dropped. Page-specific styles are either inline on the element or handled by the existing four files. The flat structure is simpler at this scale.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Content Changes
|
||||||
|
|
||||||
|
### Existing pages (restyle, preserve content)
|
||||||
|
- `content/en/_index.md` — homepage, Docsy shortcodes replaced
|
||||||
|
- `content/en/hosting/_index.md` — hosting plans, shortcodes replaced
|
||||||
|
- `content/en/about/_index.md`
|
||||||
|
- `content/en/contact/_index.md`
|
||||||
|
- `content/en/locations/` — all 4 pages, layout adapted
|
||||||
|
|
||||||
|
### New content
|
||||||
|
- `content/en/open-source/_index.md` — "Community & Open Source Hosting" section index
|
||||||
|
- `content/en/open-source/goldendog.md` — GoldenDog Linux partner page
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Page Specs
|
||||||
|
|
||||||
|
### Homepage
|
||||||
|
|
||||||
|
1. **Hero** — large Commit Mono heading: "We handle your hosting / so you don't have to." Gradient text on "so you don't have to." Two CTAs (View Plans / Learn More).
|
||||||
|
2. **Feature trio** — Human-Scale Support / Reliable Infrastructure / Transparent Pricing. Green `●` dot beside each.
|
||||||
|
3. **"What We Host"** — service grid, icon-forward, monospace labels.
|
||||||
|
4. **"Powering Real Projects"** — new section. GoldenDog Linux as first entry with their paw logo. CTA to open-source section.
|
||||||
|
5. **"By Invitation Only"** — distinct visual block, not buried in body copy. Positioned as quality signal.
|
||||||
|
6. **CTA** — "Ready to get started?" with personality.
|
||||||
|
|
||||||
|
### Hosting Plans
|
||||||
|
|
||||||
|
- Proper card components (no Docsy shortcode hacks)
|
||||||
|
- Pricing numbers get gradient text treatment
|
||||||
|
- Green highlight on recommended tier
|
||||||
|
- Plan cards styled like terminal output / spec sheets
|
||||||
|
|
||||||
|
### Community & Open Source (`/open-source/`)
|
||||||
|
|
||||||
|
**Index page**: Explains the model — shrug.host hosts open source projects in exchange for a shoutout. Transparent, no cash, no lock-in. GoldenDog Linux featured as the first example.
|
||||||
|
|
||||||
|
**GoldenDog Linux page** (`/open-source/goldendog/`):
|
||||||
|
- GoldenDog paw logo + "Hosted on Shrug.host"
|
||||||
|
- Alexia's story: built a distro, didn't want to charge users or ask for donations, this deal is the honest solution
|
||||||
|
- What shrug.host provides: APT mirror / package repo (bandwidth-ready for hundreds of concurrent `apt update` runs), website hosting, docs, downloads
|
||||||
|
- GoldenDog gradient (`#02AA93` → `#67FF80`) used as accent on this page
|
||||||
|
- Technical specs callout
|
||||||
|
- Forward hook: GoldenDog Server edition coming — shrug.host ready
|
||||||
|
- Closes: "Building something open source? Get in touch."
|
||||||
|
|
||||||
|
### Locations (`/locations/`)
|
||||||
|
Restyled to match new theme. Structure preserved. Sidebar layout kept.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Work Phases
|
||||||
|
|
||||||
|
### Phase 1 — Foundation ✅
|
||||||
|
- [x] Git tag `pre-redesign-docsy`
|
||||||
|
- [x] PLAN.md written
|
||||||
|
- [x] Font files in `static/fonts/` (CommitMono ×4, SourceSerif4 ×2, all woff2)
|
||||||
|
- [x] CSS tokens / base / components / layouts written
|
||||||
|
- [x] Docsy removed from go.mod, hugo.toml, themes/, assets/scss/, node_modules/
|
||||||
|
- [x] Base layouts scaffold (baseof, head, navbar, footer)
|
||||||
|
|
||||||
|
### Phase 2 — Brand Assets ✅
|
||||||
|
- [x] Logo SVG (full lockup, currentColor-aware)
|
||||||
|
- [x] Favicon SVG (icon-only, readable at 16px)
|
||||||
|
- [x] "Powered by" badge SVGs (light + dark variants)
|
||||||
|
|
||||||
|
### Phase 3 — Core Pages ✅
|
||||||
|
- [x] Homepage
|
||||||
|
- [x] Hosting Plans
|
||||||
|
- [x] About
|
||||||
|
- [x] Contact
|
||||||
|
- [x] 404 page
|
||||||
|
|
||||||
|
### Phase 4 — New Section ✅
|
||||||
|
- [x] Open Source section index (`/open-source/`)
|
||||||
|
- [x] GoldenDog Linux partner page (`/open-source/goldendog/`)
|
||||||
|
|
||||||
|
### Phase 5 — Locations
|
||||||
|
- [x] Intentionally removed (user decision)
|
||||||
|
|
||||||
|
### Phase 6 — Polish ✅
|
||||||
|
- [x] OG card updated (dark bg, new rack style, Courier New fallback)
|
||||||
|
- [x] branding.md rewritten for Warm Terminal system
|
||||||
|
- [x] PLAN.md checklist updated
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Partner: GoldenDog Linux
|
||||||
|
|
||||||
|
- **Site**: https://goldendoglinux.org
|
||||||
|
- **Creator**: Alexia (Lexi on shrug.games team)
|
||||||
|
- **What it is**: Debian derivative, KDE Plasma desktop, based on Debian Stable cycle
|
||||||
|
- **Deal**: shrug.host hosts the infrastructure, GoldenDog mentions shrug.host — transparent, no cash changes hands
|
||||||
|
- **What we host**: APT/package mirror (primary), website, docs, downloads
|
||||||
|
- **Their brand colors**: `#02AA93` → `#67FF80` gradient (teal to lime green — harmonizes with our `#10b981`)
|
||||||
|
- **Logo**: SVG paw print with the GoldenDog gradient — located at goldendoglinux.org/img/logo.svg
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes & Decisions Log
|
||||||
|
|
||||||
|
- **2026-04**: Decided to replace Docsy entirely. It's a docs framework, not a marketing theme.
|
||||||
|
- **2026-04**: Green-led color system. Blue is structural chrome only.
|
||||||
|
- **2026-04**: Commit Mono (headings) + Source Serif 4 (body). Both self-hosted.
|
||||||
|
- **2026-04**: Tagline removed from logo SVG — used contextually instead.
|
||||||
|
- **2026-04**: Logo uses `currentColor` for rack stroke — single SVG handles light + dark.
|
||||||
|
- **2026-04**: Created `Community & Open Source Hosting` as a repeatable partner model, with GoldenDog as first entry.
|
||||||
|
- **2026-04**: "Powered by Shrug.host" badge — for GoldenDog and future partners to embed.
|
||||||
|
- **2026-04**: Locations section intentionally removed (user decision).
|
||||||
|
- **2026-04**: Per-page CSS splitting dropped — flat four-file structure is simpler at this scale.
|
||||||
|
- **2026-04**: Docsy theme directory, assets/scss/, and node_modules/ deleted — full cleanup complete.
|
||||||
|
- **2026-04**: Open source hosting framing softened — not a barter, a community relationship.
|
||||||
28
asdf
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
FROM nvcr.io/nvidia/pytorch:23.07-py3
|
||||||
|
|
||||||
|
RUN wget \
|
||||||
|
https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh \
|
||||||
|
&& mkdir /root/.conda \
|
||||||
|
&& bash Miniconda3-latest-Linux-x86_64.sh -b \
|
||||||
|
&& rm -f Miniconda3-latest-Linux-x86_64.sh
|
||||||
|
|
||||||
|
ENV PATH="/root/miniconda3/bin:${PATH}"
|
||||||
|
ARG PATH="/root/miniconda3/bin:${PATH}"
|
||||||
|
|
||||||
|
#RUN conda config --set ssl_verify no
|
||||||
|
RUN conda tos accept
|
||||||
|
RUN conda install -y python==3.12.0 pytorch==2.5.0 torchvision==0.20.0 -c pytorch -c nvidia
|
||||||
|
RUN conda install plyfile tqdm -c conda-forge
|
||||||
|
ADD ./submodules ./submodules
|
||||||
|
RUN pip install setuptools
|
||||||
|
RUN pip3.10 install submodules/simple-knn
|
||||||
|
RUN apt-get update && apt-get install libgl1 -y
|
||||||
|
RUN pip install opencv-python scipy wandb six
|
||||||
|
WORKDIR /workspace/submodules/diff-gaussian-rasterization
|
||||||
|
RUN pip3.10 install .
|
||||||
|
WORKDIR /workspace/submodules/gaussian-rasterization-grad
|
||||||
|
RUN apt-get install libglm-dev
|
||||||
|
RUN pip3.10 install .
|
||||||
|
WORKDIR /workspace
|
||||||
|
RUN pip3.10 install torchmetrics imutils einops==0.6.0 timm==0.6.12 matplotlib
|
||||||
|
COPY ./maxxvit.py /root/miniconda3/lib/python3.11/site-packages/timm/models/maxxvit.py
|
||||||
286
assets/css/base.css
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
/* ==========================================================================
|
||||||
|
SHRUG.HOST — Base Styles
|
||||||
|
Reset, typography scale, body defaults.
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Reset
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
*, *::before, *::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: var(--font-serif);
|
||||||
|
font-size: var(--text-base);
|
||||||
|
line-height: 1.7;
|
||||||
|
color: var(--text);
|
||||||
|
background-color: var(--bg);
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
transition: background-color var(--transition-md), color var(--transition-md);
|
||||||
|
min-height: 100dvh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
img, video {
|
||||||
|
max-width: 100%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--green);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: var(--green-dim);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Headings — Commit Mono for all heading levels
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.2;
|
||||||
|
color: var(--text);
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 { font-size: var(--text-5xl); }
|
||||||
|
h2 { font-size: var(--text-4xl); }
|
||||||
|
h3 { font-size: var(--text-3xl); }
|
||||||
|
h4 { font-size: var(--text-2xl); }
|
||||||
|
h5 { font-size: var(--text-xl); }
|
||||||
|
h6 { font-size: var(--text-lg); }
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
h1 { font-size: var(--text-4xl); }
|
||||||
|
h2 { font-size: var(--text-3xl); }
|
||||||
|
h3 { font-size: var(--text-2xl); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Body text — Source Serif 4
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: var(--space-4);
|
||||||
|
max-width: 68ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
p:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
strong { font-weight: 700; }
|
||||||
|
em { font-style: italic; }
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Lists
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
ul, ol {
|
||||||
|
padding-left: var(--space-6);
|
||||||
|
margin-bottom: var(--space-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: var(--space-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Status list — green dot bullets */
|
||||||
|
ul.status-list {
|
||||||
|
list-style: none;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.status-list li {
|
||||||
|
padding-left: var(--space-6);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.status-list li::before {
|
||||||
|
content: '●';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--green);
|
||||||
|
font-size: 0.6em;
|
||||||
|
top: 0.45em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Code / pre — inherit Commit Mono
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
code, kbd, samp, pre {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
background: var(--bg-elevated);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
padding: 0.1em 0.4em;
|
||||||
|
color: var(--green);
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
background: var(--bg-surface);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
padding: var(--space-6);
|
||||||
|
overflow-x: auto;
|
||||||
|
margin-bottom: var(--space-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
pre code {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Blockquote
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
border-left: 3px solid var(--green);
|
||||||
|
padding: var(--space-4) var(--space-6);
|
||||||
|
margin: var(--space-8) 0;
|
||||||
|
background: var(--bg-surface);
|
||||||
|
border-radius: 0 var(--radius-md) var(--radius-md) 0;
|
||||||
|
font-style: italic;
|
||||||
|
color: var(--text-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote p { max-width: none; }
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Horizontal rule — thin, accent-colored
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border: none;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
margin: var(--space-12) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Container utility
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: var(--max-width);
|
||||||
|
margin-inline: auto;
|
||||||
|
padding-inline: var(--space-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container--text {
|
||||||
|
max-width: var(--max-width-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Prose — used inside content areas
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.prose h2 { margin-top: var(--space-12); margin-bottom: var(--space-4); }
|
||||||
|
.prose h3 { margin-top: var(--space-8); margin-bottom: var(--space-3); }
|
||||||
|
.prose h4 { margin-top: var(--space-6); margin-bottom: var(--space-2); }
|
||||||
|
.prose p { margin-bottom: var(--space-5); }
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Screen reader only
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.sr-only {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
padding: 0;
|
||||||
|
margin: -1px;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
white-space: nowrap;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Section label — e.g. "// services" decorative monospace prefix
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.section-label {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-xs);
|
||||||
|
font-weight: 400;
|
||||||
|
letter-spacing: 0.12em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--green);
|
||||||
|
display: block;
|
||||||
|
margin-bottom: var(--space-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Status dot — the recurring leitmotif
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
display: inline-block;
|
||||||
|
width: var(--dot-size);
|
||||||
|
height: var(--dot-size);
|
||||||
|
border-radius: 50%;
|
||||||
|
background: var(--dot-color);
|
||||||
|
margin-right: var(--space-2);
|
||||||
|
flex-shrink: 0;
|
||||||
|
position: relative;
|
||||||
|
top: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot--pulse {
|
||||||
|
animation: pulse 2.4s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0%, 100% { opacity: 1; }
|
||||||
|
50% { opacity: 0.45; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Utility: gradient text
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.gradient-text {
|
||||||
|
background: linear-gradient(135deg, var(--green) 0%, var(--blue) 100%);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Utility: visually hidden but accessible
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.visually-hidden {
|
||||||
|
clip: rect(0 0 0 0);
|
||||||
|
clip-path: inset(50%);
|
||||||
|
height: 1px;
|
||||||
|
overflow: hidden;
|
||||||
|
position: absolute;
|
||||||
|
white-space: nowrap;
|
||||||
|
width: 1px;
|
||||||
|
}
|
||||||
635
assets/css/components.css
Normal file
@ -0,0 +1,635 @@
|
|||||||
|
/* ==========================================================================
|
||||||
|
SHRUG.HOST — Components
|
||||||
|
Navbar, footer, buttons, cards, badges, pricing.
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Navbar
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 100;
|
||||||
|
background: var(--blue-deep);
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.07);
|
||||||
|
backdrop-filter: blur(8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar__inner {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: 60px;
|
||||||
|
padding-inline: var(--space-6);
|
||||||
|
max-width: var(--max-width);
|
||||||
|
margin-inline: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Logo */
|
||||||
|
.navbar__logo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-3);
|
||||||
|
text-decoration: none;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar__logo svg {
|
||||||
|
height: 36px;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nav links */
|
||||||
|
.navbar__links {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-1);
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar__links a {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
font-weight: 400;
|
||||||
|
color: rgba(255, 255, 255, 0.75);
|
||||||
|
text-decoration: none;
|
||||||
|
padding: var(--space-2) var(--space-3);
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
transition: color var(--transition), background var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar__links a:hover,
|
||||||
|
.navbar__links a[aria-current="page"] {
|
||||||
|
color: #fff;
|
||||||
|
background: rgba(255, 255, 255, 0.09);
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar__links a[aria-current="page"] {
|
||||||
|
color: var(--green);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark mode toggle */
|
||||||
|
.theme-toggle {
|
||||||
|
background: none;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
color: rgba(255, 255, 255, 0.7);
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
padding: var(--space-2) var(--space-3);
|
||||||
|
margin-left: var(--space-3);
|
||||||
|
transition: color var(--transition), border-color var(--transition), background var(--transition);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-2);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle:hover {
|
||||||
|
color: #fff;
|
||||||
|
border-color: rgba(255, 255, 255, 0.4);
|
||||||
|
background: rgba(255, 255, 255, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle .icon-sun { display: none; }
|
||||||
|
.theme-toggle .icon-moon { display: inline; }
|
||||||
|
|
||||||
|
[data-theme="dark"] .theme-toggle .icon-sun { display: inline; }
|
||||||
|
[data-theme="dark"] .theme-toggle .icon-moon { display: none; }
|
||||||
|
|
||||||
|
/* Mobile hamburger */
|
||||||
|
.navbar__hamburger {
|
||||||
|
display: none;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: rgba(255, 255, 255, 0.8);
|
||||||
|
cursor: pointer;
|
||||||
|
padding: var(--space-2);
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 700px) {
|
||||||
|
.navbar__links {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 60px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
background: var(--blue-deep);
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.07);
|
||||||
|
padding: var(--space-3) var(--space-4);
|
||||||
|
gap: var(--space-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar__links.is-open {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar__links a {
|
||||||
|
display: block;
|
||||||
|
padding: var(--space-3) var(--space-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar__hamburger {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle {
|
||||||
|
margin-left: 0;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: var(--space-2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Footer
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
background: var(--bg-dark);
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 0.07);
|
||||||
|
padding: var(--space-16) 0 var(--space-8);
|
||||||
|
margin-top: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer__inner {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
gap: var(--space-8);
|
||||||
|
max-width: var(--max-width);
|
||||||
|
margin-inline: auto;
|
||||||
|
padding-inline: var(--space-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer__brand {
|
||||||
|
grid-column: 1 / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer__brand svg {
|
||||||
|
height: 32px;
|
||||||
|
width: auto;
|
||||||
|
margin-bottom: var(--space-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer__tagline {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
color: var(--text-on-dark-muted);
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer__col h4 {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--text-on-dark);
|
||||||
|
margin-bottom: var(--space-4);
|
||||||
|
letter-spacing: 0.06em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer__links {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--space-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer__links a {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
color: var(--text-on-dark-muted);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer__links a:hover {
|
||||||
|
color: var(--green);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer__bottom {
|
||||||
|
max-width: var(--max-width);
|
||||||
|
margin-inline: auto;
|
||||||
|
padding-inline: var(--space-6);
|
||||||
|
padding-top: var(--space-8);
|
||||||
|
margin-top: var(--space-8);
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 0.07);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: var(--space-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer__copy {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-xs);
|
||||||
|
color: var(--text-on-dark-muted);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer__family {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-xs);
|
||||||
|
color: var(--text-on-dark-muted);
|
||||||
|
display: flex;
|
||||||
|
gap: var(--space-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer__family a {
|
||||||
|
color: var(--text-on-dark-muted);
|
||||||
|
transition: color var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer__family a:hover {
|
||||||
|
color: var(--green);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 700px) {
|
||||||
|
.footer__inner {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
.footer__brand {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
}
|
||||||
|
.footer__bottom {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Buttons
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-2);
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
font-weight: 700;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: var(--space-3) var(--space-6);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
border: 2px solid transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all var(--transition);
|
||||||
|
white-space: nowrap;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn--primary {
|
||||||
|
background: var(--green);
|
||||||
|
color: #fff;
|
||||||
|
border-color: var(--green);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn--primary:hover {
|
||||||
|
background: var(--green-dim);
|
||||||
|
border-color: var(--green-dim);
|
||||||
|
color: #fff;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 4px 12px var(--green-glow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn--ghost {
|
||||||
|
background: transparent;
|
||||||
|
color: #fff;
|
||||||
|
border-color: rgba(255, 255, 255, 0.35);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn--ghost:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.08);
|
||||||
|
border-color: rgba(255, 255, 255, 0.6);
|
||||||
|
color: #fff;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn--ghost-dark {
|
||||||
|
background: transparent;
|
||||||
|
color: var(--text);
|
||||||
|
border-color: var(--border-strong);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn--ghost-dark:hover {
|
||||||
|
background: var(--bg-elevated);
|
||||||
|
color: var(--text);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn--sm {
|
||||||
|
font-size: var(--text-xs);
|
||||||
|
padding: var(--space-2) var(--space-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Cards
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.card {
|
||||||
|
background: var(--bg);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
padding: var(--space-8);
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
transition: transform var(--transition), box-shadow var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card__icon {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
background: var(--green-glow);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: var(--space-5);
|
||||||
|
color: var(--green);
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card__title {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-lg);
|
||||||
|
font-weight: 700;
|
||||||
|
/* Always dark text — cards have their own background regardless of section */
|
||||||
|
color: var(--text) !important;
|
||||||
|
margin-bottom: var(--space-3);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card__title .dot {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card__body {
|
||||||
|
font-size: var(--text-base);
|
||||||
|
color: var(--text-muted);
|
||||||
|
line-height: 1.65;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card__body p { margin-bottom: 0; }
|
||||||
|
|
||||||
|
/* Cards always carry their own background — headings must stay readable */
|
||||||
|
.card h3, .card h4, .card h5 {
|
||||||
|
color: var(--text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Centered block utility — for paragraphs containing inline-flex buttons */
|
||||||
|
.text-center-block {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
gap: var(--space-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Partner card heading fix */
|
||||||
|
.partner-card h4 {
|
||||||
|
color: var(--text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Pricing cards
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.pricing-card {
|
||||||
|
background: var(--bg);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
padding: var(--space-8);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
transition: transform var(--transition), box-shadow var(--transition);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pricing-card:hover {
|
||||||
|
transform: translateY(-3px);
|
||||||
|
box-shadow: var(--shadow-lg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pricing-card--featured {
|
||||||
|
border-color: var(--green);
|
||||||
|
box-shadow: 0 0 0 1px var(--green), var(--shadow-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pricing-card__badge {
|
||||||
|
position: absolute;
|
||||||
|
top: -12px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
background: var(--green);
|
||||||
|
color: #fff;
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-xs);
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
padding: var(--space-1) var(--space-4);
|
||||||
|
border-radius: 999px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pricing-card__name {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--text-muted);
|
||||||
|
margin-bottom: var(--space-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pricing-card__price {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-4xl);
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1;
|
||||||
|
margin-bottom: var(--space-1);
|
||||||
|
background: linear-gradient(135deg, var(--green) 0%, var(--blue) 100%);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pricing-card__period {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
color: var(--text-muted);
|
||||||
|
margin-bottom: var(--space-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pricing-card__divider {
|
||||||
|
border: none;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
margin: var(--space-6) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pricing-card__features {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0 0 var(--space-6);
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--space-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pricing-card__features li {
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
color: var(--text-muted);
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: var(--space-2);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pricing-card__features li::before {
|
||||||
|
content: '●';
|
||||||
|
color: var(--green);
|
||||||
|
font-size: 0.55em;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pricing-card__suitable {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-xs);
|
||||||
|
color: var(--text-faint);
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
padding-top: var(--space-4);
|
||||||
|
margin-top: auto;
|
||||||
|
padding-top: var(--space-4);
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Inline badge (e.g. "By Invitation Only")
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-2);
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-xs);
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.06em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
padding: var(--space-1) var(--space-3);
|
||||||
|
border-radius: 999px;
|
||||||
|
border: 1px solid currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge--green {
|
||||||
|
color: var(--green);
|
||||||
|
border-color: var(--green);
|
||||||
|
background: var(--green-glow);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Invitation block — the "By Invitation Only" visual treatment
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.invitation-block {
|
||||||
|
background: var(--bg-surface);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-left: 4px solid var(--green);
|
||||||
|
border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
|
||||||
|
padding: var(--space-8) var(--space-10);
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: var(--space-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.invitation-block__dot {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
background: var(--green);
|
||||||
|
border-radius: 50%;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-top: 6px;
|
||||||
|
animation: pulse 2.4s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invitation-block__content h3 {
|
||||||
|
font-size: var(--text-xl);
|
||||||
|
margin-bottom: var(--space-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.invitation-block__content p {
|
||||||
|
color: var(--text-muted);
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Partner / project card (used in "Powering Real Projects" section)
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.partner-card {
|
||||||
|
background: var(--bg);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
padding: var(--space-6) var(--space-8);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-6);
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--text);
|
||||||
|
transition: transform var(--transition), box-shadow var(--transition);
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.partner-card:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.partner-card__logo {
|
||||||
|
width: 56px;
|
||||||
|
height: 56px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.partner-card__info h4 {
|
||||||
|
font-size: var(--text-lg);
|
||||||
|
margin-bottom: var(--space-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.partner-card__info p {
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
color: var(--text-muted);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.partner-card__arrow {
|
||||||
|
margin-left: auto;
|
||||||
|
color: var(--text-faint);
|
||||||
|
font-size: 1.25rem;
|
||||||
|
transition: transform var(--transition), color var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.partner-card:hover .partner-card__arrow {
|
||||||
|
transform: translateX(3px);
|
||||||
|
color: var(--green);
|
||||||
|
}
|
||||||
508
assets/css/layouts.css
Normal file
@ -0,0 +1,508 @@
|
|||||||
|
/* ==========================================================================
|
||||||
|
SHRUG.HOST — Page Section Layouts
|
||||||
|
Hero, feature grids, pricing grids, dark sections, etc.
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Main content wrapper
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.site-main {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Section — base padding
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.section {
|
||||||
|
padding: var(--space-24) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section--sm {
|
||||||
|
padding: var(--space-16) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section--lg {
|
||||||
|
padding: var(--space-32) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Section variants — dark, surface
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.section--dark {
|
||||||
|
background: var(--bg-dark);
|
||||||
|
color: var(--text-on-dark);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Noise grain overlay on dark sections */
|
||||||
|
.section--dark::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background-image: var(--noise);
|
||||||
|
background-repeat: repeat;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section--dark > * {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section--dark h1,
|
||||||
|
.section--dark h2,
|
||||||
|
.section--dark h3,
|
||||||
|
.section--dark h4 {
|
||||||
|
color: var(--text-on-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section--dark p {
|
||||||
|
color: var(--text-on-dark-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section--surface {
|
||||||
|
background: var(--bg-surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Diagonal section divider (bottom of a section)
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.section--diagonal-bottom {
|
||||||
|
clip-path: polygon(0 0, 100% 0, 100% calc(100% - 48px), 0 100%);
|
||||||
|
padding-bottom: calc(var(--space-24) + 48px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section--diagonal-top {
|
||||||
|
clip-path: polygon(0 48px, 100% 0, 100% 100%, 0 100%);
|
||||||
|
padding-top: calc(var(--space-24) + 48px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Hero section
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.hero {
|
||||||
|
background: var(--bg-dark);
|
||||||
|
padding: var(--space-32) 0 var(--space-24);
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Subtle grid pattern */
|
||||||
|
.hero::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background-image:
|
||||||
|
linear-gradient(rgba(16, 185, 129, 0.04) 1px, transparent 1px),
|
||||||
|
linear-gradient(90deg, rgba(16, 185, 129, 0.04) 1px, transparent 1px);
|
||||||
|
background-size: 40px 40px;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background-image: var(--noise);
|
||||||
|
background-repeat: repeat;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 0;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero > * {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero__eyebrow {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-xs);
|
||||||
|
font-weight: 400;
|
||||||
|
letter-spacing: 0.15em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--green);
|
||||||
|
margin-bottom: var(--space-5);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: var(--space-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Location rotator ───────────────────────────────────────── */
|
||||||
|
.location-rotator {
|
||||||
|
display: inline-grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.location-rotator__item {
|
||||||
|
grid-area: 1 / 1;
|
||||||
|
opacity: 0;
|
||||||
|
animation: location-rotate 15s infinite both;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* item 1 gets a slight negative delay so it's already visible at page load */
|
||||||
|
.location-rotator__item:nth-child(1) { animation-delay: -0.5s; }
|
||||||
|
.location-rotator__item:nth-child(2) { animation-delay: 3s; }
|
||||||
|
.location-rotator__item:nth-child(3) { animation-delay: 6s; }
|
||||||
|
.location-rotator__item:nth-child(4) { animation-delay: 9s; }
|
||||||
|
.location-rotator__item:nth-child(5) { animation-delay: 12s; }
|
||||||
|
|
||||||
|
@keyframes location-rotate {
|
||||||
|
0% { opacity: 0; transform: translateY(3px); }
|
||||||
|
2% { opacity: 1; transform: translateY(0); }
|
||||||
|
18% { opacity: 1; transform: translateY(0); }
|
||||||
|
20% { opacity: 0; transform: translateY(-3px); }
|
||||||
|
100% { opacity: 0; transform: translateY(-3px); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.location-rotator__item { animation: none; opacity: 0; }
|
||||||
|
.location-rotator__item:nth-child(1) { opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero__title {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: clamp(2.25rem, 5vw, 3.75rem);
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.15;
|
||||||
|
color: var(--text-on-dark);
|
||||||
|
margin-bottom: var(--space-6);
|
||||||
|
letter-spacing: -0.03em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero__title .gradient-text {
|
||||||
|
background: linear-gradient(135deg, var(--green) 0%, #6ee7b7 100%);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero__subtitle {
|
||||||
|
font-family: var(--font-serif);
|
||||||
|
font-size: var(--text-lg);
|
||||||
|
color: var(--text-on-dark-muted);
|
||||||
|
max-width: 580px;
|
||||||
|
margin: 0 auto var(--space-10);
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero__actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: var(--space-4);
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Feature grid — 3-up, responsive
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.feature-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: var(--space-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
.feature-grid {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 580px) {
|
||||||
|
.feature-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Services grid — 2x3 (6 items), responsive
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.services-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: var(--space-5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
.services-grid {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 580px) {
|
||||||
|
.services-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--space-2);
|
||||||
|
padding: var(--space-5);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
background: var(--bg);
|
||||||
|
transition: border-color var(--transition), background var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-item:hover {
|
||||||
|
border-color: var(--green);
|
||||||
|
background: var(--bg-surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-item__label {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--text);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-item__desc {
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
color: var(--text-muted);
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.55;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Pricing grid — 3-up with optional 4th enterprise row
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.pricing-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: var(--space-6);
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
.pricing-grid {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 580px) {
|
||||||
|
.pricing-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pricing-grid--enterprise {
|
||||||
|
margin-top: var(--space-10);
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Section header — centered heading + optional lead text
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.section-header {
|
||||||
|
text-align: center;
|
||||||
|
max-width: 640px;
|
||||||
|
margin: 0 auto var(--space-12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-header h2 {
|
||||||
|
margin-bottom: var(--space-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-header p {
|
||||||
|
font-size: var(--text-lg);
|
||||||
|
color: var(--text-muted);
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section--dark .section-header p {
|
||||||
|
color: var(--text-on-dark-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
CTA section
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* .cta-section is currently white (bg-surface) because the section immediately
|
||||||
|
* preceding it on the homepage is dark ("Powering Real Projects").
|
||||||
|
* If a light/surface section is ever inserted between that dark section and
|
||||||
|
* this CTA, flip background back to var(--bg-dark) and restore the text
|
||||||
|
* colors to var(--text-on-dark) / var(--text-on-dark-muted) + re-add the
|
||||||
|
* ::before noise overlay below.
|
||||||
|
*/
|
||||||
|
.cta-section {
|
||||||
|
text-align: center;
|
||||||
|
padding: var(--space-24) 0;
|
||||||
|
background: var(--bg-surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-section h2 {
|
||||||
|
color: var(--text);
|
||||||
|
font-size: var(--text-4xl);
|
||||||
|
margin-bottom: var(--space-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-section p {
|
||||||
|
color: var(--text-muted);
|
||||||
|
font-size: var(--text-lg);
|
||||||
|
max-width: 520px;
|
||||||
|
margin: 0 auto var(--space-8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Two-column content layout (used on location and partner pages)
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.content-with-sidebar {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 320px;
|
||||||
|
gap: var(--space-12);
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
.content-with-sidebar {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--space-5);
|
||||||
|
position: sticky;
|
||||||
|
top: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar__card {
|
||||||
|
background: var(--bg-surface);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
padding: var(--space-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar__card h4 {
|
||||||
|
font-size: var(--text-base);
|
||||||
|
color: var(--text) !important; /* sidebar has its own background */
|
||||||
|
margin-bottom: var(--space-4);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar__card ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--space-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar__card ul li a {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
color: var(--text-muted);
|
||||||
|
transition: color var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar__card ul li a:hover {
|
||||||
|
color: var(--green);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Page hero (inner pages — not homepage)
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.page-hero {
|
||||||
|
background: var(--bg-dark);
|
||||||
|
padding: var(--space-20) 0 var(--space-16);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-hero::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background-image: var(--noise);
|
||||||
|
background-repeat: repeat;
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0.5;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-hero > * { position: relative; z-index: 1; }
|
||||||
|
|
||||||
|
.page-hero__eyebrow {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-xs);
|
||||||
|
letter-spacing: 0.12em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--green);
|
||||||
|
margin-bottom: var(--space-3);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-hero__title {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: clamp(1.875rem, 4vw, 3rem);
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--text-on-dark);
|
||||||
|
margin-bottom: var(--space-4);
|
||||||
|
letter-spacing: -0.025em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-hero__subtitle {
|
||||||
|
font-family: var(--font-serif);
|
||||||
|
font-size: var(--text-lg);
|
||||||
|
color: var(--text-on-dark-muted);
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Breadcrumb
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.breadcrumb {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: var(--text-xs);
|
||||||
|
color: var(--text-faint);
|
||||||
|
margin-bottom: var(--space-6);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-2);
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb a {
|
||||||
|
color: var(--text-faint);
|
||||||
|
transition: color var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb a:hover {
|
||||||
|
color: var(--green);
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb__sep {
|
||||||
|
color: var(--text-faint);
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
183
assets/css/tokens.css
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
/* ==========================================================================
|
||||||
|
SHRUG.HOST — Design Tokens
|
||||||
|
CSS custom properties for the full design system.
|
||||||
|
Light mode is the default; dark mode overrides via [data-theme="dark"].
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Font faces — self-hosted, no external requests
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Commit Mono';
|
||||||
|
src: url('/fonts/CommitMono-400-Regular.woff2') format('woff2');
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Commit Mono';
|
||||||
|
src: url('/fonts/CommitMono-400-Italic.woff2') format('woff2');
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Commit Mono';
|
||||||
|
src: url('/fonts/CommitMono-700-Regular.woff2') format('woff2');
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Commit Mono';
|
||||||
|
src: url('/fonts/CommitMono-700-Italic.woff2') format('woff2');
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Source Serif 4';
|
||||||
|
src: url('/fonts/SourceSerif4.woff2') format('woff2');
|
||||||
|
font-weight: 200 900;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Source Serif 4';
|
||||||
|
src: url('/fonts/SourceSerif4-Italic.woff2') format('woff2');
|
||||||
|
font-weight: 200 900;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Light mode tokens (default)
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
/* Brand */
|
||||||
|
--green: #10b981;
|
||||||
|
--green-dim: #0d9268;
|
||||||
|
--green-glow: rgba(16, 185, 129, 0.15);
|
||||||
|
--blue: #4f81a3;
|
||||||
|
--blue-dim: #3d6580;
|
||||||
|
--blue-deep: #1e3a52;
|
||||||
|
|
||||||
|
/* Backgrounds */
|
||||||
|
--bg: #ffffff;
|
||||||
|
--bg-surface: #f9fafb;
|
||||||
|
--bg-elevated: #f3f4f6;
|
||||||
|
--bg-dark: #1e3a52; /* blue-deep sections */
|
||||||
|
--bg-darker: #0f1a24;
|
||||||
|
|
||||||
|
/* Text */
|
||||||
|
--text: #1f2937;
|
||||||
|
--text-muted: #6b7280;
|
||||||
|
--text-faint: #9ca3af;
|
||||||
|
--text-on-dark: #f0f0f5;
|
||||||
|
--text-on-dark-muted: #9ca3af;
|
||||||
|
|
||||||
|
/* Borders */
|
||||||
|
--border: #e5e7eb;
|
||||||
|
--border-strong: #d1d5db;
|
||||||
|
|
||||||
|
/* Shadows */
|
||||||
|
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04);
|
||||||
|
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08), 0 2px 4px rgba(0, 0, 0, 0.04);
|
||||||
|
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.10), 0 4px 8px rgba(0, 0, 0, 0.04);
|
||||||
|
|
||||||
|
/* Typography */
|
||||||
|
--font-mono: 'Commit Mono', 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;
|
||||||
|
--font-serif: 'Source Serif 4', 'Georgia', ui-serif, serif;
|
||||||
|
|
||||||
|
/* Type scale */
|
||||||
|
--text-xs: 0.75rem; /* 12px */
|
||||||
|
--text-sm: 0.875rem; /* 14px */
|
||||||
|
--text-base: 1rem; /* 16px */
|
||||||
|
--text-lg: 1.125rem; /* 18px */
|
||||||
|
--text-xl: 1.25rem; /* 20px */
|
||||||
|
--text-2xl: 1.5rem; /* 24px */
|
||||||
|
--text-3xl: 1.875rem; /* 30px */
|
||||||
|
--text-4xl: 2.25rem; /* 36px */
|
||||||
|
--text-5xl: 3rem; /* 48px */
|
||||||
|
--text-6xl: 3.75rem; /* 60px */
|
||||||
|
|
||||||
|
/* Spacing */
|
||||||
|
--space-1: 0.25rem;
|
||||||
|
--space-2: 0.5rem;
|
||||||
|
--space-3: 0.75rem;
|
||||||
|
--space-4: 1rem;
|
||||||
|
--space-5: 1.25rem;
|
||||||
|
--space-6: 1.5rem;
|
||||||
|
--space-8: 2rem;
|
||||||
|
--space-10: 2.5rem;
|
||||||
|
--space-12: 3rem;
|
||||||
|
--space-16: 4rem;
|
||||||
|
--space-20: 5rem;
|
||||||
|
--space-24: 6rem;
|
||||||
|
--space-32: 8rem;
|
||||||
|
|
||||||
|
/* Layout */
|
||||||
|
--max-width: 1100px;
|
||||||
|
--max-width-text: 680px;
|
||||||
|
--radius-sm: 4px;
|
||||||
|
--radius-md: 8px;
|
||||||
|
--radius-lg: 12px;
|
||||||
|
--radius-xl: 16px;
|
||||||
|
|
||||||
|
/* Transitions */
|
||||||
|
--transition: 0.18s ease;
|
||||||
|
--transition-md: 0.28s ease;
|
||||||
|
|
||||||
|
/* Status dot — the brand leitmotif */
|
||||||
|
--dot-size: 8px;
|
||||||
|
--dot-color: var(--green);
|
||||||
|
|
||||||
|
/* Noise texture overlay (SVG data URI — subtle film grain) */
|
||||||
|
--noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='0.04'/%3E%3C/svg%3E");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Dark mode overrides
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
[data-theme="dark"] {
|
||||||
|
--bg: #0f1117;
|
||||||
|
--bg-surface: #16181f;
|
||||||
|
--bg-elevated: #1e2028;
|
||||||
|
--bg-dark: #0a0e14;
|
||||||
|
--bg-darker: #060810;
|
||||||
|
|
||||||
|
--text: #f0f0f5;
|
||||||
|
--text-muted: #9ca3af;
|
||||||
|
--text-faint: #6b7280;
|
||||||
|
--text-on-dark: #f0f0f5;
|
||||||
|
--text-on-dark-muted: #9ca3af;
|
||||||
|
|
||||||
|
--border: #2a2a3a;
|
||||||
|
--border-strong: #3a3a50;
|
||||||
|
|
||||||
|
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||||
|
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4), 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||||
|
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.5), 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||||
|
|
||||||
|
--green-glow: rgba(16, 185, 129, 0.20);
|
||||||
|
|
||||||
|
--noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='0.07'/%3E%3C/svg%3E");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
GoldenDog partner page accent (scoped to .page-goldendog)
|
||||||
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.page-goldendog {
|
||||||
|
--gd-start: #02AA93;
|
||||||
|
--gd-end: #67FF80;
|
||||||
|
--gd-gradient: linear-gradient(135deg, var(--gd-start), var(--gd-end));
|
||||||
|
}
|
||||||
@ -1,29 +1,28 @@
|
|||||||
<svg width="240" height="60" viewBox="0 0 240 60" xmlns="http://www.w3.org/2000/svg">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 48" fill="none" role="img" aria-label="shrug.host">
|
||||||
|
<!--
|
||||||
|
shrug.host logo — refined server rack + Commit Mono wordmark
|
||||||
|
currentColor on rack stroke + text adapts to light/dark mode.
|
||||||
|
Status dots (#10b981) are always green — they are the life of the rack.
|
||||||
|
No tagline baked in; use contextually in page copy.
|
||||||
|
-->
|
||||||
|
|
||||||
<!-- Server/infrastructure icon -->
|
<!-- Server rack icon -->
|
||||||
<g transform="translate(10, 15)">
|
<g transform="translate(0, 4)">
|
||||||
<!-- Server rack base -->
|
<!-- Rack outline -->
|
||||||
<rect x="0" y="0" width="24" height="30" rx="2" fill="#6b7280" stroke="#9ca3af" stroke-width="1"/>
|
<rect x="2" y="2" width="36" height="36" rx="3" stroke="currentColor" stroke-width="1.5" fill="none"/>
|
||||||
|
<!-- Server slot 1 -->
|
||||||
<!-- Server rack details -->
|
<rect x="6" y="7" width="24" height="7" rx="1.5" stroke="currentColor" stroke-width="1" fill="none"/>
|
||||||
<rect x="2" y="2" width="20" height="6" rx="1" fill="#e5e7eb"/>
|
<!-- Server slot 2 -->
|
||||||
<rect x="2" y="10" width="20" height="6" rx="1" fill="#e5e7eb"/>
|
<rect x="6" y="18" width="24" height="7" rx="1.5" stroke="currentColor" stroke-width="1" fill="none"/>
|
||||||
<rect x="2" y="18" width="20" height="6" rx="1" fill="#e5e7eb"/>
|
<!-- Server slot 3 -->
|
||||||
<rect x="2" y="26" width="20" height="2" rx="1" fill="#10b981"/>
|
<rect x="6" y="29" width="24" height="7" rx="1.5" stroke="currentColor" stroke-width="1" fill="none"/>
|
||||||
|
<!-- Status dots — always green, the defining visual element -->
|
||||||
<!-- Status lights -->
|
<circle cx="34" cy="10.5" r="3" fill="#10b981"/>
|
||||||
<circle cx="20" cy="5" r="1.5" fill="#10b981"/>
|
<circle cx="34" cy="21.5" r="3" fill="#10b981"/>
|
||||||
<circle cx="20" cy="13" r="1.5" fill="#10b981"/>
|
<circle cx="34" cy="32.5" r="3" fill="#10b981"/>
|
||||||
<circle cx="20" cy="21" r="1.5" fill="#10b981"/>
|
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
<!-- Text: "shrug.host" -->
|
<!-- Wordmark: "shrug" bold + ".host" lighter weight -->
|
||||||
<text x="45" y="28" font-family="system-ui, -apple-system, sans-serif" font-size="22" font-weight="600" fill="#ffffff">
|
<text x="50" y="32" font-family="'Commit Mono', 'JetBrains Mono', ui-monospace, monospace" font-size="20" font-weight="700" fill="currentColor" letter-spacing="-0.02em">shrug</text>
|
||||||
shrug.host
|
<text x="103" y="32" font-family="'Commit Mono', 'JetBrains Mono', ui-monospace, monospace" font-size="20" font-weight="400" fill="currentColor" letter-spacing="-0.02em" opacity="0.65">.host</text>
|
||||||
</text>
|
|
||||||
|
|
||||||
<!-- Tagline -->
|
|
||||||
<text x="45" y="45" font-family="system-ui, -apple-system, sans-serif" font-size="13" fill="#e5e7eb">
|
|
||||||
hosting that just works
|
|
||||||
</text>
|
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.6 KiB |
@ -1,849 +0,0 @@
|
|||||||
// Custom project styles for shrug.host
|
|
||||||
|
|
||||||
// Brand Variables (aligned with branding.md)
|
|
||||||
$primary-color: #6b7280; // Primary neutral gray
|
|
||||||
$accent-color: #10b981; // Green for reliability/uptime
|
|
||||||
$secondary-color: #9ca3af; // Light gray
|
|
||||||
$dark-text: #374151; // Dark gray text
|
|
||||||
$light-text: #6b7280; // Medium gray text
|
|
||||||
$muted-text: #9ca3af; // Light gray text
|
|
||||||
$border-color: #e5e7eb; // Light border
|
|
||||||
$success-color: #10b981; // Green for success
|
|
||||||
|
|
||||||
$card-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
|
|
||||||
$card-shadow-hover: 0 8px 20px rgba(0, 0, 0, 0.1);
|
|
||||||
$card-radius: 12px;
|
|
||||||
$transition: all 0.2s ease;
|
|
||||||
|
|
||||||
// Fix text contrast issues
|
|
||||||
.td-cover-block {
|
|
||||||
h1, .display-1, .lead, p {
|
|
||||||
color: white !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure good contrast on colored backgrounds
|
|
||||||
.td-box--primary {
|
|
||||||
h1, h2, h3, h4, h5, h6, p, .lead {
|
|
||||||
color: white !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.td-box--dark {
|
|
||||||
h1, h2, h3, h4, h5, h6, p, .lead {
|
|
||||||
color: white !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Specific brand integrations
|
|
||||||
.btn-primary {
|
|
||||||
background-color: $accent-color !important;
|
|
||||||
border-color: $accent-color !important;
|
|
||||||
|
|
||||||
&:hover, &:focus, &:active {
|
|
||||||
background-color: darken($accent-color, 10%) !important;
|
|
||||||
border-color: darken($accent-color, 10%) !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========================================
|
|
||||||
// LOCATION PAGE STYLES
|
|
||||||
// ========================================
|
|
||||||
|
|
||||||
.location-page {
|
|
||||||
// Breadcrumb styling
|
|
||||||
.location-breadcrumb {
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
margin-top: 2rem; // Space from navbar
|
|
||||||
|
|
||||||
.breadcrumb {
|
|
||||||
background: transparent;
|
|
||||||
padding: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
|
|
||||||
.breadcrumb-item {
|
|
||||||
a {
|
|
||||||
color: $light-text;
|
|
||||||
text-decoration: none;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $accent-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
color: $muted-text;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:not(:last-child)::after {
|
|
||||||
content: "›";
|
|
||||||
color: $muted-text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Page header
|
|
||||||
.location-header {
|
|
||||||
margin-bottom: 3rem;
|
|
||||||
padding-bottom: 2rem;
|
|
||||||
border-bottom: 1px solid $border-color;
|
|
||||||
|
|
||||||
.location-title {
|
|
||||||
color: $dark-text;
|
|
||||||
font-weight: 700;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
font-size: 2.5rem;
|
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
font-size: 2rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.location-description {
|
|
||||||
color: $light-text;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
line-height: 1.6;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Content styling
|
|
||||||
.location-content {
|
|
||||||
h2 {
|
|
||||||
color: $dark-text;
|
|
||||||
font-weight: 600;
|
|
||||||
margin-top: 3rem;
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
padding-bottom: 0.5rem;
|
|
||||||
border-bottom: 2px solid $accent-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
color: $dark-text;
|
|
||||||
font-weight: 600;
|
|
||||||
margin-top: 2.5rem;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
color: $light-text;
|
|
||||||
font-weight: 600;
|
|
||||||
margin-top: 2rem;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
line-height: 1.7;
|
|
||||||
margin-bottom: 1.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul, ol {
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
|
|
||||||
li {
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
line-height: 1.6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Highlight boxes for key points
|
|
||||||
blockquote {
|
|
||||||
background: rgba($accent-color, 0.05);
|
|
||||||
border-left: 4px solid $accent-color;
|
|
||||||
padding: 1.5rem 2rem;
|
|
||||||
margin: 2rem 0;
|
|
||||||
font-style: italic;
|
|
||||||
|
|
||||||
p:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CTA section
|
|
||||||
.location-cta {
|
|
||||||
margin-top: 4rem;
|
|
||||||
|
|
||||||
.card {
|
|
||||||
border: 1px solid $border-color;
|
|
||||||
box-shadow: $card-shadow;
|
|
||||||
|
|
||||||
.card-title {
|
|
||||||
color: $dark-text;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-text {
|
|
||||||
color: $light-text;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sidebar styling
|
|
||||||
.location-sidebar {
|
|
||||||
margin-top: 2rem; // Space from navbar on mobile
|
|
||||||
|
|
||||||
@media (min-width: 992px) {
|
|
||||||
margin-top: 4rem; // Align with main content header
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
border: 1px solid $border-color;
|
|
||||||
box-shadow: $card-shadow;
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
|
|
||||||
.card-header {
|
|
||||||
background: rgba($accent-color, 0.05);
|
|
||||||
border-bottom: 1px solid $border-color;
|
|
||||||
|
|
||||||
h5 {
|
|
||||||
color: $dark-text;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-body {
|
|
||||||
a {
|
|
||||||
color: $accent-color;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: darken($accent-color, 10%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Location index page
|
|
||||||
.location-index-header {
|
|
||||||
margin-top: 2rem; // Space from navbar
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
color: $dark-text;
|
|
||||||
font-weight: 700;
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lead {
|
|
||||||
color: $light-text;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
line-height: 1.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Two-column layout for key sections
|
|
||||||
.row.two-column {
|
|
||||||
margin-top: 3rem;
|
|
||||||
margin-bottom: 3rem;
|
|
||||||
|
|
||||||
.col-md-6 {
|
|
||||||
margin-bottom: 2rem; // Space between columns on mobile
|
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
margin-bottom: 0;
|
|
||||||
padding-left: 2rem;
|
|
||||||
padding-right: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
color: $dark-text;
|
|
||||||
font-weight: 600;
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
font-size: 1.8rem;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
padding-left: 0;
|
|
||||||
list-style: none;
|
|
||||||
|
|
||||||
li {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
line-height: 1.7;
|
|
||||||
padding-left: 1.5rem;
|
|
||||||
position: relative;
|
|
||||||
font-size: 1.05rem;
|
|
||||||
text-align: left;
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
content: "✓";
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
color: $accent-color;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
strong {
|
|
||||||
color: $dark-text;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.location-card {
|
|
||||||
border: 1px solid $border-color;
|
|
||||||
box-shadow: $card-shadow;
|
|
||||||
transition: $transition;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: $card-shadow-hover;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-title a {
|
|
||||||
color: $dark-text;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $accent-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-text {
|
|
||||||
color: $light-text;
|
|
||||||
line-height: 1.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul li {
|
|
||||||
color: $light-text;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
margin-bottom: 0.3rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Global fixes for location pages
|
|
||||||
.td-content {
|
|
||||||
// Fix list indentation issues
|
|
||||||
ul:not(.list-unstyled):not(.breadcrumb) {
|
|
||||||
padding-left: 1.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ready to get started section spacing
|
|
||||||
.card.border-0.bg-primary {
|
|
||||||
margin-bottom: 3rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Global layout fixes (applies to all pages)
|
|
||||||
.td-navbar {
|
|
||||||
position: sticky;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Navbar logo sizing
|
|
||||||
.navbar-logo svg {
|
|
||||||
height: 50px !important;
|
|
||||||
width: auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide the text logo since SVG already contains text
|
|
||||||
.navbar-brand__name {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
header {
|
|
||||||
min-height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.td-main {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
min-height: 100dvh;
|
|
||||||
}
|
|
||||||
|
|
||||||
main > section:nth-of-type(-n+3) {
|
|
||||||
flex: 1 1 0;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Section spacing (global)
|
|
||||||
.td-block + .td-block {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// "Ready to get started?" section - consistent across all pages
|
|
||||||
.td-box--primary {
|
|
||||||
padding: 4rem 0 !important;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
.container {
|
|
||||||
max-width: 800px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: 2.5rem !important;
|
|
||||||
margin-bottom: 1.5rem !important;
|
|
||||||
text-align: center;
|
|
||||||
color: white !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: 1.2rem !important;
|
|
||||||
line-height: 1.6;
|
|
||||||
text-align: center;
|
|
||||||
max-width: 600px;
|
|
||||||
margin: 0 auto 2.5rem auto;
|
|
||||||
color: rgba(255, 255, 255, 0.9) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
font-size: 1.1rem;
|
|
||||||
padding: 0.75rem 2rem;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========================================
|
|
||||||
// HOMEPAGE SPECIFIC STYLES (td-home)
|
|
||||||
// ========================================
|
|
||||||
.td-home {
|
|
||||||
// Feature blocks on homepage only
|
|
||||||
.td-block {
|
|
||||||
&.td-block--dark {
|
|
||||||
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%) !important;
|
|
||||||
color: $light-text !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.td-block--primary {
|
|
||||||
background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%) !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.td-box--white {
|
|
||||||
padding: 4rem 0 !important;
|
|
||||||
|
|
||||||
.col-lg-8.mx-auto {
|
|
||||||
max-width: 95% !important;
|
|
||||||
flex: 0 0 95% !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: 2.5rem !important;
|
|
||||||
margin-bottom: 1.5rem !important;
|
|
||||||
color: $dark-text !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap; /* allow wrapping */
|
|
||||||
gap: 2rem;
|
|
||||||
align-items: stretch;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-4 {
|
|
||||||
/* default: 3 per row */
|
|
||||||
flex: 0 1 calc(33.333% - 2rem);
|
|
||||||
max-width: calc(33.333% - 2rem);
|
|
||||||
|
|
||||||
/* your existing styles */
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
text-align: center !important;
|
|
||||||
margin-bottom: 3rem;
|
|
||||||
padding: 2rem 1.5rem;
|
|
||||||
background: rgba(255, 255, 255, 0.8);
|
|
||||||
border-radius: $card-radius;
|
|
||||||
box-shadow: $card-shadow;
|
|
||||||
transition: $transition;
|
|
||||||
|
|
||||||
/* If the last row has exactly 1 item (N ≡ 1 mod 3), make it full-width */
|
|
||||||
&:last-child:nth-child(3n + 1) {
|
|
||||||
flex-basis: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the last row has exactly 2 items (N ≡ 2 mod 3), make each half-width */
|
|
||||||
&:nth-last-child(2):nth-child(3n + 1),
|
|
||||||
&:last-child:nth-child(3n + 2) {
|
|
||||||
flex-basis: calc(50% - 1rem); /* subtract half the gap so two fit perfectly */
|
|
||||||
max-width: calc(50% - 1rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 2-column layout for screens < 1200px */
|
|
||||||
@media (max-width: 1199px) {
|
|
||||||
flex: 0 1 calc(50% - 1rem);
|
|
||||||
max-width: calc(50% - 1rem);
|
|
||||||
|
|
||||||
/* Reset 3-column rules */
|
|
||||||
&:last-child:nth-child(3n + 1),
|
|
||||||
&:nth-last-child(2):nth-child(3n + 1),
|
|
||||||
&:last-child:nth-child(3n + 2) {
|
|
||||||
flex-basis: calc(50% - 1rem);
|
|
||||||
max-width: calc(50% - 1rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle odd number in 2-column: last item goes full width */
|
|
||||||
&:last-child:nth-child(odd) {
|
|
||||||
flex-basis: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 1-column layout for screens < 800px */
|
|
||||||
@media (max-width: 799px) {
|
|
||||||
flex: 0 1 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
|
|
||||||
/* Reset 3-column rules */
|
|
||||||
&:last-child:nth-child(3n + 1),
|
|
||||||
&:nth-last-child(2):nth-child(3n + 1),
|
|
||||||
&:last-child:nth-child(3n + 2) {
|
|
||||||
flex-basis: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
transform: translateY(-3px);
|
|
||||||
box-shadow: $card-shadow-hover;
|
|
||||||
}
|
|
||||||
|
|
||||||
i {
|
|
||||||
margin-bottom: 1.5rem !important;
|
|
||||||
color: $accent-color !important;
|
|
||||||
font-size: 3rem !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
h5 {
|
|
||||||
margin-bottom: 1.5rem !important;
|
|
||||||
font-weight: 600 !important;
|
|
||||||
color: $dark-text !important;
|
|
||||||
font-size: 1.3rem !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin-bottom: 0 !important;
|
|
||||||
line-height: 1.6 !important;
|
|
||||||
color: $light-text !important;
|
|
||||||
font-size: 1rem !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.td-block-feature {
|
|
||||||
background: rgba(255, 255, 255, 0.95);
|
|
||||||
border: 1px solid $border-color;
|
|
||||||
border-radius: $card-radius;
|
|
||||||
padding: 2rem;
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
box-shadow: $card-shadow;
|
|
||||||
transition: $transition;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: $card-shadow-hover;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
color: $dark-text !important;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.td-block-feature__subtitle {
|
|
||||||
color: $muted-text !important;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
color: $muted-text !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
i {
|
|
||||||
color: $muted-text !important;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
list-style: disc !important;
|
|
||||||
padding-left: 1.2rem !important;
|
|
||||||
margin-left: 0 !important;
|
|
||||||
|
|
||||||
li {
|
|
||||||
margin-bottom: 0.3rem !important;
|
|
||||||
line-height: 1.4 !important;
|
|
||||||
padding-left: 0 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p + ul, ul + p {
|
|
||||||
margin-top: 1rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========================================
|
|
||||||
// HOSTING PAGE SPECIFIC STYLES (td-section + hosting content)
|
|
||||||
// ========================================
|
|
||||||
body.td-section {
|
|
||||||
// Only target the hosting page specifically by looking for pricing cards
|
|
||||||
// This targets the hosting page's pricing sections specifically
|
|
||||||
|
|
||||||
// Pricing cards - shared styles (only for hosting page)
|
|
||||||
%pricing-card {
|
|
||||||
flex: 1;
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
background: rgba(255, 255, 255, 0.95) !important;
|
|
||||||
border-radius: 16px !important;
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.2) !important;
|
|
||||||
padding: 2rem !important;
|
|
||||||
transition: transform 0.3s ease, box-shadow 0.3s ease !important;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
transform: translateY(-4px) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3, h4 {
|
|
||||||
text-align: center !important;
|
|
||||||
font-size: 1.5rem !important;
|
|
||||||
margin-bottom: 0.5rem !important;
|
|
||||||
color: $dark-text !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Description paragraph styling (first paragraph in cards)
|
|
||||||
p:first-of-type {
|
|
||||||
text-align: center !important;
|
|
||||||
font-style: italic;
|
|
||||||
margin-bottom: 0.5rem !important;
|
|
||||||
color: $muted-text !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Target pricing paragraphs specifically using dedicated class
|
|
||||||
p.pricing {
|
|
||||||
text-align: center !important;
|
|
||||||
font-size: 2rem !important;
|
|
||||||
font-weight: 700 !important;
|
|
||||||
margin: 1rem 0 1.5rem 0 !important;
|
|
||||||
|
|
||||||
strong {
|
|
||||||
background: linear-gradient(135deg, $accent-color, darken($accent-color, 15%)) !important;
|
|
||||||
-webkit-background-clip: text !important;
|
|
||||||
-webkit-text-fill-color: transparent !important;
|
|
||||||
background-clip: text !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
text-align: left !important;
|
|
||||||
list-style: none !important;
|
|
||||||
padding-left: 1rem !important;
|
|
||||||
margin: 1rem 0 !important;
|
|
||||||
flex: 1;
|
|
||||||
|
|
||||||
li {
|
|
||||||
text-align: left !important;
|
|
||||||
margin-bottom: 0.75rem !important;
|
|
||||||
padding-left: 1.5rem !important;
|
|
||||||
position: relative;
|
|
||||||
line-height: 1.5 !important;
|
|
||||||
color: $light-text !important;
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
content: "✓";
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only apply separator styling to the "Suitable for:" paragraph in pricing cards
|
|
||||||
p:last-of-type:not(.pricing) {
|
|
||||||
// Only if it starts with "Suitable for:" (pricing card specific)
|
|
||||||
&[data-suitable-for],
|
|
||||||
&.suitable-for {
|
|
||||||
text-align: center !important;
|
|
||||||
margin-top: auto !important;
|
|
||||||
padding-top: 1.5rem !important;
|
|
||||||
margin-bottom: 0 !important;
|
|
||||||
font-weight: 600 !important;
|
|
||||||
color: $light-text !important;
|
|
||||||
border-top: 1px solid $border-color !important;
|
|
||||||
margin-left: -2rem !important;
|
|
||||||
margin-right: -2rem !important;
|
|
||||||
padding-left: 2rem !important;
|
|
||||||
padding-right: 2rem !important;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p, strong, li {
|
|
||||||
color: $light-text !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dark pricing section (hosting page)
|
|
||||||
.td-box--dark {
|
|
||||||
.row {
|
|
||||||
display: flex;
|
|
||||||
align-items: stretch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-4 {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
.mb-4.h1 {
|
|
||||||
background: transparent !important;
|
|
||||||
border: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
margin-bottom: 2rem !important;
|
|
||||||
|
|
||||||
i {
|
|
||||||
font-size: 3rem !important;
|
|
||||||
color: rgba(255, 255, 255, 0.9) !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h3, h4 {
|
|
||||||
margin-bottom: 1.5rem !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
> div:not(.mb-4) {
|
|
||||||
@extend %pricing-card;
|
|
||||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12) !important;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.18) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul li:before {
|
|
||||||
color: $success-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Primary pricing section (hosting page)
|
|
||||||
.td-box--primary {
|
|
||||||
.row {
|
|
||||||
display: flex;
|
|
||||||
align-items: stretch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-lg-4 {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
.mb-4.h1 {
|
|
||||||
background: transparent !important;
|
|
||||||
border: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
margin-bottom: 2rem !important;
|
|
||||||
|
|
||||||
i {
|
|
||||||
font-size: 3rem !important;
|
|
||||||
color: $accent-color !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h3, h4 {
|
|
||||||
margin-bottom: 1.5rem !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
> div:not(.mb-4) {
|
|
||||||
@extend %pricing-card;
|
|
||||||
background: rgba(255, 255, 255, 0.98) !important;
|
|
||||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08) !important;
|
|
||||||
border: 1px solid $border-color !important;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
transform: translateY(-3px) !important;
|
|
||||||
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.12) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-size: 1.4rem !important;
|
|
||||||
margin-bottom: 1rem !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul li:before {
|
|
||||||
color: $accent-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getting Started section (also appears on hosting page)
|
|
||||||
.td-box--white {
|
|
||||||
padding: 4rem 0 !important;
|
|
||||||
|
|
||||||
.col-lg-8.mx-auto {
|
|
||||||
max-width: 95% !important;
|
|
||||||
flex: 0 0 95% !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: 2.5rem !important;
|
|
||||||
margin-bottom: 1.5rem !important;
|
|
||||||
color: $dark-text !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
|
||||||
display: flex;
|
|
||||||
align-items: stretch;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 1rem;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
margin-top: 4rem;
|
|
||||||
@media (max-width: 1199px) {
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.col-md-4 {
|
|
||||||
@media (max-width: 1199px) {
|
|
||||||
min-width: 469px;
|
|
||||||
}
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
text-align: center !important;
|
|
||||||
margin-bottom: 3rem;
|
|
||||||
padding: 2rem 1.5rem;
|
|
||||||
flex: 1;
|
|
||||||
background: rgba(255, 255, 255, 0.8);
|
|
||||||
border-radius: $card-radius;
|
|
||||||
box-shadow: $card-shadow;
|
|
||||||
transition: $transition;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
transform: translateY(-3px);
|
|
||||||
box-shadow: $card-shadow-hover;
|
|
||||||
}
|
|
||||||
|
|
||||||
i {
|
|
||||||
margin-bottom: 1.5rem !important;
|
|
||||||
color: $accent-color !important;
|
|
||||||
font-size: 3rem !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
h5 {
|
|
||||||
margin-bottom: 1.5rem !important;
|
|
||||||
font-weight: 600 !important;
|
|
||||||
color: $dark-text !important;
|
|
||||||
font-size: 1.3rem !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin-bottom: 0 !important;
|
|
||||||
line-height: 1.6 !important;
|
|
||||||
color: $light-text !important;
|
|
||||||
font-size: 1rem !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
Override Bootstrap and Docsy variables for shrug.host brand alignment
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Brand color palette (from logo)
|
|
||||||
$shrug-primary: #6b7280; // Server rack base color
|
|
||||||
$shrug-accent: #10b981; // Green status lights
|
|
||||||
$shrug-secondary: #9ca3af; // Server rack stroke
|
|
||||||
$shrug-text-primary: #374151; // Main logo text
|
|
||||||
$shrug-text-secondary: #6b7280; // Tagline text
|
|
||||||
$shrug-bg-elements: #e5e7eb; // Server modules
|
|
||||||
|
|
||||||
// Override Bootstrap color variables - more subtle approach
|
|
||||||
$primary: #4f81a3 !default; // Muted blue that complements our gray palette
|
|
||||||
$secondary: $shrug-secondary !default; // Use our light gray as secondary
|
|
||||||
$success: $shrug-accent !default; // Use our green for success states
|
|
||||||
$info: #c0e0de !default; // Keep existing info color
|
|
||||||
$warning: #ffa630 !default; // Keep existing warning color
|
|
||||||
$danger: #ed6a5a !default; // Keep existing danger color
|
|
||||||
$light: $shrug-bg-elements !default; // Use our background color
|
|
||||||
$dark: $shrug-text-primary !default; // Use our dark text color
|
|
||||||
|
|
||||||
// Text colors - keep readable
|
|
||||||
$body-color: $shrug-text-primary !default;
|
|
||||||
$headings-color: $shrug-text-primary !default;
|
|
||||||
|
|
||||||
// Link colors - use our accent sparingly
|
|
||||||
$link-color: $shrug-accent !default;
|
|
||||||
$link-hover-color: darken($shrug-accent, 15%) !default;
|
|
||||||
|
|
||||||
// Border colors
|
|
||||||
$border-color: $shrug-bg-elements !default;
|
|
||||||
115
branding.md
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
# shrug.host — Brand Guidelines
|
||||||
|
|
||||||
|
Last updated: April 2026 (Warm Terminal redesign)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Aesthetic Direction: Warm Terminal
|
||||||
|
|
||||||
|
The feel of a well-maintained Linux box: precise, reliable, lived-in, not corporate. Monospace headings signal that infrastructure people built this site — intentionally. Serif body type creates contrast and warmth. The green status dot is the recurring motif throughout: it means "running, live, real."
|
||||||
|
|
||||||
|
Not: enterprise cold steel, generic SaaS purple gradients, bootstrap defaults.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Color System
|
||||||
|
|
||||||
|
All colors defined as CSS custom properties in `assets/css/tokens.css`. Light mode is default; dark mode via `[data-theme="dark"]` on `<html>`.
|
||||||
|
|
||||||
|
### Brand colors (theme-invariant)
|
||||||
|
|
||||||
|
| Token | Value | Use |
|
||||||
|
|---|---|---|
|
||||||
|
| `--green` | `#10b981` | Primary accent: CTAs, dots, links, icons |
|
||||||
|
| `--blue` | `#4f81a3` | Structural chrome: navbar, dark section backgrounds |
|
||||||
|
| `--blue-deep` | `#1e3a52` | Deepest backgrounds: navbar, hero, OG card |
|
||||||
|
|
||||||
|
Green leads. Blue structures.
|
||||||
|
|
||||||
|
### Light mode tokens
|
||||||
|
|
||||||
|
`--bg: #ffffff` · `--bg-surface: #f9fafb` · `--bg-elevated: #f3f4f6`
|
||||||
|
`--text: #1f2937` · `--text-muted: #6b7280` · `--text-faint: #9ca3af` · `--border: #e5e7eb`
|
||||||
|
|
||||||
|
### Dark mode tokens
|
||||||
|
|
||||||
|
`--bg: #0f1117` · `--bg-surface: #16181f` · `--bg-elevated: #1e2028`
|
||||||
|
`--text: #f0f0f5` · `--text-muted: #9ca3af` · `--text-faint: #6b7280` · `--border: #2a2a3a`
|
||||||
|
|
||||||
|
### Partner accent (GoldenDog Linux, scoped to `.page-goldendog`)
|
||||||
|
|
||||||
|
`--gd-gradient: linear-gradient(135deg, #02AA93, #67FF80)` — harmonizes with `--green`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Typography
|
||||||
|
|
||||||
|
Both fonts self-hosted in `static/fonts/` as woff2. No external font requests.
|
||||||
|
|
||||||
|
**Headings / UI / logo:** Commit Mono (`font-family: 'Commit Mono', 'JetBrains Mono', ui-monospace, monospace`)
|
||||||
|
- Weights 400 + 700, roman + italic
|
||||||
|
- `-0.02em` letter-spacing on headings; `+0.06–0.12em` on small uppercase labels
|
||||||
|
|
||||||
|
**Body / prose:** Source Serif 4 (`font-family: 'Source Serif 4', 'Georgia', ui-serif, serif`)
|
||||||
|
- Variable font, `opsz` 8–60, `wght` 200–900
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Logo
|
||||||
|
|
||||||
|
**File:** `assets/icons/logo.svg` — single SVG, light + dark via `currentColor`.
|
||||||
|
|
||||||
|
- Rack outline + slot lines: `currentColor` (adapts automatically)
|
||||||
|
- Status dots: always `#10b981` — the dominant visual element
|
||||||
|
- Wordmark: `shrug` weight 700 + `.host` weight 400 at 0.65 opacity
|
||||||
|
- No tagline baked in
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Brand Assets
|
||||||
|
|
||||||
|
| Asset | File |
|
||||||
|
|---|---|
|
||||||
|
| Full logo | `assets/icons/logo.svg` |
|
||||||
|
| Favicon | `static/favicon.svg` + `static/favicon.ico` |
|
||||||
|
| OG card | `static/images/social/og-card.svg` (1200×630) |
|
||||||
|
| Badge (light bg) | `static/badge-powered-by-dark.svg` |
|
||||||
|
| Badge (dark bg) | `static/badge-powered-by-light.svg` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## The Green Dot
|
||||||
|
|
||||||
|
`●` is the recurring motif. Appears in section eyebrows, list items, service labels, sidebar status, favicon, OG card, partner badge. Does **not** appear on card titles (too noisy).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tone
|
||||||
|
|
||||||
|
Direct, never corporate. Sounds like a systems engineer you'd want to work with. Avoid "enterprise-grade", "cutting-edge", excessive superlatives, transactional framing for community hosting.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CSS Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
assets/css/
|
||||||
|
tokens.css ← custom properties, font-faces, light/dark tokens
|
||||||
|
base.css ← reset, typography, body defaults
|
||||||
|
components.css ← navbar, footer, buttons, cards, badges, pricing
|
||||||
|
layouts.css ← section layouts, hero, grids
|
||||||
|
```
|
||||||
|
|
||||||
|
Vanilla CSS. No Sass, no Bootstrap, no external dependencies. Per-page CSS splitting intentionally dropped — flat four-file structure is simpler at this scale.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## The Shrug Family
|
||||||
|
|
||||||
|
| Brand | Site | Theme |
|
||||||
|
|---|---|---|
|
||||||
|
| Shrug PW Consulting | shrugpw.com | IBM Plex Mono, near-monochrome PaperMod |
|
||||||
|
| shrug.games | shrug.games | Purple/cyan dark, fully custom |
|
||||||
|
| GoldenDog Linux | goldendoglinux.org | Partner — Debian derivative by Alexia |
|
||||||
|
| thepotato.tech | thepotato.tech | Bootstrap, blue accent, personal blog |
|
||||||
|
| shrug.pw | shrug.pw | Animated kaomoji, deliberately anti-site |
|
||||||
@ -1,82 +1,4 @@
|
|||||||
---
|
---
|
||||||
title: "Shrug.host"
|
title: "shrug.host — Managed Hosting for Small Organizations"
|
||||||
linkTitle: "Home"
|
description: "Human-scale managed hosting for small organizations and open source projects. Starting at $25/month."
|
||||||
---
|
---
|
||||||
|
|
||||||
{{< blocks/cover title="We handle your hosting so you don't have to" image_anchor="top" height="auto" >}}
|
|
||||||
<a class="btn btn-lg btn-primary me-3 mb-4" href="/hosting/">
|
|
||||||
View Hosting Plans <i class="fas fa-arrow-alt-circle-right ms-2"></i>
|
|
||||||
</a>
|
|
||||||
<a class="btn btn-lg btn-secondary me-3 mb-4" href="/about/">
|
|
||||||
Learn More <i class="fab fa-github ms-2 "></i>
|
|
||||||
</a>
|
|
||||||
<p class="lead mt-5">Human-scale hosting for small organizations and projects that need reliability without enterprise complexity.</p>
|
|
||||||
{{< /blocks/cover >}}
|
|
||||||
|
|
||||||
{{% blocks/lead color="primary" %}}
|
|
||||||
**Low-drama hosting that actually works.**
|
|
||||||
|
|
||||||
Static sites, email, DNS, and lightweight applications. Personal support, transparent pricing, no vendor lock-in.
|
|
||||||
|
|
||||||
{{% /blocks/lead %}}
|
|
||||||
|
|
||||||
{{% blocks/section color="dark" type="row" %}}
|
|
||||||
{{% blocks/feature icon="fa-lightbulb" title="Human-Scale Support" %}}
|
|
||||||
Real people, not ticket systems. We know your setup and respond quickly when you need help.
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fa-shield-alt" title="Reliable Infrastructure" %}}
|
|
||||||
Modern, redundant systems designed for uptime. No cutting-edge experiments with your critical services.
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fa-dollar-sign" title="Transparent Pricing" %}}
|
|
||||||
$25-75/month for most setups. No surprise charges, no vendor lock-in, no subscription traps.
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{% /blocks/section %}}
|
|
||||||
|
|
||||||
{{% blocks/lead color="white" type="row" %}}
|
|
||||||
## What We Host
|
|
||||||
|
|
||||||
{{% blocks/section color="white" type="row" %}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-code" title="Static Websites" %}}
|
|
||||||
Hugo, Jekyll, React, Vue, or plain HTML sites with lightning-fast delivery and automatic SSL certificates.
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-envelope" title="Email & DNS" %}}
|
|
||||||
Professional email with your domain, complete DNS management, and anti-spam protection that actually works.
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-cloud" title="File Storage" %}}
|
|
||||||
Nextcloud instances for secure file sharing, document collaboration, and team coordination.
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-comments" title="Communication" %}}
|
|
||||||
Discourse forums for community discussions and Matrix chat for real-time team communication.
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-database" title="Small Databases" %}}
|
|
||||||
PostgreSQL and MySQL databases for lightweight applications and content management systems.
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-cogs" title="Custom Applications" %}}
|
|
||||||
APIs, microservices, and lightweight web applications tailored to your organization's specific needs.
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{% /blocks/section %}}
|
|
||||||
|
|
||||||
All hosted on **modern infrastructure** with automated backups, monitoring, and security updates.
|
|
||||||
|
|
||||||
**By invitation or referral only** - we keep our community small and focused on organizations that value quality over quantity.
|
|
||||||
|
|
||||||
{{< /blocks/lead >}}
|
|
||||||
|
|
||||||
{{% blocks/section color="primary" %}}
|
|
||||||
## Ready to get started?
|
|
||||||
|
|
||||||
<a class="btn btn-lg btn-light me-3 mb-4" href="mailto:hello@shrug.host">
|
|
||||||
Get in Touch <i class="fas fa-envelope ms-2"></i>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
{{% /blocks/section %}}
|
|
||||||
|
|||||||
@ -1,114 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: "About Shrug.host"
|
title: "About shrug.host"
|
||||||
linkTitle: "About"
|
description: "shrug.host is a one-person managed hosting service for small organizations. Real support, reliable infrastructure, no enterprise complexity."
|
||||||
weight: 30
|
weight: 40
|
||||||
menu:
|
|
||||||
main:
|
|
||||||
weight: 30
|
|
||||||
---
|
---
|
||||||
|
|
||||||
{{< blocks/cover title="About Shrug.host" image_anchor="top" height="min" color="primary" >}}
|
|
||||||
<p class="lead mt-5">We handle your hosting so you don't have to.</p>
|
|
||||||
{{< /blocks/cover >}}
|
|
||||||
|
|
||||||
{{% blocks/lead color="white" %}}
|
|
||||||
Human-scale hosting for small organizations that need reliability without enterprise complexity. We're the hosting service you wish existed: personal support, transparent pricing, and infrastructure that just works.
|
|
||||||
{{% /blocks/lead %}}
|
|
||||||
|
|
||||||
{{< blocks/section color="dark" type="row" >}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-users" title="Our Approach" %}}
|
|
||||||
**Human-scale support.** Real people who know your setup and respond quickly. No ticket systems or call centers.
|
|
||||||
|
|
||||||
**Reliable infrastructure.** Modern, battle-tested systems designed for uptime and security.
|
|
||||||
|
|
||||||
**Transparent pricing.** $25-75/month covers most organizations. No surprise charges or vendor lock-in.
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-heart" title="Who We Serve" %}}
|
|
||||||
Small organizations that value quality service:
|
|
||||||
|
|
||||||
- **Nonprofits and community groups** needing professional web presence
|
|
||||||
- **Small businesses** wanting expert-managed hosting
|
|
||||||
- **Creative projects** needing reliable infrastructure
|
|
||||||
- **Professional services** requiring compliance support
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-user-check" title="By Invitation Only" %}}
|
|
||||||
We operate by invitation or referral to maintain service quality:
|
|
||||||
|
|
||||||
- Focus on organizations that value long-term relationships
|
|
||||||
- Personalized service without scaling to thousands of customers
|
|
||||||
- Expertise and attention small organizations deserve
|
|
||||||
- Quality over rock-bottom pricing
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{< /blocks/section >}}
|
|
||||||
|
|
||||||
{{< blocks/section color="primary" type="row" >}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-server" title="Technical Foundation" %}}
|
|
||||||
Our infrastructure is built for reliability:
|
|
||||||
|
|
||||||
- **Modern Linux systems** with automatic security updates
|
|
||||||
- **Redundant storage and networking** to eliminate single points of failure
|
|
||||||
- **Daily automated backups** with 30-day retention
|
|
||||||
- **24/7 monitoring** with automatic failover for critical services
|
|
||||||
- **SSL certificates** automatically managed and renewed
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-user-tie" title="The Team" %}}
|
|
||||||
Shrug.host is operated by [Neil Hanlon](https://shrugpw.com/about), a systems engineer with over a decade of experience building reliable infrastructure.
|
|
||||||
|
|
||||||
Neil co-leads the infrastructure team for Rocky Linux, maintains packages for Fedora and EPEL, and serves as a core reviewer for OpenStack-Ansible. Find his thoughts on systems engineering at [thepotato.tech](https://thepotato.tech).
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-handshake" title="Related Services" %}}
|
|
||||||
Shrug.host works closely with [Shrug PW Consulting](https://shrugpw.com):
|
|
||||||
|
|
||||||
- **Hosting clients** needing infrastructure strategy, migrations, or technical projects can access consulting services
|
|
||||||
- **Consulting clients** needing managed hosting can transition here for ongoing operations
|
|
||||||
- **Same values, different expertise** - reliable systems and straightforward communication
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{< /blocks/section >}}
|
|
||||||
|
|
||||||
{{< blocks/section color="white" >}}
|
|
||||||
<div class="col-12">
|
|
||||||
<h2 class="text-center">Getting Started</h2>
|
|
||||||
<p class="text-center">Ready to get started with human-scale hosting?</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-lg-12 mx-auto text-center">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-4 mb-4">
|
|
||||||
<i class="fas fa-envelope fa-2x text-primary mb-3"></i>
|
|
||||||
<h5>1. Contact Us</h5>
|
|
||||||
<p>Email us at <a href="mailto:hello@shrug.host">hello@shrug.host</a> with your hosting needs</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-4 mb-4">
|
|
||||||
<i class="fas fa-comments fa-2x text-primary mb-3"></i>
|
|
||||||
<h5>2. Discuss Fit</h5>
|
|
||||||
<p>We'll schedule a brief conversation to understand your requirements</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-4 mb-4">
|
|
||||||
<i class="fas fa-rocket fa-2x text-primary mb-3"></i>
|
|
||||||
<h5>3. We Handle Setup</h5>
|
|
||||||
<p>Most setups are completed within 24-48 hours</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-4">
|
|
||||||
<a class="btn btn-primary btn-lg" href="mailto:hello@shrug.host">
|
|
||||||
Get Started <i class="fas fa-envelope ms-2"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-3">
|
|
||||||
<p><small>Most organizations find our approach refreshingly different from typical hosting providers.</small></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
{{< /blocks/section >}}
|
|
||||||
|
|||||||
@ -1,88 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: "Contact Us"
|
title: "Contact"
|
||||||
linkTitle: "Contact"
|
description: "Email hello@shrug.host to discuss managed hosting for your organization. We respond within 24 hours on business days."
|
||||||
menu:
|
|
||||||
main:
|
|
||||||
weight: 50
|
weight: 50
|
||||||
description: "Get in touch with shrug.host for hosting consultations and support"
|
|
||||||
---
|
---
|
||||||
|
|
||||||
{{% blocks/cover title="Get in Touch" image_anchor="center" height="min" color="primary" %}}
|
|
||||||
<p class="lead">Ready to discuss your hosting needs? We're here to help.</p>
|
|
||||||
{{% /blocks/cover %}}
|
|
||||||
|
|
||||||
{{< blocks/section color="dark" type="row" >}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-envelope" title="How to Reach Us" %}}
|
|
||||||
**Email:** [hello@shrug.host](mailto:hello@shrug.host)
|
|
||||||
|
|
||||||
**Phone:** Available during business consultations
|
|
||||||
|
|
||||||
**Response Time:** We typically respond within 24 hours during business days
|
|
||||||
|
|
||||||
Ready to discuss your hosting needs? We focus on building long-term relationships with small organizations and businesses that value reliable, human-scale support.
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-list-check" title="What to Include" %}}
|
|
||||||
Help us understand your needs by including:
|
|
||||||
|
|
||||||
- Brief description of your organization
|
|
||||||
- Current hosting situation and challenges
|
|
||||||
- Specific services you're interested in
|
|
||||||
- Timeline for potential transition
|
|
||||||
- How you heard about shrug.host
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-comments" title="Our Process" %}}
|
|
||||||
**1. Initial Contact** - Email us with your basic requirements
|
|
||||||
|
|
||||||
**2. Discovery Call** - 30-minute conversation to understand your needs
|
|
||||||
|
|
||||||
**3. Proposal** - Custom service plan with transparent pricing
|
|
||||||
|
|
||||||
**4. Onboarding** - Smooth transition with dedicated support
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{< /blocks/section >}}
|
|
||||||
|
|
||||||
{{< blocks/section color="white" >}}
|
|
||||||
<div class="col-12">
|
|
||||||
<h2 class="text-center">Service Areas</h2>
|
|
||||||
<p class="text-center">While our services are delivered remotely, we have particular expertise supporting organizations in:</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-lg-8 mx-auto text-center">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6 mb-4">
|
|
||||||
<i class="fas fa-city fa-2x text-primary mb-3"></i>
|
|
||||||
<h5>Greater Boston Area</h5>
|
|
||||||
<p>Deep understanding of the local business environment and regulatory landscape</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-6 mb-4">
|
|
||||||
<i class="fas fa-road fa-2x text-primary mb-3"></i>
|
|
||||||
<h5>Route 128 Corridor</h5>
|
|
||||||
<p>Specialized experience with technology companies and research organizations</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6 mb-4">
|
|
||||||
<i class="fas fa-laptop fa-2x text-primary mb-3"></i>
|
|
||||||
<h5>Remote-First Organizations</h5>
|
|
||||||
<p>Infrastructure designed for distributed teams and flexible work arrangements</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-6 mb-4">
|
|
||||||
<i class="fas fa-globe fa-2x text-primary mb-3"></i>
|
|
||||||
<h5>Distributed Teams</h5>
|
|
||||||
<p>Communication tools and collaboration platforms that scale with your team</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-4">
|
|
||||||
<p><strong>Need consulting services instead?</strong> For network consulting, security assessments, and technical advisory services, visit <a href="https://shrugpw.com">shrugpw.com</a>.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
{{< /blocks/section >}}
|
|
||||||
@ -1,139 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: "Hosting Plans"
|
title: "Managed Hosting Plans"
|
||||||
linkTitle: "Hosting"
|
description: "Managed hosting from $25/month for small organizations. Reliable infrastructure, human support, no surprise charges."
|
||||||
weight: 20
|
|
||||||
menu:
|
|
||||||
main:
|
|
||||||
weight: 20
|
weight: 20
|
||||||
---
|
---
|
||||||
|
|
||||||
{{< blocks/cover title="Hosting Plans" image_anchor="top" height="min" color="primary" >}}
|
|
||||||
<p class="lead mt-5">Reliable hosting at transparent prices, with human support when you need it.</p>
|
|
||||||
{{< /blocks/cover >}}
|
|
||||||
|
|
||||||
{{% blocks/lead color="white" %}}
|
|
||||||
We keep it simple: professional hosting for small organizations that value quality service over rock-bottom pricing.
|
|
||||||
{{% /blocks/lead %}}
|
|
||||||
|
|
||||||
{{< blocks/section color="dark" type="row" >}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-seedling" title="Essential Hosting" %}}
|
|
||||||
Perfect for small organizations and personal projects.
|
|
||||||
|
|
||||||
<p class="pricing"><strong>$25/month</strong></p>
|
|
||||||
|
|
||||||
**Includes:**
|
|
||||||
- Static website hosting (Hugo, Jekyll, React, etc.)
|
|
||||||
- Professional email (up to 5 mailboxes; unlimited aliases)
|
|
||||||
- DNS management & SSL certificates
|
|
||||||
- Daily backups & basic monitoring
|
|
||||||
|
|
||||||
<p class="suitable-for"><strong>Suitable for:</strong> Small nonprofits, personal portfolios, simple business websites, documentation sites</p>
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-users" title="Standard Hosting" %}}
|
|
||||||
For organizations that need collaboration tools and more email.
|
|
||||||
|
|
||||||
<p class="pricing"><strong>$50/month</strong></p>
|
|
||||||
|
|
||||||
**Everything in Essential, plus:**
|
|
||||||
- Nextcloud instance (10GB storage)
|
|
||||||
- Up to 15 email mailboxes
|
|
||||||
- Forum/discussion platform (Discourse)
|
|
||||||
- Simple database applications
|
|
||||||
- Priority support
|
|
||||||
|
|
||||||
<p class="suitable-for"><strong>Suitable for:</strong> Medium-sized nonprofits, small businesses, community groups, teams needing file sharing</p>
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-cogs" title="Professional Hosting" %}}
|
|
||||||
For organizations with more complex needs.
|
|
||||||
|
|
||||||
<p class="pricing"><strong>$75/month</strong></p>
|
|
||||||
|
|
||||||
**Everything in Standard, plus:**
|
|
||||||
- Matrix chat server
|
|
||||||
- Custom application hosting
|
|
||||||
- Up to 50 email mailboxes
|
|
||||||
- Extended storage (50GB)
|
|
||||||
- Custom domain configurations
|
|
||||||
- Dedicated support contact
|
|
||||||
|
|
||||||
<p class="suitable-for"><strong>Suitable for:</strong> Professional services firms, growing organizations, teams with specific technical requirements</p>
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{< /blocks/section >}}
|
|
||||||
|
|
||||||
{{< blocks/section color="primary" type="row" >}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-handshake" title="Enterprise & Custom Solutions" %}}
|
|
||||||
Need something specific? We work with organizations that have unique requirements:
|
|
||||||
|
|
||||||
- Custom applications and APIs
|
|
||||||
- Compliance support (HIPAA, SOC2, etc.)
|
|
||||||
- Migration from existing systems
|
|
||||||
- Integration with external services
|
|
||||||
- Dedicated infrastructure
|
|
||||||
|
|
||||||
**Pricing:** Custom quotes based on requirements, typically $150-500/month.
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-shield-alt" title="What's Included in Every Plan" %}}
|
|
||||||
- **No Setup Fees** - Get started immediately
|
|
||||||
- **Human Support** - Email response within 24 hours, urgent issues much faster
|
|
||||||
- **Security Updates** - Automatic system patches and security monitoring
|
|
||||||
- **Backups** - Daily automated backups, retained for 30 days
|
|
||||||
- **Uptime Monitoring** - 24/7 monitoring with automatic failover
|
|
||||||
- **Transparent Pricing** - No surprise charges or hidden fees
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{% blocks/feature icon="fas fa-user-check" title="By Invitation Only" %}}
|
|
||||||
**We operate by invitation or referral only.** This keeps our community focused on organizations that value quality service over rock-bottom pricing.
|
|
||||||
|
|
||||||
This approach lets us:
|
|
||||||
- Keep our community focused on long-term relationships
|
|
||||||
- Provide personalized service without scaling to thousands of customers
|
|
||||||
- Maintain the expertise and attention that small organizations deserve
|
|
||||||
{{% /blocks/feature %}}
|
|
||||||
|
|
||||||
{{< /blocks/section >}}
|
|
||||||
|
|
||||||
{{< blocks/section color="white" >}}
|
|
||||||
<div class="col-12">
|
|
||||||
<h2 class="text-center">Getting Started</h2>
|
|
||||||
<p class="text-center">Ready to get started with human-scale hosting?</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-lg-12 mx-auto text-center">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-4 mb-4">
|
|
||||||
<i class="fas fa-envelope fa-2x text-primary mb-3"></i>
|
|
||||||
<h5>1. Contact Us</h5>
|
|
||||||
<p>Email us at <a href="mailto:hello@shrug.host">hello@shrug.host</a> with your hosting needs</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-4 mb-4">
|
|
||||||
<i class="fas fa-comments fa-2x text-primary mb-3"></i>
|
|
||||||
<h5>2. Discuss Fit</h5>
|
|
||||||
<p>We'll schedule a brief conversation to understand your requirements</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-4 mb-4">
|
|
||||||
<i class="fas fa-rocket fa-2x text-primary mb-3"></i>
|
|
||||||
<h5>3. We Handle Setup</h5>
|
|
||||||
<p>Most setups are completed within 24-48 hours</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-4">
|
|
||||||
<a class="btn btn-primary btn-lg" href="mailto:hello@shrug.host">
|
|
||||||
Get Started <i class="fas fa-envelope ms-2"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-3">
|
|
||||||
<p><small>Need infrastructure strategy beyond hosting?<br />We work closely with <a href="https://shrugpw.com">Shrug PW Consulting</a></small></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
{{< /blocks/section >}}
|
|
||||||
|
|||||||
@ -1,40 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Local Hosting Services"
|
|
||||||
linkTitle: "Locations"
|
|
||||||
menu:
|
|
||||||
main:
|
|
||||||
weight: 30
|
|
||||||
description: "Professional hosting services for businesses in the Greater Boston area and Route 128 tech corridor"
|
|
||||||
---
|
|
||||||
|
|
||||||
# Hosting Services for Greater Boston Tech Companies
|
|
||||||
|
|
||||||
Shrug.host provides professional hosting and infrastructure services specifically designed for technology companies in the Route 128 corridor and Greater Boston area.
|
|
||||||
|
|
||||||
<div class="row two-column mt-5">
|
|
||||||
<div class="col-md-6">
|
|
||||||
|
|
||||||
## Our Local Focus
|
|
||||||
|
|
||||||
We understand the unique needs of:
|
|
||||||
- **Biotech companies** requiring HIPAA-compliant hosting
|
|
||||||
- **Advanced manufacturing** firms needing reliable infrastructure
|
|
||||||
- **Professional services** requiring SOC2 compliance
|
|
||||||
- **Healthcare organizations** with strict data requirements
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
|
|
||||||
## Why Local Businesses Choose Shrug.host
|
|
||||||
|
|
||||||
The advantages of working with a local Massachusetts team:
|
|
||||||
|
|
||||||
- **Local expertise** serving the Route 128 tech ecosystem
|
|
||||||
- **Compliance-ready** infrastructure for regulated industries
|
|
||||||
- **Human-scale support** from real people, not ticket systems
|
|
||||||
- **Transparent pricing** with no surprise charges or vendor lock-in
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
[Contact us today](/contact/) to learn how we can support your organization's hosting needs.
|
|
||||||
@ -1,97 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Web Hosting Services in Bedford, Massachusetts"
|
|
||||||
description: "Professional hosting services for Bedford, MA businesses. Reliable infrastructure for biotech, manufacturing, and tech companies in the Route 128 corridor."
|
|
||||||
keywords: ["Bedford MA web hosting", "Massachusetts hosting services", "Route 128 web hosting", "Bedford business hosting", "HIPAA hosting Bedford"]
|
|
||||||
weight: 10
|
|
||||||
---
|
|
||||||
|
|
||||||
# Professional Web Hosting Services in Bedford, Massachusetts
|
|
||||||
|
|
||||||
Shrug.host provides enterprise-grade hosting solutions specifically designed for technology companies, biotech firms, and professional services organizations in Bedford, Massachusetts and the surrounding Route 128 tech corridor.
|
|
||||||
|
|
||||||
## Why Bedford Businesses Choose Shrug.host
|
|
||||||
|
|
||||||
### Local Expertise, Regional Focus
|
|
||||||
Based in Massachusetts, we understand the unique requirements of Bedford's thriving technology ecosystem:
|
|
||||||
- **Biotech companies** on North Road requiring HIPAA-compliant hosting
|
|
||||||
- **Advanced manufacturing** firms needing 24/7 reliable infrastructure
|
|
||||||
- **Professional services** requiring SOC2 and compliance-ready solutions
|
|
||||||
- **Growing startups** scaling from Bedford's innovation hubs
|
|
||||||
|
|
||||||
### Compliance-Ready Infrastructure
|
|
||||||
Many Bedford businesses operate in regulated industries. Our hosting platform provides:
|
|
||||||
- **HIPAA-compliant hosting** for healthcare and biotech companies
|
|
||||||
- **SOC2 Type II controls** for professional services
|
|
||||||
- **FDA CFR Part 11** compliance capabilities for life sciences
|
|
||||||
- **Automated backup and monitoring** meeting regulatory requirements
|
|
||||||
|
|
||||||
## Services for Bedford Area Companies
|
|
||||||
|
|
||||||
### Essential Hosting ($25/month)
|
|
||||||
Perfect for Bedford startups and small professional services:
|
|
||||||
- Static websites and landing pages
|
|
||||||
- Professional email hosting
|
|
||||||
- DNS management
|
|
||||||
- SSL certificates included
|
|
||||||
|
|
||||||
### Standard Hosting ($50/month)
|
|
||||||
Ideal for growing Bedford technology companies:
|
|
||||||
- Everything in Essential
|
|
||||||
- Nextcloud collaboration platform
|
|
||||||
- Community forums and wikis
|
|
||||||
- Enhanced email capabilities (25+ accounts)
|
|
||||||
|
|
||||||
### Professional Hosting ($75/month)
|
|
||||||
Built for established Bedford biotech and manufacturing firms:
|
|
||||||
- Everything in Standard
|
|
||||||
- Matrix chat for secure team communication
|
|
||||||
- Custom application hosting
|
|
||||||
- 50+ email accounts
|
|
||||||
- Priority support
|
|
||||||
|
|
||||||
### Enterprise Solutions (Custom Pricing)
|
|
||||||
For large Bedford organizations requiring:
|
|
||||||
- Custom compliance configurations
|
|
||||||
- Dedicated infrastructure
|
|
||||||
- Advanced monitoring and alerting
|
|
||||||
- SLA guarantees
|
|
||||||
|
|
||||||
## Local Bedford Business Benefits
|
|
||||||
|
|
||||||
- **No vendor lock-in** - maintain control of your data and infrastructure
|
|
||||||
- **Transparent pricing** - no surprise charges or hidden fees
|
|
||||||
- **Human support** - real people, not offshore call centers
|
|
||||||
- **Local understanding** - we know the Bedford business community
|
|
||||||
|
|
||||||
## Serving the Greater Bedford Area
|
|
||||||
|
|
||||||
We proudly serve businesses throughout Bedford and neighboring communities:
|
|
||||||
- **Lexington** - Technology firms and professional services
|
|
||||||
- **Burlington** - Route 128 biotech corridor companies
|
|
||||||
- **Billerica** - Manufacturing and engineering companies
|
|
||||||
- **Concord** - Professional services and healthcare practices
|
|
||||||
- **Lincoln** - Small businesses and nonprofits
|
|
||||||
|
|
||||||
## About Our Bedford Hosting Infrastructure
|
|
||||||
|
|
||||||
Our hosting platform uses modern, redundant infrastructure designed for Bedford's business needs:
|
|
||||||
- **99.9% uptime guarantee** with automatic failover
|
|
||||||
- **Daily automated backups** with 30-day retention
|
|
||||||
- **24/7 monitoring** with instant alerts
|
|
||||||
- **Automatic security updates** and patch management
|
|
||||||
- **SSL certificates** automatically managed
|
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
Ready to move your Bedford business to reliable, professional hosting?
|
|
||||||
|
|
||||||
1. **Schedule a consultation** to discuss your specific needs
|
|
||||||
2. **Receive a custom proposal** tailored to your requirements
|
|
||||||
3. **Seamless migration** with zero downtime
|
|
||||||
4. **Ongoing support** from our local team
|
|
||||||
|
|
||||||
[Contact us today](/contact/) to learn how shrug.host can support your Bedford business with professional hosting services.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Serving Bedford, MA businesses since 2024. Professional hosting without the enterprise complexity.*
|
|
||||||
@ -1,100 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Burlington, MA Web Hosting for Biotech Companies"
|
|
||||||
description: "Specialized web hosting for Burlington, Massachusetts biotech and life sciences companies. HIPAA-compliant hosting with local support."
|
|
||||||
keywords: ["Burlington MA hosting", "biotech hosting Burlington", "life sciences hosting", "HIPAA hosting Burlington MA"]
|
|
||||||
weight: 15
|
|
||||||
---
|
|
||||||
|
|
||||||
# Burlington, MA Web Hosting for Biotech and Life Sciences
|
|
||||||
|
|
||||||
Burlington, Massachusetts sits at the heart of the biotech corridor, home to numerous life sciences companies requiring specialized hosting infrastructure. Shrug.host provides HIPAA-compliant, FDA-ready hosting solutions designed specifically for Burlington's biotech ecosystem.
|
|
||||||
|
|
||||||
## Burlington's Biotech Landscape
|
|
||||||
|
|
||||||
Burlington hosts a concentration of:
|
|
||||||
- **Pharmaceutical companies** requiring validated environments
|
|
||||||
- **Medical device manufacturers** needing FDA compliance
|
|
||||||
- **Clinical research organizations** handling patient data
|
|
||||||
- **Biotech startups** scaling rapidly with regulatory needs
|
|
||||||
|
|
||||||
## Specialized Biotech Hosting Services
|
|
||||||
|
|
||||||
### HIPAA-Compliant Infrastructure
|
|
||||||
- **Business Associate Agreements** for patient data handling
|
|
||||||
- **Encrypted storage and transmission** for clinical data
|
|
||||||
- **Access controls and audit logs** meeting HIPAA requirements
|
|
||||||
- **Secure backup and disaster recovery** systems
|
|
||||||
|
|
||||||
### FDA CFR Part 11 Compliance
|
|
||||||
- **Electronic signature** support for validated systems
|
|
||||||
- **Audit trails** for all system modifications
|
|
||||||
- **Data integrity** controls and validation
|
|
||||||
- **Change control** procedures and documentation
|
|
||||||
|
|
||||||
### Clinical Trial Data Management
|
|
||||||
- **Secure patient portals** for clinical trials
|
|
||||||
- **REDCap hosting** for research data collection
|
|
||||||
- **Integration capabilities** with clinical systems
|
|
||||||
- **Multi-site collaboration** platforms
|
|
||||||
|
|
||||||
## Burlington Business Benefits
|
|
||||||
|
|
||||||
### Local Advantages
|
|
||||||
- **5-minute response** to Burlington-based emergencies
|
|
||||||
- **On-site consultation** available for complex deployments
|
|
||||||
- **Local compliance expertise** familiar with Massachusetts regulations
|
|
||||||
- **Relationship-based service** understanding your business
|
|
||||||
|
|
||||||
### Cost Efficiency
|
|
||||||
- **30-40% cost reduction** compared to enterprise hosting
|
|
||||||
- **No vendor lock-in** maintaining data portability
|
|
||||||
- **Transparent pricing** with no hidden compliance fees
|
|
||||||
- **Predictable scaling** as your company grows
|
|
||||||
|
|
||||||
## Serving Burlington's Business Community
|
|
||||||
|
|
||||||
Located minutes from major Burlington employers:
|
|
||||||
- **Third Avenue** biotech corridor companies
|
|
||||||
- **Northwest Park** technology firms
|
|
||||||
- **Burlington Woods** professional services
|
|
||||||
- **Route 3A** manufacturing and engineering
|
|
||||||
|
|
||||||
### Easy Access and Support
|
|
||||||
- **Local meetings** at Burlington cafes or your office
|
|
||||||
- **Rapid response** to infrastructure emergencies
|
|
||||||
- **Personal relationships** with your technical team
|
|
||||||
- **Community involvement** in Burlington business networks
|
|
||||||
|
|
||||||
## Migration from Legacy Systems
|
|
||||||
|
|
||||||
Many Burlington biotech companies struggle with:
|
|
||||||
- **Outdated compliance systems** requiring expensive maintenance
|
|
||||||
- **Vendor lock-in** with inflexible enterprise contracts
|
|
||||||
- **Hidden costs** and surprise compliance charges
|
|
||||||
- **Poor support** from distant providers
|
|
||||||
|
|
||||||
### Our Migration Process
|
|
||||||
1. **Compliance assessment** of current systems
|
|
||||||
2. **Gap analysis** for regulatory requirements
|
|
||||||
3. **Phased migration** minimizing business disruption
|
|
||||||
4. **Validation support** for FDA-regulated environments
|
|
||||||
|
|
||||||
## Burlington Success Story
|
|
||||||
|
|
||||||
*A Burlington-based clinical research organization was spending $15,000 monthly on hosting with poor support and compliance gaps. After migrating to shrug.host, they achieved full HIPAA compliance while reducing costs by 40%. The migration was completed over a weekend with zero downtime.*
|
|
||||||
|
|
||||||
## Getting Started in Burlington
|
|
||||||
|
|
||||||
Ready to upgrade your Burlington biotech company's hosting infrastructure?
|
|
||||||
|
|
||||||
### Next Steps
|
|
||||||
1. **Schedule a consultation** at our Burlington meeting location
|
|
||||||
2. **Compliance review** of your current requirements
|
|
||||||
3. **Custom proposal** with transparent pricing
|
|
||||||
4. **Seamless migration** with validation support
|
|
||||||
|
|
||||||
[Contact us today](/contact/) to discuss your Burlington biotech hosting needs.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Supporting Burlington's biotech community with professional hosting solutions since 2024.*
|
|
||||||
@ -1,141 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Web Hosting for Route 128 Tech Corridor Companies"
|
|
||||||
description: "Professional hosting services for biotech, manufacturing, and technology companies along Route 128 in Massachusetts. HIPAA-compliant, SOC2-ready infrastructure."
|
|
||||||
keywords: ["Route 128 web hosting", "biotech hosting Massachusetts", "tech corridor hosting", "Burlington MA hosting", "Lexington web hosting"]
|
|
||||||
weight: 5
|
|
||||||
---
|
|
||||||
|
|
||||||
# Professional Hosting for Route 128 Tech Corridor
|
|
||||||
|
|
||||||
Shrug.host provides enterprise-grade hosting solutions specifically designed for the thriving technology ecosystem along Massachusetts' Route 128 corridor. From Burlington biotech to Lexington startups, we understand the unique infrastructure needs of regulated industries and high-growth companies.
|
|
||||||
|
|
||||||
## The Route 128 Advantage
|
|
||||||
|
|
||||||
Route 128 is home to some of the world's most innovative companies in:
|
|
||||||
- **Biotechnology and Life Sciences** - From Burlington to Cambridge
|
|
||||||
- **Advanced Manufacturing** - Precision engineering and robotics
|
|
||||||
- **Healthcare Technology** - Medical devices and digital health
|
|
||||||
- **Professional Services** - Consulting and financial technology
|
|
||||||
- **Emerging Technologies** - AI, machine learning, and data analytics
|
|
||||||
|
|
||||||
## Hosting Solutions Built for Route 128 Businesses
|
|
||||||
|
|
||||||
### Biotech and Life Sciences Hosting
|
|
||||||
Specialized infrastructure for companies requiring:
|
|
||||||
- **HIPAA compliance** for patient data and clinical trials
|
|
||||||
- **FDA CFR Part 11** compliance for regulated environments
|
|
||||||
- **GxP validation** support for pharmaceutical companies
|
|
||||||
- **Secure collaboration** platforms for research teams
|
|
||||||
|
|
||||||
### Manufacturing and Engineering Hosting
|
|
||||||
Reliable infrastructure supporting:
|
|
||||||
- **IoT device management** and data collection
|
|
||||||
- **CAD/CAM application hosting** for design teams
|
|
||||||
- **Supply chain management** systems
|
|
||||||
- **Quality management** platforms
|
|
||||||
|
|
||||||
### Professional Services Technology
|
|
||||||
Compliance-ready hosting for:
|
|
||||||
- **SOC2 Type II** controls and auditing
|
|
||||||
- **Client portal hosting** with secure access
|
|
||||||
- **Document management** systems
|
|
||||||
- **CRM and business intelligence** platforms
|
|
||||||
|
|
||||||
## Our Route 128 Client Success Stories
|
|
||||||
|
|
||||||
### Burlington Biotech Company
|
|
||||||
*"Shrug.host helped us achieve HIPAA compliance while reducing our hosting costs by 35%. Their understanding of biotech requirements was evident from day one."*
|
|
||||||
|
|
||||||
### Lexington Manufacturing Firm
|
|
||||||
*"We needed reliable hosting for our IoT data platform. Shrug.host's infrastructure handles millions of sensor readings daily without missing a beat."*
|
|
||||||
|
|
||||||
### Billerica Professional Services
|
|
||||||
*"The migration to shrug.host was seamless. Their local team understood our compliance requirements and delivered a solution that just works."*
|
|
||||||
|
|
||||||
## Route 128 Service Areas
|
|
||||||
|
|
||||||
We proudly serve technology companies throughout the Route 128 corridor:
|
|
||||||
|
|
||||||
### Northern Route 128
|
|
||||||
- **Burlington** - Biotech and pharmaceutical companies
|
|
||||||
- **Billerica** - Manufacturing and technology firms
|
|
||||||
- **Chelmsford** - Engineering and professional services
|
|
||||||
- **Tewksbury** - Growing tech startups
|
|
||||||
|
|
||||||
### Central Route 128
|
|
||||||
- **Lexington** - Technology companies and consultancies
|
|
||||||
- **Bedford** - Professional services and manufacturing
|
|
||||||
- **Lincoln** - Small businesses and nonprofits
|
|
||||||
- **Concord** - Healthcare practices and services
|
|
||||||
|
|
||||||
### Southern Route 128
|
|
||||||
- **Waltham** - Biotech and technology companies
|
|
||||||
- **Newton** - Professional services and startups
|
|
||||||
- **Needham** - Financial technology and consulting
|
|
||||||
- **Wellesley** - Healthcare and life sciences
|
|
||||||
|
|
||||||
## Why Route 128 Companies Choose Shrug.host
|
|
||||||
|
|
||||||
### Local Expertise
|
|
||||||
- **Massachusetts-based team** familiar with local business environment
|
|
||||||
- **Route 128 experience** serving regulated industries
|
|
||||||
- **Compliance knowledge** for biotech, healthcare, and professional services
|
|
||||||
|
|
||||||
### No-Drama Infrastructure
|
|
||||||
- **99.9% uptime** with redundant systems
|
|
||||||
- **Automatic failover** and disaster recovery
|
|
||||||
- **24/7 monitoring** with immediate alerts
|
|
||||||
- **Predictable pricing** with no surprise charges
|
|
||||||
|
|
||||||
### Human-Scale Support
|
|
||||||
- **Real people** providing technical support
|
|
||||||
- **No offshore call centers** or ticket systems
|
|
||||||
- **Direct access** to engineering team when needed
|
|
||||||
- **Local response** understanding business urgency
|
|
||||||
|
|
||||||
## Compliance and Security Features
|
|
||||||
|
|
||||||
### Industry Standards
|
|
||||||
- **SOC2 Type II** controls and regular audits
|
|
||||||
- **HIPAA Business Associate** agreements available
|
|
||||||
- **ISO 27001** aligned security practices
|
|
||||||
- **GDPR compliance** for international operations
|
|
||||||
|
|
||||||
### Technical Security
|
|
||||||
- **End-to-end encryption** for data in transit and at rest
|
|
||||||
- **Multi-factor authentication** for administrative access
|
|
||||||
- **Regular security updates** and patch management
|
|
||||||
- **Intrusion detection** and threat monitoring
|
|
||||||
|
|
||||||
## Getting Started with Route 128 Hosting
|
|
||||||
|
|
||||||
### Discovery Call
|
|
||||||
Schedule a consultation to discuss:
|
|
||||||
- Your specific compliance requirements
|
|
||||||
- Current infrastructure challenges
|
|
||||||
- Growth and scaling needs
|
|
||||||
- Integration with existing systems
|
|
||||||
|
|
||||||
### Custom Proposal
|
|
||||||
Receive a detailed proposal including:
|
|
||||||
- Infrastructure recommendations
|
|
||||||
- Compliance mapping
|
|
||||||
- Migration timeline
|
|
||||||
- Transparent pricing
|
|
||||||
|
|
||||||
### Seamless Migration
|
|
||||||
Our team handles:
|
|
||||||
- Zero-downtime migration
|
|
||||||
- DNS and email transitions
|
|
||||||
- Application testing and validation
|
|
||||||
- Staff training and documentation
|
|
||||||
|
|
||||||
## Ready to Upgrade Your Hosting?
|
|
||||||
|
|
||||||
Join the growing number of Route 128 companies trusting shrug.host with their critical infrastructure.
|
|
||||||
|
|
||||||
[Schedule a consultation](/contact/) to learn how we can support your organization's specific needs.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Proudly serving the Route 128 tech corridor since 2024. Professional hosting for serious businesses.*
|
|
||||||
5
content/en/open-source/_index.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: "Community & Open Source Hosting"
|
||||||
|
description: "We host open source projects and community software in exchange for a shoutout. No cash, no lock-in — just honest infrastructure for work that matters."
|
||||||
|
weight: 20
|
||||||
|
---
|
||||||
5
content/en/open-source/goldendog.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: "GoldenDog Linux"
|
||||||
|
description: "Hosting Alexia's Debian-based Linux distribution — APT mirror, package repo, website and docs — free for every user."
|
||||||
|
eyebrow: "open source hosting"
|
||||||
|
---
|
||||||
@ -10,9 +10,3 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "3000"
|
- "3000"
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
labels:
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.shrug-host.rule=Host(`shrug.host`)"
|
|
||||||
- "traefik.http.routers.shrug-host.tls=true"
|
|
||||||
- "traefik.http.routers.shrug-host.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.services.shrug-host.loadbalancer.server.port=3000"
|
|
||||||
|
|||||||
10
go.mod
@ -1,10 +0,0 @@
|
|||||||
module shrug.host
|
|
||||||
|
|
||||||
go 1.24
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/FortAwesome/Font-Awesome v0.0.0-20241216213156-af620534bfc3 // indirect
|
|
||||||
github.com/google/docsy v0.12.0 // indirect
|
|
||||||
github.com/google/docsy/dependencies v0.7.2 // indirect
|
|
||||||
github.com/twbs/bootstrap v5.3.8+incompatible // indirect
|
|
||||||
)
|
|
||||||
11
go.sum
@ -1,11 +0,0 @@
|
|||||||
github.com/FortAwesome/Font-Awesome v0.0.0-20230327165841-0698449d50f2/go.mod h1:IUgezN/MFpCDIlFezw3L8j83oeiIuYoj28Miwr/KUYo=
|
|
||||||
github.com/FortAwesome/Font-Awesome v0.0.0-20241216213156-af620534bfc3 h1:/iluJkJiyTAdnqrw3Yi9rH2HNHhrrtCmj8VJe7I6o3w=
|
|
||||||
github.com/FortAwesome/Font-Awesome v0.0.0-20241216213156-af620534bfc3/go.mod h1:IUgezN/MFpCDIlFezw3L8j83oeiIuYoj28Miwr/KUYo=
|
|
||||||
github.com/google/docsy v0.12.0 h1:CddZKL39YyJzawr8GTVaakvcUTCJRAAYdz7W0qfZ2P4=
|
|
||||||
github.com/google/docsy v0.12.0/go.mod h1:1bioDqA493neyFesaTvQ9reV0V2vYy+xUAnlnz7+miM=
|
|
||||||
github.com/google/docsy/dependencies v0.7.2 h1:+t5ufoADQAj4XneFphz4A+UU0ICAxmNaRHVWtMYXPSI=
|
|
||||||
github.com/google/docsy/dependencies v0.7.2/go.mod h1:gihhs5gmgeO+wuoay4FwOzob+jYJVyQbNaQOh788lD4=
|
|
||||||
github.com/twbs/bootstrap v5.2.3+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0=
|
|
||||||
github.com/twbs/bootstrap v5.3.6+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0=
|
|
||||||
github.com/twbs/bootstrap v5.3.8+incompatible h1:eK1fsXP7R/FWFt+sSNmmvUH9usPocf240nWVw7Dh02o=
|
|
||||||
github.com/twbs/bootstrap v5.3.8+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0=
|
|
||||||
90
hugo.toml
@ -1,23 +1,13 @@
|
|||||||
baseURL = "https://shrug.host/"
|
baseURL = "https://shrug.host/"
|
||||||
title = "shrug.host"
|
title = "shrug.host"
|
||||||
theme = "docsy"
|
|
||||||
languageCode = "en-us"
|
languageCode = "en-us"
|
||||||
contentDir = "content/en"
|
contentDir = "content/en"
|
||||||
defaultContentLanguage = "en"
|
defaultContentLanguage = "en"
|
||||||
defaultContentLanguageInSubdir = false
|
defaultContentLanguageInSubdir = false
|
||||||
enableRobotsTXT = true
|
enableRobotsTXT = true
|
||||||
enableGitInfo = true
|
enableGitInfo = true
|
||||||
|
|
||||||
timeout = "120s"
|
timeout = "120s"
|
||||||
|
|
||||||
# Language settings
|
|
||||||
[languages]
|
|
||||||
[languages.en]
|
|
||||||
title = "shrug.host"
|
|
||||||
description = "Human-scale hosting that just works - reliable infrastructure for small organizations"
|
|
||||||
languageName = "English"
|
|
||||||
weight = 1
|
|
||||||
|
|
||||||
[markup]
|
[markup]
|
||||||
[markup.goldmark]
|
[markup.goldmark]
|
||||||
[markup.goldmark.parser]
|
[markup.goldmark.parser]
|
||||||
@ -29,10 +19,10 @@ weight = 1
|
|||||||
unsafe = true
|
unsafe = true
|
||||||
[markup.highlight]
|
[markup.highlight]
|
||||||
style = "github"
|
style = "github"
|
||||||
lineNos = true
|
lineNos = false
|
||||||
[markup.tableOfContents]
|
[markup.tableOfContents]
|
||||||
startLevel = 2
|
startLevel = 2
|
||||||
endLevel = 6
|
endLevel = 4
|
||||||
ordered = false
|
ordered = false
|
||||||
|
|
||||||
[imaging]
|
[imaging]
|
||||||
@ -40,76 +30,38 @@ resampleFilter = "CatmullRom"
|
|||||||
quality = 75
|
quality = 75
|
||||||
anchor = "Smart"
|
anchor = "Smart"
|
||||||
|
|
||||||
[services]
|
[[menus.main]]
|
||||||
[services.googleAnalytics]
|
name = "Hosting"
|
||||||
# Comment out the next line to disable GA tracking
|
url = "/hosting/"
|
||||||
# id = "UA-00000000-0"
|
weight = 10
|
||||||
|
|
||||||
[outputs]
|
[[menus.main]]
|
||||||
section = ["HTML", "print", "RSS"]
|
name = "Open Source"
|
||||||
|
url = "/open-source/"
|
||||||
|
weight = 20
|
||||||
|
|
||||||
|
[[menus.main]]
|
||||||
|
name = "About"
|
||||||
|
url = "/about/"
|
||||||
|
weight = 40
|
||||||
|
|
||||||
|
[[menus.main]]
|
||||||
|
name = "Contact"
|
||||||
|
url = "/contact/"
|
||||||
|
weight = 50
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
copyright = "Shrug PW Consulting LLC dba Shrug.host"
|
copyright = "Shrug PW Consulting LLC dba Shrug.host"
|
||||||
privacy_policy = ""
|
description = "Human-scale hosting that just works — reliable infrastructure for small organizations and open source projects."
|
||||||
|
|
||||||
# Social media configuration
|
|
||||||
[params.social]
|
[params.social]
|
||||||
linkedin = "company/shrug-host"
|
linkedin = "company/shrug-host"
|
||||||
bluesky = "@shrug.host"
|
bluesky = "@shrug.host"
|
||||||
|
|
||||||
# Open Graph defaults
|
|
||||||
[params.og]
|
[params.og]
|
||||||
image = "/images/social/og-card.svg"
|
image = "/images/social/og-card.svg"
|
||||||
type = "website"
|
type = "website"
|
||||||
|
|
||||||
# Twitter card defaults
|
|
||||||
[params.twitter]
|
[params.twitter]
|
||||||
card = "summary_large_image"
|
card = "summary_large_image"
|
||||||
image = "/images/social/og-card.svg"
|
image = "/images/social/og-card.svg"
|
||||||
|
|
||||||
# Menu title if your navbar has a versions selector
|
|
||||||
version_menu = "Releases"
|
|
||||||
archived_version = false
|
|
||||||
version = "0.0"
|
|
||||||
|
|
||||||
# Repository configuration
|
|
||||||
github_repo = "https://git.shrug.pw/shrug.host/website"
|
|
||||||
github_branch = "main"
|
|
||||||
github_project_repo = "https://git.shrug.pw/shrug.host/website"
|
|
||||||
|
|
||||||
[module]
|
|
||||||
# Enable modules for Docsy dependencies
|
|
||||||
[[module.imports]]
|
|
||||||
path = "github.com/google/docsy"
|
|
||||||
disable = false
|
|
||||||
[[module.imports]]
|
|
||||||
path = "github.com/google/docsy/dependencies"
|
|
||||||
disable = false
|
|
||||||
|
|
||||||
# User interface configuration
|
|
||||||
[params.ui]
|
|
||||||
breadcrumb_disable = false
|
|
||||||
footer_about_enable = true
|
|
||||||
navbar_logo = true
|
|
||||||
navbar_translucent_over_cover_disable = true
|
|
||||||
sidebar_menu_compact = false
|
|
||||||
sidebar_search_disable = false
|
|
||||||
|
|
||||||
[params.ui.feedback]
|
|
||||||
enable = false
|
|
||||||
|
|
||||||
[params.ui.readingtime]
|
|
||||||
enable = false
|
|
||||||
|
|
||||||
[params.links]
|
|
||||||
[[params.links.user]]
|
|
||||||
name = "Email Support"
|
|
||||||
url = "mailto:support@shrug.host"
|
|
||||||
icon = "fa fa-envelope"
|
|
||||||
desc = "Get help with your hosting"
|
|
||||||
|
|
||||||
[[params.links.developer]]
|
|
||||||
name = "GitHub"
|
|
||||||
url = "https://git.shrug.pw/shrug.host/website"
|
|
||||||
icon = "fab fa-github"
|
|
||||||
desc = "Development takes place here!"
|
|
||||||
|
|||||||
27
layouts/404.html
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{{ define "body-class" }}page-404{{ end }}
|
||||||
|
|
||||||
|
{{ define "main" }}
|
||||||
|
<section class="hero" style="min-height: calc(100dvh - 60px); display:flex; align-items:center;" aria-labelledby="error-heading">
|
||||||
|
<div class="container" style="text-align:center;">
|
||||||
|
|
||||||
|
<p class="hero__eyebrow">
|
||||||
|
<span class="dot dot--pulse" aria-hidden="true"></span>
|
||||||
|
404 · not found
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h1 class="hero__title" id="error-heading" style="font-size: clamp(4rem, 15vw, 9rem); line-height:1; margin-bottom: var(--space-6);">
|
||||||
|
<span class="gradient-text">404</span>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<p class="hero__subtitle" style="margin-bottom: var(--space-10);">
|
||||||
|
This page doesn't exist. The server's running fine — there's just nothing here.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="hero__actions">
|
||||||
|
<a href="/" class="btn btn--primary">Back to Home</a>
|
||||||
|
<a href="/hosting/" class="btn btn--ghost">View Hosting Plans</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{{ end }}
|
||||||
17
layouts/_default/baseof.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="{{ .Site.LanguageCode | default "en" }}" data-theme="light">
|
||||||
|
<head>
|
||||||
|
{{- partial "head.html" . }}
|
||||||
|
</head>
|
||||||
|
<body class="{{ block "body-class" . }}{{ end }}">
|
||||||
|
|
||||||
|
{{- partial "navbar.html" . }}
|
||||||
|
|
||||||
|
<main class="site-main" id="main-content">
|
||||||
|
{{- block "main" . }}{{- end }}
|
||||||
|
</main>
|
||||||
|
|
||||||
|
{{- partial "footer.html" . }}
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
38
layouts/_default/list.html
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{{ define "main" }}
|
||||||
|
<div class="page-hero">
|
||||||
|
<div class="container">
|
||||||
|
<p class="page-hero__eyebrow">
|
||||||
|
<span class="dot dot--pulse"></span>
|
||||||
|
{{ with .Params.eyebrow }}{{ . }}{{ else }}shrug.host{{ end }}
|
||||||
|
</p>
|
||||||
|
<h1 class="page-hero__title">{{ .Title }}</h1>
|
||||||
|
{{- with .Description }}
|
||||||
|
<p class="page-hero__subtitle">{{ . }}</p>
|
||||||
|
{{- end }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="container">
|
||||||
|
{{- with .Content }}
|
||||||
|
<div class="prose" style="margin-bottom: var(--space-12);">{{ . }}</div>
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- if .Pages }}
|
||||||
|
<div class="feature-grid">
|
||||||
|
{{- range .Pages }}
|
||||||
|
<a href="{{ .RelPermalink }}" class="card" style="text-decoration:none;color:inherit;">
|
||||||
|
<div class="card__title">
|
||||||
|
<span class="dot"></span>
|
||||||
|
{{ .Title }}
|
||||||
|
</div>
|
||||||
|
{{- with .Description }}
|
||||||
|
<p class="card__body">{{ . }}</p>
|
||||||
|
{{- end }}
|
||||||
|
</a>
|
||||||
|
{{- end }}
|
||||||
|
</div>
|
||||||
|
{{- end }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
35
layouts/_default/single.html
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
{{ define "main" }}
|
||||||
|
<article>
|
||||||
|
<div class="page-hero">
|
||||||
|
<div class="container">
|
||||||
|
{{- if .Parent }}
|
||||||
|
<nav class="breadcrumb" aria-label="Breadcrumb">
|
||||||
|
<a href="/">Home</a>
|
||||||
|
<span class="breadcrumb__sep" aria-hidden="true">›</span>
|
||||||
|
{{- if .Parent.Title }}
|
||||||
|
<a href="{{ .Parent.RelPermalink }}">{{ .Parent.Title }}</a>
|
||||||
|
<span class="breadcrumb__sep" aria-hidden="true">›</span>
|
||||||
|
{{- end }}
|
||||||
|
<span aria-current="page">{{ .Title }}</span>
|
||||||
|
</nav>
|
||||||
|
{{- end }}
|
||||||
|
<p class="page-hero__eyebrow">
|
||||||
|
<span class="dot dot--pulse"></span>
|
||||||
|
{{ with .Params.eyebrow }}{{ . }}{{ else }}shrug.host{{ end }}
|
||||||
|
</p>
|
||||||
|
<h1 class="page-hero__title">{{ .Title }}</h1>
|
||||||
|
{{- with .Description }}
|
||||||
|
<p class="page-hero__subtitle">{{ . }}</p>
|
||||||
|
{{- end }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="container">
|
||||||
|
<div class="prose">
|
||||||
|
{{ .Content }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
{{ end }}
|
||||||
96
layouts/about/list.html
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
{{ define "body-class" }}page-about{{ end }}
|
||||||
|
|
||||||
|
{{ define "main" }}
|
||||||
|
|
||||||
|
<section class="page-hero">
|
||||||
|
<div class="container">
|
||||||
|
<p class="page-hero__eyebrow"><span class="dot dot--pulse" aria-hidden="true"></span>about</p>
|
||||||
|
<h1 class="page-hero__title">About shrug.host</h1>
|
||||||
|
<p class="page-hero__subtitle">Human-scale managed hosting for small organizations. Reliable infrastructure, real support, no enterprise complexity.</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Our Approach -->
|
||||||
|
<section class="section section--surface">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<span class="section-label">// our approach</span>
|
||||||
|
<h2>Built differently, on purpose.</h2>
|
||||||
|
</div>
|
||||||
|
<div class="feature-grid">
|
||||||
|
<div class="card">
|
||||||
|
<h3 class="card__title">Human-Scale Support</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<p>Real people who know your setup. No ticket systems, no call centers. When you email us, a person who knows your infrastructure reads it and responds.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<h3 class="card__title">Who We Serve</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<ul class="status-list">
|
||||||
|
<li>Small nonprofits and community organizations</li>
|
||||||
|
<li>Small businesses wanting expert-managed hosting</li>
|
||||||
|
<li>Creative and open source projects needing reliable infrastructure</li>
|
||||||
|
<li>Professional services requiring compliance guidance</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<h3 class="card__title">By Invitation Only</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<p>We operate by invitation or referral to maintain service quality. Every client gets the same level of attention — which means we can't take on everyone.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Technical + Team + Related -->
|
||||||
|
<section class="section section--dark">
|
||||||
|
<div class="container">
|
||||||
|
<div class="feature-grid">
|
||||||
|
<div class="card" style="background: var(--bg-elevated); border-color: var(--border);">
|
||||||
|
<h3 class="card__title">Technical Foundation</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<ul class="status-list">
|
||||||
|
<li>Modern Linux systems with automatic security updates</li>
|
||||||
|
<li>Redundant storage and networking — no single points of failure</li>
|
||||||
|
<li>Daily automated backups with 30-day retention</li>
|
||||||
|
<li>24/7 monitoring with automatic failover for critical services</li>
|
||||||
|
<li>SSL certificates automatically managed and renewed</li>
|
||||||
|
</ul>
|
||||||
|
<p style="margin-top: var(--space-4); font-size: var(--text-sm); color: var(--text);">We're based in Boston, but we run infrastructure wherever clients need it — including EU-only deployments for organizations with data residency requirements.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card" style="background: var(--bg-elevated); border-color: var(--border);">
|
||||||
|
<h3 class="card__title">The Team</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<p>Shrug.host is operated by <a href="https://shrugpw.com/about">Neil Hanlon</a>, a systems engineer with over a decade of experience building reliable infrastructure.</p>
|
||||||
|
<p style="margin-top: var(--space-4);">Neil co-leads the infrastructure team for Rocky Linux, maintains packages for Fedora and EPEL, and is a core reviewer for OpenStack-Ansible.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card" style="background: var(--bg-elevated); border-color: var(--border);">
|
||||||
|
<h3 class="card__title">Related Services</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<p>Shrug.host works closely with <a href="https://shrugpw.com">Shrug PW Consulting</a>:</p>
|
||||||
|
<ul class="status-list" style="margin-top: var(--space-3);">
|
||||||
|
<li>Hosting clients needing infrastructure strategy can access consulting services</li>
|
||||||
|
<li>Consulting clients needing managed hosting can transition here</li>
|
||||||
|
<li>Same values, different expertise</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- CTA -->
|
||||||
|
<section class="cta-section">
|
||||||
|
<div class="container">
|
||||||
|
<h2>Want to work together?</h2>
|
||||||
|
<p>Tell us about your organization and we'll take it from there.</p>
|
||||||
|
<a href="mailto:hello@shrug.host" class="btn btn--primary">Get in Touch</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
95
layouts/about/single.html
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
{{ define "body-class" }}page-about{{ end }}
|
||||||
|
|
||||||
|
{{ define "main" }}
|
||||||
|
|
||||||
|
<section class="page-hero">
|
||||||
|
<div class="container">
|
||||||
|
<p class="page-hero__eyebrow"><span class="dot dot--pulse" aria-hidden="true"></span>about</p>
|
||||||
|
<h1 class="page-hero__title">About shrug.host</h1>
|
||||||
|
<p class="page-hero__subtitle">Human-scale hosting for small organizations that need reliability without enterprise complexity. The hosting service you wish existed.</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Our Approach -->
|
||||||
|
<section class="section section--surface">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<span class="section-label">// our approach</span>
|
||||||
|
<h2>Built differently, on purpose.</h2>
|
||||||
|
</div>
|
||||||
|
<div class="feature-grid">
|
||||||
|
<div class="card">
|
||||||
|
<h3 class="card__title">Human-Scale Support</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<p>Real people who know your setup. No ticket systems, no call centers. When you email us, a person who knows your infrastructure reads it and responds.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<h3 class="card__title">Who We Serve</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<ul class="status-list">
|
||||||
|
<li>Small nonprofits and community organizations</li>
|
||||||
|
<li>Small businesses wanting expert-managed hosting</li>
|
||||||
|
<li>Creative and open source projects needing reliable infrastructure</li>
|
||||||
|
<li>Professional services requiring compliance support</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<h3 class="card__title">By Invitation Only</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<p>We operate by invitation or referral to maintain service quality. Every client gets the same level of attention — which means we can't take on everyone. Quality over quantity.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Technical + Team + Related -->
|
||||||
|
<section class="section section--dark">
|
||||||
|
<div class="container">
|
||||||
|
<div class="feature-grid">
|
||||||
|
<div class="card" style="background: var(--bg-elevated); border-color: var(--border);">
|
||||||
|
<h3 class="card__title">Technical Foundation</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<ul class="status-list">
|
||||||
|
<li>Modern Linux systems with automatic security updates</li>
|
||||||
|
<li>Redundant storage and networking — no single points of failure</li>
|
||||||
|
<li>Daily automated backups with 30-day retention</li>
|
||||||
|
<li>24/7 monitoring with automatic failover for critical services</li>
|
||||||
|
<li>SSL certificates automatically managed and renewed</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card" style="background: var(--bg-elevated); border-color: var(--border);">
|
||||||
|
<h3 class="card__title">The Team</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<p>Shrug.host is operated by <a href="https://shrugpw.com/about">Neil Hanlon</a>, a systems engineer with over a decade of experience building reliable infrastructure.</p>
|
||||||
|
<p style="margin-top: var(--space-4);">Neil co-leads the infrastructure team for Rocky Linux, maintains packages for Fedora and EPEL, and serves as a core reviewer for OpenStack-Ansible.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card" style="background: var(--bg-elevated); border-color: var(--border);">
|
||||||
|
<h3 class="card__title">Related Services</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<p>Shrug.host works closely with <a href="https://shrugpw.com">Shrug PW Consulting</a>:</p>
|
||||||
|
<ul class="status-list" style="margin-top: var(--space-3);">
|
||||||
|
<li>Hosting clients needing infrastructure strategy can access consulting services</li>
|
||||||
|
<li>Consulting clients needing managed hosting can transition here</li>
|
||||||
|
<li>Same values, different expertise</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- CTA -->
|
||||||
|
<section class="cta-section">
|
||||||
|
<div class="container">
|
||||||
|
<h2>Ready to get started?</h2>
|
||||||
|
<p>Tell us about your organization. If we're a good fit, we'll have you set up quickly.</p>
|
||||||
|
<a href="mailto:hello@shrug.host" class="btn btn--primary">Get in Touch</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
65
layouts/contact/list.html
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
{{ define "body-class" }}page-contact{{ end }}
|
||||||
|
|
||||||
|
{{ define "main" }}
|
||||||
|
|
||||||
|
<section class="page-hero">
|
||||||
|
<div class="container">
|
||||||
|
<p class="page-hero__eyebrow"><span class="dot dot--pulse" aria-hidden="true"></span>contact</p>
|
||||||
|
<h1 class="page-hero__title">Get in Touch</h1>
|
||||||
|
<p class="page-hero__subtitle">Email us. We'll reply within a business day.</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section section--dark">
|
||||||
|
<div class="container">
|
||||||
|
<div class="feature-grid">
|
||||||
|
|
||||||
|
<div class="card" style="background: var(--bg-elevated); border-color: var(--border);">
|
||||||
|
<h3 class="card__title">How to Reach Us</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<p><strong>Email:</strong> <a href="mailto:hello@shrug.host">hello@shrug.host</a></p>
|
||||||
|
<p style="margin-top: var(--space-3);">We respond within 24 hours on business days. Urgent issues faster.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card" style="background: var(--bg-elevated); border-color: var(--border);">
|
||||||
|
<h3 class="card__title">What to Include</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<ul class="status-list">
|
||||||
|
<li>Brief description of your organization</li>
|
||||||
|
<li>Current hosting situation and challenges</li>
|
||||||
|
<li>Specific services you're interested in</li>
|
||||||
|
<li>Timeline for potential transition</li>
|
||||||
|
<li>How you found us</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card" style="background: var(--bg-elevated); border-color: var(--border);">
|
||||||
|
<h3 class="card__title">Our Process</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<ul class="status-list">
|
||||||
|
<li><strong>Initial contact</strong> — email us with your basic requirements</li>
|
||||||
|
<li><strong>Quick conversation</strong> — 30 minutes to understand what you need</li>
|
||||||
|
<li><strong>Proposal</strong> — custom service plan with transparent pricing</li>
|
||||||
|
<li><strong>Onboarding</strong> — we handle the migration, usually within 24–48 hours</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
<div class="container" style="max-width: 800px;">
|
||||||
|
<div style="padding: var(--space-6); background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--radius-md);">
|
||||||
|
<p style="margin: 0; font-family: var(--font-mono); font-size: var(--text-sm);">
|
||||||
|
Need network consulting, security assessments, or technical advisory services?
|
||||||
|
Visit <a href="https://shrugpw.com">shrugpw.com →</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
91
layouts/contact/single.html
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
{{ define "body-class" }}page-contact{{ end }}
|
||||||
|
|
||||||
|
{{ define "main" }}
|
||||||
|
|
||||||
|
<section class="page-hero">
|
||||||
|
<div class="container">
|
||||||
|
<p class="page-hero__eyebrow"><span class="dot dot--pulse" aria-hidden="true"></span>contact</p>
|
||||||
|
<h1 class="page-hero__title">Get in Touch</h1>
|
||||||
|
<p class="page-hero__subtitle">Ready to discuss your hosting needs? We respond within 24 hours on business days.</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section section--dark">
|
||||||
|
<div class="container">
|
||||||
|
<div class="feature-grid">
|
||||||
|
|
||||||
|
<div class="card" style="background: var(--bg-elevated); border-color: var(--border);">
|
||||||
|
<h3 class="card__title">How to Reach Us</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<p><strong>Email:</strong> <a href="mailto:hello@shrug.host">hello@shrug.host</a></p>
|
||||||
|
<p style="margin-top: var(--space-3);">We focus on building long-term relationships with small organizations and businesses that value reliable, human-scale support. We typically respond within 24 hours on business days.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card" style="background: var(--bg-elevated); border-color: var(--border);">
|
||||||
|
<h3 class="card__title">What to Include</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<ul class="status-list">
|
||||||
|
<li>Brief description of your organization</li>
|
||||||
|
<li>Current hosting situation and challenges</li>
|
||||||
|
<li>Specific services you're interested in</li>
|
||||||
|
<li>Timeline for potential transition</li>
|
||||||
|
<li>How you heard about shrug.host</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card" style="background: var(--bg-elevated); border-color: var(--border);">
|
||||||
|
<h3 class="card__title">Our Process</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<ul class="status-list">
|
||||||
|
<li><strong>Initial contact</strong> — email us with your basic requirements</li>
|
||||||
|
<li><strong>Discovery call</strong> — 30-minute conversation to understand your needs</li>
|
||||||
|
<li><strong>Proposal</strong> — custom service plan with transparent pricing</li>
|
||||||
|
<li><strong>Onboarding</strong> — smooth transition with dedicated support</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Service Areas -->
|
||||||
|
<section class="section">
|
||||||
|
<div class="container" style="max-width: 800px;">
|
||||||
|
<div class="section-header" style="text-align: left; max-width: none; margin-bottom: var(--space-8);">
|
||||||
|
<span class="section-label">// service areas</span>
|
||||||
|
<h2>Where We Work</h2>
|
||||||
|
<p>Our services are delivered remotely, but we have particular expertise supporting organizations in:</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="services-grid">
|
||||||
|
<div class="service-item">
|
||||||
|
<div class="service-item__label"><span class="dot" aria-hidden="true"></span>Greater Boston</div>
|
||||||
|
<p class="service-item__desc">Deep understanding of the local business environment and regulatory landscape.</p>
|
||||||
|
</div>
|
||||||
|
<div class="service-item">
|
||||||
|
<div class="service-item__label"><span class="dot" aria-hidden="true"></span>Route 128 Corridor</div>
|
||||||
|
<p class="service-item__desc">Specialized experience with technology companies and research organizations.</p>
|
||||||
|
</div>
|
||||||
|
<div class="service-item">
|
||||||
|
<div class="service-item__label"><span class="dot" aria-hidden="true"></span>Remote-First</div>
|
||||||
|
<p class="service-item__desc">Infrastructure designed for distributed teams and flexible work arrangements.</p>
|
||||||
|
</div>
|
||||||
|
<div class="service-item">
|
||||||
|
<div class="service-item__label"><span class="dot" aria-hidden="true"></span>Distributed Teams</div>
|
||||||
|
<p class="service-item__desc">Communication and collaboration platforms that scale with your team wherever they are.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-top: var(--space-10); padding: var(--space-6); background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--radius-md);">
|
||||||
|
<p style="margin: 0; font-family: var(--font-mono); font-size: var(--text-sm);">
|
||||||
|
Need network consulting, security assessments, or technical advisory services?
|
||||||
|
Visit <a href="https://shrugpw.com">shrugpw.com →</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
172
layouts/hosting/list.html
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
{{ define "body-class" }}page-hosting{{ end }}
|
||||||
|
|
||||||
|
{{ define "main" }}
|
||||||
|
|
||||||
|
<!-- Page Hero -->
|
||||||
|
<section class="page-hero">
|
||||||
|
<div class="container">
|
||||||
|
<p class="page-hero__eyebrow">
|
||||||
|
<span class="dot dot--pulse" aria-hidden="true"></span>
|
||||||
|
pricing & plans
|
||||||
|
</p>
|
||||||
|
<h1 class="page-hero__title">Hosting Plans</h1>
|
||||||
|
<p class="page-hero__subtitle">Professional hosting at transparent prices, with human support when you need it. No surprise charges. No lock-in.</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Pricing Grid -->
|
||||||
|
<section class="section section--surface" aria-labelledby="pricing-heading">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<span class="section-label">// plans</span>
|
||||||
|
<h2 id="pricing-heading">Simple, honest pricing.</h2>
|
||||||
|
<p>Professional managed hosting for small organizations. Reliable infrastructure and a real person on the other end — without the enterprise overhead.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pricing-grid">
|
||||||
|
|
||||||
|
<!-- Essential -->
|
||||||
|
<div class="pricing-card">
|
||||||
|
<div class="pricing-card__name">Essential</div>
|
||||||
|
<div class="pricing-card__price">$25</div>
|
||||||
|
<div class="pricing-card__period">per month</div>
|
||||||
|
<hr class="pricing-card__divider">
|
||||||
|
<ul class="pricing-card__features">
|
||||||
|
<li>Static website hosting (Hugo, Jekyll, React, etc.)</li>
|
||||||
|
<li>Professional email — up to 5 mailboxes, unlimited aliases</li>
|
||||||
|
<li>DNS management & SSL certificates</li>
|
||||||
|
<li>Daily backups & basic monitoring</li>
|
||||||
|
</ul>
|
||||||
|
<p class="pricing-card__suitable"><strong>Suitable for:</strong> Small nonprofits, personal portfolios, simple business websites, documentation sites</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Standard — featured -->
|
||||||
|
<div class="pricing-card pricing-card--featured">
|
||||||
|
<div class="pricing-card__badge">Best for Teams</div>
|
||||||
|
<div class="pricing-card__name">Standard</div>
|
||||||
|
<div class="pricing-card__price">$50</div>
|
||||||
|
<div class="pricing-card__period">per month</div>
|
||||||
|
<hr class="pricing-card__divider">
|
||||||
|
<ul class="pricing-card__features">
|
||||||
|
<li>Everything in Essential</li>
|
||||||
|
<li>Nextcloud instance (10 GB storage)</li>
|
||||||
|
<li>Up to 15 email mailboxes</li>
|
||||||
|
<li>Forum / discussion platform (Discourse)</li>
|
||||||
|
<li>Simple database applications</li>
|
||||||
|
<li>Priority support</li>
|
||||||
|
</ul>
|
||||||
|
<p class="pricing-card__suitable"><strong>Suitable for:</strong> Medium-sized nonprofits, small businesses, community groups, teams needing file sharing</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Professional -->
|
||||||
|
<div class="pricing-card">
|
||||||
|
<div class="pricing-card__name">Professional</div>
|
||||||
|
<div class="pricing-card__price">$75</div>
|
||||||
|
<div class="pricing-card__period">per month</div>
|
||||||
|
<hr class="pricing-card__divider">
|
||||||
|
<ul class="pricing-card__features">
|
||||||
|
<li>Everything in Standard</li>
|
||||||
|
<li>Matrix chat server</li>
|
||||||
|
<li>Custom application hosting</li>
|
||||||
|
<li>Up to 50 email mailboxes</li>
|
||||||
|
<li>Extended storage (50 GB)</li>
|
||||||
|
<li>Custom domain configurations</li>
|
||||||
|
<li>Dedicated support contact</li>
|
||||||
|
</ul>
|
||||||
|
<p class="pricing-card__suitable"><strong>Suitable for:</strong> Professional services firms, growing organizations, teams with specific technical requirements</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Enterprise + Included + Invitation -->
|
||||||
|
<section class="section section--dark" aria-labelledby="enterprise-heading">
|
||||||
|
<div class="container">
|
||||||
|
<div class="feature-grid">
|
||||||
|
|
||||||
|
<div class="card" style="background: var(--bg-elevated); border-color: var(--border);">
|
||||||
|
<h3 class="card__title" id="enterprise-heading">Enterprise & Custom
|
||||||
|
</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<p>Need something specific? We work with organizations that have unique requirements:</p>
|
||||||
|
<ul class="status-list" style="margin-top: var(--space-4);">
|
||||||
|
<li>Custom applications and APIs</li>
|
||||||
|
<li>Compliance guidance for regulated industries</li>
|
||||||
|
<li>Migration from existing systems</li>
|
||||||
|
<li>Integration with external services</li>
|
||||||
|
<li>Dedicated infrastructure</li>
|
||||||
|
</ul>
|
||||||
|
<p style="margin-top: var(--space-4); font-family: var(--font-mono); font-size: var(--text-sm); color: var(--text);">
|
||||||
|
Custom quotes based on requirements —<br>typically <strong>$150–500/month</strong>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card" style="background: var(--bg-elevated); border-color: var(--border);">
|
||||||
|
<h3 class="card__title">Included in Every Plan
|
||||||
|
</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<ul class="status-list">
|
||||||
|
<li><strong>No setup fees</strong> — get started immediately</li>
|
||||||
|
<li><strong>Human support</strong> — email response within 24 hours, urgent issues faster</li>
|
||||||
|
<li><strong>Security updates</strong> — automatic patches and monitoring</li>
|
||||||
|
<li><strong>Backups</strong> — daily automated, retained for 30 days</li>
|
||||||
|
<li><strong>Uptime monitoring</strong> — 24/7 with automatic failover</li>
|
||||||
|
<li><strong>Transparent pricing</strong> — no surprise charges</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card" style="background: var(--bg-elevated); border-color: var(--border);">
|
||||||
|
<h3 class="card__title">By Invitation Only
|
||||||
|
</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<p>We operate by invitation or referral to maintain service quality. Every client gets real attention — we don't scale to thousands of anonymous customers.</p>
|
||||||
|
<ul class="status-list" style="margin-top: var(--space-4);">
|
||||||
|
<li>Personalized service — we know your setup</li>
|
||||||
|
<li>Focused on long-term relationships</li>
|
||||||
|
<li>No scaling to thousands of anonymous customers</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Getting Started -->
|
||||||
|
<section class="section" aria-labelledby="start-heading">
|
||||||
|
<div class="container" style="max-width: 720px; text-align: center;">
|
||||||
|
<span class="section-label">// getting started</span>
|
||||||
|
<h2 id="start-heading" style="margin-bottom: var(--space-12);">Three steps, that's it.</h2>
|
||||||
|
|
||||||
|
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-8); text-align: left; margin-bottom: var(--space-12);">
|
||||||
|
<div>
|
||||||
|
<div style="font-family: var(--font-mono); font-size: var(--text-3xl); font-weight: 700; color: var(--green); margin-bottom: var(--space-3);">01</div>
|
||||||
|
<h4 style="font-size: var(--text-lg); margin-bottom: var(--space-2);">Contact Us</h4>
|
||||||
|
<p style="font-size: var(--text-sm); color: var(--text-muted);">Email <a href="mailto:hello@shrug.host">hello@shrug.host</a> with your hosting needs.</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div style="font-family: var(--font-mono); font-size: var(--text-3xl); font-weight: 700; color: var(--green); margin-bottom: var(--space-3);">02</div>
|
||||||
|
<h4 style="font-size: var(--text-lg); margin-bottom: var(--space-2);">Discuss Fit</h4>
|
||||||
|
<p style="font-size: var(--text-sm); color: var(--text-muted);">A brief conversation to understand your requirements and make sure we're a good match.</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div style="font-family: var(--font-mono); font-size: var(--text-3xl); font-weight: 700; color: var(--green); margin-bottom: var(--space-3);">03</div>
|
||||||
|
<h4 style="font-size: var(--text-lg); margin-bottom: var(--space-2);">We Handle Setup</h4>
|
||||||
|
<p style="font-size: var(--text-sm); color: var(--text-muted);">Most setups are completed within 24–48 hours. You handle your work; we handle the servers.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="display:flex; flex-direction:column; align-items:center; gap: var(--space-4); margin-top: var(--space-4);">
|
||||||
|
<a href="mailto:hello@shrug.host" class="btn btn--primary">Get Started</a>
|
||||||
|
<p style="font-size: var(--text-sm); color: var(--text-muted); margin: 0; text-align: center; max-width: none;">
|
||||||
|
Need infrastructure strategy beyond hosting?
|
||||||
|
We work closely with <a href="https://shrugpw.com">Shrug PW Consulting</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
172
layouts/hosting/single.html
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
{{ define "body-class" }}page-hosting{{ end }}
|
||||||
|
|
||||||
|
{{ define "main" }}
|
||||||
|
|
||||||
|
<!-- Page Hero -->
|
||||||
|
<section class="page-hero">
|
||||||
|
<div class="container">
|
||||||
|
<p class="page-hero__eyebrow">
|
||||||
|
<span class="dot dot--pulse" aria-hidden="true"></span>
|
||||||
|
pricing & plans
|
||||||
|
</p>
|
||||||
|
<h1 class="page-hero__title">Hosting Plans</h1>
|
||||||
|
<p class="page-hero__subtitle">Professional hosting at transparent prices, with human support when you need it. No surprise charges. No lock-in.</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Pricing Grid -->
|
||||||
|
<section class="section section--surface" aria-labelledby="pricing-heading">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<span class="section-label">// plans</span>
|
||||||
|
<h2 id="pricing-heading">Simple, honest pricing.</h2>
|
||||||
|
<p>We keep it simple: professional hosting for small organizations that value quality service over rock-bottom pricing.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pricing-grid">
|
||||||
|
|
||||||
|
<!-- Essential -->
|
||||||
|
<div class="pricing-card">
|
||||||
|
<div class="pricing-card__name">Essential</div>
|
||||||
|
<div class="pricing-card__price">$25</div>
|
||||||
|
<div class="pricing-card__period">per month</div>
|
||||||
|
<hr class="pricing-card__divider">
|
||||||
|
<ul class="pricing-card__features">
|
||||||
|
<li>Static website hosting (Hugo, Jekyll, React, etc.)</li>
|
||||||
|
<li>Professional email — up to 5 mailboxes, unlimited aliases</li>
|
||||||
|
<li>DNS management & SSL certificates</li>
|
||||||
|
<li>Daily backups & basic monitoring</li>
|
||||||
|
</ul>
|
||||||
|
<p class="pricing-card__suitable"><strong>Suitable for:</strong> Small nonprofits, personal portfolios, simple business websites, documentation sites</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Standard — featured -->
|
||||||
|
<div class="pricing-card pricing-card--featured">
|
||||||
|
<div class="pricing-card__badge">Most Popular</div>
|
||||||
|
<div class="pricing-card__name">Standard</div>
|
||||||
|
<div class="pricing-card__price">$50</div>
|
||||||
|
<div class="pricing-card__period">per month</div>
|
||||||
|
<hr class="pricing-card__divider">
|
||||||
|
<ul class="pricing-card__features">
|
||||||
|
<li>Everything in Essential</li>
|
||||||
|
<li>Nextcloud instance (10 GB storage)</li>
|
||||||
|
<li>Up to 15 email mailboxes</li>
|
||||||
|
<li>Forum / discussion platform (Discourse)</li>
|
||||||
|
<li>Simple database applications</li>
|
||||||
|
<li>Priority support</li>
|
||||||
|
</ul>
|
||||||
|
<p class="pricing-card__suitable"><strong>Suitable for:</strong> Medium-sized nonprofits, small businesses, community groups, teams needing file sharing</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Professional -->
|
||||||
|
<div class="pricing-card">
|
||||||
|
<div class="pricing-card__name">Professional</div>
|
||||||
|
<div class="pricing-card__price">$75</div>
|
||||||
|
<div class="pricing-card__period">per month</div>
|
||||||
|
<hr class="pricing-card__divider">
|
||||||
|
<ul class="pricing-card__features">
|
||||||
|
<li>Everything in Standard</li>
|
||||||
|
<li>Matrix chat server</li>
|
||||||
|
<li>Custom application hosting</li>
|
||||||
|
<li>Up to 50 email mailboxes</li>
|
||||||
|
<li>Extended storage (50 GB)</li>
|
||||||
|
<li>Custom domain configurations</li>
|
||||||
|
<li>Dedicated support contact</li>
|
||||||
|
</ul>
|
||||||
|
<p class="pricing-card__suitable"><strong>Suitable for:</strong> Professional services firms, growing organizations, teams with specific technical requirements</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Enterprise + Included + Invitation -->
|
||||||
|
<section class="section section--dark" aria-labelledby="enterprise-heading">
|
||||||
|
<div class="container">
|
||||||
|
<div class="feature-grid">
|
||||||
|
|
||||||
|
<div class="card" style="background: var(--bg-elevated); border-color: var(--border);">
|
||||||
|
<h3 class="card__title" id="enterprise-heading">Enterprise & Custom
|
||||||
|
</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<p>Need something specific? We work with organizations that have unique requirements:</p>
|
||||||
|
<ul class="status-list" style="margin-top: var(--space-4);">
|
||||||
|
<li>Custom applications and APIs</li>
|
||||||
|
<li>Compliance support (HIPAA, SOC2, etc.)</li>
|
||||||
|
<li>Migration from existing systems</li>
|
||||||
|
<li>Integration with external services</li>
|
||||||
|
<li>Dedicated infrastructure</li>
|
||||||
|
</ul>
|
||||||
|
<p style="margin-top: var(--space-4); font-family: var(--font-mono); font-size: var(--text-sm); color: var(--text);">
|
||||||
|
Custom quotes based on requirements —<br>typically <strong>$150–500/month</strong>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card" style="background: var(--bg-elevated); border-color: var(--border);">
|
||||||
|
<h3 class="card__title">Included in Every Plan
|
||||||
|
</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<ul class="status-list">
|
||||||
|
<li><strong>No setup fees</strong> — get started immediately</li>
|
||||||
|
<li><strong>Human support</strong> — email response within 24 hours, urgent issues faster</li>
|
||||||
|
<li><strong>Security updates</strong> — automatic patches and monitoring</li>
|
||||||
|
<li><strong>Backups</strong> — daily automated, retained for 30 days</li>
|
||||||
|
<li><strong>Uptime monitoring</strong> — 24/7 with automatic failover</li>
|
||||||
|
<li><strong>Transparent pricing</strong> — no surprise charges</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card" style="background: var(--bg-elevated); border-color: var(--border);">
|
||||||
|
<h3 class="card__title">By Invitation Only
|
||||||
|
</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<p>We operate by invitation or referral to maintain service quality. This keeps our community focused on organizations that value long-term relationships over rock-bottom pricing.</p>
|
||||||
|
<ul class="status-list" style="margin-top: var(--space-4);">
|
||||||
|
<li>Personalized service — we know your setup</li>
|
||||||
|
<li>Focused on long-term relationships</li>
|
||||||
|
<li>No scaling to thousands of anonymous customers</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Getting Started -->
|
||||||
|
<section class="section" aria-labelledby="start-heading">
|
||||||
|
<div class="container" style="max-width: 720px; text-align: center;">
|
||||||
|
<span class="section-label">// getting started</span>
|
||||||
|
<h2 id="start-heading" style="margin-bottom: var(--space-12);">Three steps, that's it.</h2>
|
||||||
|
|
||||||
|
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-8); text-align: left; margin-bottom: var(--space-12);">
|
||||||
|
<div>
|
||||||
|
<div style="font-family: var(--font-mono); font-size: var(--text-3xl); font-weight: 700; color: var(--green); margin-bottom: var(--space-3);">01</div>
|
||||||
|
<h4 style="font-size: var(--text-lg); margin-bottom: var(--space-2);">Contact Us</h4>
|
||||||
|
<p style="font-size: var(--text-sm); color: var(--text-muted);">Email <a href="mailto:hello@shrug.host">hello@shrug.host</a> with your hosting needs.</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div style="font-family: var(--font-mono); font-size: var(--text-3xl); font-weight: 700; color: var(--green); margin-bottom: var(--space-3);">02</div>
|
||||||
|
<h4 style="font-size: var(--text-lg); margin-bottom: var(--space-2);">Discuss Fit</h4>
|
||||||
|
<p style="font-size: var(--text-sm); color: var(--text-muted);">A brief conversation to understand your requirements and make sure we're a good match.</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div style="font-family: var(--font-mono); font-size: var(--text-3xl); font-weight: 700; color: var(--green); margin-bottom: var(--space-3);">03</div>
|
||||||
|
<h4 style="font-size: var(--text-lg); margin-bottom: var(--space-2);">We Handle Setup</h4>
|
||||||
|
<p style="font-size: var(--text-sm); color: var(--text-muted);">Most setups are completed within 24–48 hours. You handle your work; we handle the servers.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="display:flex; flex-direction:column; align-items:center; gap: var(--space-4); margin-top: var(--space-4);">
|
||||||
|
<a href="mailto:hello@shrug.host" class="btn btn--primary">Get Started</a>
|
||||||
|
<p style="font-size: var(--text-sm); color: var(--text-muted); margin: 0; text-align: center; max-width: none;">
|
||||||
|
Need infrastructure strategy beyond hosting?
|
||||||
|
We work closely with <a href="https://shrugpw.com">Shrug PW Consulting</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
179
layouts/index.html
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
{{ define "body-class" }}page-home{{ end }}
|
||||||
|
|
||||||
|
{{ define "main" }}
|
||||||
|
|
||||||
|
<!-- ============================================================
|
||||||
|
HERO
|
||||||
|
============================================================ -->
|
||||||
|
<section class="hero" aria-labelledby="hero-heading">
|
||||||
|
<div class="container">
|
||||||
|
<p class="hero__eyebrow">
|
||||||
|
<span class="dot dot--pulse" aria-hidden="true"></span>
|
||||||
|
systems online · <span class="location-rotator" aria-hidden="true"><span class="location-rotator__item">boston, ma</span><span class="location-rotator__item">helsinki, fi</span><span class="location-rotator__item">ashburn, va</span><span class="location-rotator__item">são paulo, br</span><span class="location-rotator__item">near you</span></span>
|
||||||
|
</p>
|
||||||
|
<h1 class="hero__title" id="hero-heading">
|
||||||
|
We handle your hosting<br>
|
||||||
|
<span class="gradient-text">so you don't have to.</span>
|
||||||
|
</h1>
|
||||||
|
<p class="hero__subtitle">
|
||||||
|
Human-scale hosting for small organizations and open source projects — by invitation or referral.
|
||||||
|
Reliable infrastructure without enterprise complexity.
|
||||||
|
</p>
|
||||||
|
<div class="hero__actions">
|
||||||
|
<a href="/hosting/" class="btn btn--primary">View Hosting Plans</a>
|
||||||
|
<a href="/about/" class="btn btn--ghost">About Us</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- ============================================================
|
||||||
|
THREE PILLARS
|
||||||
|
============================================================ -->
|
||||||
|
<section class="section section--surface" aria-labelledby="pillars-heading">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<span class="section-label">// why shrug.host</span>
|
||||||
|
<h2 id="pillars-heading">Low-drama hosting that actually works.</h2>
|
||||||
|
<p>Managed hosting for websites, web apps, email, and DNS. Personal support, transparent pricing, no vendor lock-in.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="feature-grid">
|
||||||
|
<div class="card">
|
||||||
|
<h3 class="card__title">Human-Scale Support
|
||||||
|
</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<p>Real people, not ticket systems. We know your setup and respond quickly when you need help.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3 class="card__title">Reliable Infrastructure
|
||||||
|
</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<p>Modern, redundant systems designed for uptime. No cutting-edge experiments with your critical services.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3 class="card__title">Transparent Pricing
|
||||||
|
</h3>
|
||||||
|
<div class="card__body">
|
||||||
|
<p>$25–75/month for most setups. No surprise charges, no vendor lock-in, no subscription traps.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- ============================================================
|
||||||
|
WHAT WE HOST
|
||||||
|
============================================================ -->
|
||||||
|
<section class="section" aria-labelledby="services-heading">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<span class="section-label">// services</span>
|
||||||
|
<h2 id="services-heading">What We Host</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="services-grid">
|
||||||
|
<div class="service-item">
|
||||||
|
<div class="service-item__label">
|
||||||
|
<span class="dot" aria-hidden="true"></span>
|
||||||
|
Static Websites
|
||||||
|
</div>
|
||||||
|
<p class="service-item__desc">Hugo, Jekyll, React, Vue, or plain HTML — fast delivery, automatic SSL, no fuss.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="service-item">
|
||||||
|
<div class="service-item__label">
|
||||||
|
<span class="dot" aria-hidden="true"></span>
|
||||||
|
Email & DNS
|
||||||
|
</div>
|
||||||
|
<p class="service-item__desc">Professional email with your domain, full DNS management, and anti-spam that actually works.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="service-item">
|
||||||
|
<div class="service-item__label">
|
||||||
|
<span class="dot" aria-hidden="true"></span>
|
||||||
|
File Storage
|
||||||
|
</div>
|
||||||
|
<p class="service-item__desc">Nextcloud for secure file sharing, document collaboration, and team coordination.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="service-item">
|
||||||
|
<div class="service-item__label">
|
||||||
|
<span class="dot" aria-hidden="true"></span>
|
||||||
|
Communication
|
||||||
|
</div>
|
||||||
|
<p class="service-item__desc">Discourse forums for community discussions. Matrix chat for real-time team communication.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="service-item">
|
||||||
|
<div class="service-item__label">
|
||||||
|
<span class="dot" aria-hidden="true"></span>
|
||||||
|
Small Databases
|
||||||
|
</div>
|
||||||
|
<p class="service-item__desc">PostgreSQL and MySQL for lightweight applications and content management systems.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="service-item">
|
||||||
|
<div class="service-item__label">
|
||||||
|
<span class="dot" aria-hidden="true"></span>
|
||||||
|
Custom Applications
|
||||||
|
</div>
|
||||||
|
<p class="service-item__desc">APIs, microservices, and lightweight web applications tailored to your specific needs.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p style="margin-top: var(--space-8); color: var(--text-muted); font-size: var(--text-sm); font-family: var(--font-mono); max-width: none;">
|
||||||
|
All hosted on modern Linux infrastructure with automated backups, 24/7 monitoring, and security updates.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- ============================================================
|
||||||
|
POWERING REAL PROJECTS
|
||||||
|
============================================================ -->
|
||||||
|
<section class="section section--dark" aria-labelledby="projects-heading">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<span class="section-label">// open source hosting</span>
|
||||||
|
<h2 id="projects-heading">Powering Real Projects</h2>
|
||||||
|
<p>We support open source projects and community software with professional infrastructure. Sometimes they mention us — we appreciate it when they do.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="max-width: 560px; margin: 0 auto;">
|
||||||
|
<a href="/open-source/goldendog/" class="partner-card" aria-label="GoldenDog Linux — see hosting details">
|
||||||
|
<img src="https://goldendoglinux.org/img/logo.svg" alt="GoldenDog Linux logo" class="partner-card__logo" width="56" height="56" loading="lazy">
|
||||||
|
<div class="partner-card__info">
|
||||||
|
<h4>GoldenDog Linux</h4>
|
||||||
|
<p>APT mirror, package repo, website & docs hosting for Alexia's Debian derivative — free for every user.</p>
|
||||||
|
</div>
|
||||||
|
<span class="partner-card__arrow" aria-hidden="true">→</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="display:flex; justify-content:center; margin-top: var(--space-8);">
|
||||||
|
<a href="/open-source/" class="btn btn--ghost">Learn about open source hosting →</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- ============================================================
|
||||||
|
OPTIONAL: white/surface section here (e.g. a feature callout, social
|
||||||
|
proof block, etc.). If one is added, flip .cta-section back to dark
|
||||||
|
in assets/css/layouts.css — see the comment there.
|
||||||
|
============================================================ -->
|
||||||
|
|
||||||
|
<!-- ============================================================
|
||||||
|
CTA
|
||||||
|
============================================================ -->
|
||||||
|
<section class="cta-section" aria-labelledby="cta-heading">
|
||||||
|
<div class="container">
|
||||||
|
<h2 id="cta-heading">Ready to get started?</h2>
|
||||||
|
<p>Tell us what you need. If we're a good fit, we'll get you set up and out of the weeds.</p>
|
||||||
|
<a href="mailto:hello@shrug.host" class="btn btn--primary">Get in Touch</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
@ -1,76 +0,0 @@
|
|||||||
{{ define "main" }}
|
|
||||||
<div class="td-content">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12">
|
|
||||||
<!-- Page Header -->
|
|
||||||
<div class="location-index-header text-center mb-5">
|
|
||||||
<h1>{{ .Title }}</h1>
|
|
||||||
{{ with .Content }}
|
|
||||||
<div class="lead">
|
|
||||||
{{ . }}
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Location Cards -->
|
|
||||||
<div class="row">
|
|
||||||
{{ range .Pages }}
|
|
||||||
<div class="col-md-6 col-lg-4 mb-4">
|
|
||||||
<div class="card h-100 location-card">
|
|
||||||
<div class="card-body">
|
|
||||||
<h5 class="card-title">
|
|
||||||
<a href="{{ .RelPermalink }}" class="text-decoration-none">
|
|
||||||
{{ .Title }}
|
|
||||||
</a>
|
|
||||||
</h5>
|
|
||||||
{{ with .Params.description }}
|
|
||||||
<p class="card-text text-muted small">{{ . }}</p>
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
<!-- Extract location-specific highlights -->
|
|
||||||
{{ if in .RelPermalink "bedford" }}
|
|
||||||
<ul class="list-unstyled small">
|
|
||||||
<li>• Professional services focus</li>
|
|
||||||
<li>• Route 128 tech corridor</li>
|
|
||||||
<li>• Local business support</li>
|
|
||||||
</ul>
|
|
||||||
{{ else if in .RelPermalink "burlington" }}
|
|
||||||
<ul class="list-unstyled small">
|
|
||||||
<li>• Biotech specialization</li>
|
|
||||||
<li>• HIPAA compliance</li>
|
|
||||||
<li>• Life sciences expertise</li>
|
|
||||||
</ul>
|
|
||||||
{{ else if in .RelPermalink "route-128" }}
|
|
||||||
<ul class="list-unstyled small">
|
|
||||||
<li>• Tech corridor focus</li>
|
|
||||||
<li>• Multiple locations</li>
|
|
||||||
<li>• Industry expertise</li>
|
|
||||||
</ul>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
<div class="card-footer bg-transparent">
|
|
||||||
<a href="{{ .RelPermalink }}" class="btn btn-outline-primary btn-sm">Learn More</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- General CTA -->
|
|
||||||
<div class="row mt-5">
|
|
||||||
<div class="col-12">
|
|
||||||
<div class="card border-0 bg-primary text-white">
|
|
||||||
<div class="card-body text-center py-5">
|
|
||||||
<h3 class="card-title">Serving the Greater Boston Area</h3>
|
|
||||||
<p class="card-text">Professional hosting for technology companies, biotech firms, and professional services throughout Massachusetts.</p>
|
|
||||||
<a href="/contact/" class="btn btn-light btn-lg">Get Started Today</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
@ -1,92 +0,0 @@
|
|||||||
{{ define "main" }}
|
|
||||||
<div class="td-content">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12 col-lg-8">
|
|
||||||
<div class="location-page">
|
|
||||||
<!-- Breadcrumb -->
|
|
||||||
<nav aria-label="breadcrumb" class="location-breadcrumb">
|
|
||||||
<ol class="breadcrumb">
|
|
||||||
<li class="breadcrumb-item"><a href="/">Home</a></li>
|
|
||||||
<li class="breadcrumb-item"><a href="/locations/">Locations</a></li>
|
|
||||||
<li class="breadcrumb-item active" aria-current="page">{{ .Title }}</li>
|
|
||||||
</ol>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<!-- Page Header -->
|
|
||||||
<div class="location-header">
|
|
||||||
<h1 class="location-title">{{ .Title }}</h1>
|
|
||||||
{{ with .Params.description }}
|
|
||||||
<p class="location-description lead">{{ . }}</p>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Main Content -->
|
|
||||||
<div class="location-content">
|
|
||||||
{{ .Content }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- CTA Section -->
|
|
||||||
<div class="location-cta">
|
|
||||||
<div class="card border-0 bg-light">
|
|
||||||
<div class="card-body text-center py-5">
|
|
||||||
<h3 class="card-title">Ready to Get Started?</h3>
|
|
||||||
<p class="card-text">Contact us today to discuss your hosting needs and get a custom proposal.</p>
|
|
||||||
<a href="/contact/" class="btn btn-primary btn-lg">Get in Touch</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Sidebar -->
|
|
||||||
<div class="col-12 col-lg-4">
|
|
||||||
<div class="location-sidebar">
|
|
||||||
<!-- Quick Contact -->
|
|
||||||
<div class="card mb-4">
|
|
||||||
<div class="card-header">
|
|
||||||
<h5 class="mb-0">Quick Contact</h5>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<p class="small text-muted">Get started with professional hosting</p>
|
|
||||||
<a href="/contact/" class="btn btn-outline-primary btn-sm d-block mb-2">Schedule Consultation</a>
|
|
||||||
<a href="/hosting/" class="btn btn-outline-secondary btn-sm d-block">View Hosting Plans</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Service Areas -->
|
|
||||||
<div class="card mb-4">
|
|
||||||
<div class="card-header">
|
|
||||||
<h5 class="mb-0">Service Areas</h5>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<ul class="list-unstyled small">
|
|
||||||
<li><a href="/locations/bedford-ma-hosting/" class="text-decoration-none">Bedford, MA</a></li>
|
|
||||||
<li><a href="/locations/burlington-ma-hosting/" class="text-decoration-none">Burlington, MA</a></li>
|
|
||||||
<li><a href="/locations/route-128-hosting/" class="text-decoration-none">Route 128 Corridor</a></li>
|
|
||||||
<li class="mt-2"><a href="/locations/" class="text-muted">View all locations →</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Key Benefits -->
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h5 class="mb-0">Why Choose Shrug.host</h5>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<ul class="list-unstyled small">
|
|
||||||
<li class="mb-2">✓ Local Massachusetts team</li>
|
|
||||||
<li class="mb-2">✓ HIPAA & SOC2 compliance</li>
|
|
||||||
<li class="mb-2">✓ No vendor lock-in</li>
|
|
||||||
<li class="mb-2">✓ Transparent pricing</li>
|
|
||||||
<li class="mb-2">✓ Human support</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
78
layouts/open-source/list.html
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
{{ define "body-class" }}page-open-source{{ end }}
|
||||||
|
|
||||||
|
{{ define "main" }}
|
||||||
|
|
||||||
|
<section class="page-hero">
|
||||||
|
<div class="container">
|
||||||
|
<p class="page-hero__eyebrow"><span class="dot dot--pulse" aria-hidden="true"></span>open source hosting</p>
|
||||||
|
<h1 class="page-hero__title">Community & Open Source Hosting</h1>
|
||||||
|
<p class="page-hero__subtitle">We support open source projects and community software with professional infrastructure. Good work deserves good servers.</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- How it works -->
|
||||||
|
<section class="section section--surface">
|
||||||
|
<div class="container" style="max-width: 800px;">
|
||||||
|
<div class="section-header" style="text-align: left; max-width: none; margin-bottom: var(--space-10);">
|
||||||
|
<span class="section-label">// how it works</span>
|
||||||
|
<h2>Hosting without the hustle.</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-8); margin-bottom: var(--space-10);">
|
||||||
|
<div>
|
||||||
|
<h3 style="font-size: var(--text-xl); margin-bottom: var(--space-3);">The situation</h3>
|
||||||
|
<p>Open source projects and community software need professional infrastructure — bandwidth, uptime, backups — but don't want to charge users or survive on donations. Scaling on a shoestring means your APT mirror goes down the moment it gets popular.</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 style="font-size: var(--text-xl); margin-bottom: var(--space-3);">How we help</h3>
|
||||||
|
<p>We provide professional hosting capacity to projects we find worth supporting. Most of them mention us somewhere — a footer link, a credits page — and we appreciate it when they do. But that's a natural outcome of a good relationship, not a condition of one.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="invitation-block">
|
||||||
|
<div class="invitation-block__dot" aria-hidden="true"></div>
|
||||||
|
<div class="invitation-block__content">
|
||||||
|
<h3>What we can host</h3>
|
||||||
|
<p>APT/package mirrors, websites, documentation, download infrastructure, small databases, and custom applications — the same stack we offer paying clients, made available to community projects worth supporting.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Current projects -->
|
||||||
|
<section class="section section--dark">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-header">
|
||||||
|
<span class="section-label">// hosted projects</span>
|
||||||
|
<h2>Projects we host</h2>
|
||||||
|
<p>Projects we currently support with professional infrastructure.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="max-width: 600px; margin: 0 auto;">
|
||||||
|
{{- range .Pages }}
|
||||||
|
{{- $title := .Title }}
|
||||||
|
<a href="{{ .RelPermalink }}" class="partner-card" style="margin-bottom: var(--space-4);">
|
||||||
|
{{- with .Params.logo }}
|
||||||
|
<img src="{{ . }}" alt="{{ $title }} logo" class="partner-card__logo" width="56" height="56" loading="lazy">
|
||||||
|
{{- end }}
|
||||||
|
<div class="partner-card__info">
|
||||||
|
<h4>{{ .Title }}</h4>
|
||||||
|
{{- with .Description }}<p>{{ . }}</p>{{- end }}
|
||||||
|
</div>
|
||||||
|
<span class="partner-card__arrow" aria-hidden="true">→</span>
|
||||||
|
</a>
|
||||||
|
{{- end }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- CTA -->
|
||||||
|
<section class="cta-section">
|
||||||
|
<div class="container">
|
||||||
|
<h2>Working on something open source?</h2>
|
||||||
|
<p>We're always happy to hear about what people are building. If we can help, we will.</p>
|
||||||
|
<a href="mailto:hello@shrug.host" class="btn btn--primary">Say Hello</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
174
layouts/open-source/single.html
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
{{ define "body-class" }}page-open-source page-goldendog{{ end }}
|
||||||
|
|
||||||
|
{{ define "main" }}
|
||||||
|
|
||||||
|
<!-- Partner hero -->
|
||||||
|
<section class="page-hero">
|
||||||
|
<div class="container">
|
||||||
|
<nav class="breadcrumb" aria-label="Breadcrumb">
|
||||||
|
<a href="/">Home</a>
|
||||||
|
<span class="breadcrumb__sep" aria-hidden="true">›</span>
|
||||||
|
<a href="/open-source/">Open Source Hosting</a>
|
||||||
|
<span class="breadcrumb__sep" aria-hidden="true">›</span>
|
||||||
|
<span aria-current="page">{{ .Title }}</span>
|
||||||
|
</nav>
|
||||||
|
<p class="page-hero__eyebrow">
|
||||||
|
<span class="dot dot--pulse" aria-hidden="true"></span>
|
||||||
|
{{ with .Params.eyebrow }}{{ . }}{{ else }}hosted project{{ end }}
|
||||||
|
</p>
|
||||||
|
<h1 class="page-hero__title">{{ .Title }}</h1>
|
||||||
|
{{- with .Description }}
|
||||||
|
<p class="page-hero__subtitle">{{ . }}</p>
|
||||||
|
{{- end }}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- GoldenDog content — hardcoded for now, can be templated later -->
|
||||||
|
<section class="section">
|
||||||
|
<div class="container">
|
||||||
|
<div class="content-with-sidebar">
|
||||||
|
|
||||||
|
<!-- Main content -->
|
||||||
|
<article class="prose">
|
||||||
|
|
||||||
|
<div style="display: flex; align-items: center; gap: var(--space-6); margin-bottom: var(--space-10); padding: var(--space-6); background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--radius-lg);">
|
||||||
|
<img src="https://goldendoglinux.org/img/logo.svg" alt="GoldenDog Linux logo" width="72" height="72" style="flex-shrink: 0;">
|
||||||
|
<div>
|
||||||
|
<div style="font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-muted); margin-bottom: var(--space-1);">Hosted on shrug.host</div>
|
||||||
|
<h2 style="font-size: var(--text-2xl); margin: 0 0 var(--space-1);">GoldenDog Linux</h2>
|
||||||
|
<p style="margin: 0; font-size: var(--text-sm); color: var(--text-muted);">A Debian-based Linux distribution. Built to stay out of your way.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>The Story</h2>
|
||||||
|
<p>
|
||||||
|
<a href="https://goldendoglinux.org/about" rel="noopener">Alexia</a> built GoldenDog Linux as a tribute to YellowDog Linux — a legendary distribution she used
|
||||||
|
to breathe new life into aging PowerPC Macs. Named after her golden retriever and the project that
|
||||||
|
inspired her, GoldenDog is a clean KDE Plasma experience on a Debian Stable base, built for everyday use and
|
||||||
|
designed to stay out of your way.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
When GoldenDog started growing past the testing phase, the infrastructure couldn't keep up.
|
||||||
|
A few hundred users running <code>apt update</code> simultaneously was enough to bring the original server down.
|
||||||
|
Professional hosting costs money, and Alexia had a clear principle: she didn't want to charge users for GoldenDog,
|
||||||
|
and she didn't want to ask for donations.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
"I needed something professional. But that costs money. And I don't want to charge people for GoldenDog
|
||||||
|
or ask for donations. I don't need to squeeze money out of people. So this advertising deal seemed like
|
||||||
|
the most honest way for everyone to have their GoldenDog."
|
||||||
|
<footer style="margin-top: var(--space-3); font-style: normal; font-size: var(--text-sm);">— Alexia, creator of GoldenDog Linux</footer>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
shrug.host handles the infrastructure. GoldenDog stays free for everyone. Alexia mentions us in her
|
||||||
|
project because she wants to — and because it's the kind of straightforward arrangement that doesn't
|
||||||
|
require anyone to feel weird about it.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>What We Host</h2>
|
||||||
|
|
||||||
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-5); margin: var(--space-6) 0;">
|
||||||
|
<div style="padding: var(--space-5); background: var(--bg-surface); border: 1px solid var(--border); border-left: 3px solid var(--green); border-radius: 0 var(--radius-md) var(--radius-md) 0;">
|
||||||
|
<div style="font-family: var(--font-mono); font-weight: 700; margin-bottom: var(--space-2); display: flex; align-items: center; gap: var(--space-2);">
|
||||||
|
<span class="dot" aria-hidden="true"></span>APT Mirror & Package Repo
|
||||||
|
</div>
|
||||||
|
<p style="font-size: var(--text-sm); color: var(--text-muted); margin: 0;">
|
||||||
|
The primary service. Bandwidth-ready for hundreds of concurrent <code>apt update</code> runs
|
||||||
|
without breaking a sweat. GoldenDog's packages stay available even when the distro gets popular.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div style="padding: var(--space-5); background: var(--bg-surface); border: 1px solid var(--border); border-left: 3px solid var(--green); border-radius: 0 var(--radius-md) var(--radius-md) 0;">
|
||||||
|
<div style="font-family: var(--font-mono); font-weight: 700; margin-bottom: var(--space-2); display: flex; align-items: center; gap: var(--space-2);">
|
||||||
|
<span class="dot" aria-hidden="true"></span>Website & Docs
|
||||||
|
</div>
|
||||||
|
<p style="font-size: var(--text-sm); color: var(--text-muted); margin: 0;">
|
||||||
|
goldendoglinux.org and its documentation — static site hosting with automatic SSL,
|
||||||
|
fast delivery, and the same infrastructure as paying clients.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div style="padding: var(--space-5); background: var(--bg-surface); border: 1px solid var(--border); border-left: 3px solid var(--green); border-radius: 0 var(--radius-md) var(--radius-md) 0;">
|
||||||
|
<div style="font-family: var(--font-mono); font-weight: 700; margin-bottom: var(--space-2); display: flex; align-items: center; gap: var(--space-2);">
|
||||||
|
<span class="dot" aria-hidden="true"></span>Download Infrastructure
|
||||||
|
</div>
|
||||||
|
<p style="font-size: var(--text-sm); color: var(--text-muted); margin: 0;">
|
||||||
|
ISO images and release artifacts — served reliably so new users can actually get the distro
|
||||||
|
without hitting bandwidth limits.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div style="padding: var(--space-5); background: var(--bg-surface); border: 1px solid var(--border); border-left: 3px solid var(--green); border-radius: 0 var(--radius-md) var(--radius-md) 0;">
|
||||||
|
<div style="font-family: var(--font-mono); font-weight: 700; margin-bottom: var(--space-2); display: flex; align-items: center; gap: var(--space-2);">
|
||||||
|
<span class="dot" aria-hidden="true"></span>What's Next
|
||||||
|
</div>
|
||||||
|
<p style="font-size: var(--text-sm); color: var(--text-muted); margin: 0;">
|
||||||
|
GoldenDog Server edition is on the drawing board — a minimal, security-hardened variant
|
||||||
|
with deployment presets. When it ships, shrug.host will be ready for it.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Visit GoldenDog Linux</h2>
|
||||||
|
<p>
|
||||||
|
GoldenDog Linux is currently available for download.
|
||||||
|
Find the documentation, changelog, and community at <a href="https://goldendoglinux.org" rel="noopener">goldendoglinux.org</a>.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a href="https://goldendoglinux.org/docs/intro" class="btn btn--ghost-dark" rel="noopener" style="margin-right: var(--space-3);">Get GoldenDog Linux →</a>
|
||||||
|
<a href="https://bsky.app/profile/goldendoglinux.org" rel="noopener" style="font-family: var(--font-mono); font-size: var(--text-sm); color: var(--text-muted);">@goldendoglinux.org on Bluesky</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<aside class="sidebar" aria-label="Quick facts">
|
||||||
|
|
||||||
|
<div class="sidebar__card">
|
||||||
|
<h4>Quick Facts</h4>
|
||||||
|
<ul class="status-list" style="list-style: none; padding: 0;">
|
||||||
|
<li style="font-size: var(--text-sm); padding-left: var(--space-4); position: relative; margin-bottom: var(--space-2);">
|
||||||
|
<span style="position: absolute; left: 0; color: var(--green); font-size: 0.6em; top: 0.45em;">●</span>
|
||||||
|
Based on Debian stable
|
||||||
|
</li>
|
||||||
|
<li style="font-size: var(--text-sm); padding-left: var(--space-4); position: relative; margin-bottom: var(--space-2);">
|
||||||
|
<span style="position: absolute; left: 0; color: var(--green); font-size: 0.6em; top: 0.45em;">●</span>
|
||||||
|
KDE Plasma desktop
|
||||||
|
</li>
|
||||||
|
<li style="font-size: var(--text-sm); padding-left: var(--space-4); position: relative; margin-bottom: var(--space-2);">
|
||||||
|
<span style="position: absolute; left: 0; color: var(--green); font-size: 0.6em; top: 0.45em;">●</span>
|
||||||
|
Free for everyone, always
|
||||||
|
</li>
|
||||||
|
<li style="font-size: var(--text-sm); padding-left: var(--space-4); position: relative; margin-bottom: var(--space-2);">
|
||||||
|
<span style="position: absolute; left: 0; color: var(--green); font-size: 0.6em; top: 0.45em;">●</span>
|
||||||
|
Community-driven development
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sidebar__card" style="border-left: 3px solid var(--green);">
|
||||||
|
<h4>Infrastructure Status</h4>
|
||||||
|
<p style="font-size: var(--text-sm); color: var(--text-muted); margin-bottom: var(--space-3);">Live status for all hosted services.</p>
|
||||||
|
<a href="https://status.shrug.host" rel="noopener" style="font-family: var(--font-mono); font-size: var(--text-sm); color: var(--green);">status.shrug.host →</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sidebar__card">
|
||||||
|
<h4>Open Source Hosting</h4>
|
||||||
|
<p style="font-size: var(--text-sm); color: var(--text-muted); margin-bottom: var(--space-4);">Building something open source? We might be able to help.</p>
|
||||||
|
<a href="/open-source/" style="font-family: var(--font-mono); font-size: var(--text-sm); color: var(--green);">Learn about our model →</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- CTA -->
|
||||||
|
<section class="cta-section">
|
||||||
|
<div class="container">
|
||||||
|
<h2>Working on something open source?</h2>
|
||||||
|
<p>We're always happy to hear about what people are building. If we can help, we will.</p>
|
||||||
|
<a href="mailto:hello@shrug.host" class="btn btn--primary">Say Hello</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
48
layouts/partials/footer.html
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<footer class="footer" aria-label="Site footer">
|
||||||
|
<div class="footer__inner">
|
||||||
|
|
||||||
|
<div class="footer__brand">
|
||||||
|
<a href="/" aria-label="shrug.host home">
|
||||||
|
{{- $logo := resources.Get "icons/logo.svg" }}
|
||||||
|
{{- $logo.Content | safeHTML }}
|
||||||
|
</a>
|
||||||
|
<p class="footer__tagline">hosting that just works</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer__col">
|
||||||
|
<h4>Services</h4>
|
||||||
|
<ul class="footer__links">
|
||||||
|
<li><a href="/hosting/">Hosting Plans</a></li>
|
||||||
|
<li><a href="/open-source/">Open Source Hosting</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer__col">
|
||||||
|
<h4>Company</h4>
|
||||||
|
<ul class="footer__links">
|
||||||
|
<li><a href="/about/">About</a></li>
|
||||||
|
<li><a href="/contact/">Contact</a></li>
|
||||||
|
<li><a href="https://status.shrug.host" rel="noopener">System Status</a></li>
|
||||||
|
<li><a href="mailto:hello@shrug.host">hello@shrug.host</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer__col">
|
||||||
|
<h4>Shrug Family</h4>
|
||||||
|
<ul class="footer__links">
|
||||||
|
<li><a href="https://shrugpw.com" rel="noopener">shrugpw.com</a> <span style="color:var(--text-on-dark-muted);font-size:var(--text-xs)">— consulting</span></li>
|
||||||
|
<li><a href="https://shrug.games" rel="noopener">shrug.games</a> <span style="color:var(--text-on-dark-muted);font-size:var(--text-xs)">— game servers</span></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer__bottom">
|
||||||
|
<p class="footer__copy">
|
||||||
|
© {{ now.Year }} {{ .Site.Params.copyright }}. All rights reserved.
|
||||||
|
</p>
|
||||||
|
<div class="footer__family">
|
||||||
|
<span>Invite-only · Boston MA · Remote-first</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
60
layouts/partials/head.html
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="color-scheme" content="light dark">
|
||||||
|
|
||||||
|
<title>{{ if .IsHome }}{{ .Site.Title }} — {{ .Site.Params.description }}{{ else }}{{ .Title }} | {{ .Site.Title }}{{ end }}</title>
|
||||||
|
<meta name="description" content="{{ with .Description }}{{ . }}{{ else }}{{ .Site.Params.description }}{{ end }}">
|
||||||
|
|
||||||
|
{{- partial "opengraph.html" . }}
|
||||||
|
{{- partial "twitter_cards.html" . }}
|
||||||
|
{{- partial "schema.html" . }}
|
||||||
|
|
||||||
|
<!-- Favicons -->
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||||
|
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
||||||
|
|
||||||
|
<!-- Canonical -->
|
||||||
|
<link rel="canonical" href="{{ .Permalink }}">
|
||||||
|
|
||||||
|
<!-- Preload critical fonts -->
|
||||||
|
<link rel="preload" href="/fonts/CommitMono-700-Regular.woff2" as="font" type="font/woff2" crossorigin>
|
||||||
|
<link rel="preload" href="/fonts/CommitMono-400-Regular.woff2" as="font" type="font/woff2" crossorigin>
|
||||||
|
<link rel="preload" href="/fonts/SourceSerif4.woff2" as="font" type="font/woff2" crossorigin>
|
||||||
|
|
||||||
|
<!-- Styles -->
|
||||||
|
{{- $tokens := resources.Get "css/tokens.css" }}
|
||||||
|
{{- $base := resources.Get "css/base.css" }}
|
||||||
|
{{- $components := resources.Get "css/components.css" }}
|
||||||
|
{{- $layouts := resources.Get "css/layouts.css" }}
|
||||||
|
{{- $css := slice $tokens $base $components $layouts }}
|
||||||
|
|
||||||
|
{{- if .Params.pageCSS }}
|
||||||
|
{{- range .Params.pageCSS }}
|
||||||
|
{{- $pageCSS := resources.Get . }}
|
||||||
|
{{- $css = $css | append $pageCSS }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- $bundle := $css | resources.Concat "css/main.css" | resources.Minify | resources.Fingerprint }}
|
||||||
|
<link rel="stylesheet" href="{{ $bundle.RelPermalink }}" integrity="{{ $bundle.Data.Integrity }}">
|
||||||
|
|
||||||
|
<!-- Theme: read from localStorage before render to avoid flash -->
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
var t = localStorage.getItem('shrug-theme') || 'light';
|
||||||
|
document.documentElement.setAttribute('data-theme', t);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{{ if hugo.IsServer }}
|
||||||
|
<!-- Dev: disable minification cache busting noise -->
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{- if not hugo.IsServer }}
|
||||||
|
<!-- Privacy-friendly analytics by Plausible -->
|
||||||
|
<script async src="https://plausible.io/js/pa-Ylmvll6UdcklmAQuj2VY3.js"></script>
|
||||||
|
<script>
|
||||||
|
window.plausible=window.plausible||function(){(plausible.q=plausible.q||[]).push(arguments)},plausible.init=plausible.init||function(i){plausible.o=i||{}};
|
||||||
|
plausible.init()
|
||||||
|
</script>
|
||||||
|
{{- end }}
|
||||||
68
layouts/partials/navbar.html
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<nav class="navbar" aria-label="Main navigation">
|
||||||
|
<div class="navbar__inner">
|
||||||
|
|
||||||
|
<a href="/" class="navbar__logo" aria-label="shrug.host home">
|
||||||
|
{{- $logo := resources.Get "icons/logo.svg" }}
|
||||||
|
{{- $logo.Content | safeHTML }}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<button class="navbar__hamburger" aria-label="Toggle navigation" aria-expanded="false" id="nav-hamburger">
|
||||||
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round">
|
||||||
|
<line x1="2" y1="5" x2="18" y2="5"/>
|
||||||
|
<line x1="2" y1="10" x2="18" y2="10"/>
|
||||||
|
<line x1="2" y1="15" x2="18" y2="15"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<ul class="navbar__links" id="nav-links" role="list">
|
||||||
|
{{ $currentPage := . }}
|
||||||
|
{{ range .Site.Menus.main }}
|
||||||
|
<li>
|
||||||
|
<a href="{{ .URL }}"
|
||||||
|
{{ if $currentPage.IsMenuCurrent "main" . }}aria-current="page"{{ end }}>
|
||||||
|
{{ .Name }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{{ end }}
|
||||||
|
<li>
|
||||||
|
<button class="theme-toggle" id="theme-toggle" aria-label="Toggle dark mode">
|
||||||
|
<svg class="icon-sun" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||||
|
<circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/>
|
||||||
|
<line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
|
||||||
|
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/>
|
||||||
|
<line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
|
||||||
|
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
|
||||||
|
</svg>
|
||||||
|
<svg class="icon-moon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||||
|
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
|
||||||
|
</svg>
|
||||||
|
<span class="sr-only">Toggle theme</span>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Theme toggle
|
||||||
|
var btn = document.getElementById('theme-toggle');
|
||||||
|
if (btn) {
|
||||||
|
btn.addEventListener('click', function() {
|
||||||
|
var current = document.documentElement.getAttribute('data-theme');
|
||||||
|
var next = current === 'dark' ? 'light' : 'dark';
|
||||||
|
document.documentElement.setAttribute('data-theme', next);
|
||||||
|
localStorage.setItem('shrug-theme', next);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mobile nav
|
||||||
|
var hamburger = document.getElementById('nav-hamburger');
|
||||||
|
var navLinks = document.getElementById('nav-links');
|
||||||
|
if (hamburger && navLinks) {
|
||||||
|
hamburger.addEventListener('click', function() {
|
||||||
|
var open = navLinks.classList.toggle('is-open');
|
||||||
|
hamburger.setAttribute('aria-expanded', open ? 'true' : 'false');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -5,7 +5,7 @@
|
|||||||
{{- $og_title = .Site.Title -}}
|
{{- $og_title = .Site.Title -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
{{- $og_description := partial "page-description.html" . -}}
|
{{- $og_description := .Description | default .Site.Params.description -}}
|
||||||
|
|
||||||
{{- $og_image := .Site.Params.og.image | default "/images/social/og-card.svg" -}}
|
{{- $og_image := .Site.Params.og.image | default "/images/social/og-card.svg" -}}
|
||||||
{{- if .Params.image -}}
|
{{- if .Params.image -}}
|
||||||
@ -148,54 +148,3 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{{- if in .RelPermalink "/locations/" -}}
|
|
||||||
{{/* Additional LocalBusiness schema for location pages */}}
|
|
||||||
<script type="application/ld+json">
|
|
||||||
{
|
|
||||||
"@context": "https://schema.org",
|
|
||||||
"@type": "LocalBusiness",
|
|
||||||
"name": "Shrug.host",
|
|
||||||
"description": "Professional web hosting services for {{ if in .RelPermalink "bedford" }}Bedford, MA{{ else if in .RelPermalink "burlington" }}Burlington, MA{{ else if in .RelPermalink "route-128" }}Route 128 corridor{{ else }}Greater Boston area{{ end }} businesses",
|
|
||||||
"url": "{{ .Permalink }}",
|
|
||||||
|
|
||||||
"address": {
|
|
||||||
"@type": "PostalAddress",
|
|
||||||
"addressRegion": "MA",
|
|
||||||
"addressCountry": "US"
|
|
||||||
},
|
|
||||||
|
|
||||||
"geo": {
|
|
||||||
"@type": "GeoCoordinates",
|
|
||||||
{{- if in .RelPermalink "bedford" -}}
|
|
||||||
"latitude": 42.4906,
|
|
||||||
"longitude": -71.2767
|
|
||||||
{{- else if in .RelPermalink "burlington" -}}
|
|
||||||
"latitude": 42.5047,
|
|
||||||
"longitude": -71.2356
|
|
||||||
{{- else -}}
|
|
||||||
"latitude": 42.4584,
|
|
||||||
"longitude": -71.4139
|
|
||||||
{{- end -}}
|
|
||||||
},
|
|
||||||
|
|
||||||
"serviceArea": {
|
|
||||||
"@type": "GeoCircle",
|
|
||||||
"geoMidpoint": {
|
|
||||||
"@type": "GeoCoordinates",
|
|
||||||
{{- if in .RelPermalink "bedford" -}}
|
|
||||||
"latitude": 42.4906,
|
|
||||||
"longitude": -71.2767
|
|
||||||
{{- else if in .RelPermalink "burlington" -}}
|
|
||||||
"latitude": 42.5047,
|
|
||||||
"longitude": -71.2356
|
|
||||||
{{- else -}}
|
|
||||||
"latitude": 42.4584,
|
|
||||||
"longitude": -71.4139
|
|
||||||
{{- end -}}
|
|
||||||
},
|
|
||||||
"geoRadius": "25000"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
{{- end -}}
|
|
||||||
@ -6,7 +6,7 @@
|
|||||||
{{- $twitter_title = .Site.Title -}}
|
{{- $twitter_title = .Site.Title -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
{{- $twitter_description := partial "page-description.html" . -}}
|
{{- $twitter_description := .Description | default .Site.Params.description -}}
|
||||||
|
|
||||||
{{- $twitter_image := .Site.Params.twitter.image | default "/images/social/og-card.svg" -}}
|
{{- $twitter_image := .Site.Params.twitter.image | default "/images/social/og-card.svg" -}}
|
||||||
{{- if .Params.image -}}
|
{{- if .Params.image -}}
|
||||||
@ -1,9 +0,0 @@
|
|||||||
const autoprefixer = require('autoprefixer');
|
|
||||||
const postcssImport = require('postcss-import');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
plugins: [
|
|
||||||
postcssImport,
|
|
||||||
autoprefixer
|
|
||||||
]
|
|
||||||
};
|
|
||||||
462
pricing-analysis.md
Normal file
@ -0,0 +1,462 @@
|
|||||||
|
# Pricing Strategy Analysis: shrug.host
|
||||||
|
|
||||||
|
*Prepared April 2026 — initial analysis by research agent, refined through operator Q&A, updated with ops tracking work*
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Context & Framing
|
||||||
|
|
||||||
|
This analysis was commissioned after the shrug.host site redesign raised natural questions about whether the pricing had kept pace with the service's positioning. The short answer: it hasn't. The service is priced substantially below market across all three tiers, and the gap grows at higher tiers. None of the recommended changes require apologizing to clients — the value delivered is real and the comparables are documented.
|
||||||
|
|
||||||
|
A subsequent Q&A with Neil materially updated the cost model and infrastructure picture. Those updates are incorporated throughout. The original agent analysis is preserved where still accurate; sections marked **[Updated]** reflect post-conversation revisions.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Competitive Landscape
|
||||||
|
|
||||||
|
Understanding where shrug.host sits requires decomposing it by service category, because there is no direct competitor offering this exact bundle. The market shrug.host operates in is better understood as the intersection of several separate markets.
|
||||||
|
|
||||||
|
### Static and Web Hosting
|
||||||
|
|
||||||
|
The market for static site hosting has been almost entirely destroyed as a revenue category by platform providers. Cloudflare Pages, Netlify, Vercel, and GitHub Pages all offer free tiers adequate for Hugo, Jekyll, and React sites without traffic pressure. Netlify and Vercel charge $19–20/month for their Pro tier, but mostly because clients outgrow bandwidth or build-minute limits — not for lack of a free alternative. Static hosting as a standalone offer is essentially a commodity. The practical floor for a client who knows what they're doing is $0/month.
|
||||||
|
|
||||||
|
That said, shrug.host is not offering static hosting as a standalone product. It is offering *managed* infrastructure: correct DNS, automated SSL, uptime monitoring, and a human who knows your setup. The management layer is what has value, not the raw compute.
|
||||||
|
|
||||||
|
**[Updated]** The scope of "web hosting" at shrug.host is broader than the tier descriptions currently imply. Dynamic PHP apps (WordPress, InvoiceNinja) are deployable via Coolify and in scope within resource limits. The current tier copy says "static site hosting" but should say something closer to "website and app hosting" — the actual constraint is resource usage, not app type.
|
||||||
|
|
||||||
|
### Professional Email
|
||||||
|
|
||||||
|
**[Updated — the email cost model is structurally different than per-mailbox providers]**
|
||||||
|
|
||||||
|
The initial analysis used Fastmail Business ($5/user/month), Google Workspace ($7/user/month), and similar per-mailbox providers as the email cost benchmark. This is the right benchmark for what *clients* would pay if assembling the service themselves, and it remains valid for value-based pricing arguments. However, it is not how shrug.host's actual email costs work.
|
||||||
|
|
||||||
|
shrug.host currently runs all client email through **Migadu**, a flat-rate email provider priced per account rather than per mailbox:
|
||||||
|
|
||||||
|
| Migadu Plan | Cost | Outgoing/day | Incoming/day | Storage |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| Mini | $90/year ($7.50/mo) | 100 | 1,000 | 30 GB |
|
||||||
|
| **Standard (current)** | $290/year ($24.17/mo) | **500** | 3,000 | 100 GB |
|
||||||
|
| Maxi | $990/year ($82.50/mo) | 2,000 | 10,000 | 500 GB |
|
||||||
|
|
||||||
|
Key properties of Migadu: unlimited mailboxes, unlimited domains, all on one flat account. This means the marginal email cost of adding a client is approximately zero — the per-client email cost is just the shared account fee divided by the number of clients.
|
||||||
|
|
||||||
|
**Additionally:** Neil already pays for Migadu Standard for his own personal email. At current scale (one client), the effective email infrastructure cost attributed to the business is **$0** — it's already paid for personally.
|
||||||
|
|
||||||
|
**The scaling constraint that matters:** The 500 outgoing emails/day limit is *account-wide across all domains*. At 10 clients each doing light email use (~25–50 outbound/day), that's fine. At 10 clients with one running active Discourse email notifications or a newsletter, it becomes a real constraint. The Maxi plan at $990/year resolves this — at 15+ active clients, $66/client/year ($5.50/client/month) for unlimited email is extremely efficient.
|
||||||
|
|
||||||
|
**Long-term email strategy:** Self-hosted mail is the right answer at the intended scale. With shrug.host's own announced IP space (see Infrastructure section), bootstrapping email reputation is tractable. An enterprise deal with Migadu is an interim option worth exploring before that point. Short-term, the shared Migadu Standard account with Neil's personal email is fine.
|
||||||
|
|
||||||
|
### Nextcloud Hosting
|
||||||
|
|
||||||
|
Managed Nextcloud from third-party providers generally runs $15–40/month for a small-organization dedicated instance (10–25 users, 50–100 GB). The market is fragmented and much of it operates in European markets where GDPR compliance drives the offering.
|
||||||
|
|
||||||
|
### Discourse Hosting
|
||||||
|
|
||||||
|
Discourse.org publishes clean pricing: $20/month for Starter (no custom domain), **$100/month for Pro** (custom domain, themes, plugins, 5 staff seats), $500/month for Business. There is no official path to a custom-domain Discourse forum for less than $100/month without self-hosting. This is the single strongest value-signal in the shrug.host package and should be used explicitly in marketing copy (see §6).
|
||||||
|
|
||||||
|
### Matrix/Element Hosting
|
||||||
|
|
||||||
|
Element.io has no published SMB pricing tier. Community providers (etke.cc, etc.) charge $5–25/month for managed small-organization homeservers. There is no mid-market Matrix hosting product, which means shrug.host's inclusion of Matrix is essentially competing with self-hosting only.
|
||||||
|
|
||||||
|
### Boutique / White Glove Managed Services
|
||||||
|
|
||||||
|
MSPs in the SMB market typically charge $50–150/user/month for full managed IT — email, file storage, endpoint management, help desk, security monitoring. For a 5-person nonprofit, that's $250–750/month. Below MSP pricing and above commodity hosting is exactly where shrug.host operates, with very few named competitors at that price point.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Infrastructure Reality **[Updated]**
|
||||||
|
|
||||||
|
The initial analysis assumed commodity cloud infrastructure with per-client variable costs similar to typical hosting resellers. The actual picture is more serious.
|
||||||
|
|
||||||
|
### Current Setup
|
||||||
|
|
||||||
|
- **Coolify** — self-hosted PaaS used for app deployment and management. Handles containers, static sites, WordPress, and anything else that runs in Docker.
|
||||||
|
- **Hetzner CPX31** — current production node (~6 vCPU, 16 GB RAM, 160 GB NVMe, ~$24.99/month). Currently running one client (WordPress + InvoiceNinja). Overkill for the current load; will be repurposed as a dedicated Professional-tier node as the client base grows.
|
||||||
|
- **Migadu Standard** — $290/year, paid by Neil for personal email, zero incremental cost to the business at current scale.
|
||||||
|
|
||||||
|
### Near-Term Infrastructure Buildout (happening now, tied to GoldenDog launch)
|
||||||
|
|
||||||
|
- **ARIN IPv6 resources** — already in hand
|
||||||
|
- **IPv4 allocation + ASN** — in process with ARIN
|
||||||
|
- **CDN ingress nodes** — small VPS instances in multiple regions (targeting this year); enables proper GeoDNS and anycast delivery
|
||||||
|
|
||||||
|
The ASN + owned IP space is meaningfully above what typical managed hosting resellers operate. It enables:
|
||||||
|
1. **Self-hosted email with controlled deliverability** — own IPs mean reputation is bootstrapped intentionally rather than inherited from shared cloud IP pools
|
||||||
|
2. **Anycast/CDN delivery** — distributing content from edge nodes close to clients' users
|
||||||
|
3. **Independence from single cloud provider IP reputation**
|
||||||
|
|
||||||
|
At intended scale, having your own AS is a genuine differentiator and a quality signal to technical buyers.
|
||||||
|
|
||||||
|
### Infrastructure Cost Model Per Tier **[Updated]**
|
||||||
|
|
||||||
|
The right tier/infrastructure model, as discussed:
|
||||||
|
|
||||||
|
| Tier | Infrastructure | Estimated cost/client | Proposed price | Gross margin |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| Essential | Shared Coolify cluster | ~$2–5/mo | $35 | ~$30–33 |
|
||||||
|
| Standard | Shared Coolify cluster (heavier) | ~$5–10/mo | $75 | ~$65–70 |
|
||||||
|
| Professional | **Dedicated Coolify node** | ~$25–30/mo | $125 | ~$95–100 |
|
||||||
|
| Enterprise | Custom / compliance | Variable | $250+ | — |
|
||||||
|
|
||||||
|
"Dedicated" for Professional means a client-isolated Coolify server rather than sharing a pool with Essential/Standard clients. The current CPX31 is a natural fit as the first Professional dedicated node.
|
||||||
|
|
||||||
|
The marginal cost of adding an Essential or Standard client to a shared cluster is genuinely close to zero once the cluster exists. Revenue at these tiers is almost entirely gross margin — the constraint is Neil's operational time, not infrastructure spend.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Pricing Adequacy
|
||||||
|
|
||||||
|
**The headline finding: all three named tiers are underpriced relative to what they deliver. The degree of underpricing increases with tier.**
|
||||||
|
|
||||||
|
The correct framing for the repricing case is *value delivered to the client*, not *costs incurred by Neil*. Costs are low; value delivered is high. The argument for raising prices does not rest on covering infrastructure — it rests on the fact that clients receiving these services would pay substantially more to assemble them independently, and are getting a better integrated product on top.
|
||||||
|
|
||||||
|
### Essential at $25/month
|
||||||
|
|
||||||
|
The value-based argument: the market equivalent for 5 mailboxes, managed hosting, DNS, SSL, backups, and monitoring assembled independently runs $40–55/month before the client's own time. At $25/month, shrug.host is effectively subsidizing the management layer.
|
||||||
|
|
||||||
|
**Essential should be $35/month.** Still below the email-alone cost at Google Workspace ($35/month for 5 users). Upsell path for additional mailboxes above 5 at $5/mailbox/month lets clients grow without jumping tiers prematurely.
|
||||||
|
|
||||||
|
### Standard at $50/month
|
||||||
|
|
||||||
|
The strongest value mismatch on the menu. Independent assembly cost:
|
||||||
|
|
||||||
|
| Component | Market cost |
|
||||||
|
|---|---|
|
||||||
|
| Email, 15 users (Fastmail Business) | $75/month |
|
||||||
|
| Nextcloud managed (10 GB, third-party) | $15–25/month |
|
||||||
|
| Discourse Pro with custom domain (Discourse.org) | **$100/month** |
|
||||||
|
| Web hosting | $0–20/month |
|
||||||
|
| **Total** | **~$190–220/month** |
|
||||||
|
|
||||||
|
Standard at $50 is priced at roughly 25% of market-assembly cost. Discourse alone at Discourse.org's official Pro tier costs twice as much as shrug.host's entire Standard plan.
|
||||||
|
|
||||||
|
**Standard should be $75/month.** Still ~35% of the market-assembled equivalent. The Discourse pricing comparison alone justifies the tier.
|
||||||
|
|
||||||
|
### Professional at $75/month
|
||||||
|
|
||||||
|
The email component at full utilization (50 mailboxes at Fastmail rates) = $250/month. That already exceeds the current price of the entire tier before adding Matrix, custom app hosting, 50 GB storage, and a dedicated support contact. Even at 20 active mailboxes the client is getting ~$200/month in market-rate services for $75.
|
||||||
|
|
||||||
|
**[Updated]** The "dedicated server" framing for Professional also changes the cost calculus. A dedicated CPX31 costs ~$25/month. At $75/month current price, margin before Neil's time is $50. At $125, margin is $100. The latter is defensible for dedicated infrastructure and a direct support relationship.
|
||||||
|
|
||||||
|
**Professional should be $125/month.**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Package Composition Critique
|
||||||
|
|
||||||
|
### Essential
|
||||||
|
|
||||||
|
Coherent but thin. The email anchor is strong; static/web hosting is a commodity addition that completes the package. Two suggested strengthening moves:
|
||||||
|
|
||||||
|
1. **Managed form endpoint** — many static sites need exactly one dynamic capability (a contact form). A managed form handler completes the use case without meaningful operational overhead.
|
||||||
|
2. **Per-mailbox upsell** — $5/mailbox/month above the 5-mailbox base allows clients to grow without jumping to Standard prematurely.
|
||||||
|
|
||||||
|
**[Updated]** Essential should specify "website and application hosting" rather than "static site hosting" — WordPress and similar dynamic apps are in scope within resource limits. "Static only" is technically incorrect and undersells the capability.
|
||||||
|
|
||||||
|
### Standard
|
||||||
|
|
||||||
|
The strongest tier. The Nextcloud + Discourse + email combination maps exactly to what small nonprofits and community groups are trying to assemble with Dropbox/Google Drive + mailing lists/Slack.
|
||||||
|
|
||||||
|
Two composition improvements:
|
||||||
|
|
||||||
|
1. **Nextcloud storage floor** — 10 GB is too tight for real document collaboration. Any team doing PDFs, images, or shared files saturates 10 GB within months. The floor should be **25 GB**, with storage upsell at $2–3/month per 10 GB increment.
|
||||||
|
2. **State the SLA** — "Priority support" at Standard is vague. "Same business day response" makes the differentiation from Essential concrete and creates accountability.
|
||||||
|
|
||||||
|
### Professional
|
||||||
|
|
||||||
|
**[Updated]** The key structural change for Professional: it now represents a dedicated infrastructure tier, not just a feature expansion of Standard. This is a meaningful differentiation that justifies the price gap and gives the tier a clear identity.
|
||||||
|
|
||||||
|
Remaining composition issues:
|
||||||
|
|
||||||
|
- **Matrix as optional add-on** — Matrix has real value propositions (sovereignty, federation, E2EE) but is a steep learning curve and not the primary reason most Professional clients are at this tier. Move it to a $15/month add-on available to Standard and above. This lets Professional clients who don't need Matrix subscribe without paying for something unused, and creates natural add-on revenue.
|
||||||
|
- **Define "custom application"** — "One containerized web application (up to X GB RAM, custom domain, managed via Coolify)" is concrete. "Custom application hosting" is not.
|
||||||
|
- **50 mailbox ceiling** — more of an operational liability than a feature at this tier. Consider whether it's worth the implied promise of 50 onboarding events, 50 password resets, 50 spam complaints over the contract life.
|
||||||
|
|
||||||
|
### The Progression
|
||||||
|
|
||||||
|
**[Updated]** With the dedicated-server model for Professional, the progression becomes:
|
||||||
|
|
||||||
|
- Essential → Standard: more apps, more email, team tools (shared infrastructure)
|
||||||
|
- Standard → Professional: dedicated server, isolation, complex app support
|
||||||
|
- Professional → Enterprise: compliance, BAAs, custom infrastructure, migration services
|
||||||
|
|
||||||
|
This is a cleaner story than the original flat-increment model. Each tier has a distinct identity, not just more features.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. The Invitation-Only Premium
|
||||||
|
|
||||||
|
The "by invitation or referral only" framing is a genuine pricing signal: not everyone can buy this. That is valuable to the clients who get in. Each client relationship is deliberate. MSPs on the white-glove end charge $50–150/user/month. Even at the recommended raised prices, shrug.host is extraordinarily competitive.
|
||||||
|
|
||||||
|
The premium a boutique service commands exists because of the relationship and attention, not because of superior hardware. Price for clients who understand what managed infrastructure costs — not for clients who view hosting as a commodity.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Open Source Community Hosting **[Updated]**
|
||||||
|
|
||||||
|
The GoldenDog Linux arrangement — APT mirror, website, docs, and download infrastructure — is happening now (tied to the CDN/ASN buildout). A few updated observations:
|
||||||
|
|
||||||
|
**The actual cost is lower than initially estimated.** With the Coolify infrastructure already running and the CDN buildout happening for GoldenDog anyway, the incremental hosting cost for GoldenDog is primarily storage and bandwidth on nodes that would be running regardless. The marginal cost is probably $5–15/month in real terms.
|
||||||
|
|
||||||
|
**The infrastructure relationship is reversed from typical community hosting.** GoldenDog isn't just a beneficiary of Neil's spare capacity — the GoldenDog launch is actively driving the CDN/ingress buildout. The operational benefit flows both ways: GoldenDog gets professional infrastructure, and shrug.host gets a real-world, high-traffic use case to validate the CDN architecture before commercial clients rely on it. That's worth more than a mention.
|
||||||
|
|
||||||
|
**Formalize the "Community" policy internally.** Not as a public product tier, but as an internal policy for future OSS projects that ask:
|
||||||
|
- Open source, non-commercial use only
|
||||||
|
- Known referral from the existing network (not cold inbound)
|
||||||
|
- Capped footprint (e.g., 10 GB storage, 100 GB/month bandwidth)
|
||||||
|
- One or two projects maximum at any time; additional projects start at a reduced paid rate ($10–15/month)
|
||||||
|
|
||||||
|
The GoldenDog arrangement should be a deliberate relationship, not a template.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Recommendations
|
||||||
|
|
||||||
|
### Revised Pricing
|
||||||
|
|
||||||
|
| Tier | Current | Recommended | Core justification |
|
||||||
|
|---|---|---|---|
|
||||||
|
| Essential | $25/mo | **$35/mo** | Email alone (5 mailboxes) = $25–35/mo at market; management layer priced at zero currently |
|
||||||
|
| Standard | $50/mo | **$75/mo** | Discourse Pro alone = $100/mo from official host |
|
||||||
|
| Professional | $75/mo | **$125/mo** | Dedicated node; email (50 boxes) = $250/mo at market rates |
|
||||||
|
| Business *(new)* | — | **$175/mo** | Fills dead zone between Professional and Enterprise |
|
||||||
|
| Enterprise | $150–500 | **$250–500** | Compliance tier, clearly separated from Business |
|
||||||
|
|
||||||
|
### Add a Business Tier at $175/month
|
||||||
|
|
||||||
|
There is a real dead zone between Professional ($125) and Enterprise ($250+). A small professional services firm that needs more than Professional but isn't ready for a compliance engagement needs somewhere to land. Business at $175/month:
|
||||||
|
|
||||||
|
- Everything in Professional
|
||||||
|
- Two containerized applications (vs. one)
|
||||||
|
- 100 GB storage
|
||||||
|
- Up to 100 mailboxes
|
||||||
|
- Next-business-day SLA for critical issues (stated explicitly)
|
||||||
|
- Monthly 15-minute check-in call — high perceived value, low actual cost, reinforces the boutique relationship
|
||||||
|
|
||||||
|
### Clarify the Enterprise Floor
|
||||||
|
|
||||||
|
Enterprise should have a hard floor of $250/month and be defined as the compliance, dedicated infrastructure, and migration tier: HIPAA BAA, SOC 2 documentation, fully isolated compute, migration services. Compliance work is not off the table — it requires a lawyer and business insurance, but that's a "when the right client appears" investment, not a blocker.
|
||||||
|
|
||||||
|
### Annual Pricing
|
||||||
|
|
||||||
|
~16% discount for annual payment (10 months' price for 12 months' service). Improves cash flow and reduces churn.
|
||||||
|
|
||||||
|
| Tier | Monthly | Annual |
|
||||||
|
|---|---|---|
|
||||||
|
| Essential | $35 | $350/year |
|
||||||
|
| Standard | $75 | $750/year |
|
||||||
|
| Professional | $125 | $1,250/year |
|
||||||
|
| Business | $175 | $1,750/year |
|
||||||
|
|
||||||
|
### Compliance Add-On for Professional
|
||||||
|
|
||||||
|
Small therapy practices, independent financial advisors, small dental offices — many need HIPAA-compliant email and document storage without a full Enterprise engagement. A Compliance Add-On at $50/month on top of Professional ($175/month total) including a BAA, documented data handling procedures, and audit-ready logging captures this segment without requiring a full Enterprise quote. The technical infrastructure is already there; this prices the legal and documentation layer around it.
|
||||||
|
|
||||||
|
### Use Discourse Pricing as a Marketing Hook
|
||||||
|
|
||||||
|
Standard should be marketed explicitly against Discourse.org's own pricing:
|
||||||
|
|
||||||
|
> "A Discourse forum under your own domain costs $100/month from Discourse.org. Our Standard plan includes Discourse plus Nextcloud, email, and hosting for $75/month."
|
||||||
|
|
||||||
|
This is not a subtle value proposition. State it plainly wherever potential clients with Discourse experience might see it.
|
||||||
|
|
||||||
|
### Matrix as an Optional Add-On
|
||||||
|
|
||||||
|
Remove Matrix from the Professional default bundle. Offer it at $15/month as an add-on available to Standard and above. Clients who don't want Matrix don't pay for it; clients who do get a clean upsell path.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. The shrug.games Cross-Sell **[Added from discussion]**
|
||||||
|
|
||||||
|
The cross-sell relationship between shrug.host and shrug.games is asymmetric and intentionally so. The natural flow is:
|
||||||
|
|
||||||
|
- **shrug.host → shrug.games**: a hosting client whose community wants game servers is a natural referral
|
||||||
|
- **shrug.games → shrug.host**: less natural; game server clients are a different audience with different needs
|
||||||
|
|
||||||
|
A potential exception: a **gaming community bundle** combining a shrug.games game server with lightweight community infrastructure (Discourse forums, basic web presence) at a combined price point below Standard. This would be scoped for gaming communities specifically — one use case, lower price — rather than a general managed hosting tier.
|
||||||
|
|
||||||
|
With voice/chat on the shrug.games roadmap, there's a future natural cross-sell in the other direction: shrug.games clients wanting managed Matrix or Mumble as part of their community stack.
|
||||||
|
|
||||||
|
**Tabled for now.** Design this when the shrug.games voice/chat roadmap solidifies. The bundle price and scope should be informed by what voice/chat adds to the package.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Current State & Transition **[Updated from Q&A]**
|
||||||
|
|
||||||
|
### Client Mix
|
||||||
|
|
||||||
|
One client. Personal friend. Paying $240/year ($20/month). Running WordPress + InvoiceNinja on a dedicated CPX31. Invoiced informally as "Professional" at a deep discount.
|
||||||
|
|
||||||
|
**Revenue vs. cost today:**
|
||||||
|
|
||||||
|
| Item | Monthly |
|
||||||
|
|---|---|
|
||||||
|
| CPX31 (dedicated to client) | $24.99 |
|
||||||
|
| Migadu Standard | $0 (paid personally; no incremental business cost) |
|
||||||
|
| Revenue | $20.00 |
|
||||||
|
| **Net** | **-$4.99/month** |
|
||||||
|
|
||||||
|
This is a friendship rate at pre-launch. The repricing conversation is a casual one — the client knows the setup and the relationship is personal. No urgency; $20/month for a couple of PHP apps is fine at this scale. The repricing matters for *new* clients at launch.
|
||||||
|
|
||||||
|
### Infrastructure Transition
|
||||||
|
|
||||||
|
The CPX31 currently runs one client in isolation. As new clients come on:
|
||||||
|
- **Essential/Standard**: consolidated onto a shared Coolify cluster (new or repurposed node)
|
||||||
|
- **Professional**: the existing CPX31 becomes the first dedicated Professional node
|
||||||
|
- **CDN/ingress layer**: small regional nodes coming this year, driven by GoldenDog launch
|
||||||
|
|
||||||
|
### Email Strategy Roadmap
|
||||||
|
|
||||||
|
| Phase | State | Email infrastructure |
|
||||||
|
|---|---|---|
|
||||||
|
| Now | 1 client | Migadu Standard (paid personally; zero incremental cost) |
|
||||||
|
| Near-term (~10 clients) | Migadu Standard adequate; monitor outbound limits | Same account |
|
||||||
|
| Medium-term (~15+ clients) | Migadu Maxi ($990/year) or enterprise deal | Evaluate per-client Migadu accounts vs. upgrade |
|
||||||
|
| Long-term | Self-hosted | Stalwart or Mailcow on owned IP space (ASN buildout enables this with controlled deliverability) |
|
||||||
|
|
||||||
|
Self-hosted is the only realistic long-term strategy at intended scale. The owned IP space makes deliverability tractable — reputation is built intentionally rather than inherited. Migadu enterprise deal is a viable interim option worth a conversation with them before self-hosting becomes necessary.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Summary
|
||||||
|
|
||||||
|
| Tier | Current | Recommended | Key changes |
|
||||||
|
|---|---|---|---|
|
||||||
|
| Essential | $25/mo | $35/mo | "Web/app hosting" copy; +$5/mailbox upsell; form handler |
|
||||||
|
| Standard | $50/mo | $75/mo | Nextcloud → 25 GB; storage upsell; stated SLA |
|
||||||
|
| Professional | $75/mo | $125/mo | Dedicated node framing; Matrix → add-on; define "custom app" |
|
||||||
|
| Business *(new)* | — | $175/mo | Fills Professional→Enterprise gap |
|
||||||
|
| Enterprise | $150–500 | $250–500 | Floor $250; compliance/BAA/dedicated infra clearly defined |
|
||||||
|
|
||||||
|
The pricing case rests on value delivered, not cost coverage. Infrastructure costs are low and largely shared fixed costs. The repricing case is: clients receiving these services would pay significantly more to assemble them independently, and are getting a better integrated product. The invitation-only framing gives permission to price for the right clients.
|
||||||
|
|
||||||
|
The redesign is the natural moment. The window is open now.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. Work Tracked in Ops Repo **[Added April 2026]**
|
||||||
|
|
||||||
|
All action items from this analysis have been filed as issues in the shrug.host ops repo at https://git.shrug.pw/shrug.host/ops. Issues are organized into four milestones with labels and assignee.
|
||||||
|
|
||||||
|
### Labels
|
||||||
|
|
||||||
|
| Label | Color | Scope |
|
||||||
|
|---|---|---|
|
||||||
|
| `infrastructure` | blue `#4f81a3` | Server, CDN, ASN, email |
|
||||||
|
| `website` | green `#10b981` | Site layouts, copy, content |
|
||||||
|
| `pricing` | purple `#7c3aed` | Tier changes, pricing page |
|
||||||
|
| `branding` | orange `#f59e0b` | Logo, assets, brand docs |
|
||||||
|
| `goldendog` | teal `#02AA93` | GoldenDog partnership |
|
||||||
|
| `business` | gray `#6b7280` | Contracts, legal, internal policy |
|
||||||
|
| `p:high` | red `#ef4444` | Priority |
|
||||||
|
| `p:low` | light `#d1d5db` | Priority |
|
||||||
|
|
||||||
|
### Milestones and Issues
|
||||||
|
|
||||||
|
**Milestone 1 — Launch Readiness** (#1–5)
|
||||||
|
|
||||||
|
| # | Issue |
|
||||||
|
|---|---|
|
||||||
|
| 1 | Update tier copy: "static site hosting" → "web/app hosting" |
|
||||||
|
| 2 | Smoke test all pages in light and dark mode |
|
||||||
|
| 3 | Review and sign off on 404 page |
|
||||||
|
| 4 | Copy and tone review pass across all pages |
|
||||||
|
| 5 | Audit .gitignore for deleted Docsy/SCSS/node_modules references |
|
||||||
|
|
||||||
|
**Milestone 2 — Infrastructure Buildout** (#6–14)
|
||||||
|
|
||||||
|
| # | Issue |
|
||||||
|
|---|---|
|
||||||
|
| 6 | Request IPv4 allocation from ARIN `p:high` |
|
||||||
|
| 7 | Request ASN from ARIN `p:high` |
|
||||||
|
| 8 | Provision CDN ingress nodes (multi-region) |
|
||||||
|
| 9 | Document CDN and network architecture |
|
||||||
|
| 10 | Set up shared Coolify cluster for Essential/Standard clients |
|
||||||
|
| 11 | Define and document resource cap policy for shared cluster |
|
||||||
|
| 12 | Evaluate self-hosted email (Stalwart / Mailcow) |
|
||||||
|
| 13 | Contact Migadu about enterprise/volume pricing |
|
||||||
|
| 14 | Establish backup and monitoring stack for multi-node infrastructure |
|
||||||
|
|
||||||
|
**Milestone 3 — GoldenDog Launch** (#15–20)
|
||||||
|
|
||||||
|
| # | Issue |
|
||||||
|
|---|---|
|
||||||
|
| 15 | Provision GoldenDog APT mirror infrastructure `p:high` |
|
||||||
|
| 16 | Set up GoldenDog website and docs hosting |
|
||||||
|
| 17 | Set up GoldenDog download / ISO mirror |
|
||||||
|
| 18 | Set up GoldenDog email (Migadu shared account) |
|
||||||
|
| 19 | Deliver "Powered by Shrug.host" badge to Alexia |
|
||||||
|
| 20 | Finalize and verify GoldenDog page content with Alexia |
|
||||||
|
|
||||||
|
**Milestone 4 — Pricing & Packages v2** (#21–30)
|
||||||
|
|
||||||
|
| # | Issue |
|
||||||
|
|---|---|
|
||||||
|
| 21 | Decision: adopt recommended pricing ($35 / $75 / $125) `p:high` |
|
||||||
|
| 22 | Decision: add Business tier at $175/month |
|
||||||
|
| 23 | Decision: move Matrix to optional add-on ($15/month) |
|
||||||
|
| 24 | Decision: set Enterprise floor at $250/month |
|
||||||
|
| 25 | Update hosting plans page with revised pricing and tiers |
|
||||||
|
| 26 | Add Discourse pricing comparison to Standard marketing copy |
|
||||||
|
| 27 | Write internal community hosting policy doc |
|
||||||
|
| 28 | Add annual pricing option to hosting plans page |
|
||||||
|
| 29 | Define revised package contents for each tier |
|
||||||
|
| 30 | Decision: add compliance add-on for Professional ($50/month) `p:low` |
|
||||||
|
|
||||||
|
### Issue Dependencies
|
||||||
|
|
||||||
|
A few issues that must be sequenced correctly:
|
||||||
|
|
||||||
|
- **#29** (package contents) should be resolved *before* #21 (pricing decision) and #25 (hosting page update). It defines exactly what goes in each box, which the pricing decision and copy update depend on.
|
||||||
|
- **#21–24** (all pricing decisions) must be signed off *before* #25 (hosting page update) and #26 (Discourse copy hook).
|
||||||
|
- **#6 + #7** (IPv4 + ASN) gate **#8** (CDN nodes) and eventually **#12** (self-hosted email).
|
||||||
|
- **#15** (GoldenDog APT mirror) is tied to the CDN buildout (#8) — GoldenDog is the first real-traffic validation of that infrastructure.
|
||||||
|
- **#30** (compliance add-on) is blocked on lawyer + business insurance; lowest priority in the milestone.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. Project Board Prioritization **[Added April 2026]**
|
||||||
|
|
||||||
|
This table maps every open issue to a rough priority and sequencing logic for when the Gitea project board is set up. Three swim lanes are proposed: **Now** (active or immediately actionable), **Soon** (next natural phase), **Later** (important but not blocking anything current).
|
||||||
|
|
||||||
|
| # | Issue | Lane | Rationale |
|
||||||
|
|---|---|---|---|
|
||||||
|
| 15 | Provision GoldenDog APT mirror | **Now** | Active commitment; GoldenDog launch is happening |
|
||||||
|
| 16 | GoldenDog website/docs hosting | **Now** | Part of same launch push |
|
||||||
|
| 17 | GoldenDog ISO/download mirror | **Now** | Part of same launch push |
|
||||||
|
| 18 | GoldenDog email | **Now** | Quick win; just adding domain to Migadu |
|
||||||
|
| 19 | Deliver badge to Alexia | **Now** | Assets already built; just needs to be sent |
|
||||||
|
| 20 | Verify GoldenDog page content with Alexia | **Now** | Should happen before site goes live |
|
||||||
|
| 6 | Request IPv4 from ARIN | **Now** | Long lead time; start now regardless of other sequencing |
|
||||||
|
| 7 | Request ASN from ARIN | **Now** | Same — ARIN lead times are not short |
|
||||||
|
| 8 | Provision CDN ingress nodes | **Now** | Tied directly to GoldenDog launch |
|
||||||
|
| 1 | Update tier copy (static → web/app) | **Now** | Small change, immediately accurate, unblocked |
|
||||||
|
| 2 | Smoke test light/dark mode | **Now** | Should happen before any public launch |
|
||||||
|
| 3 | Sign off on 404 page | **Now** | Quick visual review |
|
||||||
|
| 29 | Define package contents per tier | **Now** | Pre-requisite for all pricing decisions; do this first |
|
||||||
|
| 21 | Decision: adopt new pricing | **Soon** | Blocked on #29; make the call with context |
|
||||||
|
| 22 | Decision: Business tier | **Soon** | Blocked on #29 |
|
||||||
|
| 23 | Decision: Matrix as add-on | **Soon** | Blocked on #29 |
|
||||||
|
| 24 | Decision: Enterprise floor | **Soon** | Can be concurrent with #21–23 |
|
||||||
|
| 25 | Update hosting plans page | **Soon** | Blocked on #21–24 and #29 |
|
||||||
|
| 26 | Discourse pricing comparison copy | **Soon** | Blocked on #25 |
|
||||||
|
| 28 | Annual pricing on plans page | **Soon** | Blocked on #25 |
|
||||||
|
| 9 | Document CDN architecture | **Soon** | Should be written as #8 is built |
|
||||||
|
| 10 | Set up shared Coolify cluster | **Soon** | Needed before first Essential/Standard client |
|
||||||
|
| 11 | Define resource cap policy | **Soon** | Should precede #10 conceptually; can run concurrently |
|
||||||
|
| 4 | Copy/tone review pass | **Soon** | Not blocking launch but should happen before growth push |
|
||||||
|
| 5 | Audit .gitignore | **Soon** | Minor; do when convenient |
|
||||||
|
| 27 | Community hosting policy doc | **Soon** | Should be written while GoldenDog details are fresh |
|
||||||
|
| 12 | Evaluate self-hosted email | **Later** | Relevant at ~15 clients; not urgent now |
|
||||||
|
| 13 | Contact Migadu enterprise | **Later** | Interim option; evaluate when Standard limits pressure |
|
||||||
|
| 14 | Backup/monitoring for multi-node | **Later** | Needed before second or third node is production |
|
||||||
|
| 30 | Compliance add-on decision | **Later** | Blocked on lawyer/insurance; wait for right client |
|
||||||
|
|
||||||
|
### Proposed swim lanes for project board
|
||||||
|
|
||||||
|
When the Gitea upgrade lands and project boards are available via API:
|
||||||
|
|
||||||
|
- **Now** — 13 issues: GoldenDog launch (15–20), ARIN filings (6–7), CDN (8), copy fix (1), smoke test (2), 404 review (3), package contents (29)
|
||||||
|
- **Soon** — 11 issues: pricing decisions (21–24), site updates (25–26, 28), CDN docs (9), cluster setup (10–11), copy pass (4), community policy (27), gitignore (5)
|
||||||
|
- **Later** — 4 issues: email strategy (12–13), multi-node monitoring (14), compliance add-on (30)
|
||||||
|
- **Done** — populated as issues close
|
||||||
75
social-media-assets.md
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
# Social Media Assets for Shrug.host
|
||||||
|
|
||||||
|
## Generated Assets
|
||||||
|
|
||||||
|
### Social Media Cards
|
||||||
|
- **`/static/images/social/og-card.svg`** - General Open Graph card (1200x630)
|
||||||
|
- Use for: Twitter, Facebook, general social sharing
|
||||||
|
|
||||||
|
- **`/static/images/social/linkedin-card.svg`** - LinkedIn-optimized card (1200x627)
|
||||||
|
- Use for: LinkedIn posts and company page
|
||||||
|
- Professional messaging focused on business benefits
|
||||||
|
|
||||||
|
- **`/static/images/social/bluesky-card.svg`** - Bluesky-optimized card (1200x675)
|
||||||
|
- Use for: Bluesky posts and profile
|
||||||
|
- Community-focused messaging with open web values
|
||||||
|
|
||||||
|
### Profile/Avatar Images
|
||||||
|
- **`/static/images/social/profile-logo.svg`** - Square profile image (400x400)
|
||||||
|
- Use for: Social media profile pictures, avatars
|
||||||
|
|
||||||
|
- **`/static/images/social/icon-only.svg`** - Icon-only version (200x200)
|
||||||
|
- Use for: Favicons, small displays, app icons
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Hugo is configured in `hugo.toml` with:
|
||||||
|
- Default Open Graph images
|
||||||
|
- Twitter card settings
|
||||||
|
- Social media handles (update when accounts are created)
|
||||||
|
|
||||||
|
## Usage Guidelines
|
||||||
|
|
||||||
|
### Color Consistency
|
||||||
|
All assets use the brand color palette:
|
||||||
|
- Primary Blue: #4f81a3 (electric muted blue)
|
||||||
|
- Accent Green: #10b981 (status lights, CTAs)
|
||||||
|
- Brand Grays: #374151, #6b7280, #9ca3af, #e5e7eb
|
||||||
|
|
||||||
|
### Platform-Specific Considerations
|
||||||
|
|
||||||
|
**LinkedIn:**
|
||||||
|
- Professional tone
|
||||||
|
- Business benefits focused
|
||||||
|
- Corporate messaging
|
||||||
|
|
||||||
|
**Bluesky:**
|
||||||
|
- Community-focused
|
||||||
|
- Open web values
|
||||||
|
- More casual/approachable tone
|
||||||
|
|
||||||
|
**Twitter/General:**
|
||||||
|
- Balanced approach
|
||||||
|
- Clear value proposition
|
||||||
|
- Call-to-action included
|
||||||
|
|
||||||
|
## Account Creation Checklist
|
||||||
|
|
||||||
|
When creating social media accounts, update:
|
||||||
|
1. `hugo.toml` social media handles
|
||||||
|
2. Profile pictures: use `profile-logo.svg`
|
||||||
|
3. Cover images: use platform-specific cards
|
||||||
|
4. Bio/description: reference brand messaging in CLAUDE.md
|
||||||
|
|
||||||
|
## File Formats
|
||||||
|
|
||||||
|
All assets are created as SVG for:
|
||||||
|
- Scalability at any size
|
||||||
|
- Small file sizes
|
||||||
|
- Sharp rendering on all displays
|
||||||
|
- Easy editing for future updates
|
||||||
|
|
||||||
|
Convert to PNG if platforms don't support SVG:
|
||||||
|
- Use 2x resolution for crisp display
|
||||||
|
- Maintain aspect ratios
|
||||||
|
- Optimize file sizes for web
|
||||||
19
static/badge-powered-by-dark.svg
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 30" fill="none" role="img" aria-label="Powered by shrug.host">
|
||||||
|
<!--
|
||||||
|
"Powered by shrug.host" badge — dark variant (for light backgrounds).
|
||||||
|
Embed in your site footer or README.
|
||||||
|
Links to: https://shrug.host
|
||||||
|
-->
|
||||||
|
<!-- Background pill -->
|
||||||
|
<rect width="220" height="30" rx="6" fill="rgba(0,0,0,0.04)" stroke="#e5e7eb" stroke-width="1"/>
|
||||||
|
<!-- Status dot -->
|
||||||
|
<circle cx="16" cy="15" r="4.5" fill="#10b981"/>
|
||||||
|
<!-- "POWERED BY" label -->
|
||||||
|
<text x="27" y="20" font-family="'Commit Mono', ui-monospace, monospace" font-size="8" font-weight="400" fill="#9ca3af" letter-spacing="0.10em">POWERED BY</text>
|
||||||
|
<!-- Thin divider -->
|
||||||
|
<line x1="100" y1="7" x2="100" y2="23" stroke="#e5e7eb" stroke-width="1"/>
|
||||||
|
<!-- "shrug.host" wordmark — single text/tspan so no gap artifact -->
|
||||||
|
<text y="21" font-family="'Commit Mono', ui-monospace, monospace" font-size="12" letter-spacing="-0.01em">
|
||||||
|
<tspan x="110" font-weight="700" fill="#1f2937">shrug</tspan><tspan font-weight="400" fill="#6b7280">.host</tspan>
|
||||||
|
</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
19
static/badge-powered-by-light.svg
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 30" fill="none" role="img" aria-label="Powered by shrug.host">
|
||||||
|
<!--
|
||||||
|
"Powered by shrug.host" badge — light variant (for dark backgrounds).
|
||||||
|
Embed in your site footer or README.
|
||||||
|
Links to: https://shrug.host
|
||||||
|
-->
|
||||||
|
<!-- Background pill -->
|
||||||
|
<rect width="220" height="30" rx="6" fill="rgba(255,255,255,0.08)" stroke="rgba(255,255,255,0.2)" stroke-width="1"/>
|
||||||
|
<!-- Status dot -->
|
||||||
|
<circle cx="16" cy="15" r="4.5" fill="#10b981"/>
|
||||||
|
<!-- "POWERED BY" label -->
|
||||||
|
<text x="27" y="20" font-family="'Commit Mono', ui-monospace, monospace" font-size="8" font-weight="400" fill="rgba(255,255,255,0.45)" letter-spacing="0.10em">POWERED BY</text>
|
||||||
|
<!-- Thin divider -->
|
||||||
|
<line x1="100" y1="7" x2="100" y2="23" stroke="rgba(255,255,255,0.15)" stroke-width="1"/>
|
||||||
|
<!-- "shrug.host" wordmark — single text/tspan so no gap artifact -->
|
||||||
|
<text y="21" font-family="'Commit Mono', ui-monospace, monospace" font-size="12" letter-spacing="-0.01em">
|
||||||
|
<tspan x="110" font-weight="700" fill="#ffffff">shrug</tspan><tspan font-weight="400" fill="rgba(255,255,255,0.6)">.host</tspan>
|
||||||
|
</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -1,11 +1,19 @@
|
|||||||
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none">
|
||||||
<!-- Server icon simplified for favicon -->
|
<!--
|
||||||
<rect x="4" y="4" width="24" height="24" rx="2" fill="#6b7280"/>
|
shrug.host favicon — server rack icon only.
|
||||||
<rect x="6" y="6" width="20" height="4" rx="1" fill="#e5e7eb"/>
|
Blue-deep background, white rack outline, green status dots.
|
||||||
<rect x="6" y="12" width="20" height="4" rx="1" fill="#e5e7eb"/>
|
Readable at 16px: the three green dots are the identifier.
|
||||||
<rect x="6" y="18" width="20" height="4" rx="1" fill="#e5e7eb"/>
|
-->
|
||||||
<rect x="6" y="24" width="20" height="2" rx="1" fill="#10b981"/>
|
<!-- Background -->
|
||||||
<circle cx="24" cy="8" r="1.5" fill="#10b981"/>
|
<rect width="32" height="32" rx="6" fill="#1e3a52"/>
|
||||||
<circle cx="24" cy="14" r="1.5" fill="#10b981"/>
|
<!-- Rack outline -->
|
||||||
<circle cx="24" cy="20" r="1.5" fill="#10b981"/>
|
<rect x="4" y="4" width="24" height="24" rx="2" stroke="rgba(255,255,255,0.7)" stroke-width="1.2" fill="none"/>
|
||||||
|
<!-- Slot lines -->
|
||||||
|
<rect x="6" y="8" width="14" height="4" rx="1" stroke="rgba(255,255,255,0.35)" stroke-width="0.8" fill="none"/>
|
||||||
|
<rect x="6" y="14" width="14" height="4" rx="1" stroke="rgba(255,255,255,0.35)" stroke-width="0.8" fill="none"/>
|
||||||
|
<rect x="6" y="20" width="14" height="4" rx="1" stroke="rgba(255,255,255,0.35)" stroke-width="0.8" fill="none"/>
|
||||||
|
<!-- Status dots — pulled inward, clear of the rack border -->
|
||||||
|
<circle cx="23" cy="10" r="2" fill="#10b981"/>
|
||||||
|
<circle cx="23" cy="16" r="2" fill="#10b981"/>
|
||||||
|
<circle cx="23" cy="22" r="2" fill="#10b981"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 622 B After Width: | Height: | Size: 1.0 KiB |
BIN
static/fonts/CommitMono-400-Italic.woff2
Normal file
BIN
static/fonts/CommitMono-400-Regular.woff2
Normal file
BIN
static/fonts/CommitMono-700-Italic.woff2
Normal file
BIN
static/fonts/CommitMono-700-Regular.woff2
Normal file
BIN
static/fonts/SourceSerif4-Italic.woff2
Normal file
BIN
static/fonts/SourceSerif4.woff2
Normal file
@ -1,66 +1,74 @@
|
|||||||
<svg width="1200" height="630" viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg">
|
<svg width="1200" height="630" viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg">
|
||||||
<!-- Background gradient -->
|
<!--
|
||||||
|
shrug.host OG card — updated for Warm Terminal redesign
|
||||||
|
Background: blue-deep (#1e3a52), refined rack icon, Commit Mono-style monospace text
|
||||||
|
-->
|
||||||
<defs>
|
<defs>
|
||||||
<linearGradient id="bgGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
<!-- Subtle grid pattern -->
|
||||||
<stop offset="0%" style="stop-color:#4f81a3;stop-opacity:1" />
|
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
|
||||||
<stop offset="100%" style="stop-color:#374151;stop-opacity:1" />
|
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="rgba(16,185,129,0.06)" stroke-width="1"/>
|
||||||
</linearGradient>
|
</pattern>
|
||||||
</defs>
|
</defs>
|
||||||
|
|
||||||
<!-- Background -->
|
<!-- Background -->
|
||||||
<rect width="1200" height="630" fill="url(#bgGradient)"/>
|
<rect width="1200" height="630" fill="#1e3a52"/>
|
||||||
|
<!-- Grid overlay -->
|
||||||
|
<rect width="1200" height="630" fill="url(#grid)"/>
|
||||||
|
<!-- Subtle bottom gradient fade -->
|
||||||
|
<rect width="1200" height="200" y="430" fill="url(#fade)" opacity="0.4"/>
|
||||||
|
|
||||||
<!-- Server rack icon (larger for social card) -->
|
<!-- Server rack icon — refined, thin stroke, green dots dominant -->
|
||||||
<g transform="translate(100, 180)">
|
<g transform="translate(88, 215)">
|
||||||
<!-- Server rack base -->
|
<!-- Rack outline -->
|
||||||
<rect x="0" y="0" width="60" height="75" rx="5" fill="#6b7280" stroke="#9ca3af" stroke-width="2"/>
|
<rect x="2" y="2" width="90" height="90" rx="7" stroke="rgba(255,255,255,0.55)" stroke-width="3" fill="none"/>
|
||||||
|
<!-- Server slot 1 -->
|
||||||
<!-- Server modules -->
|
<rect x="12" y="16" width="56" height="18" rx="4" stroke="rgba(255,255,255,0.25)" stroke-width="1.5" fill="none"/>
|
||||||
<rect x="5" y="5" width="50" height="15" rx="2" fill="#e5e7eb" stroke="#d1d5db" stroke-width="1"/>
|
<!-- Server slot 2 -->
|
||||||
<rect x="5" y="25" width="50" height="15" rx="2" fill="#e5e7eb" stroke="#d1d5db" stroke-width="1"/>
|
<rect x="12" y="40" width="56" height="18" rx="4" stroke="rgba(255,255,255,0.25)" stroke-width="1.5" fill="none"/>
|
||||||
<rect x="5" y="45" width="50" height="15" rx="2" fill="#e5e7eb" stroke="#d1d5db" stroke-width="1"/>
|
<!-- Server slot 3 -->
|
||||||
|
<rect x="12" y="64" width="56" height="18" rx="4" stroke="rgba(255,255,255,0.25)" stroke-width="1.5" fill="none"/>
|
||||||
<!-- Power/status bar -->
|
<!-- Status dots — always green, the dominant element -->
|
||||||
<rect x="5" y="65" width="50" height="5" rx="2" fill="#10b981"/>
|
<circle cx="82" cy="25" r="7" fill="#10b981"/>
|
||||||
|
<circle cx="82" cy="49" r="7" fill="#10b981"/>
|
||||||
<!-- Status lights -->
|
<circle cx="82" cy="73" r="7" fill="#10b981"/>
|
||||||
<circle cx="50" cy="12.5" r="3" fill="#10b981"/>
|
|
||||||
<circle cx="50" cy="32.5" r="3" fill="#10b981"/>
|
|
||||||
<circle cx="50" cy="52.5" r="3" fill="#10b981"/>
|
|
||||||
|
|
||||||
<!-- Data ports -->
|
|
||||||
<rect x="10" y="10" width="8" height="3" rx="1" fill="#6b7280"/>
|
|
||||||
<rect x="10" y="30" width="8" height="3" rx="1" fill="#6b7280"/>
|
|
||||||
<rect x="10" y="50" width="8" height="3" rx="1" fill="#6b7280"/>
|
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
<!-- Main content area -->
|
<!-- Eyebrow label -->
|
||||||
<g transform="translate(200, 150)">
|
<text x="88" y="196"
|
||||||
<!-- Main title -->
|
font-family="'Courier New', Courier, monospace"
|
||||||
<text x="0" y="60" font-family="system-ui, -apple-system, BlinkMacSystemFont, sans-serif" font-size="72" font-weight="700" fill="#ffffff">
|
font-size="18" font-weight="400"
|
||||||
shrug.host
|
fill="#10b981" letter-spacing="0.12em">
|
||||||
|
● HOSTING THAT JUST WORKS
|
||||||
</text>
|
</text>
|
||||||
|
|
||||||
|
<!-- Wordmark: "shrug" bold + ".host" lighter -->
|
||||||
|
<text x="205" y="287.5"
|
||||||
|
font-family="'Courier New', Courier, monospace"
|
||||||
|
font-size="96" font-weight="700"
|
||||||
|
fill="#ffffff" letter-spacing="-0.02em">shrug</text>
|
||||||
|
<text x="491" y="287.5"
|
||||||
|
font-family="'Courier New', Courier, monospace"
|
||||||
|
font-size="96" font-weight="400"
|
||||||
|
fill="rgba(255,255,255,0.55)" letter-spacing="-0.02em">.host</text>
|
||||||
|
|
||||||
<!-- Tagline -->
|
<!-- Tagline -->
|
||||||
<text x="0" y="120" font-family="system-ui, -apple-system, BlinkMacSystemFont, sans-serif" font-size="32" font-weight="400" fill="#e5e7eb">
|
<text x="110" y="370"
|
||||||
hosting that just works
|
font-family="'Courier New', Courier, monospace"
|
||||||
|
font-size="24" font-weight="400"
|
||||||
|
fill="rgba(255,255,255,0.6)" letter-spacing="0.01em">
|
||||||
|
Human-scale hosting for small organizations and open source projects.
|
||||||
</text>
|
</text>
|
||||||
|
|
||||||
<!-- Description -->
|
<!-- Bottom bar — domain -->
|
||||||
<text x="0" y="180" font-family="system-ui, -apple-system, BlinkMacSystemFont, sans-serif" font-size="24" font-weight="400" fill="#d1d5db">
|
<rect x="0" y="570" width="1200" height="60" fill="rgba(0,0,0,0.25)"/>
|
||||||
Human-scale hosting for small organizations
|
<text x="88" y="607"
|
||||||
</text>
|
font-family="'Courier New', Courier, monospace"
|
||||||
<text x="0" y="220" font-family="system-ui, -apple-system, BlinkMacSystemFont, sans-serif" font-size="24" font-weight="400" fill="#d1d5db">
|
font-size="20" font-weight="400"
|
||||||
and projects that need reliability without
|
fill="rgba(255,255,255,0.45)" letter-spacing="0.04em">shrug.host</text>
|
||||||
</text>
|
<!-- Green status indicator in bottom bar -->
|
||||||
<text x="0" y="260" font-family="system-ui, -apple-system, BlinkMacSystemFont, sans-serif" font-size="24" font-weight="400" fill="#d1d5db">
|
<circle cx="1100" cy="600" r="7" fill="#10b981"/>
|
||||||
enterprise complexity.
|
<text x="1118" y="607"
|
||||||
</text>
|
font-family="'Courier New', Courier, monospace"
|
||||||
|
font-size="16" font-weight="400"
|
||||||
<!-- Call to action -->
|
fill="rgba(255,255,255,0.4)" letter-spacing="0.04em">online</text>
|
||||||
<rect x="0" y="300" width="200" height="50" rx="6" fill="#10b981"/>
|
|
||||||
<text x="100" y="332" font-family="system-ui, -apple-system, BlinkMacSystemFont, sans-serif" font-size="18" font-weight="600" fill="#ffffff" text-anchor="middle">
|
|
||||||
View Hosting Plans
|
|
||||||
</text>
|
|
||||||
</g>
|
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 3.1 KiB |
@ -1 +0,0 @@
|
|||||||
Subproject commit aa8a7015c7459773a930e65e5d88e07f20ac8cc4
|
|
||||||