@pollinations/ui 0.1.0-alpha.7 → 0.1.0-alpha.9

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.
@@ -737,16 +737,12 @@ var defaultLabels = {
737
737
  };
738
738
  var CONNECT_SIZES = {
739
739
  md: {
740
- button: "polli:h-10",
741
- cell: "polli:w-10",
742
- mark: "polli:h-6 polli:w-6",
743
- label: "polli:px-3"
740
+ button: "polli:h-10 polli:px-4",
741
+ mark: "polli:h-5 polli:w-5"
744
742
  },
745
743
  lg: {
746
- button: "polli:h-12 polli:text-base",
747
- cell: "polli:w-12",
748
- mark: "polli:h-7 polli:w-7",
749
- label: "polli:px-4"
744
+ button: "polli:h-12 polli:px-5 polli:text-base",
745
+ mark: "polli:h-6 polli:w-6"
750
746
  }
751
747
  };
752
748
  function AppUserMenu({
@@ -808,31 +804,14 @@ function AppUserMenu({
808
804
  children: !isLoggedIn ? /* @__PURE__ */ jsxs8(
809
805
  LoginButton,
810
806
  {
807
+ intent: "brand",
811
808
  className: cn(
812
- "polli:gap-0 polli:overflow-hidden polli:border polli:border-theme-bg-active polli:bg-surface-white polli:p-0 polli:text-theme-text-strong polli:whitespace-nowrap polli:hover:bg-surface-white polli:[.dark_&]:bg-transparent polli:[.dark_&]:hover:bg-transparent",
809
+ "polli:gap-2 polli:py-0 polli:whitespace-nowrap",
813
810
  size.button
814
811
  ),
815
812
  children: [
816
- /* @__PURE__ */ jsx13(
817
- "span",
818
- {
819
- "aria-hidden": "true",
820
- className: cn(
821
- "polli:flex polli:h-full polli:shrink-0 polli:items-center polli:justify-center polli:bg-theme-bg-active",
822
- size.cell
823
- ),
824
- children: /* @__PURE__ */ jsx13(
825
- BrandMark,
826
- {
827
- className: cn(
828
- "polli:relative polli:-top-px polli:left-px",
829
- size.mark
830
- )
831
- }
832
- )
833
- }
834
- ),
835
- /* @__PURE__ */ jsx13("span", { className: size.label, children: labels2.authorize })
813
+ /* @__PURE__ */ jsx13(BrandMark, { className: size.mark }),
814
+ labels2.authorize
836
815
  ]
837
816
  }
838
817
  ) : /* @__PURE__ */ jsx13(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/modules/app-user-menu/AppUserMenu.tsx","../../src/compositions/AccountIdentity.tsx","../../src/lib/cn.ts","../../src/primitives/ChevronIcon.tsx","../../src/primitives/Dropdown.tsx","../../src/primitives/icons/index.tsx","../../src/primitives/BrandMark.tsx","../../src/primitives/DropdownItem.tsx","../../src/modules/auth/LoginButton.tsx","../../src/primitives/Button.tsx","../../src/primitives/Chip.tsx","../../src/lib/link.ts","../../src/primitives/InlineLink.tsx","../../src/modules/wallet/format-pollen.ts","../../src/modules/wallet/wallet-display.tsx","../../src/modules/wallet/AccountPollen.tsx"],"sourcesContent":["import {\n useAccountBalance,\n useAccountKey,\n useAccountProfile,\n useAuthActions,\n useAuthState,\n} from \"@pollinations/sdk/react\";\nimport { useEffect } from \"react\";\nimport { AccountMenu } from \"../../compositions/AccountMenu.tsx\";\nimport { cn } from \"../../lib/cn.ts\";\nimport { BrandMark } from \"../../primitives/BrandMark.tsx\";\nimport { DropdownItem } from \"../../primitives/DropdownItem.tsx\";\nimport {\n ExternalLinkIcon,\n KeyIcon,\n PowerIcon,\n WalletIcon,\n} from \"../../primitives/icons/index.tsx\";\nimport { LoginButton } from \"../auth/sdk.ts\";\nimport {\n AccountPollen,\n type AccountPollenSource,\n} from \"../wallet/AccountPollen.tsx\";\n\nexport type AppUserMenuLabels = {\n authorize: string;\n appUserMenu: string;\n permissions: string;\n buyPollen: string;\n logout: string;\n};\n\nexport type AppUserMenuProps = {\n /** Optional caller-owned dashboard destination for the linked avatar. */\n dashboardHref?: string;\n /** Larger logged-out action for prominent placements such as a page hero. */\n connectSize?: keyof typeof CONNECT_SIZES;\n labels?: Partial<AppUserMenuLabels>;\n};\n\nconst defaultLabels: AppUserMenuLabels = {\n authorize: \"Pollinations Connect\",\n appUserMenu: \"App user menu\",\n permissions: \"Permissions\",\n buyPollen: \"Buy Pollen\",\n logout: \"Disconnect\",\n};\n\nconst CONNECT_SIZES = {\n md: {\n button: \"polli:h-10\",\n cell: \"polli:w-10\",\n mark: \"polli:h-6 polli:w-6\",\n label: \"polli:px-3\",\n },\n lg: {\n button: \"polli:h-12 polli:text-base\",\n cell: \"polli:w-12\",\n mark: \"polli:h-7 polli:w-7\",\n label: \"polli:px-4\",\n },\n};\n\nexport function AppUserMenu({\n dashboardHref,\n connectSize = \"md\",\n labels: labelOverrides,\n}: AppUserMenuProps) {\n const labels = { ...defaultLabels, ...labelOverrides };\n const size = CONNECT_SIZES[connectSize];\n const { logout, enterUrl } = useAuthActions();\n const { isLoggedIn } = useAuthState();\n const profile = useAccountProfile({ enabled: isLoggedIn });\n const key = useAccountKey({ enabled: isLoggedIn });\n // The wallet is shown only for an unlimited key that may read it; ask only then.\n const canReadWallet =\n key.data?.pollenBudget === null &&\n (key.data.permissions?.account?.includes(\"usage\") ?? false);\n const balance = useAccountBalance({\n enabled: isLoggedIn && canReadWallet,\n });\n const wallet = balance.data?.accountBalance;\n useEffect(() => {\n if (!isLoggedIn) return;\n const onVisible = () => {\n if (document.visibilityState !== \"visible\") return;\n void key.refresh();\n void balance.refresh();\n };\n document.addEventListener(\"visibilitychange\", onVisible);\n return () =>\n document.removeEventListener(\"visibilitychange\", onVisible);\n }, [isLoggedIn, key.refresh, balance.refresh]);\n const returnUrl =\n typeof window === \"undefined\" ? undefined : window.location.href;\n const topUpUrl = new URL(\"/top-up\", enterUrl);\n if (returnUrl) topUpUrl.searchParams.set(\"redirect\", returnUrl);\n const keyId = key.data?.id;\n let editKeyUrl: URL | undefined;\n if (keyId) {\n editKeyUrl = new URL(\"/edit-key\", enterUrl);\n editKeyUrl.searchParams.set(\"id\", keyId);\n if (returnUrl) editKeyUrl.searchParams.set(\"redirect\", returnUrl);\n }\n let pollenSource: AccountPollenSource | undefined;\n if (key.data && key.data.pollenBudget !== null) {\n pollenSource = {\n type: \"budget\",\n remaining: key.data.pollenBudget,\n generationEnabled: key.data.permissions?.models?.length !== 0,\n };\n } else if (wallet) {\n pollenSource = {\n type: \"wallet\",\n balances: { paid: wallet.paid, quest: wallet.tier },\n };\n } else if (key.data && !canReadWallet) {\n pollenSource = { type: \"budget\", remaining: null };\n }\n\n return (\n <div\n data-theme=\"accent\"\n className=\"polli:flex polli:shrink-0 polli:justify-end\"\n >\n {!isLoggedIn ? (\n <LoginButton\n className={cn(\n \"polli:gap-0 polli:overflow-hidden polli:border polli:border-theme-bg-active polli:bg-surface-white polli:p-0 polli:text-theme-text-strong polli:whitespace-nowrap polli:hover:bg-surface-white polli:[.dark_&]:bg-transparent polli:[.dark_&]:hover:bg-transparent\",\n size.button,\n )}\n >\n {/* Amber cell with the mark, then a light cell with the label. */}\n <span\n aria-hidden=\"true\"\n className={cn(\n \"polli:flex polli:h-full polli:shrink-0 polli:items-center polli:justify-center polli:bg-theme-bg-active\",\n size.cell,\n )}\n >\n <BrandMark\n className={cn(\n \"polli:relative polli:-top-px polli:left-px\",\n size.mark,\n )}\n />\n </span>\n <span className={size.label}>{labels.authorize}</span>\n </LoginButton>\n ) : (\n <AccountMenu\n name={\n profile.data?.name ||\n profile.data?.githubUsername ||\n \"Connected user\"\n }\n avatarUrl={profile.data?.image}\n dashboardHref={\n dashboardHref ?? new URL(\"/pollen\", enterUrl).href\n }\n menuLabel={labels.appUserMenu}\n className=\"polli:max-w-80\"\n secondaryContent={\n pollenSource ? (\n <AccountPollen source={pollenSource} />\n ) : undefined\n }\n >\n {(close) => (\n <>\n {editKeyUrl && (\n <DropdownItem\n as=\"a\"\n href={editKeyUrl.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={close}\n >\n <KeyIcon\n className=\"polli:h-4 polli:w-4 polli:shrink-0\"\n aria-hidden=\"true\"\n />\n {labels.permissions}\n <ExternalLinkIcon\n className=\"polli:ml-auto polli:h-3.5 polli:w-3.5 polli:shrink-0\"\n aria-hidden=\"true\"\n />\n </DropdownItem>\n )}\n <DropdownItem\n as=\"a\"\n href={topUpUrl.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={close}\n >\n <WalletIcon\n className=\"polli:h-4 polli:w-4 polli:shrink-0\"\n aria-hidden=\"true\"\n />\n {labels.buyPollen}\n <ExternalLinkIcon\n className=\"polli:ml-auto polli:h-3.5 polli:w-3.5 polli:shrink-0\"\n aria-hidden=\"true\"\n />\n </DropdownItem>\n <DropdownItem\n type=\"button\"\n className=\"polli:justify-start polli:text-left\"\n onClick={() => {\n close();\n logout();\n }}\n >\n <PowerIcon\n className=\"polli:h-4 polli:w-4 polli:shrink-0\"\n aria-hidden=\"true\"\n />\n {labels.logout}\n </DropdownItem>\n </>\n )}\n </AccountMenu>\n )}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { useId } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport { ChevronIcon } from \"../primitives/ChevronIcon.tsx\";\nimport { Dropdown, type DropdownProps } from \"../primitives/Dropdown.tsx\";\nimport { ExternalLinkIcon } from \"../primitives/icons/index.tsx\";\n\nfunction initials(name: string) {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return \"?\";\n if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();\n return `${parts[0][0] ?? \"\"}${parts.at(-1)?.[0] ?? \"\"}`.toUpperCase();\n}\n\nfunction AccountAvatar({\n name,\n avatarUrl,\n secondaryContent,\n dashboardHref,\n inline = false,\n}: {\n name: string;\n avatarUrl?: string | null;\n secondaryContent?: ReactNode;\n dashboardHref?: string;\n /** Small avatar inside a pill link; hovering the pill zooms it. */\n inline?: boolean;\n}) {\n const size = inline\n ? \"polli:h-6 polli:w-6\"\n : secondaryContent != null\n ? \"polli:h-11 polli:w-11\"\n : \"polli:h-8 polli:w-8\";\n const className = cn(\n size,\n inline &&\n \"polli:transition-transform polli:group-hover:scale-110 polli:group-hover:brightness-110 polli:motion-reduce:transition-none polli:motion-reduce:group-hover:scale-100\",\n );\n const avatar = avatarUrl ? (\n <img\n src={avatarUrl}\n alt=\"\"\n className={cn(\n className,\n \"polli:shrink-0 polli:rounded-full polli:object-cover\",\n )}\n />\n ) : (\n <span\n role=\"img\"\n aria-label={`${name} avatar`}\n className={cn(\n className,\n \"polli:flex polli:shrink-0 polli:items-center polli:justify-center polli:rounded-full polli:bg-theme-bg-pale polli:text-xs polli:font-semibold polli:text-theme-text-strong\",\n )}\n >\n {initials(name)}\n </span>\n );\n return dashboardHref ? (\n <a\n href={dashboardHref}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label=\"Open dashboard\"\n title=\"Open dashboard\"\n className=\"polli:shrink-0 polli:rounded-full polli:cursor-pointer polli:transition-transform polli:hover:scale-105 polli:hover:brightness-110 polli:focus-visible:outline-2 polli:focus-visible:outline-offset-2 polli:focus-visible:outline-current polli:motion-reduce:transition-none polli:motion-reduce:hover:scale-100\"\n >\n {avatar}\n </a>\n ) : (\n avatar\n );\n}\n\nexport type AccountIdentityProps = {\n name: string;\n avatarUrl?: string | null;\n secondaryContent?: ReactNode;\n /** Optional dashboard destination, owned by the caller. Opens in a new tab. */\n dashboardHref?: string;\n className?: string;\n};\n\nexport type AccountIdentityLinkProps = Pick<\n AccountIdentityProps,\n \"name\" | \"avatarUrl\" | \"className\"\n> & {\n /** External profile the whole pill opens in a new tab. */\n href: string;\n};\n\nexport function AccountIdentity({\n name,\n avatarUrl,\n secondaryContent,\n dashboardHref,\n className,\n}: AccountIdentityProps) {\n return (\n <span\n className={cn(\n \"polli:flex polli:min-w-0 polli:items-center polli:gap-2 polli:rounded-full polli:bg-surface-opaque polli:p-1 polli:pr-3\",\n className,\n )}\n >\n <AccountAvatar\n name={name}\n avatarUrl={avatarUrl}\n dashboardHref={dashboardHref}\n secondaryContent={secondaryContent}\n />\n <AccountDetails name={name} secondaryContent={secondaryContent} />\n </span>\n );\n}\n\n/** Someone else's identity as a one-line pill link, e.g. an app's developer. */\nexport function AccountIdentityLink({\n name,\n avatarUrl,\n href,\n className,\n}: AccountIdentityLinkProps) {\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={cn(\n // Sits in running text on cards, so it is compact and tinted.\n \"polli:group polli:inline-flex polli:max-w-full polli:min-w-0 polli:items-center polli:gap-1.5 polli:rounded-full polli:bg-theme-bg-subtle polli:p-0.5 polli:pr-2.5 polli:align-middle polli:focus-visible:outline-2 polli:focus-visible:outline-offset-2 polli:focus-visible:outline-current\",\n className,\n )}\n >\n <AccountAvatar name={name} avatarUrl={avatarUrl} inline />\n <AccountDetails name={name} />\n {/* InlineLink's external arrow at the name's size: this pill leaves the app. */}\n <ExternalLinkIcon\n aria-hidden=\"true\"\n className=\"polli:-ml-0.5 polli:h-3 polli:w-3 polli:shrink-0 polli:text-theme-text-strong polli:opacity-65\"\n />\n </a>\n );\n}\n\nfunction AccountDetails({\n name,\n secondaryContent,\n secondaryId,\n}: {\n name: string;\n secondaryContent?: ReactNode;\n secondaryId?: string;\n}) {\n return (\n <span className=\"polli:flex polli:min-w-0 polli:flex-col polli:items-start polli:text-left\">\n <span\n title={name}\n className=\"polli:max-w-full polli:truncate polli:text-sm polli:font-medium polli:leading-5 polli:text-theme-text-strong\"\n >\n {name}\n </span>\n {secondaryContent != null && (\n <span\n id={secondaryId}\n className=\"polli:inline-flex polli:min-h-5 polli:items-center polli:whitespace-nowrap polli:text-xs polli:leading-4 polli:text-theme-text-base\"\n >\n {secondaryContent}\n </span>\n )}\n </span>\n );\n}\n\nexport type AccountMenuProps = AccountIdentityProps & {\n /** The caller owns navigation, permissions and sign-out behavior. */\n children: DropdownProps[\"children\"];\n menuClassName?: string;\n side?: \"top\" | \"bottom\";\n menuLabel?: string;\n};\n\n/**\n * With `dashboardHref` the avatar is a link and the name/chevron open the\n * menu; without one the whole pill is the trigger.\n */\nexport function AccountMenu({\n name,\n avatarUrl,\n dashboardHref,\n secondaryContent,\n children,\n className,\n menuClassName,\n side = \"bottom\",\n menuLabel = `Account menu for ${name}`,\n}: AccountMenuProps) {\n const statusId = useId();\n const avatar = (\n <AccountAvatar\n name={name}\n avatarUrl={avatarUrl}\n dashboardHref={dashboardHref}\n secondaryContent={secondaryContent}\n />\n );\n\n return (\n <div\n data-theme=\"accent\"\n className={cn(\n \"polli:flex polli:min-w-0 polli:items-center polli:gap-2 polli:rounded-full polli:bg-theme-bg-active polli:p-1 polli:pr-3 polli:text-theme-text-strong polli:transition-colors polli:hover:bg-theme-bg-hover\",\n className,\n )}\n >\n {dashboardHref && avatar}\n <Dropdown\n align=\"end\"\n side={side}\n className={cn(\n \"polli:w-max polli:min-w-[var(--reference-width)] polli:p-1\",\n menuClassName,\n )}\n trigger={(open) => (\n <button\n type=\"button\"\n aria-label={menuLabel}\n aria-describedby={\n secondaryContent != null ? statusId : undefined\n }\n className=\"polli-control polli:flex polli:min-w-0 polli:flex-1 polli:items-center polli:gap-2 polli:self-stretch polli:rounded-full polli:text-theme-text-strong\"\n >\n {!dashboardHref && avatar}\n <AccountDetails\n name={name}\n secondaryContent={secondaryContent}\n secondaryId={statusId}\n />\n <ChevronIcon\n expanded={open}\n className=\"polli:ml-auto polli:h-4 polli:w-4 polli:text-theme-text-strong\"\n />\n </button>\n )}\n >\n {children}\n </Dropdown>\n </div>\n );\n}\n","import { clsx } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({ prefix: \"polli\" });\n\n/** Internal class merge for polli:-prefixed package primitive classes. */\nexport function cn(...inputs: (string | undefined | null | false)[]) {\n return twMerge(clsx(...inputs));\n}\n","import type { FC } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\n\ntype ChevronIconProps = {\n /** Rotate 180° when expanded/open. */\n expanded?: boolean;\n className?: string;\n};\n\n/**\n * Canonical chevron used for collapsibles, dropdown triggers, and select pills\n * across the app. One icon everywhere.\n */\nexport const ChevronIcon: FC<ChevronIconProps> = ({ expanded, className }) => (\n <svg\n aria-hidden=\"true\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n className={cn(\n \"polli:shrink-0 polli:transition-transform polli:duration-200 polli:ease-out\",\n expanded && \"polli:rotate-180\",\n className,\n )}\n >\n <path\n d=\"M3 4.5 6 7.5l3-3\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"1.5\"\n />\n </svg>\n);\n","import { Popover } from \"@ark-ui/react/popover\";\nimport { Portal } from \"@ark-ui/react/portal\";\nimport type { CSSProperties, FC, ReactNode } from \"react\";\nimport { useId, useState } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\n\nconst DEFAULT_PANEL = \"polli:rounded-lg polli:bg-surface-menu polli:shadow-lg\";\n\nexport type DropdownProps = {\n /** Trigger element; receives the current open state (e.g. to rotate a chevron). */\n trigger: (open: boolean) => ReactNode;\n /** Panel content. As a function, receives `close` to dismiss after a selection. */\n children: ReactNode | ((close: () => void) => ReactNode);\n /** Panel placement relative to the trigger. */\n align?: \"start\" | \"end\";\n side?: \"top\" | \"bottom\";\n /** Controlled open state. Omit to let the Dropdown manage its own. */\n open?: boolean;\n /** Render inside the parent dialog so its focus and accessibility scope includes the menu. */\n portalled?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Appended after the surface (widths, padding, max-height…). */\n className?: string;\n /** Theme variables for portaled content that cannot inherit from its trigger. */\n panelStyle?: CSSProperties;\n};\n\nexport const Dropdown: FC<DropdownProps> = ({\n trigger,\n children,\n align = \"start\",\n side = \"bottom\",\n open: openProp,\n portalled = true,\n onOpenChange,\n className,\n panelStyle,\n}) => {\n const triggerId = useId();\n const [internalOpen, setInternalOpen] = useState(false);\n const isControlled = openProp !== undefined;\n const open = isControlled ? openProp : internalOpen;\n\n const setOpen = (next: boolean) => {\n if (!isControlled) setInternalOpen(next);\n onOpenChange?.(next);\n };\n\n return (\n <Popover.Root\n ids={{ trigger: triggerId }}\n open={open}\n portalled={portalled}\n onOpenChange={(details) => setOpen(details.open)}\n positioning={{\n placement: `${side}-${align}`,\n strategy: portalled ? \"absolute\" : \"fixed\",\n }}\n >\n <Popover.Trigger asChild>{trigger(open)}</Popover.Trigger>\n <Portal disabled={!portalled}>\n <Popover.Positioner>\n <Popover.Content\n aria-labelledby={triggerId}\n style={panelStyle}\n className={cn(\n \"polli:z-[120] polli:overflow-hidden polli:focus:outline-none\",\n DEFAULT_PANEL,\n className,\n )}\n >\n {typeof children === \"function\"\n ? children(() => setOpen(false))\n : children}\n </Popover.Content>\n </Popover.Positioner>\n </Portal>\n </Popover.Root>\n );\n};\n","import type { IconProps } from \"./types.ts\";\n\nconst strokeProps = {\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n} as const;\n\nexport function AppIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <rect x=\"2\" y=\"4\" width=\"20\" height=\"14\" rx=\"2\" />\n <path d=\"M2 20h20\" />\n </svg>\n );\n}\n\nexport function AccountIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <circle cx=\"12\" cy=\"8\" r=\"4\" />\n <path d=\"M4 21a8 8 0 0 1 16 0\" />\n </svg>\n );\n}\n\nexport function ArrowRightIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M5 12h14M13 6l6 6-6 6\" />\n </svg>\n );\n}\n\nexport function BeakerIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M9 3h6\" />\n <path d=\"M10 3v6.5L4.5 18a2 2 0 0 0 1.7 3h11.6a2 2 0 0 0 1.7-3L14 9.5V3\" />\n <path d=\"M7 14h10\" />\n </svg>\n );\n}\n\nexport function BotIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M12 8V4H8\" />\n <rect x=\"4\" y=\"8\" width=\"16\" height=\"12\" rx=\"2\" />\n <path d=\"M2 14h2M20 14h2\" />\n <path d=\"M9 13v2M15 13v2\" />\n </svg>\n );\n}\n\nexport function BookIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M4 4h5a3 3 0 0 1 3 3v13a2 2 0 0 0-2-2H4z\" />\n <path d=\"M20 4h-5a3 3 0 0 0-3 3v13a2 2 0 0 1 2-2h6z\" />\n </svg>\n );\n}\n\nexport function BugIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"m8 2 1.9 1.9M14.1 3.9 16 2\" />\n <path d=\"M9 7V6a3 3 0 0 1 6 0v1\" />\n <path d=\"M12 20c-3.3 0-6-2.7-6-6v-3a6 6 0 0 1 12 0v3c0 3.3-2.7 6-6 6Z\" />\n <path d=\"M12 20v-9M6.5 9C4.6 8.8 3 7.1 3 5M6 13H2M3 21c0-2.1 1.7-3.9 3.8-4M17.5 9C19.4 8.8 21 7.1 21 5M18 13h4M21 21c0-2.1-1.7-3.9-3.8-4\" />\n </svg>\n );\n}\n\nexport function CheckIcon(props: IconProps) {\n return (\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n {...strokeProps}\n strokeWidth={2.5}\n {...props}\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n );\n}\n\nexport function ClipboardIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" />\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n </svg>\n );\n}\n\nexport function ClockIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M12 7v5l3 2\" />\n </svg>\n );\n}\n\nexport function DiscordIcon(props: IconProps) {\n return (\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" {...props}>\n <path\n fill=\"currentColor\"\n d=\"M20.32 4.37A19.8 19.8 0 0 0 15.36 2.83a.07.07 0 0 0-.08.04c-.21.38-.45.88-.62 1.27a18.27 18.27 0 0 0-5.52 0 12.84 12.84 0 0 0-.63-1.27.08.08 0 0 0-.08-.04A19.74 19.74 0 0 0 3.47 4.37a.07.07 0 0 0-.03.03C.31 9.07-.55 13.61-.13 18.1a.08.08 0 0 0 .03.06 19.9 19.9 0 0 0 6.08 3.07.08.08 0 0 0 .09-.03c.47-.64.88-1.31 1.24-2.02a.08.08 0 0 0-.04-.1 13.08 13.08 0 0 1-1.9-.91.08.08 0 0 1-.01-.13c.13-.1.25-.2.37-.29a.07.07 0 0 1 .08-.01 14.24 14.24 0 0 0 12.38 0 .07.07 0 0 1 .08.01c.12.1.25.2.38.3a.08.08 0 0 1-.01.12 12.22 12.22 0 0 1-1.9.9.08.08 0 0 0-.04.11c.36.7.77 1.38 1.23 2.02a.08.08 0 0 0 .1.03 19.84 19.84 0 0 0 6.08-3.07.08.08 0 0 0 .03-.05c.5-5.2-.84-9.7-3.77-13.71a.06.06 0 0 0-.03-.03ZM8.02 15.37c-1.18 0-2.16-1.08-2.16-2.4 0-1.32.96-2.4 2.16-2.4 1.2 0 2.18 1.09 2.16 2.4 0 1.32-.96 2.4-2.16 2.4Zm7.96 0c-1.18 0-2.16-1.08-2.16-2.4 0-1.32.96-2.4 2.16-2.4 1.2 0 2.18 1.09 2.16 2.4 0 1.32-.95 2.4-2.16 2.4Z\"\n />\n </svg>\n );\n}\n\nexport function InstagramIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"5\" />\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <circle\n cx=\"17.5\"\n cy=\"6.5\"\n r=\"1\"\n fill=\"currentColor\"\n stroke=\"none\"\n />\n </svg>\n );\n}\n\nexport function XSocialIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...props}>\n <path\n fill=\"currentColor\"\n d=\"M18.24 2.25h3.31l-7.23 8.26 8.51 11.24h-6.66l-5.21-6.82-5.97 6.82H1.68l7.73-8.84L1.25 2.25h6.83l4.71 6.23 5.45-6.23Zm-1.16 17.52h1.83L7.08 4.13H5.12l11.96 15.64Z\"\n />\n </svg>\n );\n}\n\nexport function LinkedInIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...props}>\n <path\n fill=\"currentColor\"\n d=\"M20.45 20.45h-3.56v-5.57c0-1.33-.03-3.04-1.85-3.04-1.86 0-2.14 1.45-2.14 2.94v5.67H9.34V9h3.42v1.56h.05c.47-.9 1.64-1.85 3.37-1.85 3.6 0 4.27 2.37 4.27 5.46v6.28ZM5.32 7.43a2.07 2.07 0 1 1 0-4.13 2.07 2.07 0 0 1 0 4.13ZM7.1 20.45H3.54V9H7.1v11.45Z\"\n />\n </svg>\n );\n}\n\nexport function DownloadIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"7 10 12 15 17 10\" />\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\" />\n </svg>\n );\n}\n\nexport function ExpandIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M8 3H3v5M16 3h5v5M21 16v5h-5M3 16v5h5\" />\n </svg>\n );\n}\n\nexport function PlayIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...props}>\n <path fill=\"currentColor\" d=\"M7 4.5v15l12-7.5z\" />\n </svg>\n );\n}\n\nexport function PauseIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...props}>\n <path fill=\"currentColor\" d=\"M6 4h4v16H6zM14 4h4v16h-4z\" />\n </svg>\n );\n}\n\nexport function CloudUploadIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M17.5 19H19a4 4 0 0 0 .4-8A7.5 7.5 0 0 0 5 9.5 5 5 0 0 0 6 19h1.5\" />\n <path d=\"m8.5 15.5 3.5-3.5 3.5 3.5M12 12v9\" />\n </svg>\n );\n}\n\nexport function ExternalLinkIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M7 17 17 7M9 7h8v8\" />\n </svg>\n );\n}\n\nexport function GenApiIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"m8 3 4 1.5L16 3v18l-4-1.5L8 21z\" />\n <path d=\"M8 3v18M16 3v18\" />\n </svg>\n );\n}\n\nexport function GitBranchIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <line x1=\"6\" y1=\"3\" x2=\"6\" y2=\"15\" />\n <circle cx=\"18\" cy=\"6\" r=\"3\" />\n <circle cx=\"6\" cy=\"18\" r=\"3\" />\n <path d=\"M18 9a9 9 0 0 1-9 9\" />\n </svg>\n );\n}\n\nexport function GitPullRequestIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <circle cx=\"6\" cy=\"6\" r=\"3\" />\n <circle cx=\"18\" cy=\"18\" r=\"3\" />\n <path d=\"M6 9v12M13 6h3a2 2 0 0 1 2 2v7\" />\n </svg>\n );\n}\n\nexport function GraduationCapIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M21.42 10.92a1 1 0 0 0-.02-1.84L12.83 5.18a2 2 0 0 0-1.66 0L2.6 9.08a1 1 0 0 0 0 1.83l8.57 3.91a2 2 0 0 0 1.66 0z\" />\n <path d=\"M22 10v6\" />\n <path d=\"M6 12.5V16a6 3 0 0 0 12 0v-3.5\" />\n </svg>\n );\n}\n\nexport function SparklesIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M12 3l1.9 5.8a2 2 0 0 0 1.3 1.3L21 12l-5.8 1.9a2 2 0 0 0-1.3 1.3L12 21l-1.9-5.8a2 2 0 0 0-1.3-1.3L3 12l5.8-1.9a2 2 0 0 0 1.3-1.3z\" />\n </svg>\n );\n}\n\nexport function GitHubIcon(props: IconProps) {\n return (\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" {...props}>\n <path\n fill=\"currentColor\"\n d=\"M12 .5A11.5 11.5 0 0 0 8.36 22.9c.58.11.79-.25.79-.56v-2.16c-3.21.7-3.89-1.38-3.89-1.38-.53-1.34-1.29-1.7-1.29-1.7-1.05-.72.08-.7.08-.7 1.16.08 1.77 1.19 1.77 1.19 1.04 1.76 2.71 1.25 3.37.96.11-.75.4-1.25.74-1.54-2.56-.29-5.26-1.28-5.26-5.7 0-1.26.45-2.29 1.19-3.1-.12-.29-.52-1.46.11-3.06 0 0 .97-.31 3.16 1.18a10.88 10.88 0 0 1 5.76 0c2.19-1.49 3.15-1.18 3.15-1.18.63 1.6.23 2.77.11 3.06.74.81 1.19 1.84 1.19 3.1 0 4.43-2.7 5.4-5.27 5.69.41.36.78 1.06.78 2.14v3.19c0 .31.21.68.8.56A11.5 11.5 0 0 0 12 .5Z\"\n />\n </svg>\n );\n}\n\nexport function ImageIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n <circle cx=\"9\" cy=\"9\" r=\"2\" />\n <path d=\"m21 15-5-5L5 21\" />\n </svg>\n );\n}\n\nexport function CubeIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"m21 16-9 5-9-5V8l9-5 9 5z\" />\n <path d=\"m3 8 9 5 9-5\" />\n <path d=\"M12 13v8\" />\n </svg>\n );\n}\n\nexport function AudioIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M9 18V5l12-2v13\" />\n <circle cx=\"6\" cy=\"18\" r=\"3\" />\n <circle cx=\"18\" cy=\"16\" r=\"3\" />\n </svg>\n );\n}\n\nexport function LockIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\" />\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\" />\n </svg>\n );\n}\n\nexport function LogInIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M10 17l5-5-5-5\" />\n <path d=\"M15 12H3\" />\n <path d=\"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4\" />\n </svg>\n );\n}\n\nexport function LogOutIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" />\n <path d=\"m16 17 5-5-5-5\" />\n <path d=\"M21 12H9\" />\n </svg>\n );\n}\n\nexport function MailIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n <path d=\"m3 7 9 7 9-7\" />\n </svg>\n );\n}\n\nexport function McpIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <rect x=\"2\" y=\"4\" width=\"8\" height=\"16\" rx=\"1.5\" />\n <rect x=\"14\" y=\"4\" width=\"8\" height=\"16\" rx=\"1.5\" />\n <path d=\"M10 12h4\" />\n </svg>\n );\n}\n\nexport function MenuIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M4 7h16M4 12h16M4 17h16\" />\n </svg>\n );\n}\n\nexport function NewspaperIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M5 4h12a1 1 0 0 1 1 1v14a1 1 0 0 0 1 1H4a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1h1z\" />\n <path d=\"M18 8h2a1 1 0 0 1 1 1v9a2 2 0 0 1-2 2\" />\n <path d=\"M7 8h7M7 12h7M7 16h4\" />\n </svg>\n );\n}\n\nexport function PlusIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M12 5v14M5 12h14\" />\n </svg>\n );\n}\n\nexport function TerminalIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <polyline points=\"4 8 8 12 4 16\" />\n <line x1=\"12\" y1=\"20\" x2=\"20\" y2=\"20\" />\n </svg>\n );\n}\n\nexport function ToolIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M14.7 6.3a1 1 0 0 0 0 1.4l2.1 2.1a1 1 0 0 0 1.4 0l4-4a6 6 0 0 1-8 8l-8 8a2.8 2.8 0 0 1-4-4l8-8a6 6 0 0 1 8-8l-4 4Z\" />\n </svg>\n );\n}\n\nexport function TargetIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <circle cx=\"12\" cy=\"12\" r=\"5\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.6\" fill=\"currentColor\" stroke=\"none\" />\n </svg>\n );\n}\n\nexport function TokensIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M4 9h16M4 15h16M10 3 8 21M16 3l-2 18\" />\n </svg>\n );\n}\n\nexport function UsageIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M4 18a8 8 0 1 1 16 0\" />\n <path d=\"M12 18l3.5-5\" />\n <path d=\"M7 18h10\" />\n <path d=\"M7.5 12.5 6 11\" />\n <path d=\"M16.5 12.5 18 11\" />\n </svg>\n );\n}\n\nexport function WarningIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M10.3 3.1 1.8 17a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.1a2 2 0 0 0-3.4 0Z\" />\n <path d=\"M12 9v4M12 17h.01\" />\n </svg>\n );\n}\n\nexport function TrendUpIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <polyline points=\"3 17 9 11 13 15 21 7\" />\n <polyline points=\"15 7 21 7 21 13\" />\n </svg>\n );\n}\n\nexport function EarningsIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <ellipse cx=\"10\" cy=\"6\" rx=\"6\" ry=\"3\" />\n <path d=\"M4 6v8c0 1.7 2.7 3 6 3 1.2 0 2.4-.2 3.3-.5\" />\n <path d=\"M16 6v4\" />\n <path d=\"M4 10c0 1.7 2.7 3 6 3 1.1 0 2.1-.1 3-.4\" />\n <path d=\"M18 14v6\" />\n <path d=\"M15 17h6\" />\n </svg>\n );\n}\n\nexport function WalletIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M3 7a2 2 0 0 1 2-2h13a2 2 0 0 1 2 2v2H5a2 2 0 0 0-2 2V7Z\" />\n <path d=\"M3 11a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-6Z\" />\n <circle cx=\"17\" cy=\"14\" r=\"1.25\" fill=\"currentColor\" />\n </svg>\n );\n}\n\n/** A paper receipt: what a price includes. */\nexport function ReceiptIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M6 3h12v18l-2-1.5-2 1.5-2-1.5-2 1.5-2-1.5L6 21Z\" />\n <path d=\"M9 8h6M9 12h6M9 16h3\" />\n </svg>\n );\n}\n\nexport function MoonIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8Z\" />\n </svg>\n );\n}\n\nexport function SunIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <path d=\"M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4\" />\n </svg>\n );\n}\n\nexport function XIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n );\n}\n\nexport function TrashIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M3 6h18\" />\n <path d=\"M8 6V4h8v2\" />\n <path d=\"m19 6-1 15H6L5 6\" />\n <path d=\"M10 11v6M14 11v6\" />\n </svg>\n );\n}\n\n// --- Model modality / capability / price glyphs (single-ink, replace emoji) ---\n\nexport function ChatIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n );\n}\n\nexport function RobotIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <rect x=\"3\" y=\"6\" width=\"18\" height=\"15\" rx=\"3\" />\n <path d=\"M12 2v4M3 11H1v5h2M21 11h2v5h-2M8 17h8\" />\n <circle cx=\"9\" cy=\"12\" r=\"1\" />\n <circle cx=\"15\" cy=\"12\" r=\"1\" />\n </svg>\n );\n}\n\nexport function EyeIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n );\n}\n\nexport function EyeOffIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n <path d=\"M3 3l18 18\" />\n </svg>\n );\n}\n\nexport function VideoIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"m22 8-6 4 6 4V8z\" />\n <rect x=\"2\" y=\"6\" width=\"14\" height=\"12\" rx=\"2\" />\n </svg>\n );\n}\n\nexport function MicIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3z\" />\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\" />\n <path d=\"M12 19v3\" />\n </svg>\n );\n}\n\nexport function SpeakerIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M11 5 6 9H2v6h4l5 4z\" />\n <path d=\"M15.54 8.46a5 5 0 0 1 0 7.07\" />\n <path d=\"M19.07 4.93a10 10 0 0 1 0 14.14\" />\n </svg>\n );\n}\n\nexport function MegaphoneIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"m3 11 18-5v12L3 14v-3z\" />\n <path d=\"m7 15 1.5 6H14l-2-7\" />\n </svg>\n );\n}\n\nexport function ReasoningIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M9 18h6M10 22h4M15.1 14c.2-1 .6-1.7 1.4-2.5A4.6 4.6 0 0 0 18 8 6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.8.8 1.2 1.5 1.4 2.5\" />\n </svg>\n );\n}\n\nexport function RocketIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z\" />\n <path d=\"m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z\" />\n <path d=\"M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0\" />\n <path d=\"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5\" />\n </svg>\n );\n}\n\nexport function SearchIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m21 21-4.3-4.3\" />\n </svg>\n );\n}\n\nexport function SignOutIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" />\n <path d=\"m16 17 5-5-5-5\" />\n <path d=\"M21 12H9\" />\n </svg>\n );\n}\n\nexport function PowerIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M12 2v10\" />\n <path d=\"M18.4 6.6a9 9 0 1 1-12.77.04\" />\n </svg>\n );\n}\n\nexport function SparkleIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M9.94 15.5A2 2 0 0 0 8.5 14.06l-6.14-1.58a.5.5 0 0 1 0-.96L8.5 9.94A2 2 0 0 0 9.94 8.5l1.58-6.14a.5.5 0 0 1 .96 0L14.06 8.5A2 2 0 0 0 15.5 9.94l6.14 1.58a.5.5 0 0 1 0 .96L15.5 14.06a2 2 0 0 0-1.44 1.44l-1.58 6.14a.5.5 0 0 1-.96 0z\" />\n <path d=\"M20 3v4\" />\n <path d=\"M22 5h-4\" />\n <path d=\"M4 17v2\" />\n <path d=\"M5 18H3\" />\n </svg>\n );\n}\n\nexport function StarIcon({\n filled = false,\n ...props\n}: IconProps & { filled?: boolean }) {\n return (\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n {...strokeProps}\n fill={filled ? \"currentColor\" : \"none\"}\n {...props}\n >\n <polygon points=\"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2\" />\n </svg>\n );\n}\n\nexport function CodeIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"m16 18 6-6-6-6M8 6l-6 6 6 6\" />\n </svg>\n );\n}\n\nexport function DatabaseIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\" />\n <path d=\"M3 5v14a9 3 0 0 0 18 0V5\" />\n <path d=\"M3 12a9 3 0 0 0 18 0\" />\n </svg>\n );\n}\n\nexport function CardIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <rect x=\"2\" y=\"5\" width=\"20\" height=\"14\" rx=\"2\" />\n <path d=\"M2 10h20\" />\n </svg>\n );\n}\n\nexport function SproutIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M7 20h10\" />\n <path d=\"M10 20c5.5-2.5.8-6.4 3-10\" />\n <path d=\"M9.5 9.4c1.1.8 1.8 2.2 2.3 3.7-2 .4-3.5.4-4.8-.3-1.2-.6-2.3-1.9-3-4.2 2.8-.5 4.4 0 5.5.8z\" />\n <path d=\"M14.1 6a7 7 0 0 0-1.1 4c1.9-.1 3.3-.6 4.3-1.4 1-1 1.6-2.3 1.7-4.6-2.7.1-4 1-4.9 2z\" />\n </svg>\n );\n}\n\nexport function PencilIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M12 20h9\" />\n <path d=\"M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z\" />\n </svg>\n );\n}\n\nexport function KeyIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <circle cx=\"7.5\" cy=\"15.5\" r=\"5.5\" />\n <path d=\"m21 2-9.6 9.6\" />\n <path d=\"m15.5 7.5 3 3L22 7l-3-3\" />\n </svg>\n );\n}\n\nexport function GlobeIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20\" />\n <path d=\"M2 12h20\" />\n </svg>\n );\n}\n\nexport function ArrowLeftIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M19 12H5\" />\n <path d=\"m12 19-7-7 7-7\" />\n </svg>\n );\n}\n\nexport function RefreshIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M21 12a9 9 0 1 1-2.64-6.36\" />\n <path d=\"M21 3v6h-6\" />\n </svg>\n );\n}\n\nexport type { IconProps } from \"./types.ts\";\n","import type { CSSProperties } from \"react\";\nimport lockupUrl from \"../brand/lockup-horizontal.svg\";\nimport markUrl from \"../brand/mark.svg\";\nimport { cn } from \"../lib/cn.ts\";\n\nexport type BrandMarkProps = {\n variant?: \"mark\" | \"lockup\";\n className?: string;\n};\n\nconst mask = (url: string): CSSProperties => ({\n WebkitMask: `url('${url}') center / contain no-repeat`,\n mask: `url('${url}') center / contain no-repeat`,\n});\n\nconst MASKS = { mark: mask(markUrl), lockup: mask(lockupUrl) };\n\n/** The lotus (or lotus + wordmark) painted in currentColor; size it with className. */\nexport function BrandMark({ variant = \"mark\", className }: BrandMarkProps) {\n return (\n <span\n aria-hidden=\"true\"\n className={cn(\n \"polli:block polli:shrink-0 polli:bg-current\",\n className,\n )}\n style={MASKS[variant]}\n />\n );\n}\n","import type { PropsWithChildren } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\n\ntype BaseDropdownItemProps = {\n className?: string;\n};\n\nexport type DropdownItemProps<T extends React.ElementType = \"button\"> =\n PropsWithChildren<BaseDropdownItemProps> & {\n as?: T;\n } & Omit<\n React.ComponentPropsWithoutRef<T>,\n keyof BaseDropdownItemProps | \"as\"\n >;\n\nexport function DropdownItem<T extends React.ElementType = \"button\">({\n as,\n className,\n children,\n ...rest\n}: DropdownItemProps<T>) {\n const Component: React.ElementType = as || \"button\";\n return (\n <Component\n {...(Component === \"button\" ? { type: \"button\" } : undefined)}\n {...rest}\n className={cn(\n \"polli-control polli:flex polli:w-full polli:cursor-pointer polli:items-center polli:gap-2 polli:rounded-lg polli:bg-transparent polli:px-3 polli:py-2 polli:text-left polli:text-sm polli:font-medium polli:text-theme-text-base polli:no-underline polli:transition-colors polli:hover:bg-theme-bg-hover polli:hover:text-theme-text-hover polli:focus-visible:bg-theme-bg-hover\",\n className,\n )}\n >\n {children}\n </Component>\n );\n}\n","import { useAuthActions, useAuthState } from \"@pollinations/sdk/react\";\nimport type { ReactNode } from \"react\";\nimport { Button, type ButtonProps } from \"../../primitives/Button.tsx\";\n\nexport type LoginButtonProps = Omit<\n ButtonProps<\"button\">,\n \"as\" | \"onClick\" | \"children\"\n> & {\n children: ReactNode;\n};\n\n/** Button that kicks off the auth redirect. `null` when already logged in. */\nexport function LoginButton({ children, ...buttonProps }: LoginButtonProps) {\n const { isLoggedIn } = useAuthState();\n const { login } = useAuthActions();\n if (isLoggedIn) return null;\n return (\n <Button {...buttonProps} onClick={() => login()}>\n {children}\n </Button>\n );\n}\n","import type {\n PropsWithChildren,\n MouseEvent as ReactMouseEvent,\n ReactNode,\n} from \"react\";\nimport { cn } from \"../lib/cn.ts\";\n\n/** Semantic action roles. Label recipes live on Chip. */\ntype ButtonIntent = \"danger\" | \"info\" | \"neutral\" | \"brand\" | \"commit\";\nexport type ButtonAppearance = \"pill\" | \"raised\";\n\nconst pillSizes = {\n icon: \"polli:h-12 polli:w-12 polli:p-0\",\n xs: \"polli:h-5 polli:px-1.5 polli:py-0 polli:text-[11px] polli:leading-none\",\n sm: \"polli:min-h-7 polli:px-2 polli:pt-0.5 polli:pb-1\",\n md: \"polli:min-h-9 polli:px-4 polli:pt-1.5 polli:pb-2\",\n lg: \"polli:min-h-12 polli:px-6 polli:py-3 polli:text-base\",\n} as const;\n\nconst raisedSizes = {\n icon: \"polli:h-12 polli:w-12 polli:p-0\",\n xs: \"polli:px-2 polli:py-1 polli:text-xs\",\n sm: \"polli:px-4 polli:py-2 polli:text-sm\",\n md: \"polli:px-7 polli:py-3.5 polli:text-base\",\n lg: \"polli:px-8 polli:py-4 polli:text-lg\",\n} as const;\n\nconst appearanceClasses: Record<ButtonAppearance, string> = {\n pill: \"polli:rounded-full\",\n raised:\n \"polli:rounded-xl polli:border-r-[3px] polli:border-b-[3px] polli:border-solid \" +\n \"polli:border-theme-text-strong/20 polli:hover:border-theme-text-strong/45\",\n};\n\n// Cascade-driven base — reads [data-theme] vars.\nconst themeClasses =\n \"polli:bg-theme-bg-active polli:text-theme-text-strong \" +\n \"polli:hover:bg-theme-bg-hover polli:hover:text-theme-text-hover polli:transition-colors\";\n\n// Primary actions have a soft accent fill in light mode and an outline in dark.\n// `brand` keeps a calm hover; `commit` strengthens the fill on hover and focus.\nconst outlined =\n \"polli:border polli:border-theme-text-soft polli:bg-theme-bg-active/30 polli:text-theme-text-strong \" +\n \"polli:transition-colors polli:[.dark_&]:bg-transparent\";\nconst intentClasses: Record<ButtonIntent, string> = {\n brand: `${outlined} polli:hover:bg-theme-bg-active/50 polli:[.dark_&]:hover:bg-theme-text-soft/10`,\n commit:\n `${outlined} polli:hover:border-theme-bg-active polli:hover:bg-theme-bg-active ` +\n \"polli:focus-visible:border-theme-bg-active polli:focus-visible:bg-theme-bg-active \" +\n \"polli:[.dark_&]:hover:bg-theme-bg-active polli:[.dark_&]:focus-visible:bg-theme-bg-active\",\n danger:\n \"polli:border polli:border-intent-danger-text polli:bg-intent-danger-bg-light polli:text-intent-danger-text \" +\n \"polli:hover:bg-intent-danger-bg-hover polli:focus-visible:bg-intent-danger-bg-hover polli:transition-colors \" +\n \"polli:[.dark_&]:bg-transparent polli:[.dark_&]:hover:bg-intent-danger-bg-hover polli:[.dark_&]:focus-visible:bg-intent-danger-bg-hover\",\n info:\n \"polli:bg-intent-info-bg-light polli:text-intent-info-text \" +\n \"polli:hover:bg-intent-info-bg-hover polli:transition-colors\",\n // Secondary actions never take the accent: one step stronger grey on hover.\n neutral:\n \"polli:bg-theme-bg-subtle polli:text-theme-text-base \" +\n \"polli:hover:bg-theme-text-muted/25 polli:hover:text-theme-text-strong polli:transition-colors\",\n};\n\ntype BaseButtonProps = {\n icon?: ReactNode;\n /** Optional semantic recipe; omit for the ambient theme button. */\n intent?: ButtonIntent;\n /** `raised` is the stronger website CTA treatment. */\n appearance?: ButtonAppearance;\n size?: keyof typeof pillSizes;\n className?: string;\n disabled?: boolean;\n};\n\nconst buttonClasses = ({\n intent,\n appearance = \"pill\",\n size,\n className,\n disabled,\n busy,\n}: BaseButtonProps & { disabled?: boolean; busy?: boolean }) => {\n const colorClasses = intent ? intentClasses[intent] : themeClasses;\n const sizeClasses = appearance === \"raised\" ? raisedSizes : pillSizes;\n return cn(\n \"polli-control polli:inline-flex polli:items-center polli:justify-center polli:self-center polli:font-body polli:text-sm polli:font-medium polli:leading-normal polli:box-border polli:border polli:border-transparent\",\n // A busy button is working, not unavailable: it keeps its strength.\n busy\n ? \"polli:cursor-progress\"\n : disabled\n ? \"polli:opacity-50 polli:cursor-not-allowed\"\n : \"polli:hover:filter polli:hover:brightness-105 polli:cursor-pointer\",\n colorClasses,\n appearanceClasses[appearance],\n sizeClasses[size || \"md\"],\n className,\n );\n};\n\nexport type ButtonProps<T extends React.ElementType = \"button\"> =\n PropsWithChildren<BaseButtonProps> & {\n as?: T;\n } & Omit<React.ComponentPropsWithoutRef<T>, keyof BaseButtonProps | \"as\">;\n\nexport function Button<T extends React.ElementType = \"button\">({\n as,\n children,\n icon,\n intent,\n appearance,\n size,\n className,\n disabled,\n ...buttonProps\n}: ButtonProps<T>) {\n const Component: React.ElementType = as || \"button\";\n const isButton = Component === \"button\";\n const isAnchor = Component === \"a\";\n const buttonType = (\n buttonProps as {\n type?: \"button\" | \"submit\" | \"reset\";\n }\n ).type;\n const onClick = (\n buttonProps as {\n onClick?: (event: ReactMouseEvent) => void;\n }\n ).onClick;\n const ariaBusy = (\n buttonProps as { \"aria-busy\"?: boolean | \"true\" | \"false\" }\n )[\"aria-busy\"];\n const busy = ariaBusy === true || ariaBusy === \"true\";\n const handleClick = disabled\n ? (event: ReactMouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n }\n : onClick;\n\n return (\n <Component\n {...buttonProps}\n data-intent={intent}\n {...(isButton ? { type: buttonType ?? \"button\", disabled } : {})}\n {...(!isButton && disabled\n ? { \"aria-disabled\": true, tabIndex: -1 }\n : {})}\n {...(isAnchor && disabled ? { href: undefined } : {})}\n onClick={handleClick}\n className={buttonClasses({\n intent,\n appearance,\n size,\n className,\n disabled,\n busy,\n })}\n >\n {icon && (\n <span\n aria-hidden=\"true\"\n className=\"polli:mr-2 polli:flex polli:size-4 polli:shrink-0 polli:[&>svg]:size-full\"\n >\n {busy ? (\n <span className=\"polli:block polli:size-full polli:animate-spin polli:rounded-full polli:border-2 polli:border-current polli:border-r-transparent polli:motion-reduce:animate-none\" />\n ) : (\n icon\n )}\n </span>\n )}\n {children}\n </Component>\n );\n}\n","import type { ComponentPropsWithoutRef, FC } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\n\n/** Semantic chip labels for status and metadata badges. */\ntype ChipIntent =\n | \"news\"\n | \"new\"\n | \"free\"\n | \"alpha\"\n | \"neutral\"\n | \"success\"\n | \"warning\"\n | \"info\"\n | \"danger\";\n\nconst chipSizes = {\n icon: \"polli:h-5 polli:w-5 polli:p-0 polli:text-xs\",\n sm: \"polli:h-5 polli:px-2 polli:text-xs\",\n md: \"polli:h-6 polli:px-2.5 polli:text-sm\",\n lg: \"polli:h-7 polli:px-3 polli:text-sm\",\n} as const;\n\nconst intentClasses: Record<ChipIntent, string> = {\n news: \"polli:bg-intent-news-bg-light polli:text-intent-news-text\",\n new: \"polli:bg-intent-new-bg-light polli:text-intent-new-text\",\n free: \"polli:bg-intent-free-bg-light polli:text-intent-free-text\",\n alpha: \"polli:bg-intent-alpha-bg-light polli:text-intent-alpha-text\",\n neutral: \"polli:bg-ink-100/80 polli:text-ink-900\",\n success:\n \"polli:bg-intent-success-bg-bright/15 polli:text-intent-success-text\",\n warning: \"polli:bg-intent-warning-bg-light polli:text-intent-warning-text\",\n info: \"polli:bg-intent-info-bg-light polli:text-intent-info-text\",\n danger: \"polli:bg-intent-danger-bg-light polli:text-intent-danger-text\",\n};\n\nexport type ChipProps = ComponentPropsWithoutRef<\"span\"> & {\n /** Semantic intent. */\n intent?: ChipIntent;\n size?: keyof typeof chipSizes;\n};\n\n// Static, rectangular colored container. Round shapes are reserved for buttons.\n// Reads `bg-theme-bg-active` / `text-theme-text-strong` from the cascade unless\n// `intent` is set (semantic, theme-independent).\nexport const Chip: FC<ChipProps> = ({\n intent,\n size = \"md\",\n className,\n children,\n ...rest\n}) => {\n const intentClass = intent\n ? intentClasses[intent]\n : \"polli:bg-theme-bg-active polli:text-theme-text-strong\";\n return (\n <span\n {...rest}\n className={cn(\n \"polli:inline-flex polli:shrink-0 polli:items-center polli:justify-center polli:gap-1 polli:rounded-lg polli:font-medium polli:leading-none\",\n chipSizes[size],\n intentClass,\n className,\n )}\n >\n {children}\n </span>\n );\n};\n","/** Relative URLs and same-origin absolute URLs stay in the current app. */\nexport function isExternalHref(\n href: unknown,\n origin = globalThis.location?.origin,\n): boolean {\n if (typeof href !== \"string\" || !/^(https?:)?\\/\\//i.test(href))\n return false;\n if (!origin) return true;\n try {\n return new URL(href, origin).origin !== origin;\n } catch {\n return false;\n }\n}\n","import type { PropsWithChildren } from \"react\";\nimport { isExternalHref } from \"../lib/link.ts\";\nimport { ExternalLinkIcon } from \"./icons/index.tsx\";\n\ntype BaseInlineLinkProps = {\n /** Set explicitly for non-http external links, or false for custom routing components. */\n external?: boolean;\n showIcon?: boolean;\n /** Inline text inherits its size; footers use 13px and standalone links 14px. */\n size?: \"inherit\" | \"footer\" | \"sm\";\n /** Accent for prominent links; quiet for secondary navigation. */\n tone?: \"accent\" | \"quiet\";\n className?: string;\n};\n\nexport type InlineLinkProps<T extends React.ElementType = \"a\"> =\n PropsWithChildren<BaseInlineLinkProps> & {\n as?: T;\n } & Omit<\n React.ComponentPropsWithoutRef<T>,\n keyof BaseInlineLinkProps | \"as\"\n >;\n\n/** Shared text-link rule: surrounding font, selectable ink, persistent underline,\n * visible keyboard focus, and an external arrow only when leaving the app.\n * Navigation and button-shaped actions use their own primitives.\n */\nexport function InlineLink<T extends React.ElementType = \"a\">({\n as,\n external,\n showIcon = true,\n size = \"inherit\",\n tone = \"accent\",\n className,\n children,\n ...linkProps\n}: InlineLinkProps<T>) {\n const Component: React.ElementType = as || \"a\";\n const isExternal =\n external ?? isExternalHref((linkProps as { href?: unknown }).href);\n\n return (\n <Component\n target={isExternal && as !== \"button\" ? \"_blank\" : undefined}\n rel={\n isExternal && as !== \"button\"\n ? \"noopener noreferrer\"\n : undefined\n }\n className={[\"polli-link\", className].filter(Boolean).join(\" \")}\n data-size={size}\n data-tone={tone}\n {...linkProps}\n >\n {children}\n {showIcon && isExternal && (\n <ExternalLinkIcon\n aria-hidden=\"true\"\n className=\"polli-link-external-icon\"\n />\n )}\n </Component>\n );\n}\n","// 5-digit budget for pollen display. Integer takes its space, decimals fill\n// the remainder (capped at 4), floor toward -infinity, trailing zeros stripped.\n// Integers needing >=6 digits switch to compact (K/M/B, 3 sig figs).\n// Decimal point and minus sign do not count toward the budget.\n\nconst BUDGET = 5;\nconst MAX_DECIMALS = 4;\nconst COMPACT_THRESHOLD = 100_000;\n\nfunction floorTo(value: number, decimals: number): number {\n const factor = 10 ** decimals;\n return Math.floor(value * factor) / factor;\n}\n\nfunction formatCompact(value: number): string {\n const abs = Math.abs(value);\n const sign = value < 0 ? \"-\" : \"\";\n const [unit, scale] =\n abs >= 1e9\n ? ([\"B\", 1e9] as const)\n : abs >= 1e6\n ? ([\"M\", 1e6] as const)\n : ([\"K\", 1e3] as const);\n const ratio = abs / scale;\n const intDigits = Math.max(1, Math.floor(Math.log10(ratio)) + 1);\n const decimals = Math.max(0, 3 - intDigits);\n const floored = floorTo(ratio, decimals);\n return `${sign}${Number(floored.toFixed(decimals)).toString()}${unit}`;\n}\n\nexport function formatPollen(value: number): string {\n if (!Number.isFinite(value) || value === 0) return \"0\";\n\n const abs = Math.abs(value);\n\n if (abs >= COMPACT_THRESHOLD) return formatCompact(value);\n\n const intDigits = abs >= 1 ? Math.floor(Math.log10(abs)) + 1 : 1;\n const decimals = Math.min(MAX_DECIMALS, Math.max(0, BUDGET - intDigits));\n const floored = floorTo(value, decimals);\n if (floored === 0) return \"0\";\n return Number(floored.toFixed(decimals)).toString();\n}\n","import type { FC, ReactNode } from \"react\";\nimport { cn } from \"../../lib/cn.ts\";\nimport { CardIcon, SproutIcon } from \"../../primitives/icons/index.tsx\";\n\ntype WalletBalanceKind = \"paid\" | \"tier\";\n\nconst walletPanelClasses: Record<WalletBalanceKind, string> = {\n paid: \"polli-wallet-panel-paid\",\n tier: \"polli-wallet-panel-tier\",\n};\n\nconst walletTextClasses: Record<WalletBalanceKind, string> = {\n paid: \"polli-wallet-text-paid\",\n tier: \"polli-wallet-text-tier\",\n};\n\nconst walletKindIcons: Record<WalletBalanceKind, typeof CardIcon> = {\n paid: CardIcon,\n tier: SproutIcon,\n};\n\nexport type WalletKindIconProps = {\n kind: WalletBalanceKind;\n className?: string;\n};\n\n/** The paid/Quest marker: a card for paid balance or sprout for Quest Pollen. */\nexport const WalletKindIcon: FC<WalletKindIconProps> = ({\n kind,\n className,\n}) => {\n const Icon = walletKindIcons[kind];\n return (\n <Icon\n aria-hidden=\"true\"\n className={cn(\n \"polli:h-3.5 polli:w-3.5 polli:shrink-0\",\n walletTextClasses[kind],\n className,\n )}\n />\n );\n};\n\nexport type WalletBalanceCardProps = {\n tone?: \"balance\" | \"neutral\";\n kind: WalletBalanceKind;\n label: ReactNode;\n value: ReactNode;\n icon?: ReactNode;\n info?: ReactNode;\n footer?: ReactNode;\n className?: string;\n};\n\nexport const WalletBalanceCard: FC<WalletBalanceCardProps> = ({\n tone = \"balance\",\n kind,\n label,\n value,\n icon,\n info,\n footer,\n className,\n}) => {\n const Icon = walletKindIcons[kind];\n const textColor =\n tone === \"neutral\"\n ? \"polli:text-theme-text-strong\"\n : walletTextClasses[kind];\n return (\n <div\n className={cn(\n \"polli:min-w-0 polli:rounded-card polli:p-3.5 polli:sm:p-5\",\n tone === \"neutral\"\n ? \"polli:bg-surface-opaque\"\n : walletPanelClasses[kind],\n className,\n )}\n >\n <span className=\"polli:flex polli:items-center polli:gap-2\">\n {icon ?? (\n <Icon\n aria-hidden=\"true\"\n className={cn(\n \"polli:h-3.5 polli:w-3.5 polli:shrink-0\",\n textColor,\n )}\n />\n )}\n <span\n className={cn(\n \"polli:text-sm polli:font-bold polli:uppercase polli:tracking-wide\",\n textColor,\n )}\n >\n {label}\n </span>\n {info}\n </span>\n <div\n className={cn(\n \"polli-wallet-balance-value polli:[overflow-wrap:anywhere] polli:mt-1 polli:font-bold polli:leading-none polli:tracking-tight polli:tabular-nums\",\n textColor,\n )}\n >\n {value}\n </div>\n {footer && (\n <div className=\"polli:mt-1.5 polli:text-sm polli:font-bold polli:tabular-nums polli:text-intent-success-text\">\n {footer}\n </div>\n )}\n </div>\n );\n};\n","import { Chip } from \"../../primitives/Chip.tsx\";\nimport { InlineLink } from \"../../primitives/InlineLink.tsx\";\nimport { KeyIcon, WalletIcon } from \"../../primitives/icons/index.tsx\";\nimport { formatPollen } from \"./format-pollen.ts\";\nimport { WalletKindIcon } from \"./wallet-display.tsx\";\n\nexport type AccountPollenSource =\n | {\n type: \"wallet\";\n /** Undefined while the balance is unavailable. */\n balances?: { paid: number; quest: number };\n }\n | {\n type: \"budget\";\n /** The app's remaining budget, never the owner's wallet total. `null` = unlimited. */\n remaining?: number | null;\n generationEnabled?: boolean;\n };\n\nfunction isEmpty(amount: number | null | undefined): boolean {\n return amount != null && amount <= 0;\n}\n\ntype PollenStatus = \"limit-reached\" | \"no-pollen\" | \"unlimited\";\n\nconst labels: Record<PollenStatus, string> = {\n \"limit-reached\": \"Limit reached\",\n \"no-pollen\": \"No Pollen\",\n unlimited: \"Unlimited\",\n};\n\nfunction PollenStatusBadge({\n state,\n topUpHref,\n}: {\n state: PollenStatus;\n topUpHref?: string;\n}) {\n const Icon = state === \"no-pollen\" ? WalletIcon : KeyIcon;\n const label = labels[state];\n return (\n <Chip\n size=\"sm\"\n intent={state === \"unlimited\" ? \"info\" : \"danger\"}\n aria-label={label}\n >\n <Icon\n aria-hidden=\"true\"\n className=\"polli:h-3.5 polli:w-3.5 polli:shrink-0\"\n />\n {label}\n {state === \"no-pollen\" && topUpHref && (\n <>\n <span aria-hidden=\"true\">·</span>\n <InlineLink\n href={topUpHref}\n aria-label={`${label}. Top up`}\n >\n Top up\n </InlineLink>\n </>\n )}\n </Chip>\n );\n}\n\n/** Icon + amount; unlimited, exhausted, or empty states become a badge. */\nexport function AccountPollen({\n source,\n topUpHref,\n}: {\n source: AccountPollenSource;\n /** Shown in the empty-wallet badge. A menu keeps recovery links in its dropdown. */\n topUpHref?: string;\n}) {\n if (source.type === \"budget\") {\n if (source.generationEnabled === false) return null;\n // null is the API's explicit \"no budget\"; undefined is not loaded yet.\n const unlimited = source.remaining === null;\n if (!unlimited && source.remaining === undefined) return null;\n if (unlimited) return <PollenStatusBadge state=\"unlimited\" />;\n const remaining = source.remaining as number;\n if (isEmpty(remaining))\n return <PollenStatusBadge state=\"limit-reached\" />;\n return (\n <span\n title=\"App budget left\"\n className=\"polli:inline-flex polli:items-center polli:gap-1 polli:tabular-nums\"\n >\n <KeyIcon\n aria-hidden=\"true\"\n className=\"polli:h-3.5 polli:w-3.5 polli:shrink-0\"\n />\n <span className=\"polli:sr-only\">App budget: </span>\n {formatPollen(remaining)} pollen\n </span>\n );\n }\n const { balances } = source;\n if (!balances) return null;\n if (isEmpty(balances.paid) && isEmpty(balances.quest))\n return <PollenStatusBadge state=\"no-pollen\" topUpHref={topUpHref} />;\n return (\n <span className=\"polli:inline-flex polli:items-center polli:gap-2 polli:tabular-nums\">\n {/* Quest Pollen is spent first, so it comes first. */}\n {([\"quest\", \"paid\"] as const).map((kind) => {\n const amount = balances[kind];\n return (\n <span\n key={kind}\n className=\"polli:inline-flex polli:items-center polli:gap-1\"\n >\n <WalletKindIcon\n kind={kind === \"paid\" ? \"paid\" : \"tier\"}\n />\n <span className=\"polli:sr-only\">\n {kind === \"paid\" ? \"Paid\" : \"Quest\"} Pollen:{\" \"}\n </span>\n {formatPollen(Math.max(0, amount))}\n </span>\n );\n })}\n </span>\n );\n}\n"],"mappings":"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","names":["useAuthActions","useAuthState","useId","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsx","jsxs","jsxs","jsx","useId","jsx","jsx","jsx","jsxs","jsx","jsx","intentClasses","jsx","jsxs","jsx","jsxs","jsx","jsx","jsxs","Fragment","jsx","jsxs","labels","useAuthActions","useAuthState"]}
1
+ {"version":3,"sources":["../../src/modules/app-user-menu/AppUserMenu.tsx","../../src/compositions/AccountIdentity.tsx","../../src/lib/cn.ts","../../src/primitives/ChevronIcon.tsx","../../src/primitives/Dropdown.tsx","../../src/primitives/icons/index.tsx","../../src/primitives/BrandMark.tsx","../../src/primitives/DropdownItem.tsx","../../src/modules/auth/LoginButton.tsx","../../src/primitives/Button.tsx","../../src/primitives/Chip.tsx","../../src/lib/link.ts","../../src/primitives/InlineLink.tsx","../../src/modules/wallet/format-pollen.ts","../../src/modules/wallet/wallet-display.tsx","../../src/modules/wallet/AccountPollen.tsx"],"sourcesContent":["import {\n useAccountBalance,\n useAccountKey,\n useAccountProfile,\n useAuthActions,\n useAuthState,\n} from \"@pollinations/sdk/react\";\nimport { useEffect } from \"react\";\nimport { AccountMenu } from \"../../compositions/AccountMenu.tsx\";\nimport { cn } from \"../../lib/cn.ts\";\nimport { BrandMark } from \"../../primitives/BrandMark.tsx\";\nimport { DropdownItem } from \"../../primitives/DropdownItem.tsx\";\nimport {\n ExternalLinkIcon,\n KeyIcon,\n PowerIcon,\n WalletIcon,\n} from \"../../primitives/icons/index.tsx\";\nimport { LoginButton } from \"../auth/sdk.ts\";\nimport {\n AccountPollen,\n type AccountPollenSource,\n} from \"../wallet/AccountPollen.tsx\";\n\nexport type AppUserMenuLabels = {\n authorize: string;\n appUserMenu: string;\n permissions: string;\n buyPollen: string;\n logout: string;\n};\n\nexport type AppUserMenuProps = {\n /** Optional caller-owned dashboard destination for the linked avatar. */\n dashboardHref?: string;\n /** Larger logged-out action for prominent placements such as a page hero. */\n connectSize?: keyof typeof CONNECT_SIZES;\n labels?: Partial<AppUserMenuLabels>;\n};\n\nconst defaultLabels: AppUserMenuLabels = {\n authorize: \"Pollinations Connect\",\n appUserMenu: \"App user menu\",\n permissions: \"Permissions\",\n buyPollen: \"Buy Pollen\",\n logout: \"Disconnect\",\n};\n\nconst CONNECT_SIZES = {\n md: {\n button: \"polli:h-10 polli:px-4\",\n mark: \"polli:h-5 polli:w-5\",\n },\n lg: {\n button: \"polli:h-12 polli:px-5 polli:text-base\",\n mark: \"polli:h-6 polli:w-6\",\n },\n};\n\nexport function AppUserMenu({\n dashboardHref,\n connectSize = \"md\",\n labels: labelOverrides,\n}: AppUserMenuProps) {\n const labels = { ...defaultLabels, ...labelOverrides };\n const size = CONNECT_SIZES[connectSize];\n const { logout, enterUrl } = useAuthActions();\n const { isLoggedIn } = useAuthState();\n const profile = useAccountProfile({ enabled: isLoggedIn });\n const key = useAccountKey({ enabled: isLoggedIn });\n // The wallet is shown only for an unlimited key that may read it; ask only then.\n const canReadWallet =\n key.data?.pollenBudget === null &&\n (key.data.permissions?.account?.includes(\"usage\") ?? false);\n const balance = useAccountBalance({\n enabled: isLoggedIn && canReadWallet,\n });\n const wallet = balance.data?.accountBalance;\n useEffect(() => {\n if (!isLoggedIn) return;\n const onVisible = () => {\n if (document.visibilityState !== \"visible\") return;\n void key.refresh();\n void balance.refresh();\n };\n document.addEventListener(\"visibilitychange\", onVisible);\n return () =>\n document.removeEventListener(\"visibilitychange\", onVisible);\n }, [isLoggedIn, key.refresh, balance.refresh]);\n const returnUrl =\n typeof window === \"undefined\" ? undefined : window.location.href;\n const topUpUrl = new URL(\"/top-up\", enterUrl);\n if (returnUrl) topUpUrl.searchParams.set(\"redirect\", returnUrl);\n const keyId = key.data?.id;\n let editKeyUrl: URL | undefined;\n if (keyId) {\n editKeyUrl = new URL(\"/edit-key\", enterUrl);\n editKeyUrl.searchParams.set(\"id\", keyId);\n if (returnUrl) editKeyUrl.searchParams.set(\"redirect\", returnUrl);\n }\n let pollenSource: AccountPollenSource | undefined;\n if (key.data && key.data.pollenBudget !== null) {\n pollenSource = {\n type: \"budget\",\n remaining: key.data.pollenBudget,\n generationEnabled: key.data.permissions?.models?.length !== 0,\n };\n } else if (wallet) {\n pollenSource = {\n type: \"wallet\",\n balances: { paid: wallet.paid, quest: wallet.tier },\n };\n } else if (key.data && !canReadWallet) {\n pollenSource = { type: \"budget\", remaining: null };\n }\n\n return (\n <div\n data-theme=\"accent\"\n className=\"polli:flex polli:shrink-0 polli:justify-end\"\n >\n {!isLoggedIn ? (\n <LoginButton\n intent=\"brand\"\n className={cn(\n \"polli:gap-2 polli:py-0 polli:whitespace-nowrap\",\n size.button,\n )}\n >\n <BrandMark className={size.mark} />\n {labels.authorize}\n </LoginButton>\n ) : (\n <AccountMenu\n name={\n profile.data?.name ||\n profile.data?.githubUsername ||\n \"Connected user\"\n }\n avatarUrl={profile.data?.image}\n dashboardHref={\n dashboardHref ?? new URL(\"/pollen\", enterUrl).href\n }\n menuLabel={labels.appUserMenu}\n className=\"polli:max-w-80\"\n secondaryContent={\n pollenSource ? (\n <AccountPollen source={pollenSource} />\n ) : undefined\n }\n >\n {(close) => (\n <>\n {editKeyUrl && (\n <DropdownItem\n as=\"a\"\n href={editKeyUrl.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={close}\n >\n <KeyIcon\n className=\"polli:h-4 polli:w-4 polli:shrink-0\"\n aria-hidden=\"true\"\n />\n {labels.permissions}\n <ExternalLinkIcon\n className=\"polli:ml-auto polli:h-3.5 polli:w-3.5 polli:shrink-0\"\n aria-hidden=\"true\"\n />\n </DropdownItem>\n )}\n <DropdownItem\n as=\"a\"\n href={topUpUrl.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={close}\n >\n <WalletIcon\n className=\"polli:h-4 polli:w-4 polli:shrink-0\"\n aria-hidden=\"true\"\n />\n {labels.buyPollen}\n <ExternalLinkIcon\n className=\"polli:ml-auto polli:h-3.5 polli:w-3.5 polli:shrink-0\"\n aria-hidden=\"true\"\n />\n </DropdownItem>\n <DropdownItem\n type=\"button\"\n className=\"polli:justify-start polli:text-left\"\n onClick={() => {\n close();\n logout();\n }}\n >\n <PowerIcon\n className=\"polli:h-4 polli:w-4 polli:shrink-0\"\n aria-hidden=\"true\"\n />\n {labels.logout}\n </DropdownItem>\n </>\n )}\n </AccountMenu>\n )}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { useId } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport { ChevronIcon } from \"../primitives/ChevronIcon.tsx\";\nimport { Dropdown, type DropdownProps } from \"../primitives/Dropdown.tsx\";\nimport { ExternalLinkIcon } from \"../primitives/icons/index.tsx\";\n\nfunction initials(name: string) {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return \"?\";\n if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();\n return `${parts[0][0] ?? \"\"}${parts.at(-1)?.[0] ?? \"\"}`.toUpperCase();\n}\n\nfunction AccountAvatar({\n name,\n avatarUrl,\n secondaryContent,\n dashboardHref,\n inline = false,\n}: {\n name: string;\n avatarUrl?: string | null;\n secondaryContent?: ReactNode;\n dashboardHref?: string;\n /** Small avatar inside a pill link; hovering the pill zooms it. */\n inline?: boolean;\n}) {\n const size = inline\n ? \"polli:h-6 polli:w-6\"\n : secondaryContent != null\n ? \"polli:h-11 polli:w-11\"\n : \"polli:h-8 polli:w-8\";\n const className = cn(\n size,\n inline &&\n \"polli:transition-transform polli:group-hover:scale-110 polli:group-hover:brightness-110 polli:motion-reduce:transition-none polli:motion-reduce:group-hover:scale-100\",\n );\n const avatar = avatarUrl ? (\n <img\n src={avatarUrl}\n alt=\"\"\n className={cn(\n className,\n \"polli:shrink-0 polli:rounded-full polli:object-cover\",\n )}\n />\n ) : (\n <span\n role=\"img\"\n aria-label={`${name} avatar`}\n className={cn(\n className,\n \"polli:flex polli:shrink-0 polli:items-center polli:justify-center polli:rounded-full polli:bg-theme-bg-pale polli:text-xs polli:font-semibold polli:text-theme-text-strong\",\n )}\n >\n {initials(name)}\n </span>\n );\n return dashboardHref ? (\n <a\n href={dashboardHref}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label=\"Open dashboard\"\n title=\"Open dashboard\"\n className=\"polli:shrink-0 polli:rounded-full polli:cursor-pointer polli:transition-transform polli:hover:scale-105 polli:hover:brightness-110 polli:focus-visible:outline-2 polli:focus-visible:outline-offset-2 polli:focus-visible:outline-current polli:motion-reduce:transition-none polli:motion-reduce:hover:scale-100\"\n >\n {avatar}\n </a>\n ) : (\n avatar\n );\n}\n\nexport type AccountIdentityProps = {\n name: string;\n avatarUrl?: string | null;\n secondaryContent?: ReactNode;\n /** Optional dashboard destination, owned by the caller. Opens in a new tab. */\n dashboardHref?: string;\n className?: string;\n};\n\nexport type AccountIdentityLinkProps = Pick<\n AccountIdentityProps,\n \"name\" | \"avatarUrl\" | \"className\"\n> & {\n /** External profile the whole pill opens in a new tab. */\n href: string;\n};\n\nexport function AccountIdentity({\n name,\n avatarUrl,\n secondaryContent,\n dashboardHref,\n className,\n}: AccountIdentityProps) {\n return (\n <span\n className={cn(\n \"polli:flex polli:min-w-0 polli:items-center polli:gap-2 polli:rounded-full polli:bg-surface-opaque polli:p-1 polli:pr-3\",\n className,\n )}\n >\n <AccountAvatar\n name={name}\n avatarUrl={avatarUrl}\n dashboardHref={dashboardHref}\n secondaryContent={secondaryContent}\n />\n <AccountDetails name={name} secondaryContent={secondaryContent} />\n </span>\n );\n}\n\n/** Someone else's identity as a one-line pill link, e.g. an app's developer. */\nexport function AccountIdentityLink({\n name,\n avatarUrl,\n href,\n className,\n}: AccountIdentityLinkProps) {\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={cn(\n // Sits in running text on cards, so it is compact and tinted.\n \"polli:group polli:inline-flex polli:max-w-full polli:min-w-0 polli:items-center polli:gap-1.5 polli:rounded-full polli:bg-theme-bg-subtle polli:p-0.5 polli:pr-2.5 polli:align-middle polli:focus-visible:outline-2 polli:focus-visible:outline-offset-2 polli:focus-visible:outline-current\",\n className,\n )}\n >\n <AccountAvatar name={name} avatarUrl={avatarUrl} inline />\n <AccountDetails name={name} />\n {/* InlineLink's external arrow at the name's size: this pill leaves the app. */}\n <ExternalLinkIcon\n aria-hidden=\"true\"\n className=\"polli:-ml-0.5 polli:h-3 polli:w-3 polli:shrink-0 polli:text-theme-text-strong polli:opacity-65\"\n />\n </a>\n );\n}\n\nfunction AccountDetails({\n name,\n secondaryContent,\n secondaryId,\n}: {\n name: string;\n secondaryContent?: ReactNode;\n secondaryId?: string;\n}) {\n return (\n <span className=\"polli:flex polli:min-w-0 polli:flex-col polli:items-start polli:text-left\">\n <span\n title={name}\n className=\"polli:max-w-full polli:truncate polli:text-sm polli:font-medium polli:leading-5 polli:text-theme-text-strong\"\n >\n {name}\n </span>\n {secondaryContent != null && (\n <span\n id={secondaryId}\n className=\"polli:inline-flex polli:min-h-5 polli:items-center polli:whitespace-nowrap polli:text-xs polli:leading-4 polli:text-theme-text-base\"\n >\n {secondaryContent}\n </span>\n )}\n </span>\n );\n}\n\nexport type AccountMenuProps = AccountIdentityProps & {\n /** The caller owns navigation, permissions and sign-out behavior. */\n children: DropdownProps[\"children\"];\n menuClassName?: string;\n side?: \"top\" | \"bottom\";\n menuLabel?: string;\n};\n\n/**\n * With `dashboardHref` the avatar is a link and the name/chevron open the\n * menu; without one the whole pill is the trigger.\n */\nexport function AccountMenu({\n name,\n avatarUrl,\n dashboardHref,\n secondaryContent,\n children,\n className,\n menuClassName,\n side = \"bottom\",\n menuLabel = `Account menu for ${name}`,\n}: AccountMenuProps) {\n const statusId = useId();\n const avatar = (\n <AccountAvatar\n name={name}\n avatarUrl={avatarUrl}\n dashboardHref={dashboardHref}\n secondaryContent={secondaryContent}\n />\n );\n\n return (\n <div\n data-theme=\"accent\"\n className={cn(\n \"polli:flex polli:min-w-0 polli:items-center polli:gap-2 polli:rounded-full polli:bg-theme-bg-active polli:p-1 polli:pr-3 polli:text-theme-text-strong polli:transition-colors polli:hover:bg-theme-bg-hover\",\n className,\n )}\n >\n {dashboardHref && avatar}\n <Dropdown\n align=\"end\"\n side={side}\n className={cn(\n \"polli:w-max polli:min-w-[var(--reference-width)] polli:p-1\",\n menuClassName,\n )}\n trigger={(open) => (\n <button\n type=\"button\"\n aria-label={menuLabel}\n aria-describedby={\n secondaryContent != null ? statusId : undefined\n }\n className=\"polli-control polli:flex polli:min-w-0 polli:flex-1 polli:items-center polli:gap-2 polli:self-stretch polli:rounded-full polli:text-theme-text-strong\"\n >\n {!dashboardHref && avatar}\n <AccountDetails\n name={name}\n secondaryContent={secondaryContent}\n secondaryId={statusId}\n />\n <ChevronIcon\n expanded={open}\n className=\"polli:ml-auto polli:h-4 polli:w-4 polli:text-theme-text-strong\"\n />\n </button>\n )}\n >\n {children}\n </Dropdown>\n </div>\n );\n}\n","import { clsx } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({ prefix: \"polli\" });\n\n/** Internal class merge for polli:-prefixed package primitive classes. */\nexport function cn(...inputs: (string | undefined | null | false)[]) {\n return twMerge(clsx(...inputs));\n}\n","import type { FC } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\n\ntype ChevronIconProps = {\n /** Rotate 180° when expanded/open. */\n expanded?: boolean;\n className?: string;\n};\n\n/**\n * Canonical chevron used for collapsibles, dropdown triggers, and select pills\n * across the app. One icon everywhere.\n */\nexport const ChevronIcon: FC<ChevronIconProps> = ({ expanded, className }) => (\n <svg\n aria-hidden=\"true\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n className={cn(\n \"polli:shrink-0 polli:transition-transform polli:duration-200 polli:ease-out\",\n expanded && \"polli:rotate-180\",\n className,\n )}\n >\n <path\n d=\"M3 4.5 6 7.5l3-3\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"1.5\"\n />\n </svg>\n);\n","import { Popover } from \"@ark-ui/react/popover\";\nimport { Portal } from \"@ark-ui/react/portal\";\nimport type { CSSProperties, FC, ReactNode } from \"react\";\nimport { useId, useState } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\n\nconst DEFAULT_PANEL = \"polli:rounded-lg polli:bg-surface-menu polli:shadow-lg\";\n\nexport type DropdownProps = {\n /** Trigger element; receives the current open state (e.g. to rotate a chevron). */\n trigger: (open: boolean) => ReactNode;\n /** Panel content. As a function, receives `close` to dismiss after a selection. */\n children: ReactNode | ((close: () => void) => ReactNode);\n /** Panel placement relative to the trigger. */\n align?: \"start\" | \"end\";\n side?: \"top\" | \"bottom\";\n /** Controlled open state. Omit to let the Dropdown manage its own. */\n open?: boolean;\n /** Render inside the parent dialog so its focus and accessibility scope includes the menu. */\n portalled?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Appended after the surface (widths, padding, max-height…). */\n className?: string;\n /** Theme variables for portaled content that cannot inherit from its trigger. */\n panelStyle?: CSSProperties;\n};\n\nexport const Dropdown: FC<DropdownProps> = ({\n trigger,\n children,\n align = \"start\",\n side = \"bottom\",\n open: openProp,\n portalled = true,\n onOpenChange,\n className,\n panelStyle,\n}) => {\n const triggerId = useId();\n const [internalOpen, setInternalOpen] = useState(false);\n const isControlled = openProp !== undefined;\n const open = isControlled ? openProp : internalOpen;\n\n const setOpen = (next: boolean) => {\n if (!isControlled) setInternalOpen(next);\n onOpenChange?.(next);\n };\n\n return (\n <Popover.Root\n ids={{ trigger: triggerId }}\n open={open}\n portalled={portalled}\n onOpenChange={(details) => setOpen(details.open)}\n positioning={{\n placement: `${side}-${align}`,\n strategy: portalled ? \"absolute\" : \"fixed\",\n }}\n >\n <Popover.Trigger asChild>{trigger(open)}</Popover.Trigger>\n <Portal disabled={!portalled}>\n <Popover.Positioner>\n <Popover.Content\n aria-labelledby={triggerId}\n style={panelStyle}\n className={cn(\n \"polli:z-[120] polli:overflow-hidden polli:focus:outline-none\",\n DEFAULT_PANEL,\n className,\n )}\n >\n {typeof children === \"function\"\n ? children(() => setOpen(false))\n : children}\n </Popover.Content>\n </Popover.Positioner>\n </Portal>\n </Popover.Root>\n );\n};\n","import type { IconProps } from \"./types.ts\";\n\nconst strokeProps = {\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n} as const;\n\nexport function AppIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <rect x=\"2\" y=\"4\" width=\"20\" height=\"14\" rx=\"2\" />\n <path d=\"M2 20h20\" />\n </svg>\n );\n}\n\nexport function AccountIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <circle cx=\"12\" cy=\"8\" r=\"4\" />\n <path d=\"M4 21a8 8 0 0 1 16 0\" />\n </svg>\n );\n}\n\nexport function ArrowRightIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M5 12h14M13 6l6 6-6 6\" />\n </svg>\n );\n}\n\nexport function BeakerIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M9 3h6\" />\n <path d=\"M10 3v6.5L4.5 18a2 2 0 0 0 1.7 3h11.6a2 2 0 0 0 1.7-3L14 9.5V3\" />\n <path d=\"M7 14h10\" />\n </svg>\n );\n}\n\nexport function BotIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M12 8V4H8\" />\n <rect x=\"4\" y=\"8\" width=\"16\" height=\"12\" rx=\"2\" />\n <path d=\"M2 14h2M20 14h2\" />\n <path d=\"M9 13v2M15 13v2\" />\n </svg>\n );\n}\n\nexport function BookIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M4 4h5a3 3 0 0 1 3 3v13a2 2 0 0 0-2-2H4z\" />\n <path d=\"M20 4h-5a3 3 0 0 0-3 3v13a2 2 0 0 1 2-2h6z\" />\n </svg>\n );\n}\n\nexport function BugIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"m8 2 1.9 1.9M14.1 3.9 16 2\" />\n <path d=\"M9 7V6a3 3 0 0 1 6 0v1\" />\n <path d=\"M12 20c-3.3 0-6-2.7-6-6v-3a6 6 0 0 1 12 0v3c0 3.3-2.7 6-6 6Z\" />\n <path d=\"M12 20v-9M6.5 9C4.6 8.8 3 7.1 3 5M6 13H2M3 21c0-2.1 1.7-3.9 3.8-4M17.5 9C19.4 8.8 21 7.1 21 5M18 13h4M21 21c0-2.1-1.7-3.9-3.8-4\" />\n </svg>\n );\n}\n\nexport function CheckIcon(props: IconProps) {\n return (\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n {...strokeProps}\n strokeWidth={2.5}\n {...props}\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n );\n}\n\nexport function ClipboardIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" />\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n </svg>\n );\n}\n\nexport function ClockIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M12 7v5l3 2\" />\n </svg>\n );\n}\n\nexport function DiscordIcon(props: IconProps) {\n return (\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" {...props}>\n <path\n fill=\"currentColor\"\n d=\"M20.32 4.37A19.8 19.8 0 0 0 15.36 2.83a.07.07 0 0 0-.08.04c-.21.38-.45.88-.62 1.27a18.27 18.27 0 0 0-5.52 0 12.84 12.84 0 0 0-.63-1.27.08.08 0 0 0-.08-.04A19.74 19.74 0 0 0 3.47 4.37a.07.07 0 0 0-.03.03C.31 9.07-.55 13.61-.13 18.1a.08.08 0 0 0 .03.06 19.9 19.9 0 0 0 6.08 3.07.08.08 0 0 0 .09-.03c.47-.64.88-1.31 1.24-2.02a.08.08 0 0 0-.04-.1 13.08 13.08 0 0 1-1.9-.91.08.08 0 0 1-.01-.13c.13-.1.25-.2.37-.29a.07.07 0 0 1 .08-.01 14.24 14.24 0 0 0 12.38 0 .07.07 0 0 1 .08.01c.12.1.25.2.38.3a.08.08 0 0 1-.01.12 12.22 12.22 0 0 1-1.9.9.08.08 0 0 0-.04.11c.36.7.77 1.38 1.23 2.02a.08.08 0 0 0 .1.03 19.84 19.84 0 0 0 6.08-3.07.08.08 0 0 0 .03-.05c.5-5.2-.84-9.7-3.77-13.71a.06.06 0 0 0-.03-.03ZM8.02 15.37c-1.18 0-2.16-1.08-2.16-2.4 0-1.32.96-2.4 2.16-2.4 1.2 0 2.18 1.09 2.16 2.4 0 1.32-.96 2.4-2.16 2.4Zm7.96 0c-1.18 0-2.16-1.08-2.16-2.4 0-1.32.96-2.4 2.16-2.4 1.2 0 2.18 1.09 2.16 2.4 0 1.32-.95 2.4-2.16 2.4Z\"\n />\n </svg>\n );\n}\n\nexport function InstagramIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"5\" />\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <circle\n cx=\"17.5\"\n cy=\"6.5\"\n r=\"1\"\n fill=\"currentColor\"\n stroke=\"none\"\n />\n </svg>\n );\n}\n\nexport function XSocialIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...props}>\n <path\n fill=\"currentColor\"\n d=\"M18.24 2.25h3.31l-7.23 8.26 8.51 11.24h-6.66l-5.21-6.82-5.97 6.82H1.68l7.73-8.84L1.25 2.25h6.83l4.71 6.23 5.45-6.23Zm-1.16 17.52h1.83L7.08 4.13H5.12l11.96 15.64Z\"\n />\n </svg>\n );\n}\n\nexport function LinkedInIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...props}>\n <path\n fill=\"currentColor\"\n d=\"M20.45 20.45h-3.56v-5.57c0-1.33-.03-3.04-1.85-3.04-1.86 0-2.14 1.45-2.14 2.94v5.67H9.34V9h3.42v1.56h.05c.47-.9 1.64-1.85 3.37-1.85 3.6 0 4.27 2.37 4.27 5.46v6.28ZM5.32 7.43a2.07 2.07 0 1 1 0-4.13 2.07 2.07 0 0 1 0 4.13ZM7.1 20.45H3.54V9H7.1v11.45Z\"\n />\n </svg>\n );\n}\n\nexport function DownloadIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"7 10 12 15 17 10\" />\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\" />\n </svg>\n );\n}\n\nexport function ExpandIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M8 3H3v5M16 3h5v5M21 16v5h-5M3 16v5h5\" />\n </svg>\n );\n}\n\nexport function PlayIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...props}>\n <path fill=\"currentColor\" d=\"M7 4.5v15l12-7.5z\" />\n </svg>\n );\n}\n\nexport function PauseIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...props}>\n <path fill=\"currentColor\" d=\"M6 4h4v16H6zM14 4h4v16h-4z\" />\n </svg>\n );\n}\n\nexport function CloudUploadIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M17.5 19H19a4 4 0 0 0 .4-8A7.5 7.5 0 0 0 5 9.5 5 5 0 0 0 6 19h1.5\" />\n <path d=\"m8.5 15.5 3.5-3.5 3.5 3.5M12 12v9\" />\n </svg>\n );\n}\n\nexport function ExternalLinkIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M7 17 17 7M9 7h8v8\" />\n </svg>\n );\n}\n\nexport function GenApiIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"m8 3 4 1.5L16 3v18l-4-1.5L8 21z\" />\n <path d=\"M8 3v18M16 3v18\" />\n </svg>\n );\n}\n\nexport function GitBranchIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <line x1=\"6\" y1=\"3\" x2=\"6\" y2=\"15\" />\n <circle cx=\"18\" cy=\"6\" r=\"3\" />\n <circle cx=\"6\" cy=\"18\" r=\"3\" />\n <path d=\"M18 9a9 9 0 0 1-9 9\" />\n </svg>\n );\n}\n\nexport function GitPullRequestIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <circle cx=\"6\" cy=\"6\" r=\"3\" />\n <circle cx=\"18\" cy=\"18\" r=\"3\" />\n <path d=\"M6 9v12M13 6h3a2 2 0 0 1 2 2v7\" />\n </svg>\n );\n}\n\nexport function GraduationCapIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M21.42 10.92a1 1 0 0 0-.02-1.84L12.83 5.18a2 2 0 0 0-1.66 0L2.6 9.08a1 1 0 0 0 0 1.83l8.57 3.91a2 2 0 0 0 1.66 0z\" />\n <path d=\"M22 10v6\" />\n <path d=\"M6 12.5V16a6 3 0 0 0 12 0v-3.5\" />\n </svg>\n );\n}\n\nexport function SparklesIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M12 3l1.9 5.8a2 2 0 0 0 1.3 1.3L21 12l-5.8 1.9a2 2 0 0 0-1.3 1.3L12 21l-1.9-5.8a2 2 0 0 0-1.3-1.3L3 12l5.8-1.9a2 2 0 0 0 1.3-1.3z\" />\n </svg>\n );\n}\n\nexport function GitHubIcon(props: IconProps) {\n return (\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" {...props}>\n <path\n fill=\"currentColor\"\n d=\"M12 .5A11.5 11.5 0 0 0 8.36 22.9c.58.11.79-.25.79-.56v-2.16c-3.21.7-3.89-1.38-3.89-1.38-.53-1.34-1.29-1.7-1.29-1.7-1.05-.72.08-.7.08-.7 1.16.08 1.77 1.19 1.77 1.19 1.04 1.76 2.71 1.25 3.37.96.11-.75.4-1.25.74-1.54-2.56-.29-5.26-1.28-5.26-5.7 0-1.26.45-2.29 1.19-3.1-.12-.29-.52-1.46.11-3.06 0 0 .97-.31 3.16 1.18a10.88 10.88 0 0 1 5.76 0c2.19-1.49 3.15-1.18 3.15-1.18.63 1.6.23 2.77.11 3.06.74.81 1.19 1.84 1.19 3.1 0 4.43-2.7 5.4-5.27 5.69.41.36.78 1.06.78 2.14v3.19c0 .31.21.68.8.56A11.5 11.5 0 0 0 12 .5Z\"\n />\n </svg>\n );\n}\n\nexport function ImageIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n <circle cx=\"9\" cy=\"9\" r=\"2\" />\n <path d=\"m21 15-5-5L5 21\" />\n </svg>\n );\n}\n\nexport function CubeIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"m21 16-9 5-9-5V8l9-5 9 5z\" />\n <path d=\"m3 8 9 5 9-5\" />\n <path d=\"M12 13v8\" />\n </svg>\n );\n}\n\nexport function AudioIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M9 18V5l12-2v13\" />\n <circle cx=\"6\" cy=\"18\" r=\"3\" />\n <circle cx=\"18\" cy=\"16\" r=\"3\" />\n </svg>\n );\n}\n\nexport function LockIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\" />\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\" />\n </svg>\n );\n}\n\nexport function LogInIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M10 17l5-5-5-5\" />\n <path d=\"M15 12H3\" />\n <path d=\"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4\" />\n </svg>\n );\n}\n\nexport function LogOutIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" />\n <path d=\"m16 17 5-5-5-5\" />\n <path d=\"M21 12H9\" />\n </svg>\n );\n}\n\nexport function MailIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n <path d=\"m3 7 9 7 9-7\" />\n </svg>\n );\n}\n\nexport function McpIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <rect x=\"2\" y=\"4\" width=\"8\" height=\"16\" rx=\"1.5\" />\n <rect x=\"14\" y=\"4\" width=\"8\" height=\"16\" rx=\"1.5\" />\n <path d=\"M10 12h4\" />\n </svg>\n );\n}\n\nexport function MenuIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M4 7h16M4 12h16M4 17h16\" />\n </svg>\n );\n}\n\nexport function NewspaperIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M5 4h12a1 1 0 0 1 1 1v14a1 1 0 0 0 1 1H4a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1h1z\" />\n <path d=\"M18 8h2a1 1 0 0 1 1 1v9a2 2 0 0 1-2 2\" />\n <path d=\"M7 8h7M7 12h7M7 16h4\" />\n </svg>\n );\n}\n\nexport function PlusIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M12 5v14M5 12h14\" />\n </svg>\n );\n}\n\nexport function TerminalIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <polyline points=\"4 8 8 12 4 16\" />\n <line x1=\"12\" y1=\"20\" x2=\"20\" y2=\"20\" />\n </svg>\n );\n}\n\nexport function ToolIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M14.7 6.3a1 1 0 0 0 0 1.4l2.1 2.1a1 1 0 0 0 1.4 0l4-4a6 6 0 0 1-8 8l-8 8a2.8 2.8 0 0 1-4-4l8-8a6 6 0 0 1 8-8l-4 4Z\" />\n </svg>\n );\n}\n\nexport function TargetIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <circle cx=\"12\" cy=\"12\" r=\"5\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.6\" fill=\"currentColor\" stroke=\"none\" />\n </svg>\n );\n}\n\nexport function TokensIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M4 9h16M4 15h16M10 3 8 21M16 3l-2 18\" />\n </svg>\n );\n}\n\nexport function UsageIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M4 18a8 8 0 1 1 16 0\" />\n <path d=\"M12 18l3.5-5\" />\n <path d=\"M7 18h10\" />\n <path d=\"M7.5 12.5 6 11\" />\n <path d=\"M16.5 12.5 18 11\" />\n </svg>\n );\n}\n\nexport function WarningIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M10.3 3.1 1.8 17a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.1a2 2 0 0 0-3.4 0Z\" />\n <path d=\"M12 9v4M12 17h.01\" />\n </svg>\n );\n}\n\nexport function TrendUpIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <polyline points=\"3 17 9 11 13 15 21 7\" />\n <polyline points=\"15 7 21 7 21 13\" />\n </svg>\n );\n}\n\nexport function EarningsIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <ellipse cx=\"10\" cy=\"6\" rx=\"6\" ry=\"3\" />\n <path d=\"M4 6v8c0 1.7 2.7 3 6 3 1.2 0 2.4-.2 3.3-.5\" />\n <path d=\"M16 6v4\" />\n <path d=\"M4 10c0 1.7 2.7 3 6 3 1.1 0 2.1-.1 3-.4\" />\n <path d=\"M18 14v6\" />\n <path d=\"M15 17h6\" />\n </svg>\n );\n}\n\nexport function WalletIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M3 7a2 2 0 0 1 2-2h13a2 2 0 0 1 2 2v2H5a2 2 0 0 0-2 2V7Z\" />\n <path d=\"M3 11a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-6Z\" />\n <circle cx=\"17\" cy=\"14\" r=\"1.25\" fill=\"currentColor\" />\n </svg>\n );\n}\n\n/** A paper receipt: what a price includes. */\nexport function ReceiptIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M6 3h12v18l-2-1.5-2 1.5-2-1.5-2 1.5-2-1.5L6 21Z\" />\n <path d=\"M9 8h6M9 12h6M9 16h3\" />\n </svg>\n );\n}\n\nexport function MoonIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8Z\" />\n </svg>\n );\n}\n\nexport function SunIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <path d=\"M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4\" />\n </svg>\n );\n}\n\nexport function XIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n );\n}\n\nexport function TrashIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M3 6h18\" />\n <path d=\"M8 6V4h8v2\" />\n <path d=\"m19 6-1 15H6L5 6\" />\n <path d=\"M10 11v6M14 11v6\" />\n </svg>\n );\n}\n\n// --- Model modality / capability / price glyphs (single-ink, replace emoji) ---\n\nexport function ChatIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n );\n}\n\nexport function RobotIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <rect x=\"3\" y=\"6\" width=\"18\" height=\"15\" rx=\"3\" />\n <path d=\"M12 2v4M3 11H1v5h2M21 11h2v5h-2M8 17h8\" />\n <circle cx=\"9\" cy=\"12\" r=\"1\" />\n <circle cx=\"15\" cy=\"12\" r=\"1\" />\n </svg>\n );\n}\n\nexport function EyeIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n );\n}\n\nexport function EyeOffIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n <path d=\"M3 3l18 18\" />\n </svg>\n );\n}\n\nexport function VideoIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"m22 8-6 4 6 4V8z\" />\n <rect x=\"2\" y=\"6\" width=\"14\" height=\"12\" rx=\"2\" />\n </svg>\n );\n}\n\nexport function MicIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3z\" />\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\" />\n <path d=\"M12 19v3\" />\n </svg>\n );\n}\n\nexport function SpeakerIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M11 5 6 9H2v6h4l5 4z\" />\n <path d=\"M15.54 8.46a5 5 0 0 1 0 7.07\" />\n <path d=\"M19.07 4.93a10 10 0 0 1 0 14.14\" />\n </svg>\n );\n}\n\nexport function MegaphoneIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"m3 11 18-5v12L3 14v-3z\" />\n <path d=\"m7 15 1.5 6H14l-2-7\" />\n </svg>\n );\n}\n\nexport function ReasoningIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M9 18h6M10 22h4M15.1 14c.2-1 .6-1.7 1.4-2.5A4.6 4.6 0 0 0 18 8 6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.8.8 1.2 1.5 1.4 2.5\" />\n </svg>\n );\n}\n\nexport function RocketIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z\" />\n <path d=\"m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z\" />\n <path d=\"M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0\" />\n <path d=\"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5\" />\n </svg>\n );\n}\n\nexport function SearchIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m21 21-4.3-4.3\" />\n </svg>\n );\n}\n\nexport function SignOutIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" />\n <path d=\"m16 17 5-5-5-5\" />\n <path d=\"M21 12H9\" />\n </svg>\n );\n}\n\nexport function PowerIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M12 2v10\" />\n <path d=\"M18.4 6.6a9 9 0 1 1-12.77.04\" />\n </svg>\n );\n}\n\nexport function SparkleIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M9.94 15.5A2 2 0 0 0 8.5 14.06l-6.14-1.58a.5.5 0 0 1 0-.96L8.5 9.94A2 2 0 0 0 9.94 8.5l1.58-6.14a.5.5 0 0 1 .96 0L14.06 8.5A2 2 0 0 0 15.5 9.94l6.14 1.58a.5.5 0 0 1 0 .96L15.5 14.06a2 2 0 0 0-1.44 1.44l-1.58 6.14a.5.5 0 0 1-.96 0z\" />\n <path d=\"M20 3v4\" />\n <path d=\"M22 5h-4\" />\n <path d=\"M4 17v2\" />\n <path d=\"M5 18H3\" />\n </svg>\n );\n}\n\nexport function StarIcon({\n filled = false,\n ...props\n}: IconProps & { filled?: boolean }) {\n return (\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n {...strokeProps}\n fill={filled ? \"currentColor\" : \"none\"}\n {...props}\n >\n <polygon points=\"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2\" />\n </svg>\n );\n}\n\nexport function CodeIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"m16 18 6-6-6-6M8 6l-6 6 6 6\" />\n </svg>\n );\n}\n\nexport function DatabaseIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\" />\n <path d=\"M3 5v14a9 3 0 0 0 18 0V5\" />\n <path d=\"M3 12a9 3 0 0 0 18 0\" />\n </svg>\n );\n}\n\nexport function CardIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <rect x=\"2\" y=\"5\" width=\"20\" height=\"14\" rx=\"2\" />\n <path d=\"M2 10h20\" />\n </svg>\n );\n}\n\nexport function SproutIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M7 20h10\" />\n <path d=\"M10 20c5.5-2.5.8-6.4 3-10\" />\n <path d=\"M9.5 9.4c1.1.8 1.8 2.2 2.3 3.7-2 .4-3.5.4-4.8-.3-1.2-.6-2.3-1.9-3-4.2 2.8-.5 4.4 0 5.5.8z\" />\n <path d=\"M14.1 6a7 7 0 0 0-1.1 4c1.9-.1 3.3-.6 4.3-1.4 1-1 1.6-2.3 1.7-4.6-2.7.1-4 1-4.9 2z\" />\n </svg>\n );\n}\n\nexport function PencilIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M12 20h9\" />\n <path d=\"M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z\" />\n </svg>\n );\n}\n\nexport function KeyIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <circle cx=\"7.5\" cy=\"15.5\" r=\"5.5\" />\n <path d=\"m21 2-9.6 9.6\" />\n <path d=\"m15.5 7.5 3 3L22 7l-3-3\" />\n </svg>\n );\n}\n\nexport function GlobeIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20\" />\n <path d=\"M2 12h20\" />\n </svg>\n );\n}\n\nexport function ArrowLeftIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M19 12H5\" />\n <path d=\"m12 19-7-7 7-7\" />\n </svg>\n );\n}\n\nexport function RefreshIcon(props: IconProps) {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" {...strokeProps} {...props}>\n <path d=\"M21 12a9 9 0 1 1-2.64-6.36\" />\n <path d=\"M21 3v6h-6\" />\n </svg>\n );\n}\n\nexport type { IconProps } from \"./types.ts\";\n","import type { CSSProperties } from \"react\";\nimport lockupUrl from \"../brand/lockup-horizontal.svg\";\nimport markUrl from \"../brand/mark.svg\";\nimport { cn } from \"../lib/cn.ts\";\n\nexport type BrandMarkProps = {\n variant?: \"mark\" | \"lockup\";\n className?: string;\n};\n\nconst mask = (url: string): CSSProperties => ({\n WebkitMask: `url('${url}') center / contain no-repeat`,\n mask: `url('${url}') center / contain no-repeat`,\n});\n\nconst MASKS = { mark: mask(markUrl), lockup: mask(lockupUrl) };\n\n/** The lotus (or lotus + wordmark) painted in currentColor; size it with className. */\nexport function BrandMark({ variant = \"mark\", className }: BrandMarkProps) {\n return (\n <span\n aria-hidden=\"true\"\n className={cn(\n \"polli:block polli:shrink-0 polli:bg-current\",\n className,\n )}\n style={MASKS[variant]}\n />\n );\n}\n","import type { PropsWithChildren } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\n\ntype BaseDropdownItemProps = {\n className?: string;\n};\n\nexport type DropdownItemProps<T extends React.ElementType = \"button\"> =\n PropsWithChildren<BaseDropdownItemProps> & {\n as?: T;\n } & Omit<\n React.ComponentPropsWithoutRef<T>,\n keyof BaseDropdownItemProps | \"as\"\n >;\n\nexport function DropdownItem<T extends React.ElementType = \"button\">({\n as,\n className,\n children,\n ...rest\n}: DropdownItemProps<T>) {\n const Component: React.ElementType = as || \"button\";\n return (\n <Component\n {...(Component === \"button\" ? { type: \"button\" } : undefined)}\n {...rest}\n className={cn(\n \"polli-control polli:flex polli:w-full polli:cursor-pointer polli:items-center polli:gap-2 polli:rounded-lg polli:bg-transparent polli:px-3 polli:py-2 polli:text-left polli:text-sm polli:font-medium polli:text-theme-text-base polli:no-underline polli:transition-colors polli:hover:bg-theme-bg-hover polli:hover:text-theme-text-hover polli:focus-visible:bg-theme-bg-hover\",\n className,\n )}\n >\n {children}\n </Component>\n );\n}\n","import { useAuthActions, useAuthState } from \"@pollinations/sdk/react\";\nimport type { ReactNode } from \"react\";\nimport { Button, type ButtonProps } from \"../../primitives/Button.tsx\";\n\nexport type LoginButtonProps = Omit<\n ButtonProps<\"button\">,\n \"as\" | \"onClick\" | \"children\"\n> & {\n children: ReactNode;\n};\n\n/** Button that kicks off the auth redirect. `null` when already logged in. */\nexport function LoginButton({ children, ...buttonProps }: LoginButtonProps) {\n const { isLoggedIn } = useAuthState();\n const { login } = useAuthActions();\n if (isLoggedIn) return null;\n return (\n <Button {...buttonProps} onClick={() => login()}>\n {children}\n </Button>\n );\n}\n","import type {\n PropsWithChildren,\n MouseEvent as ReactMouseEvent,\n ReactNode,\n} from \"react\";\nimport { cn } from \"../lib/cn.ts\";\n\n/** Semantic action roles. Label recipes live on Chip. */\ntype ButtonIntent = \"danger\" | \"info\" | \"neutral\" | \"brand\" | \"commit\";\nexport type ButtonAppearance = \"pill\" | \"raised\";\n\nconst pillSizes = {\n icon: \"polli:h-12 polli:w-12 polli:p-0\",\n xs: \"polli:h-5 polli:px-1.5 polli:py-0 polli:text-[11px] polli:leading-none\",\n sm: \"polli:min-h-7 polli:px-2 polli:pt-0.5 polli:pb-1\",\n md: \"polli:min-h-9 polli:px-4 polli:pt-1.5 polli:pb-2\",\n lg: \"polli:min-h-12 polli:px-6 polli:py-3 polli:text-base\",\n} as const;\n\nconst raisedSizes = {\n icon: \"polli:h-12 polli:w-12 polli:p-0\",\n xs: \"polli:px-2 polli:py-1 polli:text-xs\",\n sm: \"polli:px-4 polli:py-2 polli:text-sm\",\n md: \"polli:px-7 polli:py-3.5 polli:text-base\",\n lg: \"polli:px-8 polli:py-4 polli:text-lg\",\n} as const;\n\nconst appearanceClasses: Record<ButtonAppearance, string> = {\n pill: \"polli:rounded-full\",\n raised:\n \"polli:rounded-xl polli:border-r-[3px] polli:border-b-[3px] polli:border-solid \" +\n \"polli:border-theme-text-strong/20 polli:hover:border-theme-text-strong/45\",\n};\n\n// Cascade-driven base — reads [data-theme] vars.\nconst themeClasses =\n \"polli:bg-theme-bg-active polli:text-theme-text-strong \" +\n \"polli:hover:bg-theme-bg-hover polli:hover:text-theme-text-hover polli:transition-colors\";\n\n// Primary actions have a soft accent fill in light mode and an outline in dark.\n// `brand` keeps a calm hover; `commit` strengthens the fill on hover and focus.\nconst outlined =\n \"polli:border polli:border-theme-text-soft polli:bg-theme-bg-active/30 polli:text-theme-text-strong \" +\n \"polli:transition-colors polli:[.dark_&]:bg-transparent\";\nconst intentClasses: Record<ButtonIntent, string> = {\n brand: `${outlined} polli:hover:bg-theme-bg-active/50 polli:[.dark_&]:hover:bg-theme-text-soft/10`,\n commit:\n `${outlined} polli:hover:border-theme-bg-active polli:hover:bg-theme-bg-active ` +\n \"polli:focus-visible:border-theme-bg-active polli:focus-visible:bg-theme-bg-active \" +\n \"polli:[.dark_&]:hover:bg-theme-bg-active polli:[.dark_&]:focus-visible:bg-theme-bg-active\",\n danger:\n \"polli:border polli:border-intent-danger-text polli:bg-intent-danger-bg-light polli:text-intent-danger-text \" +\n \"polli:hover:bg-intent-danger-bg-hover polli:focus-visible:bg-intent-danger-bg-hover polli:transition-colors \" +\n \"polli:[.dark_&]:bg-transparent polli:[.dark_&]:hover:bg-intent-danger-bg-hover polli:[.dark_&]:focus-visible:bg-intent-danger-bg-hover\",\n info:\n \"polli:bg-intent-info-bg-light polli:text-intent-info-text \" +\n \"polli:hover:bg-intent-info-bg-hover polli:transition-colors\",\n // Secondary actions never take the accent: one step stronger grey on hover.\n neutral:\n \"polli:bg-theme-bg-subtle polli:text-theme-text-base \" +\n \"polli:hover:bg-theme-text-muted/25 polli:hover:text-theme-text-strong polli:transition-colors\",\n};\n\ntype BaseButtonProps = {\n icon?: ReactNode;\n /** Optional semantic recipe; omit for the ambient theme button. */\n intent?: ButtonIntent;\n /** `raised` is the stronger website CTA treatment. */\n appearance?: ButtonAppearance;\n size?: keyof typeof pillSizes;\n className?: string;\n disabled?: boolean;\n};\n\nconst buttonClasses = ({\n intent,\n appearance = \"pill\",\n size,\n className,\n disabled,\n busy,\n}: BaseButtonProps & { disabled?: boolean; busy?: boolean }) => {\n const colorClasses = intent ? intentClasses[intent] : themeClasses;\n const sizeClasses = appearance === \"raised\" ? raisedSizes : pillSizes;\n return cn(\n \"polli-control polli:inline-flex polli:items-center polli:justify-center polli:self-center polli:font-body polli:text-sm polli:font-medium polli:leading-normal polli:box-border polli:border polli:border-transparent\",\n // A busy button is working, not unavailable: it keeps its strength.\n busy\n ? \"polli:cursor-progress\"\n : disabled\n ? \"polli:opacity-50 polli:cursor-not-allowed\"\n : \"polli:hover:filter polli:hover:brightness-105 polli:cursor-pointer\",\n colorClasses,\n appearanceClasses[appearance],\n sizeClasses[size || \"md\"],\n className,\n );\n};\n\nexport type ButtonProps<T extends React.ElementType = \"button\"> =\n PropsWithChildren<BaseButtonProps> & {\n as?: T;\n } & Omit<React.ComponentPropsWithoutRef<T>, keyof BaseButtonProps | \"as\">;\n\nexport function Button<T extends React.ElementType = \"button\">({\n as,\n children,\n icon,\n intent,\n appearance,\n size,\n className,\n disabled,\n ...buttonProps\n}: ButtonProps<T>) {\n const Component: React.ElementType = as || \"button\";\n const isButton = Component === \"button\";\n const isAnchor = Component === \"a\";\n const buttonType = (\n buttonProps as {\n type?: \"button\" | \"submit\" | \"reset\";\n }\n ).type;\n const onClick = (\n buttonProps as {\n onClick?: (event: ReactMouseEvent) => void;\n }\n ).onClick;\n const ariaBusy = (\n buttonProps as { \"aria-busy\"?: boolean | \"true\" | \"false\" }\n )[\"aria-busy\"];\n const busy = ariaBusy === true || ariaBusy === \"true\";\n const handleClick = disabled\n ? (event: ReactMouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n }\n : onClick;\n\n return (\n <Component\n {...buttonProps}\n data-intent={intent}\n {...(isButton ? { type: buttonType ?? \"button\", disabled } : {})}\n {...(!isButton && disabled\n ? { \"aria-disabled\": true, tabIndex: -1 }\n : {})}\n {...(isAnchor && disabled ? { href: undefined } : {})}\n onClick={handleClick}\n className={buttonClasses({\n intent,\n appearance,\n size,\n className,\n disabled,\n busy,\n })}\n >\n {icon && (\n <span\n aria-hidden=\"true\"\n className=\"polli:mr-2 polli:flex polli:size-4 polli:shrink-0 polli:[&>svg]:size-full\"\n >\n {busy ? (\n <span className=\"polli:block polli:size-full polli:animate-spin polli:rounded-full polli:border-2 polli:border-current polli:border-r-transparent polli:motion-reduce:animate-none\" />\n ) : (\n icon\n )}\n </span>\n )}\n {children}\n </Component>\n );\n}\n","import type { ComponentPropsWithoutRef, FC } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\n\n/** Semantic chip labels for status and metadata badges. */\ntype ChipIntent =\n | \"news\"\n | \"new\"\n | \"free\"\n | \"alpha\"\n | \"neutral\"\n | \"success\"\n | \"warning\"\n | \"info\"\n | \"danger\";\n\nconst chipSizes = {\n icon: \"polli:h-5 polli:w-5 polli:p-0 polli:text-xs\",\n sm: \"polli:h-5 polli:px-2 polli:text-xs\",\n md: \"polli:h-6 polli:px-2.5 polli:text-sm\",\n lg: \"polli:h-7 polli:px-3 polli:text-sm\",\n} as const;\n\nconst intentClasses: Record<ChipIntent, string> = {\n news: \"polli:bg-intent-news-bg-light polli:text-intent-news-text\",\n new: \"polli:bg-intent-new-bg-light polli:text-intent-new-text\",\n free: \"polli:bg-intent-free-bg-light polli:text-intent-free-text\",\n alpha: \"polli:bg-intent-alpha-bg-light polli:text-intent-alpha-text\",\n neutral: \"polli:bg-ink-100/80 polli:text-ink-900\",\n success:\n \"polli:bg-intent-success-bg-bright/15 polli:text-intent-success-text\",\n warning: \"polli:bg-intent-warning-bg-light polli:text-intent-warning-text\",\n info: \"polli:bg-intent-info-bg-light polli:text-intent-info-text\",\n danger: \"polli:bg-intent-danger-bg-light polli:text-intent-danger-text\",\n};\n\nexport type ChipProps = ComponentPropsWithoutRef<\"span\"> & {\n /** Semantic intent. */\n intent?: ChipIntent;\n size?: keyof typeof chipSizes;\n};\n\n// Static, rectangular colored container. Round shapes are reserved for buttons.\n// Reads `bg-theme-bg-active` / `text-theme-text-strong` from the cascade unless\n// `intent` is set (semantic, theme-independent).\nexport const Chip: FC<ChipProps> = ({\n intent,\n size = \"md\",\n className,\n children,\n ...rest\n}) => {\n const intentClass = intent\n ? intentClasses[intent]\n : \"polli:bg-theme-bg-active polli:text-theme-text-strong\";\n return (\n <span\n {...rest}\n className={cn(\n \"polli:inline-flex polli:shrink-0 polli:items-center polli:justify-center polli:gap-1 polli:rounded-lg polli:font-medium polli:leading-none\",\n chipSizes[size],\n intentClass,\n className,\n )}\n >\n {children}\n </span>\n );\n};\n","/** Relative URLs and same-origin absolute URLs stay in the current app. */\nexport function isExternalHref(\n href: unknown,\n origin = globalThis.location?.origin,\n): boolean {\n if (typeof href !== \"string\" || !/^(https?:)?\\/\\//i.test(href))\n return false;\n if (!origin) return true;\n try {\n return new URL(href, origin).origin !== origin;\n } catch {\n return false;\n }\n}\n","import type { PropsWithChildren } from \"react\";\nimport { isExternalHref } from \"../lib/link.ts\";\nimport { ExternalLinkIcon } from \"./icons/index.tsx\";\n\ntype BaseInlineLinkProps = {\n /** Set explicitly for non-http external links, or false for custom routing components. */\n external?: boolean;\n showIcon?: boolean;\n /** Inline text inherits its size; footers use 13px and standalone links 14px. */\n size?: \"inherit\" | \"footer\" | \"sm\";\n /** Accent for prominent links; quiet for secondary navigation. */\n tone?: \"accent\" | \"quiet\";\n className?: string;\n};\n\nexport type InlineLinkProps<T extends React.ElementType = \"a\"> =\n PropsWithChildren<BaseInlineLinkProps> & {\n as?: T;\n } & Omit<\n React.ComponentPropsWithoutRef<T>,\n keyof BaseInlineLinkProps | \"as\"\n >;\n\n/** Shared text-link rule: surrounding font, selectable ink, persistent underline,\n * visible keyboard focus, and an external arrow only when leaving the app.\n * Navigation and button-shaped actions use their own primitives.\n */\nexport function InlineLink<T extends React.ElementType = \"a\">({\n as,\n external,\n showIcon = true,\n size = \"inherit\",\n tone = \"accent\",\n className,\n children,\n ...linkProps\n}: InlineLinkProps<T>) {\n const Component: React.ElementType = as || \"a\";\n const isExternal =\n external ?? isExternalHref((linkProps as { href?: unknown }).href);\n\n return (\n <Component\n target={isExternal && as !== \"button\" ? \"_blank\" : undefined}\n rel={\n isExternal && as !== \"button\"\n ? \"noopener noreferrer\"\n : undefined\n }\n className={[\"polli-link\", className].filter(Boolean).join(\" \")}\n data-size={size}\n data-tone={tone}\n {...linkProps}\n >\n {children}\n {showIcon && isExternal && (\n <ExternalLinkIcon\n aria-hidden=\"true\"\n className=\"polli-link-external-icon\"\n />\n )}\n </Component>\n );\n}\n","// 5-digit budget for pollen display. Integer takes its space, decimals fill\n// the remainder (capped at 4), floor toward -infinity, trailing zeros stripped.\n// Integers needing >=6 digits switch to compact (K/M/B, 3 sig figs).\n// Decimal point and minus sign do not count toward the budget.\n\nconst BUDGET = 5;\nconst MAX_DECIMALS = 4;\nconst COMPACT_THRESHOLD = 100_000;\n\nfunction floorTo(value: number, decimals: number): number {\n const factor = 10 ** decimals;\n return Math.floor(value * factor) / factor;\n}\n\nfunction formatCompact(value: number): string {\n const abs = Math.abs(value);\n const sign = value < 0 ? \"-\" : \"\";\n const [unit, scale] =\n abs >= 1e9\n ? ([\"B\", 1e9] as const)\n : abs >= 1e6\n ? ([\"M\", 1e6] as const)\n : ([\"K\", 1e3] as const);\n const ratio = abs / scale;\n const intDigits = Math.max(1, Math.floor(Math.log10(ratio)) + 1);\n const decimals = Math.max(0, 3 - intDigits);\n const floored = floorTo(ratio, decimals);\n return `${sign}${Number(floored.toFixed(decimals)).toString()}${unit}`;\n}\n\nexport function formatPollen(value: number): string {\n if (!Number.isFinite(value) || value === 0) return \"0\";\n\n const abs = Math.abs(value);\n\n if (abs >= COMPACT_THRESHOLD) return formatCompact(value);\n\n const intDigits = abs >= 1 ? Math.floor(Math.log10(abs)) + 1 : 1;\n const decimals = Math.min(MAX_DECIMALS, Math.max(0, BUDGET - intDigits));\n const floored = floorTo(value, decimals);\n if (floored === 0) return \"0\";\n return Number(floored.toFixed(decimals)).toString();\n}\n","import type { FC, ReactNode } from \"react\";\nimport { cn } from \"../../lib/cn.ts\";\nimport { CardIcon, SproutIcon } from \"../../primitives/icons/index.tsx\";\n\ntype WalletBalanceKind = \"paid\" | \"tier\";\n\nconst walletPanelClasses: Record<WalletBalanceKind, string> = {\n paid: \"polli-wallet-panel-paid\",\n tier: \"polli-wallet-panel-tier\",\n};\n\nconst walletTextClasses: Record<WalletBalanceKind, string> = {\n paid: \"polli-wallet-text-paid\",\n tier: \"polli-wallet-text-tier\",\n};\n\nconst walletKindIcons: Record<WalletBalanceKind, typeof CardIcon> = {\n paid: CardIcon,\n tier: SproutIcon,\n};\n\nexport type WalletKindIconProps = {\n kind: WalletBalanceKind;\n className?: string;\n};\n\n/** The paid/Quest marker: a card for paid balance or sprout for Quest Pollen. */\nexport const WalletKindIcon: FC<WalletKindIconProps> = ({\n kind,\n className,\n}) => {\n const Icon = walletKindIcons[kind];\n return (\n <Icon\n aria-hidden=\"true\"\n className={cn(\n \"polli:h-3.5 polli:w-3.5 polli:shrink-0\",\n walletTextClasses[kind],\n className,\n )}\n />\n );\n};\n\nexport type WalletBalanceCardProps = {\n tone?: \"balance\" | \"neutral\";\n kind: WalletBalanceKind;\n label: ReactNode;\n value: ReactNode;\n icon?: ReactNode;\n info?: ReactNode;\n footer?: ReactNode;\n className?: string;\n};\n\nexport const WalletBalanceCard: FC<WalletBalanceCardProps> = ({\n tone = \"balance\",\n kind,\n label,\n value,\n icon,\n info,\n footer,\n className,\n}) => {\n const Icon = walletKindIcons[kind];\n const textColor =\n tone === \"neutral\"\n ? \"polli:text-theme-text-strong\"\n : walletTextClasses[kind];\n return (\n <div\n className={cn(\n \"polli:min-w-0 polli:rounded-card polli:p-3.5 polli:sm:p-5\",\n tone === \"neutral\"\n ? \"polli:bg-surface-opaque\"\n : walletPanelClasses[kind],\n className,\n )}\n >\n <span className=\"polli:flex polli:items-center polli:gap-2\">\n {icon ?? (\n <Icon\n aria-hidden=\"true\"\n className={cn(\n \"polli:h-3.5 polli:w-3.5 polli:shrink-0\",\n textColor,\n )}\n />\n )}\n <span\n className={cn(\n \"polli:text-sm polli:font-bold polli:uppercase polli:tracking-wide\",\n textColor,\n )}\n >\n {label}\n </span>\n {info}\n </span>\n <div\n className={cn(\n \"polli-wallet-balance-value polli:[overflow-wrap:anywhere] polli:mt-1 polli:font-bold polli:leading-none polli:tracking-tight polli:tabular-nums\",\n textColor,\n )}\n >\n {value}\n </div>\n {footer && (\n <div className=\"polli:mt-1.5 polli:text-sm polli:font-bold polli:tabular-nums polli:text-intent-success-text\">\n {footer}\n </div>\n )}\n </div>\n );\n};\n","import { Chip } from \"../../primitives/Chip.tsx\";\nimport { InlineLink } from \"../../primitives/InlineLink.tsx\";\nimport { KeyIcon, WalletIcon } from \"../../primitives/icons/index.tsx\";\nimport { formatPollen } from \"./format-pollen.ts\";\nimport { WalletKindIcon } from \"./wallet-display.tsx\";\n\nexport type AccountPollenSource =\n | {\n type: \"wallet\";\n /** Undefined while the balance is unavailable. */\n balances?: { paid: number; quest: number };\n }\n | {\n type: \"budget\";\n /** The app's remaining budget, never the owner's wallet total. `null` = unlimited. */\n remaining?: number | null;\n generationEnabled?: boolean;\n };\n\nfunction isEmpty(amount: number | null | undefined): boolean {\n return amount != null && amount <= 0;\n}\n\ntype PollenStatus = \"limit-reached\" | \"no-pollen\" | \"unlimited\";\n\nconst labels: Record<PollenStatus, string> = {\n \"limit-reached\": \"Limit reached\",\n \"no-pollen\": \"No Pollen\",\n unlimited: \"Unlimited\",\n};\n\nfunction PollenStatusBadge({\n state,\n topUpHref,\n}: {\n state: PollenStatus;\n topUpHref?: string;\n}) {\n const Icon = state === \"no-pollen\" ? WalletIcon : KeyIcon;\n const label = labels[state];\n return (\n <Chip\n size=\"sm\"\n intent={state === \"unlimited\" ? \"info\" : \"danger\"}\n aria-label={label}\n >\n <Icon\n aria-hidden=\"true\"\n className=\"polli:h-3.5 polli:w-3.5 polli:shrink-0\"\n />\n {label}\n {state === \"no-pollen\" && topUpHref && (\n <>\n <span aria-hidden=\"true\">·</span>\n <InlineLink\n href={topUpHref}\n aria-label={`${label}. Top up`}\n >\n Top up\n </InlineLink>\n </>\n )}\n </Chip>\n );\n}\n\n/** Icon + amount; unlimited, exhausted, or empty states become a badge. */\nexport function AccountPollen({\n source,\n topUpHref,\n}: {\n source: AccountPollenSource;\n /** Shown in the empty-wallet badge. A menu keeps recovery links in its dropdown. */\n topUpHref?: string;\n}) {\n if (source.type === \"budget\") {\n if (source.generationEnabled === false) return null;\n // null is the API's explicit \"no budget\"; undefined is not loaded yet.\n const unlimited = source.remaining === null;\n if (!unlimited && source.remaining === undefined) return null;\n if (unlimited) return <PollenStatusBadge state=\"unlimited\" />;\n const remaining = source.remaining as number;\n if (isEmpty(remaining))\n return <PollenStatusBadge state=\"limit-reached\" />;\n return (\n <span\n title=\"App budget left\"\n className=\"polli:inline-flex polli:items-center polli:gap-1 polli:tabular-nums\"\n >\n <KeyIcon\n aria-hidden=\"true\"\n className=\"polli:h-3.5 polli:w-3.5 polli:shrink-0\"\n />\n <span className=\"polli:sr-only\">App budget: </span>\n {formatPollen(remaining)} pollen\n </span>\n );\n }\n const { balances } = source;\n if (!balances) return null;\n if (isEmpty(balances.paid) && isEmpty(balances.quest))\n return <PollenStatusBadge state=\"no-pollen\" topUpHref={topUpHref} />;\n return (\n <span className=\"polli:inline-flex polli:items-center polli:gap-2 polli:tabular-nums\">\n {/* Quest Pollen is spent first, so it comes first. */}\n {([\"quest\", \"paid\"] as const).map((kind) => {\n const amount = balances[kind];\n return (\n <span\n key={kind}\n className=\"polli:inline-flex polli:items-center polli:gap-1\"\n >\n <WalletKindIcon\n kind={kind === \"paid\" ? \"paid\" : \"tier\"}\n />\n <span className=\"polli:sr-only\">\n {kind === \"paid\" ? \"Paid\" : \"Quest\"} Pollen:{\" \"}\n </span>\n {formatPollen(Math.max(0, amount))}\n </span>\n );\n })}\n </span>\n );\n}\n"],"mappings":"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","names":["useAuthActions","useAuthState","useId","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsx","jsxs","jsxs","jsx","useId","jsx","jsx","jsx","jsxs","jsx","jsx","intentClasses","jsx","jsxs","jsx","jsxs","jsx","jsx","jsxs","Fragment","jsx","jsxs","labels","useAuthActions","useAuthState"]}
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="174" height="20" viewBox="0 0 174 20" role="img" aria-label="Made with pollinations.ai"><title>Made with pollinations.ai</title><clipPath id="r"><rect width="174" height="20" rx="3"/></clipPath><g clip-path="url(#r)"><rect width="67" height="20" fill="#555"/><rect x="67" width="107" height="20" fill="#000"/></g><g fill="#fff" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="11"><text x="6" y="14" textLength="55" lengthAdjust="spacingAndGlyphs">Made with</text><svg x="73" y="3" width="14" height="14" viewBox="15 17.6409 119.9998 114.7498" fill="#fff"><path fill-rule="evenodd" d="M73.832 19.293a1893.685 1893.685 0 0 0-7.742 9.047c-1.93 2.273-3.274 3.898-4.266 5.156-.988 1.258-1.62 2.149-2.117 2.957-.5.805-.86 1.531-1.309 2.453-.14.285-.277.563-.402.813-.121.254-.238.48-.332.676a20.107 20.107 0 0 1-.34.652c-.008.008-.062 0-.156-.02s-.227-.047-.383-.09c-.16-.039-.351-.09-.558-.148-.207-.059-.43-.121-.668-.191-1.079-.32-1.895-.559-2.684-.743-.79-.18-1.55-.3-2.516-.382-.96-.082-2.129-.121-3.734-.145-1.602-.02-3.64-.023-6.348-.023H35.31l-2.485-.004H30.34v20.574l-.527.059-.524.058-1.055.117c-.59.067-1.203.157-1.84.274-.636.113-1.292.25-1.968.414-.676.16-1.371.348-2.086.555-.715.21-1.445.441-2.195.695-.47.16-1.024.36-1.594.574a64.38 64.38 0 0 0-1.684.649c-.523.207-.992.398-1.328.546-.336.149-.539.246-.539.274 0 .039.07.234.191.535.118.297.29.7.485 1.156.195.453.418.961.644 1.473.227.508.461 1.02.676 1.484a52.041 52.041 0 0 0 9.54 13.926 47.507 47.507 0 0 0 6.14 5.41c2.164 1.59 4.426 2.953 6.75 4.047a51.197 51.197 0 0 0 3.414 1.461c1.129.43 2.242.805 3.36 1.125 1.112.324 2.226.59 3.343.809a39.04 39.04 0 0 0 3.375.504c.84.085 1.781.136 2.777.156a51.632 51.632 0 0 0 6.203-.266 34.786 34.786 0 0 0 2.836-.394 59.177 59.177 0 0 1 2.633-.442c.149-.02.235-.023.246-.015.043.043-.02.195-.152.414a9.01 9.01 0 0 1-.582.812c-.242.313-.527.645-.813.965-.289.316-.582.617-.851.86-.57.519-1.168.968-1.809 1.355-.64.383-1.324.703-2.07.969-.746.261-1.555.464-2.441.617-.891.156-1.856.258-2.926.316-1.36.07-2.582.207-3.703.422-1.118.211-2.13.496-3.07.871-.938.375-1.801.84-2.618 1.403a15.82 15.82 0 0 0-2.351 2 14.205 14.205 0 0 0-1.489 1.765 13.256 13.256 0 0 0-1.148 1.945 15.518 15.518 0 0 0-.856 2.207 20.834 20.834 0 0 0-.59 2.543c-.058.348-.105.61-.156.817-.05.207-.105.36-.183.484a1.184 1.184 0 0 1-.325.332c-.144.106-.332.211-.578.356a9.157 9.157 0 0 0-2.543 2.183 8.797 8.797 0 0 0-1.52 2.813 8.33 8.33 0 0 0-.382 3.113 7.995 7.995 0 0 0 .852 3.098 7.95 7.95 0 0 0 1.574 2.117 9.294 9.294 0 0 0 2.168 1.566c.789.418 1.629.715 2.469.868.84.152 1.68.167 2.472.007a7.941 7.941 0 0 0 1.188-.336c.406-.144.82-.32 1.222-.515.399-.2.79-.418 1.149-.653.36-.234.691-.476.976-.73a6.93 6.93 0 0 0 1.473-1.86c.39-.71.68-1.492.855-2.308.176-.82.243-1.676.188-2.527a8.74 8.74 0 0 0-.531-2.516 5.919 5.919 0 0 0-.68-1.281c-.289-.43-.64-.856-1.031-1.258a10.34 10.34 0 0 0-1.262-1.11 8.299 8.299 0 0 0-1.379-.847c-.414-.2-.722-.352-.95-.492-.226-.137-.366-.27-.44-.43-.075-.16-.083-.352-.043-.613.039-.266.125-.598.242-1.043.226-.871.566-1.695 1.004-2.465a10.426 10.426 0 0 1 3.672-3.754c.77-.46 1.605-.836 2.492-1.102.152-.046.386-.093.675-.144a30.829 30.829 0 0 1 2.246-.273c.43-.043.876-.075 1.317-.102a41.754 41.754 0 0 0 2.773-.25 19.813 19.813 0 0 0 2.243-.406 13.283 13.283 0 0 0 1.918-.621c.609-.246 1.199-.536 1.804-.88a20.824 20.824 0 0 0 1.774-1.116c.539-.383 1.031-.786 1.511-1.227.48-.445.942-.934 1.415-1.488.468-.559.953-1.18 1.468-1.899l.309-.426.308-.43.313-.429.309-.426v19.633l-.399.262-.402.265-.797.532a11.66 11.66 0 0 0-1.567 1.21c-.44.41-.808.837-1.113 1.305-.305.465-.55.97-.746 1.535-.2.567-.351 1.192-.473 1.903a7.401 7.401 0 0 0 .024 2.574 8.502 8.502 0 0 0 2.441 4.543 7.787 7.787 0 0 0 2.157 1.496c.804.367 1.632.61 2.46.715.829.105 1.66.082 2.47-.07a7.963 7.963 0 0 0 2.343-.828 8.831 8.831 0 0 0 2.094-1.567c.406-.402.738-.789 1.011-1.18.27-.394.48-.796.641-1.234.156-.441.266-.918.336-1.473.07-.55.102-1.171.105-1.894 0-.524 0-.93-.011-1.266a6.504 6.504 0 0 0-.074-.836 3.967 3.967 0 0 0-.192-.683c-.09-.23-.207-.485-.355-.805a7.845 7.845 0 0 0-1.594-2.262 8.117 8.117 0 0 0-1.07-.879 9.342 9.342 0 0 0-1.254-.718l-.348-.164-.348-.16-.343-.165-.348-.164v-4.957l-.004-2.476v-2.48c0-1.36.004-2.657.012-3.833.008-1.176.02-2.23.035-3.11.016-.882.035-1.589.055-2.07.02-.48.043-.734.066-.707.02.028.074.102.156.208l.301.421c.121.168.258.364.406.575.145.207.305.433.461.664.38.543.735 1.027 1.09 1.468.352.438.703.832 1.063 1.2.363.367.742.707 1.148 1.039.406.328.844.652 1.332.98.777.528 1.5.965 2.223 1.328.718.364 1.437.657 2.203.89.765.235 1.582.411 2.496.544.914.137 1.93.23 3.094.3.433.024.867.055 1.289.087a40.742 40.742 0 0 1 2.148.215c.27.035.477.07.602.101.965.234 1.898.64 2.761 1.168a11.119 11.119 0 0 1 2.34 1.93 10.355 10.355 0 0 1 1.688 2.437c.43.867.707 1.781.805 2.695l.03.313.032.309.035.316.031.309-.27.14-.538.274-.274.136c-.828.426-1.558.922-2.183 1.493a7.954 7.954 0 0 0-1.54 1.91 7.731 7.731 0 0 0-.87 2.273 9.264 9.264 0 0 0-.172 2.594c.066.96.285 1.871.64 2.703a7.903 7.903 0 0 0 1.446 2.258 8.316 8.316 0 0 0 2.14 1.683c.817.45 1.727.782 2.715.98 1.309.255 2.617.126 3.836-.3a8.813 8.813 0 0 0 3.266-2.05 8.893 8.893 0 0 0 2.117-3.239c.453-1.21.613-2.527.387-3.848a9.06 9.06 0 0 0-1.504-3.644 9.344 9.344 0 0 0-1.301-1.477 8.97 8.97 0 0 0-1.61-1.16c-.18-.097-.347-.2-.507-.293-.16-.097-.305-.183-.434-.265-.125-.082-.23-.153-.312-.211a.573.573 0 0 1-.137-.121.813.813 0 0 1-.063-.184c-.027-.094-.058-.223-.097-.375a11.147 11.147 0 0 1-.11-.512c-.039-.187-.082-.39-.12-.594-.098-.5-.227-1.023-.383-1.554a19.7 19.7 0 0 0-.551-1.594c-.207-.527-.43-1.039-.668-1.512a12.868 12.868 0 0 0-.735-1.3 12.93 12.93 0 0 0-1.582-1.954 15.064 15.064 0 0 0-1.98-1.691 15.833 15.833 0 0 0-2.27-1.355 14.35 14.35 0 0 0-2.449-.934 9.33 9.33 0 0 0-.836-.188 25.72 25.72 0 0 0-1.094-.18 40.224 40.224 0 0 0-2.605-.269 51.614 51.614 0 0 1-1.281-.11 47.27 47.27 0 0 1-1.242-.128 37.65 37.65 0 0 1-1.067-.14 12.643 12.643 0 0 1-.746-.133 11.48 11.48 0 0 1-1.508-.458c-.5-.187-.996-.414-1.472-.668a12.371 12.371 0 0 1-2.606-1.847 16.117 16.117 0 0 1-1.676-1.836 5.604 5.604 0 0 1-.465-.707c-.097-.192-.125-.324-.074-.375.016-.016.117-.012.285.004.168.015.407.047.696.09.293.039.633.093 1.008.156.37.062.78.137 1.207.215a60.65 60.65 0 0 0 1.789.304c.527.079 1.011.133 1.535.172.523.04 1.09.063 1.777.078.692.016 1.504.02 2.527.024 1.22 0 2.204-.008 3.06-.031a27.474 27.474 0 0 0 2.257-.153 20.662 20.662 0 0 0 2.047-.336 48.885 48.885 0 0 0 2.426-.59 44.634 44.634 0 0 0 5.347-1.761 42.256 42.256 0 0 0 4.98-2.387 43.059 43.059 0 0 0 4.633-3.031 46.976 46.976 0 0 0 4.329-3.692 55.822 55.822 0 0 0 3.312-3.468 49.244 49.244 0 0 0 2.879-3.63 50.142 50.142 0 0 0 2.516-3.886 57.29 57.29 0 0 0 2.23-4.258c.375-.793.691-1.48.95-2.066.257-.59.46-1.078.613-1.473.144-.398.242-.7.285-.918.047-.219.039-.351-.016-.402-.078-.07-.41-.23-.902-.442a57.272 57.272 0 0 0-1.828-.73c-.692-.262-1.434-.535-2.121-.777a36.517 36.517 0 0 0-1.778-.586 54.289 54.289 0 0 0-3.531-.879 48.341 48.341 0 0 0-1.715-.332 23.874 23.874 0 0 0-1.465-.215l-.633-.07-.312-.04-.316-.035V39.301l-2.461.004h-2.461l-2.457.004h-2.461c-2.645.004-4.664.007-6.266.03-1.605.024-2.797.067-3.789.141-.992.079-1.789.192-2.598.356-.812.164-1.64.383-2.703.668a23.531 23.531 0 0 1-1.203.3c-.16.036-.289.06-.383.075-.093.016-.148.02-.156.008a29.962 29.962 0 0 1-.355-.672c-.102-.2-.22-.434-.348-.692a79.19 79.19 0 0 1-.418-.828c-.45-.902-.785-1.578-1.168-2.234-.379-.66-.805-1.297-1.422-2.117-.617-.817-1.433-1.82-2.594-3.203-1.16-1.387-2.671-3.153-4.68-5.508-1.398-1.64-2.53-2.961-3.44-4.02a272.265 272.265 0 0 0-2.122-2.441c-.523-.59-.875-.973-1.11-1.211-.237-.234-.355-.324-.402-.32-.015 0-.07.047-.156.132-.086.086-.199.207-.34.356-.136.148-.296.328-.472.523-.172.2-.364.414-.555.641m7.059 11.504a151.52 151.52 0 0 1 3.582 4.336 58.05 58.05 0 0 1 2.488 3.336c.66.965 1.16 1.793 1.516 2.515.355.72.57 1.332.66 1.868.023.14.039.25.031.347a.526.526 0 0 1-.09.262 1.205 1.205 0 0 1-.266.262c-.12.093-.285.199-.492.332-.332.21-.773.554-1.265.976-.493.426-1.043.934-1.594 1.473a43.455 43.455 0 0 0-1.625 1.672 25.487 25.487 0 0 0-1.348 1.574c-.398.512-.812 1.09-1.222 1.703a39.76 39.76 0 0 0-1.204 1.91 39.73 39.73 0 0 0-1.085 1.946c-.329.636-.622 1.25-.86 1.812-.34.809-.672 1.727-.976 2.688-.305.96-.582 1.964-.817 2.945-.234.984-.43 1.945-.562 2.816-.137.871-.215 1.653-.215 2.282-.004.609-.024 1.054-.055 1.332-.035.277-.086.386-.152.328-.067-.055-.149-.278-.246-.664a26.572 26.572 0 0 1-.336-1.66 76.29 76.29 0 0 0-.54-2.758 81.86 81.86 0 0 0-.624-2.66c-.211-.844-.43-1.637-.645-2.34a22.878 22.878 0 0 0-.617-1.801 24.472 24.472 0 0 0-.742-1.66 48.94 48.94 0 0 0-2.047-3.746c-.36-.59-.707-1.13-1.027-1.582a21.393 21.393 0 0 0-1.153-1.446 44.776 44.776 0 0 0-1.558-1.71 47.283 47.283 0 0 0-1.657-1.657c-.539-.512-1.043-.96-1.468-1.3-.172-.141-.34-.278-.489-.41a8.144 8.144 0 0 1-.402-.376 3.846 3.846 0 0 1-.27-.293c-.066-.082-.101-.144-.101-.176 0-.105.098-.378.262-.753.16-.372.386-.848.644-1.356.258-.508.547-1.05.828-1.562a24.735 24.735 0 0 1 1.582-2.508c.262-.371.543-.746.871-1.16.329-.418.7-.871 1.149-1.407.45-.535.973-1.144 1.601-1.87.235-.27.536-.614.875-1.005.336-.394.715-.832 1.114-1.293.394-.46.808-.937 1.215-1.41.402-.472.8-.933 1.168-1.363l.668-.777.668-.774.667-.777.665-.778.117.118.113.12.117.118.113.117a110.75 110.75 0 0 1 1.668 1.914l1.555 1.809c.57.664 1.184 1.383 1.813 2.12M51.227 44.149c.425.09.867.2 1.304.317.434.117.864.242 1.254.37.395.13.754.259 1.055.38.297.12.535.234.687.332.051.035.09.094.11.191.02.098.023.239.011.442-.015.199-.046.457-.097.793-.055.336-.125.75-.215 1.257-.094.524-.172.989-.23 1.446-.06.457-.106.91-.137 1.41a32.68 32.68 0 0 0-.067 1.7c-.011.648-.015 1.401-.015 2.312 0 .98.004 1.761.015 2.414.012.648.035 1.172.07 1.644.04.473.09.89.165 1.336.07.446.164.918.285 1.488.074.348.156.72.242 1.094.082.375.168.754.254 1.11.086.359.168.695.242.992.074.3.14.554.195.75.055.195.102.383.149.554.043.172.082.329.113.461.031.13.059.239.07.317.016.078.02.125.012.133a.942.942 0 0 1-.183-.079 35.955 35.955 0 0 1-1.148-.629c-.255-.144-.532-.304-.821-.472a95.651 95.651 0 0 0-2.031-1.152 44.616 44.616 0 0 0-1.723-.899 34 34 0 0 0-1.633-.75 44.224 44.224 0 0 0-1.762-.715 50.86 50.86 0 0 0-2.855-1.004 45.68 45.68 0 0 0-2.8-.793 39.106 39.106 0 0 0-2.653-.562 26.924 26.924 0 0 0-2.406-.309l-.426-.03-.426-.036-.426-.031-.426-.035V43.758h7.215c1.578.004 2.832.008 3.852.015 1.02.012 1.8.028 2.437.055a20.37 20.37 0 0 1 1.547.117c.43.051.797.117 1.196.203m64.886 7.493c0 1.23-.008 2.34-.015 3.312-.008.977-.02 1.817-.04 2.504-.015.691-.038 1.23-.062 1.602-.023.367-.05.57-.082.59a1.259 1.259 0 0 1-.281.07c-.153.031-.367.062-.617.101-.254.035-.547.078-.868.117-.32.043-.664.083-1.02.122-.765.086-1.538.199-2.323.343-.79.141-1.59.313-2.407.516-.816.203-1.652.434-2.503.7-.856.26-1.73.558-2.625.882-.735.266-1.305.477-1.801.672-.496.195-.918.375-1.348.578-.43.203-.867.43-1.398.723-.528.289-1.149.644-1.946 1.101a34.54 34.54 0 0 1-1.644.895 9.035 9.035 0 0 1-.528.242c-.128.055-.21.074-.226.059-.016-.016-.02-.082-.012-.184a5.49 5.49 0 0 1 .055-.422c.031-.172.066-.371.113-.59.043-.219.098-.457.156-.699.258-1.082.454-1.906.602-2.613.152-.703.258-1.282.332-1.867.078-.583.125-1.172.156-1.895.035-.723.059-1.578.086-2.695.024-.98.04-1.77.043-2.434.004-.66-.004-1.2-.027-1.684a17.76 17.76 0 0 0-.113-1.355 29.95 29.95 0 0 0-.223-1.445c-.152-.887-.27-1.543-.336-2.035-.066-.493-.086-.825-.04-1.059a.664.664 0 0 1 .333-.492c.18-.117.437-.207.781-.336.692-.266 1.29-.469 1.926-.63.637-.16 1.309-.276 2.152-.358.84-.082 1.852-.133 3.164-.16 1.309-.032 2.922-.044 4.965-.047l3.813-.008h1.902l1.906-.004v7.883m-25.05-2.368c.195 1.02.343 1.977.437 2.91.098.934.14 1.837.133 2.75a25.621 25.621 0 0 1-.18 2.797c-.11.961-.273 1.961-.488 3.036a39.395 39.395 0 0 1-.746 3.12 31.161 31.161 0 0 1-.946 2.829c-.355.906-.75 1.781-1.187 2.64a30.9 30.9 0 0 1-1.473 2.555c-.215.34-.597.86-1.074 1.469a76.18 76.18 0 0 1-1.625 2.012 79.82 79.82 0 0 1-1.73 2.011 30.987 30.987 0 0 1-1.387 1.489l-.258.25-.262.254-.257.253-.262.254.02-1.62.023-1.622.02-1.617.019-1.621c.02-1.414.035-2.543.058-3.465.02-.922.047-1.637.082-2.227.036-.59.082-1.054.141-1.472.059-.422.133-.797.227-1.211a38.117 38.117 0 0 1 1.086-3.91c.418-1.235.89-2.403 1.433-3.524a28.68 28.68 0 0 1 1.82-3.222 31.184 31.184 0 0 1 2.258-3.012 18.08 18.08 0 0 1 1.012-1.086c.367-.363.746-.715 1.106-1.023.355-.31.69-.575.964-.762.27-.188.48-.297.59-.297.035 0 .07.031.11.086.039.05.078.129.12.226a4.214 4.214 0 0 1 .216.75m-28.895.91c.914.915 1.738 1.86 2.488 2.86a25.52 25.52 0 0 1 2.028 3.187 30.027 30.027 0 0 1 1.636 3.645 42.64 42.64 0 0 1 1.32 4.23c.122.485.22.872.294 1.274.074.406.125.832.164 1.387.043.554.07 1.242.09 2.171.023.934.039 2.11.058 3.645.02 1.441.035 2.566.04 3.438.003.87 0 1.488-.016 1.921-.016.434-.043.68-.086.813-.04.129-.094.14-.16.101-.106-.058-.376-.324-.743-.722-.367-.399-.84-.926-1.34-1.512a82.643 82.643 0 0 1-1.539-1.832 48.185 48.185 0 0 1-1.34-1.695c-.34-.45-.722-1.031-1.117-1.688a40.534 40.534 0 0 1-1.183-2.125 43.623 43.623 0 0 1-1.075-2.207 21.82 21.82 0 0 1-.773-1.933c-.07-.215-.152-.477-.238-.762-.082-.29-.172-.602-.258-.922a49.961 49.961 0 0 1-.461-1.844c-.187-.86-.316-2.113-.395-3.508a62.606 62.606 0 0 1-.066-4.378c.027-1.434.106-2.762.227-3.735.12-.969.285-1.578.492-1.578.023 0 .097.05.21.14.11.09.259.22.438.38a44.358 44.358 0 0 1 1.305 1.25m53.23 15.39a24.897 24.897 0 0 1-.965 4.492 26.72 26.72 0 0 1-.824 2.25 33.11 33.11 0 0 1-1.058 2.305c-.344.676-.66 1.262-.98 1.805-.321.543-.641 1.035-.997 1.523-.351.485-.734.961-1.18 1.473-.445.508-.953 1.05-1.542 1.66a35.204 35.204 0 0 1-1.579 1.54c-.496.448-.976.847-1.468 1.21-.493.367-1 .703-1.551 1.031-.55.328-1.145.649-1.817.989-.84.421-1.624.761-2.445 1.03a15.58 15.58 0 0 1-2.683.626c-1.004.152-2.145.25-3.532.308-1.382.063-3.011.082-4.98.082H82.18l.03-.113.036-.113.031-.113.035-.114c.055-.199.243-.582.516-1.074.274-.496.633-1.101 1.027-1.746.399-.645.836-1.324 1.266-1.969.43-.644.852-1.25 1.219-1.746a44.604 44.604 0 0 1 5.883-6.445 41.569 41.569 0 0 1 6.812-4.977 38.048 38.048 0 0 1 7.477-3.36 34.711 34.711 0 0 1 7.886-1.585c.11-.008.22-.02.325-.027.105-.008.203-.02.293-.028.09-.008.164-.02.226-.023.063-.008.106-.016.13-.02.023-.004.038.024.05.078a.934.934 0 0 1 .023.239c.004.101 0 .226-.007.363-.008.137-.02.29-.04.45M30.934 66.89c.242 1.234.562 2.488.945 3.738a41.182 41.182 0 0 0 1.32 3.68 37.438 37.438 0 0 0 1.61 3.425 27.185 27.185 0 0 0 1.816 2.961c.45.633.992 1.313 1.594 2.004a38.232 38.232 0 0 0 1.949 2.074c.687.68 1.395 1.34 2.098 1.942.699.597 1.39 1.144 2.03 1.597.298.208.575.407.825.59.25.184.469.352.649.496.18.141.32.258.41.344.09.082.129.133.105.14-.066.028-.328-.038-.71-.167-.384-.13-.891-.324-1.458-.555a48.612 48.612 0 0 1-1.812-.777 38.066 38.066 0 0 1-7.352-4.297 42.01 42.01 0 0 1-5.043-4.422 44.733 44.733 0 0 1-4.37-5.254 45.026 45.026 0 0 1-3.575-5.941c-.125-.258-.25-.504-.356-.735-.109-.226-.207-.433-.285-.609-.078-.176-.14-.32-.18-.422-.042-.101-.058-.164-.05-.172.008-.008.062-.031.148-.066.09-.035.211-.082.36-.137.144-.05.32-.113.507-.18l.614-.21c.433-.145.988-.297 1.593-.446a39.578 39.578 0 0 1 3.805-.73c.574-.078 1.07-.125 1.434-.133l.23-.004.235-.004.23-.004.234-.004.114.57.109.57.113.567.114.57m8.199-1.87c1.383.238 2.8.59 4.226 1.039 1.426.449 2.856 1 4.27 1.636a42.064 42.064 0 0 1 4.16 2.164c1.348.801 2.648 1.68 3.879 2.621.41.317.95.778 1.547 1.32a69.069 69.069 0 0 1 1.914 1.805c.652.641 1.3 1.293 1.871 1.899a31.34 31.34 0 0 1 1.422 1.586 46.416 46.416 0 0 1 1.726 2.27c.57.796 1.125 1.613 1.622 2.39.5.781.94 1.52 1.285 2.152.343.637.593 1.172.71 1.543l.032.114.035.113.04.113.03.113h-5.511c-1.918 0-3.48-.02-4.801-.078-1.324-.058-2.41-.156-3.371-.312a15.68 15.68 0 0 1-2.63-.653c-.831-.289-1.651-.652-2.581-1.109a20.527 20.527 0 0 1-3.137-1.926 24.776 24.776 0 0 1-2.902-2.523 26.07 26.07 0 0 1-2.528-2.988 24.005 24.005 0 0 1-2.011-3.305 35.404 35.404 0 0 1-1.192-2.649 38.321 38.321 0 0 1-.968-2.66 25.394 25.394 0 0 1-.645-2.39c-.156-.72-.238-1.348-.238-1.832 0-.211 0-.371.011-.489.012-.12.032-.203.079-.257.043-.055.105-.082.203-.098.093-.016.222-.016.39-.016.094 0 .25.012.453.032.204.023.454.05.73.09.278.035.583.078.903.128.32.047.653.102.977.157m84.953.085c.336.06.809.168 1.336.297.523.13 1.101.282 1.64.434.543.152 1.051.305 1.43.43.387.125.649.222.7.273.027.023-.028.184-.149.45-.121.265-.3.632-.527 1.062-.223.433-.493.93-.79 1.457a56.9 56.9 0 0 1-.937 1.633 44.31 44.31 0 0 1-3.473 5.027 46.345 46.345 0 0 1-4.12 4.531 43.203 43.203 0 0 1-4.571 3.848 34.726 34.726 0 0 1-4.82 2.969 42.898 42.898 0 0 1-3.02 1.367c-.469.191-.89.351-1.207.457-.32.105-.535.156-.598.137-.027-.012.004-.055.079-.133.074-.074.195-.18.351-.309.153-.129.348-.281.563-.445.218-.164.465-.344.722-.531a31.987 31.987 0 0 0 3.067-2.473 30.025 30.025 0 0 0 4.992-5.887 32.018 32.018 0 0 0 1.953-3.441c.398-.809.75-1.57 1.059-2.309a30.121 30.121 0 0 0 1.48-4.39c.188-.758.363-1.547.52-2.391l.109-.59.113-.586.11-.59.109-.586h1.133c.156 0 .347.008.566.024.215.012.457.035.703.062a20.21 20.21 0 0 1 1.477.203m-79.191 55.711c.363.23.671.555.917.934.247.379.426.816.536 1.273.109.457.148.938.105 1.407a3.61 3.61 0 0 1-.371 1.336c-.156.304-.332.57-.539.808a3.303 3.303 0 0 1-1.512.996 4.104 4.104 0 0 1-.965.184 4.468 4.468 0 0 1-1.03-.043 3.427 3.427 0 0 1-1.719-.805 4.434 4.434 0 0 1-.696-.77 3.378 3.378 0 0 1-.555-1.284 4.203 4.203 0 0 1-.046-1.434c.066-.48.21-.945.43-1.36.214-.413.507-.78.87-1.058a3.654 3.654 0 0 1 1.059-.555c.383-.132.789-.207 1.2-.222.41-.02.82.023 1.214.12.39.102.766.259 1.102.473m64.375-.195c.175.086.37.23.574.406.199.176.402.38.586.598.187.215.36.438.492.652.133.211.226.407.266.567.019.07.035.168.042.285.012.113.02.25.024.398.004.145 0 .301-.004.457a8.875 8.875 0 0 1-.023.461 3.545 3.545 0 0 1-.774 1.953 3.866 3.866 0 0 1-3.625 1.368 3.584 3.584 0 0 1-1.883-.95 4.289 4.289 0 0 1-.55-.609 2.827 2.827 0 0 1-.352-.637 3.475 3.475 0 0 1-.188-.746 6.793 6.793 0 0 1-.054-.941c0-.352.027-.672.082-.961.05-.293.137-.555.25-.797.117-.242.265-.465.449-.676.188-.21.406-.41.668-.601.25-.188.547-.328.879-.434a4.168 4.168 0 0 1 1.05-.187c.364-.024.735 0 1.09.066.36.062.7.176 1 .328m-31.93.473c.177.125.368.328.556.57.183.242.367.531.527.824.16.293.297.598.394.88a2.5 2.5 0 0 1 .16.737c0 .258-.074.567-.206.895a5.551 5.551 0 0 1-.54.996 6 6 0 0 1-.742.906c-.265.27-.547.489-.816.63a2.93 2.93 0 0 1-1.024.3 3.709 3.709 0 0 1-1.117-.047 3.928 3.928 0 0 1-1.066-.37 3.194 3.194 0 0 1-.871-.669 4.034 4.034 0 0 1-.68-1.012 4.028 4.028 0 0 1-.355-1.12 3.802 3.802 0 0 1-.012-1.153 3.5 3.5 0 0 1 .344-1.094c.187-.363.375-.664.586-.91.21-.242.441-.43.71-.57.266-.14.57-.23.922-.282a6.496 6.496 0 0 1 1.239-.046c.254.011.472.027.664.046.195.024.363.055.515.098a2.284 2.284 0 0 1 .813.39"/></svg><text x="91" y="14" textLength="76" lengthAdjust="spacingAndGlyphs">pollinations.ai</text></g></svg>