@squadbase/vantage 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +95 -0
  3. package/dist/chunk-73J5ZD4C.js +96 -0
  4. package/dist/chunk-73J5ZD4C.js.map +1 -0
  5. package/dist/chunk-ATYZ45XL.js +19 -0
  6. package/dist/chunk-ATYZ45XL.js.map +1 -0
  7. package/dist/chunk-B7LLBNLV.js +23 -0
  8. package/dist/chunk-B7LLBNLV.js.map +1 -0
  9. package/dist/chunk-ZGDU5YLH.js +753 -0
  10. package/dist/chunk-ZGDU5YLH.js.map +1 -0
  11. package/dist/cli.d.ts +1 -0
  12. package/dist/cli.js +765 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/client/index.d.ts +45 -0
  15. package/dist/client/index.js +141 -0
  16. package/dist/client/index.js.map +1 -0
  17. package/dist/define-page-B6y9TOfZ.d.ts +44 -0
  18. package/dist/index.d.ts +15 -0
  19. package/dist/index.js +13 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/query/index.d.ts +11 -0
  22. package/dist/query/index.js +4 -0
  23. package/dist/query/index.js.map +1 -0
  24. package/dist/router/index.d.ts +36 -0
  25. package/dist/router/index.js +27 -0
  26. package/dist/router/index.js.map +1 -0
  27. package/dist/server/index.d.ts +53 -0
  28. package/dist/server/index.js +3 -0
  29. package/dist/server/index.js.map +1 -0
  30. package/dist/server/node.d.ts +35 -0
  31. package/dist/server/node.js +84 -0
  32. package/dist/server/node.js.map +1 -0
  33. package/dist/ui/index.d.ts +217 -0
  34. package/dist/ui/index.js +616 -0
  35. package/dist/ui/index.js.map +1 -0
  36. package/dist/vite/index.d.ts +15 -0
  37. package/dist/vite/index.js +5 -0
  38. package/dist/vite/index.js.map +1 -0
  39. package/package.json +108 -0
  40. package/registry/blocks/sales-overview.tsx +37 -0
  41. package/registry/ui/data-table.tsx +115 -0
  42. package/theme.css +101 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/ui/cn.ts","../../src/ui/button.tsx","../../src/ui/input.tsx","../../src/ui/card.tsx","../../src/ui/tabs.tsx","../../src/ui/table.tsx","../../src/ui/metric-card.tsx","../../src/ui/filter-bar.tsx","../../src/ui/dashboard-shell.tsx","../../src/ui/states.tsx","../../src/ui/date-picker.tsx","../../src/ui/chart.tsx","../../src/ui/dialog.tsx","../../src/ui/dropdown.tsx"],"names":["forwardRef","jsx","useState","jsxs","FIELD","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["/** Join class values, dropping falsy entries. Small, dependency-free. */\nexport type ClassValue = string | number | false | null | undefined\nexport function cn(...classes: ClassValue[]): string {\n return classes.filter(Boolean).join(\" \")\n}\n","import { forwardRef, type ButtonHTMLAttributes } from \"react\"\nimport { cn } from \"./cn.js\"\n\nexport type ButtonVariant = \"default\" | \"secondary\" | \"outline\" | \"ghost\" | \"destructive\"\nexport type ButtonSize = \"sm\" | \"default\" | \"lg\" | \"icon\"\n\nconst VARIANTS: Record<ButtonVariant, string> = {\n default: \"bg-primary text-primary-foreground hover:opacity-90\",\n secondary: \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n outline: \"border border-border bg-background hover:bg-accent hover:text-accent-foreground\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n destructive: \"bg-destructive text-destructive-foreground hover:opacity-90\",\n}\n\nconst SIZES: Record<ButtonSize, string> = {\n sm: \"h-8 px-3 text-xs\",\n default: \"h-9 px-4 text-sm\",\n lg: \"h-10 px-6 text-sm\",\n icon: \"h-9 w-9\",\n}\n\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant\n size?: ButtonSize\n}\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant = \"default\", size = \"default\", type = \"button\", ...props }, ref) => (\n <button\n ref={ref}\n type={type}\n className={cn(\n \"inline-flex items-center justify-center gap-2 rounded-md font-medium transition-colors\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1\",\n \"disabled:pointer-events-none disabled:opacity-50\",\n VARIANTS[variant],\n SIZES[size],\n className,\n )}\n {...props}\n />\n ),\n)\nButton.displayName = \"Button\"\n","import { forwardRef, type InputHTMLAttributes, type SelectHTMLAttributes } from \"react\"\nimport { cn } from \"./cn.js\"\n\nconst FIELD =\n \"flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm shadow-sm \" +\n \"transition-colors placeholder:text-muted-foreground focus-visible:outline-none \" +\n \"focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\"\n\nexport const Input = forwardRef<HTMLInputElement, InputHTMLAttributes<HTMLInputElement>>(\n ({ className, ...props }, ref) => <input ref={ref} className={cn(FIELD, className)} {...props} />,\n)\nInput.displayName = \"Input\"\n\nexport interface SelectProps extends SelectHTMLAttributes<HTMLSelectElement> {\n options?: { label: string; value: string }[]\n}\n\nexport const Select = forwardRef<HTMLSelectElement, SelectProps>(\n ({ className, options, children, ...props }, ref) => (\n <select ref={ref} className={cn(FIELD, \"pr-8\", className)} {...props}>\n {options\n ? options.map((o) => (\n <option key={o.value} value={o.value}>\n {o.label}\n </option>\n ))\n : children}\n </select>\n ),\n)\nSelect.displayName = \"Select\"\n\nexport interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, \"type\"> {\n label?: string\n}\n\nexport const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(\n ({ className, label, id, ...props }, ref) => (\n <label className=\"inline-flex items-center gap-2 text-sm\">\n <input\n ref={ref}\n id={id}\n type=\"checkbox\"\n className={cn(\"h-4 w-4 rounded border-input text-primary focus-visible:ring-2 focus-visible:ring-ring\", className)}\n {...props}\n />\n {label ? <span>{label}</span> : null}\n </label>\n ),\n)\nCheckbox.displayName = \"Checkbox\"\n","import type { HTMLAttributes } from \"react\"\nimport { cn } from \"./cn.js\"\n\ntype Div = HTMLAttributes<HTMLDivElement>\n\nexport function Card({ className, ...props }: Div) {\n return (\n <div\n className={cn(\"rounded-xl border border-border bg-card text-card-foreground shadow-sm\", className)}\n {...props}\n />\n )\n}\n\nexport function CardHeader({ className, ...props }: Div) {\n return <div className={cn(\"flex flex-col gap-1.5 p-6\", className)} {...props} />\n}\n\nexport function CardTitle({ className, ...props }: HTMLAttributes<HTMLHeadingElement>) {\n return <h3 className={cn(\"text-base font-semibold leading-none tracking-tight\", className)} {...props} />\n}\n\nexport function CardDescription({ className, ...props }: HTMLAttributes<HTMLParagraphElement>) {\n return <p className={cn(\"text-sm text-muted-foreground\", className)} {...props} />\n}\n\nexport function CardContent({ className, ...props }: Div) {\n return <div className={cn(\"p-6 pt-0\", className)} {...props} />\n}\n\nexport function CardFooter({ className, ...props }: Div) {\n return <div className={cn(\"flex items-center p-6 pt-0\", className)} {...props} />\n}\n","import { createContext, useContext, useState, type ReactNode } from \"react\"\nimport { cn } from \"./cn.js\"\n\ninterface TabsCtx {\n value: string\n setValue: (v: string) => void\n}\nconst Ctx = createContext<TabsCtx | null>(null)\n\nexport interface TabsProps {\n defaultValue: string\n value?: string\n onValueChange?: (v: string) => void\n className?: string\n children: ReactNode\n}\n\nexport function Tabs({ defaultValue, value, onValueChange, className, children }: TabsProps) {\n const [internal, setInternal] = useState(defaultValue)\n const current = value ?? internal\n const setValue = (v: string) => {\n if (value === undefined) setInternal(v)\n onValueChange?.(v)\n }\n return (\n <Ctx.Provider value={{ value: current, setValue }}>\n <div className={className}>{children}</div>\n </Ctx.Provider>\n )\n}\n\nexport function TabsList({ className, children }: { className?: string; children: ReactNode }) {\n return (\n <div className={cn(\"inline-flex h-9 items-center gap-1 rounded-lg bg-muted p-1 text-muted-foreground\", className)}>\n {children}\n </div>\n )\n}\n\nexport function TabsTrigger({ value, children }: { value: string; children: ReactNode }) {\n const ctx = useContext(Ctx)\n if (!ctx) throw new Error(\"TabsTrigger must be used within Tabs\")\n const active = ctx.value === value\n return (\n <button\n type=\"button\"\n onClick={() => ctx.setValue(value)}\n className={cn(\n \"inline-flex items-center justify-center rounded-md px-3 py-1 text-sm font-medium transition-all\",\n active ? \"bg-background text-foreground shadow-sm\" : \"hover:text-foreground\",\n )}\n >\n {children}\n </button>\n )\n}\n\nexport function TabsContent({ value, className, children }: { value: string; className?: string; children: ReactNode }) {\n const ctx = useContext(Ctx)\n if (!ctx) throw new Error(\"TabsContent must be used within Tabs\")\n if (ctx.value !== value) return null\n return <div className={cn(\"mt-4\", className)}>{children}</div>\n}\n","import { useMemo, useState, type HTMLAttributes, type ReactNode, type TdHTMLAttributes } from \"react\"\nimport { cn } from \"./cn.js\"\nimport { Button } from \"./button.js\"\n\n/* --- Low-level table primitives --- */\n\nexport function Table({ className, ...props }: HTMLAttributes<HTMLTableElement>) {\n return (\n <div className=\"w-full overflow-x-auto\">\n <table className={cn(\"w-full caption-bottom text-sm\", className)} {...props} />\n </div>\n )\n}\nexport function TableHeader(props: HTMLAttributes<HTMLTableSectionElement>) {\n return <thead className=\"[&_tr]:border-b border-border\" {...props} />\n}\nexport function TableBody(props: HTMLAttributes<HTMLTableSectionElement>) {\n return <tbody className=\"[&_tr:last-child]:border-0\" {...props} />\n}\nexport function TableRow({ className, ...props }: HTMLAttributes<HTMLTableRowElement>) {\n return <tr className={cn(\"border-b border-border transition-colors hover:bg-muted/50\", className)} {...props} />\n}\nexport function TableHead({ className, ...props }: HTMLAttributes<HTMLTableCellElement>) {\n return (\n <th\n className={cn(\"h-10 px-3 text-left align-middle text-xs font-medium text-muted-foreground\", className)}\n {...props}\n />\n )\n}\nexport function TableCell({ className, ...props }: TdHTMLAttributes<HTMLTableCellElement>) {\n return <td className={cn(\"px-3 py-2.5 align-middle\", className)} {...props} />\n}\n\n/* --- DataTable: sortable + paginated --- */\n\nexport interface Column<T> {\n key: string\n header: string\n render?: (row: T) => ReactNode\n sortable?: boolean\n align?: \"left\" | \"right\" | \"center\"\n accessor?: (row: T) => string | number\n}\n\nexport interface DataTableProps<T> {\n columns: Column<T>[]\n data: T[]\n pageSize?: number\n getRowId?: (row: T, index: number) => string\n empty?: ReactNode\n className?: string\n}\n\ntype SortState = { key: string; dir: \"asc\" | \"desc\" } | null\n\nexport function DataTable<T extends Record<string, unknown>>({\n columns,\n data,\n pageSize = 10,\n getRowId,\n empty,\n className,\n}: DataTableProps<T>) {\n const [sort, setSort] = useState<SortState>(null)\n const [page, setPage] = useState(0)\n\n const valueOf = (row: T, col: Column<T>): string | number => {\n if (col.accessor) return col.accessor(row)\n const v = row[col.key]\n return typeof v === \"number\" ? v : String(v ?? \"\")\n }\n\n const sorted = useMemo(() => {\n if (!sort) return data\n const col = columns.find((c) => c.key === sort.key)\n if (!col) return data\n const copy = [...data]\n // Rank numbers before strings so a column with mixed cell types still has a\n // total (transitive) ordering.\n const rank = (v: string | number) => (typeof v === \"number\" ? 0 : 1)\n copy.sort((a, b) => {\n const av = valueOf(a, col)\n const bv = valueOf(b, col)\n let cmp = rank(av) - rank(bv)\n if (cmp === 0) {\n cmp =\n typeof av === \"number\" && typeof bv === \"number\"\n ? av - bv\n : String(av).localeCompare(String(bv))\n }\n return sort.dir === \"asc\" ? cmp : -cmp\n })\n return copy\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [data, sort, columns])\n\n const pageCount = Math.max(1, Math.ceil(sorted.length / pageSize))\n const clampedPage = Math.min(page, pageCount - 1)\n const rows = sorted.slice(clampedPage * pageSize, clampedPage * pageSize + pageSize)\n\n const toggleSort = (key: string) => {\n setPage(0)\n setSort((prev) =>\n prev?.key === key ? (prev.dir === \"asc\" ? { key, dir: \"desc\" } : null) : { key, dir: \"asc\" },\n )\n }\n\n const alignClass = (a?: \"left\" | \"right\" | \"center\") =>\n a === \"right\" ? \"text-right\" : a === \"center\" ? \"text-center\" : \"text-left\"\n\n if (data.length === 0 && empty) {\n return <div className={cn(\"rounded-xl border border-border bg-card\", className)}>{empty}</div>\n }\n\n return (\n <div className={cn(\"rounded-xl border border-border bg-card\", className)}>\n <Table>\n <TableHeader>\n <TableRow>\n {columns.map((col) => (\n <TableHead key={col.key} className={alignClass(col.align)}>\n {col.sortable ? (\n <button\n type=\"button\"\n onClick={() => toggleSort(col.key)}\n className=\"inline-flex items-center gap-1 hover:text-foreground\"\n >\n {col.header}\n <span className=\"text-[10px]\">\n {sort?.key === col.key ? (sort.dir === \"asc\" ? \"▲\" : \"▼\") : \"↕\"}\n </span>\n </button>\n ) : (\n col.header\n )}\n </TableHead>\n ))}\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((row, i) => (\n <TableRow key={getRowId ? getRowId(row, i) : i}>\n {columns.map((col) => (\n <TableCell key={col.key} className={alignClass(col.align)}>\n {col.render ? col.render(row) : String(row[col.key] ?? \"\")}\n </TableCell>\n ))}\n </TableRow>\n ))}\n </TableBody>\n </Table>\n {pageCount > 1 ? (\n <Pagination\n page={clampedPage}\n pageCount={pageCount}\n total={sorted.length}\n onPageChange={setPage}\n />\n ) : null}\n </div>\n )\n}\n\nexport interface PaginationProps {\n page: number\n pageCount: number\n total?: number\n onPageChange: (page: number) => void\n}\n\nexport function Pagination({ page, pageCount, total, onPageChange }: PaginationProps) {\n return (\n <div className=\"flex items-center justify-between gap-2 border-t border-border px-3 py-2 text-sm\">\n <span className=\"text-muted-foreground\">\n {total != null ? `${total} rows · ` : \"\"}Page {page + 1} of {pageCount}\n </span>\n <div className=\"flex gap-1\">\n <Button size=\"sm\" variant=\"outline\" disabled={page === 0} onClick={() => onPageChange(page - 1)}>\n Previous\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n disabled={page >= pageCount - 1}\n onClick={() => onPageChange(page + 1)}\n >\n Next\n </Button>\n </div>\n </div>\n )\n}\n","import type { ReactNode } from \"react\"\nimport { cn } from \"./cn.js\"\nimport { Card } from \"./card.js\"\n\nexport interface MetricCardProps {\n label: string\n value: ReactNode\n delta?: number\n deltaLabel?: string\n icon?: ReactNode\n className?: string\n}\n\n/** A KPI tile: label, big value, and an optional trend delta. */\nexport function MetricCard({ label, value, delta, deltaLabel, icon, className }: MetricCardProps) {\n const positive = (delta ?? 0) >= 0\n return (\n <Card className={cn(\"p-5\", className)}>\n <div className=\"flex items-start justify-between\">\n <p className=\"text-sm font-medium text-muted-foreground\">{label}</p>\n {icon ? <span className=\"text-muted-foreground\">{icon}</span> : null}\n </div>\n <p className=\"mt-2 text-3xl font-semibold tracking-tight\">{value}</p>\n {delta != null ? (\n <p className=\"mt-1 text-xs\">\n <span className={cn(\"font-medium\", positive ? \"text-[var(--chart-2)]\" : \"text-destructive\")}>\n {positive ? \"▲\" : \"▼\"} {Math.abs(delta)}%\n </span>{\" \"}\n <span className=\"text-muted-foreground\">{deltaLabel ?? \"vs. previous\"}</span>\n </p>\n ) : null}\n </Card>\n )\n}\n","import type { HTMLAttributes, ReactNode } from \"react\"\nimport { cn } from \"./cn.js\"\n\nexport interface FilterBarProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode\n}\n\n/** A responsive row of filter controls. */\nexport function FilterBar({ className, children, ...props }: FilterBarProps) {\n return (\n <div\n className={cn(\n \"flex flex-wrap items-end gap-3 rounded-xl border border-border bg-card p-4\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n )\n}\n\nexport function FilterField({ label, children }: { label: string; children: ReactNode }) {\n return (\n <div className=\"flex flex-col gap-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">{label}</label>\n {children}\n </div>\n )\n}\n","import type { ReactNode } from \"react\"\nimport { cn } from \"./cn.js\"\n\nexport interface DashboardShellProps {\n title?: ReactNode\n description?: ReactNode\n actions?: ReactNode\n nav?: ReactNode\n children: ReactNode\n className?: string\n}\n\n/** Page-level layout: sticky header with title/actions, then content. */\nexport function DashboardShell({ title, description, actions, nav, children, className }: DashboardShellProps) {\n return (\n <div className={cn(\"min-h-screen bg-background text-foreground\", className)}>\n <header className=\"sticky top-0 z-10 border-b border-border bg-background/80 backdrop-blur\">\n <div className=\"mx-auto flex max-w-7xl flex-wrap items-center justify-between gap-3 px-6 py-4\">\n <div>\n {title ? <h1 className=\"text-xl font-semibold tracking-tight\">{title}</h1> : null}\n {description ? <p className=\"text-sm text-muted-foreground\">{description}</p> : null}\n </div>\n {actions ? <div className=\"flex items-center gap-2\">{actions}</div> : null}\n </div>\n {nav ? <nav className=\"mx-auto max-w-7xl px-6 pb-2\">{nav}</nav> : null}\n </header>\n <main className=\"mx-auto max-w-7xl px-6 py-6\">{children}</main>\n </div>\n )\n}\n","import type { ReactNode } from \"react\"\nimport { cn } from \"./cn.js\"\n\nexport function Loading({ label = \"Loading…\", className }: { label?: string; className?: string }) {\n return (\n <div className={cn(\"flex min-h-[30vh] items-center justify-center\", className)} role=\"status\" aria-live=\"polite\">\n <div className=\"flex items-center gap-3 text-sm text-muted-foreground\">\n <span className=\"h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent\" />\n {label}\n </div>\n </div>\n )\n}\n\nexport function Empty({\n title = \"Nothing here yet\",\n description,\n icon,\n action,\n className,\n}: {\n title?: string\n description?: string\n icon?: ReactNode\n action?: ReactNode\n className?: string\n}) {\n return (\n <div className={cn(\"flex flex-col items-center justify-center gap-2 p-10 text-center\", className)}>\n {icon ? <div className=\"text-3xl text-muted-foreground\">{icon}</div> : null}\n <p className=\"font-medium\">{title}</p>\n {description ? <p className=\"max-w-sm text-sm text-muted-foreground\">{description}</p> : null}\n {action ? <div className=\"mt-2\">{action}</div> : null}\n </div>\n )\n}\n\nexport function ErrorState({\n title = \"Something went wrong\",\n message,\n action,\n className,\n}: {\n title?: string\n message?: ReactNode\n action?: ReactNode\n className?: string\n}) {\n return (\n <div\n className={cn(\"rounded-xl border border-destructive/30 bg-destructive/5 p-6\", className)}\n role=\"alert\"\n >\n <p className=\"font-semibold text-destructive\">{title}</p>\n {message ? <p className=\"mt-1 text-sm text-muted-foreground\">{message}</p> : null}\n {action ? <div className=\"mt-3\">{action}</div> : null}\n </div>\n )\n}\n","import { cn } from \"./cn.js\"\n\nconst FIELD =\n \"h-9 rounded-md border border-input bg-background px-3 text-sm shadow-sm \" +\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n\nexport interface DatePickerProps {\n value?: string\n onChange?: (value: string) => void\n min?: string\n max?: string\n className?: string\n id?: string\n}\n\n/** Single date field (native, no external dependency). */\nexport function DatePicker({ value, onChange, min, max, className, id }: DatePickerProps) {\n return (\n <input\n id={id}\n type=\"date\"\n value={value ?? \"\"}\n min={min}\n max={max}\n onChange={(e) => onChange?.(e.target.value)}\n className={cn(FIELD, className)}\n />\n )\n}\n\nexport interface DateRange {\n from: string\n to: string\n}\n\nexport interface DateRangePickerProps {\n value?: DateRange\n onChange?: (value: DateRange) => void\n className?: string\n}\n\n/** Two coupled date fields representing an inclusive range. */\nexport function DateRangePicker({ value, onChange, className }: DateRangePickerProps) {\n const from = value?.from ?? \"\"\n const to = value?.to ?? \"\"\n return (\n <div className={cn(\"inline-flex items-center gap-2\", className)}>\n <input\n type=\"date\"\n value={from}\n max={to || undefined}\n onChange={(e) => onChange?.({ from: e.target.value, to })}\n className={FIELD}\n aria-label=\"From date\"\n />\n <span className=\"text-muted-foreground\">–</span>\n <input\n type=\"date\"\n value={to}\n min={from || undefined}\n onChange={(e) => onChange?.({ from, to: e.target.value })}\n className={FIELD}\n aria-label=\"To date\"\n />\n </div>\n )\n}\n","import type { ReactNode } from \"react\"\nimport { cn } from \"./cn.js\"\n\nconst CHART_COLORS = [\n \"var(--chart-1)\",\n \"var(--chart-2)\",\n \"var(--chart-3)\",\n \"var(--chart-4)\",\n \"var(--chart-5)\",\n]\n\nexport interface Series {\n key: string\n label?: string\n color?: string\n}\n\nexport function ChartContainer({\n children,\n className,\n height = 260,\n}: {\n children: ReactNode\n className?: string\n height?: number\n}) {\n return (\n <div className={cn(\"w-full\", className)} style={{ height }}>\n {children}\n </div>\n )\n}\n\nexport function ChartLegend({ series }: { series: Series[] }) {\n return (\n <div className=\"flex flex-wrap items-center gap-4 pt-3 text-xs text-muted-foreground\">\n {series.map((s, i) => (\n <span key={s.key} className=\"inline-flex items-center gap-1.5\">\n <span\n className=\"h-2.5 w-2.5 rounded-[3px]\"\n style={{ backgroundColor: s.color ?? CHART_COLORS[i % CHART_COLORS.length] }}\n />\n {s.label ?? s.key}\n </span>\n ))}\n </div>\n )\n}\n\nexport function ChartTooltip({ children, className }: { children: ReactNode; className?: string }) {\n return (\n <div\n className={cn(\n \"pointer-events-none rounded-md border border-border bg-popover px-2.5 py-1.5 text-xs shadow-md\",\n className,\n )}\n >\n {children}\n </div>\n )\n}\n\ninterface BaseChartProps<T> {\n data: T[]\n categoryKey: string\n series: Series[]\n height?: number\n className?: string\n}\n\nconst PAD = { top: 8, right: 8, bottom: 22, left: 32 }\n\nfunction useGeometry<T extends Record<string, unknown>>(data: T[], series: Series[]) {\n let max = 0\n for (const row of data) {\n for (const s of series) {\n const v = Number(row[s.key] ?? 0)\n if (v > max) max = v\n }\n }\n return { max: max === 0 ? 1 : max }\n}\n\n/** Minimal dependency-free grouped bar chart. */\nexport function BarChart<T extends Record<string, unknown>>({\n data,\n categoryKey,\n series,\n height = 260,\n className,\n}: BaseChartProps<T>) {\n const width = 640\n const { max } = useGeometry(data, series)\n const chartW = width - PAD.left - PAD.right\n const chartH = height - PAD.top - PAD.bottom\n const groupW = chartW / Math.max(1, data.length)\n const barW = Math.max(2, (groupW * 0.7) / series.length)\n\n return (\n <div className={cn(\"w-full\", className)}>\n <svg viewBox={`0 0 ${width} ${height}`} className=\"w-full\" style={{ height }} role=\"img\">\n {[0, 0.25, 0.5, 0.75, 1].map((t) => {\n const y = PAD.top + chartH * (1 - t)\n return (\n <g key={t}>\n <line x1={PAD.left} x2={width - PAD.right} y1={y} y2={y} stroke=\"var(--border)\" strokeWidth={1} />\n <text x={PAD.left - 6} y={y + 3} textAnchor=\"end\" fontSize={9} fill=\"var(--muted-foreground)\">\n {Math.round(max * t)}\n </text>\n </g>\n )\n })}\n {data.map((row, i) => {\n const gx = PAD.left + groupW * i + (groupW - barW * series.length) / 2\n return (\n <g key={i}>\n {series.map((s, si) => {\n const v = Number(row[s.key] ?? 0)\n const h = (v / max) * chartH\n return (\n <rect\n key={s.key}\n x={gx + si * barW}\n y={PAD.top + chartH - h}\n width={barW - 1}\n height={Math.max(0, h)}\n rx={2}\n fill={s.color ?? CHART_COLORS[si % CHART_COLORS.length]}\n >\n <title>{`${String(row[categoryKey])} · ${s.label ?? s.key}: ${v}`}</title>\n </rect>\n )\n })}\n <text\n x={PAD.left + groupW * i + groupW / 2}\n y={height - 6}\n textAnchor=\"middle\"\n fontSize={9}\n fill=\"var(--muted-foreground)\"\n >\n {String(row[categoryKey])}\n </text>\n </g>\n )\n })}\n </svg>\n <ChartLegend series={series} />\n </div>\n )\n}\n\n/** Minimal dependency-free multi-series line chart. */\nexport function LineChart<T extends Record<string, unknown>>({\n data,\n categoryKey,\n series,\n height = 260,\n className,\n}: BaseChartProps<T>) {\n const width = 640\n const { max } = useGeometry(data, series)\n const chartW = width - PAD.left - PAD.right\n const chartH = height - PAD.top - PAD.bottom\n const stepX = chartW / Math.max(1, data.length - 1)\n const pointFor = (v: number, i: number) => ({\n x: PAD.left + stepX * i,\n y: PAD.top + chartH - (v / max) * chartH,\n })\n\n return (\n <div className={cn(\"w-full\", className)}>\n <svg viewBox={`0 0 ${width} ${height}`} className=\"w-full\" style={{ height }} role=\"img\">\n {[0, 0.5, 1].map((t) => {\n const y = PAD.top + chartH * (1 - t)\n return (\n <line key={t} x1={PAD.left} x2={width - PAD.right} y1={y} y2={y} stroke=\"var(--border)\" strokeWidth={1} />\n )\n })}\n {series.map((s, si) => {\n const pts = data.map((row, i) => pointFor(Number(row[s.key] ?? 0), i))\n const d = pts.map((p, i) => `${i === 0 ? \"M\" : \"L\"}${p.x},${p.y}`).join(\" \")\n const color = s.color ?? CHART_COLORS[si % CHART_COLORS.length]\n return (\n <g key={s.key}>\n <path d={d} fill=\"none\" stroke={color} strokeWidth={2} />\n {pts.map((p, i) => (\n <circle key={i} cx={p.x} cy={p.y} r={2.5} fill={color} />\n ))}\n </g>\n )\n })}\n {data.map((row, i) => (\n <text\n key={i}\n x={PAD.left + stepX * i}\n y={height - 6}\n textAnchor=\"middle\"\n fontSize={9}\n fill=\"var(--muted-foreground)\"\n >\n {String(row[categoryKey])}\n </text>\n ))}\n </svg>\n <ChartLegend series={series} />\n </div>\n )\n}\n","import { useEffect, type ReactNode } from \"react\"\nimport { cn } from \"./cn.js\"\n\nexport interface DialogProps {\n open: boolean\n onClose: () => void\n title?: ReactNode\n description?: ReactNode\n children?: ReactNode\n footer?: ReactNode\n className?: string\n}\n\n/** A lightweight modal dialog (no external UI dependency). */\nexport function Dialog({ open, onClose, title, description, children, footer, className }: DialogProps) {\n useEffect(() => {\n if (!open) return\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose()\n }\n document.addEventListener(\"keydown\", onKey)\n return () => document.removeEventListener(\"keydown\", onKey)\n }, [open, onClose])\n\n if (!open) return null\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center p-4\">\n <div className=\"absolute inset-0 bg-black/50\" onClick={onClose} aria-hidden />\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n className={cn(\n \"relative z-10 w-full max-w-lg rounded-xl border border-border bg-card p-6 shadow-lg\",\n className,\n )}\n >\n {title ? <h2 className=\"text-lg font-semibold\">{title}</h2> : null}\n {description ? <p className=\"mt-1 text-sm text-muted-foreground\">{description}</p> : null}\n {children ? <div className=\"mt-4\">{children}</div> : null}\n {footer ? <div className=\"mt-6 flex justify-end gap-2\">{footer}</div> : null}\n </div>\n </div>\n )\n}\n","import { useEffect, useRef, useState, type ReactNode } from \"react\"\nimport { cn } from \"./cn.js\"\n\nexport interface DropdownItem {\n label: ReactNode\n onSelect?: () => void\n disabled?: boolean\n}\n\nexport interface DropdownMenuProps {\n trigger: ReactNode\n items: DropdownItem[]\n align?: \"start\" | \"end\"\n className?: string\n}\n\n/** A simple click-to-open dropdown menu with outside-click dismissal. */\nexport function DropdownMenu({ trigger, items, align = \"start\", className }: DropdownMenuProps) {\n const [open, setOpen] = useState(false)\n const ref = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n if (!open) return\n const onDoc = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false)\n }\n document.addEventListener(\"mousedown\", onDoc)\n return () => document.removeEventListener(\"mousedown\", onDoc)\n }, [open])\n\n return (\n <div ref={ref} className={cn(\"relative inline-block\", className)}>\n <span onClick={() => setOpen((v) => !v)}>{trigger}</span>\n {open ? (\n <div\n role=\"menu\"\n className={cn(\n \"absolute z-50 mt-1 min-w-[10rem] rounded-md border border-border bg-popover p-1 shadow-md\",\n align === \"end\" ? \"right-0\" : \"left-0\",\n )}\n >\n {items.map((item, i) => (\n <button\n key={i}\n type=\"button\"\n role=\"menuitem\"\n disabled={item.disabled}\n onClick={() => {\n item.onSelect?.()\n setOpen(false)\n }}\n className={cn(\n \"flex w-full items-center rounded-sm px-2 py-1.5 text-left text-sm\",\n \"hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50\",\n )}\n >\n {item.label}\n </button>\n ))}\n </div>\n ) : null}\n </div>\n )\n}\n"]}
@@ -0,0 +1,15 @@
1
+ import { PluginOption } from 'vite';
2
+
3
+ interface VantagePluginOptions {
4
+ root: string;
5
+ /** Server-side env (process.env + loaded .env), passed to API handlers. */
6
+ env?: Record<string, string | undefined>;
7
+ }
8
+ /**
9
+ * The single plugin that turns a plain Vite instance into Vantage: file-based
10
+ * routing, generated entry/HTML, Tailwind, the server-import boundary, route
11
+ * HMR and dev console forwarding.
12
+ */
13
+ declare function vantagePlugin(options: VantagePluginOptions): PluginOption;
14
+
15
+ export { type VantagePluginOptions, vantagePlugin };
@@ -0,0 +1,5 @@
1
+ export { vantagePlugin } from '../chunk-ZGDU5YLH.js';
2
+ import '../chunk-73J5ZD4C.js';
3
+ import '../chunk-B7LLBNLV.js';
4
+ //# sourceMappingURL=index.js.map
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
package/package.json ADDED
@@ -0,0 +1,108 @@
1
+ {
2
+ "name": "@squadbase/vantage",
3
+ "version": "0.0.1",
4
+ "description": "Data dashboard framework for Squadbase Editor. Vite-powered, config-free, one-file first.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "Squadbase",
8
+ "homepage": "https://github.com/squadbase/vantage-framework/tree/main/packages/vantage#readme",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/squadbase/vantage-framework.git",
12
+ "directory": "packages/vantage"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/squadbase/vantage-framework/issues"
16
+ },
17
+ "keywords": [
18
+ "vantage",
19
+ "squadbase",
20
+ "dashboard",
21
+ "react",
22
+ "vite",
23
+ "framework",
24
+ "tailwindcss",
25
+ "tanstack"
26
+ ],
27
+ "engines": {
28
+ "node": ">=20"
29
+ },
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "bin": {
34
+ "vantage": "./dist/cli.js"
35
+ },
36
+ "exports": {
37
+ ".": {
38
+ "types": "./dist/index.d.ts",
39
+ "default": "./dist/index.js"
40
+ },
41
+ "./query": {
42
+ "types": "./dist/query/index.d.ts",
43
+ "default": "./dist/query/index.js"
44
+ },
45
+ "./router": {
46
+ "types": "./dist/router/index.d.ts",
47
+ "default": "./dist/router/index.js"
48
+ },
49
+ "./ui": {
50
+ "types": "./dist/ui/index.d.ts",
51
+ "default": "./dist/ui/index.js"
52
+ },
53
+ "./server": {
54
+ "types": "./dist/server/index.d.ts",
55
+ "default": "./dist/server/index.js"
56
+ },
57
+ "./server/node": {
58
+ "types": "./dist/server/node.d.ts",
59
+ "default": "./dist/server/node.js"
60
+ },
61
+ "./client": {
62
+ "types": "./dist/client/index.d.ts",
63
+ "default": "./dist/client/index.js"
64
+ },
65
+ "./vite": {
66
+ "types": "./dist/vite/index.d.ts",
67
+ "default": "./dist/vite/index.js"
68
+ },
69
+ "./theme.css": "./theme.css",
70
+ "./package.json": "./package.json"
71
+ },
72
+ "files": [
73
+ "dist",
74
+ "theme.css",
75
+ "registry"
76
+ ],
77
+ "scripts": {
78
+ "build": "tsup",
79
+ "dev": "tsup --watch",
80
+ "typecheck": "tsc --noEmit",
81
+ "prepublishOnly": "tsup"
82
+ },
83
+ "dependencies": {
84
+ "@hono/node-server": "^2.0.8",
85
+ "@tailwindcss/vite": "^4.3.2",
86
+ "@tanstack/react-query": "^5.101.2",
87
+ "@tanstack/react-router": "^1.170.17",
88
+ "@vitejs/plugin-react": "^6.0.3",
89
+ "esbuild": "^0.28.1",
90
+ "hono": "^4.12.30",
91
+ "picocolors": "^1.1.1",
92
+ "tailwindcss": "^4.3.2",
93
+ "vite": "^8.1.4"
94
+ },
95
+ "peerDependencies": {
96
+ "react": ">=18.2.0",
97
+ "react-dom": ">=18.2.0"
98
+ },
99
+ "devDependencies": {
100
+ "@types/node": "^22.10.0",
101
+ "@types/react": "^19.2.0",
102
+ "@types/react-dom": "^19.2.0",
103
+ "react": "^19.2.7",
104
+ "react-dom": "^19.2.7",
105
+ "tsup": "^8.5.1",
106
+ "typescript": "^5.7.0"
107
+ }
108
+ }
@@ -0,0 +1,37 @@
1
+ // Copied by `vantage add block sales-overview`. This file is yours to edit.
2
+ import { BarChart, Card, CardContent, CardHeader, CardTitle, MetricCard } from "@squadbase/vantage/ui"
3
+
4
+ export interface SalesOverviewProps {
5
+ totalRevenue: string
6
+ orders: number
7
+ revenueDelta?: number
8
+ monthly: { month: string; revenue: number; target: number }[]
9
+ }
10
+
11
+ /** A composed dashboard section: KPI row + revenue vs. target chart. */
12
+ export function SalesOverview({ totalRevenue, orders, revenueDelta, monthly }: SalesOverviewProps) {
13
+ return (
14
+ <section className="flex flex-col gap-4">
15
+ <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
16
+ <MetricCard label="Revenue" value={totalRevenue} delta={revenueDelta} />
17
+ <MetricCard label="Orders" value={orders.toLocaleString()} />
18
+ <MetricCard label="Avg. order" value={`$${Math.round((Number(totalRevenue.replace(/[^0-9.]/g, "")) || 0) / Math.max(1, orders))}`} />
19
+ </div>
20
+ <Card>
21
+ <CardHeader>
22
+ <CardTitle>Revenue vs. target</CardTitle>
23
+ </CardHeader>
24
+ <CardContent>
25
+ <BarChart
26
+ data={monthly}
27
+ categoryKey="month"
28
+ series={[
29
+ { key: "revenue", label: "Revenue" },
30
+ { key: "target", label: "Target" },
31
+ ]}
32
+ />
33
+ </CardContent>
34
+ </Card>
35
+ </section>
36
+ )
37
+ }
@@ -0,0 +1,115 @@
1
+ // Copied by `vantage add ui data-table`. This file is yours to edit.
2
+ import { useMemo, useState, type ReactNode } from "react"
3
+
4
+ export interface Column<T> {
5
+ key: string
6
+ header: string
7
+ render?: (row: T) => ReactNode
8
+ sortable?: boolean
9
+ align?: "left" | "right" | "center"
10
+ }
11
+
12
+ export interface DataTableProps<T> {
13
+ columns: Column<T>[]
14
+ data: T[]
15
+ pageSize?: number
16
+ }
17
+
18
+ type Sort = { key: string; dir: "asc" | "desc" } | null
19
+
20
+ /**
21
+ * A fully-customizable data table. Unlike `DataTable` from
22
+ * `@squadbase/vantage/ui`, this copy lives in your project so you can change
23
+ * markup, styling and behavior freely.
24
+ */
25
+ export function DataTable<T extends Record<string, unknown>>({ columns, data, pageSize = 10 }: DataTableProps<T>) {
26
+ const [sort, setSort] = useState<Sort>(null)
27
+ const [page, setPage] = useState(0)
28
+
29
+ const sorted = useMemo(() => {
30
+ if (!sort) return data
31
+ const copy = [...data]
32
+ copy.sort((a, b) => {
33
+ const av = a[sort.key]
34
+ const bv = b[sort.key]
35
+ const cmp =
36
+ typeof av === "number" && typeof bv === "number"
37
+ ? av - bv
38
+ : String(av ?? "").localeCompare(String(bv ?? ""))
39
+ return sort.dir === "asc" ? cmp : -cmp
40
+ })
41
+ return copy
42
+ }, [data, sort])
43
+
44
+ const pageCount = Math.max(1, Math.ceil(sorted.length / pageSize))
45
+ const rows = sorted.slice(page * pageSize, page * pageSize + pageSize)
46
+
47
+ return (
48
+ <div className="rounded-xl border border-border bg-card">
49
+ <table className="w-full text-sm">
50
+ <thead className="border-b border-border">
51
+ <tr>
52
+ {columns.map((c) => (
53
+ <th key={c.key} className="h-10 px-3 text-left text-xs font-medium text-muted-foreground">
54
+ {c.sortable ? (
55
+ <button
56
+ type="button"
57
+ onClick={() =>
58
+ setSort((p) =>
59
+ p?.key === c.key
60
+ ? p.dir === "asc"
61
+ ? { key: c.key, dir: "desc" }
62
+ : null
63
+ : { key: c.key, dir: "asc" },
64
+ )
65
+ }
66
+ >
67
+ {c.header} {sort?.key === c.key ? (sort.dir === "asc" ? "▲" : "▼") : "↕"}
68
+ </button>
69
+ ) : (
70
+ c.header
71
+ )}
72
+ </th>
73
+ ))}
74
+ </tr>
75
+ </thead>
76
+ <tbody>
77
+ {rows.map((row, i) => (
78
+ <tr key={i} className="border-b border-border last:border-0 hover:bg-muted/50">
79
+ {columns.map((c) => (
80
+ <td key={c.key} className="px-3 py-2.5">
81
+ {c.render ? c.render(row) : String(row[c.key] ?? "")}
82
+ </td>
83
+ ))}
84
+ </tr>
85
+ ))}
86
+ </tbody>
87
+ </table>
88
+ {pageCount > 1 ? (
89
+ <div className="flex items-center justify-between border-t border-border px-3 py-2 text-sm">
90
+ <span className="text-muted-foreground">
91
+ Page {page + 1} of {pageCount}
92
+ </span>
93
+ <div className="flex gap-1">
94
+ <button
95
+ type="button"
96
+ className="rounded-md border border-border px-3 py-1 disabled:opacity-50"
97
+ disabled={page === 0}
98
+ onClick={() => setPage((p) => p - 1)}
99
+ >
100
+ Previous
101
+ </button>
102
+ <button
103
+ type="button"
104
+ className="rounded-md border border-border px-3 py-1 disabled:opacity-50"
105
+ disabled={page >= pageCount - 1}
106
+ onClick={() => setPage((p) => p + 1)}
107
+ >
108
+ Next
109
+ </button>
110
+ </div>
111
+ </div>
112
+ ) : null}
113
+ </div>
114
+ )
115
+ }
package/theme.css ADDED
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Vantage design tokens. Imported after `@import "tailwindcss"` by the
3
+ * generated runtime.css. Defines CSS variables (light + dark) and maps them to
4
+ * Tailwind v4 color/radius utilities via `@theme inline`.
5
+ */
6
+
7
+ :root {
8
+ --background: hsl(0 0% 100%);
9
+ --foreground: hsl(240 10% 3.9%);
10
+ --card: hsl(0 0% 100%);
11
+ --card-foreground: hsl(240 10% 3.9%);
12
+ --popover: hsl(0 0% 100%);
13
+ --popover-foreground: hsl(240 10% 3.9%);
14
+ --primary: hsl(240 5.9% 10%);
15
+ --primary-foreground: hsl(0 0% 98%);
16
+ --secondary: hsl(240 4.8% 95.9%);
17
+ --secondary-foreground: hsl(240 5.9% 10%);
18
+ --muted: hsl(240 4.8% 95.9%);
19
+ --muted-foreground: hsl(240 3.8% 46.1%);
20
+ --accent: hsl(240 4.8% 95.9%);
21
+ --accent-foreground: hsl(240 5.9% 10%);
22
+ --destructive: hsl(0 72% 51%);
23
+ --destructive-foreground: hsl(0 0% 98%);
24
+ --border: hsl(240 5.9% 90%);
25
+ --input: hsl(240 5.9% 90%);
26
+ --ring: hsl(240 5.9% 10%);
27
+ --radius: 0.625rem;
28
+
29
+ --chart-1: hsl(221 83% 53%);
30
+ --chart-2: hsl(160 60% 45%);
31
+ --chart-3: hsl(31 90% 55%);
32
+ --chart-4: hsl(280 65% 60%);
33
+ --chart-5: hsl(340 75% 55%);
34
+ }
35
+
36
+ .dark,
37
+ [data-theme="dark"] {
38
+ --background: hsl(240 10% 3.9%);
39
+ --foreground: hsl(0 0% 98%);
40
+ --card: hsl(240 8% 6%);
41
+ --card-foreground: hsl(0 0% 98%);
42
+ --popover: hsl(240 8% 6%);
43
+ --popover-foreground: hsl(0 0% 98%);
44
+ --primary: hsl(0 0% 98%);
45
+ --primary-foreground: hsl(240 5.9% 10%);
46
+ --secondary: hsl(240 3.7% 15.9%);
47
+ --secondary-foreground: hsl(0 0% 98%);
48
+ --muted: hsl(240 3.7% 15.9%);
49
+ --muted-foreground: hsl(240 5% 64.9%);
50
+ --accent: hsl(240 3.7% 15.9%);
51
+ --accent-foreground: hsl(0 0% 98%);
52
+ --destructive: hsl(0 62% 50%);
53
+ --destructive-foreground: hsl(0 0% 98%);
54
+ --border: hsl(240 3.7% 15.9%);
55
+ --input: hsl(240 3.7% 18%);
56
+ --ring: hsl(240 4.9% 83.9%);
57
+
58
+ --chart-1: hsl(217 91% 60%);
59
+ --chart-2: hsl(160 60% 45%);
60
+ --chart-3: hsl(31 90% 55%);
61
+ --chart-4: hsl(280 65% 65%);
62
+ --chart-5: hsl(340 75% 60%);
63
+ }
64
+
65
+ @theme inline {
66
+ --color-background: var(--background);
67
+ --color-foreground: var(--foreground);
68
+ --color-card: var(--card);
69
+ --color-card-foreground: var(--card-foreground);
70
+ --color-popover: var(--popover);
71
+ --color-popover-foreground: var(--popover-foreground);
72
+ --color-primary: var(--primary);
73
+ --color-primary-foreground: var(--primary-foreground);
74
+ --color-secondary: var(--secondary);
75
+ --color-secondary-foreground: var(--secondary-foreground);
76
+ --color-muted: var(--muted);
77
+ --color-muted-foreground: var(--muted-foreground);
78
+ --color-accent: var(--accent);
79
+ --color-accent-foreground: var(--accent-foreground);
80
+ --color-destructive: var(--destructive);
81
+ --color-destructive-foreground: var(--destructive-foreground);
82
+ --color-border: var(--border);
83
+ --color-input: var(--input);
84
+ --color-ring: var(--ring);
85
+ --color-chart-1: var(--chart-1);
86
+ --color-chart-2: var(--chart-2);
87
+ --color-chart-3: var(--chart-3);
88
+ --color-chart-4: var(--chart-4);
89
+ --color-chart-5: var(--chart-5);
90
+ --radius-sm: calc(var(--radius) - 4px);
91
+ --radius-md: calc(var(--radius) - 2px);
92
+ --radius-lg: var(--radius);
93
+ --radius-xl: calc(var(--radius) + 4px);
94
+ }
95
+
96
+ body {
97
+ background-color: var(--background);
98
+ color: var(--foreground);
99
+ font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
100
+ -webkit-font-smoothing: antialiased;
101
+ }