@supertype.ai/foundations 0.1.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +369 -0
- package/bin/foundations.mjs +713 -0
- package/dist/blocks/accordion.d.ts +23 -0
- package/dist/blocks/accordion.js +59 -0
- package/dist/blocks/callout.d.ts +57 -0
- package/dist/blocks/callout.js +61 -0
- package/dist/blocks/card.d.ts +34 -0
- package/dist/blocks/card.js +56 -0
- package/dist/blocks/index.d.ts +7 -0
- package/dist/blocks/index.js +7 -0
- package/dist/blocks/interactive-accordion.d.ts +13 -0
- package/dist/blocks/interactive-accordion.js +27 -0
- package/dist/blocks/segment.d.ts +37 -0
- package/dist/blocks/segment.js +37 -0
- package/dist/blocks/steps.d.ts +10 -0
- package/dist/blocks/steps.js +13 -0
- package/dist/blocks/tabs.d.ts +32 -0
- package/dist/blocks/tabs.js +69 -0
- package/dist/cjs/eslint.js +146 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cn.d.ts +2 -0
- package/dist/cn.js +5 -0
- package/dist/contrast.d.ts +47 -0
- package/dist/contrast.js +255 -0
- package/dist/eslint.d.ts +74 -0
- package/dist/eslint.js +138 -0
- package/dist/essay/contents.d.ts +10 -0
- package/dist/essay/contents.js +17 -0
- package/dist/essay/essay.d.ts +125 -0
- package/dist/essay/essay.js +92 -0
- package/dist/essay/index.d.ts +7 -0
- package/dist/essay/index.js +9 -0
- package/dist/essay/layout.d.ts +72 -0
- package/dist/essay/layout.js +77 -0
- package/dist/essay/rail.d.ts +15 -0
- package/dist/essay/rail.js +26 -0
- package/dist/essay/reading.d.ts +17 -0
- package/dist/essay/reading.js +31 -0
- package/dist/essay/scroll.d.ts +8 -0
- package/dist/essay/scroll.js +78 -0
- package/dist/essay/toc.d.ts +23 -0
- package/dist/essay/toc.js +50 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +33 -0
- package/dist/injection.d.ts +8 -0
- package/dist/injection.js +1 -0
- package/dist/mdx.d.ts +47 -0
- package/dist/mdx.js +68 -0
- package/dist/og.d.ts +18 -0
- package/dist/og.js +50 -0
- package/dist/rehype.d.ts +18 -0
- package/dist/rehype.js +41 -0
- package/dist/seo.d.ts +174 -0
- package/dist/seo.js +152 -0
- package/dist/typography/as.d.ts +15 -0
- package/dist/typography/as.js +8 -0
- package/dist/typography/header.d.ts +44 -0
- package/dist/typography/header.js +119 -0
- package/dist/typography/highlight.d.ts +33 -0
- package/dist/typography/highlight.js +98 -0
- package/dist/typography/index.d.ts +4 -0
- package/dist/typography/index.js +3 -0
- package/dist/typography/paragraph.d.ts +157 -0
- package/dist/typography/paragraph.js +229 -0
- package/llms.txt +125 -0
- package/package.json +140 -0
- package/src/prose.css +12 -0
- package/src/shiki.css +23 -0
- package/src/theme.css +272 -0
- package/src/tokens.css +43 -0
- package/src/type.css +73 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { type VariantProps } from "class-variance-authority";
|
|
2
|
+
import type { ComponentProps, ReactNode } from "react";
|
|
3
|
+
import { type WithAs } from "./as.js";
|
|
4
|
+
/** The body layer: two axes and no more. A paragraph picks a rung and an ink; a
|
|
5
|
+
* caption is always secondary ink and picks a size. `lead` was a third rung a
|
|
6
|
+
* breakpoint away from `prose`, and its standfirst role is now the eyebrow's. */
|
|
7
|
+
declare const pVariants: (props?: ({
|
|
8
|
+
variant?: "ui" | "prose" | null | undefined;
|
|
9
|
+
tone?: "default" | "muted" | null | undefined;
|
|
10
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
11
|
+
export type ParagraphVariants = VariantProps<typeof pVariants>;
|
|
12
|
+
export declare function TypographyP({ className, variant, tone, children, ...props }: ComponentProps<"p"> & ParagraphVariants): import("react").JSX.Element;
|
|
13
|
+
/** A preset's props: its base's, minus the axes it has decided. `keyof Pins` reads
|
|
14
|
+
* the exclusion off the pinned object the preset also spreads, so the two cannot
|
|
15
|
+
* drift — `<TypographyMuted tone="default">` used to compile and un-mute it. */
|
|
16
|
+
type Preset<Base, Pins> = Omit<Base, keyof Pins>;
|
|
17
|
+
type ParagraphProps = ComponentProps<"p"> & ParagraphVariants;
|
|
18
|
+
/** The UI rung in the secondary ink. */
|
|
19
|
+
declare const MUTED: {
|
|
20
|
+
readonly tone: "muted";
|
|
21
|
+
};
|
|
22
|
+
export declare function TypographyMuted(props: Preset<ParagraphProps, typeof MUTED>): import("react").JSX.Element;
|
|
23
|
+
/** Reading-size body copy. `TypographyMuted` is the same ink one rung down. */
|
|
24
|
+
declare const PROSE: {
|
|
25
|
+
readonly variant: "prose";
|
|
26
|
+
readonly tone: "muted";
|
|
27
|
+
};
|
|
28
|
+
export declare function TypographyProse(props: Preset<ParagraphProps, typeof PROSE>): import("react").JSX.Element;
|
|
29
|
+
export type ListProps = ComponentProps<"ul"> & Pick<ParagraphVariants, "variant"> & {
|
|
30
|
+
ordered?: boolean;
|
|
31
|
+
};
|
|
32
|
+
export declare function TypographyList({ className, children, ordered, variant, ...props }: ListProps): import("react").JSX.Element;
|
|
33
|
+
/**
|
|
34
|
+
* The reading rung, pinned. The name predates the axis and keeps every call site
|
|
35
|
+
* that already had it; `Preset` stops one re-opening the rung it names.
|
|
36
|
+
*/
|
|
37
|
+
declare const PROSE_LIST: {
|
|
38
|
+
readonly variant: "prose";
|
|
39
|
+
};
|
|
40
|
+
export declare function TypographyProseList(props: Preset<ListProps, typeof PROSE_LIST>): import("react").JSX.Element;
|
|
41
|
+
/**
|
|
42
|
+
* Meta beside content: timestamps, counts, bylines, the key in a key-value row.
|
|
43
|
+
*
|
|
44
|
+
* Always the secondary ink and never a weight — a caption is secondary because
|
|
45
|
+
* it is muted, and 500 on top would have the colour and the weight arguing.
|
|
46
|
+
* `sm` is the default because meta is separated from body by ink, not size;
|
|
47
|
+
* the smaller rungs are a deliberate step down, not the norm.
|
|
48
|
+
*
|
|
49
|
+
* Leading is pinned per size rather than left to the rung. Plenty of captions
|
|
50
|
+
* are a wrapped sentence, and the ramp's tight setting sets those cramped —
|
|
51
|
+
* descenders nearly on the caps below. `leading-normal` writes `--tw-leading`,
|
|
52
|
+
* the variable the `text-*` step reads, so 1.5 wins at every rung.
|
|
53
|
+
*
|
|
54
|
+
* `inherit` is the parenthetical inside a heading, an eyebrow or a stat. It
|
|
55
|
+
* takes the size of whatever set it and resets the weight, because the only
|
|
56
|
+
* reason to sit there is to be quieter than the thing you qualify — and every
|
|
57
|
+
* container that sets a size for you sets a weight too.
|
|
58
|
+
*/
|
|
59
|
+
declare const captionVariants: (props?: ({
|
|
60
|
+
size?: "inherit" | "sm" | "xs" | "2xs" | null | undefined;
|
|
61
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
62
|
+
export type CaptionVariants = VariantProps<typeof captionVariants>;
|
|
63
|
+
/**
|
|
64
|
+
* `as` covers the one thing that genuinely differs between call sites: whether
|
|
65
|
+
* the run is inline beside its subject or a block under it.
|
|
66
|
+
*/
|
|
67
|
+
export declare function TypographyCaption({ className, size, as, children, ...props }: WithAs<CaptionVariants>): import("react").JSX.Element;
|
|
68
|
+
/**
|
|
69
|
+
* Small print set as a block: a note under the thing it annotates, rather than
|
|
70
|
+
* an aside inline with it. Same rung and same ink as the caption — small print
|
|
71
|
+
* is small because it is muted, and dropping it a rung as well is what made
|
|
72
|
+
* both apps hand-roll their own.
|
|
73
|
+
*/
|
|
74
|
+
declare const BLOCK: {
|
|
75
|
+
readonly as: "p";
|
|
76
|
+
};
|
|
77
|
+
export declare function TypographySmall(props: Preset<WithAs<CaptionVariants>, typeof BLOCK>): import("react").JSX.Element;
|
|
78
|
+
/**
|
|
79
|
+
* The label role: a form label, a column header, the key a reader scans for.
|
|
80
|
+
* 500 is the only weight bump a dense surface needs below a heading.
|
|
81
|
+
*
|
|
82
|
+
* The rungs are the caption's, deliberately. A label and a caption are one pair
|
|
83
|
+
* — the key and the value, the name and the note — and a pair that cannot be set
|
|
84
|
+
* at one size is not a pair. Pinning the label to `sm` while the caption had an
|
|
85
|
+
* axis is what sent a key next to an `xs` value out to `font-medium text-xs` in
|
|
86
|
+
* a className, leaving the weight arguing with the rung it landed on.
|
|
87
|
+
*
|
|
88
|
+
* `as` is here for the same reason it is on `TypographyEyebrow`: a config panel
|
|
89
|
+
* names its sections at this size, and those names are the page's outline.
|
|
90
|
+
*/
|
|
91
|
+
declare const labelVariants: (props?: ({
|
|
92
|
+
size?: "inherit" | "sm" | "xs" | "2xs" | null | undefined;
|
|
93
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
94
|
+
export type LabelVariants = VariantProps<typeof labelVariants>;
|
|
95
|
+
export declare function TypographyLabel({ className, size, as, children, ...props }: WithAs<LabelVariants>): import("react").JSX.Element;
|
|
96
|
+
/**
|
|
97
|
+
* A numeric readout. Size and colour ride in via className per use.
|
|
98
|
+
*
|
|
99
|
+
* Tabular is right in a column and wrong in a headline, so it is an axis rather
|
|
100
|
+
* than a constant. Keep `tabular` anywhere a value updates in place.
|
|
101
|
+
*/
|
|
102
|
+
declare const statVariants: (props?: ({
|
|
103
|
+
size?: "inherit" | "display" | "card" | "panel" | "page" | null | undefined;
|
|
104
|
+
figures?: "tabular" | "proportional" | null | undefined;
|
|
105
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
106
|
+
export type StatVariants = VariantProps<typeof statVariants>;
|
|
107
|
+
export declare function TypographyStat({ className, size, figures, children, ...props }: ComponentProps<"span"> & StatVariants): import("react").JSX.Element;
|
|
108
|
+
/**
|
|
109
|
+
* A run of code inside a sentence: a command, a field name, a trigger.
|
|
110
|
+
*
|
|
111
|
+
* Everything is in `em`, not a rung: the chip has to sit in whatever size the
|
|
112
|
+
* sentence around it is set at, and the ramp differs per surface. The 0.9 is an
|
|
113
|
+
* optical correction — the mono face carries a taller x-height than the sans.
|
|
114
|
+
*/
|
|
115
|
+
export declare function TypographyInlineCode({ className, children, ...props }: ComponentProps<"code">): import("react").JSX.Element;
|
|
116
|
+
/**
|
|
117
|
+
* A statement about the surface, not the link: `foreground` inside a paragraph,
|
|
118
|
+
* `primary` when the link is the point of the line, `secondary` for a note
|
|
119
|
+
* beneath a hero where `primary` would compete with the CTA beside it.
|
|
120
|
+
*/
|
|
121
|
+
declare const LINK_TONES: {
|
|
122
|
+
readonly foreground: "font-medium text-foreground";
|
|
123
|
+
readonly primary: "font-medium text-primary";
|
|
124
|
+
readonly secondary: "text-secondary-ink";
|
|
125
|
+
};
|
|
126
|
+
export type LinkTone = keyof typeof LINK_TONES;
|
|
127
|
+
type TypographyLinkProps = Omit<ComponentProps<"a">, "href"> & {
|
|
128
|
+
href: string;
|
|
129
|
+
children: ReactNode;
|
|
130
|
+
tone?: LinkTone;
|
|
131
|
+
/** Defaults on for an off-site link. Turn it off for one that starts a flow the reader should stay in. */
|
|
132
|
+
newTab?: boolean;
|
|
133
|
+
/**
|
|
134
|
+
* A trailing arrow, for a link that ends a sentence and leads somewhere. The
|
|
135
|
+
* glyph follows the href: `↗` when the link leaves the site, `→` when it does
|
|
136
|
+
* not. That is the convention, and it is not a call site's to get wrong.
|
|
137
|
+
*/
|
|
138
|
+
addArrow?: boolean;
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* The inline link.
|
|
142
|
+
*
|
|
143
|
+
* Internal and external are decided from the href, never at the call site: an
|
|
144
|
+
* href with a scheme renders a plain anchor and, if it is http(s), opens away
|
|
145
|
+
* with `rel="noopener noreferrer"`; everything else routes through the router's
|
|
146
|
+
* Link. `newTab` is the one override, for an off-site href that starts a flow
|
|
147
|
+
* the reader should stay in. Call-site props apply last, so a passed
|
|
148
|
+
* `target`/`rel` still wins.
|
|
149
|
+
*
|
|
150
|
+
* The router is `next-view-transitions`, imported rather than injected. Every
|
|
151
|
+
* project on this package is a Next app and wants the same link, and a factory
|
|
152
|
+
* bought router-agnosticism nobody used at the price of a component that could
|
|
153
|
+
* not be imported by name. One call site ended up on the unbound version that
|
|
154
|
+
* way and lost its decoration.
|
|
155
|
+
*/
|
|
156
|
+
export declare function TypographyLink({ href, children, tone, newTab, addArrow, className, ...props }: TypographyLinkProps): import("react").JSX.Element;
|
|
157
|
+
export {};
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Link } from "next-view-transitions";
|
|
3
|
+
import { cva } from "class-variance-authority";
|
|
4
|
+
import { cn } from "../cn.js";
|
|
5
|
+
import { TextAs } from "./as.js";
|
|
6
|
+
/** The body layer: two axes and no more. A paragraph picks a rung and an ink; a
|
|
7
|
+
* caption is always secondary ink and picks a size. `lead` was a third rung a
|
|
8
|
+
* breakpoint away from `prose`, and its standfirst role is now the eyebrow's. */
|
|
9
|
+
const pVariants = cva("", {
|
|
10
|
+
variants: {
|
|
11
|
+
/**
|
|
12
|
+
* `ui` is interface copy. `prose` is the reading rung, stated here and
|
|
13
|
+
* nowhere else — it had drifted to five copies once already. `--text-lg`
|
|
14
|
+
* resolves larger on an editorial subtree, by design.
|
|
15
|
+
*/
|
|
16
|
+
variant: {
|
|
17
|
+
ui: "text-sm",
|
|
18
|
+
prose: "text-pretty text-lg leading-relaxed",
|
|
19
|
+
},
|
|
20
|
+
tone: {
|
|
21
|
+
default: "text-foreground",
|
|
22
|
+
muted: "text-muted-foreground",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
defaultVariants: { variant: "ui", tone: "default" },
|
|
26
|
+
});
|
|
27
|
+
export function TypographyP({ className, variant, tone, children, ...props }) {
|
|
28
|
+
return (_jsx("p", { className: cn(pVariants({ variant, tone }), className), ...props, children: children }));
|
|
29
|
+
}
|
|
30
|
+
/** The UI rung in the secondary ink. */
|
|
31
|
+
const MUTED = { tone: "muted" };
|
|
32
|
+
export function TypographyMuted(props) {
|
|
33
|
+
return _jsx(TypographyP, { ...props, ...MUTED });
|
|
34
|
+
}
|
|
35
|
+
/** Reading-size body copy. `TypographyMuted` is the same ink one rung down. */
|
|
36
|
+
const PROSE = { variant: "prose", tone: "muted" };
|
|
37
|
+
export function TypographyProse(props) {
|
|
38
|
+
return _jsx(TypographyP, { ...props, ...PROSE });
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* A list, on the same rung axis as the paragraph beside it.
|
|
42
|
+
*
|
|
43
|
+
* The rung composes `pVariants` rather than restating one, so a list cannot
|
|
44
|
+
* drift from the copy it sits under. The old `proseClass` held that property for
|
|
45
|
+
* the prose rung alone.
|
|
46
|
+
*
|
|
47
|
+
* `variant` is here because a list is not always reading copy. A tier card or a
|
|
48
|
+
* bento cell sets its paragraphs in `ui`, and a list pinned to `prose` inside one
|
|
49
|
+
* lands two rungs above the sentence introducing it, with no prop to say so. Call
|
|
50
|
+
* sites answered that by hand-rolling `<ul className="list-disc text-sm">`, which
|
|
51
|
+
* is the shape this replaces.
|
|
52
|
+
*
|
|
53
|
+
* Tone stays pinned to `muted`: a list is body copy, secondary for the same
|
|
54
|
+
* reason the paragraph presets are, and a weight-or-ink argument at the marker
|
|
55
|
+
* is not a thing a call site should be able to start.
|
|
56
|
+
*/
|
|
57
|
+
const listClass = (variant, ordered) => cn("my-4 flex flex-col gap-1 pl-6 [&>li]:pl-1.5", ordered ? "list-decimal" : "list-disc", pVariants({ variant, tone: "muted" }));
|
|
58
|
+
export function TypographyList({ className, children, ordered, variant, ...props }) {
|
|
59
|
+
const List = ordered ? "ol" : "ul";
|
|
60
|
+
return (_jsx(List, { className: cn(listClass(variant, ordered), className), ...props, children: children }));
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The reading rung, pinned. The name predates the axis and keeps every call site
|
|
64
|
+
* that already had it; `Preset` stops one re-opening the rung it names.
|
|
65
|
+
*/
|
|
66
|
+
const PROSE_LIST = { variant: "prose" };
|
|
67
|
+
export function TypographyProseList(props) {
|
|
68
|
+
return _jsx(TypographyList, { ...props, ...PROSE_LIST });
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Meta beside content: timestamps, counts, bylines, the key in a key-value row.
|
|
72
|
+
*
|
|
73
|
+
* Always the secondary ink and never a weight — a caption is secondary because
|
|
74
|
+
* it is muted, and 500 on top would have the colour and the weight arguing.
|
|
75
|
+
* `sm` is the default because meta is separated from body by ink, not size;
|
|
76
|
+
* the smaller rungs are a deliberate step down, not the norm.
|
|
77
|
+
*
|
|
78
|
+
* Leading is pinned per size rather than left to the rung. Plenty of captions
|
|
79
|
+
* are a wrapped sentence, and the ramp's tight setting sets those cramped —
|
|
80
|
+
* descenders nearly on the caps below. `leading-normal` writes `--tw-leading`,
|
|
81
|
+
* the variable the `text-*` step reads, so 1.5 wins at every rung.
|
|
82
|
+
*
|
|
83
|
+
* `inherit` is the parenthetical inside a heading, an eyebrow or a stat. It
|
|
84
|
+
* takes the size of whatever set it and resets the weight, because the only
|
|
85
|
+
* reason to sit there is to be quieter than the thing you qualify — and every
|
|
86
|
+
* container that sets a size for you sets a weight too.
|
|
87
|
+
*/
|
|
88
|
+
const captionVariants = cva("text-muted-foreground", {
|
|
89
|
+
variants: {
|
|
90
|
+
size: {
|
|
91
|
+
sm: "text-sm leading-normal",
|
|
92
|
+
xs: "text-xs leading-normal",
|
|
93
|
+
"2xs": "text-2xs leading-normal",
|
|
94
|
+
inherit: "font-normal",
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
defaultVariants: { size: "sm" },
|
|
98
|
+
});
|
|
99
|
+
/**
|
|
100
|
+
* `as` covers the one thing that genuinely differs between call sites: whether
|
|
101
|
+
* the run is inline beside its subject or a block under it.
|
|
102
|
+
*/
|
|
103
|
+
export function TypographyCaption({ className, size, as, children, ...props }) {
|
|
104
|
+
return (_jsx(TextAs, { as: as, className: cn(captionVariants({ size }), className), ...props, children: children }));
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Small print set as a block: a note under the thing it annotates, rather than
|
|
108
|
+
* an aside inline with it. Same rung and same ink as the caption — small print
|
|
109
|
+
* is small because it is muted, and dropping it a rung as well is what made
|
|
110
|
+
* both apps hand-roll their own.
|
|
111
|
+
*/
|
|
112
|
+
const BLOCK = { as: "p" };
|
|
113
|
+
export function TypographySmall(props) {
|
|
114
|
+
return _jsx(TypographyCaption, { ...props, ...BLOCK });
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* The label role: a form label, a column header, the key a reader scans for.
|
|
118
|
+
* 500 is the only weight bump a dense surface needs below a heading.
|
|
119
|
+
*
|
|
120
|
+
* The rungs are the caption's, deliberately. A label and a caption are one pair
|
|
121
|
+
* — the key and the value, the name and the note — and a pair that cannot be set
|
|
122
|
+
* at one size is not a pair. Pinning the label to `sm` while the caption had an
|
|
123
|
+
* axis is what sent a key next to an `xs` value out to `font-medium text-xs` in
|
|
124
|
+
* a className, leaving the weight arguing with the rung it landed on.
|
|
125
|
+
*
|
|
126
|
+
* `as` is here for the same reason it is on `TypographyEyebrow`: a config panel
|
|
127
|
+
* names its sections at this size, and those names are the page's outline.
|
|
128
|
+
*/
|
|
129
|
+
const labelVariants = cva("font-medium text-foreground", {
|
|
130
|
+
variants: {
|
|
131
|
+
size: {
|
|
132
|
+
sm: "text-sm",
|
|
133
|
+
xs: "text-xs",
|
|
134
|
+
"2xs": "text-2xs",
|
|
135
|
+
/** Inside a heading or a chip, where the container has already set one. */
|
|
136
|
+
inherit: "",
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
defaultVariants: { size: "sm" },
|
|
140
|
+
});
|
|
141
|
+
export function TypographyLabel({ className, size, as, children, ...props }) {
|
|
142
|
+
return (_jsx(TextAs, { as: as, className: cn(labelVariants({ size }), className), ...props, children: children }));
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* A numeric readout. Size and colour ride in via className per use.
|
|
146
|
+
*
|
|
147
|
+
* Tabular is right in a column and wrong in a headline, so it is an axis rather
|
|
148
|
+
* than a constant. Keep `tabular` anywhere a value updates in place.
|
|
149
|
+
*/
|
|
150
|
+
const statVariants = cva("font-semibold tracking-tight", {
|
|
151
|
+
variants: {
|
|
152
|
+
/**
|
|
153
|
+
* Named rungs, because the ramp was reachable only by spelling a class. The
|
|
154
|
+
* three here are the ones call sites actually converged on: `display` is the
|
|
155
|
+
* figure a section is built around, `page` and `panel` ride the heading
|
|
156
|
+
* ladder so a stat and the heading beside it step together — and therefore
|
|
157
|
+
* retune together on an editorial surface, which a literal never would.
|
|
158
|
+
*
|
|
159
|
+
* `inherit` is the default and writes nothing: a stat inside a heading, a
|
|
160
|
+
* chip or a sentence takes the size that set it, and every existing call
|
|
161
|
+
* site keeps the size it passed.
|
|
162
|
+
*/
|
|
163
|
+
size: {
|
|
164
|
+
inherit: "",
|
|
165
|
+
card: "text-h4",
|
|
166
|
+
panel: "text-h3",
|
|
167
|
+
page: "text-h1",
|
|
168
|
+
display: "text-6xl font-black",
|
|
169
|
+
},
|
|
170
|
+
figures: {
|
|
171
|
+
/** Even advances stop a value jittering as it refreshes. */
|
|
172
|
+
tabular: "tabular-nums",
|
|
173
|
+
/** A headline figure wants its drawn spacing: a lone 1 is not an 8. */
|
|
174
|
+
proportional: "proportional-nums",
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
defaultVariants: { size: "inherit", figures: "tabular" },
|
|
178
|
+
});
|
|
179
|
+
export function TypographyStat({ className, size, figures, children, ...props }) {
|
|
180
|
+
return (_jsx("span", { className: cn(statVariants({ size, figures }), className), ...props, children: children }));
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* A run of code inside a sentence: a command, a field name, a trigger.
|
|
184
|
+
*
|
|
185
|
+
* Everything is in `em`, not a rung: the chip has to sit in whatever size the
|
|
186
|
+
* sentence around it is set at, and the ramp differs per surface. The 0.9 is an
|
|
187
|
+
* optical correction — the mono face carries a taller x-height than the sans.
|
|
188
|
+
*/
|
|
189
|
+
export function TypographyInlineCode({ className, children, ...props }) {
|
|
190
|
+
return (_jsx("code", { className: cn("rounded-[3px] bg-foreground/[0.03] px-[0.3em] py-[0.1em] font-mono text-[0.9em] text-secondary-ink", className), ...props, children: children }));
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* A statement about the surface, not the link: `foreground` inside a paragraph,
|
|
194
|
+
* `primary` when the link is the point of the line, `secondary` for a note
|
|
195
|
+
* beneath a hero where `primary` would compete with the CTA beside it.
|
|
196
|
+
*/
|
|
197
|
+
const LINK_TONES = {
|
|
198
|
+
foreground: "font-medium text-foreground",
|
|
199
|
+
primary: "font-medium text-primary",
|
|
200
|
+
secondary: "text-secondary-ink",
|
|
201
|
+
};
|
|
202
|
+
const LINK_DECORATION = "underline decoration-dotted decoration-1 decoration-muted-foreground decoration-skip-ink-none underline-offset-2 hover:decoration-solid hover:decoration-current/70";
|
|
203
|
+
const linkClass = (tone = "foreground", className) => cn(LINK_TONES[tone], LINK_DECORATION, className);
|
|
204
|
+
/**
|
|
205
|
+
* The inline link.
|
|
206
|
+
*
|
|
207
|
+
* Internal and external are decided from the href, never at the call site: an
|
|
208
|
+
* href with a scheme renders a plain anchor and, if it is http(s), opens away
|
|
209
|
+
* with `rel="noopener noreferrer"`; everything else routes through the router's
|
|
210
|
+
* Link. `newTab` is the one override, for an off-site href that starts a flow
|
|
211
|
+
* the reader should stay in. Call-site props apply last, so a passed
|
|
212
|
+
* `target`/`rel` still wins.
|
|
213
|
+
*
|
|
214
|
+
* The router is `next-view-transitions`, imported rather than injected. Every
|
|
215
|
+
* project on this package is a Next app and wants the same link, and a factory
|
|
216
|
+
* bought router-agnosticism nobody used at the price of a component that could
|
|
217
|
+
* not be imported by name. One call site ended up on the unbound version that
|
|
218
|
+
* way and lost its decoration.
|
|
219
|
+
*/
|
|
220
|
+
export function TypographyLink({ href, children, tone = "foreground", newTab, addArrow, className, ...props }) {
|
|
221
|
+
const style = linkClass(tone, className);
|
|
222
|
+
const external = /^[a-z][a-z0-9+.-]*:/i.test(href);
|
|
223
|
+
const body = (_jsxs(_Fragment, { children: [children, addArrow && (_jsx("svg", { "aria-hidden": "true", className: "ml-1 inline size-3.5 align-middle", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("path", { d: external ? "M7 17 17 7M7 7h10v10" : "M5 12h14M12 5l7 7-7 7" }) }))] }));
|
|
224
|
+
if (external) {
|
|
225
|
+
const away = newTab ?? href.startsWith("http");
|
|
226
|
+
return (_jsx("a", { href: href, className: style, ...(away ? { target: "_blank", rel: "noopener noreferrer" } : {}), ...props, children: body }));
|
|
227
|
+
}
|
|
228
|
+
return (_jsx(Link, { href: href, className: style, ...props, children: body }));
|
|
229
|
+
}
|
package/llms.txt
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# @supertype.ai/foundations
|
|
2
|
+
|
|
3
|
+
The shared design layer for Supertype's Next apps: typography primitives,
|
|
4
|
+
content blocks, a long-form essay shell, token and theme CSS, and build-time
|
|
5
|
+
tooling for SEO, OG cards, lint rules and contrast checks.
|
|
6
|
+
|
|
7
|
+
This file is for coding agents working in an app that consumes the package. It
|
|
8
|
+
covers what to import and the mistakes that do not produce an error. Full
|
|
9
|
+
reference: https://github.com/supertypeai/foundations
|
|
10
|
+
|
|
11
|
+
## Rules
|
|
12
|
+
|
|
13
|
+
1. **Never write type styles by hand.** If you are about to write `text-sm`,
|
|
14
|
+
`text-xs`, `font-medium`, `leading-tight`, `text-muted-foreground` or similar
|
|
15
|
+
on a text element, there is a primitive for it. Use that instead.
|
|
16
|
+
2. **Retune with CSS variables, not classes.** The package owns its classnames.
|
|
17
|
+
Change a `--text-*` rung, `--heading-weight` or a colour token. Do not
|
|
18
|
+
override the package's utilities.
|
|
19
|
+
3. **Import from the right entry point.** `blocks`, `essay`, `mdx`, `seo`, `og`,
|
|
20
|
+
`eslint`, `rehype` and `contrast` are subpaths, not part of the root barrel.
|
|
21
|
+
4. **Use colour tokens, never literal colours.** `bg-card`, `text-foreground`,
|
|
22
|
+
`border-border`. No hex values, no `bg-zinc-800`, no `dark:` overrides that
|
|
23
|
+
swap one token for another.
|
|
24
|
+
|
|
25
|
+
## Which component
|
|
26
|
+
|
|
27
|
+
| you want | use | from |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| a page title | `TypographyH1` (add `variant="display"` on marketing pages) | root |
|
|
30
|
+
| a section heading | `TypographyH2` (add `divider` for a rule under it) | root |
|
|
31
|
+
| a subheading | `TypographyH3`, `TypographyH4` | root |
|
|
32
|
+
| a kicker above a heading | `TypographyEyebrow` | root |
|
|
33
|
+
| interface copy, 13px | `TypographyP` | root |
|
|
34
|
+
| the same, secondary ink | `TypographyMuted` | root |
|
|
35
|
+
| reading copy, 18px | `TypographyProse` | root |
|
|
36
|
+
| a bulleted or numbered list | `TypographyList`, `TypographyProseList` | root |
|
|
37
|
+
| a timestamp, count or value | `TypographyCaption` | root |
|
|
38
|
+
| a form label or column header | `TypographyLabel` | root |
|
|
39
|
+
| small print as a block | `TypographySmall` | root |
|
|
40
|
+
| a number or metric | `TypographyStat` | root |
|
|
41
|
+
| inline code | `TypographyInlineCode` | root |
|
|
42
|
+
| a link | `TypographyLink` | root |
|
|
43
|
+
| a highlighted phrase | `TypographyHighlight` | root |
|
|
44
|
+
| a link card, or a grid of them | `Card`, `Cards` | `/blocks` |
|
|
45
|
+
| an aside, warning or note | `Callout` | `/blocks` |
|
|
46
|
+
| numbered instructions | `Steps`, `Step` | `/blocks` |
|
|
47
|
+
| an FAQ or collapsible, no JS | `Disclosure`, `DisclosureGroup` | `/blocks` |
|
|
48
|
+
| an animated accordion | `Accordion` (client) | `/blocks` |
|
|
49
|
+
| tabbed content | `Tabs` or `TabGroup` (client) | `/blocks` |
|
|
50
|
+
| a long-form article page | `EssayHeader` + `EssayLayout` + `EssaySection` | `/essay` |
|
|
51
|
+
| a post meta row (date, read time, tags) | `PostMetaRow` and friends | `/essay` |
|
|
52
|
+
| a table of contents | `TableOfContents`, `ReadingRail` | `/essay` |
|
|
53
|
+
| page metadata and JSON-LD | `createSeo` | `/seo` |
|
|
54
|
+
| an OG image | `ogCard`, `OG_SIZE` | `/og` |
|
|
55
|
+
| to merge classnames | `cn` | root |
|
|
56
|
+
|
|
57
|
+
## Entry points
|
|
58
|
+
|
|
59
|
+
| import | exports |
|
|
60
|
+
|---|---|
|
|
61
|
+
| `@supertype.ai/foundations` | `cn`, `TypographyH1`, `TypographyH2`, `TypographyH3`, `TypographyH4`, `TypographyEyebrow`, `TypographyP`, `TypographyMuted`, `TypographyProse`, `TypographyList`, `TypographyProseList`, `TypographyCaption`, `TypographySmall`, `TypographyLabel`, `TypographyStat`, `TypographyInlineCode`, `TypographyLink`, `TypographyHighlight`, `headingClass`, `eyebrowClass`. Types: `TypographyTag`, `ParagraphVariants`, `ListProps`, `CaptionVariants`, `LabelVariants`, `StatVariants`, `LinkTone`, `HighlightTone` |
|
|
62
|
+
| `@supertype.ai/foundations/blocks` | `Cards`, `Card`, `CardHeader`, `CardTitle`, `CardDescription`, `CardContent`, `Callout`, `Steps`, `Step`, `Disclosure`, `DisclosureGroup`, `Accordion`, `AccordionItem`, `AccordionTrigger`, `AccordionContent`, `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent`, `TabGroup`, `Tab`, `SEGMENT` |
|
|
63
|
+
| `@supertype.ai/foundations/mdx` | `proseMdxComponents` |
|
|
64
|
+
| `@supertype.ai/foundations/essay` | `createEssay`, `EssayHeader`, `EssayLayout`, `EssaySection`, `EssayPullQuote`, `EssayFigure`, `EssayMovements`, `EssayDocument`, `EssayColumns`, `TableOfContents`, `ReadingRail`, `ReadingProgressBar`, `Rail`, `RailLink`, `PostMetaRow`, `PostDate`, `ReadTime`, `TagPills`, `MetaDot`, `formatPostDate`, `extractHeadings`, `readingTime`, `createSlugger`, `useReadingProgress`, `useScrollSpy`. Types: `TocHeading`, `EssayDecorations`, `EssayIndexEntry`, `EssayDocSection`, `EssayMovement`, `PostDateFormat` |
|
|
65
|
+
| `@supertype.ai/foundations/seo` | `createSeo`. Types: `SeoConfig`, `ArticleAuthor`, `ArticleOptions`, `PageMetadata` |
|
|
66
|
+
| `@supertype.ai/foundations/og` | `ogCard`, `OG_SIZE`. Types: `OgCardOptions` |
|
|
67
|
+
| `@supertype.ai/foundations/eslint` | `designConfig` (the whole set as one flat-config entry), plus `colourRules`, `typographyRules`, `themeOverrideRules`, `surfaceAsInkRules`, `renamedTokenRules` for building your own. Types: `FlatConfigEntry`, `DesignConfigOptions`, `RestrictedSyntax`, `ColourOptions`, `TypographyOptions` |
|
|
68
|
+
| `@supertype.ai/foundations/rehype` | `rehypeProseCode`, `proseCodeOptions`, `PROSE_LANGS`, `PROSE_THEMES`. Build-time only, must not resolve React |
|
|
69
|
+
| `@supertype.ai/foundations/contrast` | `checkLegibility` (inks at 4.5:1), `checkSignals` (fills at 3:1, tinted inks at 4.5:1, labels against their own fill), `resolveTokens`, `formatFailures`, `specificity`, `parseColor`, `luminance`, `contrast`. Types: `Rgb`, `Theme`, `LegibilityFailure`. Build-time only |
|
|
70
|
+
|
|
71
|
+
## Props worth knowing
|
|
72
|
+
|
|
73
|
+
- `TypographyH1`, `TypographyH3`: `variant?: "default" | "display"`.
|
|
74
|
+
- `TypographyH2`: `variant?`, plus `divider?: boolean` for a rule underneath.
|
|
75
|
+
- `TypographyP`: `variant?: "ui" | "prose"` (default `ui`), `tone?: "default" | "muted"`.
|
|
76
|
+
- `TypographyMuted`, `TypographyProse`, `TypographyProseList` are presets. The
|
|
77
|
+
prop each one pins is removed from its type, so passing it will not compile.
|
|
78
|
+
- `TypographyCaption`, `TypographyLabel`, `TypographySmall`: `size?: "sm" | "xs" | "2xs" | "inherit"`, `as?`.
|
|
79
|
+
- `TypographyEyebrow`: `tone?: "heading" | "label"`, `as?`.
|
|
80
|
+
- `TypographyStat`: `size?: "inherit" | "card" | "panel" | "page" | "display"`, `figures?: "tabular" | "proportional"`. Keep tabular where a value updates in place.
|
|
81
|
+
- `TypographyLink`: `href` (required), `tone?: "foreground" | "primary" | "secondary"`, `addArrow?`, `newTab?`. Internal versus external is decided from the href.
|
|
82
|
+
- `TypographyHighlight`: `tone?: "primary" | "success" | "ochre" | "terracotta" | "sage" | "fig"`, `seed?: number`.
|
|
83
|
+
- `Card`: `href`, `title`, `description`, `icon`, `external`. An href makes the whole card a link.
|
|
84
|
+
- `Callout`: `tone?: "muted" | "destructive" | "warn" | "accent"`, `density?: "compact" | "editorial"`, `title`, `icon`, `action`.
|
|
85
|
+
- `DisclosureGroup`: `type?: "multiple" | "single"`, `defaultValue` (matches the title string).
|
|
86
|
+
- `TabsList`: `variant?: "default" | "line"`.
|
|
87
|
+
|
|
88
|
+
## Common mistakes
|
|
89
|
+
|
|
90
|
+
- `<p className="text-sm text-muted-foreground">` — use `<TypographyMuted>`.
|
|
91
|
+
- `<h2 className="text-lg font-semibold">` — use `<TypographyH2>`, or
|
|
92
|
+
`headingClass()` if you must pass classes to someone else's component.
|
|
93
|
+
- Importing `Card` or `Callout` from `@supertype.ai/foundations`. They live in
|
|
94
|
+
`@supertype.ai/foundations/blocks`.
|
|
95
|
+
- `<TypographyMuted tone="default">` — a type error. Use `TypographyP`.
|
|
96
|
+
- Binding fonts with `font.className` instead of `font.variable`. The className
|
|
97
|
+
form sets `font-family` on the element and leaves the roles unresolved.
|
|
98
|
+
- Omitting `@source '../node_modules/@supertype.ai/foundations/dist/**/*.js'` from
|
|
99
|
+
the CSS entry. Tailwind then purges every class the package ships.
|
|
100
|
+
- Omitting `@import "@supertype.ai/foundations/theme.css"`. `tokens.css` names the
|
|
101
|
+
colour roles but holds no values, so the whole palette resolves to nothing.
|
|
102
|
+
- Using `Accordion` for a static FAQ. `Disclosure` needs no JavaScript.
|
|
103
|
+
- Adding a second `@custom-variant dark`. `tokens.css` already binds it.
|
|
104
|
+
|
|
105
|
+
Run `npx foundations doctor` in the app to check the last four.
|
|
106
|
+
|
|
107
|
+
## Surfaces
|
|
108
|
+
|
|
109
|
+
Two classes change how everything renders, and both go on `<html>` or a subtree:
|
|
110
|
+
|
|
111
|
+
- `.dark` re-points every colour token. It is bound by `tokens.css`, not by the
|
|
112
|
+
OS setting.
|
|
113
|
+
- `.editorial` gives the heading role to the serif at weight 400 and retunes the
|
|
114
|
+
whole heading ladder against an 18px body, instead of the product's 13px.
|
|
115
|
+
|
|
116
|
+
## Docs
|
|
117
|
+
|
|
118
|
+
Read from `node_modules`, so these are absolute:
|
|
119
|
+
|
|
120
|
+
- README: https://github.com/supertypeai/foundations#readme
|
|
121
|
+
- Typography: https://github.com/supertypeai/foundations/blob/main/docs/typography.md
|
|
122
|
+
- Blocks and MDX: https://github.com/supertypeai/foundations/blob/main/docs/blocks.md
|
|
123
|
+
- The essay shell: https://github.com/supertypeai/foundations/blob/main/docs/essay.md
|
|
124
|
+
- Build-time tooling: https://github.com/supertypeai/foundations/blob/main/docs/tooling.md
|
|
125
|
+
- The CLI: https://github.com/supertypeai/foundations/blob/main/docs/cli.md
|
package/package.json
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@supertype.ai/foundations",
|
|
3
|
+
"version": "0.1.24",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public",
|
|
7
|
+
"registry": "https://registry.npmjs.org/"
|
|
8
|
+
},
|
|
9
|
+
"description": "Shared typography, prose, essay, and building blocks for Supertype projects.",
|
|
10
|
+
"keywords": [
|
|
11
|
+
"design-system",
|
|
12
|
+
"design-tokens",
|
|
13
|
+
"typography",
|
|
14
|
+
"prose",
|
|
15
|
+
"essay",
|
|
16
|
+
"mdx",
|
|
17
|
+
"react",
|
|
18
|
+
"nextjs",
|
|
19
|
+
"tailwind",
|
|
20
|
+
"css",
|
|
21
|
+
"accessibility",
|
|
22
|
+
"contrast",
|
|
23
|
+
"eslint-plugin"
|
|
24
|
+
],
|
|
25
|
+
"type": "module",
|
|
26
|
+
"sideEffects": [
|
|
27
|
+
"*.css"
|
|
28
|
+
],
|
|
29
|
+
"files": [
|
|
30
|
+
"bin",
|
|
31
|
+
"dist",
|
|
32
|
+
"llms.txt",
|
|
33
|
+
"src/*.css",
|
|
34
|
+
"LICENSE"
|
|
35
|
+
],
|
|
36
|
+
"bin": {
|
|
37
|
+
"foundations": "./bin/foundations.mjs"
|
|
38
|
+
},
|
|
39
|
+
"exports": {
|
|
40
|
+
".": {
|
|
41
|
+
"types": "./dist/index.d.ts",
|
|
42
|
+
"default": "./dist/index.js"
|
|
43
|
+
},
|
|
44
|
+
"./blocks": {
|
|
45
|
+
"types": "./dist/blocks/index.d.ts",
|
|
46
|
+
"default": "./dist/blocks/index.js"
|
|
47
|
+
},
|
|
48
|
+
"./mdx": {
|
|
49
|
+
"types": "./dist/mdx.d.ts",
|
|
50
|
+
"default": "./dist/mdx.js"
|
|
51
|
+
},
|
|
52
|
+
"./essay": {
|
|
53
|
+
"types": "./dist/essay/index.d.ts",
|
|
54
|
+
"default": "./dist/essay/index.js"
|
|
55
|
+
},
|
|
56
|
+
"./seo": {
|
|
57
|
+
"types": "./dist/seo.d.ts",
|
|
58
|
+
"default": "./dist/seo.js"
|
|
59
|
+
},
|
|
60
|
+
"./contrast": {
|
|
61
|
+
"types": "./dist/contrast.d.ts",
|
|
62
|
+
"default": "./dist/contrast.js"
|
|
63
|
+
},
|
|
64
|
+
"./eslint": {
|
|
65
|
+
"types": "./dist/eslint.d.ts",
|
|
66
|
+
"require": "./dist/cjs/eslint.js",
|
|
67
|
+
"default": "./dist/eslint.js"
|
|
68
|
+
},
|
|
69
|
+
"./rehype": {
|
|
70
|
+
"types": "./dist/rehype.d.ts",
|
|
71
|
+
"default": "./dist/rehype.js"
|
|
72
|
+
},
|
|
73
|
+
"./tokens.css": "./src/tokens.css",
|
|
74
|
+
"./theme.css": "./src/theme.css",
|
|
75
|
+
"./type.css": "./src/type.css",
|
|
76
|
+
"./prose.css": "./src/prose.css",
|
|
77
|
+
"./shiki.css": "./src/shiki.css",
|
|
78
|
+
"./og": {
|
|
79
|
+
"types": "./dist/og.d.ts",
|
|
80
|
+
"default": "./dist/og.js"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"scripts": {
|
|
84
|
+
"build": "tsc -p tsconfig.json && tsc -p tsconfig.cjs.json && node scripts/cjs-marker.mjs && node scripts/check-llms.mjs && node scripts/pins.mjs",
|
|
85
|
+
"dev": "tsc -p tsconfig.json --watch",
|
|
86
|
+
"test": "yarn build && vitest run",
|
|
87
|
+
"test:watch": "vitest",
|
|
88
|
+
"check:llms": "node scripts/check-llms.mjs",
|
|
89
|
+
"check:pins": "node scripts/pins.mjs",
|
|
90
|
+
"release": "node scripts/release.mjs",
|
|
91
|
+
"sync": "node scripts/sync.mjs",
|
|
92
|
+
"dev:sync": "node scripts/sync.mjs --watch",
|
|
93
|
+
"example": "node scripts/sync.mjs examples/site && yarn --cwd examples/site dev",
|
|
94
|
+
"example:install": "yarn --cwd examples/site install",
|
|
95
|
+
"example:build": "node scripts/sync.mjs examples/site && yarn --cwd examples/site build",
|
|
96
|
+
"example:pinned": "node scripts/pinned.mjs",
|
|
97
|
+
"example:static": "node scripts/sync.mjs examples/site && yarn --cwd examples/site build:static",
|
|
98
|
+
"prepublishOnly": "yarn build"
|
|
99
|
+
},
|
|
100
|
+
"dependencies": {
|
|
101
|
+
"@shikijs/rehype": "^2.3.2",
|
|
102
|
+
"class-variance-authority": "^0.7.1",
|
|
103
|
+
"clsx": "^2.1.1",
|
|
104
|
+
"shiki": "^2.3.2",
|
|
105
|
+
"tailwind-merge": "^3.0.0"
|
|
106
|
+
},
|
|
107
|
+
"peerDependencies": {
|
|
108
|
+
"@base-ui/react": ">=1.4",
|
|
109
|
+
"next": ">=15",
|
|
110
|
+
"next-view-transitions": ">=0.3",
|
|
111
|
+
"react": ">=19"
|
|
112
|
+
},
|
|
113
|
+
"devDependencies": {
|
|
114
|
+
"@base-ui/react": "^1.4.1",
|
|
115
|
+
"@types/react": "^19.0.0",
|
|
116
|
+
"next": "^15.5.7",
|
|
117
|
+
"next-view-transitions": "^0.3.5",
|
|
118
|
+
"react": "^19.0.0",
|
|
119
|
+
"typescript": "^5.7.0",
|
|
120
|
+
"vitest": "4.1.11"
|
|
121
|
+
},
|
|
122
|
+
"author": {
|
|
123
|
+
"name": "Samuel Chan",
|
|
124
|
+
"url": "https://supertype.ai/p/samuel"
|
|
125
|
+
},
|
|
126
|
+
"repository": {
|
|
127
|
+
"type": "git",
|
|
128
|
+
"url": "git+https://github.com/supertypeai/foundations.git"
|
|
129
|
+
},
|
|
130
|
+
"homepage": "https://github.com/supertypeai/foundations#readme",
|
|
131
|
+
"contributors": [
|
|
132
|
+
{
|
|
133
|
+
"name": "Supertype Pte. Ltd.",
|
|
134
|
+
"url": "https://supertype.ai"
|
|
135
|
+
}
|
|
136
|
+
],
|
|
137
|
+
"bugs": {
|
|
138
|
+
"url": "https://github.com/supertypeai/foundations/issues"
|
|
139
|
+
}
|
|
140
|
+
}
|
package/src/prose.css
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/* `code` fires for both an inline span and the <code> in a fence, and the
|
|
2
|
+
`language-*` class that tells them apart does not survive a host swapping in
|
|
3
|
+
its own code block. A child combinator knows what the component cannot. */
|
|
4
|
+
|
|
5
|
+
:not(pre) > code {
|
|
6
|
+
border-radius: 0.25rem;
|
|
7
|
+
background-color: var(--muted);
|
|
8
|
+
padding: 0.125rem 0.375rem;
|
|
9
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
10
|
+
font-size: 0.85em;
|
|
11
|
+
color: var(--foreground);
|
|
12
|
+
}
|