I should have written this a few weeks ago, when the project started and the ideas were fresh and messy. But honestly? I'm glad I waited. Because now there's something worth looking at.
This is how we built GRGhost, our fully custom Ghost CMS theme for the DarkLoom Studio website. From a blank folder to what you're reading right now.
Why We Didn't Just Buy a Theme
Ghost has a genuinely great theme ecosystem. Casper is clean. Edition is slick. Headline does the job for most content-focused sites. If you're starting a blog today and you need to be live by Monday, grab one of those and don't look back.
But we weren't building a blog. We were building a home for our future game projects and the visual identity we've been developing internally doesn't fit "clean blog aesthetic".
Most themes are designed for morning-coffee lifestyle content. Lots of white space, friendly sans-serifs, soft CTAs. That's not us. So we decided to build something that is.
Every pixel on this site exists because we made a deliberate decision to put it there. That ownership is worth more than the time it cost.
Choosing Ghost in the First Place
Before we could build a theme, we had to pick a platform. We looked seriously at four options:
WordPress was the obvious default, and we almost went with it. The plugin ecosystem is unbeatable. But the performance ceiling is low without serious infrastructure work, and the codebase carries decades of legacy debt. We'd be fighting the platform constantly.
Webflow is genuinely beautiful for design-first workflows, but the editor lock-in worried us. Content editors shouldn't need to think about flexbox to publish a post.
Framer — probably the coolest looking output of any of these — but it's not built for high-volume content. SEO is an afterthought and pagination doesn't exist in the way you need it for a real devblog.
Ghost won on three things: the writing experience is exceptional, Members and subscriptions are native so there's no plugin hell when we eventually gate content, and the theme API is clean and actually documented. On top of that, it gets updated with new features quite frequently.
The Homepage Was the Hardest Page
Every serious web project starts with the hardest page. For us, that was the homepage.
It needed to feel like landing on the splash screen of a AAA game studio — not a blog index, not a portfolio grid, but a destination. The kind of page where you arrive and immediately feel the world we're building.
The centerpiece is the Hero Carousel. Full-screen crossfade slides. Six-second autoplay with pause on hover. Keyboard navigation, touch swipe on mobile, dot indicators, arrow buttons — the whole thing. Each slide is its own world:
- A full-bleed key art background image
- Category label + game title + short hook description
- Platform store buttons (Steam, PlayStation, Xbox, Switch)
- Optional trailer button that opens a YouTube modal
That last piece — the trailer modal — was one of the trickier bits. We needed it to clean itself up properly on close (so you don't get audio bleeding through after the modal disappears) and use youtube-nocookie.com to stay privacy-respecting without adding a cookie consent wall.
The solution was simple once we stopped overthinking it: destroy and recreate the iframe on every open, rather than trying to pause or mute an existing one.
The Navbar Trick Nobody Will Notice
This is the kind of detail I love most: things that work perfectly and go completely unnoticed.
On the homepage, the navbar loads transparent — floating over the carousel hero, white text, no background. Once you scroll past 60px, it transitions to a solid dark background with a subtle border.
On interior pages, tag archives, author profiles, the team page — we use a body class to get contextually appropriate transparency without any JavaScript at all. Ghost's template system lets each page template declare its own body classes, so each context gets exactly what it needs.
The Full Template Map
One of Ghost's most underrated features is its template hierarchy. You can have completely different layouts for completely different contexts, and the routing system handles all the matching logic automatically.
Here's what GRGhost ships with:
| Template | Purpose |
|---|---|
home.hbs |
Cinematic homepage — carousel, info panels, discord CTA |
index.hbs |
Blog feed — paginated post grid |
post.hbs |
Individual article with dark reading canvas |
tag.hbs |
Tag/collection archive pages |
author.hbs |
Author profile with bio + post list |
page-team.hbs |
Team/About page with rarity-tiered member cards |
The Team page is the one I'm most proud of right now. It uses a JavaScript rarity tier system — directly inspired by loot rarity in games — to automatically classify team members based on their job title keyword.
CEO and Founders get legendary treatment. Leads and Seniors are epic. Developers, Designers, and Engineers are rare. QA land on uncommon. The badge appears automatically without anyone having to manually set a tier per member.
How the CSS Is Actually Organized
One thing that will quietly destroy a hand-rolled theme is CSS bleed. Styles intended for the homepage leaking onto post pages. Index-specific grid styles breaking the team layout. It's death by a thousand specificity battles.
We avoided this by keeping everything scoped to page-specific body classes and compiling through a single entry point.
/* screen.css — the bundle entry, Gulp compiles this */
@import "general/basics.css"; /* design tokens, resets, base typography */
@import "general/components.css"; /* shared UI: buttons, cards, tags */
@import "site/home.css"; /* scoped to .home-custom */
@import "site/post.css"; /* scoped to .gr-post-dark */
@import "site/team.css"; /* scoped to .gr-team-page */
The design token system is the part I'd do the same way on any future project. Everything visual — colors, spacing, borders, shadows — lives as CSS custom properties in basics.css. There's exactly one place to change the brand color.
:root {
/* Ghost writes this value from the Admin accent color picker */
--ghost-accent-color: #ff572f;
/* We bind our brand token to it, with a fallback */
--brand-color: var(--ghost-accent-color, #ff572f);
--navbar-height: 80px;
--surface-dark: #0d0d0d;
--surface-mid: #141414;
--text-primary: #f0ece6;
--text-muted: rgba(240, 236, 230, 0.55);
}
--ghost-accent-color is automatically set from the theme customization panel in Ghost Admin. By binding --brand-color to it, the site owner can change the accent color across the entire site without touching a single line of code.What's Still in Progress
The theme is in a solid v1 state. The homepage works, the blog feed works, the templates are all there. But there's a real roadmap ahead of this:
See the full Roadmap
- Light/dark mode toggle — the token architecture is already built for this.
prefers-color-schemesupport and a manual toggle UI are next. - Post series system — grouping multi-part reviews and dev diaries into ordered sequences with prev/next navigation.
- More hero slide types — video background slides, split-panel layouts, and a text-only minimal variant.
- Lighthouse performance audit — we want 95+ across the board before we call this production-ready.
Building a custom Ghost theme from scratch is not the path of least resistance. But when something breaks, we know where to look. When we want to add something new, we can do it cleanly without worrying about it interfering with a third-party stylesheet we don't control.
That ownership matters more than we expected it to.
If you're building a game studio site, a devblog, or any kind of content-heavy presence where visual identity actually matters — Ghost is worth your time. And if you have the bandwidth to build your own theme, do it. You'll regret nothing.
Follow Development
I’m keeping development transparent and grounded. No fake hype. Just building and sharing.
- Twitter / X — dev updates & behind-the-scenes
- Discord — feedback, discussion, chaos
- Steam Wishlist — playtests & updates (coming soon)
Closed alpha tests are planned for Q3 2026.
Subscribers & Wishlisters will be prioritized — especially the ones who break things.
Got thoughts? Questions?
Drop a comment or join the Discord. I read everything.
— DarkLoom Studio
Member discussion