Compare commits

..

10 Commits

Author SHA1 Message Date
mido
ca44aa17b3 add wrangler
Co-authored-by: Copilot <copilot@github.com>
2026-05-04 17:19:09 -05:00
mido
ec3340f970 Use ICO favicon, update layout & add policy
copilot stop sneaking into my commits, i only used you to generate commit messages
2026-05-04 17:04:14 -05:00
mido
6d1b567a37 Enhance configuration and layout: add environment variables, improve metadata, and update content section keys for consistency
Co-authored-by: Copilot <copilot@github.com>
2026-05-04 16:51:18 -05:00
mido
d78d5107e2 Add in-game error documentation and enhance ContentTOC component 2026-05-04 16:00:55 -05:00
mido
11bab0b14b Add Dark Mode 2026-05-04 10:33:46 -05:00
mido
bcbb97040d Refactor code structure for improved readability and maintainability
Co-authored-by: Copilot <copilot@github.com>
2026-05-04 10:30:44 -05:00
mido
55c19578aa Implement styling, easier config 2026-05-01 10:39:41 -05:00
mido
a8186111ac Implement breadcrum navigation 2026-04-15 11:34:53 -05:00
mido
549f131ffd Add documentation on how to add content 2026-04-15 11:29:36 -05:00
mido
56ea450e7b Add TOC and Layout components; update pages 2026-04-15 11:23:10 -05:00
30 changed files with 1699 additions and 183 deletions

1
.gitignore vendored
View File

@@ -22,3 +22,4 @@ pnpm-debug.log*
# jetbrains setting folder # jetbrains setting folder
.idea/ .idea/
.wrangler/

143
README.md
View File

@@ -1,43 +1,134 @@
# Astro Starter Kit: Minimal # radie-help
Content-driven help site built with Astro and MDX.
## Requirements
- `node >= 22.12.0`
- `npm`
## Basic Setup
1. Install dependencies:
```sh ```sh
npm create astro@latest -- --template minimal npm install
``` ```
> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! 2. Start the local dev server:
## 🚀 Project Structure ```sh
npm run dev
```
Inside of your Astro project, you'll see the following folders and files: 3. Open `http://localhost:4321`.
## Available Commands
| Command | What it does |
| --- | --- |
| `npm run dev` | Start the local Astro dev server |
| `npm run build` | Build the site for production |
| `npm run preview` | Preview the production build locally |
## How Content Works
- Each top-level folder inside `src/content/` is a content section.
- The current site includes sections for `src/content/website/` and `src/content/avatar-items/`.
- Files in a section can be `.md` or `.mdx`.
- Each content file must include frontmatter with:
```md
---
title: Page Title
description: Short summary
---
```
- `index.mdx` becomes the landing page for that section.
Example: `src/content/website/index.mdx` maps to `/website`
- Any other file becomes a subpage under that section.
Example: `src/content/website/registration.mdx` maps to `/website/registration`
## Adding A New Content Subpage
To add a new page inside an existing section:
1. Create a new `.md` or `.mdx` file in the relevant folder under `src/content/`.
2. Add the required frontmatter:
```md
---
title: New Page
description: What this page covers
---
```
3. Add the page body content.
Example:
```text ```text
/ src/content/website/account-recovery.mdx
├── public/
├── src/
│ └── pages/
│ └── index.astro
└── package.json
``` ```
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name. This page will be available at:
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components. ```text
/website/account-recovery
```
Any static assets, like images, can be placed in the `public/` directory. ## Adding A New Content Section
## 🧞 Commands If you want a new group of subpages, create a new folder in `src/content/` and then register it once in `src/config/content.ts`.
All commands are run from the root of the project, from a terminal: ### 1. Create the folder and files
| Command | Action | Example:
| :------------------------ | :----------------------------------------------- |
| `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:4321` |
| `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more? ```text
src/content/mobile-app/
├── index.mdx
└── notifications.mdx
```
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat). `index.mdx` should describe the section landing page. Any additional files become subpages for that section.
### 2. Update `src/config/content.ts`
Add a new entry to `contentSections`:
```ts
export const contentSections = {
website: {
dir: "website",
},
avatarItems: {
dir: "avatar-items",
},
mobileApp: {
dir: "mobile-app",
},
};
```
The object key is the section route and Astro collection name. The `dir` value is the folder under `src/content/`.
### 3. Run the site locally
```sh
npm run dev
```
Verify that:
- the new section appears on the home page
- the section index page loads
- the new subpages resolve under the expected URL path
## Contributor Notes
- Keep one topic per file.
- Use `index.mdx` only for a section landing page.
- Prefer lowercase, hyphenated filenames for clean URLs.
- If you create a new top-level content folder, register it in `src/config/content.ts`. `src/content.config.ts`, navigation, and routing derive from that registry.

View File

@@ -1,12 +1,16 @@
// @ts-check // @ts-check
import { defineConfig } from 'astro/config'; import { defineConfig } from 'astro/config';
import tailwindcss from '@tailwindcss/vite'; import tailwindcss from '@tailwindcss/vite';
import { loadEnv } from 'vite';
import mdx from '@astrojs/mdx'; import mdx from '@astrojs/mdx';
const env = loadEnv(process.env.NODE_ENV ?? 'development', process.cwd(), 'PUBLIC_');
// https://astro.build/config // https://astro.build/config
export default defineConfig({ export default defineConfig({
site: env.PUBLIC_SITE_URL,
vite: { vite: {
plugins: [tailwindcss()] plugins: [tailwindcss()]
}, },

1103
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -13,8 +13,13 @@
}, },
"dependencies": { "dependencies": {
"@astrojs/mdx": "^5.0.3", "@astrojs/mdx": "^5.0.3",
"@tailwindcss/vite": "^4.2.2", "@tailwindcss/vite": "^4.2.4",
"astro": "^6.1.5", "astro": "^6.1.5",
"tailwindcss": "^4.2.2" "tailwindcss": "^4.2.4"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.19",
"@types/node": "^25.6.0",
"wrangler": "^4.87.0"
} }
} }

BIN
public/branding/banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 KiB

BIN
public/branding/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 655 B

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -1,9 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
<style>
path { fill: #000; }
@media (prefers-color-scheme: dark) {
path { fill: #FFF; }
}
</style>
</svg>

Before

Width:  |  Height:  |  Size: 749 B

View File

@@ -0,0 +1,36 @@
---
import type { BreadcrumbItem } from "../lib/types/breadcrum";
const { items = [] } = Astro.props as { items?: BreadcrumbItem[] };
---
{
items.length > 0 && (
<nav
aria-label="Breadcrumb"
class="flex flex-wrap items-center gap-1.5 rounded text-[13px] leading-none text-muted md:px-3"
>
{items.map((item, index) => {
const isCurrent = index === items.length - 1;
return (
<>
{item.href && !isCurrent ? (
<a href={item.href} class="text-link hover:underline">
{item.label}
</a>
) : (
<span
aria-current={isCurrent ? "page" : undefined}
class={isCurrent ? "font-bold text-foreground" : undefined}
>
{item.label}
</span>
)}
{index < items.length - 1 && <span class="text-muted-soft">/</span>}
</>
);
})}
</nav>
)
}

View File

@@ -0,0 +1,26 @@
---
import { getCollection } from "astro:content";
import { isSiteCollection } from "../config/content";
const { sectionName } = Astro.props;
if (!sectionName || !isSiteCollection(sectionName)) {
throw new Error("ContentTOC requires a valid sectionName prop.");
}
const entries = (await getCollection(sectionName)).sort((a, b) =>
a.data.title.localeCompare(b.data.title),
);
const articles = entries.filter((entry) => entry.id !== "index");
---
<ul>
{articles.map((entry) => (
<li>
<a href={`/${sectionName}/${entry.id}`}>
{entry.data.title}
</a>
</li>
))}
</ul>

49
src/components/TOC.astro Normal file
View File

@@ -0,0 +1,49 @@
---
import { getCollection } from "astro:content";
import { collectionNames } from "../config/content";
const sections = await Promise.all(
collectionNames.map(async (name) => {
const entries = (await getCollection(name)).sort((a, b) =>
a.data.title.localeCompare(b.data.title),
);
const indexEntry = entries.find((entry) => entry.id === "index");
const articles = entries.filter((entry) => entry.id !== "index");
return {
name,
indexEntry,
articles,
};
}),
);
---
<ul class="prose-radium">
{
sections.map((section) => (
<li>
{section.indexEntry ? (
<a href={`/${section.name}`}>
{section.indexEntry.data.title}
</a>
) : (
section.name
)}
{section.articles.length > 0 && (
<ul>
{section.articles.map((entry) => (
<li>
<a href={`/${section.name}/${entry.id}`}>
{entry.data.title}
</a>
</li>
))}
</ul>
)}
</li>
))
}
</ul>

View File

@@ -1,6 +1,15 @@
export const collectionNames = ["website"] as const; export const contentSections = {
export type SiteCollection = (typeof collectionNames)[number]; "avatar-items": {
dir: "avatar-items",
},
"in-game-errors": {
dir: "in-game-errors",
},
} as const;
export type SiteCollection = keyof typeof contentSections;
export const collectionNames = Object.keys(contentSections) as SiteCollection[];
export function isSiteCollection(value: string): value is SiteCollection { export function isSiteCollection(value: string): value is SiteCollection {
return collectionNames.includes(value as SiteCollection); return value in contentSections;
} }

View File

@@ -1,17 +1,23 @@
import { defineCollection } from "astro/content/config"; import { defineCollection } from "astro/content/config";
import { glob } from "astro/loaders"; import { glob } from "astro/loaders";
import { z } from "astro/zod"; import { z } from "astro/zod";
import { contentSections, type SiteCollection } from "./config/content";
const articleSchema = z.object({ const articleSchema = z.object({
title: z.string(), title: z.string(),
description: z.string() description: z.string()
}); });
const website = defineCollection({ function createArticleCollection(dir: string) {
loader: glob({ base: './src/content/website', pattern: '**/*.{md,mdx}' }), return defineCollection({
schema: articleSchema loader: glob({ base: `./src/content/${dir}`, pattern: "**/*.{md,mdx}" }),
schema: articleSchema,
}); });
}
export const collections = { export const collections = Object.fromEntries(
website Object.entries(contentSections).map(([name, section]) => [
}; name,
createArticleCollection(section.dir),
]),
) as Record<SiteCollection, ReturnType<typeof createArticleCollection>>;

View File

@@ -0,0 +1,35 @@
---
title: Excluded Avatar Items
description: Avatar items that are excluded from being obtained in Radium.
---
# Excluded Avatar Items
The items listed here are excluded from being obtained in Radium and are not planned to return.
Items may be excluded for reasons such as unofficial access, licensed content restrictions, or internal moderation decisions.
## Availability Policy
Some items were only available for a limited time. If you did not obtain one of those items while it was available, we cannot credit, transfer, gift, or grant it later.
We also do not transfer items from Rec Room to Radium. Owning an item in Rec Room does not mean it will be granted to you in Radium.
Excluded or timed items are not given as rewards for bug bounty reports, security submissions, or similar reports.
Radium does not accept private offers, bribes, or special arrangements for these items.
## Excluded Items
* Licensed Fourth Fridays clothing
* Licensed RecRocks clothing
* NBA/NFL clothing
* Miraculous Ladybug
* Mattel items, including He-Man and Barbie
* Teenage Mutant Ninja Turtles
* Puma
* AJR
* Raw Data
* Destiny 2
* SFVRCC promo shirt
* Helix shirt

View File

@@ -0,0 +1,16 @@
---
title: Avatar Items
description: Learn how avatar items are handled in Radium.
---
import ContentTOC from '../../components/ContentTOC.astro';
# Avatar Items
Avatar items are wearable cosmetics and related inventory items that may appear in Radium. This section documents how specific item groups are handled, including items that are unavailable, restricted, or excluded from resurfacing.
Use the pages below to check the current status of avatar item categories.
## Pages
<ContentTOC sectionName="avatar-items" />

View File

@@ -0,0 +1,22 @@
---
title: Error Code 5
description: Error Code 5 usually means Radium is having trouble reaching one of its services.
---
# Error Code: 5
Error Code 5 usually means Radium is having trouble reaching one of its services. This is often temporary and may happen during high traffic, maintenance, or a partial service outage.
## Common Causes
* High traffic on Radium services
* Temporary server connectivity issues
* Scheduled maintenance
* A partial outage affecting one of Radium's backend services
## What To Try
1. Wait a few minutes, then try again.
2. Restart Radium.
3. Check whether other players are reporting the same issue.
4. If the error continues, try again later.

View File

@@ -0,0 +1,30 @@
---
title: Error Code C
description: Error Code C usually means Radium traffic may be blocked or filtered by your network provider.
---
# Error Code: C
Error Code C usually means Radium traffic may be blocked or filtered by your internet service provider, network, firewall, or DNS settings.
## Common Causes
* Your internet service provider blocking or filtering Radium traffic
* School, work, or public Wi-Fi restrictions
* DNS filtering
* Firewall or antivirus software blocking Radium
## Networks That May Be Affected
Players have reported this issue on some networks from:
* Comcast / Xfinity
* Rogers
* Spectrum
## What To Try
1. Restart Radium and try again.
2. Try a different network, such as a mobile hotspot.
3. Check whether firewall, antivirus, or parental control software is blocking Radium.
4. Try a trusted VPN or DNS service, such as [1.1.1.1](https://one.one.one.one/), if your network allows it.

View File

@@ -0,0 +1,23 @@
---
title: Error Code SUMMER
description: Error Code SUMMER means Radium could not connect to the required game services.
---
# Error Code: SUMMER
Error Code SUMMER means the game could not connect to Radium's servers. This can happen when certain Radium services are unavailable or when something on your network or device is blocking the connection.
## Common Causes
* Radium server outage or maintenance
* Unstable internet connection
* Firewall or antivirus software blocking Radium
* Network restrictions on school, work, or public Wi-Fi
## What To Try
1. Restart Radium.
2. Check that your internet connection is working normally.
3. Try a different network if one is available.
4. Temporarily check whether firewall or antivirus settings are blocking Radium.
5. Wait and try again later if other players are seeing the same error.

View File

@@ -0,0 +1,21 @@
---
title: HTTP 429
description: HTTP 429 means too many requests were sent to Radium in a short amount of time.
---
# Error Code: 429
HTTP 429 means too many requests were sent to Radium in a short amount of time. This can happen if you retry the same action repeatedly or if a client is reconnecting too quickly.
## Common Causes
* Repeatedly refreshing, reconnecting, or retrying the same action
* A temporary client loop sending requests too quickly
* Network instability causing repeated reconnect attempts
## What To Try
1. Stop retrying the action for a few minutes.
2. Restart Radium.
3. Make sure your network connection is stable.
4. Try again after the cooldown has had time to clear.

View File

@@ -0,0 +1,20 @@
---
title: HTTP 500
description: HTTP 500 means a Radium server encountered an unexpected problem.
---
# Error Code: 500
HTTP 500 means one of Radium's services encountered an unexpected problem while handling your request. This is usually a server-side issue, not something caused by your account or device.
## Common Causes
* A temporary Radium service issue
* Server maintenance or deployment work
* A request failing because one of Radium's backend services is unavailable
## What To Try
1. Wait a few minutes, then try again.
2. Restart Radium if the error keeps appearing.
3. Try the action again later if the issue appears during login, loading, or inventory actions.

View File

@@ -0,0 +1,16 @@
---
title: In-Game Errors
description: Common errors that can appear when attempting to play Radium.
---
import ContentTOC from '../../components/ContentTOC.astro';
# In-Game Errors
This section covers common error messages, connection issues, and server responses that may appear while playing Radium.
Choose the error code you are seeing to learn what it usually means and what to try next.
## Error Pages
<ContentTOC sectionName="in-game-errors" />

View File

@@ -1,10 +0,0 @@
---
title: Website
description: Learn about the Radium website
---
# Website
The Radium website is the central hub for all things Radium. It includes the following sections:
- [Home](https://radium.live/): The main landing page for Radium, where you can learn about the project and its features.
- [Documentation](https://docs.radium.live/): The official documentation for Radium, which includes guides, API references, and tutorials.
- [Community Forum](https://forum.radium.live/): A place to ask questions, share ideas, and connect with other Radium users.
- [Blog](https://blog.radium.live/): A collection of articles and updates about Radium, including release notes, feature announcements, and community highlights.

View File

@@ -1,9 +0,0 @@
---
title: Registration
description: Learn how to register for Radium
---
# Registration
To register for Radium, follow these steps:
1. Go to the [Radium website](https://radium.live/).
2. Click on the "Sign Up" button in the top right corner of the homepage.
3. Fill out the registration form with your email address, username, and password.

65
src/layouts/Layout.astro Normal file
View File

@@ -0,0 +1,65 @@
---
import "../styles/global.css";
import Breadcrumbs from "../components/Breadcrumbs.astro";
import type { BreadcrumbItem } from "../lib/types/breadcrum";
const {
title,
description = "Find quick answers, setup guidance, and reference information for Radium.",
breadcrumbs = [],
} = Astro.props as {
title: string;
description?: string;
breadcrumbs?: BreadcrumbItem[];
};
const siteTitle = `Radium Help - ${title}`;
const baseUrl = Astro.site ?? Astro.url;
const pageUrl = new URL(Astro.url.pathname, baseUrl).href;
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Radium Help - {siteTitle}</title>
<meta name="description" content={description} />
<meta property="og:type" content="website" />
<meta property="og:title" content={siteTitle} />
<meta property="og:description" content={description} />
<meta property="og:url" content={pageUrl} />
<meta property="og:site_name" content="Radium Help" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={siteTitle} />
<meta name="twitter:description" content={description} />
<link rel="icon" href="/favicon.ico" />
</head>
<body class="site-shell min-h-screen sm:flex sm:items-center sm:justify-center">
<main class="flex min-h-screen w-full flex-col bg-surface p-4 text-foreground sm:min-h-200 sm:w-11/12 sm:rounded sm:p-5 sm:shadow md:w-3/4">
<header class="mb-5 flex flex-col gap-3 border-b border-border pb-4 sm:mb-6 sm:flex-row sm:items-center sm:justify-between">
<a href="/" class="inline-flex w-fit items-center">
<img
src="/branding/logo.png"
alt="Radium Logo"
class="h-auto w-42.5"
/>
</a>
<Breadcrumbs items={breadcrumbs} />
</header>
<slot />
<footer class="flex flex-1 items-end text-muted">
<p>
&copy; {new Date().getFullYear()} Radium, a project by
<a
href="https://recroomarchive.org"
class="underline">Rec Room Archive</a
>.
</p>
</footer>
</main>
</body>
</html>

View File

@@ -0,0 +1,4 @@
export type BreadcrumbItem = {
label: string;
href?: string;
};

View File

@@ -1,6 +1,7 @@
--- ---
import { getCollection, render } from "astro:content"; import { getCollection, render } from "astro:content";
import { collectionNames, isSiteCollection } from "../../config/content"; import { collectionNames, isSiteCollection } from "../../config/content";
import Layout from "../../layouts/Layout.astro";
export async function getStaticPaths() { export async function getStaticPaths() {
const paths = []; const paths = [];
@@ -29,7 +30,31 @@ if (!collection || !isSiteCollection(collection)) {
} }
const { entry } = Astro.props; const { entry } = Astro.props;
const entries = await getCollection(collection);
const collectionIndex = entries.find((item) => item.id === "index");
const entryUrl =
entry.id === "index" ? `/${collection}` : `/${collection}/${entry.id}`;
const breadcrumbs = [
{ label: "Help", href: "/" },
{
label: collectionIndex?.data.title ?? collection,
href: entry.id === "index" ? undefined : `/${collection}`,
},
];
if (entry.id !== "index") {
breadcrumbs.push({ label: entry.data.title, href: entryUrl });
}
const { Content } = await render(entry); const { Content } = await render(entry);
--- ---
<Content /> <Layout
title={entry.data.title}
description={entry.data.description}
breadcrumbs={breadcrumbs}
>
<div class="prose-radium">
<Content class="prose-radium" />
</div>
</Layout>

View File

@@ -1,43 +1,71 @@
--- ---
import { getCollection } from "astro:content"; import { getCollection } from "astro:content";
import Layout from "../layouts/Layout.astro";
import { collectionNames } from "../config/content"; import { collectionNames } from "../config/content";
const breadcrumbs = [{ label: "Help" }];
const sections = await Promise.all( const sections = await Promise.all(
collectionNames.map(async (name) => { collectionNames.map(async (name) => {
const entries = (await getCollection(name)).sort((a, b) => const entries = await getCollection(name);
a.data.title.localeCompare(b.data.title)
);
const indexEntry = entries.find((entry) => entry.id === "index"); const indexEntry = entries.find((entry) => entry.id === "index");
const articles = entries.filter((entry) => entry.id !== "index"); const articles = entries.filter((entry) => entry.id !== "index");
return { return {
name, name,
indexEntry, title: indexEntry?.data.title ?? name,
articles, description:
indexEntry?.data.description ??
"Browse help articles for this section.",
articleCount: articles.length,
}; };
}) }),
); );
--- ---
<ul> <Layout
{sections.map((section) => ( title="Home"
<li> description="Find quick answers, setup guidance, and reference information for Radium."
{section.indexEntry ? ( breadcrumbs={breadcrumbs}
<a href={`/${section.name}`}>{section.indexEntry.data.title}</a> >
) : ( <section class="prose-radium mb-6">
section.name <h1>Welcome to Radium's Official Help Page!</h1>
)} <p>
Find quick answers, setup guidance, and reference information for
Radium. Choose a section below to get started!
</p>
</section>
{section.articles.length > 0 && ( <section class="mb-7">
<ul> <h2 class="mb-3 text-sm font-bold">Start here</h2>
{section.articles.map((entry) => ( <div class="grid gap-3 md:grid-cols-2">
<li> {
<a href={`/${section.name}/${entry.id}`}>{entry.data.title}</a> sections.map((section) => (
</li> <a
))} href={`/${section.name}`}
</ul> class="block rounded border border-border bg-surface p-4 text-foreground hover:bg-surface-subtle"
>
<span class="mb-1 block text-sm font-bold text-link">
{section.title}
</span>
<span class="mb-2 block text-[12px] leading-5 text-muted">
{section.description}
</span>
{section.articleCount !== 0 && (
<span class="text-[11px] text-muted-soft">
{section.articleCount === 1
? "1 article"
: `${section.articleCount} articles`}
</span>
)} )}
</li> </a>
))} ))
</ul> }
</div>
</section>
<!-- <section>
<h2 class="mb-2 text-sm font-bold">All help topics</h2>
<TOC />
</section> -->
</Layout>

View File

@@ -1 +1,63 @@
@import "tailwindcss"; @import "tailwindcss";
@plugin "@tailwindcss/typography";
:root {
color-scheme: light;
--background: #f3f4f6;
--foreground: #000000;
--surface: #ffffff;
--surface-subtle: #f9fafb;
--border: #e5e7eb;
--muted: #4b5563;
--muted-soft: #6b7280;
--link: #095fb5;
--banner-overlay: rgb(0 0 0 / 30%);
}
body {
background: var(--surface);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
}
/* @media (prefers-color-scheme: dark) {
:root {
color-scheme: dark;
--background: #000000;
--foreground: #f4f7fb;
--surface: #11161d;
--surface-subtle: #1a202a;
--border: #2a3340;
--muted: #c7d0dc;
--muted-soft: #98a6b6;
--link: #7ab8ff;
--banner-overlay: rgb(0 0 0 / 58%);
}
} */
@media (min-width: 640px) {
body.site-shell {
background-image:
linear-gradient(var(--banner-overlay), var(--banner-overlay)),
url("/branding/banner.png");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-surface: var(--surface);
--color-surface-subtle: var(--surface-subtle);
--color-border: var(--border);
--color-muted: var(--muted);
--color-muted-soft: var(--muted-soft);
--color-link: var(--link);
}
@utility prose-radium {
@apply prose prose-sm max-w-none text-[12px] text-foreground prose-headings:mt-0 prose-headings:mb-1 prose-headings:font-bold prose-headings:text-foreground prose-p:text-foreground prose-strong:text-foreground prose-li:text-foreground prose-li:marker:text-muted prose-hr:mt-2 prose-hr:mb-6 prose-hr:border-border prose-a:text-link prose-a:no-underline prose-a:hover:underline;
}

7
wrangler.jsonc Normal file
View File

@@ -0,0 +1,7 @@
{
"name": "radie-help",
"compatibility_date": "2026-05-04",
"assets": {
"directory": "./dist"
}
}