// portfolio-atoms.jsx — shared themeable atoms (CSS-var driven) // Each screen wrapper defines: --bg --card --card2 --border --border-soft // --text --muted --dim --accent --accent-soft --pos --neg --pos-soft --neg-soft // Exports to window: Dot, Pnl, ShareBar, RangeBadge, Ticker, Sparkdots, signClass const { useState } = React; function signClass(v) { return v >= 0 ? "pos" : "neg"; } // colored status dot function Dot({ color, size = 8, glow }) { return ( ); } // PnL value text, colored function Pnl({ children, v, weight = 600, size }) { const pos = v >= 0; return ( {children} ); } // mini share-of-portfolio bar with number function ShareBar({ pct, width = 56, accent = "var(--bar, var(--accent))", showNum = true, max = 50 }) { const w = Math.max(2, Math.min(100, (pct / max) * 100)); return ( {showNum && ( {window.fmt.pct(pct)} )} ); } // LP range status badge function RangeBadge({ inRange }) { return ( {inRange ? "в диапазоне" : "вне диапазона"} ); } // real crypto coin logos — crisp inline SVG brand marks function Glyph({ ch, dx = 16, dy = 21.5, fs = 17 }) { return ( {ch} ); } const LOGOS = { BTC: () => ( ), cbBTC: () => ( ), ETH: () => ( ), SOL: () => ( ), USDC: () => ( ), USDT: () => ( ), }; // Логотипы остальных монет — настоящие иконки CoinGecko (для тех, у кого нет // рисованного SVG выше). Грузятся как . Новую монету достаточно добавить сюда. const LOGO_URLS = { APT: "https://coin-images.coingecko.com/coins/images/26455/large/Aptos-Network-Symbol-Black-RGB-1x.png?1761789140", ARB: "https://coin-images.coingecko.com/coins/images/16547/large/arb.jpg?1721358242", CFG: "https://coin-images.coingecko.com/coins/images/15380/large/centrifuge.PNG?1696515027", DAI: "https://coin-images.coingecko.com/coins/images/9956/large/Badge_Dai.png?1696509996", EYWA: "https://coin-images.coingecko.com/coins/images/51242/large/Eywa.png?1730449129", FDUSD: "https://coin-images.coingecko.com/coins/images/31079/large/FDUSD_icon_black.png?1731097953", FRAX: "https://coin-images.coingecko.com/coins/images/13422/large/LFRAX.png?1751911193", GHO: "https://coin-images.coingecko.com/coins/images/30663/large/gho-token-logo.png?1720517092", GUSD: "https://coin-images.coingecko.com/coins/images/5992/large/gemini-dollar-gusd.png?1696506408", HBAR: "https://coin-images.coingecko.com/coins/images/3688/large/hbar.png?1696504364", LUSD: "https://coin-images.coingecko.com/coins/images/14666/large/Group_3.png?1696514341", ONDO: "https://coin-images.coingecko.com/coins/images/26580/large/ONDO.png?1696525656", PYUSD: "https://coin-images.coingecko.com/coins/images/31212/large/PYUSD_Token_Logo_2x.png?1765987788", RLUSD: "https://coin-images.coingecko.com/coins/images/39651/large/RLUSD_200x200_%281%29.png?1727376633", STRK: "https://coin-images.coingecko.com/coins/images/26433/large/starknet.png?1696525507", TUSD: "https://coin-images.coingecko.com/coins/images/3449/large/tusd.png?1696504140", USD0: "https://coin-images.coingecko.com/coins/images/38272/large/USD0LOGO.png?1716962811", USDD: "https://coin-images.coingecko.com/coins/images/25380/large/UUSD.jpg?1696524513", USDE: "https://coin-images.coingecko.com/coins/images/33613/large/usde.png?1733810059", USDP: "https://coin-images.coingecko.com/coins/images/6013/large/Pax_Dollar.png?1696506427", USDS: "https://coin-images.coingecko.com/coins/images/39926/large/usds.webp?1726666683", ZK: "https://coin-images.coingecko.com/coins/images/38043/large/ZKTokenBlack.png?1718614502", crvUSD: "https://coin-images.coingecko.com/coins/images/30118/large/crvusd.jpg?1746670973", }; function Ticker({ sym, size = 28 }) { const draw = LOGOS[sym]; if (draw) { return ( {draw()} ); } // настоящая иконка CoinGecko на белой подложке (чтобы чёрные логотипы вроде // APT/ZK были видны и на тёмной теме); при ошибке загрузки — fallback на букву const url = LOGO_URLS[sym]; if (url) { return ( {sym} { e.currentTarget.style.display = "none"; if (e.currentTarget.nextSibling) e.currentTarget.nextSibling.style.display = "inline-flex"; }} /> {sym.slice(0, 1)} ); } // fallback: neutral circle with first letter return ( {sym.slice(0, 1)} ); } Object.assign(window, { Dot, Pnl, ShareBar, RangeBadge, Ticker, signClass });