Files
Cinderwild/tools/site/index.html

343 lines
19 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Emberwild: a self-hosted co-op survival game</title>
<meta name="description" content="Emberwild is a low-poly survival game: gather, hunt, build a home and hold out through the night, then dig through the sea cliffs to the Cove. Alone, or with friends on your own server.">
<meta name="theme-color" content="#15110d">
<meta property="og:type" content="website">
<meta property="og:url" content="{{SITE_URL}}/">
<meta property="og:title" content="Emberwild">
<meta property="og:description" content="Survive the island. Build a home. Self-hosted co-op survival for Mac and Windows.">
<meta property="og:image" content="{{SITE_URL}}/poster.jpg">
<meta name="twitter:card" content="summary_large_image">
<style>
:root {
--bg: #15110d; --bg2: #1b1510; --panel: #221b14; --line: #3a2e22;
--text: #f1e8da; --dim: #bcae98; --ember: #e8833a; --ember-hi: #f6a35c;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body { margin: 0; background: var(--bg); color: var(--text);
font: 17px/1.6 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; }
a { color: var(--ember-hi); }
a:focus-visible, button:focus-visible, video:focus-visible { outline: 3px solid var(--ember-hi); outline-offset: 3px; }
img { max-width: 100%; height: auto; display: block; }
.skip { position: absolute; left: -9999px; top: 8px; background: var(--ember); color: #1a120a; padding: 8px 14px; border-radius: 6px; z-index: 10; }
.skip:focus { left: 8px; }
.wrap { max-width: 1080px; margin: 0 auto; padding: 0 22px; }
/* Top bar */
nav.top { position: absolute; inset: 0 0 auto 0; z-index: 2; }
nav.top .wrap { display: flex; align-items: center; gap: 22px; padding-top: 16px; padding-bottom: 16px; }
nav.top .brand { font-weight: 700; letter-spacing: .14em; color: var(--text); text-decoration: none; margin-right: auto; }
nav.top a.l { color: var(--text); text-decoration: none; font-size: 15px; opacity: .9; }
nav.top a.l:hover { color: var(--ember-hi); }
@media (max-width: 620px) { nav.top a.l.opt { display: none; } }
/* Hero */
.hero { position: relative; min-height: min(88vh, 760px); display: flex; align-items: flex-end;
background: #0d0a07 url("shots/cove.jpg") center 35% / cover no-repeat; }
.hero::before { content: ""; position: absolute; inset: 0;
background: linear-gradient(180deg, rgba(13,10,7,.55) 0%, rgba(13,10,7,.15) 35%, rgba(21,17,13,.85) 78%, var(--bg) 100%); }
.hero .wrap { position: relative; padding-bottom: 56px; width: 100%; }
.pill { display: inline-block; font-size: 14px; padding: 3px 12px; border-radius: 999px;
background: rgba(232,131,58,.18); border: 1px solid rgba(246,163,92,.55); color: var(--ember-hi); }
.hero h1 { font-size: clamp(52px, 11vw, 112px); line-height: 1; letter-spacing: .07em; margin: 14px 0 8px; font-weight: 700;
text-shadow: 0 2px 24px rgba(0,0,0,.55); }
.hero .tag { font-size: clamp(19px, 2.6vw, 25px); margin: 0 0 6px; text-shadow: 0 1px 10px rgba(0,0,0,.7); }
.hero .sub { color: var(--dim); margin: 0 0 26px; max-width: 640px; text-shadow: 0 1px 8px rgba(0,0,0,.8); }
.ctas { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.btn { display: inline-block; background: var(--ember); color: #1a120a; text-decoration: none;
font-weight: 650; padding: 12px 22px; border-radius: 9px; border: 1px solid transparent; }
.btn:hover { background: var(--ember-hi); }
.btn.big { font-size: 19px; padding: 15px 28px; }
.btn.ghost { background: rgba(21,17,13,.55); color: var(--text); border-color: rgba(241,232,218,.35); }
.btn.ghost:hover { border-color: var(--ember-hi); color: var(--ember-hi); background: rgba(21,17,13,.75); }
.hero .small { color: var(--dim); font-size: 14px; margin: 12px 0 0; }
.hero .small a { color: var(--text); }
section { padding: 56px 0; }
section.alt { background: var(--bg2); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
h2 { font-size: clamp(26px, 3.4vw, 34px); line-height: 1.2; margin: 0 0 8px; font-weight: 650; }
.lead { color: var(--dim); margin: 0 0 26px; max-width: 720px; }
/* Trailer */
.video { border: 1px solid var(--line); border-radius: 12px; overflow: hidden; background: #000; aspect-ratio: 16 / 9;
box-shadow: 0 20px 60px rgba(0,0,0,.45); }
.video video { width: 100%; height: 100%; display: block; }
/* Feature cards */
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 18px; }
.card { background: var(--panel); border: 1px solid var(--line); border-radius: 12px; overflow: hidden; display: flex; flex-direction: column; }
.card img { aspect-ratio: 16 / 9; object-fit: cover; width: 100%; }
.card .body { padding: 16px 18px 18px; }
.card h3 { margin: 0 0 6px; font-size: 20px; }
.card p { margin: 0; color: var(--dim); font-size: 15.5px; }
/* What's new */
.new { display: grid; grid-template-columns: 1.3fr 1fr; gap: 28px; align-items: start; }
@media (max-width: 820px) { .new { grid-template-columns: 1fr; } }
ul.ticks { list-style: none; padding: 0; margin: 0; }
ul.ticks li { padding: 8px 0 8px 30px; position: relative; border-bottom: 1px solid var(--line); }
ul.ticks li:last-child { border-bottom: 0; }
ul.ticks li::before { content: ""; position: absolute; left: 4px; top: 17px; width: 10px; height: 10px; border-radius: 50%;
background: var(--ember); box-shadow: 0 0 10px rgba(232,131,58,.8); }
.callout { background: var(--panel); border: 1px solid var(--ember); border-radius: 12px; padding: 20px 22px; }
.callout h3 { margin: 0 0 8px; font-size: 20px; }
.callout p { margin: 0 0 10px; color: var(--dim); font-size: 15.5px; }
.callout p:last-child { margin: 0; }
kbd { font: 600 13px/1 ui-monospace, SFMono-Regular, Menlo, monospace; background: #2f251b; border: 1px solid #4a3b2c;
border-bottom-width: 2px; border-radius: 5px; padding: 3px 6px; color: var(--text); }
/* Gallery */
.gallery { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 14px; margin: 0; }
.gallery figure { margin: 0; position: relative; border-radius: 10px; overflow: hidden; border: 1px solid var(--line); background: #000; }
.gallery a { display: block; }
.gallery img { aspect-ratio: 16 / 9; object-fit: cover; width: 100%; transition: transform .35s ease; }
.gallery a:hover img { transform: scale(1.03); }
.gallery figcaption { position: absolute; left: 0; right: 0; bottom: 0; padding: 22px 14px 10px; font-size: 14.5px;
background: linear-gradient(transparent, rgba(0,0,0,.78)); pointer-events: none; }
/* Downloads */
.downloads { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 18px; }
.dl { background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 22px; }
.dl.mine { border-color: var(--ember); box-shadow: 0 0 0 1px var(--ember) inset; }
.dl h3 { margin: 0 0 2px; font-size: 21px; }
.dl .meta { margin: 0 0 16px; color: var(--dim); font-size: 15px; }
.dl .yours { display: none; font-size: 13px; color: var(--ember-hi); margin-left: 8px; font-weight: 600; }
.dl.mine .yours { display: inline; }
.note { color: var(--dim); font-size: 14.5px; margin: 14px 0 0; }
.note code, td code, p code { color: var(--text); background: #2a2119; padding: 1px 6px; border-radius: 5px; font-size: .92em; }
/* Friends */
.steps { counter-reset: s; display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 18px; margin: 0 0 22px; padding: 0; list-style: none; }
.steps li { background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 18px 18px 18px 60px; position: relative; color: var(--dim); font-size: 15.5px; }
.steps li b { color: var(--text); }
.steps li::before { counter-increment: s; content: counter(s); position: absolute; left: 18px; top: 16px; width: 28px; height: 28px;
border-radius: 50%; background: var(--ember); color: #1a120a; font-weight: 700; display: grid; place-items: center; font-size: 15px; }
table { border-collapse: collapse; width: 100%; max-width: 640px; font-size: 15.5px; }
th, td { text-align: left; padding: 9px 12px; border-bottom: 1px solid var(--line); }
th { color: var(--dim); font-weight: 600; }
footer { border-top: 1px solid var(--line); padding: 28px 0 44px; color: var(--dim); font-size: 14.5px; }
footer .wrap { display: flex; flex-wrap: wrap; gap: 10px 26px; justify-content: space-between; }
footer nav a { margin-right: 18px; }
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
.gallery img { transition: none; }
.gallery a:hover img { transform: none; }
}
</style>
</head>
<body>
<a class="skip" href="#main">Skip to the page</a>
<nav class="top" aria-label="Site">
<div class="wrap">
<a class="brand" href="#">EMBERWILD</a>
<a class="l opt" href="#trailer">Trailer</a>
<a class="l opt" href="#world">The game</a>
<a class="l" href="guide.html">Guide</a>
<a class="l" href="#download">Download</a>
</div>
</nav>
<header class="hero">
<div class="wrap">
<span class="pill">Version {{VERSION}} · playtest</span>
<h1>EMBERWILD</h1>
<p class="tag">Survive the island. Build a home. Find what lies beyond.</p>
<p class="sub">A low-poly survival game for Mac and Windows. Gather, hunt and build, hold out
through wolf moons and hard winters, then dig down through the sea cliffs to the Cove.
Alone, or with friends on a server you run yourself.</p>
<div class="ctas">
<a class="btn big" id="hero-dl" href="#download">Download free</a>
<a class="btn ghost" href="#trailer">Watch the trailer</a>
<a class="btn ghost" href="guide.html">Read the guide</a>
</div>
<p class="small" id="hero-other">For macOS (Apple silicon and Intel) and Windows (64-bit).</p>
</div>
</header>
<main id="main">
<section id="trailer" aria-labelledby="trailer-title">
<div class="wrap">
<h2 id="trailer-title">The trailer</h2>
<p class="lead">Under a minute, recorded in the game.</p>
<div class="video">
<video controls preload="metadata" poster="poster.jpg" aria-label="Emberwild trailer">
<source src="trailer.mp4" type="video/mp4">
Your browser can't play this video. <a href="trailer.mp4">Download the trailer</a>.
</video>
</div>
</div>
</section>
<section id="world" class="alt" aria-labelledby="world-title">
<div class="wrap">
<h2 id="world-title">What you'll do</h2>
<p class="lead">Every tree, animal and hut is built from low-poly shapes in the game's
own code, under a lot of weather.</p>
<div class="cards">
<article class="card">
<img src="shots/meadow.jpg" alt="A sunny meadow with deer among the trees" width="1280" height="720" loading="lazy">
<div class="body"><h3>Survive</h3>
<p>Gather, craft and cook. Keep warm, fed and dry, and eat a mix of meat, fish and
greens. Food goes off; salt and smoke keep it.</p></div>
</article>
<article class="card">
<img src="shots/hut.jpg" alt="A wooden hut with a campfire at dusk" width="1280" height="720" loading="lazy">
<div class="body"><h3>Build</h3>
<p>Floors, walls and roofs that snap together, in wood and then stone. A roof, a
fire and a bed make a home you'll be glad of at night.</p></div>
</article>
<article class="card">
<img src="shots/wolves.jpg" alt="Wolves circling a campfire under a red moon" width="1280" height="720" loading="lazy">
<div class="body"><h3>Hold out</h3>
<p>Wolves move in, and every seventh night the moon turns red. There's a bear in
the deep woods, a barrow, and the Old Stag at the standing stones.</p></div>
</article>
<article class="card">
<img src="shots/treasure.jpg" alt="A marker stone in the Cove's hills at dusk, with a drowned sailor among the trees" width="1280" height="720" loading="lazy">
<div class="body"><h3>Explore</h3>
<p>Dig through the sea cliffs to the Cove: a sandy bay, a pier for sea fishing, a
wreck, and a pirate treasure for each player, guarded by the drowned crew.</p></div>
</article>
</div>
</div>
</section>
<section id="new" aria-labelledby="new-title">
<div class="wrap">
<h2 id="new-title">New in {{VERSION}}</h2>
<p class="lead">The Cove gets its own. This is a playtest build: thanks for trying it.</p>
<div class="new">
<ul class="ticks">
<li>A wreck on the Cove's beach, with a treasure map in the captain's sea chest for each player.</li>
<li>Your own X on your map: dig up the pirate chest for a ship's compass, a spyglass, a cutlass and gold.</li>
<li>The drowned crew rise to guard it. Dig by day if you're wise.</li>
<li>Crabs on the sand from dusk till dawn, and gulls after any food you leave out.</li>
<li>Build a rowing boat from driftwood, seagrass rope and pitch, and tie it up at the pier.</li>
<li>Report a bug, straight from the pause menu.</li>
</ul>
<aside class="callout" aria-labelledby="bug-title">
<h3 id="bug-title">Found a bug?</h3>
<p>Press <kbd>Esc</kbd> in the game, then <b>Report a bug</b>. It opens a new issue
on <a href="{{REPO_URL}}/issues">our Gitea</a>, already filled in with your
version, computer and where you are. Say what happened and press Create Issue.</p>
<p>You'll need a free account there. <a href="{{REPO_URL}}/src/branch/master/docs/PLAYTEST.md">What to try, and what isn't a bug yet</a>.</p>
</aside>
</div>
</div>
</section>
<section class="alt" aria-labelledby="gallery-title">
<div class="wrap">
<h2 id="gallery-title">Screenshots</h2>
<p class="lead">Straight from the game. Click one to see it full size.</p>
<div class="gallery">
<figure><a href="shots/cove.jpg"><img src="shots/cove.jpg" alt="The Cove's bay and pier on a clear morning, a rowing boat tied up" width="1280" height="720" loading="lazy"></a>
<figcaption>The Cove, and a boat at the pier</figcaption></figure>
<figure><a href="shots/crabs.jpg"><img src="shots/crabs.jpg" alt="Red crabs on the sand at dusk" width="1280" height="720" loading="lazy"></a>
<figcaption>Crabs come up the beach at dusk</figcaption></figure>
<figure><a href="shots/winter.jpg"><img src="shots/winter.jpg" alt="A hut in a snowy clearing in a blizzard" width="1280" height="720" loading="lazy"></a>
<figcaption>Weather the winter</figcaption></figure>
<figure><a href="shots/hut.jpg"><img src="shots/hut.jpg" alt="A wooden hut with a campfire at dusk" width="1280" height="720" loading="lazy"></a>
<figcaption>A home of your own</figcaption></figure>
<figure><a href="shots/wolves.jpg"><img src="shots/wolves.jpg" alt="Wolves circling a campfire under a red moon" width="1280" height="720" loading="lazy"></a>
<figcaption>The wolf moon</figcaption></figure>
<figure><a href="shots/treasure.jpg"><img src="shots/treasure.jpg" alt="A marker stone and a mound of loose earth in the hills at dusk" width="1280" height="720" loading="lazy"></a>
<figcaption>X marks the spot</figcaption></figure>
</div>
</div>
</section>
<section id="download" aria-labelledby="dl-title">
<div class="wrap">
<h2 id="dl-title">Download version {{VERSION}}</h2>
<p class="lead">Free. Released {{DATE}}. The game tells you on its title screen when a newer version is out.</p>
<div class="downloads">
<div class="dl" data-os="mac">
<h3>macOS <span class="yours">· your computer</span></h3>
<p class="meta">Apple silicon and Intel · {{MAC_SIZE}}</p>
<a class="btn" href="{{MAC_URL}}">Download for Mac</a>
<p class="note">Unzip it. The first time, right-click the app and choose <b>Open</b>
(it isn't notarised by Apple yet).</p>
</div>
<div class="dl" data-os="win">
<h3>Windows <span class="yours">· your computer</span></h3>
<p class="meta">64-bit · {{WIN_SIZE}}</p>
<a class="btn" href="{{WIN_URL}}">Download for Windows</a>
<p class="note">Unzip, then run <code>Emberwild.exe</code>. If SmartScreen warns,
choose <b>More info</b> &gt; <b>Run anyway</b> (it isn't signed yet).</p>
</div>
</div>
<p class="note"><a href="{{RELEASES_URL}}">All releases, release notes and checksums</a>.</p>
</div>
</section>
<section id="friends" class="alt" aria-labelledby="host-title">
<div class="wrap">
<h2 id="host-title">Playing with friends</h2>
<p class="lead">No accounts and no company servers: one of you hosts, on your own computer.</p>
<ol class="steps">
<li><b>Host Game</b> on the title screen. Pick a name, a rules preset (co-op, rivals
or adversarial) and a password if you like.</li>
<li>Friends choose <b>Join Game</b> and type your address. Everyone needs the same
version.</li>
<li>On the same network, or over Tailscale, that's it. Over the internet, forward the
ports below on your router.</li>
</ol>
<table>
<caption class="note" style="caption-side: bottom; text-align: left;">The Cove runs as its own server on the next port, started when someone first goes there.</caption>
<thead><tr><th scope="col">UDP port</th><th scope="col">For</th></tr></thead>
<tbody>
<tr><td><code>24242</code></td><td>The Valley (the server you join)</td></tr>
<tr><td><code>24243</code></td><td>The Cove</td></tr>
</tbody>
</table>
<p class="note">A spare computer can run a dedicated server from the same download:
<code>Emberwild --headless -- --server</code>.
<a href="guide.html#multiplayer">More in the guide</a>.</p>
</div>
</section>
</main>
<footer>
<div class="wrap">
<nav aria-label="More">
<a href="guide.html">The guide</a>
<a href="{{RELEASES_URL}}">Releases</a>
<a href="{{REPO_URL}}/issues">Report a bug</a>
<a href="{{REPO_URL}}">Source</a>
</nav>
<span>Emberwild {{VERSION}}. Made with Godot.</span>
</div>
</footer>
<script>
// The visitor's own computer: its download first and marked, and the
// hero's button goes straight to it. (Without this, the page still works.)
(function () {
var ua = navigator.userAgent;
var os = /iPhone|iPad|Android/i.test(ua) ? "" : /Mac/i.test(ua) ? "mac" : /Win/i.test(ua) ? "win" : "";
if (!os) return;
var card = document.querySelector('.dl[data-os="' + os + '"]');
if (!card) return;
card.classList.add("mine");
card.parentNode.insertBefore(card, card.parentNode.firstChild);
var link = card.querySelector("a.btn");
var hero = document.getElementById("hero-dl");
hero.href = link.href;
hero.textContent = os === "mac" ? "Download for Mac" : "Download for Windows";
var other = document.getElementById("hero-other");
other.innerHTML = "Free · {{VERSION}} · " + card.querySelector(".meta").textContent.split("·").pop().trim() +
' · <a href="#download">' + (os === "mac" ? "Windows" : "Mac") + " and install notes</a>";
})();
</script>
</body>
</html>