Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

<img alt="The 0-draft desk" src="public/og.png">

Everything public in the [0-draft](https://github.com/0-draft) org, filed as dossiers on a lodge desk at <https://0-draft.github.io/>.
Everything public in the [0-draft](https://github.com/0-draft) org, pulled as proofs and laid out on a print-shop desk at night: <https://0-draft.github.io/>.

Drag the desk to look around and pinch (or press `+` and `-`) to zoom. Break the wax seal on a sheet and the real site opens right on the desk. Red string ties together sheets that belong together across piles. Blackjack, shogi and the guest book are read live from their READMEs, so you can make a move from here. Prefer a plain page? Press "List view".
Drag the desk to look around and pinch (or press `+` and `-`) to zoom. Break the wax seal on a sheet and the real site opens right on the desk. Blackjack, shogi and the guest book are read live from their READMEs, so you can make a move from here. Prefer a plain page? Press "List view".

## How it works

- `scripts/sync.ts` pulls the org's public repos (archived repos and forks are left out), the live region of each README game, and the latest dev.to articles into `src/data/`. A source that fails keeps its previous file.
- `src/data/groups.ts` decides which pile a repo sits in. A new repo that isn't filed there shows up on its own pile on the next build.
- `src/lib/desk.ts` holds where each sheet sits on the mat. `src/scripts/desk.ts` is the camera: pan, zoom, rulers, minimap and the live frame. It has no dependencies.
- `src/lib/desk.ts` holds where each sheet sits on the desk. `src/scripts/desk.ts` is the camera: pan, zoom, the minimap and the live frame. It has no dependencies.
- `src/assets/shots/` holds a screenshot per project, named after the repo.

## CI
Expand Down
22 changes: 7 additions & 15 deletions astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,17 @@ export default defineConfig({
fonts: [
{
provider: fontProviders.google(),
name: "M PLUS Rounded 1c",
cssVariable: "--font-round",
weights: [500, 800, 900],
name: "Archivo",
cssVariable: "--font-sans",
weights: [400, 500, 700, 800, 900],
subsets: ["latin"],
fallbacks: ["ui-rounded", "system-ui", "sans-serif"],
fallbacks: ["Helvetica Neue", "Arial", "sans-serif"],
},
{
provider: fontProviders.google(),
name: "IM Fell English SC",
cssVariable: "--font-fell",
weights: [400],
subsets: ["latin"],
fallbacks: ["Georgia", "serif"],
},
{
provider: fontProviders.google(),
name: "DotGothic16",
cssVariable: "--font-dot",
weights: [400],
name: "Martian Mono",
cssVariable: "--font-mono",
weights: [400, 500],
subsets: ["latin"],
fallbacks: ["ui-monospace", "monospace"],
},
Expand Down
Binary file modified public/og.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/tex/ink.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/tex/paper.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/tex/stock.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 2 additions & 13 deletions src/components/Sheet.astro
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
import { Image } from "astro:assets";
// One project, printed and taped to the mat.
// One project, pulled as a proof and laid on the desk.
import type { ImageMetadata } from "astro";
import wax from "../assets/wax.png";
import { ago, framable, type Shelf } from "../lib/desk.ts";
Expand Down Expand Up @@ -29,17 +29,6 @@ const host = site?.replace(/^https:\/\//, "").replace(/\/$/, "");
data-group={group}
aria-labelledby={`${repo.name}-title`}
>
{
repo.tape === 0 ? (
<Image class="fix fix-seal" src={wax} alt="" width={136} format="webp" />
) : repo.tape === 1 ? (
<span class="fix tape" aria-hidden="true" />
) : (
<svg class="fix fix-clip" viewBox="0 0 40 110" aria-hidden="true">
<use href="#clip" />
</svg>
)
}
{
kind === "screen" && (
<div class="screen">
Expand Down Expand Up @@ -82,5 +71,5 @@ const host = site?.replace(/^https:\/\//, "").replace(/\/$/, "");
<a class="btn" href={repo.url}>Source</a>
</p>
</div>
<svg class:list={["stamp", `stamp-${repo.tape}`]} viewBox="0 0 120 120" aria-hidden="true"><use href="#stamp"></use></svg>
<svg class:list={["stamp", `stamp-${repo.tape}`]} viewBox="0 0 172 76" aria-hidden="true"><use href="#stamp"></use></svg>
</article>
13 changes: 1 addition & 12 deletions src/lib/desk.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Where everything sits on the mat, in world pixels. The home sheet is centred on (0, 0).
// Where everything sits on the desk, in world pixels. The home sheet is centred on (0, 0).
// Positions are top-left corners; sizes come from the rendered elements, so only placement lives here.
import { fallback, groups } from "../data/groups.ts";
import repos from "../data/repos.json";
Expand Down Expand Up @@ -36,17 +36,6 @@ export const labels: Record<string, Spot> = {
fresh: { x: 900, y: 1500 },
};

// Red string between sheets that belong together across piles: the same subject,
// or a project and the article written about it. Pairs naming a missing repo are skipped.
export const threads: [string, string][] = [
["caller-identity", "assume-role"],
["assume-role", "identity-deep-dive"],
["on-ramp", "cross-connect"],
["authz-playground", "dev.to"],
["identity-deep-dive", "dev.to"],
["shogi", "dev.to"],
];

// Dossier numbers are primes, for anyone who notices.
const PRIMES = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31];
export const fileNo = (i: number) => `File ${String(PRIMES[i] ?? i + 1).padStart(2, "0")}`;
Expand Down
27 changes: 0 additions & 27 deletions src/lib/guilloche.ts

This file was deleted.

76 changes: 13 additions & 63 deletions src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import Blocks from "../components/Blocks.astro";
import Sheet from "../components/Sheet.astro";
import articles from "../data/articles.json";
import games from "../data/games.json";
import { fileNo, home, shelves, threads } from "../lib/desk.ts";
import { rosette } from "../lib/guilloche.ts";
import { fileNo, home, shelves } from "../lib/desk.ts";
import type { Block } from "../lib/readme.ts";
import "../styles/desk.css";

Expand All @@ -17,12 +16,6 @@ const shortDate = (iso: string) =>
new Date(iso).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric", timeZone: "UTC" });
const description = "Raw outputs, researches, and unpolished tools. Everything here is v0.";
const count = all.reduce((n, s) => n + s.repos.length, 0);
const onDesk = new Set(all.flatMap((s) => s.repos.map((r) => r.name)));
const strings = threads.filter(([a, b]) => onDesk.has(a) && onDesk.has(b)).map((t) => t.join(":"));
const crest = rosette(330, 330, [
{ radius: 300, amplitude: 14, waves: 36, strands: 7 },
{ radius: 252, amplitude: 9, waves: 48, strands: 5 },
]);
---

<!doctype html>
Expand All @@ -36,52 +29,18 @@ const crest = rosette(330, 330, [
<meta property="og:description" content={description} />
<meta property="og:image" content={new URL("/og.png", Astro.site)} />
<meta name="twitter:card" content="summary_large_image" />
<meta name="theme-color" content="#1c3f33" />
<meta name="theme-color" content="#0f0e0d" />
<link rel="icon" href="/favicon.png" type="image/png" />
<Font cssVariable="--font-round" preload />
<Font cssVariable="--font-dot" preload />
<Font cssVariable="--font-fell" preload />
<Font cssVariable="--font-sans" preload />
<Font cssVariable="--font-mono" preload />
</head>
<body>
<svg width="0" height="0" class="sprite" aria-hidden="true">
<defs>
<radialGradient id="brass-fill" cx="35%" cy="30%" r="75%">
<stop offset="0" stop-color="#f3dfa6"></stop>
<stop offset="0.45" stop-color="#c9a45c"></stop>
<stop offset="1" stop-color="#7a5a2a"></stop>
</radialGradient>
</defs>
<symbol id="pin" viewBox="0 0 40 40">
<ellipse cx="22" cy="30" rx="11" ry="5" fill="rgb(0 0 0 / 0.35)"></ellipse>
<circle cx="20" cy="18" r="13" fill="url(#brass-fill)"></circle>
<circle cx="16" cy="13" r="4" fill="#fff6d8" opacity="0.7"></circle>
</symbol>
<symbol id="clip" viewBox="0 0 40 110">
<path
d="M12 96V22a8 8 0 0 1 16 0v66a13 13 0 0 1-26 0V14a12 12 0 0 1 24 0"
fill="none"
stroke="#8a6a3a"
stroke-width="5"
stroke-linecap="round"></path>
<path
d="M12 96V22a8 8 0 0 1 16 0v66a13 13 0 0 1-26 0V14a12 12 0 0 1 24 0"
fill="none"
stroke="#e3c98b"
stroke-width="2.2"
stroke-linecap="round"
transform="translate(-0.8 -0.8)"></path>
</symbol>
<symbol id="stamp" viewBox="0 0 120 120">
<path id="stamp-ring" d="M60 60m-45 0a45 45 0 1 1 90 0a45 45 0 1 1-90 0" fill="none"></path>
<circle cx="60" cy="60" r="57" fill="none" stroke="currentColor" stroke-width="4"></circle>
<circle cx="60" cy="60" r="35" fill="none" stroke="currentColor" stroke-width="2"></circle>
<text font-size="11.5" font-weight="900" letter-spacing="1.4" fill="currentColor">
<textPath href="#stamp-ring">raw output · unpolished · draft zero ·</textPath>
</text>
<path
d="M60 45.5s-5-3-5-6.4a2.6 2.6 0 0 1 5-1 2.6 2.6 0 0 1 5 1c0 3.4-5 6.4-5 6.4z"
fill="currentColor"></path>
<text x="60" y="78" text-anchor="middle" font-size="30" font-weight="900" fill="currentColor">v0</text>
<symbol id="stamp" viewBox="0 0 172 76">
<rect x="3" y="3" width="166" height="70" rx="5" fill="none" stroke="currentColor" stroke-width="4.5"></rect>
<rect x="10" y="10" width="152" height="56" rx="2" fill="none" stroke="currentColor" stroke-width="1.6"></rect>
<text x="86" y="44" text-anchor="middle" font-size="31" font-weight="900" letter-spacing="5" fill="currentColor">PROOF</text>
<text x="86" y="59" text-anchor="middle" font-size="9" font-weight="700" letter-spacing="1.6" fill="currentColor">v0 · not for release</text>
</symbol>
</svg>
<a class="skip" href="#list" data-mode="list">Skip to the project list</a>
Expand All @@ -98,16 +57,13 @@ const crest = rosette(330, 330, [
</header>

<main class="desk" id="desk" aria-label="The 0-draft desk">
<div class="surface" aria-hidden="true"></div>
<div class="world" id="world">
<section class="item home" id="home" data-x={home.x} data-y={home.y} data-tilt="0" data-group="home">
<div class="crest">
<svg class="guilloche" viewBox="0 0 660 660" aria-hidden="true"><path d={crest}></path></svg>
<img class="home-seal" src="/seal.png" alt="The 0-draft seal: a robot face under a black beret with a red heart" width="900" height="860" fetchpriority="high" />
</div>
<img class="home-seal" src="/seal.png" alt="The 0-draft seal: a robot face under a black beret with a red heart" width="900" height="860" fetchpriority="high" />
<div class="home-copy">
<p class="motto">Societas Draftorum Nulla</p>
<h1>0-draft</h1>
<p class="bubble">Raw outputs, researches, and unpolished tools. Everything here is v0.</p>
<p class="lede">Raw outputs, researches, and unpolished tools. Everything here is v0.</p>
<p class="hint">
<span class="hint-desk">Drag the desk to look around and pinch to zoom. Break a seal and the project opens right here.</span>
<span class="hint-list">{count} files on the desk right now, in {all.length} piles.</span>
Expand All @@ -119,12 +75,8 @@ const crest = rosette(330, 330, [
</button>.
</p>
</div>
<img class="sticker sticker-avatar" src="/avatar.png" alt="" width="370" height="370" loading="lazy" />
</section>

<svg class="strings" data-threads={strings.join(",")} aria-hidden="true"></svg>
<svg class="strings pins" aria-hidden="true"></svg>

<div class="list-anchor" id="list" tabindex="-1"></div>

{
Expand All @@ -134,7 +86,7 @@ const crest = rosette(330, 330, [
class="item label"
data-x={shelf.label.x}
data-y={shelf.label.y}
data-tilt="-1.2"
data-tilt="0"
data-group={shelf.id}
>
<span class="file-no">{fileNo(i)}</span>
Expand Down Expand Up @@ -208,8 +160,6 @@ const crest = rosette(330, 330, [
<div class="scrim" aria-hidden="true"></div>
</main>

<canvas class="ruler ruler-x" aria-hidden="true"></canvas>
<canvas class="ruler ruler-y" aria-hidden="true"></canvas>

<nav class="hud tray" aria-label="Move around the desk">
<div class="tray-go">
Expand Down
Loading
Loading