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
2 changes: 1 addition & 1 deletion astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default defineConfig({
title: 'FluxServe',
description: 'A serving engine for diffusion language models.',
favicon: '/fluxserve-icon.png',
customCss: ['./src/styles/site.css'],
customCss: ['./src/styles/site.css', './src/styles/controls.css'],
credits: false,
disable404Route: true,
components: {
Expand Down
50 changes: 50 additions & 0 deletions src/components/PageActions.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
import { Icon } from '@astrojs/starlight/components';
interface Props { id: string; }
const { id } = Astro.props;
const markdownURL = '/markdown/' + id.split('/').map(encodeURIComponent).join('/') + '.txt';
---
<div class="page-actions" data-markdown-url={markdownURL}>
<div class="action-buttons">
<button type="button" class="copy-page"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" aria-hidden="true"><rect x="8" y="8" width="12" height="13" rx="1" /><path d="M16 8V3H3v13h5" /></svg> <span>Copy page</span></button>
<details>
<summary aria-label="More page options"><Icon name="right-caret" size="20" /></summary>
<div class="page-menu"><a href={markdownURL} target="_blank" rel="noopener">View as Markdown ↗</a></div>
</details>
</div>
<span class="copy-status" role="status"></span>
</div>
<script>
document.querySelectorAll<HTMLElement>('.page-actions').forEach(actions => {
const button = actions.querySelector<HTMLButtonElement>('.copy-page')!;
const label = button.querySelector('span')!;
const status = actions.querySelector('.copy-status')!;
const details = actions.querySelector('details')!;
button.addEventListener('click', async () => {
button.disabled = true;
try {
const response = await fetch(actions.dataset.markdownUrl!);
if (!response.ok) throw new Error('Markdown unavailable');
await navigator.clipboard.writeText(await response.text());
label.textContent = 'Copied';
status.textContent = 'Page Markdown copied.';
} catch {
status.textContent = 'Could not copy. Use View as Markdown to copy manually.';
} finally {
button.disabled = false;
}
});
document.addEventListener('click', event => { if (!actions.contains(event.target as Node)) details.open = false; });
actions.addEventListener('keydown', event => {
if (event.key === 'Escape' && details.open) { details.open = false; details.querySelector('summary')!.focus(); }
});
});
</script>
<style>
.page-actions { flex-shrink: 0; position: relative; width: fit-content; font-size: .8rem; }
.action-buttons { display: flex; }
summary::-webkit-details-marker { display: none; }
.page-menu { position: absolute; top: calc(100% + 6px); right: 0; z-index: 10; min-width: 190px; padding: .4rem; border: 1px solid var(--line); border-radius: 6px; background: var(--sl-color-bg); box-shadow: 0 4px 12px #0002; }
.page-menu a { display: block; padding: .5rem; color: var(--sl-color-white); text-decoration: none; white-space: nowrap; }
.copy-status { position: absolute; right: 0; top: calc(100% + 6px); width: max-content; max-width: 220px; font-size: .75rem; color: var(--muted); }
</style>
10 changes: 9 additions & 1 deletion src/components/PageTitle.astro
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
---
import DefaultPageTitle from '@astrojs/starlight/components/PageTitle.astro';
import PageActions from './PageActions.astro';
const { hasSidebar, entry } = Astro.locals.starlightRoute;
---
{Astro.url.pathname !== '/' && <DefaultPageTitle />}
{Astro.url.pathname !== '/' && (
hasSidebar ? <div class="docs-title-row"><DefaultPageTitle /><PageActions id={entry.id} /></div> : <DefaultPageTitle />
)}
<style>
.docs-title-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-top: 1rem; }
.docs-title-row :global(h1) { min-width: 0; margin: 0; overflow-wrap: anywhere; }
</style>
4 changes: 2 additions & 2 deletions src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
import { Code } from '@astrojs/starlight/components';
import BenchmarkChart from '../components/BenchmarkChart.astro';
const install = 'git clone https://github.com/FLX-OSS/FluxServe\ncd FluxServe\nexport PIP_BREAK_SYSTEM_PACKAGES=1\npip install -e flux-kernel/python/ --no-build-isolation\npip install -e flux-scheduler\npip install -e .';
const install = 'docker pull flxoss/fluxserve:v0.1-cu130-fa4';
---
<StarlightPage frontmatter={{ title: 'Serving diffusion, one block at a time.', description: 'FluxServe is a lightweight serving engine for diffusion language models. Get started with block-level scheduling, efficient attention, and multi-GPU execution.', template: 'splash', editUrl: false, lastUpdated: false }}>
<div class="landing not-content">
Expand All @@ -15,7 +15,7 @@ const install = 'git clone https://github.com/FLX-OSS/FluxServe\ncd FluxServe\ne
<a class="button primary" href="/docs/guides/quickstart/">Get started <span aria-hidden="true">↗</span></a>
<a class="button secondary" href="https://github.com/FLX-OSS/FluxServe">View on GitHub <span aria-hidden="true">→</span></a>
</div>
<div class="hero-install"><p>Install from source inside the <a href="/docs/guides/getting_started/">FluxServe CUDA container ↗</a></p><Code code={install} lang="bash" frame="none" /></div>
<div class="hero-install"><p><a href="/docs/guides/getting_started/">Docker setup ↗</a></p><Code code={install} lang="bash" frame="none" /></div>
</div>
<BenchmarkChart />
</section>
Expand Down
13 changes: 13 additions & 0 deletions src/pages/markdown/[...slug].txt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { getCollection, type CollectionEntry } from 'astro:content';
import type { APIRoute } from 'astro';

export async function getStaticPaths() {
return (await getCollection('docs')).map(page => ({ params: { slug: page.id }, props: { page } }));
}

export const GET: APIRoute = ({ props }) => {
const page = props.page as CollectionEntry<'docs'>;
return new Response(`# ${page.data.title}\n\n${page.body ?? ''}`, {
headers: { 'Content-Type': 'text/plain; charset=utf-8' },
});
};
93 changes: 93 additions & 0 deletions src/styles/controls.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/* Shared neutral controls, including Starlight's search and contents controls. */
:root {
--control-height: 40px;
--control-radius: 6px;
--control-icon: 20px;
--control-hover: var(--sl-color-gray-6);
}
.header-tools site-search > button,
mobile-starlight-toc .toggle,
.page-actions .action-buttons,
.header-tools .theme-toggle,
.header-tools .github-link {
box-sizing: border-box;
height: var(--control-height);
min-height: var(--control-height);
border: 1px solid var(--line);
border-radius: var(--control-radius);
background: transparent;
color: var(--sl-color-gray-2);
box-shadow: none;
font-size: .875rem;
}
.header-tools site-search > button,
mobile-starlight-toc .toggle { padding: 0 12px; gap: 8px; }
.header-tools .theme-toggle,
.header-tools .github-link { width: var(--control-height); display: grid; place-items: center; padding: 0; }
.page-actions .copy-page,
.page-actions summary {
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
height: calc(var(--control-height) - 2px);
min-height: 0;
padding: 0 12px;
border: 0;
background: transparent;
color: var(--sl-color-gray-2);
font: inherit;
cursor: pointer;
}
.page-actions .copy-page { border-radius: calc(var(--control-radius) - 1px) 0 0 calc(var(--control-radius) - 1px); }
.page-actions summary {
width: calc(var(--control-height) - 1px);
padding: 0;
border-left: 1px solid var(--line);
border-radius: 0 calc(var(--control-radius) - 1px) calc(var(--control-radius) - 1px) 0;
list-style: none;
}
.header-tools site-search > button:hover,
mobile-starlight-toc details .toggle:hover,
mobile-starlight-toc details[open] .toggle,
.page-actions .copy-page:hover,
.page-actions summary:hover,
.page-actions details[open] summary,
.header-tools .theme-toggle:hover,
.header-tools .github-link:hover {
color: var(--sl-color-white);
background: var(--control-hover);
border-color: var(--line);
box-shadow: none;
}
.header-tools :is(button, a):focus-visible,
.page-actions :is(button, summary, a):focus-visible,
mobile-starlight-toc summary:focus-visible,
.sidebar-content :is(summary, a):focus-visible {
outline: 2px solid var(--brand);
outline-offset: 2px;
}
.header-tools :is(button, a) svg,
.page-actions :is(button, summary) svg,
mobile-starlight-toc .caret,
.sidebar-content summary .caret {
width: var(--control-icon);
height: var(--control-icon);
font-size: var(--control-icon);
flex-shrink: 0;
}
/* Use the same right chevron, rotated consistently to indicate open state. */
.page-actions summary svg { transform: rotate(90deg); }
.page-actions details[open] summary svg { transform: rotate(-90deg); }
.sidebar-content summary { border-radius: var(--control-radius); }
.sidebar-content summary:hover,
.sidebar-content a:not([aria-current='page']):hover,
.page-actions .page-menu a:hover {
background: var(--control-hover);
color: var(--sl-color-white);
}
.page-actions .page-menu a { border-radius: calc(var(--control-radius) - 1px); }
.header-tools .theme-toggle { flex-shrink: 0; cursor: pointer; }
.theme-toggle span:not([hidden]) { display: flex; }
@media(max-width: 49.99rem) { .header-tools .github-link { display: none; } }
8 changes: 1 addition & 7 deletions src/styles/site.css
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ a:focus-visible, button:focus-visible, select:focus-visible { outline: 2px solid
.primary-nav a:hover, .primary-nav a[aria-current] { color: var(--brand); }
.header-tools { display: flex; align-items: center; gap: 1rem; margin-left: auto; }
.header-tools site-search { min-width: 0; }
.header-tools site-search > button { width: 11rem; border-color: var(--line); background: var(--surface); border-radius: 7px; }
.github-link { color: var(--sl-color-white); display: flex; }
.header-tools site-search > button { width: 11rem; }
html:not([data-has-sidebar]) { --sl-content-width: 72rem; }
html:not([data-has-sidebar]) .content-panel + .content-panel { border-top: 0; padding-top: 0; }
html:has(.landing) .content-panel:first-child { display: none; }
Expand Down Expand Up @@ -125,8 +124,3 @@ html:has(.landing) main { padding-top: 0; }
@media(prefers-reduced-motion: reduce) { *,*::before,*::after { scroll-behavior: auto !important; animation: none !important; transition: none !important; } }

.sidebar-content summary .large { text-transform: capitalize; }

.theme-toggle { display: grid; place-items: center; flex-shrink: 0; width: 2.5rem; height: 2.5rem; padding: 0; border: 0; border-radius: .5rem; background: transparent; color: var(--sl-color-gray-2); cursor: pointer; }
.theme-toggle:hover { background: var(--surface); color: var(--sl-color-white); }
.theme-toggle:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.theme-toggle span:not([hidden]) { display: flex; font-size: 1.125rem; }
Loading