Compare commits
7 Commits
jazz-react
...
callumflac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b6fc692aa | ||
|
|
8e8abada48 | ||
|
|
e83247407c | ||
|
|
fd2e2b8d75 | ||
|
|
8c67734667 | ||
|
|
1047072edd | ||
|
|
3edb085272 |
@@ -28,6 +28,7 @@
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "14.2.7",
|
||||
"postcss": "^8",
|
||||
"postcss-import": "^16.1.0",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"typescript": "^5"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/** @type {import('postcss-load-config').Config} */
|
||||
const config = {
|
||||
plugins: {
|
||||
"postcss-import": {},
|
||||
tailwindcss: {},
|
||||
},
|
||||
};
|
||||
|
||||
57
homepage/design-system/src/app/components/atoms/Space.tsx
Normal file
57
homepage/design-system/src/app/components/atoms/Space.tsx
Normal file
@@ -0,0 +1,57 @@
|
||||
import { cva, cx, type VariantProps } from "class-variance-authority";
|
||||
|
||||
/*
|
||||
Space helps you group related elements by whitespace, both vertically and horizontally. Use it to create layouts with whitespace.
|
||||
*/
|
||||
|
||||
export const spaceVariants = cva([""], {
|
||||
variants: {
|
||||
vertical: {
|
||||
minor: "space-y-d8",
|
||||
major: "space-y-d16",
|
||||
super: "space-y-d24",
|
||||
},
|
||||
container: {
|
||||
true: "container",
|
||||
},
|
||||
},
|
||||
compoundVariants: [
|
||||
// EXAMPLE:
|
||||
// {
|
||||
// intent: "display",
|
||||
// size: ["super", "title", "subtitle"],
|
||||
// class: "text-super tracking-super",
|
||||
// },
|
||||
],
|
||||
defaultVariants: {
|
||||
// vertical: "default",
|
||||
container: true,
|
||||
},
|
||||
});
|
||||
|
||||
export interface SpaceProps
|
||||
extends React.HTMLAttributes<HTMLElement>,
|
||||
VariantProps<typeof spaceVariants> {
|
||||
as?: React.ElementType;
|
||||
}
|
||||
|
||||
export function GroupWithSpace({
|
||||
as: Component = "div",
|
||||
vertical,
|
||||
className,
|
||||
...props
|
||||
}: SpaceProps) {
|
||||
return (
|
||||
<Component
|
||||
{...props}
|
||||
className={cx(
|
||||
spaceVariants({
|
||||
vertical,
|
||||
className,
|
||||
})
|
||||
)}
|
||||
>
|
||||
{props.children}
|
||||
</Component>
|
||||
);
|
||||
}
|
||||
103
homepage/design-system/src/app/components/atoms/Text.tsx
Normal file
103
homepage/design-system/src/app/components/atoms/Text.tsx
Normal file
@@ -0,0 +1,103 @@
|
||||
import { cva, cx, type VariantProps } from "class-variance-authority";
|
||||
|
||||
const displayStyle = "font-display font-semibold";
|
||||
const headingStyle = "font-sans font-medium";
|
||||
const paragraphStyle = "font-sans font-normal";
|
||||
// const monoStyle = "font-mono font-medium";
|
||||
|
||||
export const textVariants = cva([], {
|
||||
variants: {
|
||||
intent: {
|
||||
default: "",
|
||||
link: "link",
|
||||
markdown: "prose", // TBC
|
||||
fine: [paragraphStyle, "text-fine subpixel-antialiased"],
|
||||
// TODO: metaHeading: [monoStyle]
|
||||
body: [paragraphStyle, "text-base"],
|
||||
lead: [headingStyle, "text-lead"],
|
||||
subheading: [displayStyle, "text-subheading"],
|
||||
heading: [displayStyle, "text-heading"],
|
||||
subtitle: [displayStyle, "text-subtitle"],
|
||||
title: [displayStyle, "text-title"],
|
||||
super: [displayStyle, "text-super"],
|
||||
},
|
||||
color: {
|
||||
feint: "text-line",
|
||||
dim: "text-solid",
|
||||
default: "text-fill",
|
||||
destructive: "text-destructive",
|
||||
},
|
||||
align: {
|
||||
left: "text-left",
|
||||
center: "text-center",
|
||||
right: "text-right",
|
||||
},
|
||||
inline: {
|
||||
true: "leading-none",
|
||||
},
|
||||
balance: {
|
||||
true: "text-balance",
|
||||
},
|
||||
bullet: {
|
||||
true: ["list-disc"],
|
||||
},
|
||||
},
|
||||
// Compound variants apply classes when multiple other variant conditions are met: https://cva.style/docs/getting-started/variants#compound-variants
|
||||
compoundVariants: [
|
||||
// EXAMPLE:
|
||||
// {
|
||||
// intent: "display",
|
||||
// size: ["super", "title", "subtitle"],
|
||||
// class: "text-super tracking-super",
|
||||
// },
|
||||
],
|
||||
// I find the less that is defaulted and the more inherited from the body element's typographic settings, the less property assignment is required. Let's wait & see what are needs are.
|
||||
defaultVariants: {
|
||||
// intent: "body",
|
||||
// color: "default",
|
||||
// align: "left",
|
||||
},
|
||||
});
|
||||
|
||||
export interface TextProps
|
||||
extends Omit<React.HTMLAttributes<HTMLElement>, "color">,
|
||||
VariantProps<typeof textVariants> {
|
||||
as?: React.ElementType;
|
||||
}
|
||||
|
||||
export const Text = ({
|
||||
as: Component = "p",
|
||||
className,
|
||||
intent,
|
||||
color,
|
||||
align,
|
||||
inline,
|
||||
balance,
|
||||
bullet,
|
||||
...props
|
||||
}: TextProps) => {
|
||||
if (Component === "li") {
|
||||
bullet = true;
|
||||
}
|
||||
|
||||
return (
|
||||
<Component
|
||||
{...props}
|
||||
className={cx(
|
||||
textVariants({
|
||||
intent,
|
||||
color,
|
||||
align,
|
||||
inline,
|
||||
balance,
|
||||
bullet,
|
||||
className,
|
||||
}),
|
||||
Component === "ul" ? "pl-[2em]" : ""
|
||||
)}
|
||||
>
|
||||
{/* {format ? formatText(children) : children} */}
|
||||
{props.children}
|
||||
</Component>
|
||||
);
|
||||
};
|
||||
2
homepage/design-system/src/app/components/atoms/index.ts
Normal file
2
homepage/design-system/src/app/components/atoms/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./Text";
|
||||
export * from "./Space";
|
||||
@@ -1,23 +1,25 @@
|
||||
import clsx from "clsx";
|
||||
|
||||
export function HairlineBleedGrid({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6",
|
||||
"mb-10",
|
||||
"items-stretch",
|
||||
"gap-[1px]",
|
||||
"-mx-4 md:-mx-6",
|
||||
"rounded-xl",
|
||||
"overflow-hidden",
|
||||
"bg-stone-50 dark:bg-stone-950",
|
||||
"[&>*]:rounded-none",
|
||||
"[&>*]:border-none",
|
||||
"[&>*]:bg-stone-100 [&>*]:dark:bg-stone-900"
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6",
|
||||
"mb-10",
|
||||
"items-stretch",
|
||||
"gap-[1px]",
|
||||
"-mx-4 md:-mx-6",
|
||||
"rounded-xl",
|
||||
"overflow-hidden",
|
||||
// "bg-stone-50 dark:bg-stone-950",
|
||||
"bg-canvas",
|
||||
"[&>*]:rounded-none",
|
||||
"[&>*]:border-none",
|
||||
// "[&>*]:bg-stone-100 [&>*]:dark:bg-stone-900"
|
||||
"[&>*]:bg-background"
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,35 +1,23 @@
|
||||
import { ReactNode } from "react";
|
||||
import { H1 } from "../atoms/Headings";
|
||||
import clsx from "clsx";
|
||||
|
||||
function H1Sub({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<p
|
||||
className={clsx(
|
||||
"text-3xl lg:text-4xl",
|
||||
"leading-snug",
|
||||
"tracking-tight",
|
||||
"mb-5",
|
||||
"max-w-4xl",
|
||||
"text-stone-700 dark:text-stone-500"
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
import { Text } from "../atoms";
|
||||
|
||||
export function HeroHeader({
|
||||
title,
|
||||
slogan,
|
||||
title,
|
||||
slogan,
|
||||
}: {
|
||||
title: ReactNode;
|
||||
slogan: ReactNode;
|
||||
title: ReactNode;
|
||||
slogan: ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<hgroup className="md:pt-20 mb-10">
|
||||
<H1>{title}</H1>
|
||||
<H1Sub>{slogan}</H1Sub>
|
||||
</hgroup>
|
||||
);
|
||||
return (
|
||||
// prefer header over hgroup? I prefer to avoid semantic HTML as it has not made much difference to web apps or SEO or anything for the last decade. I do like header, footer, main, section, article, aside, etc. as they make sense in the context of a document. Naming this header or section would be premature, hgroup is actually better but folks reading it may assume they need to be pedantic here. So IMHO, div would suffice.
|
||||
// no "mb-10 md:pt-20", always hoist whitespace styles to the parent.
|
||||
<hgroup className="space-y-1.5">
|
||||
<Text as="h1" intent="super">
|
||||
{title}
|
||||
</Text>
|
||||
<Text as="h2" intent="subtitle" color="dim">
|
||||
{slogan}
|
||||
</Text>
|
||||
</hgroup>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,34 +1,23 @@
|
||||
import { ReactNode } from "react";
|
||||
import { H2 } from "../atoms/Headings";
|
||||
import clsx from "clsx";
|
||||
|
||||
function H2Sub({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<p
|
||||
className={clsx(
|
||||
"text-lg lg:text-xl",
|
||||
"leading-snug",
|
||||
"tracking-tight",
|
||||
"max-w-4xl",
|
||||
"text-stone-700 dark:text-stone-500"
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
import { Text } from "../atoms";
|
||||
|
||||
export function SectionHeader({
|
||||
title,
|
||||
slogan,
|
||||
title,
|
||||
slogan,
|
||||
}: {
|
||||
title: ReactNode;
|
||||
slogan: ReactNode;
|
||||
title: ReactNode;
|
||||
slogan: ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<hgroup className="mb-5">
|
||||
<H2>{title}</H2>
|
||||
<H2Sub>{slogan}</H2Sub>
|
||||
</hgroup>
|
||||
);
|
||||
return (
|
||||
// no mb-*, always hoist whitespace styles to the parent
|
||||
<hgroup className="space-y-0.5">
|
||||
<Text as="h2" intent="subheading">
|
||||
{title}
|
||||
</Text>
|
||||
{/* remove "max-w-4xl", hoist width styles to the parent */}
|
||||
<Text as="p" intent="lead" color="dim">
|
||||
{slogan}
|
||||
</Text>
|
||||
</hgroup>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "./HeroHeader";
|
||||
export * from "./SectionHeader";
|
||||
@@ -6,176 +6,166 @@ import { ReactNode, useLayoutEffect, useRef, useState } from "react";
|
||||
import { BreadCrumb } from "../molecules/Breadcrumb";
|
||||
import clsx from "clsx";
|
||||
import Link from "next/link";
|
||||
import { cva, cx, type VariantProps } from "class-variance-authority";
|
||||
|
||||
export function Nav({
|
||||
mainLogo,
|
||||
items,
|
||||
docNav,
|
||||
mainLogo,
|
||||
items,
|
||||
docNav,
|
||||
}: {
|
||||
mainLogo: ReactNode;
|
||||
items: {
|
||||
href: string;
|
||||
icon?: ReactNode;
|
||||
title: string;
|
||||
firstOnRight?: boolean;
|
||||
newTab?: boolean;
|
||||
}[];
|
||||
docNav: ReactNode;
|
||||
mainLogo: ReactNode;
|
||||
items: {
|
||||
href: string;
|
||||
icon?: ReactNode;
|
||||
title: string;
|
||||
firstOnRight?: boolean;
|
||||
newTab?: boolean;
|
||||
}[];
|
||||
docNav: ReactNode;
|
||||
}) {
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
const [searchOpen, setSearchOpen] = useState(false);
|
||||
const searchRef = useRef<HTMLInputElement>(null);
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
const [searchOpen, setSearchOpen] = useState(false);
|
||||
const searchRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
searchOpen && searchRef.current?.focus();
|
||||
}, [searchOpen]);
|
||||
useLayoutEffect(() => {
|
||||
searchOpen && searchRef.current?.focus();
|
||||
}, [searchOpen]);
|
||||
|
||||
const pathname = usePathname();
|
||||
const pathname = usePathname();
|
||||
|
||||
return (
|
||||
<>
|
||||
<nav
|
||||
className={[
|
||||
clsx(
|
||||
"hidden md:flex sticky left-0 right-0 top-0 max-sm:bottom-0 w-full justify-center",
|
||||
"bg-stone-50 dark:bg-stone-950 border-b max-sm:border-t border-stone-50 dark:border-b-stone-950",
|
||||
"max-h-none overflow-hidden transition[max-height] duration-300 ease-in-out",
|
||||
"z-50",
|
||||
menuOpen ? "h-[100dvh]" : "h-16"
|
||||
)
|
||||
].join(" ")}
|
||||
return (
|
||||
<>
|
||||
<nav
|
||||
className={cx(
|
||||
"hidden sticky inset-x-0 top-0 max-sm:bottom-0 w-full",
|
||||
"md:flex justify-center z-50",
|
||||
// "bg-stone-50 dark:bg-stone-950 border-b max-sm:border-t border-stone-50 dark:border-b-stone-950",
|
||||
"bg-canvas border-canvas max-sm:border-t",
|
||||
"max-h-none overflow-hidden transition-[max-height] duration-300 ease-in-out",
|
||||
menuOpen ? "h-[100dvh]" : "h-16"
|
||||
)}
|
||||
>
|
||||
<div className="flex flex-wrap px-8 items-center max-sm:justify-between lg:gap-2 max-w-[80rem] w-full">
|
||||
<div className="flex items-center flex-shrink">
|
||||
<NavLinkLogo prominent href="/" className="-ml-2">
|
||||
{mainLogo}
|
||||
</NavLinkLogo>
|
||||
</div>
|
||||
{items.map((item, i) =>
|
||||
"icon" in item ? (
|
||||
<NavLinkLogo key={i} href={item.href} newTab={item.newTab}>
|
||||
{item.icon}
|
||||
</NavLinkLogo>
|
||||
) : (
|
||||
<NavLink
|
||||
key={i}
|
||||
href={item.href}
|
||||
newTab={item.newTab}
|
||||
className={clsx(
|
||||
"max-sm:w-full",
|
||||
item.firstOnRight ? "md:ml-auto" : ""
|
||||
)}
|
||||
>
|
||||
{item.title}
|
||||
</NavLink>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</nav>
|
||||
<div className="flex items-center self-stretch px-4 md:hidden dark:text-white">
|
||||
<NavLinkLogo prominent href="/" className="mr-auto">
|
||||
{mainLogo}
|
||||
</NavLinkLogo>
|
||||
<button
|
||||
className="flex items-center p-3 rounded-xl"
|
||||
onMouseDown={() => {
|
||||
setMenuOpen((o) => !o);
|
||||
setSearchOpen(false);
|
||||
}}
|
||||
>
|
||||
<MenuIcon className="mr-2" />
|
||||
<BreadCrumb items={items} />
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
onClick={() => {
|
||||
setMenuOpen(false);
|
||||
setSearchOpen(false);
|
||||
}}
|
||||
className={clsx(
|
||||
menuOpen || searchOpen ? "block" : "hidden",
|
||||
"fixed top-0 bottom-0 left-0 right-0 bg-stone-200/80 dark:bg-black/80 w-full h-full z-20"
|
||||
)}
|
||||
></div>
|
||||
<nav
|
||||
className={clsx(
|
||||
"md:hidden fixed flex flex-col bottom-4 right-4 z-50",
|
||||
"bg-stone-50 dark:bg-stone-925 dark:text-white border border-stone-100 dark:border-stone-900 dark:outline dark:outline-1 dark:outline-black/60 rounded-lg shadow-lg",
|
||||
menuOpen || searchOpen ? "left-4" : ""
|
||||
)}
|
||||
>
|
||||
<div className={clsx(menuOpen ? "block" : "hidden", " px-2 pb-2")}>
|
||||
<div className="flex items-center w-full border-b border-stone-100 dark:border-stone-900">
|
||||
<NavLinkLogo
|
||||
prominent
|
||||
href="/"
|
||||
className="mr-auto"
|
||||
onClick={() => setMenuOpen(false)}
|
||||
>
|
||||
<div className="flex flex-wrap px-8 items-center max-sm:justify-between lg:gap-2 max-w-[80rem] w-full">
|
||||
<div className="flex items-center flex-shrink">
|
||||
<NavLinkLogo prominent href="/" className="-ml-2">
|
||||
{mainLogo}
|
||||
</NavLinkLogo>
|
||||
</div>
|
||||
{items.map((item, i) =>
|
||||
"icon" in item ? (
|
||||
<NavLinkLogo
|
||||
key={i}
|
||||
href={item.href}
|
||||
newTab={item.newTab}
|
||||
>
|
||||
{item.icon}
|
||||
</NavLinkLogo>
|
||||
) : (
|
||||
<NavLink
|
||||
key={i}
|
||||
href={item.href}
|
||||
newTab={item.newTab}
|
||||
className={clsx(
|
||||
"max-sm:w-full",
|
||||
item.firstOnRight ? "md:ml-auto" : "",
|
||||
)}
|
||||
>
|
||||
{item.title}
|
||||
</NavLink>
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
</nav>
|
||||
<div className="md:hidden px-4 flex items-center self-stretch dark:text-white">
|
||||
<NavLinkLogo prominent href="/" className="mr-auto">
|
||||
{mainLogo}
|
||||
{mainLogo}
|
||||
</NavLinkLogo>
|
||||
{items
|
||||
.filter((item) => "icon" in item)
|
||||
.map((item, i) => (
|
||||
<NavLinkLogo key={i} href={item.href} newTab={item.newTab}>
|
||||
{item.icon}
|
||||
</NavLinkLogo>
|
||||
<button
|
||||
className="flex p-3 rounded-xl items-center"
|
||||
onMouseDown={() => {
|
||||
setMenuOpen((o) => !o);
|
||||
setSearchOpen(false);
|
||||
}}
|
||||
>
|
||||
<MenuIcon className="mr-2" />
|
||||
<BreadCrumb items={items} />
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{pathname === "/docs" && (
|
||||
<div className="max-h-[calc(100dvh-15rem)] p-4 border-b border-stone-100 dark:border-stone-900 overflow-x-auto prose-sm prose-ul:pl-1 prose-ul:ml-1 prose-li:my-2 prose-li:leading-tight prose-ul:list-['-']">
|
||||
{docNav}
|
||||
</div>
|
||||
<div
|
||||
onClick={() => {
|
||||
setMenuOpen(false);
|
||||
setSearchOpen(false);
|
||||
}}
|
||||
className={clsx(
|
||||
menuOpen || searchOpen ? "block" : "hidden",
|
||||
"fixed top-0 bottom-0 left-0 right-0 bg-stone-200/80 dark:bg-black/80 w-full h-full z-20",
|
||||
)}
|
||||
></div>
|
||||
<nav
|
||||
className={clsx(
|
||||
"md:hidden fixed flex flex-col bottom-4 right-4 z-50",
|
||||
"bg-stone-50 dark:bg-stone-925 dark:text-white border border-stone-100 dark:border-stone-900 dark:outline dark:outline-1 dark:outline-black/60 rounded-lg shadow-lg",
|
||||
menuOpen || searchOpen ? "left-4" : "",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(menuOpen ? "block" : "hidden", " px-2 pb-2")}
|
||||
)}
|
||||
|
||||
<div className="flex justify-end gap-4 -mb-2">
|
||||
{items
|
||||
.filter((item) => !("icon" in item))
|
||||
.slice(0, 3)
|
||||
.map((item, i) => (
|
||||
<>
|
||||
<NavLink
|
||||
key={i}
|
||||
href={item.href}
|
||||
onClick={() => setMenuOpen(false)}
|
||||
newTab={item.newTab}
|
||||
>
|
||||
{item.title}
|
||||
</NavLink>
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end gap-4 border-b border-stone-100 dark:border-stone-900">
|
||||
{items
|
||||
.filter((item) => !("icon" in item))
|
||||
.slice(3)
|
||||
.map((item, i) => (
|
||||
<NavLink
|
||||
key={i}
|
||||
href={item.href}
|
||||
onClick={() => setMenuOpen(false)}
|
||||
newTab={item.newTab}
|
||||
className={clsx("")}
|
||||
>
|
||||
<div className="flex items-center w-full border-b border-stone-100 dark:border-stone-900">
|
||||
<NavLinkLogo
|
||||
prominent
|
||||
href="/"
|
||||
className="mr-auto"
|
||||
onClick={() => setMenuOpen(false)}
|
||||
>
|
||||
{mainLogo}
|
||||
</NavLinkLogo>
|
||||
{items
|
||||
.filter((item) => "icon" in item)
|
||||
.map((item, i) => (
|
||||
<NavLinkLogo
|
||||
key={i}
|
||||
href={item.href}
|
||||
newTab={item.newTab}
|
||||
>
|
||||
{item.icon}
|
||||
</NavLinkLogo>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{pathname === "/docs" && (
|
||||
<div className="max-h-[calc(100dvh-15rem)] p-4 border-b border-stone-100 dark:border-stone-900 overflow-x-auto prose-sm prose-ul:pl-1 prose-ul:ml-1 prose-li:my-2 prose-li:leading-tight prose-ul:list-['-']">
|
||||
{docNav}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex gap-4 justify-end -mb-2">
|
||||
{items
|
||||
.filter((item) => !("icon" in item))
|
||||
.slice(0, 3)
|
||||
.map((item, i) => (
|
||||
<>
|
||||
<NavLink
|
||||
key={i}
|
||||
href={item.href}
|
||||
onClick={() => setMenuOpen(false)}
|
||||
newTab={item.newTab}
|
||||
>
|
||||
{item.title}
|
||||
</NavLink>
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex gap-4 justify-end border-b border-stone-100 dark:border-stone-900">
|
||||
{items
|
||||
.filter((item) => !("icon" in item))
|
||||
.slice(3)
|
||||
.map((item, i) => (
|
||||
<NavLink
|
||||
key={i}
|
||||
href={item.href}
|
||||
onClick={() => setMenuOpen(false)}
|
||||
newTab={item.newTab}
|
||||
className={clsx("")}
|
||||
>
|
||||
{item.title}
|
||||
</NavLink>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center self-stretch justify-end">
|
||||
{/* <input
|
||||
{item.title}
|
||||
</NavLink>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center self-stretch justify-end">
|
||||
{/* <input
|
||||
type="text"
|
||||
className={clsx(
|
||||
menuOpen || searchOpen ? "" : "hidden",
|
||||
@@ -184,7 +174,7 @@ export function Nav({
|
||||
placeholder="Search docs..."
|
||||
ref={searchRef}
|
||||
/> */}
|
||||
{/* <button
|
||||
{/* <button
|
||||
className="flex p-3 rounded-xl"
|
||||
onClick={() => {
|
||||
setSearchOpen(true);
|
||||
@@ -197,102 +187,102 @@ export function Nav({
|
||||
>
|
||||
<SearchIcon className="" />
|
||||
</button> */}
|
||||
<button
|
||||
className="flex p-3 rounded-xl items-center"
|
||||
onMouseDown={() => {
|
||||
setMenuOpen((o) => !o);
|
||||
setSearchOpen(false);
|
||||
}}
|
||||
>
|
||||
{menuOpen || searchOpen ? (
|
||||
<XIcon />
|
||||
) : (
|
||||
<>
|
||||
<MenuIcon className="mr-2" />
|
||||
<BreadCrumb items={items} />
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
</>
|
||||
);
|
||||
<button
|
||||
className="flex items-center p-3 rounded-xl"
|
||||
onMouseDown={() => {
|
||||
setMenuOpen((o) => !o);
|
||||
setSearchOpen(false);
|
||||
}}
|
||||
>
|
||||
{menuOpen || searchOpen ? (
|
||||
<XIcon />
|
||||
) : (
|
||||
<>
|
||||
<MenuIcon className="mr-2" />
|
||||
<BreadCrumb items={items} />
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function NavLink({
|
||||
href,
|
||||
className,
|
||||
children,
|
||||
onClick,
|
||||
newTab,
|
||||
href,
|
||||
className,
|
||||
children,
|
||||
onClick,
|
||||
newTab,
|
||||
}: {
|
||||
href: string;
|
||||
className?: string;
|
||||
children: ReactNode;
|
||||
onClick?: () => void;
|
||||
newTab?: boolean;
|
||||
href: string;
|
||||
className?: string;
|
||||
children: ReactNode;
|
||||
onClick?: () => void;
|
||||
newTab?: boolean;
|
||||
}) {
|
||||
const path = usePathname();
|
||||
const path = usePathname();
|
||||
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
className={clsx(
|
||||
"px-2 lg:px-4 py-3 text-sm",
|
||||
className,
|
||||
path === href
|
||||
? "font-medium text-black dark:text-white cursor-default"
|
||||
: "text-stone-600 dark:text-stone-400 hover:text-black dark:hover:text-white transition-colors hover:transition-none",
|
||||
)}
|
||||
onClick={onClick}
|
||||
target={newTab ? "_blank" : undefined}
|
||||
>
|
||||
{children}
|
||||
{newTab ? (
|
||||
<span className="inline-block text-stone-300 dark:text-stone-700 relative -top-0.5 -left-0.5 -mr-2">
|
||||
⌝
|
||||
</span>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</Link>
|
||||
);
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
className={clsx(
|
||||
"px-2 lg:px-4 py-3 text-sm",
|
||||
className,
|
||||
path === href
|
||||
? "font-medium text-black dark:text-white cursor-default"
|
||||
: "text-stone-600 dark:text-stone-400 hover:text-black dark:hover:text-white transition-colors hover:transition-none"
|
||||
)}
|
||||
onClick={onClick}
|
||||
target={newTab ? "_blank" : undefined}
|
||||
>
|
||||
{children}
|
||||
{newTab ? (
|
||||
<span className="inline-block text-stone-300 dark:text-stone-700 relative -top-0.5 -left-0.5 -mr-2">
|
||||
⌝
|
||||
</span>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
function NavLinkLogo({
|
||||
href,
|
||||
className,
|
||||
children,
|
||||
prominent,
|
||||
onClick,
|
||||
newTab,
|
||||
href,
|
||||
className,
|
||||
children,
|
||||
prominent,
|
||||
onClick,
|
||||
newTab,
|
||||
}: {
|
||||
href: string;
|
||||
className?: string;
|
||||
children: ReactNode;
|
||||
prominent?: boolean;
|
||||
onClick?: () => void;
|
||||
newTab?: boolean;
|
||||
href: string;
|
||||
className?: string;
|
||||
children: ReactNode;
|
||||
prominent?: boolean;
|
||||
onClick?: () => void;
|
||||
newTab?: boolean;
|
||||
}) {
|
||||
const path = usePathname();
|
||||
const path = usePathname();
|
||||
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
className={clsx(
|
||||
"max-sm:px-4 px-2 lg:px-3 py-3 transition-opacity hover:transition-none",
|
||||
path === href
|
||||
? "cursor-default"
|
||||
: prominent
|
||||
? "hover:opacity-50"
|
||||
: "opacity-60 hover:opacity-100",
|
||||
"text-black dark:text-white",
|
||||
className,
|
||||
)}
|
||||
onClick={onClick}
|
||||
target={newTab ? "_blank" : undefined}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
className={clsx(
|
||||
"max-sm:px-4 px-2 lg:px-3 py-3 transition-opacity hover:transition-none",
|
||||
path === href
|
||||
? "cursor-default"
|
||||
: prominent
|
||||
? "hover:opacity-50"
|
||||
: "opacity-60 hover:opacity-100",
|
||||
"text-black dark:text-white",
|
||||
className
|
||||
)}
|
||||
onClick={onClick}
|
||||
target={newTab ? "_blank" : undefined}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
/* .manrope-bold {
|
||||
font-family: "Manrope", sans-serif;
|
||||
font-optical-sizing: auto;
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
} */
|
||||
|
||||
:root {
|
||||
--foreground-rgb: 0, 0, 0;
|
||||
--background-start-rgb: 214, 219, 220;
|
||||
--background-end-rgb: 255, 255, 255;
|
||||
|
||||
font-family: "Manrope", sans-serif;
|
||||
font-optical-sizing: auto;
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--foreground-rgb: 255, 255, 255;
|
||||
--background-start-rgb: 0, 0, 0;
|
||||
--background-end-rgb: 0, 0, 0;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
color: rgb(var(--foreground-rgb));
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
transparent,
|
||||
rgb(var(--background-end-rgb))
|
||||
)
|
||||
rgb(var(--background-start-rgb));
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
.text-balance {
|
||||
text-wrap: balance;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Metadata } from 'next';
|
||||
import './globals.css';
|
||||
import type { Metadata } from "next";
|
||||
import "../styles/globals.css";
|
||||
|
||||
import { Manrope } from "next/font/google";
|
||||
import { Inter } from "next/font/google";
|
||||
@@ -21,8 +21,8 @@ const pragmata = localFont({
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Create Next App',
|
||||
description: 'Generated by create next app',
|
||||
title: "Jazz Design System",
|
||||
description: "The Jazz Design System",
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
@@ -32,11 +32,13 @@ export default function RootLayout({
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={[
|
||||
manrope.variable,
|
||||
pragmata.variable,
|
||||
inter.className,
|
||||
].join(" ")}>{children}</body>
|
||||
<body
|
||||
className={[manrope.variable, pragmata.variable, inter.className].join(
|
||||
" "
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
||||
27
homepage/design-system/src/lib/generate-clamp-size.ts
Normal file
27
homepage/design-system/src/lib/generate-clamp-size.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
// const result = generateClampFontSize(500, 1200, 11.5, 14);
|
||||
// console.log(result); // clamp(11.5px, 9.7143px + 0.3571vw, 14px)
|
||||
// prev used: https://clamp.font-size.app/
|
||||
// alt method from klim.co.nz:
|
||||
// w1: "calc(8 / var(--viewport-basis) * 100vw)"
|
||||
|
||||
export function generateClampSize(
|
||||
minViewportWidth: number,
|
||||
maxViewportWidth: number,
|
||||
minFontSize: number,
|
||||
maxFontSize: number
|
||||
): string {
|
||||
const minClampValue = `${minFontSize}px`;
|
||||
const maxClampValue = `${maxFontSize}px`;
|
||||
|
||||
const fontSizeDiff = maxFontSize - minFontSize;
|
||||
const viewportWidthDiff = maxViewportWidth - minViewportWidth;
|
||||
|
||||
const slope = fontSizeDiff / viewportWidthDiff;
|
||||
const yIntercept = minFontSize - slope * minViewportWidth;
|
||||
|
||||
const clampExpression = `${yIntercept.toFixed(4)}px + ${(slope * 100).toFixed(
|
||||
4
|
||||
)}vw`;
|
||||
|
||||
return `clamp(${minClampValue}, ${clampExpression}, ${maxClampValue})`;
|
||||
}
|
||||
19
homepage/design-system/src/styles/base-theme.css
Normal file
19
homepage/design-system/src/styles/base-theme.css
Normal file
@@ -0,0 +1,19 @@
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border;
|
||||
}
|
||||
html {
|
||||
@apply bg-canvas;
|
||||
}
|
||||
::selection {
|
||||
@apply bg-fill text-canvas;
|
||||
}
|
||||
body {
|
||||
@apply font-sans font-normal antialiased;
|
||||
@apply text-base;
|
||||
@apply bg-canvas text-fill;
|
||||
|
||||
/* transition color everywhere: do NOT use tailwind here as the variables are inherited across every transition across the codebase */
|
||||
transition: color 50ms ease 0s;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
.dark,
|
||||
.dark-theme {
|
||||
--stone-950: #fefbf5;
|
||||
--stone-925: #fcf9f2;
|
||||
--stone-900: #f7f3ee;
|
||||
--stone-800: #e7e3de;
|
||||
--stone-700: #d2cec9;
|
||||
--stone-600: #bdbab5;
|
||||
--stone-500: #aaa6a1;
|
||||
--stone-400: #87837f;
|
||||
--stone-300: #6d6965;
|
||||
--stone-200: #4e4a46;
|
||||
--stone-100: #312e2a;
|
||||
--stone-75: #252320;
|
||||
--stone-50: #171411;
|
||||
}
|
||||
|
||||
@supports (color: oklch(0% 0 0)) {
|
||||
@media (color-gamut: p3) {
|
||||
.dark,
|
||||
.dark-theme {
|
||||
--stone-950: oklch(0.988281 0.002 75);
|
||||
--stone-925: oklch(0.980563 0.002 75);
|
||||
--stone-900: oklch(0.964844 0.002 75);
|
||||
--stone-800: oklch(0.917969 0.002 75);
|
||||
--stone-700: oklch(0.853516 0.002 75);
|
||||
/* --stone-700: oklch(0.523438 0.002 75); */
|
||||
--stone-600: oklch(0.789063 0.002 75);
|
||||
--stone-500: oklch(0.726563 0.002 75);
|
||||
--stone-400: oklch(0.613281 0.002 75);
|
||||
--stone-300: oklch(0.523438 0.002 75);
|
||||
--stone-200: oklch(0.412109 0.002 75);
|
||||
--stone-100: oklch(0.302734 0.002 75);
|
||||
--stone-75: oklch(0.22 0.002 75);
|
||||
--stone-50: oklch(0.193359 0.002 75);
|
||||
}
|
||||
}
|
||||
}
|
||||
35
homepage/design-system/src/styles/color-custom-stone.css
Normal file
35
homepage/design-system/src/styles/color-custom-stone.css
Normal file
@@ -0,0 +1,35 @@
|
||||
:root {
|
||||
--stone-50: #fefbf5;
|
||||
--stone-75: #fcf9f2;
|
||||
--stone-100: #f7f3ee;
|
||||
--stone-200: #e7e3de;
|
||||
--stone-300: #d2cec9;
|
||||
--stone-400: #bdbab5;
|
||||
--stone-500: #aaa6a1;
|
||||
--stone-600: #87837f;
|
||||
--stone-700: #6d6965;
|
||||
--stone-800: #4e4a46;
|
||||
--stone-900: #312e2a;
|
||||
--stone-925: #252320;
|
||||
--stone-950: #171411;
|
||||
}
|
||||
|
||||
@supports (color: oklch(0% 0 0)) {
|
||||
@media (color-gamut: p3) {
|
||||
:root {
|
||||
--stone-50: oklch(0.988281 0.002 75);
|
||||
--stone-75: oklch(0.980563 0.002 75);
|
||||
--stone-100: oklch(0.964844 0.002 75);
|
||||
--stone-200: oklch(0.917969 0.002 75);
|
||||
--stone-300: oklch(0.853516 0.002 75);
|
||||
--stone-400: oklch(0.789063 0.002 75);
|
||||
--stone-500: oklch(0.726563 0.002 75);
|
||||
--stone-600: oklch(0.613281 0.002 75);
|
||||
--stone-700: oklch(0.523438 0.002 75);
|
||||
--stone-800: oklch(0.412109 0.002 75);
|
||||
--stone-900: oklch(0.302734 0.002 75);
|
||||
--stone-925: oklch(0.22 0.002 75);
|
||||
--stone-950: oklch(0.193359 0.002 75);
|
||||
}
|
||||
}
|
||||
}
|
||||
42
homepage/design-system/src/styles/color-theme.css
Normal file
42
homepage/design-system/src/styles/color-theme.css
Normal file
@@ -0,0 +1,42 @@
|
||||
@import "./color-custom-stone.css";
|
||||
@import "./color-custom-stone-dark.css";
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
/* GRAY */
|
||||
/* backgrounds & panels */
|
||||
--color-gray-base: var(--stone-50);
|
||||
--color-gray-bg-subtle: var(--stone-75);
|
||||
--color-gray-bg: var(--stone-100);
|
||||
--color-gray-bg-hover: var(--stone-200);
|
||||
--color-gray-bg-active: var(--stone-300);
|
||||
|
||||
/* borders, lines & focus rings */
|
||||
--color-gray-border-light: var(--stone-200);
|
||||
--color-gray-border: var(--stone-300);
|
||||
--color-gray-border-hover: var(--stone-400);
|
||||
--color-gray-line: var(--stone-500);
|
||||
|
||||
/* solids */
|
||||
--color-gray-light: var(--stone-600);
|
||||
--color-gray-solid: var(--stone-700);
|
||||
--color-gray-solid-hover: var(--stone-800);
|
||||
|
||||
/* fills */
|
||||
--color-gray-fill: var(--stone-900);
|
||||
--color-gray-fill-contrast: var(--stone-950);
|
||||
|
||||
/* ACCENT */
|
||||
/* TODO: We'll populate this schema as we need… */
|
||||
--color-accent-fill: #3313f7;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Dark theme variations.
|
||||
Because `.dark` only exists when next-themes renders it,
|
||||
we don't wrap it in `base` b/c we don't want Tailwind to omit it.
|
||||
*/
|
||||
.dark {
|
||||
--color-gray-solid: var(--stone-500);
|
||||
}
|
||||
13
homepage/design-system/src/styles/globals.css
Normal file
13
homepage/design-system/src/styles/globals.css
Normal file
@@ -0,0 +1,13 @@
|
||||
@import "tailwindcss/base";
|
||||
@import "tailwindcss/components";
|
||||
@import "tailwindcss/utilities";
|
||||
@import "./color-theme.css";
|
||||
@import "./space-theme.css";
|
||||
@import "./base-theme.css";
|
||||
|
||||
:root {
|
||||
font-family: "Manrope", sans-serif;
|
||||
font-optical-sizing: auto;
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
}
|
||||
23
homepage/design-system/src/styles/space-theme.css
Normal file
23
homepage/design-system/src/styles/space-theme.css
Normal file
@@ -0,0 +1,23 @@
|
||||
/* @import "@radix-ui/colors/black-alpha.css"; */
|
||||
/* @import "@evilmartians/harmony/css/stone.css"; */
|
||||
@import "./color-custom-stone.css";
|
||||
@import "./color-custom-stone-dark.css";
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--radius: 8px;
|
||||
--height-nav: 80px;
|
||||
--height-tab: 54px;
|
||||
--space-inset: 20px;
|
||||
--space-inset-2x: calc(var(--space-inset) * 2);
|
||||
|
||||
--container-text-px: 660px;
|
||||
--container-text: calc(var(--container-text-px) - (var(--space-inset) * 2));
|
||||
--container-hero-px: 1000px;
|
||||
--container-hero: calc(var(--container-hero-px) - (var(--space-inset) * 2));
|
||||
|
||||
--inset-full: calc((100vw - (var(--space-inset) * 2)));
|
||||
--inset-text: calc((100vw - var(--container-text)) / 2);
|
||||
--inset-hero: calc((100vw - var(--container-hero)) / 2);
|
||||
}
|
||||
}
|
||||
@@ -1,95 +1,221 @@
|
||||
import harmonyPalette from "@evilmartians/harmony/tailwind";
|
||||
import typography from "@tailwindcss/typography";
|
||||
import tailwindCSSAnimate from "tailwindcss-animate";
|
||||
import { generateClampSize } from "./src/lib/generate-clamp-size";
|
||||
|
||||
const lineHeight = {
|
||||
body: `${24 / 17}`,
|
||||
heading: "1.333",
|
||||
title: "1.2",
|
||||
super: "0.98",
|
||||
};
|
||||
const letterSpacing = {
|
||||
meta: "0.02em",
|
||||
body: "0",
|
||||
heading: "-0.01em",
|
||||
super: "-0.03em",
|
||||
};
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
const config = {
|
||||
content: [
|
||||
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
],
|
||||
theme: {
|
||||
colors: {
|
||||
...harmonyPalette,
|
||||
stone: {
|
||||
"50": "oklch(0.988281 0.002 75 / <alpha-value>)",
|
||||
"75": "oklch(0.980563 0.002 75 / <alpha-value>)",
|
||||
"100": "oklch(0.964844 0.002 75 / <alpha-value>)",
|
||||
"200": "oklch(0.917969 0.002 75 / <alpha-value>)",
|
||||
"300": "oklch(0.853516 0.002 75 / <alpha-value>)",
|
||||
"400": "oklch(0.789063 0.002 75 / <alpha-value>)",
|
||||
"500": "oklch(0.726563 0.002 75 / <alpha-value>)",
|
||||
"600": "oklch(0.613281 0.002 75 / <alpha-value>)",
|
||||
"700": "oklch(0.523438 0.002 75 / <alpha-value>)",
|
||||
"800": "oklch(0.412109 0.002 75 / <alpha-value>)",
|
||||
"900": "oklch(0.302734 0.002 75 / <alpha-value>)",
|
||||
"925": "oklch(0.220000 0.002 75 / <alpha-value>)",
|
||||
"950": "oklch(0.193359 0.002 75 / <alpha-value>)",
|
||||
},
|
||||
},
|
||||
extend: {
|
||||
fontFamily: {
|
||||
display: ["var(--font-manrope)"],
|
||||
mono: ["var(--font-ppr)"],
|
||||
},
|
||||
// shadcn-ui
|
||||
colors: {
|
||||
border: "hsl(var(--border))",
|
||||
input: "hsl(var(--input))",
|
||||
ring: "hsl(var(--ring))",
|
||||
background: "hsl(var(--background))",
|
||||
foreground: "hsl(var(--foreground))",
|
||||
primary: {
|
||||
DEFAULT: "hsl(var(--primary))",
|
||||
foreground: "hsl(var(--primary-foreground))",
|
||||
},
|
||||
secondary: {
|
||||
DEFAULT: "hsl(var(--secondary))",
|
||||
foreground: "hsl(var(--secondary-foreground))",
|
||||
},
|
||||
destructive: {
|
||||
DEFAULT: "hsl(var(--destructive))",
|
||||
foreground: "hsl(var(--destructive-foreground))",
|
||||
},
|
||||
muted: {
|
||||
DEFAULT: "hsl(var(--muted))",
|
||||
foreground: "hsl(var(--muted-foreground))",
|
||||
},
|
||||
accent: {
|
||||
DEFAULT: "hsl(var(--accent))",
|
||||
foreground: "hsl(var(--accent-foreground))",
|
||||
},
|
||||
popover: {
|
||||
DEFAULT: "hsl(var(--popover))",
|
||||
foreground: "hsl(var(--popover-foreground))",
|
||||
},
|
||||
card: {
|
||||
DEFAULT: "hsl(var(--card))",
|
||||
foreground: "hsl(var(--card-foreground))",
|
||||
},
|
||||
},
|
||||
borderRadius: {
|
||||
lg: "var(--radius)",
|
||||
md: "calc(var(--radius) - 2px)",
|
||||
sm: "calc(var(--radius) - 4px)",
|
||||
},
|
||||
keyframes: {
|
||||
"accordion-down": {
|
||||
from: { height: "0" },
|
||||
to: { height: "var(--radix-accordion-content-height)" },
|
||||
},
|
||||
"accordion-up": {
|
||||
from: { height: "var(--radix-accordion-content-height)" },
|
||||
to: { height: "0" },
|
||||
},
|
||||
},
|
||||
animation: {
|
||||
"accordion-down": "accordion-down 0.2s ease-out",
|
||||
"accordion-up": "accordion-up 0.2s ease-out",
|
||||
},
|
||||
},
|
||||
content: [
|
||||
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
],
|
||||
darkMode: "selector",
|
||||
theme: {
|
||||
colors: {
|
||||
// DARK SPECTRUM
|
||||
canvas: "var(--color-gray-base)", // avoids name clash with text-base
|
||||
"background-subtle": "var(--color-gray-bg-subtle)",
|
||||
background: "var(--color-gray-bg)",
|
||||
"background-hover": "var(--color-gray-bg-hover)",
|
||||
"background-active": "var(--color-gray-bg-active)",
|
||||
"border-light": "var(--color-gray-border-light)",
|
||||
border: "var(--color-gray-border)",
|
||||
"border-hover": "var(--color-gray-border-hover)",
|
||||
line: "var(--color-gray-line)",
|
||||
"solid-light": "var(--color-gray-light)",
|
||||
solid: "var(--color-gray-solid)",
|
||||
"solid-hover": "var(--color-gray-solid-hover)",
|
||||
"fill-tint": "var(--color-gray-fill)",
|
||||
fill: "var(--color-gray-fill-contrast)",
|
||||
|
||||
// ACCENT SPECTRUM
|
||||
accent: "var(--color-accent-fill)",
|
||||
},
|
||||
plugins: [tailwindCSSAnimate, typography()],
|
||||
fontSize: {
|
||||
xs: [
|
||||
generateClampSize(500, 1200, 9, 11),
|
||||
{ lineHeight: lineHeight.body, letterSpacing: letterSpacing.body },
|
||||
],
|
||||
fine: [
|
||||
generateClampSize(500, 1200, 9, 11),
|
||||
{ lineHeight: lineHeight.body, letterSpacing: letterSpacing.body },
|
||||
],
|
||||
meta: [
|
||||
generateClampSize(500, 1200, 11, 13),
|
||||
{ lineHeight: lineHeight.body, letterSpacing: letterSpacing.body },
|
||||
],
|
||||
small: [
|
||||
generateClampSize(500, 1200, 12, 14),
|
||||
{ lineHeight: lineHeight.body, letterSpacing: letterSpacing.body },
|
||||
],
|
||||
base: [
|
||||
generateClampSize(500, 1200, 14, 16),
|
||||
{ lineHeight: lineHeight.body, letterSpacing: letterSpacing.body },
|
||||
],
|
||||
large: [
|
||||
generateClampSize(500, 1200, 15, 17),
|
||||
{ lineHeight: lineHeight.body, letterSpacing: letterSpacing.body },
|
||||
],
|
||||
lead: [
|
||||
generateClampSize(500, 1200, 17, 20),
|
||||
{
|
||||
lineHeight: lineHeight.body,
|
||||
letterSpacing: letterSpacing.heading,
|
||||
},
|
||||
],
|
||||
subheading: [
|
||||
generateClampSize(500, 1200, 18, 24),
|
||||
{
|
||||
lineHeight: lineHeight.heading,
|
||||
letterSpacing: letterSpacing.heading,
|
||||
},
|
||||
],
|
||||
heading: [
|
||||
generateClampSize(500, 1200, 20, 27),
|
||||
{ lineHeight: lineHeight.title, letterSpacing: letterSpacing.heading },
|
||||
],
|
||||
subtitle: [
|
||||
generateClampSize(500, 1200, 22, 36),
|
||||
{ lineHeight: lineHeight.title, letterSpacing: letterSpacing.heading },
|
||||
],
|
||||
title: [
|
||||
generateClampSize(500, 1200, 27, 42),
|
||||
{ lineHeight: lineHeight.title, letterSpacing: letterSpacing.heading },
|
||||
],
|
||||
subsuper: [
|
||||
generateClampSize(500, 1200, 32, 48),
|
||||
{ lineHeight: lineHeight.super, letterSpacing: letterSpacing.super },
|
||||
],
|
||||
super: [
|
||||
generateClampSize(500, 1200, 39, 60),
|
||||
{ lineHeight: lineHeight.super, letterSpacing: letterSpacing.super },
|
||||
],
|
||||
display: [
|
||||
generateClampSize(500, 1200, 39, 60),
|
||||
{ lineHeight: lineHeight.super, letterSpacing: letterSpacing.super },
|
||||
],
|
||||
},
|
||||
container: {
|
||||
center: true,
|
||||
padding: "var(--space-inset)",
|
||||
screens: {
|
||||
// lg: "var(--container-text)", doesn't take vars WTF?
|
||||
xl: "1280px",
|
||||
},
|
||||
},
|
||||
spacing: {
|
||||
// new default used to mtach icons to font-size
|
||||
em: "1em",
|
||||
|
||||
// insets & heights
|
||||
navH: "var(--height-nav)",
|
||||
tabH: "var(--height-tab)",
|
||||
inset: "var(--space-inset)",
|
||||
"inset-2x": "var(--space-inset-2x)",
|
||||
|
||||
// horizontal containers
|
||||
"text-px": "var(--container-text-px)",
|
||||
text: "var(--container-text)",
|
||||
"hero-px": "var(--container-hero-px)",
|
||||
hero: "var(--container-hero)",
|
||||
mobile: "639px",
|
||||
"inset-full": "var(--inset-full)",
|
||||
"inset-hero": "var(--inset-hero)",
|
||||
"inset-text": "var(--inset-text)",
|
||||
|
||||
// lower value is 2/3 of upper value
|
||||
d4: generateClampSize(500, 1200, 10.5, 16),
|
||||
d6: generateClampSize(500, 1200, 16, 24),
|
||||
d8: generateClampSize(500, 1200, 21, 32),
|
||||
d12: generateClampSize(500, 1200, 32, 48),
|
||||
d16: generateClampSize(500, 1200, 43, 64),
|
||||
d20: generateClampSize(500, 1200, 54, 80),
|
||||
d24: generateClampSize(500, 1200, 64, 96),
|
||||
d28: generateClampSize(500, 1200, 75, 112),
|
||||
d32: generateClampSize(500, 1200, 85, 128),
|
||||
d36: generateClampSize(500, 1200, 96, 144),
|
||||
d42: generateClampSize(500, 1200, 112, 168),
|
||||
d48: generateClampSize(500, 1200, 128, 192),
|
||||
d64: generateClampSize(500, 1200, 171, 256),
|
||||
d72: generateClampSize(500, 1200, 192, 288),
|
||||
d96: generateClampSize(500, 1200, 256, 384),
|
||||
|
||||
// Tailwind defaults: we need to import these here because we're creating a new theme, not extending it
|
||||
px: "1px",
|
||||
0: "0px",
|
||||
0.5: "0.125rem",
|
||||
1: "0.25rem",
|
||||
1.5: "0.375rem",
|
||||
2: "0.5rem",
|
||||
2.5: "0.625rem",
|
||||
3: "0.75rem",
|
||||
3.5: "0.875rem",
|
||||
4: "1rem",
|
||||
5: "1.25rem",
|
||||
6: "1.5rem",
|
||||
7: "1.75rem",
|
||||
8: "2rem",
|
||||
9: "2.25rem",
|
||||
10: "2.5rem",
|
||||
11: "2.75rem",
|
||||
12: "3rem",
|
||||
14: "3.5rem",
|
||||
16: "4rem",
|
||||
20: "5rem",
|
||||
24: "6rem",
|
||||
28: "7rem",
|
||||
32: "8rem",
|
||||
36: "9rem",
|
||||
40: "10rem",
|
||||
44: "11rem",
|
||||
48: "12rem",
|
||||
52: "13rem",
|
||||
56: "14rem",
|
||||
60: "15rem",
|
||||
64: "16rem",
|
||||
72: "18rem",
|
||||
80: "20rem",
|
||||
96: "24rem",
|
||||
},
|
||||
extend: {
|
||||
fontFamily: {
|
||||
display: ["var(--font-manrope)"],
|
||||
mono: ["var(--font-ppr)"],
|
||||
},
|
||||
borderRadius: {
|
||||
lg: "var(--radius)",
|
||||
md: "calc(var(--radius) - 2px)",
|
||||
sm: "calc(var(--radius) - 4px)",
|
||||
},
|
||||
keyframes: {
|
||||
"accordion-down": {
|
||||
from: { height: "0" },
|
||||
to: { height: "var(--radix-accordion-content-height)" },
|
||||
},
|
||||
"accordion-up": {
|
||||
from: { height: "var(--radix-accordion-content-height)" },
|
||||
to: { height: "0" },
|
||||
},
|
||||
},
|
||||
animation: {
|
||||
"accordion-down": "accordion-down 0.2s ease-out",
|
||||
"accordion-up": "accordion-up 0.2s ease-out",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [tailwindCSSAnimate, typography()],
|
||||
};
|
||||
export default config;
|
||||
|
||||
@@ -15,6 +15,7 @@ import { UL } from "gcmp-design-system/src/app/components/molecules/List";
|
||||
import { LI } from "gcmp-design-system/src/app/components/atoms/ListItem";
|
||||
import { P } from "gcmp-design-system/src/app/components/atoms/Paragraph";
|
||||
import { TextLink } from "gcmp-design-system/src/app/components/atoms/TextLink";
|
||||
import { GroupWithSpace } from "gcmp-design-system/src/app/components/atoms";
|
||||
|
||||
import {
|
||||
UploadCloudIcon,
|
||||
@@ -54,63 +55,64 @@ import { H3 } from "gcmp-design-system/src/app/components/atoms/Headings";
|
||||
export default function Home() {
|
||||
return (
|
||||
<>
|
||||
<HeroHeader
|
||||
title="Instant sync."
|
||||
slogan="A new way to build apps with distributed state."
|
||||
/>
|
||||
<GroupWithSpace as="section" vertical="minor">
|
||||
<HeroHeader
|
||||
title="Instant sync."
|
||||
slogan="A new way to build apps with distributed state."
|
||||
/>
|
||||
<HairlineBleedGrid>
|
||||
<LabelledFeatureIcon
|
||||
label="Cross-device sync"
|
||||
icon={MonitorSmartphoneIcon}
|
||||
/>
|
||||
<LabelledFeatureIcon
|
||||
label="Real-time multiplayer"
|
||||
icon={SquareMousePointerIcon}
|
||||
/>
|
||||
<LabelledFeatureIcon
|
||||
label="Team/social features"
|
||||
icon={UsersIcon}
|
||||
/>
|
||||
<LabelledFeatureIcon
|
||||
label="Built-in permissions"
|
||||
icon={FileLock2Icon}
|
||||
/>
|
||||
<LabelledFeatureIcon
|
||||
label="Cloud sync & storage"
|
||||
icon={UploadCloudIcon}
|
||||
/>
|
||||
<LabelledFeatureIcon
|
||||
label="On-device storage"
|
||||
icon={HardDriveDownloadIcon}
|
||||
/>
|
||||
<LabelledFeatureIcon
|
||||
label="Instant UI updates"
|
||||
icon={GaugeIcon}
|
||||
/>
|
||||
<LabelledFeatureIcon
|
||||
label="E2EE & signatures"
|
||||
icon={KeyRoundIcon}
|
||||
/>
|
||||
|
||||
<HairlineBleedGrid>
|
||||
<LabelledFeatureIcon
|
||||
label="Cross-device sync"
|
||||
icon={MonitorSmartphoneIcon}
|
||||
/>
|
||||
<LabelledFeatureIcon
|
||||
label="Real-time multiplayer"
|
||||
icon={SquareMousePointerIcon}
|
||||
/>
|
||||
<LabelledFeatureIcon
|
||||
label="Team/social features"
|
||||
icon={UsersIcon}
|
||||
/>
|
||||
<LabelledFeatureIcon
|
||||
label="Built-in permissions"
|
||||
icon={FileLock2Icon}
|
||||
/>
|
||||
<LabelledFeatureIcon
|
||||
label="Cloud sync & storage"
|
||||
icon={UploadCloudIcon}
|
||||
/>
|
||||
<LabelledFeatureIcon
|
||||
label="On-device storage"
|
||||
icon={HardDriveDownloadIcon}
|
||||
/>
|
||||
<LabelledFeatureIcon
|
||||
label="Instant UI updates"
|
||||
icon={GaugeIcon}
|
||||
/>
|
||||
<LabelledFeatureIcon
|
||||
label="E2EE & signatures"
|
||||
icon={KeyRoundIcon}
|
||||
/>
|
||||
<div className="col-span-2 col-start-1 row-span-2 row-start-1 px-4 pb-4 text-base md:px-6">
|
||||
<Prose>
|
||||
<Intro />
|
||||
</Prose>
|
||||
</div>
|
||||
</HairlineBleedGrid>
|
||||
</GroupWithSpace>
|
||||
|
||||
<div className="col-start-1 row-start-1 row-span-2 col-span-2 px-4 md:px-6 pb-4 text-base">
|
||||
<Prose>
|
||||
<Intro />
|
||||
</Prose>
|
||||
</div>
|
||||
</HairlineBleedGrid>
|
||||
|
||||
<div className="-mx-[calc(min(0,(100vw-95rem)/2))]">
|
||||
<GroupWithSpace as="section" vertical="minor">
|
||||
<SectionHeader
|
||||
title="First impressions..."
|
||||
slogan="A chat app in 84 lines of code."
|
||||
/>
|
||||
|
||||
<GappedGrid className="mt-0 -mx-4 md:-mx-6">
|
||||
<div className="md:col-start-1 col-span-2">
|
||||
<div className="col-span-2 md:col-start-1">
|
||||
<App_tsx />
|
||||
</div>
|
||||
<div className="md:col-start-3 col-span-2">
|
||||
<div className="col-span-2 md:col-start-3">
|
||||
<ChatScreen_tsx />
|
||||
</div>
|
||||
<ResponsiveIframe
|
||||
@@ -119,102 +121,108 @@ export default function Home() {
|
||||
className="lg:col-start-5 col-span-2 rounded-xl overflow-hidden min-h-[50vh]"
|
||||
/>
|
||||
</GappedGrid>
|
||||
</div>
|
||||
</GroupWithSpace>
|
||||
|
||||
<SectionHeader
|
||||
title="Collaborative Values"
|
||||
slogan="Your new building blocks."
|
||||
/>
|
||||
<Prose>
|
||||
<CoValuesIntro />
|
||||
</Prose>
|
||||
<GroupWithSpace as="section" vertical="minor">
|
||||
<SectionHeader
|
||||
title="Collaborative Values"
|
||||
slogan="Your new building blocks."
|
||||
/>
|
||||
<Prose>
|
||||
<CoValuesIntro />
|
||||
</Prose>
|
||||
|
||||
<GappedGrid
|
||||
title="Bread-and-butter datastructures"
|
||||
className="grid-cols-2 lg:grid-cols-4"
|
||||
>
|
||||
<GridCard>
|
||||
<H3>
|
||||
<CodeRef>CoMap</CodeRef>
|
||||
</H3>
|
||||
<SmallProse>
|
||||
<CoMapDescription />
|
||||
</SmallProse>
|
||||
</GridCard>
|
||||
<GappedGrid
|
||||
title="Bread-and-butter datastructures"
|
||||
className="grid-cols-2 lg:grid-cols-4"
|
||||
>
|
||||
<GridCard>
|
||||
<H3>
|
||||
<CodeRef>CoMap</CodeRef>
|
||||
</H3>
|
||||
<SmallProse>
|
||||
<CoMapDescription />
|
||||
</SmallProse>
|
||||
</GridCard>
|
||||
|
||||
<GridCard>
|
||||
<H3>
|
||||
<CodeRef>CoList</CodeRef>
|
||||
</H3>
|
||||
<SmallProse>
|
||||
<CoListDescription />
|
||||
</SmallProse>
|
||||
</GridCard>
|
||||
<GridCard>
|
||||
<H3>
|
||||
<CodeRef>CoList</CodeRef>
|
||||
</H3>
|
||||
<SmallProse>
|
||||
<CoListDescription />
|
||||
</SmallProse>
|
||||
</GridCard>
|
||||
|
||||
<GridCard>
|
||||
<H3>
|
||||
<CodeRef>CoPlainText</CodeRef> &{" "}
|
||||
<CodeRef>CoRichText</CodeRef> <ComingSoonBadge />
|
||||
</H3>
|
||||
<SmallProse>
|
||||
<CoPlainTextDescription />
|
||||
</SmallProse>
|
||||
</GridCard>
|
||||
<GridCard>
|
||||
<H3>
|
||||
<CodeRef>CoPlainText</CodeRef> &{" "}
|
||||
<CodeRef>CoRichText</CodeRef> <ComingSoonBadge />
|
||||
</H3>
|
||||
<SmallProse>
|
||||
<CoPlainTextDescription />
|
||||
</SmallProse>
|
||||
</GridCard>
|
||||
|
||||
<GridCard>
|
||||
<H3>
|
||||
<CodeRef>CoStream</CodeRef>
|
||||
</H3>
|
||||
<SmallProse>
|
||||
<CoStreamDescription />
|
||||
</SmallProse>
|
||||
</GridCard>
|
||||
</GappedGrid>
|
||||
<GridCard>
|
||||
<H3>
|
||||
<CodeRef>CoStream</CodeRef>
|
||||
</H3>
|
||||
<SmallProse>
|
||||
<CoStreamDescription />
|
||||
</SmallProse>
|
||||
</GridCard>
|
||||
</GappedGrid>
|
||||
</GroupWithSpace>
|
||||
|
||||
<GappedGrid
|
||||
title="First-class files & binary data"
|
||||
className="grid-cols-2 lg:grid-cols-4"
|
||||
>
|
||||
<GridCard>
|
||||
<H3>
|
||||
<CodeRef>BinaryCoStream</CodeRef>
|
||||
</H3>
|
||||
<SmallProse>
|
||||
<BinaryCoStreamDescription />
|
||||
</SmallProse>
|
||||
</GridCard>
|
||||
<GroupWithSpace as="section" vertical="minor">
|
||||
<GappedGrid
|
||||
title="First-class files & binary data"
|
||||
className="grid-cols-2 lg:grid-cols-4"
|
||||
>
|
||||
<GridCard>
|
||||
<H3>
|
||||
<CodeRef>BinaryCoStream</CodeRef>
|
||||
</H3>
|
||||
<SmallProse>
|
||||
<BinaryCoStreamDescription />
|
||||
</SmallProse>
|
||||
</GridCard>
|
||||
|
||||
<GridCard>
|
||||
<H3>
|
||||
<CodeRef>ImageDefinition</CodeRef>
|
||||
</H3>
|
||||
<SmallProse>
|
||||
<ImageDefinitionDescription />
|
||||
</SmallProse>
|
||||
</GridCard>
|
||||
</GappedGrid>
|
||||
<GridCard>
|
||||
<H3>
|
||||
<CodeRef>ImageDefinition</CodeRef>
|
||||
</H3>
|
||||
<SmallProse>
|
||||
<ImageDefinitionDescription />
|
||||
</SmallProse>
|
||||
</GridCard>
|
||||
</GappedGrid>
|
||||
</GroupWithSpace>
|
||||
|
||||
<GappedGrid
|
||||
title="Secure permissions, authorship & teams"
|
||||
className="grid-cols-2 lg:grid-cols-4"
|
||||
>
|
||||
<GridCard>
|
||||
<H3>
|
||||
<CodeRef>Group</CodeRef>
|
||||
</H3>
|
||||
<SmallProse>
|
||||
<GroupDescription />
|
||||
</SmallProse>
|
||||
</GridCard>
|
||||
<GridCard>
|
||||
<H3>
|
||||
<CodeRef>Account</CodeRef>
|
||||
</H3>
|
||||
<SmallProse>
|
||||
<AccountDescription />
|
||||
</SmallProse>
|
||||
</GridCard>
|
||||
</GappedGrid>
|
||||
<GroupWithSpace as="section" vertical="minor">
|
||||
<GappedGrid
|
||||
title="Secure permissions, authorship & teams"
|
||||
className="grid-cols-2 lg:grid-cols-4"
|
||||
>
|
||||
<GridCard>
|
||||
<H3>
|
||||
<CodeRef>Group</CodeRef>
|
||||
</H3>
|
||||
<SmallProse>
|
||||
<GroupDescription />
|
||||
</SmallProse>
|
||||
</GridCard>
|
||||
<GridCard>
|
||||
<H3>
|
||||
<CodeRef>Account</CodeRef>
|
||||
</H3>
|
||||
<SmallProse>
|
||||
<AccountDescription />
|
||||
</SmallProse>
|
||||
</GridCard>
|
||||
</GappedGrid>
|
||||
</GroupWithSpace>
|
||||
|
||||
<SectionHeader
|
||||
title="The Jazz Toolkit"
|
||||
@@ -293,32 +301,42 @@ export default function Home() {
|
||||
</GridCard>
|
||||
</GappedGrid>
|
||||
|
||||
<SectionHeader
|
||||
title="Jazz Mesh"
|
||||
slogan="Serverless sync & storage for Jazz apps"
|
||||
/>
|
||||
<GroupWithSpace as="section" vertical="minor">
|
||||
<SectionHeader
|
||||
title="Jazz Mesh"
|
||||
slogan="Serverless sync & storage for Jazz apps"
|
||||
/>
|
||||
|
||||
<Prose>
|
||||
<MeshIntro />
|
||||
</Prose>
|
||||
<Prose>
|
||||
<MeshIntro />
|
||||
</Prose>
|
||||
|
||||
<P>{'->'} <TextLink href="/mesh" target="_blank">
|
||||
Learn more about Jazz Mesh
|
||||
</TextLink></P>
|
||||
|
||||
<H3>Get Started</H3>
|
||||
<UL>
|
||||
<LI>
|
||||
<TextLink href="/docs" target="_blank">
|
||||
Read the docs
|
||||
<P>
|
||||
{"->"}{" "}
|
||||
<TextLink href="/mesh" target="_blank">
|
||||
Learn more about Jazz Mesh
|
||||
</TextLink>
|
||||
</LI>
|
||||
<LI>
|
||||
<TextLink href="https://discord.gg/utDMjHYg42" target="_blank">
|
||||
Join our Discord
|
||||
</TextLink>
|
||||
</LI>
|
||||
</UL>
|
||||
</P>
|
||||
</GroupWithSpace>
|
||||
|
||||
<GroupWithSpace as="section" vertical="minor">
|
||||
<H3>Get Started</H3>
|
||||
<UL>
|
||||
<LI>
|
||||
<TextLink href="/docs" target="_blank">
|
||||
Read the docs
|
||||
</TextLink>
|
||||
</LI>
|
||||
<LI>
|
||||
<TextLink
|
||||
href="https://discord.gg/utDMjHYg42"
|
||||
target="_blank"
|
||||
>
|
||||
Join our Discord
|
||||
</TextLink>
|
||||
</LI>
|
||||
</UL>
|
||||
</GroupWithSpace>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,418 +1,21 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@import "tailwindcss/base";
|
||||
@import "tailwindcss/components";
|
||||
@import "tailwindcss/utilities";
|
||||
@import "gcmp-design-system/src/styles/color-theme.css";
|
||||
@import "gcmp-design-system/src/styles/space-theme.css";
|
||||
@import "gcmp-design-system/src/styles/base-theme.css";
|
||||
@import "../styles/code-theme.css";
|
||||
|
||||
@layer base, shiki;
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 20 14.3% 4.1%;
|
||||
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 20 14.3% 4.1%;
|
||||
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 20 14.3% 4.1%;
|
||||
|
||||
--primary: 24 9.8% 10%;
|
||||
--primary-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--secondary: 60 4.8% 95.9%;
|
||||
--secondary-foreground: 24 9.8% 10%;
|
||||
|
||||
--muted: 60 4.8% 95.9%;
|
||||
--muted-foreground: 25 5.3% 44.7%;
|
||||
|
||||
--accent: 60 4.8% 95.9%;
|
||||
--accent-foreground: 24 9.8% 10%;
|
||||
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--border: 20 5.9% 90%;
|
||||
--input: 20 5.9% 90%;
|
||||
--ring: 20 14.3% 4.1%;
|
||||
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 20 14.3% 4.1%;
|
||||
--foreground: 60 9.1% 97.8%;
|
||||
|
||||
--card: 20 14.3% 4.1%;
|
||||
--card-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--popover: 20 14.3% 4.1%;
|
||||
--popover-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--primary: 60 9.1% 97.8%;
|
||||
--primary-foreground: 24 9.8% 10%;
|
||||
|
||||
--secondary: 12 6.5% 15.1%;
|
||||
--secondary-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--muted: 12 6.5% 15.1%;
|
||||
--muted-foreground: 24 5.4% 63.9%;
|
||||
|
||||
--accent: 12 6.5% 15.1%;
|
||||
--accent-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 60 9.1% 97.8%;
|
||||
|
||||
--border: 12 6.5% 15.1%;
|
||||
--input: 12 6.5% 15.1%;
|
||||
--ring: 24 5.7% 82.9%;
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
.overlay-close {
|
||||
background-color: "black";
|
||||
@apply bg-fill-contrast;
|
||||
}
|
||||
}
|
||||
|
||||
pre.shiki {
|
||||
overflow: hidden;
|
||||
}
|
||||
pre.shiki:hover .dim {
|
||||
opacity: 1;
|
||||
}
|
||||
pre.shiki div.dim {
|
||||
opacity: 0.5;
|
||||
}
|
||||
pre.shiki div.dim,
|
||||
pre.shiki div.highlight {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
pre.shiki div.highlight {
|
||||
opacity: 1;
|
||||
background-color: #f1f8ff;
|
||||
}
|
||||
pre.shiki div.line {
|
||||
/* min-height: 1rem; */
|
||||
counter-increment: lineNumber 1;
|
||||
}
|
||||
|
||||
pre.shiki div.line::before {
|
||||
content: counter(lineNumber);
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 1.3rem;
|
||||
padding-right: 0.3rem;
|
||||
text-align: right;
|
||||
transition: color 0.3s;
|
||||
@apply text-stone-200/50 dark:text-stone-900 text-[0.65rem];
|
||||
}
|
||||
|
||||
pre.shiki div.line:hover::before {
|
||||
@apply text-stone-400 dark:text-stone-600;
|
||||
}
|
||||
|
||||
/** Don't show the language identifiers */
|
||||
pre.shiki .language-id {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/** When you mouse over the pre, show the underlines */
|
||||
pre.twoslash:hover data-lsp {
|
||||
@apply border-dotted border-b border-stone-300 dark:border-stone-700;
|
||||
}
|
||||
|
||||
/** The tooltip-like which provides the LSP response */
|
||||
pre.twoslash data-lsp::before {
|
||||
content: attr(lsp);
|
||||
position: absolute;
|
||||
transform: translate(0, 1.2rem);
|
||||
max-width: 30rem;
|
||||
@apply text-xs px-1.5 py-1 rounded border border-stone-200 dark:border-stone-800 shadow-lg overflow-hidden whitespace-pre-wrap text-stone-700 bg-stone-50 dark:text-stone-200 dark:bg-stone-950;
|
||||
text-align: left;
|
||||
z-index: 100;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
pointer-events: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
pre.twoslash data-lsp:hover::before {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
pointer-events: visible;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.shiki-outer {
|
||||
@apply shadow-sm rounded-xl;
|
||||
}
|
||||
|
||||
.shiki-filename {
|
||||
@apply px-3 py-2 bg-stone-100 text-stone-700 dark:bg-stone-900 dark:text-stone-300 rounded-t-xl text-xs;
|
||||
}
|
||||
|
||||
pre .code-container {
|
||||
overflow: scroll;
|
||||
@apply p-2 pl-0 bg-stone-75 dark:bg-stone-925 rounded-b-xl text-[0.8rem] leading-tight border border-stone-100 dark:border-stone-900;
|
||||
}
|
||||
/* The try button */
|
||||
pre .code-container > a {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
bottom: 8px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #719af4;
|
||||
padding: 0 8px;
|
||||
color: #719af4;
|
||||
text-decoration: none;
|
||||
opacity: 0;
|
||||
transition-timing-function: ease;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
/* Respect no animations */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
pre .code-container > a {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
pre .code-container > a:hover {
|
||||
color: white;
|
||||
background-color: #719af4;
|
||||
}
|
||||
pre .code-container:hover a {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
pre code {
|
||||
white-space: pre;
|
||||
}
|
||||
pre code a {
|
||||
text-decoration: none;
|
||||
}
|
||||
pre data-err {
|
||||
/* Extracted from VS Code */
|
||||
background: url("data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%206%203'%20enable-background%3D'new%200%200%206%203'%20height%3D'3'%20width%3D'6'%3E%3Cg%20fill%3D'%23c94824'%3E%3Cpolygon%20points%3D'5.5%2C0%202.5%2C3%201.1%2C3%204.1%2C0'%2F%3E%3Cpolygon%20points%3D'4%2C0%206%2C2%206%2C0.6%205.4%2C0'%2F%3E%3Cpolygon%20points%3D'0%2C2%201%2C3%202.4%2C3%200%2C0.6'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")
|
||||
repeat-x bottom left;
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
pre .query {
|
||||
margin-bottom: 10px;
|
||||
color: #137998;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* In order to have the 'popped out' style design and to not break the layout
|
||||
/* we need to place a fake and un-selectable copy of the error which _isn't_ broken out
|
||||
/* behind the actual error message.
|
||||
|
||||
/* This sections keeps both of those two in in sync */
|
||||
|
||||
pre .error,
|
||||
pre .error-behind {
|
||||
margin-left: -14px;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 4px;
|
||||
padding: 6px;
|
||||
padding-left: 14px;
|
||||
width: calc(100% - 20px);
|
||||
white-space: pre-wrap;
|
||||
display: block;
|
||||
}
|
||||
pre .error {
|
||||
position: absolute;
|
||||
background-color: #fee;
|
||||
border-left: 2px solid #bf1818;
|
||||
/* Give the space to the error code */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: black;
|
||||
}
|
||||
pre .error .code {
|
||||
display: none;
|
||||
}
|
||||
pre .error-behind {
|
||||
user-select: none;
|
||||
visibility: transparent;
|
||||
color: #fee;
|
||||
}
|
||||
/* Queries */
|
||||
pre .arrow {
|
||||
/* Transparent background */
|
||||
background-color: #eee;
|
||||
position: relative;
|
||||
top: -7px;
|
||||
margin-left: 0.1rem;
|
||||
/* Edges */
|
||||
border-left: 1px solid #eee;
|
||||
border-top: 1px solid #eee;
|
||||
transform: translateY(25%) rotate(45deg);
|
||||
/* Size */
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
}
|
||||
pre .popover {
|
||||
margin-bottom: 10px;
|
||||
background-color: #eee;
|
||||
display: inline-block;
|
||||
padding: 0 0.5rem 0.3rem;
|
||||
margin-top: 10px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
/* Completion */
|
||||
pre .inline-completions ul.dropdown {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
width: 240px;
|
||||
background-color: gainsboro;
|
||||
color: grey;
|
||||
padding-top: 4px;
|
||||
font-family: var(--code-font);
|
||||
font-size: 0.8rem;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border-left: 4px solid #4b9edd;
|
||||
}
|
||||
pre .inline-completions ul.dropdown::before {
|
||||
background-color: #4b9edd;
|
||||
width: 2px;
|
||||
position: absolute;
|
||||
top: -1.2rem;
|
||||
left: -3px;
|
||||
content: " ";
|
||||
}
|
||||
pre .inline-completions ul.dropdown li {
|
||||
overflow-x: hidden;
|
||||
padding-left: 4px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
pre .inline-completions ul.dropdown li.deprecated {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
pre .inline-completions ul.dropdown li span.result-found {
|
||||
color: #4b9edd;
|
||||
}
|
||||
pre .inline-completions ul.dropdown li span.result {
|
||||
width: 100px;
|
||||
color: black;
|
||||
display: inline-block;
|
||||
}
|
||||
.dark-theme .markdown pre {
|
||||
background-color: #d8d8d8;
|
||||
border-color: #ddd;
|
||||
filter: invert(98%) hue-rotate(180deg);
|
||||
}
|
||||
data-lsp {
|
||||
/* Ensures there's no 1px jump when the hover happens */
|
||||
border-bottom: 1px dotted transparent;
|
||||
/* Fades in unobtrusively */
|
||||
transition-timing-function: ease;
|
||||
transition: border-color 0.3s;
|
||||
}
|
||||
/* Respect people's wishes to not have animations */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
data-lsp {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
/** Annotations support, providing a tool for meta commentary */
|
||||
.tag-container {
|
||||
position: relative;
|
||||
}
|
||||
.tag-container .twoslash-annotation {
|
||||
position: absolute;
|
||||
font-family:
|
||||
"JetBrains Mono",
|
||||
Menlo,
|
||||
Monaco,
|
||||
Consolas,
|
||||
Courier New,
|
||||
monospace;
|
||||
right: -10px;
|
||||
/** Default annotation text to 200px */
|
||||
width: 200px;
|
||||
color: #187abf;
|
||||
background-color: #fcf3d9 bb;
|
||||
}
|
||||
.tag-container .twoslash-annotation p {
|
||||
text-align: left;
|
||||
font-size: 0.8rem;
|
||||
line-height: 0.9rem;
|
||||
}
|
||||
.tag-container .twoslash-annotation svg {
|
||||
float: left;
|
||||
margin-left: -44px;
|
||||
}
|
||||
.tag-container .twoslash-annotation.left {
|
||||
right: auto;
|
||||
left: -200px;
|
||||
}
|
||||
.tag-container .twoslash-annotation.left svg {
|
||||
float: right;
|
||||
margin-right: -5px;
|
||||
}
|
||||
|
||||
/** Support for showing console log/warn/errors inline */
|
||||
pre .logger {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: black;
|
||||
padding: 6px;
|
||||
padding-left: 8px;
|
||||
width: calc(100% - 19px);
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
pre .logger svg {
|
||||
margin-right: 9px;
|
||||
}
|
||||
pre .logger.error-log {
|
||||
background-color: #fee;
|
||||
border-left: 2px solid #bf1818;
|
||||
}
|
||||
pre .logger.warn-log {
|
||||
background-color: #ffe;
|
||||
border-left: 2px solid #eae662;
|
||||
}
|
||||
pre .logger.log-log {
|
||||
background-color: #e9e9e9;
|
||||
border-left: 2px solid #ababab;
|
||||
}
|
||||
pre .logger.log-log svg {
|
||||
margin-left: 6px;
|
||||
margin-right: 9px;
|
||||
}
|
||||
|
||||
body {
|
||||
--shiki-color-text: #606060;
|
||||
--shiki-color-background: transparent;
|
||||
--shiki-token-constant: #00a5a5;
|
||||
--shiki-token-string: #4e3a2c;
|
||||
--shiki-token-comment: #aaa;
|
||||
--shiki-token-keyword: #7b8bff;
|
||||
--shiki-token-parameter: #ff9800;
|
||||
--shiki-token-function: #445dd7;
|
||||
--shiki-token-string-expression: #38a35f;
|
||||
--shiki-token-punctuation: #969696;
|
||||
--shiki-token-link: #1aa245;
|
||||
}
|
||||
|
||||
.dark body {
|
||||
--shiki-color-text: #d1d1d1;
|
||||
--shiki-token-constant: #2dc9c9;
|
||||
--shiki-token-string: #feb179;
|
||||
--shiki-token-comment: #6b737c;
|
||||
--shiki-token-keyword: #7b8bff;
|
||||
--shiki-token-parameter: #ff9800;
|
||||
--shiki-token-function: #9babff;
|
||||
--shiki-token-string-expression: #42bb69;
|
||||
--shiki-token-punctuation: #bbb;
|
||||
--shiki-token-link: #ffab70;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import { SpeedInsights } from "@vercel/speed-insights/next";
|
||||
import { Analytics } from "@vercel/analytics/react";
|
||||
import { JazzNav } from "@/components/docs/nav";
|
||||
import { JazzFooter } from "@/components/docs/footer";
|
||||
import { spaceVariants } from "gcmp-design-system/src/app/components/atoms";
|
||||
import { cx } from "class-variance-authority";
|
||||
|
||||
// If loading a variable font, you don't need to specify the font weight
|
||||
const manrope = Manrope({
|
||||
@@ -44,7 +46,7 @@ export default function RootLayout({
|
||||
manrope.variable,
|
||||
pragmata.variable,
|
||||
inter.className,
|
||||
"flex flex-col items-center bg-stone-50 dark:bg-stone-950 overflow-x-hidden",
|
||||
"flex flex-col items-center overflow-x-hidden",
|
||||
].join(" ")}
|
||||
>
|
||||
<SpeedInsights />
|
||||
@@ -56,7 +58,14 @@ export default function RootLayout({
|
||||
disableTransitionOnChange
|
||||
>
|
||||
<JazzNav />
|
||||
<main className="flex min-h-screen flex-col p-8 max-w-[80rem] w-full [&_*]:scroll-mt-[6rem]">
|
||||
<main
|
||||
className={cx(
|
||||
spaceVariants({
|
||||
vertical: "major",
|
||||
}),
|
||||
"py-d16",
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</main>
|
||||
<JazzFooter />
|
||||
|
||||
@@ -136,7 +136,7 @@ export function DocNav() {
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p className="font-medium border-t -mx-4 px-4 pt-4 border-stone-200 dark:border-stone-800">
|
||||
<p className="px-4 pt-4 -mx-4 font-medium border-t border-stone-200 dark:border-stone-800">
|
||||
<DocNavLink href="#faq">FAQ</DocNavLink>
|
||||
</p>
|
||||
|
||||
@@ -158,7 +158,7 @@ export async function NavPackage({
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2 className="text-sm mt-4 flex gap-1 items-center -mx-4 px-4 pt-4 border-t border-stone-200 dark:border-stone-800 ">
|
||||
<h2 className="flex items-center gap-1 px-4 pt-4 mt-4 -mx-4 text-sm border-t border-background-hover">
|
||||
<code className="font-bold">{packageName}</code>{" "}
|
||||
<PackageIcon size={15} strokeWidth={1.5} />
|
||||
</h2>
|
||||
@@ -169,7 +169,7 @@ export async function NavPackage({
|
||||
open={category.title !== "Other"}
|
||||
className="[&:not([open])_summary]:after:content-['...']"
|
||||
>
|
||||
<summary className="block text-xs mt-2 cursor-pointer">
|
||||
<summary className="block mt-2 text-xs cursor-pointer">
|
||||
{category.title}
|
||||
</summary>
|
||||
<div className="text-sm -ml-0.5 max-w-full text-balance">
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
},
|
||||
"packageManager": "pnpm@9.1.4",
|
||||
"dependencies": {
|
||||
"gcmp-design-system": "workspace:*",
|
||||
"@icons-pack/react-simple-icons": "^9.1.0",
|
||||
"@mdx-js/loader": "^2.3.0",
|
||||
"@mdx-js/react": "^2.3.0",
|
||||
@@ -24,6 +23,8 @@
|
||||
"@types/mdx": "^2.0.8",
|
||||
"@vercel/analytics": "^1.3.1",
|
||||
"@vercel/speed-insights": "^1.0.12",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"gcmp-design-system": "workspace:*",
|
||||
"lucide-react": "^0.436.0",
|
||||
"mdast-util-from-markdown": "^2.0.0",
|
||||
"mdast-util-mdx": "^3.0.0",
|
||||
@@ -44,6 +45,7 @@
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "13.5.4",
|
||||
"postcss": "^8",
|
||||
"postcss-import": "^16.1.0",
|
||||
"prettier": "^3.2.5",
|
||||
"tailwindcss": "^3",
|
||||
"typedoc": "^0.25.13",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
"postcss-import": {},
|
||||
tailwindcss: {},
|
||||
"@csstools/postcss-oklab-function": { preserve: true },
|
||||
autoprefixer: {},
|
||||
|
||||
344
homepage/homepage/styles/code-theme.css
Normal file
344
homepage/homepage/styles/code-theme.css
Normal file
@@ -0,0 +1,344 @@
|
||||
pre.shiki {
|
||||
overflow: hidden;
|
||||
}
|
||||
pre.shiki:hover .dim {
|
||||
opacity: 1;
|
||||
}
|
||||
pre.shiki div.dim {
|
||||
opacity: 0.5;
|
||||
}
|
||||
pre.shiki div.dim,
|
||||
pre.shiki div.highlight {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
pre.shiki div.highlight {
|
||||
opacity: 1;
|
||||
background-color: #f1f8ff;
|
||||
}
|
||||
pre.shiki div.line {
|
||||
/* min-height: 1rem; */
|
||||
counter-increment: lineNumber 1;
|
||||
}
|
||||
|
||||
pre.shiki div.line::before {
|
||||
content: counter(lineNumber);
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 1.3rem;
|
||||
padding-right: 0.3rem;
|
||||
text-align: right;
|
||||
transition: color 0.3s;
|
||||
@apply text-border-light text-[0.65rem];
|
||||
}
|
||||
|
||||
pre.shiki div.line:hover::before {
|
||||
@apply text-border;
|
||||
}
|
||||
|
||||
/** Don't show the language identifiers */
|
||||
pre.shiki .language-id {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/** When you mouse over the pre, show the underlines */
|
||||
pre.twoslash:hover data-lsp {
|
||||
@apply border-dotted border-b border-border;
|
||||
}
|
||||
|
||||
/** The tooltip-like which provides the LSP response */
|
||||
pre.twoslash data-lsp::before {
|
||||
content: attr(lsp);
|
||||
position: absolute;
|
||||
transform: translate(0, 1.2rem);
|
||||
max-width: 30rem;
|
||||
@apply text-xs px-1.5 py-1 rounded shadow-lg overflow-hidden whitespace-pre-wrap;
|
||||
@apply border border-border-light;
|
||||
@apply text-solid bg-canvas;
|
||||
text-align: left;
|
||||
z-index: 100;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
pointer-events: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
pre.twoslash data-lsp:hover::before {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
pointer-events: visible;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.shiki-outer {
|
||||
@apply shadow-sm rounded-xl;
|
||||
}
|
||||
|
||||
.shiki-filename {
|
||||
@apply px-3 py-2 rounded-t-xl text-xs;
|
||||
/* @apply bg-background-subtle text-stone-700 dark:text-stone-300; */
|
||||
@apply bg-background text-solid;
|
||||
}
|
||||
|
||||
pre .code-container {
|
||||
overflow: scroll;
|
||||
@apply p-2 pl-0 rounded-b-xl text-[0.8rem] leading-tight;
|
||||
/* @apply bg-stone-75 dark:bg-stone-925; */
|
||||
@apply bg-background-subtle;
|
||||
/* @apply border border-stone-100 dark:border-stone-900; */
|
||||
@apply border border-background;
|
||||
}
|
||||
/* The try button */
|
||||
pre .code-container > a {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
bottom: 8px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #719af4;
|
||||
padding: 0 8px;
|
||||
color: #719af4;
|
||||
text-decoration: none;
|
||||
opacity: 0;
|
||||
transition-timing-function: ease;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
/* Respect no animations */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
pre .code-container > a {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
pre .code-container > a:hover {
|
||||
color: white;
|
||||
background-color: #719af4;
|
||||
}
|
||||
pre .code-container:hover a {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
pre code {
|
||||
white-space: pre;
|
||||
}
|
||||
pre code a {
|
||||
text-decoration: none;
|
||||
}
|
||||
pre data-err {
|
||||
/* Extracted from VS Code */
|
||||
background: url("data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%206%203'%20enable-background%3D'new%200%200%206%203'%20height%3D'3'%20width%3D'6'%3E%3Cg%20fill%3D'%23c94824'%3E%3Cpolygon%20points%3D'5.5%2C0%202.5%2C3%201.1%2C3%204.1%2C0'%2F%3E%3Cpolygon%20points%3D'4%2C0%206%2C2%206%2C0.6%205.4%2C0'%2F%3E%3Cpolygon%20points%3D'0%2C2%201%2C3%202.4%2C3%200%2C0.6'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")
|
||||
repeat-x bottom left;
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
pre .query {
|
||||
margin-bottom: 10px;
|
||||
color: #137998;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* In order to have the 'popped out' style design and to not break the layout
|
||||
/* we need to place a fake and un-selectable copy of the error which _isn't_ broken out
|
||||
/* behind the actual error message.
|
||||
|
||||
/* This sections keeps both of those two in in sync */
|
||||
|
||||
pre .error,
|
||||
pre .error-behind {
|
||||
margin-left: -14px;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 4px;
|
||||
padding: 6px;
|
||||
padding-left: 14px;
|
||||
width: calc(100% - 20px);
|
||||
white-space: pre-wrap;
|
||||
display: block;
|
||||
}
|
||||
pre .error {
|
||||
position: absolute;
|
||||
background-color: #fee;
|
||||
border-left: 2px solid #bf1818;
|
||||
/* Give the space to the error code */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: black;
|
||||
}
|
||||
pre .error .code {
|
||||
display: none;
|
||||
}
|
||||
pre .error-behind {
|
||||
user-select: none;
|
||||
visibility: transparent;
|
||||
color: #fee;
|
||||
}
|
||||
/* Queries */
|
||||
pre .arrow {
|
||||
/* Transparent background */
|
||||
background-color: #eee;
|
||||
position: relative;
|
||||
top: -7px;
|
||||
margin-left: 0.1rem;
|
||||
/* Edges */
|
||||
border-left: 1px solid #eee;
|
||||
border-top: 1px solid #eee;
|
||||
transform: translateY(25%) rotate(45deg);
|
||||
/* Size */
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
}
|
||||
pre .popover {
|
||||
margin-bottom: 10px;
|
||||
background-color: #eee;
|
||||
display: inline-block;
|
||||
padding: 0 0.5rem 0.3rem;
|
||||
margin-top: 10px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
/* Completion */
|
||||
pre .inline-completions ul.dropdown {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
width: 240px;
|
||||
background-color: gainsboro;
|
||||
color: grey;
|
||||
padding-top: 4px;
|
||||
font-family: var(--code-font);
|
||||
font-size: 0.8rem;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border-left: 4px solid #4b9edd;
|
||||
}
|
||||
pre .inline-completions ul.dropdown::before {
|
||||
background-color: #4b9edd;
|
||||
width: 2px;
|
||||
position: absolute;
|
||||
top: -1.2rem;
|
||||
left: -3px;
|
||||
content: " ";
|
||||
}
|
||||
pre .inline-completions ul.dropdown li {
|
||||
overflow-x: hidden;
|
||||
padding-left: 4px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
pre .inline-completions ul.dropdown li.deprecated {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
pre .inline-completions ul.dropdown li span.result-found {
|
||||
color: #4b9edd;
|
||||
}
|
||||
pre .inline-completions ul.dropdown li span.result {
|
||||
width: 100px;
|
||||
color: black;
|
||||
display: inline-block;
|
||||
}
|
||||
.dark-theme .markdown pre {
|
||||
background-color: #d8d8d8;
|
||||
border-color: #ddd;
|
||||
filter: invert(98%) hue-rotate(180deg);
|
||||
}
|
||||
data-lsp {
|
||||
/* Ensures there's no 1px jump when the hover happens */
|
||||
border-bottom: 1px dotted transparent;
|
||||
/* Fades in unobtrusively */
|
||||
transition-timing-function: ease;
|
||||
transition: border-color 0.3s;
|
||||
}
|
||||
/* Respect people's wishes to not have animations */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
data-lsp {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
/** Annotations support, providing a tool for meta commentary */
|
||||
.tag-container {
|
||||
position: relative;
|
||||
}
|
||||
.tag-container .twoslash-annotation {
|
||||
position: absolute;
|
||||
font-family:
|
||||
"JetBrains Mono",
|
||||
Menlo,
|
||||
Monaco,
|
||||
Consolas,
|
||||
Courier New,
|
||||
monospace;
|
||||
right: -10px;
|
||||
/** Default annotation text to 200px */
|
||||
width: 200px;
|
||||
color: #187abf;
|
||||
background-color: #fcf3d9 bb;
|
||||
}
|
||||
.tag-container .twoslash-annotation p {
|
||||
text-align: left;
|
||||
font-size: 0.8rem;
|
||||
line-height: 0.9rem;
|
||||
}
|
||||
.tag-container .twoslash-annotation svg {
|
||||
float: left;
|
||||
margin-left: -44px;
|
||||
}
|
||||
.tag-container .twoslash-annotation.left {
|
||||
right: auto;
|
||||
left: -200px;
|
||||
}
|
||||
.tag-container .twoslash-annotation.left svg {
|
||||
float: right;
|
||||
margin-right: -5px;
|
||||
}
|
||||
|
||||
/** Support for showing console log/warn/errors inline */
|
||||
pre .logger {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: black;
|
||||
padding: 6px;
|
||||
padding-left: 8px;
|
||||
width: calc(100% - 19px);
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
pre .logger svg {
|
||||
margin-right: 9px;
|
||||
}
|
||||
pre .logger.error-log {
|
||||
background-color: #fee;
|
||||
border-left: 2px solid #bf1818;
|
||||
}
|
||||
pre .logger.warn-log {
|
||||
background-color: #ffe;
|
||||
border-left: 2px solid #eae662;
|
||||
}
|
||||
pre .logger.log-log {
|
||||
background-color: #e9e9e9;
|
||||
border-left: 2px solid #ababab;
|
||||
}
|
||||
pre .logger.log-log svg {
|
||||
margin-left: 6px;
|
||||
margin-right: 9px;
|
||||
}
|
||||
|
||||
body {
|
||||
--shiki-color-text: #606060;
|
||||
--shiki-color-background: transparent;
|
||||
--shiki-token-constant: #00a5a5;
|
||||
--shiki-token-string: #4e3a2c;
|
||||
--shiki-token-comment: #aaa;
|
||||
--shiki-token-keyword: #7b8bff;
|
||||
--shiki-token-parameter: #ff9800;
|
||||
--shiki-token-function: #445dd7;
|
||||
--shiki-token-string-expression: #38a35f;
|
||||
--shiki-token-punctuation: #969696;
|
||||
--shiki-token-link: #1aa245;
|
||||
}
|
||||
|
||||
.dark body {
|
||||
--shiki-color-text: #d1d1d1;
|
||||
--shiki-token-constant: #2dc9c9;
|
||||
--shiki-token-string: #feb179;
|
||||
--shiki-token-comment: #6b737c;
|
||||
--shiki-token-keyword: #7b8bff;
|
||||
--shiki-token-parameter: #ff9800;
|
||||
--shiki-token-function: #9babff;
|
||||
--shiki-token-string-expression: #42bb69;
|
||||
--shiki-token-punctuation: #bbb;
|
||||
--shiki-token-link: #ffab70;
|
||||
}
|
||||
@@ -10,5 +10,8 @@ const config: Config = {
|
||||
"./app/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./node_modules/gcmp-design-system/src/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
};
|
||||
export default config;
|
||||
|
||||
35
homepage/pnpm-lock.yaml
generated
35
homepage/pnpm-lock.yaml
generated
@@ -60,6 +60,9 @@ importers:
|
||||
postcss:
|
||||
specifier: ^8
|
||||
version: 8.4.38
|
||||
postcss-import:
|
||||
specifier: ^16.1.0
|
||||
version: 16.1.0(postcss@8.4.38)
|
||||
tailwindcss:
|
||||
specifier: ^3.4.1
|
||||
version: 3.4.3
|
||||
@@ -148,6 +151,9 @@ importers:
|
||||
postcss:
|
||||
specifier: ^8
|
||||
version: 8.4.38
|
||||
postcss-import:
|
||||
specifier: ^16.1.0
|
||||
version: 16.1.0(postcss@8.4.38)
|
||||
prettier:
|
||||
specifier: ^3.2.5
|
||||
version: 3.2.5
|
||||
@@ -241,6 +247,7 @@ packages:
|
||||
'@humanwhocodes/config-array@0.11.14':
|
||||
resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==}
|
||||
engines: {node: '>=10.10.0'}
|
||||
deprecated: Use @eslint/config-array instead
|
||||
|
||||
'@humanwhocodes/module-importer@1.0.1':
|
||||
resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
|
||||
@@ -248,6 +255,7 @@ packages:
|
||||
|
||||
'@humanwhocodes/object-schema@2.0.3':
|
||||
resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==}
|
||||
deprecated: Use @eslint/object-schema instead
|
||||
|
||||
'@icons-pack/react-simple-icons@9.4.1':
|
||||
resolution: {integrity: sha512-oDX8iE/AOyRIY0ys56+eybKSsyZODHQIPZ5mAGVxx3TszkA5l8lIxKl8HI9F801Y1CJxcySBjIk1XibrnFF0Hw==}
|
||||
@@ -871,7 +879,7 @@ packages:
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
concat-map@0.0.1:
|
||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||
resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
|
||||
|
||||
cross-spawn@7.0.3:
|
||||
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
|
||||
@@ -1268,9 +1276,11 @@ packages:
|
||||
|
||||
glob@7.1.7:
|
||||
resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==}
|
||||
deprecated: Glob versions prior to v9 are no longer supported
|
||||
|
||||
glob@7.2.3:
|
||||
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
|
||||
deprecated: Glob versions prior to v9 are no longer supported
|
||||
|
||||
globals@13.24.0:
|
||||
resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==}
|
||||
@@ -1339,6 +1349,7 @@ packages:
|
||||
|
||||
inflight@1.0.6:
|
||||
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
|
||||
deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
|
||||
|
||||
inherits@2.0.4:
|
||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||
@@ -2056,6 +2067,12 @@ packages:
|
||||
peerDependencies:
|
||||
postcss: ^8.0.0
|
||||
|
||||
postcss-import@16.1.0:
|
||||
resolution: {integrity: sha512-7hsAZ4xGXl4MW+OKEWCnF6T5jqBw80/EE9aXg1r2yyn1RsVEU8EtKXbijEODa+rg7iih4bKf7vlvTGYR4CnPNg==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
peerDependencies:
|
||||
postcss: ^8.0.0
|
||||
|
||||
postcss-js@4.0.1:
|
||||
resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
|
||||
engines: {node: ^12 || ^14 || >= 16}
|
||||
@@ -2184,6 +2201,7 @@ packages:
|
||||
|
||||
rimraf@3.0.2:
|
||||
resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
|
||||
deprecated: Rimraf versions prior to v4 are no longer supported
|
||||
hasBin: true
|
||||
|
||||
run-parallel@1.2.0:
|
||||
@@ -3554,7 +3572,7 @@ snapshots:
|
||||
eslint: 8.57.0
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0)
|
||||
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
|
||||
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
|
||||
eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0)
|
||||
eslint-plugin-react: 7.34.1(eslint@8.57.0)
|
||||
eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0)
|
||||
@@ -3572,7 +3590,7 @@ snapshots:
|
||||
eslint: 8.57.0
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0)
|
||||
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
|
||||
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
|
||||
eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0)
|
||||
eslint-plugin-react: 7.34.1(eslint@8.57.0)
|
||||
eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0)
|
||||
@@ -3596,7 +3614,7 @@ snapshots:
|
||||
enhanced-resolve: 5.16.1
|
||||
eslint: 8.57.0
|
||||
eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
|
||||
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
|
||||
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
|
||||
fast-glob: 3.3.2
|
||||
get-tsconfig: 4.7.4
|
||||
is-core-module: 2.13.1
|
||||
@@ -3618,7 +3636,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0):
|
||||
eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
|
||||
dependencies:
|
||||
array-includes: 3.1.8
|
||||
array.prototype.findlastindex: 1.2.5
|
||||
@@ -5082,6 +5100,13 @@ snapshots:
|
||||
read-cache: 1.0.0
|
||||
resolve: 1.22.8
|
||||
|
||||
postcss-import@16.1.0(postcss@8.4.38):
|
||||
dependencies:
|
||||
postcss: 8.4.38
|
||||
postcss-value-parser: 4.2.0
|
||||
read-cache: 1.0.0
|
||||
resolve: 1.22.8
|
||||
|
||||
postcss-js@4.0.1(postcss@8.4.38):
|
||||
dependencies:
|
||||
camelcase-css: 2.0.1
|
||||
|
||||
Reference in New Issue
Block a user