From cd2994c25b4036360780f81365fd1cd1fbc87a16 Mon Sep 17 00:00:00 2001 From: Bailey Pumfleet Date: Tue, 13 Oct 2026 10:49:17 -0500 Subject: [PATCH] chore(shipyard): remove apps/shipyard, served from cosscom/coss coss.com/shipyard and /shipyard/docs are served by coss.com's site in cosscom/coss (apps/site), where the landing page and docs were moved (cosscom/coss#51, #52). This copy was never deployed and would only drift. The products menu keeps linking to /shipyard. Claude-Session: https://claude.ai/code/session_018shdXm52pLc2E5HNmFLM44 --- apps/shipyard/.gitignore | 44 - apps/shipyard/README.md | 27 - apps/shipyard/app/api/raw/[...slug]/route.ts | 50 - apps/shipyard/app/apple-icon.png | Bin 5548 -> 0 bytes apps/shipyard/app/docs.css | 325 ----- apps/shipyard/app/docs/[[...slug]]/page.tsx | 102 -- apps/shipyard/app/docs/layout.tsx | 18 - apps/shipyard/app/globals.css | 12 - apps/shipyard/app/icon.svg | 4 - apps/shipyard/app/landing.css | 766 ---------- apps/shipyard/app/layout.tsx | 53 - apps/shipyard/app/not-found.tsx | 44 - apps/shipyard/app/opengraph-image.jpg | Bin 185579 -> 0 bytes apps/shipyard/app/page.tsx | 515 ------- apps/shipyard/app/sitemap.ts | 14 - apps/shipyard/app/twitter-image.jpg | Bin 185579 -> 0 bytes apps/shipyard/components/command-menu.tsx | 172 --- apps/shipyard/components/docs-copy-page.tsx | 21 - apps/shipyard/components/docs-sidebar.tsx | 66 - apps/shipyard/components/docs-toc.tsx | 74 - apps/shipyard/components/docs/callout.tsx | 53 - apps/shipyard/components/docs/cards.tsx | 51 - apps/shipyard/components/docs/diagram.css | 339 ----- apps/shipyard/components/docs/diagram.tsx | 183 --- apps/shipyard/components/docs/scenes.css | 439 ------ apps/shipyard/components/docs/scenes.tsx | 969 ------------- apps/shipyard/components/docs/shot.tsx | 53 - apps/shipyard/components/docs/stage.tsx | 26 - apps/shipyard/components/landing/runtime.tsx | 105 -- apps/shipyard/components/main-nav.tsx | 38 - apps/shipyard/components/mobile-nav.tsx | 128 -- apps/shipyard/components/site-footer.tsx | 38 - apps/shipyard/components/site-header.tsx | 33 - .../content/docs/(root)/changelog.mdx | 1277 ----------------- apps/shipyard/content/docs/(root)/index.mdx | 79 - apps/shipyard/content/docs/(root)/meta.json | 4 - .../content/docs/concepts/architecture.mdx | 109 -- apps/shipyard/content/docs/concepts/boxes.mdx | 125 -- .../content/docs/concepts/laptop-agent.mdx | 236 --- apps/shipyard/content/docs/concepts/meta.json | 11 - .../docs/concepts/projects-and-worktrees.mdx | 164 --- .../content/docs/concepts/security.mdx | 422 ------ .../docs/concepts/sessions-and-agents.mdx | 239 --- .../content/docs/contributing/meta.json | 1 - .../content/docs/contributing/releasing.mdx | 198 --- .../docs/getting-started/add-a-box.mdx | 513 ------- .../docs/getting-started/first-agent.mdx | 146 -- .../docs/getting-started/first-project.mdx | 101 -- .../content/docs/getting-started/install.mdx | 326 ----- .../content/docs/getting-started/meta.json | 4 - .../content/docs/guides/agent-browser.mdx | 323 ----- .../docs/guides/agent-integrations.mdx | 177 --- .../content/docs/guides/artifacts.mdx | 139 -- .../content/docs/guides/automations.mdx | 350 ----- apps/shipyard/content/docs/guides/browser.mdx | 167 --- apps/shipyard/content/docs/guides/files.mdx | 175 --- apps/shipyard/content/docs/guides/home.mdx | 84 -- apps/shipyard/content/docs/guides/hooks.mdx | 136 -- apps/shipyard/content/docs/guides/kits.mdx | 287 ---- apps/shipyard/content/docs/guides/labs.mdx | 341 ----- .../shipyard/content/docs/guides/leadline.mdx | 159 -- apps/shipyard/content/docs/guides/linear.mdx | 88 -- apps/shipyard/content/docs/guides/meta.json | 32 - .../content/docs/guides/more-computers.mdx | 89 -- .../content/docs/guides/offline-queue.mdx | 78 - .../content/docs/guides/orchestration.mdx | 288 ---- apps/shipyard/content/docs/guides/phone.mdx | 105 -- apps/shipyard/content/docs/guides/plugins.mdx | 591 -------- .../content/docs/guides/project-config.mdx | 223 --- .../content/docs/guides/resource-guard.mdx | 50 - .../content/docs/guides/review-a-pr.mdx | 238 --- apps/shipyard/content/docs/guides/runs.mdx | 221 --- apps/shipyard/content/docs/guides/secrets.mdx | 88 -- .../content/docs/guides/task-templates.mdx | 44 - .../content/docs/guides/team-setup.mdx | 545 ------- .../content/docs/guides/terminals.mdx | 60 - apps/shipyard/content/docs/guides/themes.mdx | 141 -- .../content/docs/guides/visual-diffs.mdx | 198 --- apps/shipyard/content/docs/meta.json | 11 - .../content/docs/reference/app-api.mdx | 271 ---- .../content/docs/reference/berthd.mdx | 188 --- apps/shipyard/content/docs/reference/cli.mdx | 220 --- .../content/docs/reference/config.mdx | 236 --- .../content/docs/reference/events.mdx | 255 ---- .../shipyard/content/docs/reference/files.mdx | 151 -- .../shipyard/content/docs/reference/meta.json | 12 - .../content/docs/reference/plugin-sdk.mdx | 350 ----- apps/shipyard/fonts/LICENSE-inter.txt | 93 -- .../shipyard/fonts/LICENSE-jetbrains-mono.txt | 93 -- apps/shipyard/fonts/inter-latin-wght.woff2 | Bin 48256 -> 0 bytes .../fonts/jetbrains-mono-latin-wght.woff2 | Bin 40404 -> 0 bytes apps/shipyard/hooks/use-is-mac.ts | 11 - apps/shipyard/lib/config.ts | 34 - apps/shipyard/lib/docs.ts | 3 - apps/shipyard/lib/fonts.ts | 17 - apps/shipyard/lib/rehype-nowrap-tokens.ts | 50 - apps/shipyard/lib/rehype-reference.ts | 227 --- apps/shipyard/lib/shots.json | 38 - apps/shipyard/lib/source.ts | 7 - apps/shipyard/lib/utils.ts | 6 - apps/shipyard/mdx-components.tsx | 279 ---- apps/shipyard/next.config.ts | 19 - apps/shipyard/package.json | 43 - apps/shipyard/postcss.config.mjs | 3 - apps/shipyard/public/assets/clips.js | 191 --- .../public/assets/film/hero-loop-poster.webp | Bin 146062 -> 0 bytes .../shipyard/public/assets/film/hero-loop.mp4 | Bin 1196962 -> 0 bytes .../public/assets/film/hero-loop.webm | Bin 1366789 -> 0 bytes apps/shipyard/public/assets/film/poster.webp | Bin 180200 -> 0 bytes apps/shipyard/public/assets/harbour.js | 201 --- apps/shipyard/public/assets/harbour/day.webp | Bin 114304 -> 0 bytes .../shipyard/public/assets/harbour/night.webp | Bin 164082 -> 0 bytes apps/shipyard/public/assets/hero-loop.js | 232 --- .../public/assets/loops/artifacts.mp4 | Bin 173364 -> 0 bytes .../public/assets/loops/artifacts.webp | Bin 60478 -> 0 bytes apps/shipyard/public/assets/loops/ask.mp4 | Bin 199515 -> 0 bytes apps/shipyard/public/assets/loops/ask.webp | Bin 42078 -> 0 bytes apps/shipyard/public/assets/loops/compare.mp4 | Bin 495412 -> 0 bytes .../shipyard/public/assets/loops/compare.webp | Bin 75400 -> 0 bytes apps/shipyard/public/assets/loops/groups.mp4 | Bin 325303 -> 0 bytes apps/shipyard/public/assets/loops/groups.webp | Bin 47692 -> 0 bytes apps/shipyard/public/assets/loops/start.mp4 | Bin 577628 -> 0 bytes apps/shipyard/public/assets/loops/start.webp | Bin 150508 -> 0 bytes apps/shipyard/public/assets/loops/steps.mp4 | Bin 237347 -> 0 bytes apps/shipyard/public/assets/loops/steps.webp | Bin 62136 -> 0 bytes apps/shipyard/public/assets/loops/themes.mp4 | Bin 710971 -> 0 bytes apps/shipyard/public/assets/loops/themes.webp | Bin 63422 -> 0 bytes apps/shipyard/public/assets/scenes.css | 555 ------- apps/shipyard/public/assets/scenes.json | 8 - apps/shipyard/public/assets/seam.svg | 1 - .../public/shots/agent-browser-dark.webp | Bin 18478 -> 0 bytes .../public/shots/agent-browser-light.webp | Bin 19006 -> 0 bytes .../public/shots/browser-sandbox-dark.webp | Bin 43192 -> 0 bytes .../public/shots/browser-sandbox-light.webp | Bin 46616 -> 0 bytes .../public/shots/chat-artifacts-dark.webp | Bin 101722 -> 0 bytes .../public/shots/chat-artifacts-light.webp | Bin 112952 -> 0 bytes .../public/shots/chat-background-dark.webp | Bin 48662 -> 0 bytes .../public/shots/chat-background-light.webp | Bin 58378 -> 0 bytes .../public/shots/chat-question-dark.webp | Bin 61276 -> 0 bytes .../public/shots/chat-question-light.webp | Bin 66134 -> 0 bytes apps/shipyard/public/shots/kits-dark.webp | Bin 33150 -> 0 bytes apps/shipyard/public/shots/kits-light.webp | Bin 36990 -> 0 bytes .../public/shots/service-terminal-dark.webp | Bin 65514 -> 0 bytes .../public/shots/service-terminal-light.webp | Bin 68176 -> 0 bytes .../public/shots/tab-groups-dark.webp | Bin 85464 -> 0 bytes .../public/shots/tab-groups-light.webp | Bin 91792 -> 0 bytes apps/shipyard/public/shots/themes-dark.webp | Bin 64936 -> 0 bytes apps/shipyard/public/shots/themes-light.webp | Bin 68518 -> 0 bytes apps/shipyard/source.config.ts | 40 - apps/shipyard/tsconfig.json | 21 - biome.json | 1 - bun.lock | 33 - packages/ui/src/shared/github-link.tsx | 2 +- 153 files changed, 1 insertion(+), 18035 deletions(-) delete mode 100644 apps/shipyard/.gitignore delete mode 100644 apps/shipyard/README.md delete mode 100644 apps/shipyard/app/api/raw/[...slug]/route.ts delete mode 100644 apps/shipyard/app/apple-icon.png delete mode 100644 apps/shipyard/app/docs.css delete mode 100644 apps/shipyard/app/docs/[[...slug]]/page.tsx delete mode 100644 apps/shipyard/app/docs/layout.tsx delete mode 100644 apps/shipyard/app/globals.css delete mode 100644 apps/shipyard/app/icon.svg delete mode 100644 apps/shipyard/app/landing.css delete mode 100644 apps/shipyard/app/layout.tsx delete mode 100644 apps/shipyard/app/not-found.tsx delete mode 100644 apps/shipyard/app/opengraph-image.jpg delete mode 100644 apps/shipyard/app/page.tsx delete mode 100644 apps/shipyard/app/sitemap.ts delete mode 100644 apps/shipyard/app/twitter-image.jpg delete mode 100644 apps/shipyard/components/command-menu.tsx delete mode 100644 apps/shipyard/components/docs-copy-page.tsx delete mode 100644 apps/shipyard/components/docs-sidebar.tsx delete mode 100644 apps/shipyard/components/docs-toc.tsx delete mode 100644 apps/shipyard/components/docs/callout.tsx delete mode 100644 apps/shipyard/components/docs/cards.tsx delete mode 100644 apps/shipyard/components/docs/diagram.css delete mode 100644 apps/shipyard/components/docs/diagram.tsx delete mode 100644 apps/shipyard/components/docs/scenes.css delete mode 100644 apps/shipyard/components/docs/scenes.tsx delete mode 100644 apps/shipyard/components/docs/shot.tsx delete mode 100644 apps/shipyard/components/docs/stage.tsx delete mode 100644 apps/shipyard/components/landing/runtime.tsx delete mode 100644 apps/shipyard/components/main-nav.tsx delete mode 100644 apps/shipyard/components/mobile-nav.tsx delete mode 100644 apps/shipyard/components/site-footer.tsx delete mode 100644 apps/shipyard/components/site-header.tsx delete mode 100644 apps/shipyard/content/docs/(root)/changelog.mdx delete mode 100644 apps/shipyard/content/docs/(root)/index.mdx delete mode 100644 apps/shipyard/content/docs/(root)/meta.json delete mode 100644 apps/shipyard/content/docs/concepts/architecture.mdx delete mode 100644 apps/shipyard/content/docs/concepts/boxes.mdx delete mode 100644 apps/shipyard/content/docs/concepts/laptop-agent.mdx delete mode 100644 apps/shipyard/content/docs/concepts/meta.json delete mode 100644 apps/shipyard/content/docs/concepts/projects-and-worktrees.mdx delete mode 100644 apps/shipyard/content/docs/concepts/security.mdx delete mode 100644 apps/shipyard/content/docs/concepts/sessions-and-agents.mdx delete mode 100644 apps/shipyard/content/docs/contributing/meta.json delete mode 100644 apps/shipyard/content/docs/contributing/releasing.mdx delete mode 100644 apps/shipyard/content/docs/getting-started/add-a-box.mdx delete mode 100644 apps/shipyard/content/docs/getting-started/first-agent.mdx delete mode 100644 apps/shipyard/content/docs/getting-started/first-project.mdx delete mode 100644 apps/shipyard/content/docs/getting-started/install.mdx delete mode 100644 apps/shipyard/content/docs/getting-started/meta.json delete mode 100644 apps/shipyard/content/docs/guides/agent-browser.mdx delete mode 100644 apps/shipyard/content/docs/guides/agent-integrations.mdx delete mode 100644 apps/shipyard/content/docs/guides/artifacts.mdx delete mode 100644 apps/shipyard/content/docs/guides/automations.mdx delete mode 100644 apps/shipyard/content/docs/guides/browser.mdx delete mode 100644 apps/shipyard/content/docs/guides/files.mdx delete mode 100644 apps/shipyard/content/docs/guides/home.mdx delete mode 100644 apps/shipyard/content/docs/guides/hooks.mdx delete mode 100644 apps/shipyard/content/docs/guides/kits.mdx delete mode 100644 apps/shipyard/content/docs/guides/labs.mdx delete mode 100644 apps/shipyard/content/docs/guides/leadline.mdx delete mode 100644 apps/shipyard/content/docs/guides/linear.mdx delete mode 100644 apps/shipyard/content/docs/guides/meta.json delete mode 100644 apps/shipyard/content/docs/guides/more-computers.mdx delete mode 100644 apps/shipyard/content/docs/guides/offline-queue.mdx delete mode 100644 apps/shipyard/content/docs/guides/orchestration.mdx delete mode 100644 apps/shipyard/content/docs/guides/phone.mdx delete mode 100644 apps/shipyard/content/docs/guides/plugins.mdx delete mode 100644 apps/shipyard/content/docs/guides/project-config.mdx delete mode 100644 apps/shipyard/content/docs/guides/resource-guard.mdx delete mode 100644 apps/shipyard/content/docs/guides/review-a-pr.mdx delete mode 100644 apps/shipyard/content/docs/guides/runs.mdx delete mode 100644 apps/shipyard/content/docs/guides/secrets.mdx delete mode 100644 apps/shipyard/content/docs/guides/task-templates.mdx delete mode 100644 apps/shipyard/content/docs/guides/team-setup.mdx delete mode 100644 apps/shipyard/content/docs/guides/terminals.mdx delete mode 100644 apps/shipyard/content/docs/guides/themes.mdx delete mode 100644 apps/shipyard/content/docs/guides/visual-diffs.mdx delete mode 100644 apps/shipyard/content/docs/meta.json delete mode 100644 apps/shipyard/content/docs/reference/app-api.mdx delete mode 100644 apps/shipyard/content/docs/reference/berthd.mdx delete mode 100644 apps/shipyard/content/docs/reference/cli.mdx delete mode 100644 apps/shipyard/content/docs/reference/config.mdx delete mode 100644 apps/shipyard/content/docs/reference/events.mdx delete mode 100644 apps/shipyard/content/docs/reference/files.mdx delete mode 100644 apps/shipyard/content/docs/reference/meta.json delete mode 100644 apps/shipyard/content/docs/reference/plugin-sdk.mdx delete mode 100644 apps/shipyard/fonts/LICENSE-inter.txt delete mode 100644 apps/shipyard/fonts/LICENSE-jetbrains-mono.txt delete mode 100644 apps/shipyard/fonts/inter-latin-wght.woff2 delete mode 100644 apps/shipyard/fonts/jetbrains-mono-latin-wght.woff2 delete mode 100644 apps/shipyard/hooks/use-is-mac.ts delete mode 100644 apps/shipyard/lib/config.ts delete mode 100644 apps/shipyard/lib/docs.ts delete mode 100644 apps/shipyard/lib/fonts.ts delete mode 100644 apps/shipyard/lib/rehype-nowrap-tokens.ts delete mode 100644 apps/shipyard/lib/rehype-reference.ts delete mode 100644 apps/shipyard/lib/shots.json delete mode 100644 apps/shipyard/lib/source.ts delete mode 100644 apps/shipyard/lib/utils.ts delete mode 100644 apps/shipyard/mdx-components.tsx delete mode 100644 apps/shipyard/next.config.ts delete mode 100644 apps/shipyard/package.json delete mode 100644 apps/shipyard/postcss.config.mjs delete mode 100644 apps/shipyard/public/assets/clips.js delete mode 100644 apps/shipyard/public/assets/film/hero-loop-poster.webp delete mode 100644 apps/shipyard/public/assets/film/hero-loop.mp4 delete mode 100644 apps/shipyard/public/assets/film/hero-loop.webm delete mode 100644 apps/shipyard/public/assets/film/poster.webp delete mode 100644 apps/shipyard/public/assets/harbour.js delete mode 100644 apps/shipyard/public/assets/harbour/day.webp delete mode 100644 apps/shipyard/public/assets/harbour/night.webp delete mode 100644 apps/shipyard/public/assets/hero-loop.js delete mode 100644 apps/shipyard/public/assets/loops/artifacts.mp4 delete mode 100644 apps/shipyard/public/assets/loops/artifacts.webp delete mode 100644 apps/shipyard/public/assets/loops/ask.mp4 delete mode 100644 apps/shipyard/public/assets/loops/ask.webp delete mode 100644 apps/shipyard/public/assets/loops/compare.mp4 delete mode 100644 apps/shipyard/public/assets/loops/compare.webp delete mode 100644 apps/shipyard/public/assets/loops/groups.mp4 delete mode 100644 apps/shipyard/public/assets/loops/groups.webp delete mode 100644 apps/shipyard/public/assets/loops/start.mp4 delete mode 100644 apps/shipyard/public/assets/loops/start.webp delete mode 100644 apps/shipyard/public/assets/loops/steps.mp4 delete mode 100644 apps/shipyard/public/assets/loops/steps.webp delete mode 100644 apps/shipyard/public/assets/loops/themes.mp4 delete mode 100644 apps/shipyard/public/assets/loops/themes.webp delete mode 100644 apps/shipyard/public/assets/scenes.css delete mode 100644 apps/shipyard/public/assets/scenes.json delete mode 100644 apps/shipyard/public/assets/seam.svg delete mode 100644 apps/shipyard/public/shots/agent-browser-dark.webp delete mode 100644 apps/shipyard/public/shots/agent-browser-light.webp delete mode 100644 apps/shipyard/public/shots/browser-sandbox-dark.webp delete mode 100644 apps/shipyard/public/shots/browser-sandbox-light.webp delete mode 100644 apps/shipyard/public/shots/chat-artifacts-dark.webp delete mode 100644 apps/shipyard/public/shots/chat-artifacts-light.webp delete mode 100644 apps/shipyard/public/shots/chat-background-dark.webp delete mode 100644 apps/shipyard/public/shots/chat-background-light.webp delete mode 100644 apps/shipyard/public/shots/chat-question-dark.webp delete mode 100644 apps/shipyard/public/shots/chat-question-light.webp delete mode 100644 apps/shipyard/public/shots/kits-dark.webp delete mode 100644 apps/shipyard/public/shots/kits-light.webp delete mode 100644 apps/shipyard/public/shots/service-terminal-dark.webp delete mode 100644 apps/shipyard/public/shots/service-terminal-light.webp delete mode 100644 apps/shipyard/public/shots/tab-groups-dark.webp delete mode 100644 apps/shipyard/public/shots/tab-groups-light.webp delete mode 100644 apps/shipyard/public/shots/themes-dark.webp delete mode 100644 apps/shipyard/public/shots/themes-light.webp delete mode 100644 apps/shipyard/source.config.ts delete mode 100644 apps/shipyard/tsconfig.json diff --git a/apps/shipyard/.gitignore b/apps/shipyard/.gitignore deleted file mode 100644 index cccfd3167..000000000 --- a/apps/shipyard/.gitignore +++ /dev/null @@ -1,44 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.* -.yarn/* -!.yarn/patches -!.yarn/plugins -!.yarn/releases -!.yarn/versions - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* -.pnpm-debug.log* - -# env files (can opt-in for committing if needed) -.env* - -# vercel -.vercel - -# typescript -*.tsbuildinfo -next-env.d.ts - -# fumadocs -.source \ No newline at end of file diff --git a/apps/shipyard/README.md b/apps/shipyard/README.md deleted file mode 100644 index 723879805..000000000 --- a/apps/shipyard/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# shipyard - -Shipyard's website and docs at [coss.com/shipyard](https://coss.com/shipyard): -the landing page, and the docs at `/shipyard/docs` on the same Fumadocs setup -as coss ui's. - -- `app/page.tsx`, `app/landing.css`: the landing page, as it was at - berthd.app. The harbour at the top is dithered on a canvas and comes alive - at night (`public/assets/harbour.js`, `hero-loop.js`); the chapters' loops - and line scenes load once the page has painted (`clips.js`, - `scenes.css`/`scenes.json`). `components/landing/runtime.tsx` brings them - in. The page keeps its own type (Inter, JetBrains Mono, in `fonts/`) and - tokens; the header, the rails and the docs are coss's. -- `content/docs/`: the docs, moved here from the `cosscom/shipyard` - repository's `docs/` folder. `components/docs/` are its own pieces - (callouts, the stage, the path of cards, screenshots in `public/shots/`, - diagrams and the line scenes); `lib/rehype-reference.ts` makes the - reference tables linkable. -- The app's downloads, the live demo (`berthd.app/demo/`), the box's - install line (`berthd.app/install`), the plugin listing and the - **Review in Shipyard** bounce page stay on berthd.app: they are built and - published from the `cosscom/shipyard` repository. - -```sh -bun install -bun run dev --filter=shipyard # http://localhost:4100/shipyard -``` diff --git a/apps/shipyard/app/api/raw/[...slug]/route.ts b/apps/shipyard/app/api/raw/[...slug]/route.ts deleted file mode 100644 index b2eb6fbaf..000000000 --- a/apps/shipyard/app/api/raw/[...slug]/route.ts +++ /dev/null @@ -1,50 +0,0 @@ -import fs from "node:fs/promises"; -import path from "node:path"; -import { type NextRequest, NextResponse } from "next/server"; - -export async function GET( - _request: NextRequest, - { params }: { params: Promise<{ slug: string[] }> }, -) { - const { slug } = await params; - - // Construct the file path from the slug - // If we have ['docs', 'filename'], look in (root) directory - let filePath: string; - if (slug.length === 2 && slug[0] === "docs") { - filePath = path.join( - process.cwd(), - "content", - "docs", - "(root)", - slug[1] || "", - ); - } else { - filePath = path.join(process.cwd(), "content", ...slug); - } - - // Check for both .mdx and .md extensions - const mdxPath = filePath.endsWith(".mdx") ? filePath : `${filePath}.mdx`; - const mdPath = filePath.endsWith(".md") ? filePath : `${filePath}.md`; - - try { - let content: string; - - // Try .mdx first, then .md - try { - content = await fs.readFile(mdxPath, "utf-8"); - } catch { - content = await fs.readFile(mdPath, "utf-8"); - } - - // Return raw markdown with appropriate headers - return new NextResponse(content, { - headers: { - "Cache-Control": "public, max-age=3600", - "Content-Type": "text/plain; charset=utf-8", - }, - }); - } catch { - return NextResponse.json({ error: "File not found" }, { status: 404 }); - } -} diff --git a/apps/shipyard/app/apple-icon.png b/apps/shipyard/app/apple-icon.png deleted file mode 100644 index 4402aaa8e6791330b4aab50aaf949bb2f26f1608..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5548 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 u;Ao5g00030|JyyS%K!iX21!IgR09A_C)va * { - margin: 0; -} -.berth-callout-text > * + * { - margin-top: 0.5em; -} -.berth-callout-text a { - color: var(--foreground); - text-decoration: underline; - text-decoration-color: color-mix(in srgb, var(--foreground) 35%, transparent); - text-underline-offset: 3px; -} -.berth-callout-text code { - font-size: 0.86em; - padding: 0.1em 0.32em; - border-radius: 5px; - background: var(--berth-code-bg); - border: 1px solid var(--berth-border-soft); - color: var(--foreground); - overflow-wrap: anywhere; -} -.berth-stage { - display: grid; - grid-template-columns: minmax(0, 1fr) auto; - align-items: center; - gap: 8px 24px; - margin: 8px 0 36px; - padding: 20px 20px 18px 22px; - border: 1px solid var(--border); - border-radius: 14px; - background: var(--card); -} -.berth-stage-title { - margin: 0 0 10px; - font-size: 14px; - font-weight: 600; - color: var(--foreground); -} -.berth-stage-text { - font-size: 0.9375rem; - line-height: 1.6; -} -.berth-stage-text > :first-child { - margin-top: 0; -} -.berth-stage-text > :last-child { - margin-bottom: 0; -} -.berth-stage-text figure.shiki { - margin: 0 0 12px; - background: var(--background) !important; -} -.berth-stage-art { - align-self: end; - margin: 0 -6px -6px 0; -} -@media (max-width: 720px) { - .berth-stage { - grid-template-columns: minmax(0, 1fr); - padding: 16px; - } - .berth-stage-art { - order: -1; - justify-self: start; - margin: -4px 0 0 -10px; - } - .berth-stage-art svg { - width: 184px; - height: auto; - } -} -.berth-path { - counter-reset: berth-step; -} -.berth-path a[data-card] { - counter-increment: berth-step; - position: relative; - padding-left: 52px; -} -.berth-path a[data-card]::before { - content: counter(berth-step); - position: absolute; - left: 16px; - top: 15px; - display: grid; - place-items: center; - width: 22px; - height: 22px; - border-radius: 999px; - border: 1px solid var(--border); - background: var(--card); - font: 500 12px / 1 var(--font-mono); - color: var(--muted-foreground); -} -.berth-nw { - white-space: nowrap; -} -.berth-path a[data-card]::before { - top: 15px; -} -.berth-stage-text a { - color: var(--foreground); - font-weight: 500; - text-decoration: underline; - text-decoration-color: color-mix(in srgb, var(--foreground) 35%, transparent); - text-underline-offset: 3px; -} -.berth-stage-text :not(pre) > code { - font-size: 0.86em; - padding: 0.1em 0.34em; - border-radius: 5px; - background: var(--background); - border: 1px solid var(--berth-border-soft); - color: var(--foreground); -} -.berth-stage-text p { - color: var(--berth-fg-2); -} -.berth-stage-text figure.shiki { - --berth-code-ground: var(--background); -} -dl.berth-ref { - margin: 1.25rem 0 1.75rem; - border: 1px solid var(--border); - border-radius: 12px; -} -.berth-ref-item { - position: relative; - padding: 11px 40px 12px 16px; - scroll-margin-top: 7rem; - transition: background-color 0.15s; -} -.berth-ref-item + .berth-ref-item { - border-top: 1px solid var(--berth-border-soft); -} -.berth-ref-item:first-child { - border-radius: 11px 11px 0 0; -} -.berth-ref-item:last-child { - border-radius: 0 0 11px 11px; -} -.berth-ref-item:only-child { - border-radius: 11px; -} -.berth-ref-sig { - margin: 0; - font-weight: 400; - line-height: 1.55; -} -.berth-ref-sig code { - padding: 0; - border: 0; - background: none; - font-size: 13.5px; - font-weight: 500; - color: var(--foreground); -} -.berth-ref-desc { - margin: 3px 0 0; - padding: 0; - font-size: 0.875rem; - line-height: 1.6; - color: var(--berth-fg-2); -} -.berth-ref-desc > :first-child { - margin-top: 0; -} -a.berth-ref-anchor { - position: absolute; - top: 10px; - right: 10px; - display: grid; - place-items: center; - width: 24px; - height: 24px; - border-radius: 6px; - font: 500 13px / 1 var(--font-mono); - color: var(--muted-foreground); - text-decoration: none; - opacity: 0; - transition: - opacity 0.15s, - background-color 0.15s, - color 0.15s; -} -.berth-ref-item:hover a.berth-ref-anchor, -a.berth-ref-anchor:focus-visible, -.berth-ref-item:target a.berth-ref-anchor { - opacity: 1; -} -a.berth-ref-anchor:hover { - color: var(--foreground); - background: var(--accent); -} -@media (hover: none) { - a.berth-ref-anchor { - opacity: 0.6; - } -} -.berth-ref-item:target, -table.berth-fields tr:target > td { - background: var(--accent); -} -table.berth-fields tr { - scroll-margin-top: 7rem; -} -a.berth-field-link { - text-decoration: none; - font-weight: inherit; -} -a.berth-field-link:hover code { - text-decoration: underline; - text-decoration-color: color-mix(in srgb, var(--foreground) 40%, transparent); - text-underline-offset: 3px; -} -#nd-page .berth-stage-text figure.shiki pre { - width: auto; - min-width: 0; - padding-right: 0; - white-space: pre-wrap; -} -#nd-page .berth-stage-text figure.shiki .line { - white-space: pre-wrap; - overflow-wrap: anywhere; - padding-left: calc(var(--padding-left) + 2ch); - text-indent: -2ch; -} -#nd-page .berth-stage-text figure.shiki .line > span { - display: inline-block; - max-width: 100%; - text-indent: 0; -} -#nd-page .berth-stage-text figure.shiki .line > span:only-child { - display: inline; -} -.berth-shot { - margin: 1.5rem 0 1.75rem; -} -.berth-shot img { - display: block; - width: 100%; - height: auto; - border: 1px solid var(--border); - border-radius: 12px; - background: var(--berth-code-bg); -} -.berth-shot-light, -.berth-shot-dark { - display: block; -} -.berth-shot-dark, -.dark .berth-shot-light { - display: none; -} -.dark .berth-shot-dark { - display: block; -} -.berth-shot-caption { - margin: 10px 2px 0; - max-width: 68ch; - font-size: 13.5px; - line-height: 1.55; - color: var(--muted-foreground); -} diff --git a/apps/shipyard/app/docs/[[...slug]]/page.tsx b/apps/shipyard/app/docs/[[...slug]]/page.tsx deleted file mode 100644 index 677b35f55..000000000 --- a/apps/shipyard/app/docs/[[...slug]]/page.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import { Card, CardFrame, CardPanel } from "@coss/ui/components/card"; -import { ScrollArea } from "@coss/ui/components/scroll-area"; -import { notFound } from "next/navigation"; -import { DocsCopyPage } from "@/components/docs-copy-page"; -import { DocsTableOfContents } from "@/components/docs-toc"; -import { SiteFooter } from "@/components/site-footer"; -import { source } from "@/lib/source"; -import { mdxComponents } from "@/mdx-components"; - -export const revalidate = false; -export const dynamic = "force-static"; -export const dynamicParams = false; - -export function generateStaticParams() { - return source.generateParams(); -} - -export async function generateMetadata(props: { - params: Promise<{ slug?: string[] }>; -}) { - const params = await props.params; - const page = source.getPage(params.slug); - - if (!page) { - notFound(); - } - - const doc = page.data; - - if (!doc.title || !doc.description) { - notFound(); - } - - return { - description: doc.description, - title: `${doc.title} - Shipyard docs`, - }; -} - -export default async function Page(props: { - params: Promise<{ slug?: string[] }>; -}) { - const params = await props.params; - const page = source.getPage(params.slug); - if (!page) { - notFound(); - } - - const doc = page.data; - const rawContent = await page.data.getText("raw"); - const MDX = doc.body; - - return ( -
-
- - - -
-
-
-
-

- {doc.title} -

- {doc.description && ( -

- {doc.description} -

- )} -
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
- -
-
- {doc.toc?.length ? : null} -
- -
-
- ); -} diff --git a/apps/shipyard/app/docs/layout.tsx b/apps/shipyard/app/docs/layout.tsx deleted file mode 100644 index 0da66e977..000000000 --- a/apps/shipyard/app/docs/layout.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { SidebarProvider } from "@coss/ui/components/sidebar"; -import { DocsSidebar } from "@/components/docs-sidebar"; -import { source } from "@/lib/source"; - -export default function DocsLayout({ - children, -}: { - children: React.ReactNode; -}) { - return ( -
- - -
{children}
-
-
- ); -} diff --git a/apps/shipyard/app/globals.css b/apps/shipyard/app/globals.css deleted file mode 100644 index a2ca26cce..000000000 --- a/apps/shipyard/app/globals.css +++ /dev/null @@ -1,12 +0,0 @@ -@import "@coss/ui/globals.css"; -@import "./landing.css"; -@import "./docs.css"; -@import "../components/docs/diagram.css"; -@import "../components/docs/scenes.css"; - -@layer base { - a:active, - button:active { - @apply opacity-72 md:opacity-100; - } -} diff --git a/apps/shipyard/app/icon.svg b/apps/shipyard/app/icon.svg deleted file mode 100644 index df2be7ab9..000000000 --- a/apps/shipyard/app/icon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/apps/shipyard/app/landing.css b/apps/shipyard/app/landing.css deleted file mode 100644 index 4d834ceeb..000000000 --- a/apps/shipyard/app/landing.css +++ /dev/null @@ -1,766 +0,0 @@ -/* Shipyard's landing page, as it was at berthd.app (the repository's - site/styles.css), scoped to .shipyard-landing under coss.com's layout and - header. Its own type (Inter, JetBrains Mono) and tokens (Shipyard Light - and Shipyard Dark, by the site's theme class) and coss-ui's buttons. The - harbour at the top is the only picture that isn't a screenshot. The few - url()s here are under the site's base path (next.config.ts). */ - -.shipyard-landing { - --bg: #ffffff; - --card: #ffffff; - --muted-bg: #f4f4f6; - --border: #e6e6ea; - --input: #dcdce1; - --fg: #26272b; - --fg-2: #45474e; - --muted: #62646d; - --primary: #26272b; - --primary-fg: #ffffff; - --amber: #c27a12; - --ring: #8b8d96; - --sea: #eef1f6; - --blue: #3b82f6; - --green: #16a34a; - --shadow: - 0 1px 2px rgb(20 22 30 / 0.04), 0 24px 60px -28px rgb(20 22 30 / 0.28); - --sans: - var(--font-inter), ui-sans-serif, system-ui, -apple-system, "Segoe UI", - sans-serif; - --mono: var(--font-jetbrains-mono), ui-monospace, "SF Mono", Menlo, monospace; - --band: clamp(340px, 58vh, 600px); - color-scheme: light; -} -/* Night: the system's dark mode, unless the page was put to day; or the - page put to night by "Close the laptop". */ -.dark .shipyard-landing { - /* coss.com's dark ground, so the page sits flush under its header. */ - --bg: #141414; - --card: #1f2024; - --muted-bg: #222327; - --border: #2c2d33; - --input: #34353c; - --fg: #e3e4e8; - --fg-2: #c0c2c9; - --muted: #9a9ca5; - --primary: #e3e4e8; - --primary-fg: #18191c; - --amber: #e8a33d; - --ring: #6b6d76; - --sea: #131824; - --green: #4ade80; - --shadow: 0 1px 2px rgb(0 0 0 / 0.3), 0 30px 80px -30px rgb(0 0 0 / 0.75); - color-scheme: dark; -} -.shipyard-landing { - position: relative; - margin: 0; - background: var(--bg); - color: var(--fg); - font: 15px / 1.6 var(--sans); - -webkit-font-smoothing: antialiased; - text-rendering: optimizeLegibility; -} -.shipyard-landing img, -.shipyard-landing svg, -.shipyard-landing canvas { - display: block; -} -.shipyard-landing a { - color: inherit; -} -.shipyard-landing :focus-visible { - outline: 2px solid var(--ring); - outline-offset: 2px; - border-radius: 6px; -} -.shipyard-landing h1, -.shipyard-landing h2 { - margin: 0; - font-weight: 600; - letter-spacing: -0.022em; - text-wrap: balance; -} -.shipyard-landing p { - margin: 0; -} -.shipyard-landing code { - font-family: var(--mono); -} -.shipyard-landing .wrap { - width: min(1040px, 100% - 32px); - margin-inline: auto; -} -/* coss-ui buttons: default (primary) and outline, size default. */ -.shipyard-landing .btn { - display: inline-flex; - align-items: center; - gap: 8px; - height: 36px; - padding: 0 14px; - border: 1px solid var(--input); - border-radius: 10px; - background: var(--card); - color: var(--fg); - font: 500 14px / 1 var(--sans); - text-decoration: none; - white-space: nowrap; - box-shadow: 0 1px 2px rgb(0 0 0 / 0.05); - transition: - background-color 0.15s, - border-color 0.15s; -} -.shipyard-landing .btn:hover { - background: var(--muted-bg); -} -.shipyard-landing .btn.primary { - border-color: var(--primary); - background: var(--primary); - color: var(--primary-fg); - box-shadow: - inset 0 1px rgb(255 255 255 / 0.16), - 0 1px 2px rgb(0 0 0 / 0.12); -} -.shipyard-landing .btn.primary:hover { - opacity: 0.9; -} -.shipyard-landing .btn svg { - width: 16px; - height: 16px; - margin-inline: -2px; -} -.shipyard-landing .actions { - display: flex; - flex-wrap: wrap; - justify-content: center; - gap: 8px; -} -.shipyard-landing .site-header-inner { - display: flex; - align-items: center; - gap: 8px; - height: 100%; - max-width: 1416px; - margin: 0 auto; - padding: 0 16px; -} -/* coss-ui's ghost button, size sm. */ -/* A hairline between the page's links and the repository's. */ -/* The theme toggle is an icon, as on coss.com; its wording is for readers. */ -@media (min-width: 640px) { - .shipyard-landing .site-header-inner { - padding: 0 24px; - } -} -.shipyard-landing .rule { - pointer-events: none; - max-width: 1416px; - margin: 0 auto; -} -.shipyard-landing .rule { - position: relative; - z-index: 7; - height: 0; - --mark-top: -3.5px; -} -.shipyard-landing .marks::before, -.shipyard-landing .marks::after { - content: ""; - position: absolute; - top: var(--mark-top); - width: 8px; - height: 8px; - border: 1px solid var(--border); - border-radius: 2px; - background: var(--bg); - box-shadow: 0 1px 2px rgb(0 0 0 / 0.05); -} -.shipyard-landing .marks::before { - left: -15.5px; -} -.shipyard-landing .marks::after { - right: -15.5px; -} -/* Narrower than the header's width plus the rails, they'd sit at the window's - edge or past it. */ -@media (max-width: 1441px) { - .shipyard-landing .marks::before, - .shipyard-landing .marks::after { - display: none; - } -} -.shipyard-landing .chapter.ruled { - position: relative; -} -.shipyard-landing .chapter.ruled::before { - content: ""; - position: absolute; - inset: 0 0 auto; - height: 1px; - background: color-mix(in srgb, var(--border) 64%, transparent); -} -/* Hero: the harbour band, then the pitch at its foot, where it dissolves. */ -.shipyard-landing .hero { - position: relative; - /* The whole page: the harbour and what's under it fill the window. */ - min-height: 100svh; - padding-bottom: 48px; -} -.shipyard-landing .harbour { - position: relative; - height: var(--band); - overflow: hidden; -} -.shipyard-landing .harbour picture, -.shipyard-landing .harbour img { - width: 100%; - height: 100%; -} -.shipyard-landing .harbour img { - object-fit: cover; - object-position: 50% 42%; - -webkit-mask-image: linear-gradient(black 50%, transparent); - mask-image: linear-gradient(black 50%, transparent); - transition: opacity 0.4s; -} -.shipyard-landing .harbour canvas { - position: absolute; - inset: 0; - image-rendering: pixelated; - opacity: 0; - transition: opacity 0.4s; -} -.shipyard-landing .harbour.drawn canvas { - opacity: 1; -} -.shipyard-landing .harbour.drawn img { - opacity: 0; -} -/* The loop, at night: over the drawn harbour in the same box (so nothing - moves), dissolving through the same dots (a mask from assets/hero-loop.js). - It brings its own beam, so the CSS one rests. */ -.shipyard-landing .loop { - position: absolute; - inset: 0; - opacity: 0; - transition: opacity 0.8s; - -webkit-mask: - var(--mask, linear-gradient(black 50%, transparent)) 0 0 / 100% 100% - no-repeat; - mask: - var(--mask, linear-gradient(black 50%, transparent)) 0 0 / 100% 100% - no-repeat; -} -/* The video itself is a pixel, under the canvas its frames are drawn on. */ -.shipyard-landing .loop video { - position: absolute; - top: 0; - left: 0; - width: 1px; - height: 1px; -} -.shipyard-landing .loop canvas { - position: absolute; - inset: 0; - width: 100%; - height: 100%; -} -.shipyard-landing .harbour.live .loop { - opacity: 1; -} -.shipyard-landing .harbour.live > canvas { - transition-delay: 0.8s; -} -.shipyard-landing .harbour.live > canvas, -.shipyard-landing .harbour.live .beam { - opacity: 0 !important; -} -.shipyard-landing .harbour .loop canvas { - opacity: 1; - image-rendering: auto; - transition: none; -} -.shipyard-landing .hero-copy { - position: relative; - width: min(720px, 100% - 32px); - margin: calc(var(--band) * -0.3) auto 0; - text-align: center; -} - -.shipyard-landing .hero h1 { - font-size: clamp(32px, 5.2vw, 54px); - line-height: 1.06; - text-shadow: - 0 0 10px var(--bg), - 0 0 24px var(--bg); -} -.shipyard-landing .lede { - max-width: 560px; - margin: 16px auto 24px; - color: var(--fg-2); - font-size: 17px; - text-shadow: 0 0 8px var(--bg); - text-wrap: balance; -} -.shipyard-landing .install { - display: flex; - align-items: center; - gap: 10px; - width: fit-content; - max-width: 100%; - margin: 18px auto 0; - padding: 4px 4px 4px 12px; - border: 1px solid var(--border); - border-radius: 12px; - background: var(--muted-bg); - text-align: left; -} -.shipyard-landing .install-label { - flex: none; - color: var(--muted); - font-size: 12px; -} -.shipyard-landing .install code { - overflow-x: auto; - font-size: 13px; - white-space: nowrap; - scrollbar-width: none; -} -.shipyard-landing .copy { - flex: none; - height: 28px; - padding: 0 10px; - border: 1px solid var(--input); - border-radius: 8px; - background: var(--card); - color: var(--fg); - font: 500 12.5px var(--sans); - cursor: pointer; -} -.shipyard-landing .copy:hover { - background: var(--bg); -} -.shipyard-landing .note { - margin-top: 14px; - color: var(--muted); - font-size: 13px; -} -.shipyard-landing .note a { - display: inline-flex; - align-items: center; - gap: 2px; - color: var(--fg-2); - font-weight: 500; - text-decoration: none; -} -.shipyard-landing .note a:hover { - color: var(--fg); -} -.shipyard-landing .note svg { - width: 13px; - height: 13px; -} -/* The Linux app is an alpha: a quiet line under the Mac download. */ -.shipyard-landing .note.linux-alpha { - margin-top: 4px; - font-size: 12px; -} -.shipyard-landing .note.linux-alpha a { - text-decoration: underline; - text-underline-offset: 2px; - text-decoration-color: var(--muted); -} -.shipyard-landing .kicker { - display: flex; - align-items: center; - gap: 10px; - color: var(--muted); - font: 500 13px / 1 var(--mono); -} -/* A segmented switch over several views. */ -.shipyard-landing .seg { - display: flex; - width: fit-content; - margin: 0 auto 18px; - padding: 3px; - border: 1px solid var(--border); - border-radius: 11px; - background: var(--muted-bg); -} -.shipyard-landing .seg button { - height: 30px; - padding: 0 14px; - border: 0; - border-radius: 8px; - background: transparent; - color: var(--muted); - font: 500 13.5px var(--sans); - cursor: pointer; -} -.shipyard-landing .seg button:hover { - color: var(--fg); -} -.shipyard-landing .seg button[aria-pressed="true"] { - background: var(--card); - color: var(--fg); - box-shadow: - 0 1px 2px rgb(0 0 0 / 0.08), - 0 0 0 1px var(--border); -} -.shipyard-landing .stack { - display: grid; -} -.shipyard-landing .stack > [aria-hidden="true"] { - opacity: 0; - visibility: hidden; - transition: - opacity 0.3s, - visibility 0s 0.3s; -} -.shipyard-landing .sr { - position: absolute; - width: 1px; - height: 1px; - overflow: hidden; - clip-path: inset(50%); - white-space: nowrap; -} -@media (max-width: 640px) { - .shipyard-landing { - --band: clamp(300px, 52vh, 420px); - } - .shipyard-landing .hero-copy { - margin-top: calc(var(--band) * -0.22); - } - .shipyard-landing .harbour img { - object-position: 8% 42%; - } - .shipyard-landing .lede { - font-size: 16px; - } - .shipyard-landing .install-label { - display: none; - } - /* The install section is a scroll away, and the width is for the brand. */ -} -@media (prefers-reduced-motion: reduce) { - .shipyard-landing .harbour canvas, - .shipyard-landing .harbour img { - transition: none; - } -} -/* The lighthouse's beam: a wedge of halftone dots from the lamp, sweeping - slowly. Only transform moves; it rests when the page is hidden and for - reduced motion. Brighter at night. */ -.shipyard-landing .beam { - position: absolute; - z-index: 1; - width: min(70vw, 900px); - height: 220px; - margin-top: -110px; - transform-origin: 0 50%; - background: linear-gradient( - to right, - rgb(255 236 190 / 0.9), - rgb(255 236 190 / 0.35) 40%, - transparent 85% - ); - clip-path: polygon(0 48%, 100% 0, 100% 100%, 0 52%); - -webkit-mask: - radial-gradient(circle at 1px 1px, #000 0.8px, transparent 1px) 0 0 / 3px - 3px; - mask: - radial-gradient(circle at 1px 1px, #000 0.8px, transparent 1px) 0 0 / 3px - 3px; - opacity: 0; - pointer-events: none; - animation: sweep 11s ease-in-out infinite alternate; - transition: opacity 0.8s; -} -.shipyard-landing .harbour.drawn .beam { - opacity: 0.32; -} -.dark .shipyard-landing .harbour.drawn .beam { - opacity: 0.85; -} -@keyframes sweep { - from { - transform: rotate(-14deg); - } - to { - transform: rotate(10deg); - } -} -.shipyard-landing[data-page-hidden] .beam { - animation-play-state: paused; -} -/* "Close the laptop": puts the page to night, and says what keeps going. */ -/* Until the script shows it, the switch keeps its place, so the header - never moves. */ -@keyframes pulse { - 50% { - opacity: 0.35; - } -} -@media (prefers-reduced-motion: reduce) { - .shipyard-landing .beam { - animation: none; - transform: rotate(-4deg); - } -} - -@keyframes film-in { - from { - opacity: 0; - transform: translateY(8px) scale(0.985); - } -} - -@media (prefers-reduced-motion: reduce) { - .shipyard-landing .loop, - .shipyard-landing .harbour.live > canvas { - transition: none; - } -} -/* Below the harbour: the film's story in six chapters. Each opens with one - of the app's line scenes (assets/scenes.css), its one amber light, then the - film's caption and a few words, and a short loop of the real app. */ -.shipyard-landing .chapter { - padding-top: clamp(72px, 10vw, 128px); -} -.shipyard-landing .chapter .wrap { - width: min(1120px, 100% - 32px); -} -/* The hero already fills the window; the first chapter follows closer. */ -.shipyard-landing #start { - padding-top: clamp(40px, 6vw, 72px); -} -.shipyard-landing .chapter-head { - display: grid; - grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); - gap: 14px 64px; - align-items: end; - margin-bottom: clamp(28px, 4vw, 40px); -} -.shipyard-landing .chapter-mark { - grid-column: 1 / -1; - display: flex; - align-items: center; - gap: 16px; - /* Room for what rises above the scene's box: a mast, a beam, a sun. */ - padding-top: 14px; - margin-bottom: 6px; -} -.shipyard-landing .chapter-mark.centered { - flex-direction: column; - gap: 10px; - margin-bottom: 18px; -} -/* A line scene's slot, its size kept until the drawing arrives. */ -.shipyard-landing .scene { - --muted-foreground: var(--muted); - --warning: var(--amber); - flex: none; - display: block; - width: 144px; - aspect-ratio: 160 / 52; -} -.shipyard-landing .scene.dawn { - width: 208px; -} -.shipyard-landing .scene svg { - width: 100%; - height: auto; -} -.shipyard-landing .chapter h2 { - font-size: clamp(30px, 4.2vw, 48px); - line-height: 1.05; -} -.shipyard-landing .chapter-head > p { - max-width: 470px; - color: var(--fg-2); - font-size: 16.5px; - text-wrap: pretty; -} -/* A loop: its poster sizes the frame; the video fades in over it once it - plays. The footage is the app in Shipyard Dark, so the frame is dark too. */ -.shipyard-landing .clip { - position: relative; - margin: 0; - overflow: hidden; - border: 1px solid var(--border); - border-radius: 14px; - background: #1d1e22; - box-shadow: var(--shadow); -} -.shipyard-landing .clip img { - width: 100%; - height: auto; -} -/* A poster not asked for yet keeps its frame, and shows no alt text. */ -.shipyard-landing .clip img[data-src] { - visibility: hidden; -} -.shipyard-landing .clip video { - position: absolute; - inset: 0; - width: 100%; - height: 100%; - object-fit: cover; - opacity: 0; - transition: opacity 0.4s; -} -.shipyard-landing .clip.playing video { - opacity: 1; -} -.shipyard-landing .views .seg { - margin-bottom: 16px; -} -.shipyard-landing .stack > .clip { - grid-area: 1 / 1; - transition: opacity 0.3s; -} -/* It keeps going: the night comes in through the harbour's dots, whatever - the theme, and goes out the same way. */ -.shipyard-landing .chapter.after-dark { - padding-top: clamp(56px, 7vw, 96px); -} -.shipyard-landing .night-in, -.shipyard-landing .night-out { - height: 64px; - background: #18191c; - -webkit-mask: url("/shipyard/assets/seam.svg") 0 0 / 16px 64px repeat-x; - mask: url("/shipyard/assets/seam.svg") 0 0 / 16px 64px repeat-x; -} -.shipyard-landing .night-out { - transform: scaleY(-1); -} -.shipyard-landing .night-body { - --bg: #18191c; - --card: #1f2024; - --muted-bg: #222327; - --border: #2c2d33; - --input: #34353c; - --fg: #e3e4e8; - --fg-2: #c0c2c9; - --muted: #9a9ca5; - --amber: #e8a33d; - --shadow: 0 1px 2px rgb(0 0 0 / 0.3), 0 30px 80px -30px rgb(0 0 0 / 0.75); - padding: clamp(40px, 6vw, 72px) 0 clamp(48px, 7vw, 88px); - background: var(--bg); - color: var(--fg); - color-scheme: dark; -} -.shipyard-landing .night-body .clip { - border-color: #2c2d33; -} -.shipyard-landing .boxes { - display: flex; - flex-wrap: wrap; - justify-content: center; - gap: 8px 10px; - margin-top: 18px; - color: var(--fg-2); - font: 500 12.5px / 1 var(--mono); -} -.shipyard-landing .boxes span { - display: inline-flex; - align-items: center; - gap: 8px; - padding: 7px 12px 7px 10px; - border: 1px solid var(--border); - border-radius: 999px; - background: var(--card); -} -.shipyard-landing .boxes i { - width: 7px; - height: 7px; - border-radius: 50%; - background: #4ade80; - box-shadow: 0 0 8px rgb(74 222 128 / 0.6); - animation: pulse 2.6s ease-in-out infinite; -} -.shipyard-landing .boxes span + span i { - animation-delay: -1.3s; -} -.shipyard-landing[data-page-hidden] .boxes i { - animation-play-state: paused; -} -/* Install: the end, at dawn. */ -.shipyard-landing .install-ch { - padding-bottom: clamp(88px, 11vw, 136px); - text-align: center; -} -.shipyard-landing .lede-2 { - max-width: 460px; - margin: 14px auto 26px; - color: var(--fg-2); - font-size: 17px; - text-wrap: balance; -} -.shipyard-landing .ends { - display: flex; - flex-wrap: wrap; - justify-content: center; - gap: 8px 24px; - margin-top: 26px; - font-size: 14.5px; -} -.shipyard-landing .ends a { - display: inline-flex; - align-items: center; - gap: 2px; - color: var(--fg-2); - font-weight: 500; - text-decoration: none; -} -.shipyard-landing .ends a:hover { - color: var(--fg); -} -.shipyard-landing .ends svg { - width: 14px; - height: 14px; -} -@media (max-width: 760px) { - .shipyard-landing .chapter-head { - grid-template-columns: 1fr; - gap: 12px; - } - .shipyard-landing .scene { - width: 120px; - } - .shipyard-landing .scene.dawn { - width: 168px; - } - /* On a phone, the frame closes in on the app's main pane. */ - .shipyard-landing .clip img, - .shipyard-landing .clip video { - aspect-ratio: 4 / 3; - height: auto; - object-fit: cover; - object-position: 64% 40%; - } - .shipyard-landing .clip video { - height: 100%; - } - .shipyard-landing .views .seg button { - padding: 0 10px; - font-size: 13px; - } -} -@media (prefers-reduced-motion: reduce) { - .shipyard-landing .boxes i { - animation: none; - } - .shipyard-landing .clip video, - .shipyard-landing .stack > .clip { - transition: none; - } -} -@media (max-width: 760px) { - .shipyard-landing .night-body .clip img, - .shipyard-landing .night-body .clip video { - object-position: 12% 50%; - } -} -/* A phone's header: the brand a touch smaller, and the links as icons - (styles for 640px and under, above). */ diff --git a/apps/shipyard/app/layout.tsx b/apps/shipyard/app/layout.tsx deleted file mode 100644 index d5c721fd0..000000000 --- a/apps/shipyard/app/layout.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import "./globals.css"; - -import { fontMono, fontSans } from "@coss/ui/fonts"; -import { ThemeProvider } from "@coss/ui/shared/theme-provider"; -import type { Metadata } from "next"; -import { SiteHeader } from "@/components/site-header"; -import { appConfig } from "@/lib/config"; -import { inter, jetbrainsMono } from "@/lib/fonts"; - -export const metadata: Metadata = { - description: appConfig.description, - metadataBase: new URL("https://coss.com"), - openGraph: { - description: appConfig.description, - siteName: "Shipyard", - title: "Shipyard - coding agents on your own boxes", - type: "website", - url: appConfig.url, - }, - title: { - default: "Shipyard - coding agents on your own boxes", - template: "%s - Shipyard", - }, -}; - -export default function RootLayout({ - children, -}: Readonly<{ - children: React.ReactNode; -}>) { - return ( - - - -
-