Le studio a été fondé à trois, mais seul le rôle du jour était affiché. "Co-founder" ouvre maintenant les trois cartes plutôt que d'être accroché à un seul nom. La ligne de rôle passe en segments insécables au passage : sur trois cartes sur trois elle tient désormais sur deux lignes, et le navigateur aurait coupé "Co-founder" à son trait d'union. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Highland Games Studio — Website
Marketing and devblog site for Highland Games Studio. Where summits become worlds.
Built with Next.js 16 (App Router), React 19, Tailwind CSS 4 and Framer Motion.
Devblog posts are authored in MDX and rendered with next-mdx-remote.
Getting started
npm install
npm run dev
Open http://localhost:3000.
Scripts
| Command | Description |
|---|---|
npm run dev |
Start the dev server |
npm run build |
Production build |
npm run start |
Serve the production build |
npm run lint |
Run ESLint |
Asset generation scripts (require sharp, already a devDependency):
node scripts/build-favicon.mjs # favicon + app icon from the mountain mark
node scripts/build-wordmark.mjs # transparent wordmark from "Full Logo.png"
Project structure
app/ Routes, layouts, server actions, metadata (sitemap/robots/feed/OG)
app/components/ui/ Design-system primitives (Section, SectionHeading, ButtonLink, Logo…)
app/components/layout/ Navbar, Footer, SocialLinks
app/components/game/ GameCard, ScreenshotGallery
app/components/home/ Home hero
app/components/devblog/ PostList
app/components/forms/ ContactForm, Newsletter
content/devblog/ Devblog posts as .mdx (frontmatter: title, date, excerpt, tags, game)
lib/ Data + helpers (games registry, devblog loader, site config, formatting)
public/ Static assets (studio logos, game art, hero video)
scripts/ One-off asset build scripts
Content lives in lib/, never in a page
lib/site.ts— studio identity, navigation, contact channels, social accounts, brand assets.lib/games.ts— the games registry: title, description, genres, key art, banner and screenshots.
Pages read from these. That is what keeps the home page and /games/[slug] in sync — the
featured block, the "From the workshop" gallery and the game page all render the same record.
Design rule: no text over artwork
The Emberwild key art is light cream and the in-game captures are bright green, so body text
laid over them is unreadable at any gradient strength. Cards therefore put the image on one
panel and the text on a solid bg-surface panel; the game page shows the banner alone and
places the title underneath. Keep it that way when adding new layouts.
Adding a game or new screenshots
Drop the files in public/image/Games/<Game>/, then add or edit the entry in lib/games.ts:
{
slug: "emberwild",
title: "Emberwild",
status: "in-development", // in-development | coming-soon | released
tagline: "One readable line.",
description: "Full pitch, shown in the About block.",
genres: ["Survival", "Crafting"],
releaseWindow: "TBA",
keyArt: "/image/Games/Emberwild/Cover.png", // illustration, shown contained
banner: "/image/Games/Emberwild/Capture_1.png", // wide in-game shot, page banner
screenshots: [
{ src: "/image/Games/Emberwild/Capture_2.png", caption: "Autumn treeline" },
],
}
The gallery, the home page teaser, /games, the sitemap and the JSON-LD all pick it up.
Configuration
Copy .env.example to .env.local and fill in the values.
- Site URL — set
NEXT_PUBLIC_SITE_URLper environment (used by metadata, sitemap, robots, RSS and JSON-LD). Defaults tohttps://highlandgamesstudio.com— seelib/site.ts. - Contact form (Resend) — the contact form sends email via Resend.
Set
RESEND_API_KEY,CONTACT_TO_EMAIL(who receives messages) andCONTACT_FROM_EMAIL(sender, must be on a domain verified in Resend). Without these, the form returns a friendly error instead of sending. Seeapp/actions/contact.ts.
Adding a devblog post
Create a file in content/devblog/, e.g. 2026-06-01-my-post.mdx:
---
title: "My post title"
date: "2026-06-01"
excerpt: "One-line summary for listings and SEO."
author: "Highland Games Studio"
tags: ["devlog"]
game: "emberwild"
---
Your MDX content here.
Deployment
Pushes to master deploy to the Hetzner server via the Gitea Actions workflow
(.gitea/workflows/deploy.yml), which SSHes in, pulls, builds, and restarts the
PM2 process (highland, in /var/www/highland).
Requires these repo secrets (Gitea → repo → Settings → Actions → Secrets):
SSH_HOST, SSH_USER, SSH_PORT, SSH_PRIVATE_KEY.
Server-side prerequisites (one-time):
- A registered Gitea
act_runnerwith theubuntu-latestlabel. /var/www/highlandis a clone of this repo whoseorigincan pull the private Gitea repo non-interactively (deploy key or token in the remote URL).- Node +
pm2installed, with the app running as thehighlandprocess.
Known TODOs
See TODO.md for the full list. The two blockers are the 84 MB hero video
(public/Video/Header_Video.mp4) and the social links, which are still unpublished
(SOCIAL_LINKS in lib/site.ts — entries with href: null are hidden rather than
rendered as dead # links).