{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"market-side","title":"Market side","description":"The favourable / exposed / level tone every catman figure shares, the arrow that carries it without colour, and the two colour tokens behind it.","dependencies":["lucide-react"],"files":[{"path":"src/registry/catman/ui/market-side.tsx","content":"import { ArrowDownIcon, ArrowUpIcon } from \"lucide-react\"\n\n/**\n * Which side of the market a figure puts the retailer on, from the retailer's\n * point of view rather than the arithmetic's. A reader is asking one question\n * of every price figure: is this one going my way. Naming the tone after the\n * answer is what lets a price gap, an index and a cover position share it.\n *\n * Part of the twelfth catman registry (`@twelfth/market-side`). The tones read\n * the `favourable` and `exposed` colour tokens this item installs.\n */\nexport type MarketSide = \"favourable\" | \"exposed\" | \"level\" | \"unknown\"\n\n/** From a price position (ours vs theirs, in percent): above market is exposed. */\nexport function marketSideFromPosition(positionPct: number | null): MarketSide {\n  if (positionPct === null || !Number.isFinite(positionPct)) return \"unknown\"\n  if (Math.round(Math.abs(positionPct)) === 0) return \"level\"\n  return positionPct > 0 ? \"exposed\" : \"favourable\"\n}\n\n/** Tone only. Geometry stays with the caller: a table cell wants a fixed,\n * right-aligned box, a pill wants to hug its contents. */\nexport const marketToneClass: Record<MarketSide, string> = {\n  favourable: \"bg-favourable font-semibold text-favourable-foreground\",\n  exposed: \"bg-exposed font-semibold text-exposed-foreground\",\n  level: \"text-foreground\",\n  unknown: \"text-muted-foreground\",\n}\n\n/** The arrow that survives a reader who cannot separate the two tones.\n *\n * It points the way the figure beside it moved. A price or a gap is THEIR side\n * (the default): exposed is down, they are cheaper. An index is ours ÷ theirs\n * × 100, OUR side: exposed is up, we are priced above. */\nexport function MarketArrow({ side, className, pointing = \"theirs\" }: { side: MarketSide; className?: string; pointing?: \"theirs\" | \"ours\" }) {\n  const up = pointing === \"ours\" ? side === \"exposed\" : side === \"favourable\"\n  const down = pointing === \"ours\" ? side === \"favourable\" : side === \"exposed\"\n  if (up) return <ArrowUpIcon aria-hidden className={className} />\n  if (down) return <ArrowDownIcon aria-hidden className={className} />\n  return null\n}\n","type":"registry:ui"}],"cssVars":{"theme":{"color-favourable":"var(--favourable)","color-favourable-foreground":"var(--favourable-foreground)","color-exposed":"var(--exposed)","color-exposed-foreground":"var(--exposed-foreground)"},"light":{"favourable":"#dbece2","favourable-foreground":"#3e5c4b","exposed":"#f2e7c9","exposed-foreground":"#6b5223"},"dark":{"favourable":"#273b2f","favourable-foreground":"#c2e5cc","exposed":"#373320","exposed-foreground":"#e9e1c0"}},"type":"registry:ui"}