@photon-ai/pho-ui 2.1.0 → 2.1.1

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.
@@ -77,7 +77,7 @@ function E({ morphId: e, fromClassName: t, fly: i, morphRef: n, fallback: o = !1
77
77
  i && c(!0);
78
78
  },
79
79
  onLayoutAnimationComplete: () => c(!1),
80
- className: "relative inline-block max-w-full min-w-0 truncate",
80
+ className: "relative inline-block",
81
81
  children: [s, l && /* @__PURE__ */ a(u.span, {
82
82
  "aria-hidden": !0,
83
83
  initial: { opacity: 1 },
@@ -403,7 +403,7 @@ function de({ href: e, className: t, morphId: i, children: n = "Back", ...o }) {
403
403
  className: "inline-flex [&>svg]:size-[1.125em] [&>svg]:shrink-0",
404
404
  children: /* @__PURE__ */ a(N, {})
405
405
  }) : /* @__PURE__ */ a(N, {}),
406
- className: r("absolute top-4 left-[10.25px]", t),
406
+ className: r("absolute top-4 left-[10.25px] min-w-max", t),
407
407
  ...o,
408
408
  children: l && i != null ? /* @__PURE__ */ a(E, {
409
409
  morphId: i,
@@ -479,4 +479,4 @@ export {
479
479
  b as t
480
480
  };
481
481
 
482
- //# sourceMappingURL=basic-page-Dfln58iw.js.map
482
+ //# sourceMappingURL=basic-page-x3aFcSVs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basic-page-x3aFcSVs.js","names":[],"sources":["../../../../node_modules/.pnpm/@tabler+icons-react@3.44.0_react@19.2.7/node_modules/@tabler/icons-react/dist/esm/icons/IconChevronRight.mjs","../../src/sections/basic-page/basic-page.tsx"],"sourcesContent":["/**\n * @license @tabler/icons-react v3.44.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createReactComponent from '../createReactComponent.mjs';\n\nconst __iconNode = [[\"path\", { \"d\": \"M9 6l6 6l-6 6\", \"key\": \"svg-0\" }]];\nconst IconChevronRight = createReactComponent(\"outline\", \"chevron-right\", \"ChevronRight\", __iconNode);\n\nexport { __iconNode, IconChevronRight as default };\n//# sourceMappingURL=IconChevronRight.mjs.map\n","import {\n Children,\n useEffect,\n useRef,\n useState,\n type AnchorHTMLAttributes,\n type ComponentProps,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport { IconChevronLeft, IconChevronRight } from \"@tabler/icons-react\";\nimport { ButtonLink, type ButtonLinkProps } from \"../../components/button\";\nimport { Error as ErrorLine } from \"../../components/error\";\nimport { AnimatedHeight } from \"../../utils/animated-height\";\nimport { cn } from \"../../utils/cn\";\nimport { useLinkComponent } from \"../../utils/link-provider\";\n\n/**\n * BasicPage — Pho's standard content page: a page title, section titles, and\n * bordered cards of label/control rows. Settings, billing, members — any\n * single-column management surface.\n *\n * Spacing: wrap the page in `Root` (a 42rem column with `px-5` gutters,\n * vertical padding). `Stack` separates blocks (`gap-10`). Inside a block,\n * children share `gap-3`. Wrap a section title + description in `Header`\n * (no gap — title and description sit flush) so that pair stays tight —\n * don't put them as loose siblings.\n * Parts already carry `px-5`.\n *\n * Navigation: pages may drill into subpages. `RowLink` is a whole-row link\n * (trailing chevron) and `Back` returns to the parent — both render through\n * the host's `LinkProvider`; the URL itself stays the router's job. `Back`\n * floats in `Root`'s top padding, so `Title` never moves between pages that\n * have a back link and pages that don't.\n */\n\n/* ------------------------------- class map ------------------------------- */\n\n/** Card surface — border, corner, fill; no divider rules. */\nconst BASIC_PAGE_CARD_SURFACE =\n \"rounded-base border border-pho-secondary bg-pho-primary\";\n\n/**\n * Card divider rules — hairlines between direct children. A row followed by\n * an `Alert` drops its divider (the `:has()` rule) so the error line reads\n * as part of the row it belongs to — the alert's own bottom divider takes\n * over toward whatever follows. Kept separate from the surface so\n * `animateHeight` can move the dividers onto the measured content wrapper.\n */\nconst BASIC_PAGE_CARD_DIVIDERS =\n \"divide-y divide-pho-secondary [&>:has(+[data-basic-page-alert])]:border-b-0\";\n\n/** Bordered card that stacks rows with hairline dividers. */\nexport const BASIC_PAGE_CARD = `${BASIC_PAGE_CARD_SURFACE} ${BASIC_PAGE_CARD_DIVIDERS}`;\n\n/**\n * Standalone callout surface — featured block (invite form, notice, etc.).\n * Don't wrap in `Card`; this is the outer chrome.\n */\nexport const BASIC_PAGE_CALLOUT =\n \"flex min-w-0 flex-col gap-3 rounded-base border border-pho-secondary bg-pho-page p-5\";\n\n/**\n * One row — label (+ optional description) left, control right.\n * `min-h-[4.25rem]` (68px) keeps avatar/control rows from collapsing shorter\n * than a comfortable touch target.\n */\nexport const BASIC_PAGE_ROW =\n \"flex min-h-[4.25rem] min-w-0 flex-col gap-3 px-5 py-4 sm:flex-row sm:items-center sm:justify-between sm:gap-6\";\n\n/**\n * One card row that can host subviews. Same padding rhythm as a plain row —\n * an optional trailing `ItemPanel` breaks out of it on its own.\n */\nexport const BASIC_PAGE_ITEM = \"flex flex-col gap-3 px-5 py-4\";\n\n/**\n * Secondary strip closing an `Item` that is last in its card. Negative\n * margins escape the item's `px-5 pb-4` so the gray sheet runs edge-to-edge\n * and owns the row's bottom padding. The body above stays square and the\n * sheet's top is flush against it; only the bottom rounds, nesting into the\n * card's 12px corner (11px inside the 1px border). Content lands back on the\n * item's left gutter.\n */\nexport const BASIC_PAGE_ITEM_PANEL =\n \"-mx-5 -mb-4 flex items-center rounded-b-[calc(0.75rem-1px)] bg-pho-secondary py-1 pr-3 pl-5\";\n\n/**\n * Mid-list variant — the full-bleed sheet only reads well against the card's\n * bottom corner, so when later rows follow, the panel becomes an inset chip\n * instead: fully rounded at the small-control radius, overhanging the text\n * gutter by 8px per side (content stays aligned with the body above), and\n * leaving the row's own bottom padding and the card's hairline divider alone.\n * `-mt-1.5` collapses the item's `gap-3` (12px) to an effective `gap-1.5` (6px).\n */\nexport const BASIC_PAGE_ITEM_PANEL_DIVIDED =\n \"-mx-2 -mt-1.5 flex items-center rounded-sm bg-pho-secondary px-2 py-0.5\";\n\n/* --------------------------------- motion -------------------------------- */\n\n/**\n * One spring for every BasicPage motion — the `Stack` entrance, `Title` /\n * `Header` enter, `Reveal`, the Title ↔ Back morph, and the `Alert` /\n * `Footer` height reveals. Measured off a 60fps iOS push: ~330ms with a\n * long, gentle glide, everything co-landing. Essentially critically damped\n * (an overshooting edge would show clipped content).\n */\nconst ENTRANCE_SPRING = {\n type: \"spring\",\n stiffness: 400,\n damping: 40,\n} as const;\n\n/** Fade paired with the spring — spans most of the glide. */\nconst ENTRANCE_FADE = { duration: 0.25, ease: \"easeOut\" } as const;\n\n/* --------------------------------- parts --------------------------------- */\n\n/**\n * Page chrome — centered column at the standard content width. Hosts\n * `Title` + `Stack` (and any route-level siblings). Prefer this over\n * ad-hoc `max-w-*` wrappers in the app shell.\n *\n * `44.5rem` = the 42rem (`2xl`) content column plus the two `px-5` gutters,\n * so wide viewports render exactly as before while narrow ones keep a 20px\n * breathing edge instead of running content into the viewport.\n *\n * `relative` anchors `Back`, which floats in the top padding. The top zone\n * is conditional (`:has()`): pages carrying a `Back` reserve 64px for it;\n * pages without one keep the tighter 48px so the title doesn't sit low.\n *\n * The column is also a `min-h-full` flex stack: when the host gives it a\n * height context (an app shell's scroll pane), a full-page state can claim\n * the leftover viewport with `flex-1` — `ErrorView className=\"flex-1\"`\n * centers itself vertically below the title. Hosts without a height context\n * see a normal column; regular pages are unaffected.\n *\n * Root itself never animates — the page entrance lives on `Stack`, so\n * `Title` and `Back` (the page chrome) stay put while the body below rises\n * in.\n */\nfunction Root({\n className,\n ...props\n}: ComponentProps<\"div\"> & { ref?: Ref<HTMLDivElement> }) {\n return (\n <div\n className={cn(\n \"relative mx-auto flex min-h-full w-full max-w-[44.5rem] min-w-0 flex-col px-5 pt-12 pb-12 *:min-w-0 has-[[data-basic-page-back]]:pt-16\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Slug for hash targets — \"Danger zone\" → `danger-zone`. Empty / non-string\n * children yield no id; pass an explicit `id` to override or `id=\"\"` to opt out.\n */\nfunction slugifyHeading(value: string): string {\n return value\n .normalize(\"NFKD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\nfunction headingIdFromChildren(children: ReactNode): string | undefined {\n if (typeof children !== \"string\" && typeof children !== \"number\") {\n return undefined;\n }\n const slug = slugifyHeading(String(children));\n return slug || undefined;\n}\n\n/** Resolve `id`: explicit wins; `\"\"` opts out; else slug from plain-text children. */\nfunction resolveHeadingId(\n id: string | undefined,\n children: ReactNode,\n): string | undefined {\n if (id === \"\") return undefined;\n if (id != null) return id;\n return headingIdFromChildren(children);\n}\n\n/**\n * Namespaced Motion `layoutId` for the Title ↔ Back shared-element morph —\n * give a parent page's `Title` and its subpage's `Back` the same `morphId`\n * and the word itself travels between the two: the large title shrinks into\n * the back link on drill-in, and grows back on return.\n */\nconst morphLayoutId = (id: string) => `basic-page-morph-${id}`;\n\n/** The morph rides the page-tier entrance spring — one glide, everywhere. */\nconst MORPH_TRANSITION = { layout: ENTRANCE_SPRING } as const;\n\n/**\n * Chevron entrance for a morphing `Back`, measured off a 60fps iOS push\n * (sub-pixel tracking of the recording): the arrow emerges from under the\n * left edge of the arriving word at ~62% of the flight — sliding left by\n * ~2/3 of its own width with a strong ease-out while fading in over ~120ms\n * — and lands together with the word, which is still gliding its last few\n * pixels the whole time. Nothing is sequential.\n */\nconst MORPH_CHEVRON_RISE_X = 10;\nconst MORPH_CHEVRON_ENTER = {\n delay: 0.2,\n duration: 0.12,\n ease: \"easeOut\",\n} as const;\n\n/**\n * Ink crossfade for the morphing word — iOS redraws the word in the\n * destination's ink and fades the origin-ink rendition out over the first\n * half of the flight, so the word takes off in the color it had and lands\n * in the color it gets. `MorphLabel` mounts the ghost only while a layout\n * animation is actually running, so static renders never see it.\n */\nconst MORPH_INK_FADE = { duration: 0.18, ease: \"easeOut\" } as const;\n\n/**\n * A shared element can only fly between two points the user has seen. Each\n * morph word tracks whether it is on screen (keyed by `morphId`); when the\n * other end mounts, it flies only if the word it continues was visible.\n * A title scrolled out of view yields a plain fade at the destination\n * instead of a dive in from off-screen.\n */\nconst morphWordVisible = new Map<string, boolean>();\n\n/**\n * Mount-locked flight decision + live visibility tracking for a morph word.\n * `fly` is read from the registry once at mount (was the other end on\n * screen?); the ref then feeds this word's own visibility back for the next\n * navigation. No-ops without `IntersectionObserver` (jsdom, SSR).\n */\nfunction useMorphFlight(morphId: string | undefined) {\n const [fly] = useState(\n () => morphId != null && morphWordVisible.get(morphId) === true,\n );\n const ref = useRef<HTMLSpanElement | null>(null);\n useEffect(() => {\n if (morphId == null || typeof IntersectionObserver === \"undefined\") return;\n const el = ref.current;\n if (!el) return;\n const observer = new IntersectionObserver(([entry]) => {\n if (entry) morphWordVisible.set(morphId, entry.isIntersecting);\n });\n observer.observe(el);\n return () => {\n observer.disconnect();\n };\n }, [morphId]);\n return { fly, ref };\n}\n\n/**\n * The shared-element word of a Title ↔ Back morph. While the box flies, an\n * origin-ink copy of the word sits on top and fades out (the iOS snapshot\n * crossfade); the copy only exists during a real layout animation. When the\n * flight is skipped (`fly` false — the other end wasn't on screen), the\n * layout snap is instant and, with `fallback`, the word fades in instead.\n */\nfunction MorphLabel({\n morphId,\n fromClassName,\n fly,\n morphRef,\n fallback = false,\n children,\n}: {\n morphId: string;\n /** Ink the word arrives FROM (the other end's text color). */\n fromClassName: string;\n /** Fly the layout box — the other end was on screen at navigation. */\n fly: boolean;\n morphRef: React.Ref<HTMLSpanElement>;\n /** Fade the word in when not flying (instead of appearing instantly). */\n fallback?: boolean;\n children: ReactNode;\n}) {\n const [crossfading, setCrossfading] = useState(false);\n const fade = !fly && fallback;\n return (\n <motion.span\n ref={morphRef}\n layoutId={morphLayoutId(morphId)}\n initial={fade ? { opacity: 0 } : undefined}\n animate={fade ? { opacity: 1 } : undefined}\n transition={\n fly\n ? MORPH_TRANSITION\n : { layout: { duration: 0 }, opacity: ENTRANCE_FADE }\n }\n onLayoutAnimationStart={() => {\n if (fly) setCrossfading(true);\n }}\n onLayoutAnimationComplete={() => setCrossfading(false)}\n className=\"relative inline-block\"\n >\n {children}\n {crossfading && (\n <motion.span\n aria-hidden\n initial={{ opacity: 1 }}\n animate={{ opacity: 0 }}\n transition={MORPH_INK_FADE}\n className={cn(\"absolute inset-0\", fromClassName)}\n >\n {children}\n </motion.span>\n )}\n </motion.span>\n );\n}\n\nexport interface BasicPageTitleProps extends ComponentProps<\"h1\"> {\n /**\n * Shared-element key. Pair with the same `morphId` on the subpage's\n * `Back` and the word morphs between title and back link across the\n * navigation. Skipped under reduced motion.\n */\n morphId?: string;\n /**\n * Rise this title into its line on mount — for a subpage title whose line\n * an inbound Title ↔ Back morph departs from. The moment the word lifts\n * off, this title floats up from just below it (the Stack physics), so\n * the two form one upward stream and never overlap. Skipped under\n * reduced motion.\n */\n enter?: boolean;\n ref?: Ref<HTMLHeadingElement>;\n}\n\n/**\n * Page title — largest heading on the surface. Plain-text children get a slug\n * `id` for hash targets (`#profile`); the heading itself is not a link.\n * Long names ellipsize; keep trailing accessories (`Badge`, status) as\n * `shrink-0` siblings of a `min-w-0 truncate` label inside a `flex min-w-0`\n * row so they stay visible.\n */\nfunction Title({\n id,\n morphId,\n enter,\n className,\n children,\n ...props\n}: BasicPageTitleProps) {\n const headingId = resolveHeadingId(id, children);\n const reduceMotion = useReducedMotion();\n const flight = useMorphFlight(morphId);\n return (\n <h1\n id={headingId}\n className={cn(\n \"text-display-base text-pho-primary max-w-full min-w-0 scroll-mt-12 truncate px-5 font-medium\",\n className,\n )}\n {...props}\n >\n {morphId != null && !reduceMotion ? (\n <MorphLabel\n morphId={morphId}\n fromClassName=\"text-pho-secondary\"\n fly={flight.fly}\n morphRef={flight.ref}\n >\n {children}\n </MorphLabel>\n ) : enter && !reduceMotion ? (\n <motion.span\n initial={{ opacity: 0, y: REVEAL_RISE_PX }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ y: ENTRANCE_SPRING, opacity: ENTRANCE_FADE }}\n className=\"inline-block max-w-full min-w-0 truncate\"\n >\n {children}\n </motion.span>\n ) : (\n children\n )}\n </h1>\n );\n}\n\nexport interface BasicPageStackProps extends Omit<\n ComponentProps<\"div\">,\n RevealMotionConflicts\n> {\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * Vertical stack under the page title. Blocks (forms / sections) use `gap-10`;\n * each block lays out its children with `gap-3`.\n *\n * Mounting plays the page entrance: the stack rises 12px and fades in on the\n * Card-shell / Command spring while `Title` / `Back` above stay put. What\n * that means per state:\n *\n * - **Entering the page** — whatever the page first shows (skeleton\n * included) rides in with its stack.\n * - **Skeleton in a separate component** — swapping it for the loaded\n * return mounts a fresh stack, so the entrance replays as the\n * data-arrival animation. That's the right feel for shapes the skeleton\n * couldn't predict (lists of unknown length).\n * - **1:1 skeleton** — keep ONE stack mounted and branch its children\n * (`{pending ? bones : content}`): values then fill in place with no\n * motion.\n *\n * Static under reduced motion.\n */\nfunction Stack({ className, ...props }: BasicPageStackProps) {\n const reduceMotion = useReducedMotion();\n return (\n <motion.div\n initial={reduceMotion ? false : { opacity: 0, y: REVEAL_RISE_PX }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ y: ENTRANCE_SPRING, opacity: ENTRANCE_FADE }}\n className={cn(\n \"mt-6 flex min-w-0 flex-col gap-10\",\n \"*:flex *:min-w-0 *:flex-col *:gap-3\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Title + optional description pair. No gap between them — the block's\n * `gap-3` only applies between this header and the card.\n */\nexport interface BasicPageHeaderProps extends Omit<\n ComponentProps<\"div\">,\n RevealMotionConflicts\n> {\n /**\n * Rise this header into place on mount — the Header flavor of `Title`'s\n * `enter`, for a subpage title that carries a description: the pair\n * floats up from below the departing morph word as one block. Put `enter`\n * here and NOT on the `Title` inside. Skipped under reduced motion.\n */\n enter?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\nfunction Header({ enter, className, ...props }: BasicPageHeaderProps) {\n const reduceMotion = useReducedMotion();\n if (enter && !reduceMotion) {\n return (\n <motion.div\n initial={{ opacity: 0, y: REVEAL_RISE_PX }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ y: ENTRANCE_SPRING, opacity: ENTRANCE_FADE }}\n className={cn(\"flex min-w-0 flex-col\", className)}\n {...props}\n />\n );\n }\n return <div className={cn(\"flex min-w-0 flex-col\", className)} {...props} />;\n}\n\n/**\n * Section heading — same padding as the page title, smaller type. Hashable via\n * slug `id` (not a link).\n */\nfunction SectionTitle({\n id,\n className,\n children,\n ...props\n}: ComponentProps<\"h2\"> & { ref?: Ref<HTMLHeadingElement> }) {\n const headingId = resolveHeadingId(id, children);\n return (\n <h2\n id={headingId}\n className={cn(\n \"text-display-xs text-pho-primary max-w-full min-w-0 scroll-mt-12 truncate px-5 font-medium\",\n className,\n )}\n {...props}\n >\n {children}\n </h2>\n );\n}\n\n/**\n * Supporting copy under a section title. Same display step as the title;\n * color + normal weight keep it secondary. Always wrap with `Header`.\n */\nfunction Description({\n className,\n ...props\n}: ComponentProps<\"p\"> & { ref?: Ref<HTMLParagraphElement> }) {\n return (\n <p\n className={cn(\n \"text-display-xs text-pho-description px-5 font-normal\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Optional caption below a section's `Card` (outside the card). One step\n * smaller than `Description` (`text-xs`). Not the card-internal dirty-state\n * `Footer`.\n */\nfunction SectionFooter({\n className,\n ...props\n}: ComponentProps<\"p\"> & { ref?: Ref<HTMLParagraphElement> }) {\n return (\n <p\n className={cn(\"text-pho-description px-5 text-xs font-normal\", className)}\n {...props}\n />\n );\n}\n\nexport interface BasicPageCardProps extends ComponentProps<\"div\"> {\n /**\n * Glide the card's height when its content swaps — bones becoming a\n * different number of rows, a row created or revoked, an inline state\n * change. The height follows the content on the page spring instead of\n * jumping. Reserve it for cards whose contents change while mounted.\n */\n animateHeight?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\n/** Bordered card that stacks rows with hairline dividers. */\nfunction Card({\n animateHeight,\n className,\n children,\n ...props\n}: BasicPageCardProps) {\n if (animateHeight) {\n return (\n <div\n className={cn(\n BASIC_PAGE_CARD_SURFACE,\n \"min-h-0 overflow-hidden\",\n className,\n )}\n {...props}\n >\n <AnimatedHeight\n transition={ENTRANCE_SPRING}\n className={BASIC_PAGE_CARD_DIVIDERS}\n >\n {children}\n </AnimatedHeight>\n </div>\n );\n }\n return (\n <div className={cn(BASIC_PAGE_CARD, className)} {...props}>\n {children}\n </div>\n );\n}\n\n/**\n * One card row that can host subviews. Padding matches a plain row, so use it\n * for any row that may grow an `ItemPanel` — primary content goes straight in\n * as children; the panel, when present, is the last child.\n *\n * ```tsx\n * <BasicPage.Card>\n * <BasicPage.Item>\n * …name, meta, actions…\n * <BasicPage.ItemPanel divided>…secret / expanded content…</BasicPage.ItemPanel>\n * </BasicPage.Item>\n * …later siblings (pass `divided` on the panel above)…\n * </BasicPage.Card>\n * ```\n */\nfunction Item({\n className,\n ...props\n}: ComponentProps<\"div\"> & { ref?: Ref<HTMLDivElement> }) {\n return <div className={cn(BASIC_PAGE_ITEM, className)} {...props} />;\n}\n\nexport interface BasicPageItemPanelProps extends ComponentProps<\"div\"> {\n /**\n * Set when later card rows follow this item. The panel then renders as an\n * inset rounded chip (keeping the card's own divider) instead of the\n * full-bleed bottom sheet, which only reads well against the card's corner.\n * @default false\n */\n divided?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * Secondary strip at the end of an `Item`. When the item closes the card,\n * it's a gray sheet flush under the body, full-bleed and owning the row's\n * bottom padding, rounding only into the card's bottom corner. Pass `divided`\n * when later card rows follow — the panel becomes an inset rounded chip and\n * the card's hairline divider stays in charge. Content is already a centered\n * flex row either way.\n */\nfunction ItemPanel({\n divided = false,\n className,\n ...props\n}: BasicPageItemPanelProps) {\n return (\n <div\n className={cn(\n divided ? BASIC_PAGE_ITEM_PANEL_DIVIDED : BASIC_PAGE_ITEM_PANEL,\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Standalone callout. Pair with `CalloutTitle` / `CalloutDescription` (and\n * optional actions) for a featured block — e.g. an invite form. Do not wrap\n * in `Card`; this is already the outer surface.\n *\n * Pass `icon` for a decorative glyph anchored to the header block (first\n * child) — typically a Tabler outline icon. The icon is aria-hidden; keep\n * meaning in the title/description.\n */\nfunction Callout({\n className,\n icon,\n children,\n ...props\n}: ComponentProps<\"div\"> & {\n ref?: Ref<HTMLDivElement>;\n /** Decorative icon, top-right of the header (first child). */\n icon?: ReactNode;\n}) {\n // Treat boolean false (and other empty values) as absent — `icon={cond &&\n // <Icon />}` is a common pattern and must not reserve header padding.\n if (icon == null || icon === false || icon === true) {\n return (\n <div className={cn(BASIC_PAGE_CALLOUT, className)} {...props}>\n {children}\n </div>\n );\n }\n\n const [header, ...rest] = Children.toArray(children);\n\n return (\n <div className={cn(BASIC_PAGE_CALLOUT, className)} {...props}>\n <div className=\"relative\">\n <div className=\"min-w-0 pr-16\">{header}</div>\n <div\n aria-hidden\n className=\"text-pho-description pointer-events-none absolute top-1/2 right-0 size-14 -translate-y-1/2 opacity-50 [&>svg]:size-full\"\n >\n {icon}\n </div>\n </div>\n {rest}\n </div>\n );\n}\n\n/** Callout heading — same type as `SectionTitle`. Hashable via slug `id`. */\nfunction CalloutTitle({\n id,\n className,\n children,\n ...props\n}: ComponentProps<\"h2\"> & { ref?: Ref<HTMLHeadingElement> }) {\n const headingId = resolveHeadingId(id, children);\n return (\n <h2\n id={headingId}\n className={cn(\n \"text-display-xs text-pho-primary max-w-full min-w-0 scroll-mt-12 truncate font-medium\",\n className,\n )}\n {...props}\n >\n {children}\n </h2>\n );\n}\n\n/** Supporting copy under a callout title. */\nfunction CalloutDescription({\n className,\n ...props\n}: ComponentProps<\"p\"> & { ref?: Ref<HTMLParagraphElement> }) {\n return (\n <p\n className={cn(\n \"text-display-xs text-pho-description font-normal\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport interface BasicPageRowProps extends Omit<\n ComponentProps<\"div\">,\n \"title\"\n> {\n /** Left-side field name — plain text, or compose with a trailing hint. */\n label: ReactNode;\n /** Optional helper under the label. */\n description?: ReactNode;\n /** Associates the label with a control id. When omitted, the label is not a `<label>`. */\n htmlFor?: string;\n /**\n * Stack the label above a full-width control instead of the default\n * label-left / control-right layout at `sm+`. Keeps the compact `gap-3`\n * rhythm — the default row's `justify-between` would otherwise stretch\n * label and control apart under `min-h-[4.25rem]`.\n */\n stacked?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * One row: label (+ optional description) left, control right.\n * Pass `htmlFor` when the row wraps a labelled input; omit it for display/\n * action rows (avatar, danger-zone delete). Pass `stacked` for full-width\n * controls that sit under the label.\n */\nfunction Row({\n label,\n description,\n htmlFor,\n stacked = false,\n className,\n children,\n ...props\n}: BasicPageRowProps) {\n return (\n <div\n className={cn(\n BASIC_PAGE_ROW,\n stacked && \"sm:flex-col sm:items-stretch sm:justify-start sm:gap-3\",\n className,\n )}\n {...props}\n >\n <div className=\"min-w-0\">\n {htmlFor ? (\n <label\n htmlFor={htmlFor}\n className=\"text-pho-primary block text-base font-normal\"\n >\n {label}\n </label>\n ) : (\n <p className=\"text-pho-primary text-base font-normal\">{label}</p>\n )}\n {description ? (\n <p className=\"text-pho-description text-xs\">{description}</p>\n ) : null}\n </div>\n <div\n className={cn(\n \"flex w-full min-w-0 items-center gap-2 sm:w-auto\",\n stacked && \"sm:w-full\",\n )}\n >\n {children}\n </div>\n </div>\n );\n}\n\n/** Read-only value on the right side of a row (email, etc.). */\nfunction Value({\n className,\n ...props\n}: ComponentProps<\"p\"> & { ref?: Ref<HTMLParagraphElement> }) {\n return (\n <p\n className={cn(\n \"text-pho-description max-w-full min-w-0 truncate text-base\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport interface BasicPageAlertProps extends Omit<\n ComponentProps<\"div\">,\n \"children\"\n> {\n /** The caught value — a problem body, an `Error` wrapping one, or unknown. */\n error?: unknown;\n /** Override the derived message. */\n children?: ReactNode;\n /**\n * Explicit presence override — defaults to whether there is anything to\n * show, so the reveal plays as the mutation's error comes and goes.\n */\n show?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * Server error under a row, still inside the card — the partial failure\n * (\"Couldn't update your name\"), rendered by `Error` from the problem body.\n * Keep it mounted and pass the mutation's error: the line reveals and\n * collapses on `Footer`'s height spring + fade. The card drops its divider\n * above the line so it reads as part of the row it belongs to. Matches card\n * horizontal padding — don't re-apply `px-5`.\n *\n * For a page that failed to load outright, swap the stack for an `ErrorView`\n * instead.\n */\nfunction Alert({\n error,\n show,\n className,\n children,\n ...props\n}: BasicPageAlertProps) {\n const reduceMotion = useReducedMotion();\n const hasContent = error != null || children != null;\n // Explicit `show` cannot force an empty animated slot — ErrorLine returns\n // null when there is nothing to render.\n const visible = (show ?? true) && hasContent;\n return (\n <AnimatePresence initial={false}>\n {visible ? (\n <motion.div\n data-basic-page-alert=\"\"\n className=\"overflow-hidden\"\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: \"auto\", opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={\n reduceMotion\n ? { duration: 0 }\n : { height: ENTRANCE_SPRING, opacity: ENTRANCE_FADE }\n }\n >\n <ErrorLine\n error={error}\n className={cn(\"px-5 pb-3\", className)}\n {...props}\n >\n {children}\n </ErrorLine>\n </motion.div>\n ) : null}\n </AnimatePresence>\n );\n}\n\nexport interface BasicPageFooterProps extends ComponentProps<\"div\"> {\n /**\n * Animated presence for dirty-state bars: the card glides open/closed on a\n * height spring while the content fades. Omit for a static, always-visible\n * footer (no animation). No reveal plays on first mount — only on flips.\n */\n show?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * Trailing bar inside a card — typically a save status + submit button that\n * appears after the form is dirty. Same horizontal/vertical padding as a row.\n * Pass `show` (instead of conditional rendering) to animate the bar in and\n * out following the onboarding card's motion language.\n */\nfunction Footer({ show, className, ...props }: BasicPageFooterProps) {\n const reduceMotion = useReducedMotion();\n const bar = (\n <div\n className={cn(\n \"flex items-center justify-between gap-6 px-5 py-4\",\n className,\n )}\n {...props}\n />\n );\n\n if (show === undefined) return bar;\n\n return (\n <AnimatePresence initial={false}>\n {show ? (\n <motion.div\n className=\"overflow-hidden\"\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: \"auto\", opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={\n reduceMotion\n ? { duration: 0 }\n : { height: ENTRANCE_SPRING, opacity: ENTRANCE_FADE }\n }\n >\n {bar}\n </motion.div>\n ) : null}\n </AnimatePresence>\n );\n}\n\n/**\n * Rise distance for the `Reveal` entrance — small travel; the content\n * surfaces, it doesn't slide in.\n */\nconst REVEAL_RISE_PX = 12;\n\n/**\n * DOM handlers whose React signatures clash with Motion's gesture props of\n * the same name on `motion.*` elements — excluded from `Reveal`'s public API\n * (same policy as Button).\n */\ntype RevealMotionConflicts =\n | \"onAnimationStart\"\n | \"onAnimationEnd\"\n | \"onAnimationIteration\"\n | \"onDrag\"\n | \"onDragStart\"\n | \"onDragEnd\"\n | \"onDragEnter\"\n | \"onDragExit\"\n | \"onDragLeave\"\n | \"onDragOver\"\n | \"onDrop\";\n\nexport interface BasicPageRevealProps extends Omit<\n ComponentProps<\"div\">,\n RevealMotionConflicts\n> {\n /**\n * Animated presence for a `Stack` block that comes and goes: keep the\n * block mounted and drive it with `show` — it glides open and closed\n * (height + fade) on the page spring, with the Stack's `gap-10`\n * compensated so nothing jumps when it fully collapses. Omit `show` for\n * the one-shot data-arrival entrance.\n */\n show?: boolean;\n /**\n * Which gap the presence variant compensates while collapsing —\n * `\"stack\"` for a Stack block (`gap-10`), `\"block\"` for an element\n * inside a block (`gap-3`). @default \"stack\"\n */\n gap?: \"stack\" | \"block\";\n /**\n * Set when this wraps multiple `Card` rows — the extra element Reveal\n * needs for `AnimatePresence` sits between them and the card's own\n * `divide-y`, so the hairlines between the wrapped rows disappear unless\n * this restores them. Leave off for content that isn't a run of rows.\n */\n dividers?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * Exactly one surrounding flex gap — the presence variant trades this much\n * margin against its height so neighbours glide to their final positions\n * instead of snapping by a gap when the block unmounts. `dividers` rows sit\n * in a `divide-y` card with no flex `gap` at all, so they get no\n * compensation — `gap` would otherwise overshoot into the next row's padding\n * as the block collapses.\n */\nconst GAP_COMPENSATION = {\n stack: \"-2.5rem\",\n block: \"-0.75rem\",\n none: \"0px\",\n} as const;\n\n/**\n * Data-arrival entrance for regions whose shape the skeleton couldn't\n * predict — a list of unknown length, a region that depends on the data.\n * Wrap that region (keeping `Title` and 1:1 chrome outside): once the shape\n * is known it rises 12px and fades in on the Card-shell / Command spring,\n * the same physics as the `Footer` / `Alert` reveals. When the skeleton\n * mirrors the loaded layout element for element, skip the reveal — values\n * fill into a shape that never moves. The page *entrance* is separate and\n * already built into `Stack`: whatever the page first shows (including the\n * skeleton) rides that. Static under reduced motion.\n *\n * With `show`, Reveal becomes an animated-presence block instead (the\n * `Footer` grammar): a whole section of the Stack that appears or leaves at\n * runtime glides open/closed while its neighbours follow.\n */\nfunction Reveal({\n show,\n gap = \"stack\",\n dividers,\n className,\n ...props\n}: BasicPageRevealProps) {\n const reduceMotion = useReducedMotion();\n // Card rows carry their own padding and a divide-y border, not a flex\n // gap — dividers always means zero gap to compensate for.\n const gapCompensation = GAP_COMPENSATION[dividers ? \"none\" : gap];\n\n if (show === undefined) {\n return (\n <motion.div\n initial={reduceMotion ? false : { opacity: 0, y: REVEAL_RISE_PX }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ y: ENTRANCE_SPRING, opacity: ENTRANCE_FADE }}\n className={cn(dividers && BASIC_PAGE_CARD_DIVIDERS, className)}\n {...props}\n />\n );\n }\n\n return (\n <AnimatePresence initial={false}>\n {show ? (\n <motion.div\n initial={{\n height: 0,\n opacity: 0,\n marginTop: gapCompensation,\n }}\n animate={{ height: \"auto\", opacity: 1, marginTop: 0 }}\n exit={{ height: 0, opacity: 0, marginTop: gapCompensation }}\n transition={\n reduceMotion\n ? { duration: 0 }\n : {\n height: ENTRANCE_SPRING,\n marginTop: ENTRANCE_SPRING,\n opacity: ENTRANCE_FADE,\n }\n }\n className={cn(\n \"overflow-hidden\",\n dividers && BASIC_PAGE_CARD_DIVIDERS,\n className,\n )}\n {...props}\n />\n ) : null}\n </AnimatePresence>\n );\n}\n\n/* ------------------------------- navigation ------------------------------ */\n\nexport interface BasicPageBackProps extends Omit<\n ButtonLinkProps,\n \"variant\" | \"size\" | \"shape\" | \"prefix\" | \"suffix\" | \"svgOnly\" | \"href\"\n> {\n /** Parent destination — rendered through the host's `LinkProvider`. */\n href: string;\n /** Label — name the parent page. @default \"Back\" */\n children?: ReactNode;\n /**\n * Shared-element key. Pair with the same `morphId` on the parent page's\n * `Title` and the word morphs between title and back link across the\n * navigation. Skipped under reduced motion.\n */\n morphId?: string;\n}\n\n/**\n * Back link for a subpage — a small ghost `ButtonLink`; place inside `Root`,\n * before `Title`. It floats in `Root`'s reserved top padding (vertically\n * centered in the 48px zone) instead of taking layout space, so `Title` sits\n * at exactly the same position whether or not a page has one.\n *\n * The offsets align the *label* glyph with the title glyph. Title text sits\n * 40px in (`px-5` root gutter + `px-5` title pad); inside a `sm` ghost button\n * the label sits 29.75px in (8px icon-side pad + 15.75px chevron, 1.125em at\n * the 14px `text-base`, + 4px gap + 2px label-span `px-0.5`) — so `left` is\n * the 10.25px difference. `top-4` centers the 32px button in the 64px\n * reserved zone. The chevron and the ghost hover pill hang in the padding —\n * the usual optical alignment for borderless controls.\n */\nfunction Back({\n href,\n className,\n morphId,\n children = \"Back\",\n ...props\n}: BasicPageBackProps) {\n const reduceMotion = useReducedMotion();\n const morphing = morphId != null && !reduceMotion;\n const flight = useMorphFlight(morphing ? morphId : undefined);\n return (\n <ButtonLink\n variant=\"ghost\"\n size=\"sm\"\n href={href}\n data-basic-page-back=\"\"\n prefix={\n morphing ? (\n // Mirrors the slot's direct-child svg sizing — the fade wrapper\n // sits between the slot and the icon.\n <motion.span\n initial={\n flight.fly\n ? { opacity: 0, x: MORPH_CHEVRON_RISE_X }\n : { opacity: 0 }\n }\n animate={flight.fly ? { opacity: 1, x: 0 } : { opacity: 1 }}\n transition={flight.fly ? MORPH_CHEVRON_ENTER : ENTRANCE_FADE}\n className=\"inline-flex [&>svg]:size-[1.125em] [&>svg]:shrink-0\"\n >\n <IconChevronLeft />\n </motion.span>\n ) : (\n <IconChevronLeft />\n )\n }\n className={cn(\"absolute top-4 left-[10.25px] min-w-max\", className)}\n {...props}\n >\n {morphing && morphId != null ? (\n <MorphLabel\n morphId={morphId}\n fromClassName=\"text-pho-primary\"\n fly={flight.fly}\n morphRef={flight.ref}\n fallback\n >\n {children}\n </MorphLabel>\n ) : (\n children\n )}\n </ButtonLink>\n );\n}\n\nexport interface BasicPageRowLinkProps extends Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n \"href\" | \"title\"\n> {\n /** Left-side field name — plain text, or compose with a trailing badge. */\n label: ReactNode;\n /** Optional helper under the label. */\n description?: ReactNode;\n /** Optional media left of the label (e.g. project avatar). */\n leading?: ReactNode;\n /** Subpage destination — rendered through the host's `LinkProvider`. */\n href: string;\n /** Optional trailing value before the chevron (compose with `Value`). */\n children?: ReactNode;\n ref?: Ref<HTMLAnchorElement>;\n}\n\n/**\n * A row that navigates — the whole row is one link into a subpage, with a\n * trailing chevron cue. Always horizontal: a column stack would park the\n * chevron under the label on narrow viewports. Hover lifts the row, and\n * first/last rows follow the card's corner radius.\n */\nfunction RowLink({\n label,\n description,\n leading,\n href,\n className,\n children,\n ...props\n}: BasicPageRowLinkProps) {\n const Link = useLinkComponent();\n return (\n <Link\n href={href}\n {...props}\n className={cn(\n // Same padding / min-height as `BASIC_PAGE_ROW`, but never `flex-col`\n // — navigation rows keep label left and chevron right at every width.\n \"flex min-h-[4.25rem] min-w-0 flex-row items-center justify-between gap-6 px-5 py-4\",\n \"group outline-pho-brand hover:bg-pho-primary-hover cursor-pointer transition-colors focus-visible:outline-2 focus-visible:-outline-offset-2\",\n // Hover wash follows the card's rounding (minus the 1px border).\n \"first:rounded-t-[calc(var(--radius-base)-1px)] last:rounded-b-[calc(var(--radius-base)-1px)]\",\n className,\n )}\n >\n <div\n className={cn(\n \"flex min-w-0 flex-1 items-center\",\n leading != null && \"gap-3\",\n )}\n >\n {leading}\n <div className=\"min-w-0\">\n <div className=\"flex min-w-0 items-center gap-1\">\n {typeof label === \"string\" || typeof label === \"number\" ? (\n <p className=\"text-pho-primary truncate text-base font-medium\">\n {label}\n </p>\n ) : (\n label\n )}\n </div>\n {description ? (\n <div className=\"text-pho-description truncate text-xs\">\n {description}\n </div>\n ) : null}\n </div>\n </div>\n <div className=\"flex min-w-0 items-center justify-end gap-2\">\n {children != null ? <div className=\"min-w-0\">{children}</div> : null}\n <IconChevronRight\n aria-hidden\n className=\"text-pho-secondary group-hover:text-pho-secondary-hover size-4 shrink-0 transition-colors\"\n />\n </div>\n </Link>\n );\n}\n\n/* -------------------------------- assembly ------------------------------- */\n\n/**\n * Basic page layout. One stack, one gap rhythm — only title scale differs:\n *\n * ```tsx\n * <BasicPage.Root>\n * <BasicPage.Title>Profile</BasicPage.Title>\n * <BasicPage.Stack>\n * <form>\n * <BasicPage.Card>\n * <BasicPage.Row label=\"Name\" htmlFor=\"first-name\">\n * <Input id=\"first-name\" size=\"sm\" />\n * </BasicPage.Row>\n * </BasicPage.Card>\n * </form>\n * <form>\n * <BasicPage.Header>\n * <BasicPage.SectionTitle>Agent profile</BasicPage.SectionTitle>\n * <BasicPage.Description>…</BasicPage.Description>\n * </BasicPage.Header>\n * <BasicPage.Card>…</BasicPage.Card>\n * </form>\n * <div>\n * <BasicPage.SectionTitle>Danger zone</BasicPage.SectionTitle>\n * <BasicPage.Card>\n * <BasicPage.Row label=\"Delete account\" description=\"…\">\n * <Button color=\"destructive\" size=\"sm\">Delete</Button>\n * </BasicPage.Row>\n * </BasicPage.Card>\n * </div>\n * <BasicPage.Callout icon={<IconMail stroke={1.25} />}>\n * <BasicPage.Header>\n * <BasicPage.CalloutTitle>Invitations</BasicPage.CalloutTitle>\n * <BasicPage.CalloutDescription>…</BasicPage.CalloutDescription>\n * </BasicPage.Header>\n * …invite form…\n * </BasicPage.Callout>\n * </BasicPage.Stack>\n * </BasicPage.Root>\n * ```\n *\n * Subpage — `Back` above the title, `RowLink` rows to drill in:\n *\n * ```tsx\n * <BasicPage.Root>\n * <BasicPage.Back href=\"/settings\">Settings</BasicPage.Back>\n * <BasicPage.Title>Billing</BasicPage.Title>\n * <BasicPage.Stack>\n * <div>\n * <BasicPage.Card>\n * <BasicPage.RowLink label=\"Invoices\" href=\"/settings/invoices\">\n * <BasicPage.Value>12 documents</BasicPage.Value>\n * </BasicPage.RowLink>\n * </BasicPage.Card>\n * </div>\n * </BasicPage.Stack>\n * </BasicPage.Root>\n * ```\n */\nexport const BasicPage = {\n Root,\n Back,\n Title,\n Stack,\n Header,\n SectionTitle,\n Description,\n SectionFooter,\n Card,\n Item,\n ItemPanel,\n Callout,\n CalloutTitle,\n CalloutDescription,\n Row,\n RowLink,\n Value,\n Alert,\n Footer,\n Reveal,\n};\n"],"x_google_ignoreList":[0],"mappings":";;;;;;;;;;;AASA,IAAM,IAAa,CAAC,CAAC,QAAQ;AAAA,EAAE,GAAK;AAAA,EAAiB,KAAO;AAAQ,CAAC,CAAC,GAChE,IAAmB,EAAqB,WAAW,iBAAiB,gBAAgB,CAAU,GC8B9F,IACJ,2DASI,IACJ,+EAGW,IAAkB,GAAG,CAAA,IAA2B,CAAA,IAMhD,IACX,wFAOW,IACX,iHAMW,IAAkB,iCAUlB,IACX,+FAUW,IACX,2EAWI,IAAkB;AAAA,EACtB,MAAM;AAAA,EACN,WAAW;AAAA,EACX,SAAS;AACX,GAGM,IAAgB;AAAA,EAAE,UAAU;AAAA,EAAM,MAAM;AAAU;AA2BxD,SAAS,EAAK,EACZ,WAAA,GACA,GAAG,EAAA,GACqD;AACxD,SACE,gBAAA,EAAC,OAAD;AAAA,IACE,WAAW,EACT,0IACA,CACF;AAAA,IACA,GAAI;AAAA,EACL,CAAA;AAEL;AAMA,SAAS,EAAe,GAAuB;AAC7C,SAAO,EACJ,UAAU,MAAM,EAChB,QAAQ,oBAAoB,EAAE,EAC9B,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,YAAY,EAAE;AAC3B;AAEA,SAAS,EAAsB,GAAyC;AACtE,MAAI,SAAO,KAAa,YAAY,OAAO,KAAa;AAIxD,WADa,EAAe,OAAO,CAAQ,CACpC,KAAQ;AACjB;AAGA,SAAS,EACP,GACA,GACoB;AACpB,MAAI,MAAO;AACX,WAAI,KACG,EAAsB,CAAQ;AACvC;AAQA,IAAM,IAAA,CAAiB,MAAe,oBAAoB,CAAA,IAGpD,IAAmB,EAAE,QAAQ,EAAgB,GAU7C,IAAuB,IACvB,IAAsB;AAAA,EAC1B,OAAO;AAAA,EACP,UAAU;AAAA,EACV,MAAM;AACR,GASM,IAAiB;AAAA,EAAE,UAAU;AAAA,EAAM,MAAM;AAAU,GASnD,IAAmB,oBAAI,IAAqB;AAQlD,SAAS,EAAe,GAA6B;AACnD,QAAM,CAAC,CAAA,IAAO,EAAA,MACN,KAAW,QAAQ,EAAiB,IAAI,CAAO,MAAM,EAC7D,GACM,IAAM,EAA+B,IAAI;AAC/C,SAAA,EAAA,MAAgB;AACd,QAAI,KAAW,QAAQ,OAAO,uBAAyB,IAAa;AACpE,UAAM,IAAK,EAAI;AACf,QAAI,CAAC,EAAI;AACT,UAAM,IAAW,IAAI,qBAAA,CAAsB,CAAC,CAAA,MAAW;AACrD,MAAI,KAAO,EAAiB,IAAI,GAAS,EAAM,cAAc;AAAA,IAC/D,CAAC;AACD,WAAA,EAAS,QAAQ,CAAE,GACnB,MAAa;AACX,MAAA,EAAS,WAAW;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,CAAO,CAAC,GACL;AAAA,IAAE,KAAA;AAAA,IAAK,KAAA;AAAA,EAAI;AACpB;AASA,SAAS,EAAW,EAClB,SAAA,GACA,eAAA,GACA,KAAA,GACA,UAAA,GACA,UAAA,IAAW,IACX,UAAA,EAAA,GAWC;AACD,QAAM,CAAC,GAAa,CAAA,IAAkB,EAAS,EAAK,GAC9C,IAAO,CAAC,KAAO;AACrB,SACE,gBAAA,EAAC,EAAO,MAAR;AAAA,IACE,KAAK;AAAA,IACL,UAAU,EAAc,CAAO;AAAA,IAC/B,SAAS,IAAO,EAAE,SAAS,EAAE,IAAI;AAAA,IACjC,SAAS,IAAO,EAAE,SAAS,EAAE,IAAI;AAAA,IACjC,YACE,IACI,IACA;AAAA,MAAE,QAAQ,EAAE,UAAU,EAAE;AAAA,MAAG,SAAS;AAAA,IAAc;AAAA,IAExD,wBAAA,MAA8B;AAC5B,MAAI,KAAK,EAAe,EAAI;AAAA,IAC9B;AAAA,IACA,2BAAA,MAAiC,EAAe,EAAK;AAAA,IACrD,WAAU;AAAA,cAdZ,CAgBG,GACA,KACC,gBAAA,EAAC,EAAO,MAAR;AAAA,MACE,eAAA;AAAA,MACA,SAAS,EAAE,SAAS,EAAE;AAAA,MACtB,SAAS,EAAE,SAAS,EAAE;AAAA,MACtB,YAAY;AAAA,MACZ,WAAW,EAAG,oBAAoB,CAAa;AAAA,MAE9C,UAAA;AAAA,IACU,CAAA,CAEJ;AAAA;AAEjB;AA2BA,SAAS,EAAM,EACb,IAAA,GACA,SAAA,GACA,OAAA,GACA,WAAA,GACA,UAAA,GACA,GAAG,EAAA,GACmB;AACtB,QAAM,IAAY,EAAiB,GAAI,CAAQ,GACzC,IAAe,EAAiB,GAChC,IAAS,EAAe,CAAO;AACrC,SACE,gBAAA,EAAC,MAAD;AAAA,IACE,IAAI;AAAA,IACJ,WAAW,EACT,gGACA,CACF;AAAA,IACA,GAAI;AAAA,cAEH,KAAW,QAAQ,CAAC,IACnB,gBAAA,EAAC,GAAD;AAAA,MACW,SAAA;AAAA,MACT,eAAc;AAAA,MACd,KAAK,EAAO;AAAA,MACZ,UAAU,EAAO;AAAA,MAEhB,UAAA;AAAA,IACS,CAAA,IACV,KAAS,CAAC,IACZ,gBAAA,EAAC,EAAO,MAAR;AAAA,MACE,SAAS;AAAA,QAAE,SAAS;AAAA,QAAG,GAAG;AAAA,MAAe;AAAA,MACzC,SAAS;AAAA,QAAE,SAAS;AAAA,QAAG,GAAG;AAAA,MAAE;AAAA,MAC5B,YAAY;AAAA,QAAE,GAAG;AAAA,QAAiB,SAAS;AAAA,MAAc;AAAA,MACzD,WAAU;AAAA,MAET,UAAA;AAAA,IACU,CAAA,IAEb;AAAA,EAEA,CAAA;AAER;AA6BA,SAAS,EAAM,EAAE,WAAA,GAAW,GAAG,EAAA,GAA8B;AAC3D,QAAM,IAAe,EAAiB;AACtC,SACE,gBAAA,EAAC,EAAO,KAAR;AAAA,IACE,SAAS,IAAe,KAAQ;AAAA,MAAE,SAAS;AAAA,MAAG,GAAG;AAAA,IAAe;AAAA,IAChE,SAAS;AAAA,MAAE,SAAS;AAAA,MAAG,GAAG;AAAA,IAAE;AAAA,IAC5B,YAAY;AAAA,MAAE,GAAG;AAAA,MAAiB,SAAS;AAAA,IAAc;AAAA,IACzD,WAAW,EACT,qCACA,uCACA,CACF;AAAA,IACA,GAAI;AAAA,EACL,CAAA;AAEL;AAoBA,SAAS,EAAO,EAAE,OAAA,GAAO,WAAA,GAAW,GAAG,EAAA,GAA+B;AACpE,QAAM,IAAe,EAAiB;AACtC,SAAI,KAAS,CAAC,IAEV,gBAAA,EAAC,EAAO,KAAR;AAAA,IACE,SAAS;AAAA,MAAE,SAAS;AAAA,MAAG,GAAG;AAAA,IAAe;AAAA,IACzC,SAAS;AAAA,MAAE,SAAS;AAAA,MAAG,GAAG;AAAA,IAAE;AAAA,IAC5B,YAAY;AAAA,MAAE,GAAG;AAAA,MAAiB,SAAS;AAAA,IAAc;AAAA,IACzD,WAAW,EAAG,yBAAyB,CAAS;AAAA,IAChD,GAAI;AAAA,EACL,CAAA,IAGE,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,EAAG,yBAAyB,CAAS;AAAA,IAAG,GAAI;AAAA,EAAQ,CAAA;AAC7E;AAMA,SAAS,EAAa,EACpB,IAAA,GACA,WAAA,GACA,UAAA,GACA,GAAG,EAAA,GACwD;AAE3D,SACE,gBAAA,EAAC,MAAD;AAAA,IACE,IAHc,EAAiB,GAAI,CAG/B;AAAA,IACJ,WAAW,EACT,8FACA,CACF;AAAA,IACA,GAAI;AAAA,IAEH,UAAA;AAAA,EACC,CAAA;AAER;AAMA,SAAS,GAAY,EACnB,WAAA,GACA,GAAG,EAAA,GACyD;AAC5D,SACE,gBAAA,EAAC,KAAD;AAAA,IACE,WAAW,EACT,yDACA,CACF;AAAA,IACA,GAAI;AAAA,EACL,CAAA;AAEL;AAOA,SAAS,GAAc,EACrB,WAAA,GACA,GAAG,EAAA,GACyD;AAC5D,SACE,gBAAA,EAAC,KAAD;AAAA,IACE,WAAW,EAAG,iDAAiD,CAAS;AAAA,IACxE,GAAI;AAAA,EACL,CAAA;AAEL;AAcA,SAAS,GAAK,EACZ,eAAA,GACA,WAAA,GACA,UAAA,GACA,GAAG,EAAA,GACkB;AACrB,SAAI,IAEA,gBAAA,EAAC,OAAD;AAAA,IACE,WAAW,EACT,GACA,2BACA,CACF;AAAA,IACA,GAAI;AAAA,cAEJ,gBAAA,EAAC,GAAD;AAAA,MACE,YAAY;AAAA,MACZ,WAAW;AAAA,MAEV,UAAA;AAAA,IACa,CAAA;AAAA,EACb,CAAA,IAIP,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,EAAG,GAAiB,CAAS;AAAA,IAAG,GAAI;AAAA,IACjD,UAAA;AAAA,EACE,CAAA;AAET;AAiBA,SAAS,GAAK,EACZ,WAAA,GACA,GAAG,EAAA,GACqD;AACxD,SAAO,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,EAAG,GAAiB,CAAS;AAAA,IAAG,GAAI;AAAA,EAAQ,CAAA;AACrE;AAqBA,SAAS,GAAU,EACjB,SAAA,IAAU,IACV,WAAA,GACA,GAAG,EAAA,GACuB;AAC1B,SACE,gBAAA,EAAC,OAAD;AAAA,IACE,WAAW,EACT,IAAU,IAAgC,GAC1C,CACF;AAAA,IACA,GAAI;AAAA,EACL,CAAA;AAEL;AAWA,SAAS,GAAQ,EACf,WAAA,GACA,MAAA,GACA,UAAA,GACA,GAAG,EAAA,GAKF;AAGD,MAAI,KAAQ,QAAQ,MAAS,MAAS,MAAS,GAC7C,QACE,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,EAAG,GAAoB,CAAS;AAAA,IAAG,GAAI;AAAA,IACpD,UAAA;AAAA,EACE,CAAA;AAIT,QAAM,CAAC,GAAQ,GAAG,CAAA,IAAQ,EAAS,QAAQ,CAAQ;AAEnD,SACE,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,EAAG,GAAoB,CAAS;AAAA,IAAG,GAAI;AAAA,cAAvD,CACE,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAU;AAAA,gBAAf,CACE,gBAAA,EAAC,OAAD;AAAA,QAAK,WAAU;AAAA,kBAAiB;AAAA,MAAY,CAAA,GAC5C,gBAAA,EAAC,OAAD;AAAA,QACE,eAAA;AAAA,QACA,WAAU;AAAA,kBAET;AAAA,MACE,CAAA,CACF;AAAA,QACJ,CACE;AAAA;AAET;AAGA,SAAS,GAAa,EACpB,IAAA,GACA,WAAA,GACA,UAAA,GACA,GAAG,EAAA,GACwD;AAE3D,SACE,gBAAA,EAAC,MAAD;AAAA,IACE,IAHc,EAAiB,GAAI,CAG/B;AAAA,IACJ,WAAW,EACT,yFACA,CACF;AAAA,IACA,GAAI;AAAA,IAEH,UAAA;AAAA,EACC,CAAA;AAER;AAGA,SAAS,GAAmB,EAC1B,WAAA,GACA,GAAG,EAAA,GACyD;AAC5D,SACE,gBAAA,EAAC,KAAD;AAAA,IACE,WAAW,EACT,oDACA,CACF;AAAA,IACA,GAAI;AAAA,EACL,CAAA;AAEL;AA4BA,SAAS,GAAI,EACX,OAAA,GACA,aAAA,GACA,SAAA,GACA,SAAA,IAAU,IACV,WAAA,GACA,UAAA,GACA,GAAG,EAAA,GACiB;AACpB,SACE,gBAAA,EAAC,OAAD;AAAA,IACE,WAAW,EACT,GACA,KAAW,0DACX,CACF;AAAA,IACA,GAAI;AAAA,cANN,CAQE,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAU;AAAA,gBAAf,CACG,IACC,gBAAA,EAAC,SAAD;AAAA,QACW,SAAA;AAAA,QACT,WAAU;AAAA,kBAET;AAAA,MACI,CAAA,IAEP,gBAAA,EAAC,KAAD;AAAA,QAAG,WAAU;AAAA,kBAA0C;AAAA,MAAS,CAAA,GAEjE,IACC,gBAAA,EAAC,KAAD;AAAA,QAAG,WAAU;AAAA,kBAAgC;AAAA,MAAe,CAAA,IAC1D,IACD;AAAA,QACL,gBAAA,EAAC,OAAD;AAAA,MACE,WAAW,EACT,oDACA,KAAW,WACb;AAAA,MAEC,UAAA;AAAA,IACE,CAAA,CACF;AAAA;AAET;AAGA,SAAS,GAAM,EACb,WAAA,GACA,GAAG,EAAA,GACyD;AAC5D,SACE,gBAAA,EAAC,KAAD;AAAA,IACE,WAAW,EACT,8DACA,CACF;AAAA,IACA,GAAI;AAAA,EACL,CAAA;AAEL;AA6BA,SAAS,GAAM,EACb,OAAA,GACA,MAAA,GACA,WAAA,GACA,UAAA,GACA,GAAG,EAAA,GACmB;AACtB,QAAM,IAAe,EAAiB;AAKtC,SACE,gBAAA,EAAC,GAAD;AAAA,IAAiB,SAAS;AAAA,eAFX,KAAQ,QAHN,KAAS,QAAQ,KAAY,QAO1C,gBAAA,EAAC,EAAO,KAAR;AAAA,MACE,yBAAsB;AAAA,MACtB,WAAU;AAAA,MACV,SAAS;AAAA,QAAE,QAAQ;AAAA,QAAG,SAAS;AAAA,MAAE;AAAA,MACjC,SAAS;AAAA,QAAE,QAAQ;AAAA,QAAQ,SAAS;AAAA,MAAE;AAAA,MACtC,MAAM;AAAA,QAAE,QAAQ;AAAA,QAAG,SAAS;AAAA,MAAE;AAAA,MAC9B,YACE,IACI,EAAE,UAAU,EAAE,IACd;AAAA,QAAE,QAAQ;AAAA,QAAiB,SAAS;AAAA,MAAc;AAAA,gBAGxD,gBAAA,EAAC,GAAD;AAAA,QACS,OAAA;AAAA,QACP,WAAW,EAAG,aAAa,CAAS;AAAA,QACpC,GAAI;AAAA,QAEH,UAAA;AAAA,MACQ,CAAA;AAAA,IACD,CAAA,IACV;AAAA,EACW,CAAA;AAErB;AAkBA,SAAS,GAAO,EAAE,MAAA,GAAM,WAAA,GAAW,GAAG,EAAA,GAA+B;AACnE,QAAM,IAAe,EAAiB,GAChC,IACJ,gBAAA,EAAC,OAAD;AAAA,IACE,WAAW,EACT,qDACA,CACF;AAAA,IACA,GAAI;AAAA,EACL,CAAA;AAGH,SAAI,MAAS,SAAkB,IAG7B,gBAAA,EAAC,GAAD;AAAA,IAAiB,SAAS;AAAA,cACvB,IACC,gBAAA,EAAC,EAAO,KAAR;AAAA,MACE,WAAU;AAAA,MACV,SAAS;AAAA,QAAE,QAAQ;AAAA,QAAG,SAAS;AAAA,MAAE;AAAA,MACjC,SAAS;AAAA,QAAE,QAAQ;AAAA,QAAQ,SAAS;AAAA,MAAE;AAAA,MACtC,MAAM;AAAA,QAAE,QAAQ;AAAA,QAAG,SAAS;AAAA,MAAE;AAAA,MAC9B,YACE,IACI,EAAE,UAAU,EAAE,IACd;AAAA,QAAE,QAAQ;AAAA,QAAiB,SAAS;AAAA,MAAc;AAAA,gBAGvD;AAAA,IACS,CAAA,IACV;AAAA,EACW,CAAA;AAErB;AAMA,IAAM,IAAiB,IAwDjB,KAAmB;AAAA,EACvB,OAAO;AAAA,EACP,OAAO;AAAA,EACP,MAAM;AACR;AAiBA,SAAS,GAAO,EACd,MAAA,GACA,KAAA,IAAM,SACN,UAAA,GACA,WAAA,GACA,GAAG,EAAA,GACoB;AACvB,QAAM,IAAe,EAAiB,GAGhC,IAAkB,GAAiB,IAAW,SAAS,CAAA;AAE7D,SAAI,MAAS,SAET,gBAAA,EAAC,EAAO,KAAR;AAAA,IACE,SAAS,IAAe,KAAQ;AAAA,MAAE,SAAS;AAAA,MAAG,GAAG;AAAA,IAAe;AAAA,IAChE,SAAS;AAAA,MAAE,SAAS;AAAA,MAAG,GAAG;AAAA,IAAE;AAAA,IAC5B,YAAY;AAAA,MAAE,GAAG;AAAA,MAAiB,SAAS;AAAA,IAAc;AAAA,IACzD,WAAW,EAAG,KAAY,GAA0B,CAAS;AAAA,IAC7D,GAAI;AAAA,EACL,CAAA,IAKH,gBAAA,EAAC,GAAD;AAAA,IAAiB,SAAS;AAAA,cACvB,IACC,gBAAA,EAAC,EAAO,KAAR;AAAA,MACE,SAAS;AAAA,QACP,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,MACA,SAAS;AAAA,QAAE,QAAQ;AAAA,QAAQ,SAAS;AAAA,QAAG,WAAW;AAAA,MAAE;AAAA,MACpD,MAAM;AAAA,QAAE,QAAQ;AAAA,QAAG,SAAS;AAAA,QAAG,WAAW;AAAA,MAAgB;AAAA,MAC1D,YACE,IACI,EAAE,UAAU,EAAE,IACd;AAAA,QACE,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,SAAS;AAAA,MACX;AAAA,MAEN,WAAW,EACT,mBACA,KAAY,GACZ,CACF;AAAA,MACA,GAAI;AAAA,IACL,CAAA,IACC;AAAA,EACW,CAAA;AAErB;AAkCA,SAAS,GAAK,EACZ,MAAA,GACA,WAAA,GACA,SAAA,GACA,UAAA,IAAW,QACX,GAAG,EAAA,GACkB;AACrB,QAAM,IAAe,EAAiB,GAChC,IAAW,KAAW,QAAQ,CAAC,GAC/B,IAAS,EAAe,IAAW,IAAU,MAAS;AAC5D,SACE,gBAAA,EAAC,GAAD;AAAA,IACE,SAAQ;AAAA,IACR,MAAK;AAAA,IACC,MAAA;AAAA,IACN,wBAAqB;AAAA,IACrB,QACE,IAGE,gBAAA,EAAC,EAAO,MAAR;AAAA,MACE,SACE,EAAO,MACH;AAAA,QAAE,SAAS;AAAA,QAAG,GAAG;AAAA,MAAqB,IACtC,EAAE,SAAS,EAAE;AAAA,MAEnB,SAAS,EAAO,MAAM;AAAA,QAAE,SAAS;AAAA,QAAG,GAAG;AAAA,MAAE,IAAI,EAAE,SAAS,EAAE;AAAA,MAC1D,YAAY,EAAO,MAAM,IAAsB;AAAA,MAC/C,WAAU;AAAA,gBAEV,gBAAA,EAAC,GAAD,CAAkB,CAAA;AAAA,IACP,CAAA,IAEb,gBAAA,EAAC,GAAD,CAAkB,CAAA;AAAA,IAGtB,WAAW,EAAG,2CAA2C,CAAS;AAAA,IAClE,GAAI;AAAA,cAEH,KAAY,KAAW,OACtB,gBAAA,EAAC,GAAD;AAAA,MACW,SAAA;AAAA,MACT,eAAc;AAAA,MACd,KAAK,EAAO;AAAA,MACZ,UAAU,EAAO;AAAA,MACjB,UAAA;AAAA,MAEC,UAAA;AAAA,IACS,CAAA,IAEZ;AAAA,EAEQ,CAAA;AAEhB;AAyBA,SAAS,GAAQ,EACf,OAAA,GACA,aAAA,GACA,SAAA,GACA,MAAA,GACA,WAAA,GACA,UAAA,GACA,GAAG,EAAA,GACqB;AAExB,SACE,gBAAA,EAFW,EAEV,GAAD;AAAA,IACQ,MAAA;AAAA,IACN,GAAI;AAAA,IACJ,WAAW,EAGT,sFACA,+IAEA,gGACA,CACF;AAAA,cAXF,CAaE,gBAAA,EAAC,OAAD;AAAA,MACE,WAAW,EACT,oCACA,KAAW,QAAQ,OACrB;AAAA,gBAJF,CAMG,GACD,gBAAA,EAAC,OAAD;AAAA,QAAK,WAAU;AAAA,kBAAf,CACE,gBAAA,EAAC,OAAD;AAAA,UAAK,WAAU;AAAA,oBACZ,OAAO,KAAU,YAAY,OAAO,KAAU,WAC7C,gBAAA,EAAC,KAAD;AAAA,YAAG,WAAU;AAAA,sBACV;AAAA,UACA,CAAA,IAEH;AAAA,QAEC,CAAA,GACJ,IACC,gBAAA,EAAC,OAAD;AAAA,UAAK,WAAU;AAAA,oBACZ;AAAA,QACE,CAAA,IACH,IACD;AAAA,QACF;AAAA,QACL,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAU;AAAA,gBAAf,CACG,KAAY,OAAO,gBAAA,EAAC,OAAD;AAAA,QAAK,WAAU;AAAA,QAAW,UAAA;AAAA,MAAc,CAAA,IAAI,MAChE,gBAAA,EAAC,GAAD;AAAA,QACE,eAAA;AAAA,QACA,WAAU;AAAA,MACX,CAAA,CACE;AAAA,MACD;AAAA;AAEV;AA8DA,IAAa,KAAY;AAAA,EACvB,MAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,cAAA;AAAA,EACA,aAAA;AAAA,EACA,eAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,WAAA;AAAA,EACA,SAAA;AAAA,EACA,cAAA;AAAA,EACA,oBAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AACF"}
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { n as I, r as n, t as A } from "./chunks/use-press-pulse-8iorQPsh.js";
6
6
  import "./utils.js";
7
7
  import { a as e, c as R, d as p, i as B, l as C, n as O, o as P, r as f, s as u, t as D, u as N } from "./chunks/button-X5wsWvRa.js";
8
8
  import { a as c, c as l, i as V, l as U, n as G, o as d, r as M, s as b, t as g } from "./chunks/error-DR6G2LmG.js";
9
- import { a as F, i as W, n as h, o as Z, r as v, s as w, t as x } from "./chunks/basic-page-Dfln58iw.js";
9
+ import { a as F, i as W, n as h, o as Z, r as v, s as w, t as x } from "./chunks/basic-page-x3aFcSVs.js";
10
10
  import { a as z, c as Y, i as j, n as q, o as y, r as J, s as K, t as Q } from "./chunks/sidebar-DDJC1MeD.js";
11
11
  import { t as $ } from "./chunks/input-D3XQcC4J.js";
12
12
  import { t as sa } from "./chunks/close-button-xadxp0j8.js";
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { a as _, i as E, n as I, o as a, r as s, s as P, t as C } from "../chunks/basic-page-Dfln58iw.js";
2
+ import { a as _, i as E, n as I, o as a, r as s, s as P, t as C } from "../chunks/basic-page-x3aFcSVs.js";
3
3
  export {
4
4
  C as BASIC_PAGE_CALLOUT,
5
5
  I as BASIC_PAGE_CARD,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@photon-ai/pho-ui",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "description": "Pho Design System — Photon's React component library, built on Base UI",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -1 +0,0 @@
1
- {"version":3,"file":"basic-page-Dfln58iw.js","names":[],"sources":["../../../../node_modules/.pnpm/@tabler+icons-react@3.44.0_react@19.2.7/node_modules/@tabler/icons-react/dist/esm/icons/IconChevronRight.mjs","../../src/sections/basic-page/basic-page.tsx"],"sourcesContent":["/**\n * @license @tabler/icons-react v3.44.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createReactComponent from '../createReactComponent.mjs';\n\nconst __iconNode = [[\"path\", { \"d\": \"M9 6l6 6l-6 6\", \"key\": \"svg-0\" }]];\nconst IconChevronRight = createReactComponent(\"outline\", \"chevron-right\", \"ChevronRight\", __iconNode);\n\nexport { __iconNode, IconChevronRight as default };\n//# sourceMappingURL=IconChevronRight.mjs.map\n","import {\n Children,\n useEffect,\n useRef,\n useState,\n type AnchorHTMLAttributes,\n type ComponentProps,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport { IconChevronLeft, IconChevronRight } from \"@tabler/icons-react\";\nimport { ButtonLink, type ButtonLinkProps } from \"../../components/button\";\nimport { Error as ErrorLine } from \"../../components/error\";\nimport { AnimatedHeight } from \"../../utils/animated-height\";\nimport { cn } from \"../../utils/cn\";\nimport { useLinkComponent } from \"../../utils/link-provider\";\n\n/**\n * BasicPage — Pho's standard content page: a page title, section titles, and\n * bordered cards of label/control rows. Settings, billing, members — any\n * single-column management surface.\n *\n * Spacing: wrap the page in `Root` (a 42rem column with `px-5` gutters,\n * vertical padding). `Stack` separates blocks (`gap-10`). Inside a block,\n * children share `gap-3`. Wrap a section title + description in `Header`\n * (no gap — title and description sit flush) so that pair stays tight —\n * don't put them as loose siblings.\n * Parts already carry `px-5`.\n *\n * Navigation: pages may drill into subpages. `RowLink` is a whole-row link\n * (trailing chevron) and `Back` returns to the parent — both render through\n * the host's `LinkProvider`; the URL itself stays the router's job. `Back`\n * floats in `Root`'s top padding, so `Title` never moves between pages that\n * have a back link and pages that don't.\n */\n\n/* ------------------------------- class map ------------------------------- */\n\n/** Card surface — border, corner, fill; no divider rules. */\nconst BASIC_PAGE_CARD_SURFACE =\n \"rounded-base border border-pho-secondary bg-pho-primary\";\n\n/**\n * Card divider rules — hairlines between direct children. A row followed by\n * an `Alert` drops its divider (the `:has()` rule) so the error line reads\n * as part of the row it belongs to — the alert's own bottom divider takes\n * over toward whatever follows. Kept separate from the surface so\n * `animateHeight` can move the dividers onto the measured content wrapper.\n */\nconst BASIC_PAGE_CARD_DIVIDERS =\n \"divide-y divide-pho-secondary [&>:has(+[data-basic-page-alert])]:border-b-0\";\n\n/** Bordered card that stacks rows with hairline dividers. */\nexport const BASIC_PAGE_CARD = `${BASIC_PAGE_CARD_SURFACE} ${BASIC_PAGE_CARD_DIVIDERS}`;\n\n/**\n * Standalone callout surface — featured block (invite form, notice, etc.).\n * Don't wrap in `Card`; this is the outer chrome.\n */\nexport const BASIC_PAGE_CALLOUT =\n \"flex min-w-0 flex-col gap-3 rounded-base border border-pho-secondary bg-pho-page p-5\";\n\n/**\n * One row — label (+ optional description) left, control right.\n * `min-h-[4.25rem]` (68px) keeps avatar/control rows from collapsing shorter\n * than a comfortable touch target.\n */\nexport const BASIC_PAGE_ROW =\n \"flex min-h-[4.25rem] min-w-0 flex-col gap-3 px-5 py-4 sm:flex-row sm:items-center sm:justify-between sm:gap-6\";\n\n/**\n * One card row that can host subviews. Same padding rhythm as a plain row —\n * an optional trailing `ItemPanel` breaks out of it on its own.\n */\nexport const BASIC_PAGE_ITEM = \"flex flex-col gap-3 px-5 py-4\";\n\n/**\n * Secondary strip closing an `Item` that is last in its card. Negative\n * margins escape the item's `px-5 pb-4` so the gray sheet runs edge-to-edge\n * and owns the row's bottom padding. The body above stays square and the\n * sheet's top is flush against it; only the bottom rounds, nesting into the\n * card's 12px corner (11px inside the 1px border). Content lands back on the\n * item's left gutter.\n */\nexport const BASIC_PAGE_ITEM_PANEL =\n \"-mx-5 -mb-4 flex items-center rounded-b-[calc(0.75rem-1px)] bg-pho-secondary py-1 pr-3 pl-5\";\n\n/**\n * Mid-list variant — the full-bleed sheet only reads well against the card's\n * bottom corner, so when later rows follow, the panel becomes an inset chip\n * instead: fully rounded at the small-control radius, overhanging the text\n * gutter by 8px per side (content stays aligned with the body above), and\n * leaving the row's own bottom padding and the card's hairline divider alone.\n * `-mt-1.5` collapses the item's `gap-3` (12px) to an effective `gap-1.5` (6px).\n */\nexport const BASIC_PAGE_ITEM_PANEL_DIVIDED =\n \"-mx-2 -mt-1.5 flex items-center rounded-sm bg-pho-secondary px-2 py-0.5\";\n\n/* --------------------------------- motion -------------------------------- */\n\n/**\n * One spring for every BasicPage motion — the `Stack` entrance, `Title` /\n * `Header` enter, `Reveal`, the Title ↔ Back morph, and the `Alert` /\n * `Footer` height reveals. Measured off a 60fps iOS push: ~330ms with a\n * long, gentle glide, everything co-landing. Essentially critically damped\n * (an overshooting edge would show clipped content).\n */\nconst ENTRANCE_SPRING = {\n type: \"spring\",\n stiffness: 400,\n damping: 40,\n} as const;\n\n/** Fade paired with the spring — spans most of the glide. */\nconst ENTRANCE_FADE = { duration: 0.25, ease: \"easeOut\" } as const;\n\n/* --------------------------------- parts --------------------------------- */\n\n/**\n * Page chrome — centered column at the standard content width. Hosts\n * `Title` + `Stack` (and any route-level siblings). Prefer this over\n * ad-hoc `max-w-*` wrappers in the app shell.\n *\n * `44.5rem` = the 42rem (`2xl`) content column plus the two `px-5` gutters,\n * so wide viewports render exactly as before while narrow ones keep a 20px\n * breathing edge instead of running content into the viewport.\n *\n * `relative` anchors `Back`, which floats in the top padding. The top zone\n * is conditional (`:has()`): pages carrying a `Back` reserve 64px for it;\n * pages without one keep the tighter 48px so the title doesn't sit low.\n *\n * The column is also a `min-h-full` flex stack: when the host gives it a\n * height context (an app shell's scroll pane), a full-page state can claim\n * the leftover viewport with `flex-1` — `ErrorView className=\"flex-1\"`\n * centers itself vertically below the title. Hosts without a height context\n * see a normal column; regular pages are unaffected.\n *\n * Root itself never animates — the page entrance lives on `Stack`, so\n * `Title` and `Back` (the page chrome) stay put while the body below rises\n * in.\n */\nfunction Root({\n className,\n ...props\n}: ComponentProps<\"div\"> & { ref?: Ref<HTMLDivElement> }) {\n return (\n <div\n className={cn(\n \"relative mx-auto flex min-h-full w-full max-w-[44.5rem] min-w-0 flex-col px-5 pt-12 pb-12 *:min-w-0 has-[[data-basic-page-back]]:pt-16\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Slug for hash targets — \"Danger zone\" → `danger-zone`. Empty / non-string\n * children yield no id; pass an explicit `id` to override or `id=\"\"` to opt out.\n */\nfunction slugifyHeading(value: string): string {\n return value\n .normalize(\"NFKD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\nfunction headingIdFromChildren(children: ReactNode): string | undefined {\n if (typeof children !== \"string\" && typeof children !== \"number\") {\n return undefined;\n }\n const slug = slugifyHeading(String(children));\n return slug || undefined;\n}\n\n/** Resolve `id`: explicit wins; `\"\"` opts out; else slug from plain-text children. */\nfunction resolveHeadingId(\n id: string | undefined,\n children: ReactNode,\n): string | undefined {\n if (id === \"\") return undefined;\n if (id != null) return id;\n return headingIdFromChildren(children);\n}\n\n/**\n * Namespaced Motion `layoutId` for the Title ↔ Back shared-element morph —\n * give a parent page's `Title` and its subpage's `Back` the same `morphId`\n * and the word itself travels between the two: the large title shrinks into\n * the back link on drill-in, and grows back on return.\n */\nconst morphLayoutId = (id: string) => `basic-page-morph-${id}`;\n\n/** The morph rides the page-tier entrance spring — one glide, everywhere. */\nconst MORPH_TRANSITION = { layout: ENTRANCE_SPRING } as const;\n\n/**\n * Chevron entrance for a morphing `Back`, measured off a 60fps iOS push\n * (sub-pixel tracking of the recording): the arrow emerges from under the\n * left edge of the arriving word at ~62% of the flight — sliding left by\n * ~2/3 of its own width with a strong ease-out while fading in over ~120ms\n * — and lands together with the word, which is still gliding its last few\n * pixels the whole time. Nothing is sequential.\n */\nconst MORPH_CHEVRON_RISE_X = 10;\nconst MORPH_CHEVRON_ENTER = {\n delay: 0.2,\n duration: 0.12,\n ease: \"easeOut\",\n} as const;\n\n/**\n * Ink crossfade for the morphing word — iOS redraws the word in the\n * destination's ink and fades the origin-ink rendition out over the first\n * half of the flight, so the word takes off in the color it had and lands\n * in the color it gets. `MorphLabel` mounts the ghost only while a layout\n * animation is actually running, so static renders never see it.\n */\nconst MORPH_INK_FADE = { duration: 0.18, ease: \"easeOut\" } as const;\n\n/**\n * A shared element can only fly between two points the user has seen. Each\n * morph word tracks whether it is on screen (keyed by `morphId`); when the\n * other end mounts, it flies only if the word it continues was visible.\n * A title scrolled out of view yields a plain fade at the destination\n * instead of a dive in from off-screen.\n */\nconst morphWordVisible = new Map<string, boolean>();\n\n/**\n * Mount-locked flight decision + live visibility tracking for a morph word.\n * `fly` is read from the registry once at mount (was the other end on\n * screen?); the ref then feeds this word's own visibility back for the next\n * navigation. No-ops without `IntersectionObserver` (jsdom, SSR).\n */\nfunction useMorphFlight(morphId: string | undefined) {\n const [fly] = useState(\n () => morphId != null && morphWordVisible.get(morphId) === true,\n );\n const ref = useRef<HTMLSpanElement | null>(null);\n useEffect(() => {\n if (morphId == null || typeof IntersectionObserver === \"undefined\") return;\n const el = ref.current;\n if (!el) return;\n const observer = new IntersectionObserver(([entry]) => {\n if (entry) morphWordVisible.set(morphId, entry.isIntersecting);\n });\n observer.observe(el);\n return () => {\n observer.disconnect();\n };\n }, [morphId]);\n return { fly, ref };\n}\n\n/**\n * The shared-element word of a Title ↔ Back morph. While the box flies, an\n * origin-ink copy of the word sits on top and fades out (the iOS snapshot\n * crossfade); the copy only exists during a real layout animation. When the\n * flight is skipped (`fly` false — the other end wasn't on screen), the\n * layout snap is instant and, with `fallback`, the word fades in instead.\n */\nfunction MorphLabel({\n morphId,\n fromClassName,\n fly,\n morphRef,\n fallback = false,\n children,\n}: {\n morphId: string;\n /** Ink the word arrives FROM (the other end's text color). */\n fromClassName: string;\n /** Fly the layout box — the other end was on screen at navigation. */\n fly: boolean;\n morphRef: React.Ref<HTMLSpanElement>;\n /** Fade the word in when not flying (instead of appearing instantly). */\n fallback?: boolean;\n children: ReactNode;\n}) {\n const [crossfading, setCrossfading] = useState(false);\n const fade = !fly && fallback;\n return (\n <motion.span\n ref={morphRef}\n layoutId={morphLayoutId(morphId)}\n initial={fade ? { opacity: 0 } : undefined}\n animate={fade ? { opacity: 1 } : undefined}\n transition={\n fly\n ? MORPH_TRANSITION\n : { layout: { duration: 0 }, opacity: ENTRANCE_FADE }\n }\n onLayoutAnimationStart={() => {\n if (fly) setCrossfading(true);\n }}\n onLayoutAnimationComplete={() => setCrossfading(false)}\n className=\"relative inline-block max-w-full min-w-0 truncate\"\n >\n {children}\n {crossfading && (\n <motion.span\n aria-hidden\n initial={{ opacity: 1 }}\n animate={{ opacity: 0 }}\n transition={MORPH_INK_FADE}\n className={cn(\"absolute inset-0\", fromClassName)}\n >\n {children}\n </motion.span>\n )}\n </motion.span>\n );\n}\n\nexport interface BasicPageTitleProps extends ComponentProps<\"h1\"> {\n /**\n * Shared-element key. Pair with the same `morphId` on the subpage's\n * `Back` and the word morphs between title and back link across the\n * navigation. Skipped under reduced motion.\n */\n morphId?: string;\n /**\n * Rise this title into its line on mount — for a subpage title whose line\n * an inbound Title ↔ Back morph departs from. The moment the word lifts\n * off, this title floats up from just below it (the Stack physics), so\n * the two form one upward stream and never overlap. Skipped under\n * reduced motion.\n */\n enter?: boolean;\n ref?: Ref<HTMLHeadingElement>;\n}\n\n/**\n * Page title — largest heading on the surface. Plain-text children get a slug\n * `id` for hash targets (`#profile`); the heading itself is not a link.\n * Long names ellipsize; keep trailing accessories (`Badge`, status) as\n * `shrink-0` siblings of a `min-w-0 truncate` label inside a `flex min-w-0`\n * row so they stay visible.\n */\nfunction Title({\n id,\n morphId,\n enter,\n className,\n children,\n ...props\n}: BasicPageTitleProps) {\n const headingId = resolveHeadingId(id, children);\n const reduceMotion = useReducedMotion();\n const flight = useMorphFlight(morphId);\n return (\n <h1\n id={headingId}\n className={cn(\n \"text-display-base text-pho-primary max-w-full min-w-0 scroll-mt-12 truncate px-5 font-medium\",\n className,\n )}\n {...props}\n >\n {morphId != null && !reduceMotion ? (\n <MorphLabel\n morphId={morphId}\n fromClassName=\"text-pho-secondary\"\n fly={flight.fly}\n morphRef={flight.ref}\n >\n {children}\n </MorphLabel>\n ) : enter && !reduceMotion ? (\n <motion.span\n initial={{ opacity: 0, y: REVEAL_RISE_PX }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ y: ENTRANCE_SPRING, opacity: ENTRANCE_FADE }}\n className=\"inline-block max-w-full min-w-0 truncate\"\n >\n {children}\n </motion.span>\n ) : (\n children\n )}\n </h1>\n );\n}\n\nexport interface BasicPageStackProps extends Omit<\n ComponentProps<\"div\">,\n RevealMotionConflicts\n> {\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * Vertical stack under the page title. Blocks (forms / sections) use `gap-10`;\n * each block lays out its children with `gap-3`.\n *\n * Mounting plays the page entrance: the stack rises 12px and fades in on the\n * Card-shell / Command spring while `Title` / `Back` above stay put. What\n * that means per state:\n *\n * - **Entering the page** — whatever the page first shows (skeleton\n * included) rides in with its stack.\n * - **Skeleton in a separate component** — swapping it for the loaded\n * return mounts a fresh stack, so the entrance replays as the\n * data-arrival animation. That's the right feel for shapes the skeleton\n * couldn't predict (lists of unknown length).\n * - **1:1 skeleton** — keep ONE stack mounted and branch its children\n * (`{pending ? bones : content}`): values then fill in place with no\n * motion.\n *\n * Static under reduced motion.\n */\nfunction Stack({ className, ...props }: BasicPageStackProps) {\n const reduceMotion = useReducedMotion();\n return (\n <motion.div\n initial={reduceMotion ? false : { opacity: 0, y: REVEAL_RISE_PX }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ y: ENTRANCE_SPRING, opacity: ENTRANCE_FADE }}\n className={cn(\n \"mt-6 flex min-w-0 flex-col gap-10\",\n \"*:flex *:min-w-0 *:flex-col *:gap-3\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Title + optional description pair. No gap between them — the block's\n * `gap-3` only applies between this header and the card.\n */\nexport interface BasicPageHeaderProps extends Omit<\n ComponentProps<\"div\">,\n RevealMotionConflicts\n> {\n /**\n * Rise this header into place on mount — the Header flavor of `Title`'s\n * `enter`, for a subpage title that carries a description: the pair\n * floats up from below the departing morph word as one block. Put `enter`\n * here and NOT on the `Title` inside. Skipped under reduced motion.\n */\n enter?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\nfunction Header({ enter, className, ...props }: BasicPageHeaderProps) {\n const reduceMotion = useReducedMotion();\n if (enter && !reduceMotion) {\n return (\n <motion.div\n initial={{ opacity: 0, y: REVEAL_RISE_PX }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ y: ENTRANCE_SPRING, opacity: ENTRANCE_FADE }}\n className={cn(\"flex min-w-0 flex-col\", className)}\n {...props}\n />\n );\n }\n return <div className={cn(\"flex min-w-0 flex-col\", className)} {...props} />;\n}\n\n/**\n * Section heading — same padding as the page title, smaller type. Hashable via\n * slug `id` (not a link).\n */\nfunction SectionTitle({\n id,\n className,\n children,\n ...props\n}: ComponentProps<\"h2\"> & { ref?: Ref<HTMLHeadingElement> }) {\n const headingId = resolveHeadingId(id, children);\n return (\n <h2\n id={headingId}\n className={cn(\n \"text-display-xs text-pho-primary max-w-full min-w-0 scroll-mt-12 truncate px-5 font-medium\",\n className,\n )}\n {...props}\n >\n {children}\n </h2>\n );\n}\n\n/**\n * Supporting copy under a section title. Same display step as the title;\n * color + normal weight keep it secondary. Always wrap with `Header`.\n */\nfunction Description({\n className,\n ...props\n}: ComponentProps<\"p\"> & { ref?: Ref<HTMLParagraphElement> }) {\n return (\n <p\n className={cn(\n \"text-display-xs text-pho-description px-5 font-normal\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Optional caption below a section's `Card` (outside the card). One step\n * smaller than `Description` (`text-xs`). Not the card-internal dirty-state\n * `Footer`.\n */\nfunction SectionFooter({\n className,\n ...props\n}: ComponentProps<\"p\"> & { ref?: Ref<HTMLParagraphElement> }) {\n return (\n <p\n className={cn(\"text-pho-description px-5 text-xs font-normal\", className)}\n {...props}\n />\n );\n}\n\nexport interface BasicPageCardProps extends ComponentProps<\"div\"> {\n /**\n * Glide the card's height when its content swaps — bones becoming a\n * different number of rows, a row created or revoked, an inline state\n * change. The height follows the content on the page spring instead of\n * jumping. Reserve it for cards whose contents change while mounted.\n */\n animateHeight?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\n/** Bordered card that stacks rows with hairline dividers. */\nfunction Card({\n animateHeight,\n className,\n children,\n ...props\n}: BasicPageCardProps) {\n if (animateHeight) {\n return (\n <div\n className={cn(\n BASIC_PAGE_CARD_SURFACE,\n \"min-h-0 overflow-hidden\",\n className,\n )}\n {...props}\n >\n <AnimatedHeight\n transition={ENTRANCE_SPRING}\n className={BASIC_PAGE_CARD_DIVIDERS}\n >\n {children}\n </AnimatedHeight>\n </div>\n );\n }\n return (\n <div className={cn(BASIC_PAGE_CARD, className)} {...props}>\n {children}\n </div>\n );\n}\n\n/**\n * One card row that can host subviews. Padding matches a plain row, so use it\n * for any row that may grow an `ItemPanel` — primary content goes straight in\n * as children; the panel, when present, is the last child.\n *\n * ```tsx\n * <BasicPage.Card>\n * <BasicPage.Item>\n * …name, meta, actions…\n * <BasicPage.ItemPanel divided>…secret / expanded content…</BasicPage.ItemPanel>\n * </BasicPage.Item>\n * …later siblings (pass `divided` on the panel above)…\n * </BasicPage.Card>\n * ```\n */\nfunction Item({\n className,\n ...props\n}: ComponentProps<\"div\"> & { ref?: Ref<HTMLDivElement> }) {\n return <div className={cn(BASIC_PAGE_ITEM, className)} {...props} />;\n}\n\nexport interface BasicPageItemPanelProps extends ComponentProps<\"div\"> {\n /**\n * Set when later card rows follow this item. The panel then renders as an\n * inset rounded chip (keeping the card's own divider) instead of the\n * full-bleed bottom sheet, which only reads well against the card's corner.\n * @default false\n */\n divided?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * Secondary strip at the end of an `Item`. When the item closes the card,\n * it's a gray sheet flush under the body, full-bleed and owning the row's\n * bottom padding, rounding only into the card's bottom corner. Pass `divided`\n * when later card rows follow — the panel becomes an inset rounded chip and\n * the card's hairline divider stays in charge. Content is already a centered\n * flex row either way.\n */\nfunction ItemPanel({\n divided = false,\n className,\n ...props\n}: BasicPageItemPanelProps) {\n return (\n <div\n className={cn(\n divided ? BASIC_PAGE_ITEM_PANEL_DIVIDED : BASIC_PAGE_ITEM_PANEL,\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Standalone callout. Pair with `CalloutTitle` / `CalloutDescription` (and\n * optional actions) for a featured block — e.g. an invite form. Do not wrap\n * in `Card`; this is already the outer surface.\n *\n * Pass `icon` for a decorative glyph anchored to the header block (first\n * child) — typically a Tabler outline icon. The icon is aria-hidden; keep\n * meaning in the title/description.\n */\nfunction Callout({\n className,\n icon,\n children,\n ...props\n}: ComponentProps<\"div\"> & {\n ref?: Ref<HTMLDivElement>;\n /** Decorative icon, top-right of the header (first child). */\n icon?: ReactNode;\n}) {\n // Treat boolean false (and other empty values) as absent — `icon={cond &&\n // <Icon />}` is a common pattern and must not reserve header padding.\n if (icon == null || icon === false || icon === true) {\n return (\n <div className={cn(BASIC_PAGE_CALLOUT, className)} {...props}>\n {children}\n </div>\n );\n }\n\n const [header, ...rest] = Children.toArray(children);\n\n return (\n <div className={cn(BASIC_PAGE_CALLOUT, className)} {...props}>\n <div className=\"relative\">\n <div className=\"min-w-0 pr-16\">{header}</div>\n <div\n aria-hidden\n className=\"text-pho-description pointer-events-none absolute top-1/2 right-0 size-14 -translate-y-1/2 opacity-50 [&>svg]:size-full\"\n >\n {icon}\n </div>\n </div>\n {rest}\n </div>\n );\n}\n\n/** Callout heading — same type as `SectionTitle`. Hashable via slug `id`. */\nfunction CalloutTitle({\n id,\n className,\n children,\n ...props\n}: ComponentProps<\"h2\"> & { ref?: Ref<HTMLHeadingElement> }) {\n const headingId = resolveHeadingId(id, children);\n return (\n <h2\n id={headingId}\n className={cn(\n \"text-display-xs text-pho-primary max-w-full min-w-0 scroll-mt-12 truncate font-medium\",\n className,\n )}\n {...props}\n >\n {children}\n </h2>\n );\n}\n\n/** Supporting copy under a callout title. */\nfunction CalloutDescription({\n className,\n ...props\n}: ComponentProps<\"p\"> & { ref?: Ref<HTMLParagraphElement> }) {\n return (\n <p\n className={cn(\n \"text-display-xs text-pho-description font-normal\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport interface BasicPageRowProps extends Omit<\n ComponentProps<\"div\">,\n \"title\"\n> {\n /** Left-side field name — plain text, or compose with a trailing hint. */\n label: ReactNode;\n /** Optional helper under the label. */\n description?: ReactNode;\n /** Associates the label with a control id. When omitted, the label is not a `<label>`. */\n htmlFor?: string;\n /**\n * Stack the label above a full-width control instead of the default\n * label-left / control-right layout at `sm+`. Keeps the compact `gap-3`\n * rhythm — the default row's `justify-between` would otherwise stretch\n * label and control apart under `min-h-[4.25rem]`.\n */\n stacked?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * One row: label (+ optional description) left, control right.\n * Pass `htmlFor` when the row wraps a labelled input; omit it for display/\n * action rows (avatar, danger-zone delete). Pass `stacked` for full-width\n * controls that sit under the label.\n */\nfunction Row({\n label,\n description,\n htmlFor,\n stacked = false,\n className,\n children,\n ...props\n}: BasicPageRowProps) {\n return (\n <div\n className={cn(\n BASIC_PAGE_ROW,\n stacked && \"sm:flex-col sm:items-stretch sm:justify-start sm:gap-3\",\n className,\n )}\n {...props}\n >\n <div className=\"min-w-0\">\n {htmlFor ? (\n <label\n htmlFor={htmlFor}\n className=\"text-pho-primary block text-base font-normal\"\n >\n {label}\n </label>\n ) : (\n <p className=\"text-pho-primary text-base font-normal\">{label}</p>\n )}\n {description ? (\n <p className=\"text-pho-description text-xs\">{description}</p>\n ) : null}\n </div>\n <div\n className={cn(\n \"flex w-full min-w-0 items-center gap-2 sm:w-auto\",\n stacked && \"sm:w-full\",\n )}\n >\n {children}\n </div>\n </div>\n );\n}\n\n/** Read-only value on the right side of a row (email, etc.). */\nfunction Value({\n className,\n ...props\n}: ComponentProps<\"p\"> & { ref?: Ref<HTMLParagraphElement> }) {\n return (\n <p\n className={cn(\n \"text-pho-description max-w-full min-w-0 truncate text-base\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport interface BasicPageAlertProps extends Omit<\n ComponentProps<\"div\">,\n \"children\"\n> {\n /** The caught value — a problem body, an `Error` wrapping one, or unknown. */\n error?: unknown;\n /** Override the derived message. */\n children?: ReactNode;\n /**\n * Explicit presence override — defaults to whether there is anything to\n * show, so the reveal plays as the mutation's error comes and goes.\n */\n show?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * Server error under a row, still inside the card — the partial failure\n * (\"Couldn't update your name\"), rendered by `Error` from the problem body.\n * Keep it mounted and pass the mutation's error: the line reveals and\n * collapses on `Footer`'s height spring + fade. The card drops its divider\n * above the line so it reads as part of the row it belongs to. Matches card\n * horizontal padding — don't re-apply `px-5`.\n *\n * For a page that failed to load outright, swap the stack for an `ErrorView`\n * instead.\n */\nfunction Alert({\n error,\n show,\n className,\n children,\n ...props\n}: BasicPageAlertProps) {\n const reduceMotion = useReducedMotion();\n const hasContent = error != null || children != null;\n // Explicit `show` cannot force an empty animated slot — ErrorLine returns\n // null when there is nothing to render.\n const visible = (show ?? true) && hasContent;\n return (\n <AnimatePresence initial={false}>\n {visible ? (\n <motion.div\n data-basic-page-alert=\"\"\n className=\"overflow-hidden\"\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: \"auto\", opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={\n reduceMotion\n ? { duration: 0 }\n : { height: ENTRANCE_SPRING, opacity: ENTRANCE_FADE }\n }\n >\n <ErrorLine\n error={error}\n className={cn(\"px-5 pb-3\", className)}\n {...props}\n >\n {children}\n </ErrorLine>\n </motion.div>\n ) : null}\n </AnimatePresence>\n );\n}\n\nexport interface BasicPageFooterProps extends ComponentProps<\"div\"> {\n /**\n * Animated presence for dirty-state bars: the card glides open/closed on a\n * height spring while the content fades. Omit for a static, always-visible\n * footer (no animation). No reveal plays on first mount — only on flips.\n */\n show?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * Trailing bar inside a card — typically a save status + submit button that\n * appears after the form is dirty. Same horizontal/vertical padding as a row.\n * Pass `show` (instead of conditional rendering) to animate the bar in and\n * out following the onboarding card's motion language.\n */\nfunction Footer({ show, className, ...props }: BasicPageFooterProps) {\n const reduceMotion = useReducedMotion();\n const bar = (\n <div\n className={cn(\n \"flex items-center justify-between gap-6 px-5 py-4\",\n className,\n )}\n {...props}\n />\n );\n\n if (show === undefined) return bar;\n\n return (\n <AnimatePresence initial={false}>\n {show ? (\n <motion.div\n className=\"overflow-hidden\"\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: \"auto\", opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={\n reduceMotion\n ? { duration: 0 }\n : { height: ENTRANCE_SPRING, opacity: ENTRANCE_FADE }\n }\n >\n {bar}\n </motion.div>\n ) : null}\n </AnimatePresence>\n );\n}\n\n/**\n * Rise distance for the `Reveal` entrance — small travel; the content\n * surfaces, it doesn't slide in.\n */\nconst REVEAL_RISE_PX = 12;\n\n/**\n * DOM handlers whose React signatures clash with Motion's gesture props of\n * the same name on `motion.*` elements — excluded from `Reveal`'s public API\n * (same policy as Button).\n */\ntype RevealMotionConflicts =\n | \"onAnimationStart\"\n | \"onAnimationEnd\"\n | \"onAnimationIteration\"\n | \"onDrag\"\n | \"onDragStart\"\n | \"onDragEnd\"\n | \"onDragEnter\"\n | \"onDragExit\"\n | \"onDragLeave\"\n | \"onDragOver\"\n | \"onDrop\";\n\nexport interface BasicPageRevealProps extends Omit<\n ComponentProps<\"div\">,\n RevealMotionConflicts\n> {\n /**\n * Animated presence for a `Stack` block that comes and goes: keep the\n * block mounted and drive it with `show` — it glides open and closed\n * (height + fade) on the page spring, with the Stack's `gap-10`\n * compensated so nothing jumps when it fully collapses. Omit `show` for\n * the one-shot data-arrival entrance.\n */\n show?: boolean;\n /**\n * Which gap the presence variant compensates while collapsing —\n * `\"stack\"` for a Stack block (`gap-10`), `\"block\"` for an element\n * inside a block (`gap-3`). @default \"stack\"\n */\n gap?: \"stack\" | \"block\";\n /**\n * Set when this wraps multiple `Card` rows — the extra element Reveal\n * needs for `AnimatePresence` sits between them and the card's own\n * `divide-y`, so the hairlines between the wrapped rows disappear unless\n * this restores them. Leave off for content that isn't a run of rows.\n */\n dividers?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * Exactly one surrounding flex gap — the presence variant trades this much\n * margin against its height so neighbours glide to their final positions\n * instead of snapping by a gap when the block unmounts. `dividers` rows sit\n * in a `divide-y` card with no flex `gap` at all, so they get no\n * compensation — `gap` would otherwise overshoot into the next row's padding\n * as the block collapses.\n */\nconst GAP_COMPENSATION = {\n stack: \"-2.5rem\",\n block: \"-0.75rem\",\n none: \"0px\",\n} as const;\n\n/**\n * Data-arrival entrance for regions whose shape the skeleton couldn't\n * predict — a list of unknown length, a region that depends on the data.\n * Wrap that region (keeping `Title` and 1:1 chrome outside): once the shape\n * is known it rises 12px and fades in on the Card-shell / Command spring,\n * the same physics as the `Footer` / `Alert` reveals. When the skeleton\n * mirrors the loaded layout element for element, skip the reveal — values\n * fill into a shape that never moves. The page *entrance* is separate and\n * already built into `Stack`: whatever the page first shows (including the\n * skeleton) rides that. Static under reduced motion.\n *\n * With `show`, Reveal becomes an animated-presence block instead (the\n * `Footer` grammar): a whole section of the Stack that appears or leaves at\n * runtime glides open/closed while its neighbours follow.\n */\nfunction Reveal({\n show,\n gap = \"stack\",\n dividers,\n className,\n ...props\n}: BasicPageRevealProps) {\n const reduceMotion = useReducedMotion();\n // Card rows carry their own padding and a divide-y border, not a flex\n // gap — dividers always means zero gap to compensate for.\n const gapCompensation = GAP_COMPENSATION[dividers ? \"none\" : gap];\n\n if (show === undefined) {\n return (\n <motion.div\n initial={reduceMotion ? false : { opacity: 0, y: REVEAL_RISE_PX }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ y: ENTRANCE_SPRING, opacity: ENTRANCE_FADE }}\n className={cn(dividers && BASIC_PAGE_CARD_DIVIDERS, className)}\n {...props}\n />\n );\n }\n\n return (\n <AnimatePresence initial={false}>\n {show ? (\n <motion.div\n initial={{\n height: 0,\n opacity: 0,\n marginTop: gapCompensation,\n }}\n animate={{ height: \"auto\", opacity: 1, marginTop: 0 }}\n exit={{ height: 0, opacity: 0, marginTop: gapCompensation }}\n transition={\n reduceMotion\n ? { duration: 0 }\n : {\n height: ENTRANCE_SPRING,\n marginTop: ENTRANCE_SPRING,\n opacity: ENTRANCE_FADE,\n }\n }\n className={cn(\n \"overflow-hidden\",\n dividers && BASIC_PAGE_CARD_DIVIDERS,\n className,\n )}\n {...props}\n />\n ) : null}\n </AnimatePresence>\n );\n}\n\n/* ------------------------------- navigation ------------------------------ */\n\nexport interface BasicPageBackProps extends Omit<\n ButtonLinkProps,\n \"variant\" | \"size\" | \"shape\" | \"prefix\" | \"suffix\" | \"svgOnly\" | \"href\"\n> {\n /** Parent destination — rendered through the host's `LinkProvider`. */\n href: string;\n /** Label — name the parent page. @default \"Back\" */\n children?: ReactNode;\n /**\n * Shared-element key. Pair with the same `morphId` on the parent page's\n * `Title` and the word morphs between title and back link across the\n * navigation. Skipped under reduced motion.\n */\n morphId?: string;\n}\n\n/**\n * Back link for a subpage — a small ghost `ButtonLink`; place inside `Root`,\n * before `Title`. It floats in `Root`'s reserved top padding (vertically\n * centered in the 48px zone) instead of taking layout space, so `Title` sits\n * at exactly the same position whether or not a page has one.\n *\n * The offsets align the *label* glyph with the title glyph. Title text sits\n * 40px in (`px-5` root gutter + `px-5` title pad); inside a `sm` ghost button\n * the label sits 29.75px in (8px icon-side pad + 15.75px chevron, 1.125em at\n * the 14px `text-base`, + 4px gap + 2px label-span `px-0.5`) — so `left` is\n * the 10.25px difference. `top-4` centers the 32px button in the 64px\n * reserved zone. The chevron and the ghost hover pill hang in the padding —\n * the usual optical alignment for borderless controls.\n */\nfunction Back({\n href,\n className,\n morphId,\n children = \"Back\",\n ...props\n}: BasicPageBackProps) {\n const reduceMotion = useReducedMotion();\n const morphing = morphId != null && !reduceMotion;\n const flight = useMorphFlight(morphing ? morphId : undefined);\n return (\n <ButtonLink\n variant=\"ghost\"\n size=\"sm\"\n href={href}\n data-basic-page-back=\"\"\n prefix={\n morphing ? (\n // Mirrors the slot's direct-child svg sizing — the fade wrapper\n // sits between the slot and the icon.\n <motion.span\n initial={\n flight.fly\n ? { opacity: 0, x: MORPH_CHEVRON_RISE_X }\n : { opacity: 0 }\n }\n animate={flight.fly ? { opacity: 1, x: 0 } : { opacity: 1 }}\n transition={flight.fly ? MORPH_CHEVRON_ENTER : ENTRANCE_FADE}\n className=\"inline-flex [&>svg]:size-[1.125em] [&>svg]:shrink-0\"\n >\n <IconChevronLeft />\n </motion.span>\n ) : (\n <IconChevronLeft />\n )\n }\n className={cn(\"absolute top-4 left-[10.25px]\", className)}\n {...props}\n >\n {morphing && morphId != null ? (\n <MorphLabel\n morphId={morphId}\n fromClassName=\"text-pho-primary\"\n fly={flight.fly}\n morphRef={flight.ref}\n fallback\n >\n {children}\n </MorphLabel>\n ) : (\n children\n )}\n </ButtonLink>\n );\n}\n\nexport interface BasicPageRowLinkProps extends Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n \"href\" | \"title\"\n> {\n /** Left-side field name — plain text, or compose with a trailing badge. */\n label: ReactNode;\n /** Optional helper under the label. */\n description?: ReactNode;\n /** Optional media left of the label (e.g. project avatar). */\n leading?: ReactNode;\n /** Subpage destination — rendered through the host's `LinkProvider`. */\n href: string;\n /** Optional trailing value before the chevron (compose with `Value`). */\n children?: ReactNode;\n ref?: Ref<HTMLAnchorElement>;\n}\n\n/**\n * A row that navigates — the whole row is one link into a subpage, with a\n * trailing chevron cue. Always horizontal: a column stack would park the\n * chevron under the label on narrow viewports. Hover lifts the row, and\n * first/last rows follow the card's corner radius.\n */\nfunction RowLink({\n label,\n description,\n leading,\n href,\n className,\n children,\n ...props\n}: BasicPageRowLinkProps) {\n const Link = useLinkComponent();\n return (\n <Link\n href={href}\n {...props}\n className={cn(\n // Same padding / min-height as `BASIC_PAGE_ROW`, but never `flex-col`\n // — navigation rows keep label left and chevron right at every width.\n \"flex min-h-[4.25rem] min-w-0 flex-row items-center justify-between gap-6 px-5 py-4\",\n \"group outline-pho-brand hover:bg-pho-primary-hover cursor-pointer transition-colors focus-visible:outline-2 focus-visible:-outline-offset-2\",\n // Hover wash follows the card's rounding (minus the 1px border).\n \"first:rounded-t-[calc(var(--radius-base)-1px)] last:rounded-b-[calc(var(--radius-base)-1px)]\",\n className,\n )}\n >\n <div\n className={cn(\n \"flex min-w-0 flex-1 items-center\",\n leading != null && \"gap-3\",\n )}\n >\n {leading}\n <div className=\"min-w-0\">\n <div className=\"flex min-w-0 items-center gap-1\">\n {typeof label === \"string\" || typeof label === \"number\" ? (\n <p className=\"text-pho-primary truncate text-base font-medium\">\n {label}\n </p>\n ) : (\n label\n )}\n </div>\n {description ? (\n <div className=\"text-pho-description truncate text-xs\">\n {description}\n </div>\n ) : null}\n </div>\n </div>\n <div className=\"flex min-w-0 items-center justify-end gap-2\">\n {children != null ? <div className=\"min-w-0\">{children}</div> : null}\n <IconChevronRight\n aria-hidden\n className=\"text-pho-secondary group-hover:text-pho-secondary-hover size-4 shrink-0 transition-colors\"\n />\n </div>\n </Link>\n );\n}\n\n/* -------------------------------- assembly ------------------------------- */\n\n/**\n * Basic page layout. One stack, one gap rhythm — only title scale differs:\n *\n * ```tsx\n * <BasicPage.Root>\n * <BasicPage.Title>Profile</BasicPage.Title>\n * <BasicPage.Stack>\n * <form>\n * <BasicPage.Card>\n * <BasicPage.Row label=\"Name\" htmlFor=\"first-name\">\n * <Input id=\"first-name\" size=\"sm\" />\n * </BasicPage.Row>\n * </BasicPage.Card>\n * </form>\n * <form>\n * <BasicPage.Header>\n * <BasicPage.SectionTitle>Agent profile</BasicPage.SectionTitle>\n * <BasicPage.Description>…</BasicPage.Description>\n * </BasicPage.Header>\n * <BasicPage.Card>…</BasicPage.Card>\n * </form>\n * <div>\n * <BasicPage.SectionTitle>Danger zone</BasicPage.SectionTitle>\n * <BasicPage.Card>\n * <BasicPage.Row label=\"Delete account\" description=\"…\">\n * <Button color=\"destructive\" size=\"sm\">Delete</Button>\n * </BasicPage.Row>\n * </BasicPage.Card>\n * </div>\n * <BasicPage.Callout icon={<IconMail stroke={1.25} />}>\n * <BasicPage.Header>\n * <BasicPage.CalloutTitle>Invitations</BasicPage.CalloutTitle>\n * <BasicPage.CalloutDescription>…</BasicPage.CalloutDescription>\n * </BasicPage.Header>\n * …invite form…\n * </BasicPage.Callout>\n * </BasicPage.Stack>\n * </BasicPage.Root>\n * ```\n *\n * Subpage — `Back` above the title, `RowLink` rows to drill in:\n *\n * ```tsx\n * <BasicPage.Root>\n * <BasicPage.Back href=\"/settings\">Settings</BasicPage.Back>\n * <BasicPage.Title>Billing</BasicPage.Title>\n * <BasicPage.Stack>\n * <div>\n * <BasicPage.Card>\n * <BasicPage.RowLink label=\"Invoices\" href=\"/settings/invoices\">\n * <BasicPage.Value>12 documents</BasicPage.Value>\n * </BasicPage.RowLink>\n * </BasicPage.Card>\n * </div>\n * </BasicPage.Stack>\n * </BasicPage.Root>\n * ```\n */\nexport const BasicPage = {\n Root,\n Back,\n Title,\n Stack,\n Header,\n SectionTitle,\n Description,\n SectionFooter,\n Card,\n Item,\n ItemPanel,\n Callout,\n CalloutTitle,\n CalloutDescription,\n Row,\n RowLink,\n Value,\n Alert,\n Footer,\n Reveal,\n};\n"],"x_google_ignoreList":[0],"mappings":";;;;;;;;;;;AASA,IAAM,IAAa,CAAC,CAAC,QAAQ;AAAA,EAAE,GAAK;AAAA,EAAiB,KAAO;AAAQ,CAAC,CAAC,GAChE,IAAmB,EAAqB,WAAW,iBAAiB,gBAAgB,CAAU,GC8B9F,IACJ,2DASI,IACJ,+EAGW,IAAkB,GAAG,CAAA,IAA2B,CAAA,IAMhD,IACX,wFAOW,IACX,iHAMW,IAAkB,iCAUlB,IACX,+FAUW,IACX,2EAWI,IAAkB;AAAA,EACtB,MAAM;AAAA,EACN,WAAW;AAAA,EACX,SAAS;AACX,GAGM,IAAgB;AAAA,EAAE,UAAU;AAAA,EAAM,MAAM;AAAU;AA2BxD,SAAS,EAAK,EACZ,WAAA,GACA,GAAG,EAAA,GACqD;AACxD,SACE,gBAAA,EAAC,OAAD;AAAA,IACE,WAAW,EACT,0IACA,CACF;AAAA,IACA,GAAI;AAAA,EACL,CAAA;AAEL;AAMA,SAAS,EAAe,GAAuB;AAC7C,SAAO,EACJ,UAAU,MAAM,EAChB,QAAQ,oBAAoB,EAAE,EAC9B,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,YAAY,EAAE;AAC3B;AAEA,SAAS,EAAsB,GAAyC;AACtE,MAAI,SAAO,KAAa,YAAY,OAAO,KAAa;AAIxD,WADa,EAAe,OAAO,CAAQ,CACpC,KAAQ;AACjB;AAGA,SAAS,EACP,GACA,GACoB;AACpB,MAAI,MAAO;AACX,WAAI,KACG,EAAsB,CAAQ;AACvC;AAQA,IAAM,IAAA,CAAiB,MAAe,oBAAoB,CAAA,IAGpD,IAAmB,EAAE,QAAQ,EAAgB,GAU7C,IAAuB,IACvB,IAAsB;AAAA,EAC1B,OAAO;AAAA,EACP,UAAU;AAAA,EACV,MAAM;AACR,GASM,IAAiB;AAAA,EAAE,UAAU;AAAA,EAAM,MAAM;AAAU,GASnD,IAAmB,oBAAI,IAAqB;AAQlD,SAAS,EAAe,GAA6B;AACnD,QAAM,CAAC,CAAA,IAAO,EAAA,MACN,KAAW,QAAQ,EAAiB,IAAI,CAAO,MAAM,EAC7D,GACM,IAAM,EAA+B,IAAI;AAC/C,SAAA,EAAA,MAAgB;AACd,QAAI,KAAW,QAAQ,OAAO,uBAAyB,IAAa;AACpE,UAAM,IAAK,EAAI;AACf,QAAI,CAAC,EAAI;AACT,UAAM,IAAW,IAAI,qBAAA,CAAsB,CAAC,CAAA,MAAW;AACrD,MAAI,KAAO,EAAiB,IAAI,GAAS,EAAM,cAAc;AAAA,IAC/D,CAAC;AACD,WAAA,EAAS,QAAQ,CAAE,GACnB,MAAa;AACX,MAAA,EAAS,WAAW;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,CAAO,CAAC,GACL;AAAA,IAAE,KAAA;AAAA,IAAK,KAAA;AAAA,EAAI;AACpB;AASA,SAAS,EAAW,EAClB,SAAA,GACA,eAAA,GACA,KAAA,GACA,UAAA,GACA,UAAA,IAAW,IACX,UAAA,EAAA,GAWC;AACD,QAAM,CAAC,GAAa,CAAA,IAAkB,EAAS,EAAK,GAC9C,IAAO,CAAC,KAAO;AACrB,SACE,gBAAA,EAAC,EAAO,MAAR;AAAA,IACE,KAAK;AAAA,IACL,UAAU,EAAc,CAAO;AAAA,IAC/B,SAAS,IAAO,EAAE,SAAS,EAAE,IAAI;AAAA,IACjC,SAAS,IAAO,EAAE,SAAS,EAAE,IAAI;AAAA,IACjC,YACE,IACI,IACA;AAAA,MAAE,QAAQ,EAAE,UAAU,EAAE;AAAA,MAAG,SAAS;AAAA,IAAc;AAAA,IAExD,wBAAA,MAA8B;AAC5B,MAAI,KAAK,EAAe,EAAI;AAAA,IAC9B;AAAA,IACA,2BAAA,MAAiC,EAAe,EAAK;AAAA,IACrD,WAAU;AAAA,cAdZ,CAgBG,GACA,KACC,gBAAA,EAAC,EAAO,MAAR;AAAA,MACE,eAAA;AAAA,MACA,SAAS,EAAE,SAAS,EAAE;AAAA,MACtB,SAAS,EAAE,SAAS,EAAE;AAAA,MACtB,YAAY;AAAA,MACZ,WAAW,EAAG,oBAAoB,CAAa;AAAA,MAE9C,UAAA;AAAA,IACU,CAAA,CAEJ;AAAA;AAEjB;AA2BA,SAAS,EAAM,EACb,IAAA,GACA,SAAA,GACA,OAAA,GACA,WAAA,GACA,UAAA,GACA,GAAG,EAAA,GACmB;AACtB,QAAM,IAAY,EAAiB,GAAI,CAAQ,GACzC,IAAe,EAAiB,GAChC,IAAS,EAAe,CAAO;AACrC,SACE,gBAAA,EAAC,MAAD;AAAA,IACE,IAAI;AAAA,IACJ,WAAW,EACT,gGACA,CACF;AAAA,IACA,GAAI;AAAA,cAEH,KAAW,QAAQ,CAAC,IACnB,gBAAA,EAAC,GAAD;AAAA,MACW,SAAA;AAAA,MACT,eAAc;AAAA,MACd,KAAK,EAAO;AAAA,MACZ,UAAU,EAAO;AAAA,MAEhB,UAAA;AAAA,IACS,CAAA,IACV,KAAS,CAAC,IACZ,gBAAA,EAAC,EAAO,MAAR;AAAA,MACE,SAAS;AAAA,QAAE,SAAS;AAAA,QAAG,GAAG;AAAA,MAAe;AAAA,MACzC,SAAS;AAAA,QAAE,SAAS;AAAA,QAAG,GAAG;AAAA,MAAE;AAAA,MAC5B,YAAY;AAAA,QAAE,GAAG;AAAA,QAAiB,SAAS;AAAA,MAAc;AAAA,MACzD,WAAU;AAAA,MAET,UAAA;AAAA,IACU,CAAA,IAEb;AAAA,EAEA,CAAA;AAER;AA6BA,SAAS,EAAM,EAAE,WAAA,GAAW,GAAG,EAAA,GAA8B;AAC3D,QAAM,IAAe,EAAiB;AACtC,SACE,gBAAA,EAAC,EAAO,KAAR;AAAA,IACE,SAAS,IAAe,KAAQ;AAAA,MAAE,SAAS;AAAA,MAAG,GAAG;AAAA,IAAe;AAAA,IAChE,SAAS;AAAA,MAAE,SAAS;AAAA,MAAG,GAAG;AAAA,IAAE;AAAA,IAC5B,YAAY;AAAA,MAAE,GAAG;AAAA,MAAiB,SAAS;AAAA,IAAc;AAAA,IACzD,WAAW,EACT,qCACA,uCACA,CACF;AAAA,IACA,GAAI;AAAA,EACL,CAAA;AAEL;AAoBA,SAAS,EAAO,EAAE,OAAA,GAAO,WAAA,GAAW,GAAG,EAAA,GAA+B;AACpE,QAAM,IAAe,EAAiB;AACtC,SAAI,KAAS,CAAC,IAEV,gBAAA,EAAC,EAAO,KAAR;AAAA,IACE,SAAS;AAAA,MAAE,SAAS;AAAA,MAAG,GAAG;AAAA,IAAe;AAAA,IACzC,SAAS;AAAA,MAAE,SAAS;AAAA,MAAG,GAAG;AAAA,IAAE;AAAA,IAC5B,YAAY;AAAA,MAAE,GAAG;AAAA,MAAiB,SAAS;AAAA,IAAc;AAAA,IACzD,WAAW,EAAG,yBAAyB,CAAS;AAAA,IAChD,GAAI;AAAA,EACL,CAAA,IAGE,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,EAAG,yBAAyB,CAAS;AAAA,IAAG,GAAI;AAAA,EAAQ,CAAA;AAC7E;AAMA,SAAS,EAAa,EACpB,IAAA,GACA,WAAA,GACA,UAAA,GACA,GAAG,EAAA,GACwD;AAE3D,SACE,gBAAA,EAAC,MAAD;AAAA,IACE,IAHc,EAAiB,GAAI,CAG/B;AAAA,IACJ,WAAW,EACT,8FACA,CACF;AAAA,IACA,GAAI;AAAA,IAEH,UAAA;AAAA,EACC,CAAA;AAER;AAMA,SAAS,GAAY,EACnB,WAAA,GACA,GAAG,EAAA,GACyD;AAC5D,SACE,gBAAA,EAAC,KAAD;AAAA,IACE,WAAW,EACT,yDACA,CACF;AAAA,IACA,GAAI;AAAA,EACL,CAAA;AAEL;AAOA,SAAS,GAAc,EACrB,WAAA,GACA,GAAG,EAAA,GACyD;AAC5D,SACE,gBAAA,EAAC,KAAD;AAAA,IACE,WAAW,EAAG,iDAAiD,CAAS;AAAA,IACxE,GAAI;AAAA,EACL,CAAA;AAEL;AAcA,SAAS,GAAK,EACZ,eAAA,GACA,WAAA,GACA,UAAA,GACA,GAAG,EAAA,GACkB;AACrB,SAAI,IAEA,gBAAA,EAAC,OAAD;AAAA,IACE,WAAW,EACT,GACA,2BACA,CACF;AAAA,IACA,GAAI;AAAA,cAEJ,gBAAA,EAAC,GAAD;AAAA,MACE,YAAY;AAAA,MACZ,WAAW;AAAA,MAEV,UAAA;AAAA,IACa,CAAA;AAAA,EACb,CAAA,IAIP,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,EAAG,GAAiB,CAAS;AAAA,IAAG,GAAI;AAAA,IACjD,UAAA;AAAA,EACE,CAAA;AAET;AAiBA,SAAS,GAAK,EACZ,WAAA,GACA,GAAG,EAAA,GACqD;AACxD,SAAO,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,EAAG,GAAiB,CAAS;AAAA,IAAG,GAAI;AAAA,EAAQ,CAAA;AACrE;AAqBA,SAAS,GAAU,EACjB,SAAA,IAAU,IACV,WAAA,GACA,GAAG,EAAA,GACuB;AAC1B,SACE,gBAAA,EAAC,OAAD;AAAA,IACE,WAAW,EACT,IAAU,IAAgC,GAC1C,CACF;AAAA,IACA,GAAI;AAAA,EACL,CAAA;AAEL;AAWA,SAAS,GAAQ,EACf,WAAA,GACA,MAAA,GACA,UAAA,GACA,GAAG,EAAA,GAKF;AAGD,MAAI,KAAQ,QAAQ,MAAS,MAAS,MAAS,GAC7C,QACE,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,EAAG,GAAoB,CAAS;AAAA,IAAG,GAAI;AAAA,IACpD,UAAA;AAAA,EACE,CAAA;AAIT,QAAM,CAAC,GAAQ,GAAG,CAAA,IAAQ,EAAS,QAAQ,CAAQ;AAEnD,SACE,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,EAAG,GAAoB,CAAS;AAAA,IAAG,GAAI;AAAA,cAAvD,CACE,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAU;AAAA,gBAAf,CACE,gBAAA,EAAC,OAAD;AAAA,QAAK,WAAU;AAAA,kBAAiB;AAAA,MAAY,CAAA,GAC5C,gBAAA,EAAC,OAAD;AAAA,QACE,eAAA;AAAA,QACA,WAAU;AAAA,kBAET;AAAA,MACE,CAAA,CACF;AAAA,QACJ,CACE;AAAA;AAET;AAGA,SAAS,GAAa,EACpB,IAAA,GACA,WAAA,GACA,UAAA,GACA,GAAG,EAAA,GACwD;AAE3D,SACE,gBAAA,EAAC,MAAD;AAAA,IACE,IAHc,EAAiB,GAAI,CAG/B;AAAA,IACJ,WAAW,EACT,yFACA,CACF;AAAA,IACA,GAAI;AAAA,IAEH,UAAA;AAAA,EACC,CAAA;AAER;AAGA,SAAS,GAAmB,EAC1B,WAAA,GACA,GAAG,EAAA,GACyD;AAC5D,SACE,gBAAA,EAAC,KAAD;AAAA,IACE,WAAW,EACT,oDACA,CACF;AAAA,IACA,GAAI;AAAA,EACL,CAAA;AAEL;AA4BA,SAAS,GAAI,EACX,OAAA,GACA,aAAA,GACA,SAAA,GACA,SAAA,IAAU,IACV,WAAA,GACA,UAAA,GACA,GAAG,EAAA,GACiB;AACpB,SACE,gBAAA,EAAC,OAAD;AAAA,IACE,WAAW,EACT,GACA,KAAW,0DACX,CACF;AAAA,IACA,GAAI;AAAA,cANN,CAQE,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAU;AAAA,gBAAf,CACG,IACC,gBAAA,EAAC,SAAD;AAAA,QACW,SAAA;AAAA,QACT,WAAU;AAAA,kBAET;AAAA,MACI,CAAA,IAEP,gBAAA,EAAC,KAAD;AAAA,QAAG,WAAU;AAAA,kBAA0C;AAAA,MAAS,CAAA,GAEjE,IACC,gBAAA,EAAC,KAAD;AAAA,QAAG,WAAU;AAAA,kBAAgC;AAAA,MAAe,CAAA,IAC1D,IACD;AAAA,QACL,gBAAA,EAAC,OAAD;AAAA,MACE,WAAW,EACT,oDACA,KAAW,WACb;AAAA,MAEC,UAAA;AAAA,IACE,CAAA,CACF;AAAA;AAET;AAGA,SAAS,GAAM,EACb,WAAA,GACA,GAAG,EAAA,GACyD;AAC5D,SACE,gBAAA,EAAC,KAAD;AAAA,IACE,WAAW,EACT,8DACA,CACF;AAAA,IACA,GAAI;AAAA,EACL,CAAA;AAEL;AA6BA,SAAS,GAAM,EACb,OAAA,GACA,MAAA,GACA,WAAA,GACA,UAAA,GACA,GAAG,EAAA,GACmB;AACtB,QAAM,IAAe,EAAiB;AAKtC,SACE,gBAAA,EAAC,GAAD;AAAA,IAAiB,SAAS;AAAA,eAFX,KAAQ,QAHN,KAAS,QAAQ,KAAY,QAO1C,gBAAA,EAAC,EAAO,KAAR;AAAA,MACE,yBAAsB;AAAA,MACtB,WAAU;AAAA,MACV,SAAS;AAAA,QAAE,QAAQ;AAAA,QAAG,SAAS;AAAA,MAAE;AAAA,MACjC,SAAS;AAAA,QAAE,QAAQ;AAAA,QAAQ,SAAS;AAAA,MAAE;AAAA,MACtC,MAAM;AAAA,QAAE,QAAQ;AAAA,QAAG,SAAS;AAAA,MAAE;AAAA,MAC9B,YACE,IACI,EAAE,UAAU,EAAE,IACd;AAAA,QAAE,QAAQ;AAAA,QAAiB,SAAS;AAAA,MAAc;AAAA,gBAGxD,gBAAA,EAAC,GAAD;AAAA,QACS,OAAA;AAAA,QACP,WAAW,EAAG,aAAa,CAAS;AAAA,QACpC,GAAI;AAAA,QAEH,UAAA;AAAA,MACQ,CAAA;AAAA,IACD,CAAA,IACV;AAAA,EACW,CAAA;AAErB;AAkBA,SAAS,GAAO,EAAE,MAAA,GAAM,WAAA,GAAW,GAAG,EAAA,GAA+B;AACnE,QAAM,IAAe,EAAiB,GAChC,IACJ,gBAAA,EAAC,OAAD;AAAA,IACE,WAAW,EACT,qDACA,CACF;AAAA,IACA,GAAI;AAAA,EACL,CAAA;AAGH,SAAI,MAAS,SAAkB,IAG7B,gBAAA,EAAC,GAAD;AAAA,IAAiB,SAAS;AAAA,cACvB,IACC,gBAAA,EAAC,EAAO,KAAR;AAAA,MACE,WAAU;AAAA,MACV,SAAS;AAAA,QAAE,QAAQ;AAAA,QAAG,SAAS;AAAA,MAAE;AAAA,MACjC,SAAS;AAAA,QAAE,QAAQ;AAAA,QAAQ,SAAS;AAAA,MAAE;AAAA,MACtC,MAAM;AAAA,QAAE,QAAQ;AAAA,QAAG,SAAS;AAAA,MAAE;AAAA,MAC9B,YACE,IACI,EAAE,UAAU,EAAE,IACd;AAAA,QAAE,QAAQ;AAAA,QAAiB,SAAS;AAAA,MAAc;AAAA,gBAGvD;AAAA,IACS,CAAA,IACV;AAAA,EACW,CAAA;AAErB;AAMA,IAAM,IAAiB,IAwDjB,KAAmB;AAAA,EACvB,OAAO;AAAA,EACP,OAAO;AAAA,EACP,MAAM;AACR;AAiBA,SAAS,GAAO,EACd,MAAA,GACA,KAAA,IAAM,SACN,UAAA,GACA,WAAA,GACA,GAAG,EAAA,GACoB;AACvB,QAAM,IAAe,EAAiB,GAGhC,IAAkB,GAAiB,IAAW,SAAS,CAAA;AAE7D,SAAI,MAAS,SAET,gBAAA,EAAC,EAAO,KAAR;AAAA,IACE,SAAS,IAAe,KAAQ;AAAA,MAAE,SAAS;AAAA,MAAG,GAAG;AAAA,IAAe;AAAA,IAChE,SAAS;AAAA,MAAE,SAAS;AAAA,MAAG,GAAG;AAAA,IAAE;AAAA,IAC5B,YAAY;AAAA,MAAE,GAAG;AAAA,MAAiB,SAAS;AAAA,IAAc;AAAA,IACzD,WAAW,EAAG,KAAY,GAA0B,CAAS;AAAA,IAC7D,GAAI;AAAA,EACL,CAAA,IAKH,gBAAA,EAAC,GAAD;AAAA,IAAiB,SAAS;AAAA,cACvB,IACC,gBAAA,EAAC,EAAO,KAAR;AAAA,MACE,SAAS;AAAA,QACP,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,MACA,SAAS;AAAA,QAAE,QAAQ;AAAA,QAAQ,SAAS;AAAA,QAAG,WAAW;AAAA,MAAE;AAAA,MACpD,MAAM;AAAA,QAAE,QAAQ;AAAA,QAAG,SAAS;AAAA,QAAG,WAAW;AAAA,MAAgB;AAAA,MAC1D,YACE,IACI,EAAE,UAAU,EAAE,IACd;AAAA,QACE,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,SAAS;AAAA,MACX;AAAA,MAEN,WAAW,EACT,mBACA,KAAY,GACZ,CACF;AAAA,MACA,GAAI;AAAA,IACL,CAAA,IACC;AAAA,EACW,CAAA;AAErB;AAkCA,SAAS,GAAK,EACZ,MAAA,GACA,WAAA,GACA,SAAA,GACA,UAAA,IAAW,QACX,GAAG,EAAA,GACkB;AACrB,QAAM,IAAe,EAAiB,GAChC,IAAW,KAAW,QAAQ,CAAC,GAC/B,IAAS,EAAe,IAAW,IAAU,MAAS;AAC5D,SACE,gBAAA,EAAC,GAAD;AAAA,IACE,SAAQ;AAAA,IACR,MAAK;AAAA,IACC,MAAA;AAAA,IACN,wBAAqB;AAAA,IACrB,QACE,IAGE,gBAAA,EAAC,EAAO,MAAR;AAAA,MACE,SACE,EAAO,MACH;AAAA,QAAE,SAAS;AAAA,QAAG,GAAG;AAAA,MAAqB,IACtC,EAAE,SAAS,EAAE;AAAA,MAEnB,SAAS,EAAO,MAAM;AAAA,QAAE,SAAS;AAAA,QAAG,GAAG;AAAA,MAAE,IAAI,EAAE,SAAS,EAAE;AAAA,MAC1D,YAAY,EAAO,MAAM,IAAsB;AAAA,MAC/C,WAAU;AAAA,gBAEV,gBAAA,EAAC,GAAD,CAAkB,CAAA;AAAA,IACP,CAAA,IAEb,gBAAA,EAAC,GAAD,CAAkB,CAAA;AAAA,IAGtB,WAAW,EAAG,iCAAiC,CAAS;AAAA,IACxD,GAAI;AAAA,cAEH,KAAY,KAAW,OACtB,gBAAA,EAAC,GAAD;AAAA,MACW,SAAA;AAAA,MACT,eAAc;AAAA,MACd,KAAK,EAAO;AAAA,MACZ,UAAU,EAAO;AAAA,MACjB,UAAA;AAAA,MAEC,UAAA;AAAA,IACS,CAAA,IAEZ;AAAA,EAEQ,CAAA;AAEhB;AAyBA,SAAS,GAAQ,EACf,OAAA,GACA,aAAA,GACA,SAAA,GACA,MAAA,GACA,WAAA,GACA,UAAA,GACA,GAAG,EAAA,GACqB;AAExB,SACE,gBAAA,EAFW,EAEV,GAAD;AAAA,IACQ,MAAA;AAAA,IACN,GAAI;AAAA,IACJ,WAAW,EAGT,sFACA,+IAEA,gGACA,CACF;AAAA,cAXF,CAaE,gBAAA,EAAC,OAAD;AAAA,MACE,WAAW,EACT,oCACA,KAAW,QAAQ,OACrB;AAAA,gBAJF,CAMG,GACD,gBAAA,EAAC,OAAD;AAAA,QAAK,WAAU;AAAA,kBAAf,CACE,gBAAA,EAAC,OAAD;AAAA,UAAK,WAAU;AAAA,oBACZ,OAAO,KAAU,YAAY,OAAO,KAAU,WAC7C,gBAAA,EAAC,KAAD;AAAA,YAAG,WAAU;AAAA,sBACV;AAAA,UACA,CAAA,IAEH;AAAA,QAEC,CAAA,GACJ,IACC,gBAAA,EAAC,OAAD;AAAA,UAAK,WAAU;AAAA,oBACZ;AAAA,QACE,CAAA,IACH,IACD;AAAA,QACF;AAAA,QACL,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAU;AAAA,gBAAf,CACG,KAAY,OAAO,gBAAA,EAAC,OAAD;AAAA,QAAK,WAAU;AAAA,QAAW,UAAA;AAAA,MAAc,CAAA,IAAI,MAChE,gBAAA,EAAC,GAAD;AAAA,QACE,eAAA;AAAA,QACA,WAAU;AAAA,MACX,CAAA,CACE;AAAA,MACD;AAAA;AAEV;AA8DA,IAAa,KAAY;AAAA,EACvB,MAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,cAAA;AAAA,EACA,aAAA;AAAA,EACA,eAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,WAAA;AAAA,EACA,SAAA;AAAA,EACA,cAAA;AAAA,EACA,oBAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AACF"}