@tea-ui/public 0.1.0
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 +33 -0
- package/dist/index.d.ts +196 -0
- package/dist/index.js +285 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.css +2 -0
- package/package.json +60 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 landnevermore
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# @tea-ui/public
|
|
2
|
+
|
|
3
|
+
The public layer: marketing sections, hero, pricing, FAQ, conversion forms.
|
|
4
|
+
|
|
5
|
+
Part of [TEA UI](https://landnevermore.github.io/TEAui/) — a design system built once and reused across
|
|
6
|
+
products. The whole system is documented at https://landnevermore.github.io/TEAui/docs/.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @tea-ui/public
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
React 18.2 or 19 is expected as a peer dependency.
|
|
15
|
+
|
|
16
|
+
## Use
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import { Button } from "@tea-ui/public";
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Styles
|
|
23
|
+
|
|
24
|
+
The token layer ships its stylesheet as a separate export, so it is only
|
|
25
|
+
downloaded when it is asked for:
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import "@tea-ui/public/styles.css";
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Licence
|
|
32
|
+
|
|
33
|
+
MIT. See [LICENSE](./LICENSE).
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export { Slot } from 'radix-ui';
|
|
3
|
+
export { Box, Container, InlineCode } from '@tea-ui/core';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* TEA UI Public — website chrome and marketing sections.
|
|
7
|
+
*
|
|
8
|
+
* Public UI is **not** Admin UI with different colours, and this file is where
|
|
9
|
+
* that has to be true. The differences are structural, and each one is a
|
|
10
|
+
* consequence of the audience:
|
|
11
|
+
*
|
|
12
|
+
* - **Measure.** Admin text runs to the edge because a table needs the width.
|
|
13
|
+
* Prose does not: it runs to `max-w-3xl`, because a 120-character line is
|
|
14
|
+
* unreadable. Every section here is width-constrained for that reason.
|
|
15
|
+
* - **Type size.** Admin lives at `text-ui` (14px). Public body text is
|
|
16
|
+
* `text-body` (16px) minimum, and lead text is larger still. The audit found
|
|
17
|
+
* real text at 9px and 10px in the *admin* surfaces; a marketing page would
|
|
18
|
+
* be worse.
|
|
19
|
+
* - **Rhythm.** Sections are separated by far more space than panels are,
|
|
20
|
+
* because a page is a scroll narrative and a panel is a work surface.
|
|
21
|
+
* - **Conversion.** The primary action repeats per section. On an admin page a
|
|
22
|
+
* repeated primary button is noise; on a public page it is the point.
|
|
23
|
+
*/
|
|
24
|
+
type PublicSize = "sm" | "md" | "lg";
|
|
25
|
+
interface SectionProps extends React.ComponentProps<"section"> {
|
|
26
|
+
/** Vertical rhythm. `tight` sits between related blocks, `loose` between them. */
|
|
27
|
+
spacing?: "tight" | "normal" | "loose" | undefined;
|
|
28
|
+
/** A hairline separator above the section. */
|
|
29
|
+
bordered?: boolean | undefined;
|
|
30
|
+
children: React.ReactNode;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The unit of a marketing page. Everything in the Public layer is a `Section`,
|
|
34
|
+
* so page rhythm is decided once and a page cannot accidentally use six
|
|
35
|
+
* different vertical gaps.
|
|
36
|
+
*/
|
|
37
|
+
declare const Section: React.ForwardRefExoticComponent<Omit<SectionProps, "ref"> & React.RefAttributes<HTMLElement>>;
|
|
38
|
+
interface HeroProps extends React.ComponentProps<"section"> {
|
|
39
|
+
/** The eyebrow above the headline. Sets the category, not the value. */
|
|
40
|
+
eyebrow?: string | undefined;
|
|
41
|
+
/** The headline. One sentence, the thing a visitor must understand. */
|
|
42
|
+
title: string;
|
|
43
|
+
/** The promise. One or two sentences, plain, no jargon. */
|
|
44
|
+
lead?: string | undefined;
|
|
45
|
+
/** Primary and secondary actions. */
|
|
46
|
+
actions?: React.ReactNode | undefined;
|
|
47
|
+
/** Trust markers under the actions: "Seit 2019", "Made in Germany", logos. */
|
|
48
|
+
reassurance?: React.ReactNode | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* A visual below the copy — a screenshot, a diagram, a live demo. Optional,
|
|
51
|
+
* because a hero that is only words is a legitimate hero, and forcing an empty
|
|
52
|
+
* wrapper element to satisfy the type would be worse than the optional.
|
|
53
|
+
*/
|
|
54
|
+
children?: React.ReactNode | undefined;
|
|
55
|
+
}
|
|
56
|
+
declare const Hero: React.ForwardRefExoticComponent<Omit<HeroProps, "ref"> & React.RefAttributes<HTMLElement>>;
|
|
57
|
+
interface SectionHeadingProps {
|
|
58
|
+
eyebrow?: string | undefined;
|
|
59
|
+
title: string;
|
|
60
|
+
lead?: string | undefined;
|
|
61
|
+
/** `center` for a self-contained block, `start` when text follows it. */
|
|
62
|
+
align?: "start" | "center" | undefined;
|
|
63
|
+
level?: 2 | 3 | undefined;
|
|
64
|
+
className?: string | undefined;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* The heading of a content block. `align="center"` is a real decision, not a
|
|
68
|
+
* default: centred text with a centred image reads as a unit, and a centred
|
|
69
|
+
* section followed by left-aligned content reads as a mistake.
|
|
70
|
+
*/
|
|
71
|
+
declare const SectionHeading: React.ForwardRefExoticComponent<SectionHeadingProps & React.RefAttributes<HTMLDivElement>>;
|
|
72
|
+
interface FeatureGridProps extends React.ComponentProps<"div"> {
|
|
73
|
+
cols?: 2 | 3 | 4 | undefined;
|
|
74
|
+
/** Minimum column width; the grid auto-fits below the breakpoint. */
|
|
75
|
+
minItemWidth?: string | undefined;
|
|
76
|
+
children: React.ReactNode;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The auto-fit grid is the reason a TEA marketing page has no per-breakpoint
|
|
80
|
+
* column counts. The audit found the same class string
|
|
81
|
+
* (`mt-10 grid gap-4 md:grid-cols-2 lg:grid-cols-3`) copy-pasted at six sites,
|
|
82
|
+
* drifting to `md:grid-cols-3` and `md:grid-cols-4` as the density changed.
|
|
83
|
+
*/
|
|
84
|
+
declare const FeatureGrid: React.ForwardRefExoticComponent<Omit<FeatureGridProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
85
|
+
interface FeatureProps extends React.ComponentProps<"article"> {
|
|
86
|
+
title: string;
|
|
87
|
+
description: string;
|
|
88
|
+
icon?: React.ReactNode | undefined;
|
|
89
|
+
/** A short proof line: a number, a benchmark, a customer. */
|
|
90
|
+
proof?: string | undefined;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* A feature. It is an `<article>`, not a `div`, because a feature is a
|
|
94
|
+
* self-contained claim and an article is what that is in the document outline.
|
|
95
|
+
*/
|
|
96
|
+
declare const Feature: React.ForwardRefExoticComponent<Omit<FeatureProps, "ref"> & React.RefAttributes<HTMLElement>>;
|
|
97
|
+
interface CallToActionProps extends React.ComponentProps<"section"> {
|
|
98
|
+
title: string;
|
|
99
|
+
lead?: string | undefined;
|
|
100
|
+
actions: React.ReactNode;
|
|
101
|
+
/** `banner` closes the page; `inline` sits inside a section. */
|
|
102
|
+
variant?: "banner" | "inline" | undefined;
|
|
103
|
+
}
|
|
104
|
+
declare const CallToAction: React.ForwardRefExoticComponent<Omit<CallToActionProps, "ref"> & React.RefAttributes<HTMLElement>>;
|
|
105
|
+
interface FaqItem {
|
|
106
|
+
question: string;
|
|
107
|
+
answer: React.ReactNode;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* A FAQ.
|
|
111
|
+
*
|
|
112
|
+
* A `<details>`/`<summary>` pair, not a component with JavaScript: the browser
|
|
113
|
+
* already implements expand, collapse, keyboard operation and the correct
|
|
114
|
+
* semantics, and every hand-rolled accordion FAQ in the audit shipped without
|
|
115
|
+
* `aria-expanded`.
|
|
116
|
+
*/
|
|
117
|
+
declare const Faq: React.ForwardRefExoticComponent<Omit<React.ClassAttributes<HTMLDivElement> & React.HTMLAttributes<HTMLDivElement> & {
|
|
118
|
+
items: readonly FaqItem[];
|
|
119
|
+
}, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
120
|
+
interface PricingTier {
|
|
121
|
+
name: string;
|
|
122
|
+
price: string;
|
|
123
|
+
/** The billing period, e.g. "pro Monat". */
|
|
124
|
+
period?: string | undefined;
|
|
125
|
+
description?: string | undefined;
|
|
126
|
+
features: readonly string[];
|
|
127
|
+
highlighted?: boolean | undefined;
|
|
128
|
+
action?: React.ReactNode | undefined;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Pricing.
|
|
132
|
+
*
|
|
133
|
+
* The price is the largest type on the card, because that is what the visitor
|
|
134
|
+
* came for. A card that lists eleven features in eleven equal rows gives the
|
|
135
|
+
* price the same weight as the last row item, which buries the decision.
|
|
136
|
+
*/
|
|
137
|
+
declare const PricingTable: React.ForwardRefExoticComponent<Omit<React.ClassAttributes<HTMLDivElement> & React.HTMLAttributes<HTMLDivElement> & {
|
|
138
|
+
tiers: readonly PricingTier[];
|
|
139
|
+
}, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
140
|
+
interface PublicNavLink {
|
|
141
|
+
label: string;
|
|
142
|
+
href: string;
|
|
143
|
+
/** Opens in a new tab. Adds `rel` and an accessible hint. */
|
|
144
|
+
external?: boolean | undefined;
|
|
145
|
+
}
|
|
146
|
+
interface PublicNavbarProps extends React.ComponentProps<"header"> {
|
|
147
|
+
brand: React.ReactNode;
|
|
148
|
+
links: readonly PublicNavLink[];
|
|
149
|
+
/** Always-visible action, e.g. "Anmelden". */
|
|
150
|
+
action?: React.ReactNode | undefined;
|
|
151
|
+
/** Id of the main region, for the skip link. */
|
|
152
|
+
mainId?: string | undefined;
|
|
153
|
+
className?: string | undefined;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* A public navbar.
|
|
157
|
+
*
|
|
158
|
+
* The audit found the decisive defect in a real public header: the desktop nav
|
|
159
|
+
* was `hidden md:flex` and **there was no mobile menu at all**, so the entire
|
|
160
|
+
* navigation simply disappeared below 768px. Below `md` this becomes a drawer
|
|
161
|
+
* with the same links, because a hidden navigation is not a responsive
|
|
162
|
+
* navigation.
|
|
163
|
+
*/
|
|
164
|
+
declare const PublicNavbar: React.ForwardRefExoticComponent<Omit<PublicNavbarProps, "ref"> & React.RefAttributes<HTMLElement>>;
|
|
165
|
+
interface PublicFooterProps extends React.ComponentProps<"footer"> {
|
|
166
|
+
brand: React.ReactNode;
|
|
167
|
+
/** Label-to-link column groups. */
|
|
168
|
+
columns: ReadonlyArray<{
|
|
169
|
+
heading: string;
|
|
170
|
+
links: readonly PublicNavLink[];
|
|
171
|
+
}>;
|
|
172
|
+
/** Legal line: imprint, privacy, copyright. Never optional on a public site. */
|
|
173
|
+
legal: React.ReactNode;
|
|
174
|
+
className?: string | undefined;
|
|
175
|
+
}
|
|
176
|
+
declare const PublicFooter: React.ForwardRefExoticComponent<Omit<PublicFooterProps, "ref"> & React.RefAttributes<HTMLElement>>;
|
|
177
|
+
interface ConversionFormProps extends React.ComponentProps<"form"> {
|
|
178
|
+
title: string;
|
|
179
|
+
description?: string | undefined;
|
|
180
|
+
/** Submit handler. The form shows no success state on its own. */
|
|
181
|
+
onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
|
|
182
|
+
/** Rendered while submitting. Disable the submit control as well. */
|
|
183
|
+
busy?: boolean | undefined;
|
|
184
|
+
submitLabel?: string | undefined;
|
|
185
|
+
children: React.ReactNode;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* A conversion form.
|
|
189
|
+
*
|
|
190
|
+
* The audit found a public contact form whose `<label>` elements were never
|
|
191
|
+
* associated with their controls, and a login form with a working `htmlFor` that
|
|
192
|
+
* was the exception. `Field` makes the correct version the shortest one.
|
|
193
|
+
*/
|
|
194
|
+
declare const ConversionForm: React.ForwardRefExoticComponent<Omit<ConversionFormProps, "ref"> & React.RefAttributes<HTMLFormElement>>;
|
|
195
|
+
|
|
196
|
+
export { CallToAction, type CallToActionProps, ConversionForm, type ConversionFormProps, Faq, type FaqItem, Feature, FeatureGrid, type FeatureGridProps, type FeatureProps, Hero, type HeroProps, PricingTable, type PricingTier, PublicFooter, type PublicFooterProps, type PublicNavLink, PublicNavbar, type PublicNavbarProps, type PublicSize, Section, SectionHeading, type SectionHeadingProps, type SectionProps };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { Slot } from "radix-ui";
|
|
4
|
+
import { Menu, X } from "@tea-ui/icons";
|
|
5
|
+
import { cn } from "@tea-ui/utils";
|
|
6
|
+
import { COPY } from "@tea-ui/ux-standards";
|
|
7
|
+
import {
|
|
8
|
+
Box,
|
|
9
|
+
Button,
|
|
10
|
+
Container,
|
|
11
|
+
Divider,
|
|
12
|
+
Drawer,
|
|
13
|
+
DrawerBody,
|
|
14
|
+
DrawerContent,
|
|
15
|
+
DrawerHeader,
|
|
16
|
+
DrawerTitle,
|
|
17
|
+
Heading,
|
|
18
|
+
HStack,
|
|
19
|
+
IconButton,
|
|
20
|
+
InlineCode,
|
|
21
|
+
Link,
|
|
22
|
+
SkipLink,
|
|
23
|
+
Stack,
|
|
24
|
+
Text
|
|
25
|
+
} from "@tea-ui/core";
|
|
26
|
+
const Section = React.forwardRef(function Section2({ spacing = "normal", bordered = false, className, children, ...props }, ref) {
|
|
27
|
+
return /* @__PURE__ */ jsx(
|
|
28
|
+
"section",
|
|
29
|
+
{
|
|
30
|
+
ref,
|
|
31
|
+
className: cn(
|
|
32
|
+
spacing === "tight" && "py-8",
|
|
33
|
+
spacing === "normal" && "py-14",
|
|
34
|
+
spacing === "loose" && "py-20",
|
|
35
|
+
bordered && "border-t border-line",
|
|
36
|
+
className
|
|
37
|
+
),
|
|
38
|
+
...props,
|
|
39
|
+
children
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
const Hero = React.forwardRef(function Hero2({ eyebrow, title, lead, actions, reassurance, className, children, ...props }, ref) {
|
|
44
|
+
return /* @__PURE__ */ jsx("section", { ref, className: cn("border-b border-line py-20", className), ...props, children: /* @__PURE__ */ jsxs(Container, { size: "lg", children: [
|
|
45
|
+
/* @__PURE__ */ jsxs("div", { className: "max-w-3xl", children: [
|
|
46
|
+
eyebrow ? /* @__PURE__ */ jsx("p", { className: "text-label font-semibold uppercase tracking-widest text-primary", children: eyebrow }) : null,
|
|
47
|
+
/* @__PURE__ */ jsx(Heading, { level: 1, className: "mt-3 text-hero", children: title }),
|
|
48
|
+
lead ? /* @__PURE__ */ jsx(Text, { size: "lead", tone: "muted", className: "mt-5 max-w-2xl", children: lead }) : null,
|
|
49
|
+
actions ? /* @__PURE__ */ jsx(HStack, { gap: "ui", className: "mt-8", children: actions }) : null,
|
|
50
|
+
reassurance ? /* @__PURE__ */ jsx("div", { className: "mt-8 flex flex-wrap items-center gap-x-6 gap-y-2 text-micro text-fg-subtle", children: reassurance }) : null
|
|
51
|
+
] }),
|
|
52
|
+
children ? /* @__PURE__ */ jsx("div", { className: "mt-12", children }) : null
|
|
53
|
+
] }) });
|
|
54
|
+
});
|
|
55
|
+
const SectionHeading = React.forwardRef(
|
|
56
|
+
function SectionHeading2({ eyebrow, title, lead, align = "start", level = 2, className }, ref) {
|
|
57
|
+
return /* @__PURE__ */ jsxs(
|
|
58
|
+
"div",
|
|
59
|
+
{
|
|
60
|
+
ref,
|
|
61
|
+
className: cn(
|
|
62
|
+
"flex flex-col gap-3",
|
|
63
|
+
align === "center" && "items-center text-center",
|
|
64
|
+
className
|
|
65
|
+
),
|
|
66
|
+
children: [
|
|
67
|
+
eyebrow ? /* @__PURE__ */ jsx("p", { className: "text-label font-semibold uppercase tracking-widest text-primary", children: eyebrow }) : null,
|
|
68
|
+
/* @__PURE__ */ jsx(Heading, { level, className: level === 2 ? "max-w-2xl" : void 0, children: title }),
|
|
69
|
+
lead ? /* @__PURE__ */ jsx(Text, { size: "lead", tone: "muted", className: cn("max-w-2xl", align === "center" && "mx-auto"), children: lead }) : null
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
const FeatureGrid = React.forwardRef(function FeatureGrid2({ cols = 3, minItemWidth = "16rem", className, children, style, ...props }, ref) {
|
|
76
|
+
return /* @__PURE__ */ jsx(
|
|
77
|
+
"div",
|
|
78
|
+
{
|
|
79
|
+
ref,
|
|
80
|
+
style: {
|
|
81
|
+
gridTemplateColumns: `repeat(auto-fit, minmax(min(${minItemWidth}, 100%), 1fr))`,
|
|
82
|
+
...style
|
|
83
|
+
},
|
|
84
|
+
className: cn("grid gap-6", className),
|
|
85
|
+
"data-cols": cols,
|
|
86
|
+
...props,
|
|
87
|
+
children
|
|
88
|
+
}
|
|
89
|
+
);
|
|
90
|
+
});
|
|
91
|
+
const Feature = React.forwardRef(function Feature2({ title, description, icon, proof, className, ...props }, ref) {
|
|
92
|
+
return /* @__PURE__ */ jsxs("article", { ref, className: cn("flex flex-col gap-3", className), ...props, children: [
|
|
93
|
+
icon ? /* @__PURE__ */ jsx(
|
|
94
|
+
"span",
|
|
95
|
+
{
|
|
96
|
+
"aria-hidden": "true",
|
|
97
|
+
className: "flex size-10 items-center justify-center bg-accent text-accent-fg",
|
|
98
|
+
children: icon
|
|
99
|
+
}
|
|
100
|
+
) : null,
|
|
101
|
+
/* @__PURE__ */ jsx(Heading, { level: 3, children: title }),
|
|
102
|
+
/* @__PURE__ */ jsx(Text, { size: "body", tone: "muted", children: description }),
|
|
103
|
+
proof ? /* @__PURE__ */ jsx(Text, { size: "micro", tone: "subtle", className: "font-mono", children: proof }) : null
|
|
104
|
+
] });
|
|
105
|
+
});
|
|
106
|
+
const CallToAction = React.forwardRef(function CallToAction2({ title, lead, actions, variant = "banner", className, ...props }, ref) {
|
|
107
|
+
return /* @__PURE__ */ jsx(
|
|
108
|
+
"section",
|
|
109
|
+
{
|
|
110
|
+
ref,
|
|
111
|
+
className: cn(
|
|
112
|
+
variant === "banner" ? "border-t border-line py-20" : "py-10",
|
|
113
|
+
className
|
|
114
|
+
),
|
|
115
|
+
...props,
|
|
116
|
+
children: /* @__PURE__ */ jsx(Container, { size: "lg", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start justify-between gap-6 md:flex-row md:items-center", children: [
|
|
117
|
+
/* @__PURE__ */ jsxs("div", { className: "max-w-2xl", children: [
|
|
118
|
+
/* @__PURE__ */ jsx(Heading, { level: 2, children: title }),
|
|
119
|
+
lead ? /* @__PURE__ */ jsx(Text, { size: "lead", tone: "muted", className: "mt-3", children: lead }) : null
|
|
120
|
+
] }),
|
|
121
|
+
/* @__PURE__ */ jsx(HStack, { gap: "ui", className: "shrink-0", children: actions })
|
|
122
|
+
] }) })
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
});
|
|
126
|
+
const Faq = React.forwardRef(
|
|
127
|
+
function Faq2({ items, className, ...props }, ref) {
|
|
128
|
+
return /* @__PURE__ */ jsx("div", { ref, className: cn("mx-auto flex max-w-3xl flex-col", className), ...props, children: items.map((item) => /* @__PURE__ */ jsxs("details", { className: "group border-b border-line py-5", children: [
|
|
129
|
+
/* @__PURE__ */ jsxs("summary", { className: "flex cursor-pointer list-none items-center justify-between gap-4 text-ui font-medium text-fg marker:content-none", children: [
|
|
130
|
+
item.question,
|
|
131
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "text-primary transition-transform group-open:rotate-45", children: "+" })
|
|
132
|
+
] }),
|
|
133
|
+
/* @__PURE__ */ jsx("div", { className: "mt-3 text-body text-fg-muted", children: item.answer })
|
|
134
|
+
] }, item.question)) });
|
|
135
|
+
}
|
|
136
|
+
);
|
|
137
|
+
const PricingTable = React.forwardRef(function PricingTable2({ tiers, className, ...props }, ref) {
|
|
138
|
+
return /* @__PURE__ */ jsx("div", { ref, className: cn("grid gap-6 md:grid-cols-3", className), ...props, children: tiers.map((tier) => /* @__PURE__ */ jsxs(
|
|
139
|
+
"div",
|
|
140
|
+
{
|
|
141
|
+
className: cn(
|
|
142
|
+
"flex flex-col gap-5 border bg-surface p-6",
|
|
143
|
+
tier.highlighted ? "border-primary" : "border-line"
|
|
144
|
+
),
|
|
145
|
+
children: [
|
|
146
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
147
|
+
/* @__PURE__ */ jsx(Text, { size: "label", tone: tier.highlighted ? "accent" : "muted", className: "font-semibold uppercase tracking-widest", children: tier.name }),
|
|
148
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-baseline gap-2", children: [
|
|
149
|
+
/* @__PURE__ */ jsx("span", { className: "text-display font-semibold text-fg", children: tier.price }),
|
|
150
|
+
tier.period ? /* @__PURE__ */ jsx(Text, { size: "micro", tone: "muted", children: tier.period }) : null
|
|
151
|
+
] }),
|
|
152
|
+
tier.description ? /* @__PURE__ */ jsx(Text, { size: "micro", tone: "muted", className: "mt-2", children: tier.description }) : null
|
|
153
|
+
] }),
|
|
154
|
+
/* @__PURE__ */ jsx("ul", { className: "flex flex-1 flex-col gap-2", children: tier.features.map((feature) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-2 text-ui text-fg-muted", children: [
|
|
155
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "mt-1.5 size-1.5 shrink-0 rounded-pill bg-primary" }),
|
|
156
|
+
feature
|
|
157
|
+
] }, feature)) }),
|
|
158
|
+
tier.action
|
|
159
|
+
]
|
|
160
|
+
},
|
|
161
|
+
tier.name
|
|
162
|
+
)) });
|
|
163
|
+
});
|
|
164
|
+
const PublicNavbar = React.forwardRef(function PublicNavbar2({ brand, links, action, mainId = "tea-public-main", className, children, ...props }, ref) {
|
|
165
|
+
const [open, setOpen] = React.useState(false);
|
|
166
|
+
return /* @__PURE__ */ jsxs(
|
|
167
|
+
"header",
|
|
168
|
+
{
|
|
169
|
+
ref,
|
|
170
|
+
className: cn("sticky top-0 z-header border-b border-line bg-canvas", className),
|
|
171
|
+
...props,
|
|
172
|
+
children: [
|
|
173
|
+
/* @__PURE__ */ jsx(SkipLink, { targetId: mainId }),
|
|
174
|
+
/* @__PURE__ */ jsxs(Container, { size: "full", className: "flex h-16 items-center gap-6", children: [
|
|
175
|
+
/* @__PURE__ */ jsx(Link, { href: "#", className: "text-ui font-semibold tracking-tight text-fg no-underline hover:no-underline", children: brand }),
|
|
176
|
+
/* @__PURE__ */ jsx("nav", { "aria-label": COPY.navigation.main, className: "hidden items-center gap-5 md:flex", children: links.map((link) => /* @__PURE__ */ jsx(
|
|
177
|
+
Link,
|
|
178
|
+
{
|
|
179
|
+
href: link.href,
|
|
180
|
+
external: link.external,
|
|
181
|
+
className: "text-ui text-fg-muted no-underline hover:text-fg hover:no-underline",
|
|
182
|
+
children: link.label
|
|
183
|
+
},
|
|
184
|
+
link.href
|
|
185
|
+
)) }),
|
|
186
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "ui", className: "ms-auto", children: [
|
|
187
|
+
action,
|
|
188
|
+
/* @__PURE__ */ jsx(
|
|
189
|
+
IconButton,
|
|
190
|
+
{
|
|
191
|
+
label: COPY.navigation.openMenu,
|
|
192
|
+
variant: "ghost",
|
|
193
|
+
className: "md:hidden",
|
|
194
|
+
"aria-expanded": open,
|
|
195
|
+
"aria-haspopup": "dialog",
|
|
196
|
+
onClick: () => setOpen(true),
|
|
197
|
+
children: /* @__PURE__ */ jsx(Menu, { size: 20, "aria-hidden": "true" })
|
|
198
|
+
}
|
|
199
|
+
)
|
|
200
|
+
] })
|
|
201
|
+
] }),
|
|
202
|
+
children,
|
|
203
|
+
/* @__PURE__ */ jsx(Drawer, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxs(DrawerContent, { side: "end", className: "w-80", children: [
|
|
204
|
+
/* @__PURE__ */ jsx(DrawerHeader, { children: /* @__PURE__ */ jsxs(DrawerTitle, { className: "flex items-center justify-between text-ui", children: [
|
|
205
|
+
COPY.navigation.main,
|
|
206
|
+
/* @__PURE__ */ jsx(IconButton, { label: COPY.navigation.closeMenu, variant: "ghost", size: "sm", onClick: () => setOpen(false), children: /* @__PURE__ */ jsx(X, { size: 18, "aria-hidden": "true" }) })
|
|
207
|
+
] }) }),
|
|
208
|
+
/* @__PURE__ */ jsx(DrawerBody, { children: /* @__PURE__ */ jsx("nav", { "aria-label": COPY.navigation.main, children: /* @__PURE__ */ jsx(Stack, { gap: "ui", children: links.map((link) => /* @__PURE__ */ jsx(
|
|
209
|
+
Link,
|
|
210
|
+
{
|
|
211
|
+
href: link.href,
|
|
212
|
+
external: link.external,
|
|
213
|
+
className: "text-ui text-fg no-underline hover:text-primary hover:no-underline",
|
|
214
|
+
onClick: () => setOpen(false),
|
|
215
|
+
children: link.label
|
|
216
|
+
},
|
|
217
|
+
link.href
|
|
218
|
+
)) }) }) })
|
|
219
|
+
] }) })
|
|
220
|
+
]
|
|
221
|
+
}
|
|
222
|
+
);
|
|
223
|
+
});
|
|
224
|
+
const PublicFooter = React.forwardRef(function PublicFooter2({ brand, columns, legal, className, ...props }, ref) {
|
|
225
|
+
return /* @__PURE__ */ jsx("footer", { ref, className: cn("border-t border-line py-12", className), ...props, children: /* @__PURE__ */ jsxs(Container, { size: "full", children: [
|
|
226
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-10 md:grid-cols-[2fr_repeat(auto-fit,minmax(9rem,1fr))]", children: [
|
|
227
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
228
|
+
/* @__PURE__ */ jsx("div", { className: "text-ui font-semibold text-fg", children: brand }),
|
|
229
|
+
/* @__PURE__ */ jsx(Text, { size: "micro", tone: "muted", className: "mt-2 max-w-xs", children: "Build once. Generalize properly. Reuse everywhere." })
|
|
230
|
+
] }),
|
|
231
|
+
columns.map((column) => /* @__PURE__ */ jsxs("nav", { "aria-label": column.heading, children: [
|
|
232
|
+
/* @__PURE__ */ jsx("h2", { className: "text-label font-semibold uppercase tracking-widest text-fg-subtle", children: column.heading }),
|
|
233
|
+
/* @__PURE__ */ jsx("ul", { className: "mt-3 flex flex-col gap-2", children: column.links.map((link) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
234
|
+
Link,
|
|
235
|
+
{
|
|
236
|
+
href: link.href,
|
|
237
|
+
external: link.external,
|
|
238
|
+
className: "text-ui text-fg-muted no-underline hover:text-fg hover:no-underline",
|
|
239
|
+
children: link.label
|
|
240
|
+
}
|
|
241
|
+
) }, link.href)) })
|
|
242
|
+
] }, column.heading))
|
|
243
|
+
] }),
|
|
244
|
+
/* @__PURE__ */ jsx(Divider, { className: "my-8" }),
|
|
245
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center justify-between gap-3 text-micro text-fg-subtle", children: legal })
|
|
246
|
+
] }) });
|
|
247
|
+
});
|
|
248
|
+
const ConversionForm = React.forwardRef(
|
|
249
|
+
function ConversionForm2({ title, description, onSubmit, busy = false, submitLabel, className, children, ...props }, ref) {
|
|
250
|
+
return /* @__PURE__ */ jsxs(
|
|
251
|
+
"form",
|
|
252
|
+
{
|
|
253
|
+
ref,
|
|
254
|
+
onSubmit,
|
|
255
|
+
className: cn("flex flex-col gap-4", className),
|
|
256
|
+
"aria-busy": busy || void 0,
|
|
257
|
+
...props,
|
|
258
|
+
children: [
|
|
259
|
+
/* @__PURE__ */ jsx(Heading, { level: 2, children: title }),
|
|
260
|
+
description ? /* @__PURE__ */ jsx(Text, { size: "ui", tone: "muted", children: description }) : null,
|
|
261
|
+
children,
|
|
262
|
+
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { type: "submit", loading: busy, children: busy ? "Wird gesendet" : submitLabel ?? COPY.actions.save }) })
|
|
263
|
+
]
|
|
264
|
+
}
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
);
|
|
268
|
+
export {
|
|
269
|
+
Box,
|
|
270
|
+
CallToAction,
|
|
271
|
+
Container,
|
|
272
|
+
ConversionForm,
|
|
273
|
+
Faq,
|
|
274
|
+
Feature,
|
|
275
|
+
FeatureGrid,
|
|
276
|
+
Hero,
|
|
277
|
+
InlineCode,
|
|
278
|
+
PricingTable,
|
|
279
|
+
PublicFooter,
|
|
280
|
+
PublicNavbar,
|
|
281
|
+
Section,
|
|
282
|
+
SectionHeading,
|
|
283
|
+
Slot
|
|
284
|
+
};
|
|
285
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Slot } from \"radix-ui\";\nimport { Menu, X } from \"@tea-ui/icons\";\nimport { cn } from \"@tea-ui/utils\";\nimport { COPY } from \"@tea-ui/ux-standards\";\nimport {\n Box,\n Button,\n Container,\n Divider,\n Drawer,\n DrawerBody,\n DrawerContent,\n DrawerHeader,\n DrawerTitle,\n Heading,\n HStack,\n IconButton,\n InlineCode,\n Link,\n SkipLink,\n Stack,\n Text,\n} from \"@tea-ui/core\";\n\n/**\n * TEA UI Public — website chrome and marketing sections.\n *\n * Public UI is **not** Admin UI with different colours, and this file is where\n * that has to be true. The differences are structural, and each one is a\n * consequence of the audience:\n *\n * - **Measure.** Admin text runs to the edge because a table needs the width.\n * Prose does not: it runs to `max-w-3xl`, because a 120-character line is\n * unreadable. Every section here is width-constrained for that reason.\n * - **Type size.** Admin lives at `text-ui` (14px). Public body text is\n * `text-body` (16px) minimum, and lead text is larger still. The audit found\n * real text at 9px and 10px in the *admin* surfaces; a marketing page would\n * be worse.\n * - **Rhythm.** Sections are separated by far more space than panels are,\n * because a page is a scroll narrative and a panel is a work surface.\n * - **Conversion.** The primary action repeats per section. On an admin page a\n * repeated primary button is noise; on a public page it is the point.\n */\nexport type PublicSize = \"sm\" | \"md\" | \"lg\";\n\n/* ========================================================================== */\n/* Section */\n/* ========================================================================== */\n\nexport interface SectionProps extends React.ComponentProps<\"section\"> {\n /** Vertical rhythm. `tight` sits between related blocks, `loose` between them. */\n spacing?: \"tight\" | \"normal\" | \"loose\" | undefined;\n /** A hairline separator above the section. */\n bordered?: boolean | undefined;\n children: React.ReactNode;\n}\n\n/**\n * The unit of a marketing page. Everything in the Public layer is a `Section`,\n * so page rhythm is decided once and a page cannot accidentally use six\n * different vertical gaps.\n */\nexport const Section = React.forwardRef<HTMLElement, SectionProps>(function Section(\n { spacing = \"normal\", bordered = false, className, children, ...props },\n ref,\n) {\n return (\n <section\n ref={ref}\n className={cn(\n spacing === \"tight\" && \"py-8\",\n spacing === \"normal\" && \"py-14\",\n spacing === \"loose\" && \"py-20\",\n bordered && \"border-t border-line\",\n className,\n )}\n {...props}\n >\n {children}\n </section>\n );\n});\n\n/* ========================================================================== */\n/* Hero */\n/* ========================================================================== */\n\nexport interface HeroProps extends React.ComponentProps<\"section\"> {\n /** The eyebrow above the headline. Sets the category, not the value. */\n eyebrow?: string | undefined;\n /** The headline. One sentence, the thing a visitor must understand. */\n title: string;\n /** The promise. One or two sentences, plain, no jargon. */\n lead?: string | undefined;\n /** Primary and secondary actions. */\n actions?: React.ReactNode | undefined;\n /** Trust markers under the actions: \"Seit 2019\", \"Made in Germany\", logos. */\n reassurance?: React.ReactNode | undefined;\n /**\n * A visual below the copy — a screenshot, a diagram, a live demo. Optional,\n * because a hero that is only words is a legitimate hero, and forcing an empty\n * wrapper element to satisfy the type would be worse than the optional.\n */\n children?: React.ReactNode | undefined;\n}\n\nexport const Hero = React.forwardRef<HTMLElement, HeroProps>(function Hero(\n { eyebrow, title, lead, actions, reassurance, className, children, ...props },\n ref,\n) {\n return (\n <section ref={ref} className={cn(\"border-b border-line py-20\", className)} {...props}>\n <Container size=\"lg\">\n <div className=\"max-w-3xl\">\n {eyebrow ? (\n <p className=\"text-label font-semibold uppercase tracking-widest text-primary\">{eyebrow}</p>\n ) : null}\n <Heading level={1} className=\"mt-3 text-hero\">\n {title}\n </Heading>\n {lead ? (\n <Text size=\"lead\" tone=\"muted\" className=\"mt-5 max-w-2xl\">\n {lead}\n </Text>\n ) : null}\n {actions ? <HStack gap=\"ui\" className=\"mt-8\">{actions}</HStack> : null}\n {reassurance ? (\n <div className=\"mt-8 flex flex-wrap items-center gap-x-6 gap-y-2 text-micro text-fg-subtle\">\n {reassurance}\n </div>\n ) : null}\n </div>\n {children ? <div className=\"mt-12\">{children}</div> : null}\n </Container>\n </section>\n );\n});\n\n/* ========================================================================== */\n/* Content blocks */\n/* ========================================================================== */\n\nexport interface SectionHeadingProps {\n eyebrow?: string | undefined;\n title: string;\n lead?: string | undefined;\n /** `center` for a self-contained block, `start` when text follows it. */\n align?: \"start\" | \"center\" | undefined;\n level?: 2 | 3 | undefined;\n className?: string | undefined;\n}\n\n/**\n * The heading of a content block. `align=\"center\"` is a real decision, not a\n * default: centred text with a centred image reads as a unit, and a centred\n * section followed by left-aligned content reads as a mistake.\n */\nexport const SectionHeading = React.forwardRef<HTMLDivElement, SectionHeadingProps>(\n function SectionHeading({ eyebrow, title, lead, align = \"start\", level = 2, className }, ref) {\n return (\n <div\n ref={ref}\n className={cn(\n \"flex flex-col gap-3\",\n align === \"center\" && \"items-center text-center\",\n className,\n )}\n >\n {eyebrow ? (\n <p className=\"text-label font-semibold uppercase tracking-widest text-primary\">{eyebrow}</p>\n ) : null}\n <Heading level={level} className={level === 2 ? \"max-w-2xl\" : undefined}>\n {title}\n </Heading>\n {lead ? (\n <Text size=\"lead\" tone=\"muted\" className={cn(\"max-w-2xl\", align === \"center\" && \"mx-auto\")}>\n {lead}\n </Text>\n ) : null}\n </div>\n );\n },\n);\n\nexport interface FeatureGridProps extends React.ComponentProps<\"div\"> {\n cols?: 2 | 3 | 4 | undefined;\n /** Minimum column width; the grid auto-fits below the breakpoint. */\n minItemWidth?: string | undefined;\n children: React.ReactNode;\n}\n\n/**\n * The auto-fit grid is the reason a TEA marketing page has no per-breakpoint\n * column counts. The audit found the same class string\n * (`mt-10 grid gap-4 md:grid-cols-2 lg:grid-cols-3`) copy-pasted at six sites,\n * drifting to `md:grid-cols-3` and `md:grid-cols-4` as the density changed.\n */\nexport const FeatureGrid = React.forwardRef<HTMLDivElement, FeatureGridProps>(function FeatureGrid(\n { cols = 3, minItemWidth = \"16rem\", className, children, style, ...props },\n ref,\n) {\n return (\n <div\n ref={ref}\n style={{\n gridTemplateColumns: `repeat(auto-fit, minmax(min(${minItemWidth}, 100%), 1fr))`,\n ...style,\n }}\n className={cn(\"grid gap-6\", className)}\n data-cols={cols}\n {...props}\n >\n {children}\n </div>\n );\n});\n\nexport interface FeatureProps extends React.ComponentProps<\"article\"> {\n title: string;\n description: string;\n icon?: React.ReactNode | undefined;\n /** A short proof line: a number, a benchmark, a customer. */\n proof?: string | undefined;\n}\n\n/**\n * A feature. It is an `<article>`, not a `div`, because a feature is a\n * self-contained claim and an article is what that is in the document outline.\n */\nexport const Feature = React.forwardRef<HTMLElement, FeatureProps>(function Feature(\n { title, description, icon, proof, className, ...props },\n ref,\n) {\n return (\n <article ref={ref} className={cn(\"flex flex-col gap-3\", className)} {...props}>\n {icon ? (\n <span\n aria-hidden=\"true\"\n className=\"flex size-10 items-center justify-center bg-accent text-accent-fg\"\n >\n {icon}\n </span>\n ) : null}\n <Heading level={3}>{title}</Heading>\n <Text size=\"body\" tone=\"muted\">\n {description}\n </Text>\n {proof ? (\n <Text size=\"micro\" tone=\"subtle\" className=\"font-mono\">\n {proof}\n </Text>\n ) : null}\n </article>\n );\n});\n\nexport interface CallToActionProps extends React.ComponentProps<\"section\"> {\n title: string;\n lead?: string | undefined;\n actions: React.ReactNode;\n /** `banner` closes the page; `inline` sits inside a section. */\n variant?: \"banner\" | \"inline\" | undefined;\n}\n\nexport const CallToAction = React.forwardRef<HTMLElement, CallToActionProps>(function CallToAction(\n { title, lead, actions, variant = \"banner\", className, ...props },\n ref,\n) {\n return (\n <section\n ref={ref}\n className={cn(\n variant === \"banner\" ? \"border-t border-line py-20\" : \"py-10\",\n className,\n )}\n {...props}\n >\n <Container size=\"lg\">\n <div className=\"flex flex-col items-start justify-between gap-6 md:flex-row md:items-center\">\n <div className=\"max-w-2xl\">\n <Heading level={2}>{title}</Heading>\n {lead ? (\n <Text size=\"lead\" tone=\"muted\" className=\"mt-3\">\n {lead}\n </Text>\n ) : null}\n </div>\n <HStack gap=\"ui\" className=\"shrink-0\">\n {actions}\n </HStack>\n </div>\n </Container>\n </section>\n );\n});\n\n/* ========================================================================== */\n/* Content */\n/* ========================================================================== */\n\nexport interface FaqItem {\n question: string;\n answer: React.ReactNode;\n}\n\n/**\n * A FAQ.\n *\n * A `<details>`/`<summary>` pair, not a component with JavaScript: the browser\n * already implements expand, collapse, keyboard operation and the correct\n * semantics, and every hand-rolled accordion FAQ in the audit shipped without\n * `aria-expanded`.\n */\nexport const Faq = React.forwardRef<HTMLDivElement, React.ComponentProps<\"div\"> & { items: readonly FaqItem[] }>(\n function Faq({ items, className, ...props }, ref) {\n return (\n <div ref={ref} className={cn(\"mx-auto flex max-w-3xl flex-col\", className)} {...props}>\n {items.map((item) => (\n <details key={item.question} className=\"group border-b border-line py-5\">\n <summary className=\"flex cursor-pointer list-none items-center justify-between gap-4 text-ui font-medium text-fg marker:content-none\">\n {item.question}\n <span aria-hidden=\"true\" className=\"text-primary transition-transform group-open:rotate-45\">\n +\n </span>\n </summary>\n <div className=\"mt-3 text-body text-fg-muted\">{item.answer}</div>\n </details>\n ))}\n </div>\n );\n },\n);\n\nexport interface PricingTier {\n name: string;\n price: string;\n /** The billing period, e.g. \"pro Monat\". */\n period?: string | undefined;\n description?: string | undefined;\n features: readonly string[];\n highlighted?: boolean | undefined;\n action?: React.ReactNode | undefined;\n}\n\n/**\n * Pricing.\n *\n * The price is the largest type on the card, because that is what the visitor\n * came for. A card that lists eleven features in eleven equal rows gives the\n * price the same weight as the last row item, which buries the decision.\n */\nexport const PricingTable = React.forwardRef<\n HTMLDivElement,\n React.ComponentProps<\"div\"> & { tiers: readonly PricingTier[] }\n>(function PricingTable({ tiers, className, ...props }, ref) {\n return (\n <div ref={ref} className={cn(\"grid gap-6 md:grid-cols-3\", className)} {...props}>\n {tiers.map((tier) => (\n <div\n key={tier.name}\n className={cn(\n \"flex flex-col gap-5 border bg-surface p-6\",\n tier.highlighted ? \"border-primary\" : \"border-line\",\n )}\n >\n <div>\n <Text size=\"label\" tone={tier.highlighted ? \"accent\" : \"muted\"} className=\"font-semibold uppercase tracking-widest\">\n {tier.name}\n </Text>\n <div className=\"mt-2 flex items-baseline gap-2\">\n <span className=\"text-display font-semibold text-fg\">{tier.price}</span>\n {tier.period ? <Text size=\"micro\" tone=\"muted\">{tier.period}</Text> : null}\n </div>\n {tier.description ? (\n <Text size=\"micro\" tone=\"muted\" className=\"mt-2\">\n {tier.description}\n </Text>\n ) : null}\n </div>\n <ul className=\"flex flex-1 flex-col gap-2\">\n {tier.features.map((feature) => (\n <li key={feature} className=\"flex items-start gap-2 text-ui text-fg-muted\">\n <span aria-hidden=\"true\" className=\"mt-1.5 size-1.5 shrink-0 rounded-pill bg-primary\" />\n {feature}\n </li>\n ))}\n </ul>\n {tier.action}\n </div>\n ))}\n </div>\n );\n});\n\n/* ========================================================================== */\n/* Navigation */\n/* ========================================================================== */\n\nexport interface PublicNavLink {\n label: string;\n href: string;\n /** Opens in a new tab. Adds `rel` and an accessible hint. */\n external?: boolean | undefined;\n}\n\nexport interface PublicNavbarProps extends React.ComponentProps<\"header\"> {\n brand: React.ReactNode;\n links: readonly PublicNavLink[];\n /** Always-visible action, e.g. \"Anmelden\". */\n action?: React.ReactNode | undefined;\n /** Id of the main region, for the skip link. */\n mainId?: string | undefined;\n className?: string | undefined;\n}\n\n/**\n * A public navbar.\n *\n * The audit found the decisive defect in a real public header: the desktop nav\n * was `hidden md:flex` and **there was no mobile menu at all**, so the entire\n * navigation simply disappeared below 768px. Below `md` this becomes a drawer\n * with the same links, because a hidden navigation is not a responsive\n * navigation.\n */\nexport const PublicNavbar = React.forwardRef<HTMLElement, PublicNavbarProps>(function PublicNavbar(\n { brand, links, action, mainId = \"tea-public-main\", className, children, ...props },\n ref,\n) {\n const [open, setOpen] = React.useState(false);\n\n return (\n <header\n ref={ref}\n className={cn(\"sticky top-0 z-header border-b border-line bg-canvas\", className)}\n {...props}\n >\n <SkipLink targetId={mainId} />\n <Container size=\"full\" className=\"flex h-16 items-center gap-6\">\n <Link href=\"#\" className=\"text-ui font-semibold tracking-tight text-fg no-underline hover:no-underline\">\n {brand}\n </Link>\n <nav aria-label={COPY.navigation.main} className=\"hidden items-center gap-5 md:flex\">\n {links.map((link) => (\n <Link\n key={link.href}\n href={link.href}\n external={link.external}\n className=\"text-ui text-fg-muted no-underline hover:text-fg hover:no-underline\"\n >\n {link.label}\n </Link>\n ))}\n </nav>\n <HStack gap=\"ui\" className=\"ms-auto\">\n {action}\n <IconButton\n label={COPY.navigation.openMenu}\n variant=\"ghost\"\n className=\"md:hidden\"\n aria-expanded={open}\n aria-haspopup=\"dialog\"\n onClick={() => setOpen(true)}\n >\n <Menu size={20} aria-hidden=\"true\" />\n </IconButton>\n </HStack>\n </Container>\n {children}\n\n <Drawer open={open} onOpenChange={setOpen}>\n <DrawerContent side=\"end\" className=\"w-80\">\n <DrawerHeader>\n <DrawerTitle className=\"flex items-center justify-between text-ui\">\n {COPY.navigation.main}\n <IconButton label={COPY.navigation.closeMenu} variant=\"ghost\" size=\"sm\" onClick={() => setOpen(false)}>\n <X size={18} aria-hidden=\"true\" />\n </IconButton>\n </DrawerTitle>\n </DrawerHeader>\n <DrawerBody>\n <nav aria-label={COPY.navigation.main}>\n <Stack gap=\"ui\">\n {links.map((link) => (\n <Link\n key={link.href}\n href={link.href}\n external={link.external}\n className=\"text-ui text-fg no-underline hover:text-primary hover:no-underline\"\n onClick={() => setOpen(false)}\n >\n {link.label}\n </Link>\n ))}\n </Stack>\n </nav>\n </DrawerBody>\n </DrawerContent>\n </Drawer>\n </header>\n );\n});\n\nexport interface PublicFooterProps extends React.ComponentProps<\"footer\"> {\n brand: React.ReactNode;\n /** Label-to-link column groups. */\n columns: ReadonlyArray<{ heading: string; links: readonly PublicNavLink[] }>;\n /** Legal line: imprint, privacy, copyright. Never optional on a public site. */\n legal: React.ReactNode;\n className?: string | undefined;\n}\n\nexport const PublicFooter = React.forwardRef<HTMLElement, PublicFooterProps>(function PublicFooter(\n { brand, columns, legal, className, ...props },\n ref,\n) {\n return (\n <footer ref={ref} className={cn(\"border-t border-line py-12\", className)} {...props}>\n <Container size=\"full\">\n <div className=\"grid gap-10 md:grid-cols-[2fr_repeat(auto-fit,minmax(9rem,1fr))]\">\n <div>\n <div className=\"text-ui font-semibold text-fg\">{brand}</div>\n <Text size=\"micro\" tone=\"muted\" className=\"mt-2 max-w-xs\">\n Build once. Generalize properly. Reuse everywhere.\n </Text>\n </div>\n {columns.map((column) => (\n <nav key={column.heading} aria-label={column.heading}>\n <h2 className=\"text-label font-semibold uppercase tracking-widest text-fg-subtle\">\n {column.heading}\n </h2>\n <ul className=\"mt-3 flex flex-col gap-2\">\n {column.links.map((link) => (\n <li key={link.href}>\n <Link\n href={link.href}\n external={link.external}\n className=\"text-ui text-fg-muted no-underline hover:text-fg hover:no-underline\"\n >\n {link.label}\n </Link>\n </li>\n ))}\n </ul>\n </nav>\n ))}\n </div>\n <Divider className=\"my-8\" />\n <div className=\"flex flex-wrap items-center justify-between gap-3 text-micro text-fg-subtle\">{legal}</div>\n </Container>\n </footer>\n );\n});\n\n/* ========================================================================== */\n/* Conversion */\n/* ========================================================================== */\n\nexport interface ConversionFormProps extends React.ComponentProps<\"form\"> {\n title: string;\n description?: string | undefined;\n /** Submit handler. The form shows no success state on its own. */\n onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;\n /** Rendered while submitting. Disable the submit control as well. */\n busy?: boolean | undefined;\n submitLabel?: string | undefined;\n children: React.ReactNode;\n}\n\n/**\n * A conversion form.\n *\n * The audit found a public contact form whose `<label>` elements were never\n * associated with their controls, and a login form with a working `htmlFor` that\n * was the exception. `Field` makes the correct version the shortest one.\n */\nexport const ConversionForm = React.forwardRef<HTMLFormElement, ConversionFormProps>(\n function ConversionForm(\n { title, description, onSubmit, busy = false, submitLabel, className, children, ...props },\n ref,\n ) {\n return (\n <form\n ref={ref}\n onSubmit={onSubmit}\n className={cn(\"flex flex-col gap-4\", className)}\n aria-busy={busy || undefined}\n {...props}\n >\n <Heading level={2}>{title}</Heading>\n {description ? (\n <Text size=\"ui\" tone=\"muted\">\n {description}\n </Text>\n ) : null}\n {children}\n <div>\n <Button type=\"submit\" loading={busy}>\n {busy ? \"Wird gesendet\" : (submitLabel ?? COPY.actions.save)}\n </Button>\n </div>\n </form>\n );\n },\n);\n\n/* ========================================================================== */\n\nexport { Box, Container, Slot, InlineCode };\n"],"mappings":"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","names":["Section","Hero","SectionHeading","FeatureGrid","Feature","CallToAction","Faq","PricingTable","PublicNavbar","PublicFooter","ConversionForm"]}
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:"";--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0}}}@layer theme{:root,:host{--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-6xl:72rem;--tracking-tight:-.025em;--tracking-widest:.1em;--leading-tight:1.25;--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-font-family:var(--tea-font-sans);--default-mono-font-family:var(--tea-font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*,:before,:after,::backdrop{border-color:var(--tea-line)}html{-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%;scrollbar-color:var(--tea-line-strong) var(--tea-canvas);color-scheme:dark}body{background-color:var(--tea-canvas);color:var(--tea-fg);font-family:var(--tea-font-sans);font-size:var(--tea-text-ui);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;line-height:1.25rem}:focus-visible{outline:2px solid var(--tea-ring);outline-offset:2px}::selection{background-color:var(--tea-accent);color:var(--tea-accent-fg)}*{scrollbar-width:thin;scrollbar-color:var(--tea-line-strong) var(--tea-canvas)}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-track{background:var(--tea-canvas)}::-webkit-scrollbar-thumb{background:var(--tea-line-strong)}::-webkit-scrollbar-thumb:hover{background:var(--tea-accent)}::-webkit-scrollbar-corner{background:var(--tea-canvas)}@media (pointer:coarse){[data-tea-touch]{min-height:var(--tea-touch-min);min-width:var(--tea-touch-min)}}@media (prefers-reduced-motion:reduce){*,:before,:after,::backdrop{scroll-behavior:auto!important;transition-duration:.01ms!important;animation-duration:.01ms!important;animation-iteration-count:1!important}[data-tea-motion=essential]{animation-duration:.01ms!important}}}@layer components{[data-tea-motion=essential]:after{content:"";animation:1.6s steps(4,end) infinite tea-pulse-essential}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:0}.inset-x-0{inset-inline:0}.inset-y-0{inset-block:0}.start-0{inset-inline-start:calc(var(--spacing) * 0)}.start-1\/2{inset-inline-start:50%}.start-2{inset-inline-start:calc(var(--spacing) * 2)}.end-0{inset-inline-end:calc(var(--spacing) * 0)}.end-2{inset-inline-end:calc(var(--spacing) * 2)}.end-3{inset-inline-end:calc(var(--spacing) * 3)}.top-0{top:0}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing) * 2)}.top-3{top:calc(var(--spacing) * 3)}.top-14{top:calc(var(--spacing) * 14)}.top-full{top:100%}.bottom-0{bottom:0}.z-50{z-index:50}.z-base{z-index:0}.z-dropdown{z-index:300}.z-header{z-index:200}.z-max{z-index:900}.z-modal{z-index:500}.z-overlay{z-index:400}.z-popover{z-index:600}.z-raised{z-index:10}.z-sticky{z-index:100}.z-toast{z-index:700}.z-tooltip{z-index:800}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.mx-auto{margin-inline:auto}.my-1{margin-block:var(--spacing)}.my-2{margin-block:calc(var(--spacing) * 2)}.my-3{margin-block:calc(var(--spacing) * 3)}.my-8{margin-block:calc(var(--spacing) * 8)}.-ms-1{margin-inline-start:calc(var(--spacing) * -1)}.-ms-px{margin-inline-start:-1px}.ms-0{margin-inline-start:0}.ms-1{margin-inline-start:var(--spacing)}.ms-5{margin-inline-start:calc(var(--spacing) * 5)}.ms-auto{margin-inline-start:auto}.-mt-1{margin-top:calc(var(--spacing) * -1)}.-mt-px{margin-top:-1px}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-10{margin-top:calc(var(--spacing) * 10)}.mt-12{margin-top:calc(var(--spacing) * 12)}.mt-16{margin-top:calc(var(--spacing) * 16)}.mb-1{margin-bottom:var(--spacing)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-3\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-10{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.size-\[calc\(var\(--tea-control-h\)\+0\.5rem\)\]{width:calc(var(--tea-control-h) + .5rem);height:calc(var(--tea-control-h) + .5rem)}.size-\[calc\(var\(--tea-control-h\)-0\.25rem\)\]{width:calc(var(--tea-control-h) - .25rem);height:calc(var(--tea-control-h) - .25rem)}.size-\[length\:var\(--tea-control-h\)\]{width:var(--tea-control-h);height:var(--tea-control-h)}.size-full{width:100%;height:100%}.control{height:var(--tea-control-h);padding-inline:var(--tea-control-px)}.control-h{height:var(--tea-control-h)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-3{height:calc(var(--spacing) * 3)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-14{height:calc(var(--spacing) * 14)}.h-16{height:calc(var(--spacing) * 16)}.h-\[calc\(100dvh-3\.5rem\)\]{height:calc(100dvh - 3.5rem)}.h-\[calc\(var\(--tea-control-h\)\+0\.25rem\)\]{height:calc(var(--tea-control-h) + .25rem)}.h-\[calc\(var\(--tea-control-h\)-0\.25rem\)\]{height:calc(var(--tea-control-h) - .25rem)}.h-auto{height:auto}.h-dvh{height:100dvh}.h-full{height:100%}.h-px{height:1px}.max-h-72{max-height:calc(var(--spacing) * 72)}.max-h-80{max-height:calc(var(--spacing) * 80)}.max-h-\[--radix-select-content-available-height\]{max-height:--radix-select-content-available-height}.max-h-\[80dvh\]{max-height:80dvh}.max-h-\[85dvh\]{max-height:85dvh}.max-h-\[calc\(100dvh-4rem\)\]{max-height:calc(100dvh - 4rem)}.max-h-\[var\(--radix-select-content-available-height\)\]{max-height:var(--radix-select-content-available-height)}.min-h-0{min-height:0}.min-h-\[60dvh\]{min-height:60dvh}.min-h-dvh{min-height:100dvh}.w-1\/3{width:33.3333%}.w-2\/3{width:66.6667%}.w-7{width:calc(var(--spacing) * 7)}.w-24{width:calc(var(--spacing) * 24)}.w-32{width:calc(var(--spacing) * 32)}.w-40{width:calc(var(--spacing) * 40)}.w-56{width:calc(var(--spacing) * 56)}.w-64{width:calc(var(--spacing) * 64)}.w-72{width:calc(var(--spacing) * 72)}.w-80{width:calc(var(--spacing) * 80)}.w-96{width:calc(var(--spacing) * 96)}.w-\[calc\(100\%-2rem\)\]{width:calc(100% - 2rem)}.w-\[min\(20rem\,85vw\)\]{width:min(20rem,85vw)}.w-\[min\(24rem\,90vw\)\]{width:min(24rem,90vw)}.w-\[min\(40rem\,90vw\)\]{width:min(40rem,90vw)}.w-full{width:100%}.w-px{width:1px}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-\[100rem\]{max-width:100rem}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.max-w-sm{max-width:var(--container-sm)}.max-w-xl{max-width:var(--container-xl)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:0}.min-w-5{min-width:calc(var(--spacing) * 5)}.min-w-8{min-width:calc(var(--spacing) * 8)}.min-w-32{min-width:calc(var(--spacing) * 32)}.min-w-40{min-width:calc(var(--spacing) * 40)}.min-w-48{min-width:calc(var(--spacing) * 48)}.min-w-56{min-width:calc(var(--spacing) * 56)}.min-w-\[36rem\]{min-width:36rem}.min-w-\[40rem\]{min-width:40rem}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.flex-1{flex:1}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.border-collapse{border-collapse:collapse}.origin-top{transform-origin:top}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.scale-0{--tw-scale-x:0%;--tw-scale-y:0%;--tw-scale-z:0%;scale:var(--tw-scale-x) var(--tw-scale-y)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.cursor-text{cursor:text}.touch-none{touch-action:none}.resize-none{resize:none}.resize-y{resize:vertical}.scroll-mt-20{scroll-margin-top:calc(var(--spacing) * 20)}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.field-gap{gap:var(--tea-field-gap)}.gap-0{gap:0}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-8{gap:calc(var(--spacing) * 8)}.gap-10{gap:calc(var(--spacing) * 10)}.gap-ui{gap:var(--tea-gap)}.section-gap{gap:var(--tea-section-gap)}.gap-x-6{column-gap:calc(var(--spacing) * 6)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}.self-stretch{align-self:stretch}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded-full{border-radius:3.40282e38px}.rounded-none{border-radius:0}.rounded-pill{border-radius:9999px}.rounded-t-none{border-top-left-radius:0;border-top-right-radius:0}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-s{border-inline-start-style:var(--tw-border-style);border-inline-start-width:1px}.border-s-2{border-inline-start-style:var(--tw-border-style);border-inline-start-width:2px}.border-e{border-inline-end-style:var(--tw-border-style);border-inline-end-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-caution{border-color:var(--tea-caution)}.border-caution-border{border-color:var(--tea-caution-border)}.border-critical{border-color:var(--tea-critical)}.border-critical-border{border-color:var(--tea-critical-border)}.border-destructive{border-color:var(--tea-destructive)}.border-info{border-color:var(--tea-info)}.border-info-border{border-color:var(--tea-info-border)}.border-line{border-color:var(--tea-line)}.border-line-strong{border-color:var(--tea-line-strong)}.border-line\/50{border-color:var(--tea-line)}@supports (color:color-mix(in lab, red, red)){.border-line\/50{border-color:color-mix(in oklab, var(--tea-line) 50%, transparent)}}.border-neutral-border{border-color:var(--tea-neutral-border)}.border-positive{border-color:var(--tea-positive)}.border-positive-border{border-color:var(--tea-positive-border)}.border-primary{border-color:var(--tea-primary)}.border-primary-border{border-color:var(--tea-primary-border)}.border-transparent{border-color:#0000}.bg-accent{background-color:var(--tea-accent)}.bg-accent-subtle{background-color:var(--tea-accent-subtle)}.bg-canvas{background-color:var(--tea-canvas)}.bg-caution{background-color:var(--tea-caution)}.bg-caution-subtle{background-color:var(--tea-caution-subtle)}.bg-critical{background-color:var(--tea-critical)}.bg-critical-subtle{background-color:var(--tea-critical-subtle)}.bg-current{background-color:currentColor}.bg-destructive{background-color:var(--tea-destructive)}.bg-fg{background-color:var(--tea-fg)}.bg-fg-muted{background-color:var(--tea-fg-muted)}.bg-info{background-color:var(--tea-info)}.bg-info-subtle{background-color:var(--tea-info-subtle)}.bg-line{background-color:var(--tea-line)}.bg-neutral{background-color:var(--tea-neutral)}.bg-neutral-subtle{background-color:var(--tea-neutral-subtle)}.bg-overlay{background-color:var(--tea-overlay)}.bg-positive{background-color:var(--tea-positive)}.bg-positive-subtle{background-color:var(--tea-positive-subtle)}.bg-primary{background-color:var(--tea-primary)}.bg-primary-fg{background-color:var(--tea-primary-fg)}.bg-primary-subtle{background-color:var(--tea-primary-subtle)}.bg-surface{background-color:var(--tea-surface)}.bg-surface-2{background-color:var(--tea-surface-2)}.bg-surface-3{background-color:var(--tea-surface-3)}.bg-transparent{background-color:#0000}.p-0{padding:0}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1{padding:var(--spacing)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.pad-card{padding:var(--tea-pad-card)}.px-0{padding-inline:0}.px-1{padding-inline:var(--spacing)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-\[calc\(var\(--tea-control-px\)\+0\.25rem\)\]{padding-inline:calc(var(--tea-control-px) + .25rem)}.px-\[calc\(var\(--tea-control-px\)-0\.25rem\)\]{padding-inline:calc(var(--tea-control-px) - .25rem)}.px-\[length\:var\(--tea-control-px\)\]{padding-inline:var(--tea-control-px)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-10{padding-block:calc(var(--spacing) * 10)}.py-12{padding-block:calc(var(--spacing) * 12)}.py-14{padding-block:calc(var(--spacing) * 14)}.py-20{padding-block:calc(var(--spacing) * 20)}.ps-2{padding-inline-start:calc(var(--spacing) * 2)}.ps-3{padding-inline-start:calc(var(--spacing) * 3)}.ps-4{padding-inline-start:calc(var(--spacing) * 4)}.ps-8{padding-inline-start:calc(var(--spacing) * 8)}.pe-1{padding-inline-end:var(--spacing)}.pe-2{padding-inline-end:calc(var(--spacing) * 2)}.pe-4{padding-inline-end:calc(var(--spacing) * 4)}.pe-8{padding-inline-end:calc(var(--spacing) * 8)}.pe-12{padding-inline-end:calc(var(--spacing) * 12)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-\[10vh\]{padding-top:10vh}.pb-1{padding-bottom:var(--spacing)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.text-center{text-align:center}.text-end{text-align:end}.text-justify{text-align:justify}.text-left{text-align:left}.text-start{text-align:start}.align-\[-2px\]{vertical-align:-2px}.align-top{vertical-align:top}.font-mono{font-family:var(--tea-font-mono)}.text-label{font-size:.6875rem;line-height:var(--tw-leading,.875rem);letter-spacing:var(--tw-tracking,.08em);font-weight:var(--tw-font-weight,600)}.text-display{font-size:2rem;line-height:var(--tw-leading,2.5rem);letter-spacing:var(--tw-tracking,-.02em)}.text-hero{font-size:3rem;line-height:var(--tw-leading,1.1);letter-spacing:var(--tw-tracking,-.03em)}.text-section{font-size:1.5rem;line-height:var(--tw-leading,2rem);letter-spacing:var(--tw-tracking,-.01em)}.text-body{font-size:1rem;line-height:var(--tw-leading,1.625rem)}.text-lead{font-size:1.125rem;line-height:var(--tw-leading,1.75rem)}.text-micro{font-size:.75rem;line-height:var(--tw-leading,1rem)}.text-mono{font-size:.8125rem;line-height:var(--tw-leading,1.25rem)}.text-title{font-size:1.25rem;line-height:var(--tw-leading,1.75rem)}.text-ui{font-size:var(--tea-text-ui);font-size:.875rem;line-height:1.25rem;line-height:var(--tw-leading,1.25rem)}.text-\[9px\]{font-size:9px}.leading-none{--tw-leading:1;line-height:1}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:700;font-weight:700}.font-medium{--tw-font-weight:500;font-weight:500}.font-normal{--tw-font-weight:400;font-weight:400}.font-semibold{--tw-font-weight:600;font-weight:600}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.text-balance{text-wrap:balance}.text-wrap{text-wrap:wrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-accent{color:var(--tea-accent)}.text-accent-fg{color:var(--tea-accent-fg)}.text-caution{color:var(--tea-caution)}.text-caution-fg{color:var(--tea-caution-fg)}.text-critical{color:var(--tea-critical)}.text-critical-fg{color:var(--tea-critical-fg)}.text-current{color:currentColor}.text-destructive-fg{color:var(--tea-destructive-fg)}.text-fg{color:var(--tea-fg)}.text-fg-inverse{color:var(--tea-fg-inverse)}.text-fg-muted{color:var(--tea-fg-muted)}.text-fg-subtle{color:var(--tea-fg-subtle)}.text-info{color:var(--tea-info)}.text-info-fg{color:var(--tea-info-fg)}.text-neutral-fg{color:var(--tea-neutral-fg)}.text-positive{color:var(--tea-positive)}.text-positive-fg{color:var(--tea-positive-fg)}.text-primary{color:var(--tea-primary)}.text-primary-fg{color:var(--tea-primary-fg)}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.no-underline{text-decoration-line:none}.underline{text-decoration-line:underline}.underline-offset-4{text-underline-offset:4px}.accent-fg{accent-color:var(--tea-fg)}.opacity-50{opacity:.5}.shadow-modal{--tw-shadow:var(--tea-shadow-modal);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-overlay{--tw-shadow:var(--tea-shadow-overlay);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--tea-ease-standard));transition-duration:var(--tw-duration,.18s)}.transition-\[background-color\,border-color\,box-shadow\]{transition-property:background-color,border-color,box-shadow;transition-timing-function:var(--tw-ease,var(--tea-ease-standard));transition-duration:var(--tw-duration,.18s)}.transition-\[background-color\,border-color\,color\,box-shadow\,transform\]{transition-property:background-color,border-color,color,box-shadow,transform;transition-timing-function:var(--tw-ease,var(--tea-ease-standard));transition-duration:var(--tw-duration,.18s)}.transition-\[background-color\,border-color\,color\,box-shadow\]{transition-property:background-color,border-color,color,box-shadow;transition-timing-function:var(--tw-ease,var(--tea-ease-standard));transition-duration:var(--tw-duration,.18s)}.transition-\[background-color\,border-color\]{transition-property:background-color,border-color;transition-timing-function:var(--tw-ease,var(--tea-ease-standard));transition-duration:var(--tw-duration,.18s)}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--tea-ease-standard));transition-duration:var(--tw-duration,.18s)}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--tea-ease-standard));transition-duration:var(--tw-duration,.18s)}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--tea-ease-standard));transition-duration:var(--tw-duration,.18s)}.duration-\[120ms\]{--tw-duration:.12s;transition-duration:.12s}.ease-standard{--tw-ease:cubic-bezier(.2, 0, 0, 1);transition-timing-function:cubic-bezier(.2,0,0,1)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.\[--tea-control-icon\:0\.875rem\]{--tea-control-icon:.875rem}.\[--tea-control-icon\:1\.25rem\]{--tea-control-icon:1.25rem}.\[--tea-control-icon\:1rem\]{--tea-control-icon:1rem}.paused{animation-play-state:paused}.running{animation-play-state:running}.group-open\:rotate-45:is(:where(.group):is([open],:popover-open,:open) *){rotate:45deg}.group-focus-visible\:ring-2:is(:where(.group):focus-visible *){--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.group-focus-visible\:ring-ring:is(:where(.group):focus-visible *){--tw-ring-color:var(--tea-ring)}.group-data-\[state\=checked\]\:scale-100:is(:where(.group)[data-state=checked] *){--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y)}.group-data-\[state\=checked\]\:border-primary:is(:where(.group)[data-state=checked] *){border-color:var(--tea-primary)}.group-data-\[state\=checked\]\:bg-primary:is(:where(.group)[data-state=checked] *){background-color:var(--tea-primary)}.group-data-\[state\=checked\]\:font-medium:is(:where(.group)[data-state=checked] *){--tw-font-weight:500;font-weight:500}.group-data-\[state\=complete\]\:border-positive:is(:where(.group)[data-state=complete] *){border-color:var(--tea-positive)}.group-data-\[state\=complete\]\:bg-positive-subtle:is(:where(.group)[data-state=complete] *){background-color:var(--tea-positive-subtle)}.group-data-\[state\=complete\]\:text-positive:is(:where(.group)[data-state=complete] *){color:var(--tea-positive)}.group-data-\[state\=current\]\:border-primary:is(:where(.group)[data-state=current] *){border-color:var(--tea-primary)}.group-data-\[state\=current\]\:text-primary:is(:where(.group)[data-state=current] *){color:var(--tea-primary)}.group-data-\[state\=open\]\:rotate-180:is(:where(.group)[data-state=open] *){rotate:180deg}.marker\:text-fg-subtle ::marker{color:var(--tea-fg-subtle)}.marker\:text-fg-subtle::marker{color:var(--tea-fg-subtle)}.marker\:text-fg-subtle ::-webkit-details-marker{color:var(--tea-fg-subtle)}.marker\:text-fg-subtle::-webkit-details-marker{color:var(--tea-fg-subtle)}.marker\:content-none ::marker{--tw-content:none;content:none}.marker\:content-none::marker{--tw-content:none;content:none}.marker\:content-none ::-webkit-details-marker{--tw-content:none;content:none}.marker\:content-none::-webkit-details-marker{--tw-content:none;content:none}.file\:me-3::file-selector-button{margin-inline-end:calc(var(--spacing) * 3)}.file\:rounded-none::file-selector-button{border-radius:0}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-ui::file-selector-button{font-size:var(--tea-text-ui);font-size:.875rem;line-height:1.25rem;line-height:var(--tw-leading,1.25rem)}.file\:font-medium::file-selector-button{--tw-font-weight:500;font-weight:500}.placeholder\:text-fg-subtle::placeholder{color:var(--tea-fg-subtle)}.before\:absolute:before{content:var(--tw-content);position:absolute}.before\:inset-y-0:before{content:var(--tw-content);inset-block:0}.before\:start-0:before{content:var(--tw-content);inset-inline-start:calc(var(--spacing) * 0)}.before\:w-0\.5:before{content:var(--tw-content);width:calc(var(--spacing) * .5)}.before\:bg-caution:before{content:var(--tw-content);background-color:var(--tea-caution)}.before\:bg-critical:before{content:var(--tw-content);background-color:var(--tea-critical)}.before\:bg-fg-muted:before{content:var(--tw-content);background-color:var(--tea-fg-muted)}.before\:bg-info:before{content:var(--tw-content);background-color:var(--tea-info)}.before\:bg-positive:before{content:var(--tw-content);background-color:var(--tea-positive)}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.read-only\:cursor-default:read-only{cursor:default}.read-only\:bg-surface-2:read-only{background-color:var(--tea-surface-2)}.read-only\:text-fg-muted:read-only{color:var(--tea-fg-muted)}.focus-within\:border-ring-strong:focus-within{border-color:var(--tea-ring-strong)}.focus-within\:ring-2:focus-within{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-within\:ring-ring:focus-within{--tw-ring-color:var(--tea-ring)}@media (hover:hover){.hover\:border-line-strong:hover{border-color:var(--tea-line-strong)}.hover\:border-primary-hover:hover{border-color:var(--tea-primary-hover)}.hover\:bg-line:hover{background-color:var(--tea-line)}.hover\:bg-primary-hover:hover{background-color:var(--tea-primary-hover)}.hover\:bg-primary-subtle\/80:hover{background-color:var(--tea-primary-subtle)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-primary-subtle\/80:hover{background-color:color-mix(in oklab, var(--tea-primary-subtle) 80%, transparent)}}.hover\:bg-surface-2:hover{background-color:var(--tea-surface-2)}.hover\:bg-surface-3:hover{background-color:var(--tea-surface-3)}.hover\:text-fg:hover{color:var(--tea-fg)}.hover\:text-primary:hover{color:var(--tea-primary)}.hover\:no-underline:hover{text-decoration-line:none}.hover\:underline:hover{text-decoration-line:underline}.hover\:brightness-110:hover{--tw-brightness:brightness(110%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}}.focus\:not-sr-only:focus{clip-path:none;white-space:normal;width:auto;height:auto;margin:0;padding:0;position:static;overflow:visible}.focus\:fixed:focus{position:fixed}.focus\:start-3:focus{inset-inline-start:calc(var(--spacing) * 3)}.focus\:top-3:focus{top:calc(var(--spacing) * 3)}.focus\:border:focus{border-style:var(--tw-border-style);border-width:1px}.focus\:border-primary:focus{border-color:var(--tea-primary)}.focus\:bg-primary:focus{background-color:var(--tea-primary)}.focus\:px-3:focus{padding-inline:calc(var(--spacing) * 3)}.focus\:py-2:focus{padding-block:calc(var(--spacing) * 2)}.focus\:text-ui:focus{font-size:var(--tea-text-ui);font-size:.875rem;line-height:1.25rem;line-height:var(--tw-leading,1.25rem)}.focus\:font-medium:focus{--tw-font-weight:500;font-weight:500}.focus\:text-primary-fg:focus{color:var(--tea-primary-fg)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:border-ring-strong:focus-visible{border-color:var(--tea-ring-strong)}.focus-visible\:border-transparent:focus-visible{border-color:#0000}.focus-visible\:bg-accent-subtle:focus-visible{background-color:var(--tea-accent-subtle)}.focus-visible\:ring-0:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--tea-ring)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.active\:translate-y-px:active{--tw-translate-y:1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:border-line:disabled{border-color:var(--tea-line)}.disabled\:bg-surface-2:disabled{background-color:var(--tea-surface-2)}.disabled\:text-fg-subtle:disabled{color:var(--tea-fg-subtle)}.disabled\:opacity-50:disabled{opacity:.5}.has-\[svg\]\:size-\[length\:var\(--tea-control-icon\)\]:has(:is(svg)){width:var(--tea-control-icon);height:var(--tea-control-icon)}.aria-disabled\:pointer-events-none[aria-disabled=true]{pointer-events:none}.aria-disabled\:opacity-50[aria-disabled=true]{opacity:.5}.aria-invalid\:border-critical[aria-invalid=true]{border-color:var(--tea-critical)}.aria-invalid\:bg-critical-subtle[aria-invalid=true]{background-color:var(--tea-critical-subtle)}.aria-\[current\=page\]\:border-primary[aria-current=page]{border-color:var(--tea-primary)}.aria-\[current\=page\]\:text-primary[aria-current=page]{color:var(--tea-primary)}.aria-\[invalid\=true\]\:border-critical[aria-invalid=true]{border-color:var(--tea-critical)}.aria-\[invalid\=true\]\:ring-0[aria-invalid=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.aria-\[invalid\=true\]\:ring-critical[aria-invalid=true]{--tw-ring-color:var(--tea-critical)}.data-disabled\:pointer-events-none[data-disabled]{pointer-events:none}.data-disabled\:opacity-50[data-disabled]{opacity:.5}.data-\[active\]\:bg-accent-subtle[data-active]{background-color:var(--tea-accent-subtle)}.data-\[active\]\:text-fg[data-active]{color:var(--tea-fg)}.data-\[active\=true\]\:bg-accent-subtle[data-active=true]{background-color:var(--tea-accent-subtle)}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[disabled\=true\]\:cursor-not-allowed[data-disabled=true]{cursor:not-allowed}.data-\[disabled\=true\]\:opacity-50[data-disabled=true]{opacity:.5}.data-\[highlighted\]\:bg-accent-subtle[data-highlighted]{background-color:var(--tea-accent-subtle)}.data-\[highlighted\]\:bg-critical-subtle[data-highlighted]{background-color:var(--tea-critical-subtle)}.data-\[highlighted\]\:text-critical[data-highlighted]{color:var(--tea-critical)}.data-\[highlighted\]\:text-fg[data-highlighted]{color:var(--tea-fg)}.data-\[hover\]\:border-line-strong[data-hover]{border-color:var(--tea-line-strong)}.data-\[hover\]\:bg-surface-3[data-hover]{background-color:var(--tea-surface-3)}.data-\[orientation\=horizontal\]\:h-1[data-orientation=horizontal]{height:var(--spacing)}.data-\[orientation\=horizontal\]\:h-4[data-orientation=horizontal]{height:calc(var(--spacing) * 4)}.data-\[orientation\=horizontal\]\:h-full[data-orientation=horizontal]{height:100%}.data-\[orientation\=horizontal\]\:w-full[data-orientation=horizontal]{width:100%}.data-\[orientation\=vertical\]\:h-full[data-orientation=vertical]{height:100%}.data-\[orientation\=vertical\]\:w-1[data-orientation=vertical]{width:var(--spacing)}.data-\[orientation\=vertical\]\:w-4[data-orientation=vertical]{width:calc(var(--spacing) * 4)}.data-\[orientation\=vertical\]\:w-full[data-orientation=vertical]{width:100%}.data-\[orientation\=vertical\]\:flex-col[data-orientation=vertical]{flex-direction:column}.data-\[orientation\=vertical\]\:border-s-2[data-orientation=vertical]{border-inline-start-style:var(--tw-border-style);border-inline-start-width:2px}.data-\[orientation\=vertical\]\:border-e[data-orientation=vertical]{border-inline-end-style:var(--tw-border-style);border-inline-end-width:1px}.data-\[orientation\=vertical\]\:border-e-0[data-orientation=vertical]{border-inline-end-style:var(--tw-border-style);border-inline-end-width:0}.data-\[orientation\=vertical\]\:border-b-0[data-orientation=vertical]{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.data-\[orientation\=vertical\]\:text-start[data-orientation=vertical]{text-align:start}.data-\[placeholder\]\:text-fg-muted[data-placeholder]{color:var(--tea-fg-muted)}.data-\[state\=active\]\:border-primary[data-state=active]{border-color:var(--tea-primary)}.data-\[state\=active\]\:font-medium[data-state=active]{--tw-font-weight:500;font-weight:500}.data-\[state\=active\]\:text-primary[data-state=active]{color:var(--tea-primary)}.data-\[state\=checked\]\:translate-x-3[data-state=checked]{--tw-translate-x:calc(var(--spacing) * 3);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[state\=checked\]\:border-primary[data-state=checked]{border-color:var(--tea-primary)}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:var(--tea-primary)}.data-\[state\=checked\]\:bg-primary-fg[data-state=checked]{background-color:var(--tea-primary-fg)}.data-\[state\=checked\]\:text-primary[data-state=checked]{color:var(--tea-primary)}.data-\[state\=closed\]\:animate-out[data-state=closed]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-\[state\=closed\]\:fade-out-0[data-state=closed]{--tw-exit-opacity:0}.data-\[state\=closed\]\:zoom-out-95[data-state=closed]{--tw-exit-scale:.95}.data-\[state\=closed\]\:slide-out-to-bottom[data-state=closed]{--tw-exit-translate-y:100%}.data-\[state\=closed\]\:slide-out-to-left[data-state=closed]{--tw-exit-translate-x:-100%}.data-\[state\=closed\]\:slide-out-to-right[data-state=closed]{--tw-exit-translate-x:100%}.data-\[state\=closed\]\:slide-out-to-right-full[data-state=closed]{--tw-exit-translate-x:calc(1*100%)}.data-\[state\=closed\]\:slide-out-to-top[data-state=closed]{--tw-exit-translate-y:-100%}.data-\[state\=delayed-open\]\:animate-in[data-state=delayed-open]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-\[state\=delayed-open\]\:fade-in-0[data-state=delayed-open]{--tw-enter-opacity:0}.data-\[state\=delayed-open\]\:zoom-in-95[data-state=delayed-open]{--tw-enter-scale:.95}.data-\[state\=indeterminate\]\:border-primary[data-state=indeterminate]{border-color:var(--tea-primary)}.data-\[state\=indeterminate\]\:bg-primary[data-state=indeterminate]{background-color:var(--tea-primary)}.data-\[state\=on\]\:border-primary[data-state=on]{border-color:var(--tea-primary)}.data-\[state\=on\]\:bg-primary-subtle[data-state=on]{background-color:var(--tea-primary-subtle)}.data-\[state\=on\]\:text-primary[data-state=on]{color:var(--tea-primary)}.data-\[state\=open\]\:animate-in[data-state=open]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-\[state\=open\]\:fade-in-0[data-state=open]{--tw-enter-opacity:0}.data-\[state\=open\]\:zoom-in-95[data-state=open]{--tw-enter-scale:.95}.data-\[state\=open\]\:slide-in-from-bottom[data-state=open]{--tw-enter-translate-y:100%}.data-\[state\=open\]\:slide-in-from-left[data-state=open]{--tw-enter-translate-x:-100%}.data-\[state\=open\]\:slide-in-from-right[data-state=open]{--tw-enter-translate-x:100%}.data-\[state\=open\]\:slide-in-from-right-full[data-state=open]{--tw-enter-translate-x:calc(1*100%)}.data-\[state\=open\]\:slide-in-from-top[data-state=open]{--tw-enter-translate-y:-100%}.data-\[state\=unchecked\]\:translate-x-0[data-state=unchecked],.data-\[swipe\=cancel\]\:translate-x-0[data-swipe=cancel]{--tw-translate-x:0px;translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[swipe\=end\]\:animate-out[data-swipe=end]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-\[swipe\=move\]\:translate-x-\[var\(--radix-toast-swipe-move-x\)\][data-swipe=move]{--tw-translate-x:var(--radix-toast-swipe-move-x);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[swipe\=move\]\:transition-none[data-swipe=move]{transition-property:none}@media (min-width:40rem){.sm\:flex{display:flex}.sm\:inline{display:inline}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}}@media (min-width:48rem){.md\:flex{display:flex}.md\:hidden{display:none}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:grid-cols-\[2fr_repeat\(auto-fit\,minmax\(9rem\,1fr\)\)\]{grid-template-columns:2fr repeat(auto-fit,minmax(9rem,1fr))}.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:justify-between{justify-content:space-between}.md\:p-6{padding:calc(var(--spacing) * 6)}.md\:px-6{padding-inline:calc(var(--spacing) * 6)}.md\:py-6{padding-block:calc(var(--spacing) * 6)}}@media (min-width:64rem){.lg\:block{display:block}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (pointer:coarse){.pointer-coarse\:text-body{font-size:1rem;line-height:var(--tw-leading,1.625rem)}}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_svg\]\:text-fg-muted svg{color:var(--tea-fg-muted)}.\[\&\>\*\+\*\]\:-ms-px>*+*{margin-inline-start:-1px}.\[\&\>\*\+\*\]\:-mt-px>*+*{margin-top:-1px}.\[\&\>svg\]\:mt-0\.5>svg{margin-top:calc(var(--spacing) * .5)}.\[\&\>svg\]\:shrink-0>svg{flex-shrink:0}}@property --tw-animation-delay{syntax:"*";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:"*";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:"*";inherits:false}@property --tw-animation-fill-mode{syntax:"*";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:"*";inherits:false;initial-value:0}:root,[data-theme=tea]{color-scheme:dark;--tea-canvas:#111318;--tea-surface:#171a21;--tea-surface-2:#1e222b;--tea-surface-3:#232733;--tea-overlay:#000000c7;--tea-fg:#e8e6e0;--tea-fg-muted:#a3a096;--tea-fg-subtle:#83807a;--tea-fg-inverse:#111318;--tea-line:#343a46;--tea-line-strong:#4e5666;--tea-brand:#f2c012;--tea-primary:#f2c012;--tea-primary-fg:#111318;--tea-primary-hover:#f7c72e;--tea-primary-subtle:#f2c0121f;--tea-primary-border:#f2c01266;--tea-accent:#f2c012;--tea-accent-fg:#111318;--tea-accent-subtle:#f2c0121a;--tea-ring:#f2c012;--tea-ring-strong:#ffd84d;--tea-positive:#4ade80;--tea-positive-fg:#0b1f14;--tea-positive-subtle:#4ade801f;--tea-positive-border:#4ade8066;--tea-info:#60a5fa;--tea-info-fg:#0a1729;--tea-info-subtle:#60a5fa1f;--tea-info-border:#60a5fa66;--tea-caution:#fb923c;--tea-caution-fg:#241104;--tea-caution-subtle:#fb923c1f;--tea-caution-border:#fb923c66;--tea-critical:#ff6b5e;--tea-critical-fg:#240705;--tea-critical-subtle:#ff6b5e1f;--tea-critical-border:#ff6b5e66;--tea-neutral:#a3a096;--tea-neutral-fg:#111318;--tea-neutral-subtle:#a3a0961f;--tea-neutral-border:#a3a09666;--tea-destructive:var(--tea-critical);--tea-destructive-fg:var(--tea-critical-fg);--tea-destructive-subtle:var(--tea-critical-subtle);--tea-destructive-border:var(--tea-critical-border);--tea-density:default;--tea-font-sans:"Jost Variable", "Jost", "Futura", ui-sans-serif, system-ui, sans-serif;--tea-font-mono:"JetBrains Mono", ui-monospace, "SFMono-Regular", monospace;--tea-font-display:"Lilita One", "Jost Variable", ui-sans-serif, system-ui, sans-serif;--tea-shadow-raised:0 1px 3px #0000004d;--tea-shadow-overlay:6px 6px 0 0 #00000080;--tea-shadow-modal:8px 8px 0 0 #00000080;--tea-shadow-inset:inset 0 1px 0 0 #ffffff0a}[data-theme=hsm]{color-scheme:dark;--tea-canvas:#0e1116;--tea-surface:#161a21;--tea-surface-2:#1c212a;--tea-surface-3:#232935;--tea-overlay:#000c;--tea-fg:#e9eaee;--tea-fg-muted:#a1a8b4;--tea-fg-subtle:#808894;--tea-fg-inverse:#0e1116;--tea-line:#2f3743;--tea-line-strong:#49525f;--tea-brand:#e0332e;--tea-primary:#f2c012;--tea-primary-fg:#0e1116;--tea-primary-hover:#f7c72e;--tea-primary-subtle:#f2c0121f;--tea-primary-border:#f2c01266;--tea-accent:#f2c012;--tea-accent-fg:#0e1116;--tea-accent-subtle:#f2c0121a;--tea-ring:#f2c012;--tea-ring-strong:#ffd84d;--tea-positive:#4ade80;--tea-positive-fg:#0b1f14;--tea-positive-subtle:#4ade801f;--tea-positive-border:#4ade8066;--tea-info:#60a5fa;--tea-info-fg:#0a1729;--tea-info-subtle:#60a5fa1f;--tea-info-border:#60a5fa66;--tea-caution:#fb923c;--tea-caution-fg:#241104;--tea-caution-subtle:#fb923c1f;--tea-caution-border:#fb923c66;--tea-critical:#f87171;--tea-critical-fg:#240705;--tea-critical-subtle:#f871711f;--tea-critical-border:#f8717166;--tea-neutral:#a1a8b4;--tea-neutral-fg:#0e1116;--tea-neutral-subtle:#a1a8b41f;--tea-neutral-border:#a1a8b466;--tea-destructive:var(--tea-critical);--tea-destructive-fg:var(--tea-critical-fg);--tea-destructive-subtle:var(--tea-critical-subtle);--tea-destructive-border:var(--tea-critical-border);--tea-density:default;--tea-font-sans:"Jost Variable", "Jost", "Futura", ui-sans-serif, system-ui, sans-serif;--tea-font-mono:"JetBrains Mono", ui-monospace, "SFMono-Regular", monospace;--tea-font-display:"Lilita One", "Jost Variable", ui-sans-serif, system-ui, sans-serif;--tea-shadow-raised:0 1px 3px #00000059;--tea-shadow-overlay:6px 6px 0 0 #0000008c;--tea-shadow-modal:8px 8px 0 0 #0000008c;--tea-shadow-inset:inset 0 1px 0 0 #ffffff0a}[data-theme=lutea]{color-scheme:dark;--tea-canvas:#121317;--tea-surface:#1a1b1f;--tea-surface-2:#212329;--tea-surface-3:#2a2c33;--tea-overlay:#000000c7;--tea-fg:#ede9e1;--tea-fg-muted:#aba69b;--tea-fg-subtle:#8a857b;--tea-fg-inverse:#121317;--tea-line:#383b44;--tea-line-strong:#525663;--tea-brand:#f2c012;--tea-primary:#f2c012;--tea-primary-fg:#121317;--tea-primary-hover:#f7c72e;--tea-primary-subtle:#f2c0121f;--tea-primary-border:#f2c01266;--tea-accent:#f2c012;--tea-accent-fg:#121317;--tea-accent-subtle:#f2c0121a;--tea-ring:#f2c012;--tea-ring-strong:#ffd84d;--tea-positive:#4fc97e;--tea-positive-fg:#0a1f13;--tea-positive-subtle:#4fc97e1f;--tea-positive-border:#4fc97e66;--tea-info:#5b8def;--tea-info-fg:#08142b;--tea-info-subtle:#5b8def1f;--tea-info-border:#5b8def66;--tea-caution:#f2921e;--tea-caution-fg:#1f1204;--tea-caution-subtle:#f2921e1f;--tea-caution-border:#f2921e66;--tea-critical:#f0726a;--tea-critical-fg:#230604;--tea-critical-subtle:#f0726a1f;--tea-critical-border:#f0726a66;--tea-neutral:#aba69b;--tea-neutral-fg:#121317;--tea-neutral-subtle:#aba69b1f;--tea-neutral-border:#aba69b66;--tea-destructive:var(--tea-critical);--tea-destructive-fg:var(--tea-critical-fg);--tea-destructive-subtle:var(--tea-critical-subtle);--tea-destructive-border:var(--tea-critical-border);--tea-density:compact;--tea-font-sans:"Jost Variable", "Jost", "Futura", ui-sans-serif, system-ui, sans-serif;--tea-font-mono:"JetBrains Mono", ui-monospace, "SFMono-Regular", monospace;--tea-font-display:"Lilita One", "Jost Variable", ui-sans-serif, system-ui, sans-serif;--tea-shadow-raised:0 1px 3px #00000047;--tea-shadow-overlay:6px 6px 0 0 #00000080;--tea-shadow-modal:8px 8px 0 0 #00000080;--tea-shadow-inset:inset 0 1px 0 0 #ffffff0d}:root,[data-density=default]{--tea-control-h:2rem;--tea-control-px:.75rem;--tea-control-icon:1rem;--tea-row-h:2.25rem;--tea-cell-py:.5rem;--tea-cell-px:.75rem;--tea-gap:.75rem;--tea-section-gap:1.5rem;--tea-field-gap:1.25rem;--tea-pad-card:1.25rem;--tea-text-ui:.875rem;--tea-text-label:.6875rem;--tea-touch-min:2.75rem}[data-density=compact]{--tea-control-h:1.75rem;--tea-control-px:.625rem;--tea-control-icon:.875rem;--tea-row-h:2rem;--tea-cell-py:.375rem;--tea-cell-px:.625rem;--tea-gap:.5rem;--tea-section-gap:1.25rem;--tea-field-gap:1rem;--tea-pad-card:1rem;--tea-text-ui:.8125rem;--tea-text-label:.6875rem;--tea-touch-min:2.75rem}[data-density=comfortable]{--tea-control-h:2.25rem;--tea-control-px:.875rem;--tea-control-icon:1.125rem;--tea-row-h:2.75rem;--tea-cell-py:.75rem;--tea-cell-px:.875rem;--tea-gap:1rem;--tea-section-gap:2rem;--tea-field-gap:1.5rem;--tea-pad-card:1.5rem;--tea-text-ui:.9375rem;--tea-text-label:.75rem;--tea-touch-min:2.75rem}@keyframes tea-pulse-essential{0%{opacity:.35}50%{opacity:1}to{opacity:.35}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0));filter:blur(var(--tw-enter-blur,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0));filter:blur(var(--tw-exit-blur,0))}}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tea-ui/public",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "The public layer: marketing sections, hero, pricing, FAQ, conversion forms.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md",
|
|
11
|
+
"LICENSE"
|
|
12
|
+
],
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js",
|
|
17
|
+
"default": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./package.json": "./package.json",
|
|
20
|
+
"./styles.css": "./dist/styles.css"
|
|
21
|
+
},
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"module": "./dist/index.js",
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsup && node ../../scripts/fix-esm-extensions.mjs public && node ../../scripts/sync-styles.mjs",
|
|
29
|
+
"prepublishOnly": "node ../../scripts/prepublish-guard.mjs"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@tea-ui/core": "^0.1.0",
|
|
33
|
+
"@tea-ui/icons": "^0.1.0",
|
|
34
|
+
"@tea-ui/ux-standards": "^0.1.0",
|
|
35
|
+
"@tea-ui/utils": "^0.1.0",
|
|
36
|
+
"radix-ui": "^1.4.3"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"react": ">=18.2.0 <20.0.0",
|
|
40
|
+
"react-dom": ">=18.2.0 <20.0.0"
|
|
41
|
+
},
|
|
42
|
+
"keywords": [
|
|
43
|
+
"react",
|
|
44
|
+
"landing",
|
|
45
|
+
"marketing",
|
|
46
|
+
"components",
|
|
47
|
+
"tea-ui",
|
|
48
|
+
"design-system"
|
|
49
|
+
],
|
|
50
|
+
"author": "landnevermore",
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "git+https://github.com/landnevermore/TEAui.git",
|
|
54
|
+
"directory": "packages/public"
|
|
55
|
+
},
|
|
56
|
+
"homepage": "https://landnevermore.github.io/TEAui/docs/",
|
|
57
|
+
"bugs": {
|
|
58
|
+
"url": "https://github.com/landnevermore/TEAui/issues"
|
|
59
|
+
}
|
|
60
|
+
}
|