- + - {post.data.title} - {post.data.description} + + {post.data.title} + + { + authors.length > 0 && ( + + {new Intl.ListFormat("en", { + style: "long", + type: "conjunction", + }).format(authors.map((author) => author.data.name))} + + ) + } + + {post.data.description} + - { - authors.length > 0 && ( - - {new Intl.ListFormat('en', { style: 'long', type: 'conjunction' }).format( - authors.map((author) => author.data.name), - )} - - ) - }
- - - + + + • - {remarkPluginFrontmatter.minutesRead} + {remarkPluginFrontmatter.minutesRead} - {post.data.title} - + {post.data.title} + By { - new Intl.ListFormat('en', { style: 'long', type: 'conjunction' }) + new Intl.ListFormat("en", { style: "long", type: "conjunction" }) .formatToParts(authors.map((author) => author.data.name)) .map((part) => - part.type === 'element' ? ( + part.type === "element" ? ( // inline-block removes the whitespace that prettier+astro adds around the text a.data.name === part.value)?.id}`} - class="intent:underline inline-block" + class="inline-block intent:underline" data-pagefind-meta="author" > {part.value} diff --git a/site/src/pages/blog/authors/[author].astro b/site/src/pages/blog/authors/[author].astro index fb2b703e..47920614 100644 --- a/site/src/pages/blog/authors/[author].astro +++ b/site/src/pages/blog/authors/[author].astro @@ -45,30 +45,43 @@ const jsonLdSchema = createProfilePageSchema({ }); --- - + { author.data.avatar && ( ) } - {author.data.name} - {author.data.bio && {author.data.bio}} + {author.data.name} + {author.data.bio && {author.data.bio}} { author.data.socialLinks && ( - + ) } - - {postsWithAuthors.map((post) => )} + + { + postsWithAuthors.map((post) => ( + + )) + } diff --git a/site/src/pages/docs/framework/[framework]/[...slug].astro b/site/src/pages/docs/framework/[framework]/[...slug].astro index 19b92fad..c7636ceb 100644 --- a/site/src/pages/docs/framework/[framework]/[...slug].astro +++ b/site/src/pages/docs/framework/[framework]/[...slug].astro @@ -8,7 +8,7 @@ import { Selectors } from '@/components/docs/Selectors'; import { TableOfContents } from '@/components/docs/TableOfContents'; import JsonLd from '@/components/JsonLd.astro'; import defaultMarkdownComponents from '@/components/typography/defaultMarkdownComponents'; -import H3 from '@/components/typography/H3.astro'; +import H2Markdown from '@/components/typography/H2Markdown.astro'; import DocsLayout from '@/layouts/Docs.astro'; import type { SupportedFramework } from '@/types/docs'; import { SUPPORTED_FRAMEWORKS } from '@/types/docs'; @@ -95,11 +95,11 @@ const jsonLdSchema = createTechArticleSchema({ - + - {getDocTitle(doc, framework)} - {doc.data.description} + {getDocTitle(doc, framework)} + {doc.data.description} diff --git a/site/src/pages/index.astro b/site/src/pages/index.astro index 5021ad3a..5714dcb7 100644 --- a/site/src/pages/index.astro +++ b/site/src/pages/index.astro @@ -1,106 +1,27 @@ --- -import { CircleCheck, Clock } from 'lucide-react'; -import construction from '@/assets/construction.svg?raw'; import Footer from '@/components/Footer.astro'; import FooterEasterEgg from '@/components/FooterEasterEgg.astro'; -import HomePageDemo from '@/components/HomePageDemo'; -import HeroVideo from '@/components/home/HeroVideo'; -import HomePageControls from '@/components/home/HomePageControls'; +import Built from '@/components/home/Built/BuiltSection.astro'; +import Demo from '@/components/home/Demo/Demo'; +import GetStartedBanner from '@/components/home/GetStartedBanner.astro'; +import Header from '@/components/home/Header.astro'; +import RoadMap from '@/components/home/Roadmap.astro'; +import Sponsors from '@/components/home/Sponsors.astro'; import NavBar from '@/components/NavBar/NavBar.astro'; -import { SITE_DESCRIPTION, SITE_TITLE, VJS8_DEMO_VIDEO } from '@/consts'; +import { SITE_DESCRIPTION, SITE_TITLE } from '@/consts'; import Base from '@/layouts/Base.astro'; - -const poster = `${VJS8_DEMO_VIDEO.poster}?time=0`; --- - - - - - - The Open Source Player for the Web - - The open-source video player for React and HTML. Lightweight, accessible components built for performance and - streaming. - - - - - - - - - - - - - - - - - - - - Roadmap - Video.js 10 is under construction - - - - - - - - - - Preview - October 28, 2025 - Vibe check. First public look, with limited features. Not production ready. - - - - - - - - Beta - February 2026 - Core controls. Adaptive streaming with existing engines. Try it out! - - - - - - - - Release - Mid-2026 - Stable, with all the basics: Media Chrome, Vidstack, Plyr feature parity. - - - - - - - - Beyond - Late-2026 - Collab with the community, migrate major v8 plugins, develop streaming engines - - - - + + + + + + + + diff --git a/site/src/styles/globals.css b/site/src/styles/globals.css index 635432ab..6e48aba9 100644 --- a/site/src/styles/globals.css +++ b/site/src/styles/globals.css @@ -21,6 +21,7 @@ font-style: normal; font-display: swap; } + @font-face { font-family: "Eurostile LT Pro Extended"; src: @@ -28,7 +29,8 @@ url("https://static.mux.com/fonts/EurostileLTProExtended2/font.woff") format("woff"); font-weight: normal; font-style: normal; - font-display: swap; + /* the metrics of this font are wack, so, let's block instead of swap. TODO precompute metrics */ + font-display: block; } @font-face { font-family: "Eurostile LT Pro Extended"; @@ -37,68 +39,8 @@ url("https://static.mux.com/fonts/EurostileLTProBoldExtended2/font.woff") format("woff"); font-weight: bold; font-style: normal; - font-display: swap; -} - -/* before we begin with tailwind, let's go over some global rules */ -/* nested lists should have lower-alpha style */ -.list-decimal .list-decimal { - list-style-type: lower-alpha; -} - -/* slightly thinner decorations */ -* { - text-decoration-thickness: max(0.05em, 0.05rem); -} - -/* global text decoration offset */ -.font-sans { - text-underline-offset: 0.25em; -} -.font-mono { - text-underline-offset: 0.125em; -} - -/* no ligatures in code... */ -.font-mono { - font-variant-ligatures: none; -} - -/* stuff should leave room for the nav when scroll margining */ -[id] { - scroll-margin-top: calc(var(--nav-h) + var(--spacing) * 5 + var(--scroll-mt, 0px)); -} - -/* basic HTML elements */ -b, -strong { - font-weight: var(--font-weight-semibold); -} -mark { - background-color: var(--color-yellow); - color: var(--color-dark-100); -} - -/* shiki dark mode */ -.dark .shiki, -.dark .shiki span, -.dark .astro-code, -.dark .astro-code span { - /* biome-ignore lint/complexity/noImportantStyles: override shiki's inline styles */ - color: var(--shiki-dark) !important; -} - -/* Ok, now let's do some tailwind stuff */ -@custom-variant intent (&:hover, -&:focus-within); -@custom-variant supports-container { - @supports (container: size) { - @slot; - } -} -@custom-variant dark (&:where(.dark, .dark *)); -.dark * { - color-scheme: dark; + /* the metrics of this font are wack, so, let's block instead of swap. TODO precompute metrics */ + font-display: block; } /* theme inline tells tailwind to reference the value of these properties */ @@ -108,99 +50,96 @@ mark { --font-sans: var(--font-instrument-sans); --font-mono: var(--font-ibm-plex-mono); --font-display-compact: "Eurostile LT Pro", sans-serif; - --font-display-extended: "Eurostile LT Pro Extended", sans-serif; + --font-display: "Eurostile LT Pro Extended", sans-serif; } -/* Everything else can be configured here */ @theme { --color-*: initial; --color-white: white; --color-black: black; - --color-dark-110: #2a2928; - --color-dark-100: #393836; - --color-dark-90: #494741; - --color-dark-80: #5a5850; - --color-dark-40: #7d796a; + --color-faded-black: #1e1d1d; + --color-soot: #32302f; + --color-warm-gray: #403c38; + --color-manila-dark: #bfb39e; + --color-manila-75: #ccc3ab; + --color-manila-50: #dcd2bb; + --color-manila-25: #e7ddc6; + --color-manila-light: #f3e7d2; - --color-light-100: #fbf5d8; - --color-light-80: #ebe4c1; - --color-light-60: #d8d2b2; - --color-light-40: #c7c2a4; - - --color-yellow: #fcb116; - --color-orange: #f26222; - --color-red: #ea3837; - --color-purple: #a83b71; - --color-blue: #3870b7; + --color-bright-yellow: #ffca18; + --color-gold: #ffa81b; + --color-orange: #ff6200; + --color-red: #eb3132; + --color-magenta: #cc3566; /* Typography */ --tracking-*: initial; - --tracking-tighter: -0.04em; - --tracking-tight: -0.02em; + --tracking-tightest: -0.03em; + --tracking-tighter: -0.02em; + --tracking-tight: -0.01em; --tracking-normal: 0; - --tracking-wide: 0.02em; - --tracking-wider: 0.04em; - --tracking-widest: 0.08em; - - --font-weight-code-normal: 400; - --font-weight-normal: 450; - --font-weight-medium: 500; - --font-weight-semibold: 600; --text-*: initial; - --text-h1: 4rem; /* 64px */ - --text-h1--line-height: 1; - --text-h1--letter-spacing: -0.04em; - --text-h1--font-weight: var(--font-weight-semibold); - --text-h2: 3rem; /* 48px */ - --text-h2--line-height: calc(56 / 48); - --text-h2--letter-spacing: -0.04em; - --text-h2--font-weight: var(--font-weight-semibold); - --text-h3: 2.5rem; /* 40px */ + + --text-h1: 3.75rem; /* 60px */ + --text-h1--line-height: 1.1; + --text-h1--letter-spacing: var(--tracking-tightest); + --text-h1--font-weight: var(--font-weight-bold); + + --text-h15: 2.375rem; /* 38px */ + --text-h15--line-height: 1.1; + --text-h15--letter-spacing: var(--tracking-tightest); + --text-h15--font-weight: var(--font-weight-bold); + + --text-h2: 1.75rem; /* 28px */ + --text-h2--line-height: 1; + --text-h2--letter-spacing: var(--tracking-tighter); + --text-h2--font-weight: var(--font-weight-bold); + + --text-h25: 1.5rem; /* 24px */ + --text-h25--line-height: 1; + --text-h25--letter-spacing: var(--tracking-tighter); + --text-h25--font-weight: var(--font-weight-bold); + + --text-h3: 1.125rem; /* 18px */ --text-h3--line-height: 1; - --text-h3--letter-spacing: -0.04em; - --text-h3--font-weight: var(--font-weight-semibold); - --text-h4: 2rem; /* 32px */ - --text-h4--line-height: calc(40 / 32); - --text-h4--letter-spacing: -0.02em; - --text-h4--font-weight: var(--font-weight-semibold); - --text-h5: 1.5rem; /* 24px */ - --text-h5--line-height: calc(32 / 24); - --text-h5--letter-spacing: -0.02em; - --text-h5--font-weight: var(--font-weight-medium); + --text-h3--letter-spacing: var(--tracking-normal); + --text-h3--font-weight: var(--font-weight-bold); - --text-lg: 1.25rem; /* 20px */ - --text-lg--line-height: calc(28 / 20); - --text-lg--letter-spacing: -0.02em; - --text-lg--font-weight: var(--font-weight-normal); - --text-md: 1.125rem; /* 18px */ - --text-md--line-height: calc(26 / 18); - --text-md--letter-spacing: -0.02em; - --text-md--font-weight: var(--font-weight-normal); - --text-base: 1rem; /* 16px */ - --text-base--line-height: calc(24 / 16); - --text-base--letter-spacing: -0.02em; - --text-base--font-weight: var(--font-weight-normal); - --text-sm: 0.875rem; /* 14px */ - --text-sm--line-height: calc(20 / 14); - --text-sm--letter-spacing: -0.02em; - --text-sm--font-weight: var(--font-weight-normal); + --text-h4: 0.875rem; /* 14px */ + --text-h4--line-height: 1; + --text-h4--letter-spacing: var(--tracking-normal); + --text-h4--font-weight: var(--font-weight-bold); - /* Notice the use of em, so that code scales with, say, headers */ - --text-code: clamp(0.875em, calc(0.8125em + 0.125rem), 0.9375em); + --text-h5: 0.875rem; /* 14px */ + --text-h5--line-height: 1; + --text-h5--letter-spacing: var(--tracking-normal); + --text-h5--font-weight: var(--font-weight-normal); + + --text-p1: 1.375rem; /* 22px */ + --text-p1--line-height: 1.5; + --text-p1--letter-spacing: var(--tracking-tight); + --text-p1--font-weight: var(--font-weight-normal); + + --text-p2: 1rem; /* 16px */ + --text-p2--line-height: 1.5; + --text-p2--letter-spacing: var(--tracking-normal); + --text-p2--font-weight: var(--font-weight-normal); + + --text-p3: 0.875rem; /* 14px */ + --text-p3--line-height: 1.5; + --text-p3--letter-spacing: var(--tracking-normal); + --text-p3--font-weight: var(--font-weight-normal); + + --text-code: 0.875em; /* 14px */ --text-code--line-height: inherit; - --text-code--letter-spacing: -0.02em; - --text-code--font-weight: var(--font-weight-code-normal); - /* if you don't want this scaling, use text-base-code */ - --text-base-code: 0.9375rem; - --text-base-code--line-height: calc(28 / 16); - --text-base-code--letter-spacing: -0.02em; - --text-base-code--font-weight: var(--font-weight-code-normal); + --text-code--letter-spacing: var(--tracking-normal); + --text-code--font-weight: var(--font-weight-normal); /* animations */ - --animate-marquee: marquee 40s linear infinite; + --animate-marquee: marquee 30s linear infinite; @keyframes marquee { from { transform: translate3d(-50%, 0, 0); @@ -210,3 +149,190 @@ mark { } } } + +@custom-variant intent (&:hover, +&:focus-within); +@custom-variant supports-container { + @supports (container: size) { + @slot; + } +} +@custom-variant dark (&:where(.dark, .dark *)); + +@layer base { + .list-decimal .list-decimal { + list-style-type: lower-alpha; + } + + * { + text-decoration-thickness: max(0.05em, 0.05rem); + } + + .font-display, + .font-display-compact { + text-underline-offset: 0.25em; + } + + .font-sans { + text-underline-offset: 0.25em; + } + + .font-mono { + text-underline-offset: 0.125em; + font-variant-ligatures: none; + } + + [id] { + /* this only works where nav-h is defined. currently, docs */ + scroll-margin-top: calc(var(--nav-h) + var(--spacing) * 5 + var(--scroll-mt, 0px)); + } + + b, + strong { + font-weight: var(--font-weight-semibold); + } + + mark { + background-color: var(--color-bright-yellow); + color: var(--color-faded-black); + } + + .dark * { + color-scheme: dark; + } +} + +* { + scrollbar-color: var(--color-manila-dark) transparent; + + &::-webkit-scrollbar-thumb { + background: var(--color-manila-dark); + border-radius: 9999px; + } +} + +@utility data-bar { + height: 2.5rem; + background-image: url("/data-bar-white.svg"); + background-repeat: repeat-x; + background-size: auto 100%; + animation: grow-bar 1.5s ease-out forwards; + animation-play-state: paused; + + [data-animate] & { + animation-play-state: running; + } +} + +@utility data-bar-orange { + background-image: url("/data-bar-orange.svg"); +} + +@utility horizontal-bars { + width: 2.5rem; + background-image: url("/horizontal-bar-white.svg"); + background-repeat: repeat-y; + background-size: 100% 6px; + animation: horizontal-grow-bar 1.5s ease-out forwards; + animation-play-state: paused; + + [data-animate] & { + animation-play-state: running; + } +} + +@utility horizontal-bars-orange { + background-image: url("/horizontal-bar-orange.svg"); +} + +@utility built-bg-gray { + background-image: url("/built-bg-horizontal-line-gray.svg"); + background-repeat: repeat-y; + background-size: 100% 9px; + background-clip: content-box; + padding: 8px 10px 0 10px; +} + +@utility built-bg-black { + background-image: url("/built-bg-horizontal-line-black.svg"); + background-repeat: repeat-y; + background-size: 100% 9px; + background-clip: content-box; + padding: 8px 10px 0 10px; +} + +@utility text-stroke-faded-black { + color: transparent; + -webkit-text-stroke: 1.5px var(--color-faded-black); + -webkit-text-stroke: clamp(1px, 0.035em, 1.5px) var(--color-faded-black); + + &::selection { + color: transparent; + -webkit-text-stroke: 1.5px var(--color-faded-black); + -webkit-text-stroke: clamp(1px, 0.035em, 1.5px) var(--color-faded-black); + } +} + +@utility text-stroke-manila-light { + color: transparent; + -webkit-text-stroke: 1.5px var(--color-manila-light); + -webkit-text-stroke: clamp(1px, 0.035em, 1.5px) var(--color-manila-light); + + &::selection { + color: transparent; + -webkit-text-stroke: 1.5px var(--color-faded-black); + -webkit-text-stroke: clamp(1px, 0.035em, 1.5px) var(--color-faded-black); + } +} + +@utility grid-separator-container { + position: relative; + + &::before { + top: 0; + left: 0%; + width: 100%; + height: 100%; + content: ""; + position: absolute; + border: 10px solid; + border-color: inherit; + z-index: 1000; + pointer-events: none; + } +} + +@utility grid-separators { + border-right: 1px solid; + border-bottom: 1px solid; + border-color: inherit; + + &::after { + content: ""; + position: absolute; + bottom: -5px; + right: -5px; + height: 10px; + width: 10px; + background: inherit; + z-index: 10; + } +} + +@keyframes grow-bar { + from { + width: 0%; + } + to { + width: 100%; + } +} + +@keyframes horizontal-grow-bar { + from { + height: 0%; + } + to { + height: 100%; + } +} diff --git a/site/src/utils/docs/__tests__/renderInlineMarkdown.test.ts b/site/src/utils/docs/__tests__/renderInlineMarkdown.test.ts index 9786a4b5..3516b0e6 100644 --- a/site/src/utils/docs/__tests__/renderInlineMarkdown.test.ts +++ b/site/src/utils/docs/__tests__/renderInlineMarkdown.test.ts @@ -9,7 +9,7 @@ describe('renderInlineMarkdown', () => { it('unwraps a single paragraph', () => { const result = renderInlineMarkdown('Hello **world**.'); expect(result).not.toMatch(/^world'); + expect(result).toContain('world'); }); it('preserves multiple paragraphs', () => { @@ -29,12 +29,12 @@ describe('renderInlineMarkdown', () => { it('renders strong text', () => { const result = renderInlineMarkdown('**bold text**'); - expect(result).toContain('bold text'); + expect(result).toContain('bold text'); }); it('renders emphasized text', () => { const result = renderInlineMarkdown('*italic text*'); - expect(result).toContain('italic text'); + expect(result).toContain('italic text'); }); it('renders links with correct classes', () => { diff --git a/site/src/utils/docs/renderInlineMarkdown.ts b/site/src/utils/docs/renderInlineMarkdown.ts index e1fb1b3f..8bd00c55 100644 --- a/site/src/utils/docs/renderInlineMarkdown.ts +++ b/site/src/utils/docs/renderInlineMarkdown.ts @@ -1,6 +1,6 @@ import { Marked, type MarkedExtension, type Tokens } from 'marked'; -import { twMerge } from 'tailwind-merge'; import { shared } from '@/components/typography/styles'; +import { twMerge } from '@/utils/twMerge'; const classes = { p: 'mt-3 first:mt-0', diff --git a/site/src/utils/twMerge.ts b/site/src/utils/twMerge.ts new file mode 100644 index 00000000..c3945272 --- /dev/null +++ b/site/src/utils/twMerge.ts @@ -0,0 +1,21 @@ +import { extendTailwindMerge } from 'tailwind-merge'; + +export const twMerge = extendTailwindMerge({ + extend: { + classGroups: { + 'font-size': [ + 'text-h1', + 'text-h15', + 'text-h2', + 'text-h3', + 'text-h4', + 'text-h5', + 'text-p1', + 'text-p2', + 'text-p3', + 'text-code', + ], + 'font-family': ['font-display-compact', 'font-display'], + }, + }, +});
- {getDocTitle(doc, framework)} - {doc.data.description} + {getDocTitle(doc, framework)} + {doc.data.description}