mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-18 07:49:41 +02:00
New unified-app module under apps/mana/apps/web/src/lib/modules/cycles. Adds three Dexie tables (cycles, cycleDayLogs, cycleSymptoms) in db v7, SYNC_APP_MAP entry, app-registry registration, branding (icon + entry + APP_URLS), and a /cycles route. Includes phase derivation (menstruation/follicular/ovulation/luteal), heuristic next-period and fertile-window prediction (rolling mean over last 6 cycles), 10 default symptoms, and 33 unit tests covering the pure utilities. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
156 lines
38 KiB
TypeScript
156 lines
38 KiB
TypeScript
/**
|
|
* App icons as SVG data URLs for the Mana ecosystem
|
|
* These can be used directly as image src or CSS background-image
|
|
*/
|
|
|
|
// Helper to convert SVG string to data URL
|
|
const svgToDataUrl = (svg: string): string => {
|
|
const encoded = encodeURIComponent(svg).replace(/'/g, '%27').replace(/"/g, '%22');
|
|
return `data:image/svg+xml,${encoded}`;
|
|
};
|
|
|
|
// Memoro icon SVG
|
|
const memoroSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M512 130C722.973 130 894 301.027 894 512C894 722.973 722.973 894 512 894C301.027 894 130 722.973 130 512C130 301.027 301.027 130 512 130ZM328.076 324.825C322.366 323.075 316.506 323.345 310.81 324.903C299.274 328.059 288.955 336.364 283.562 342.26C260.131 367.874 245.424 391.558 236.524 418.066C227.606 444.63 224.432 474.286 224.432 512C224.432 670.525 352.874 783.368 512 783.368C671.126 783.368 799.568 670.525 799.568 512C799.568 474.285 796.393 444.629 787.475 418.064C778.574 391.555 763.867 367.872 740.435 342.257C735.237 336.575 723.981 328.835 711.804 325.948C705.777 324.52 699.735 324.331 694.177 325.975C688.685 327.599 683.404 331.086 678.906 337.479L569.857 492.133C554.287 513.249 535.932 525.917 515.688 526.654C495.436 527.391 474.644 516.138 454.368 492.428L345.154 337.57C339.593 330.392 333.746 326.563 328.076 324.825Z" fill="#F8D62B"/><path d="M512 130C722.973 130 894 301.027 894 512C894 722.973 722.973 894 512 894C301.027 894 130 722.973 130 512C130 301.027 301.027 130 512 130ZM328.076 324.825C322.366 323.075 316.506 323.345 310.81 324.903C299.274 328.059 288.955 336.364 283.562 342.26C260.131 367.874 245.424 391.558 236.524 418.066C227.606 444.63 224.432 474.286 224.432 512C224.432 670.525 352.874 783.368 512 783.368C671.126 783.368 799.568 670.525 799.568 512C799.568 474.285 796.393 444.629 787.475 418.064C778.574 391.555 763.867 367.872 740.435 342.257C735.237 336.575 723.981 328.835 711.804 325.948C705.777 324.52 699.735 324.331 694.177 325.975C688.685 327.599 683.404 331.086 678.906 337.479L569.857 492.133C554.287 513.249 535.932 525.917 515.688 526.654C495.436 527.391 474.644 516.138 454.368 492.428L345.154 337.57C339.593 330.392 333.746 326.563 328.076 324.825Z" stroke="#FFE97B" stroke-width="8"/></svg>`;
|
|
|
|
// Mana icon (single droplet)
|
|
const manaSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M515.714 104.592C516.403 105.506 586.851 198.868 657.146 311.452C692.29 367.739 727.445 428.91 753.828 485.782C780.141 542.503 797.996 595.499 798 635.247L797.994 637.095C797.001 794.047 669.581 920.992 512.52 921C354.836 921 227 793.054 227 635.247L227.014 633.369C227.567 593.742 245.359 541.362 271.366 485.376C297.857 428.348 333.141 367.024 368.373 310.65C403.613 254.263 438.847 202.755 465.267 165.349C478.478 146.644 489.489 131.46 497.198 120.95C501.053 115.695 504.083 111.608 506.15 108.833C507.184 107.446 507.977 106.386 508.513 105.673C508.78 105.316 508.984 105.046 509.12 104.864C509.188 104.774 509.24 104.705 509.274 104.659C509.292 104.636 509.305 104.619 509.313 104.607C509.318 104.602 509.322 104.597 509.324 104.594C509.329 104.593 509.419 104.658 512.52 107L509.327 104.589L512.522 100.359L515.714 104.592ZM512.519 360.227C503.066 372.996 474.086 412.798 445.191 459.084C427.696 487.109 410.282 517.433 397.254 545.525C384.156 573.769 375.759 599.211 375.759 617.659C375.762 693.248 436.998 754.533 512.52 754.533C588.041 754.533 649.277 693.248 649.277 617.659C649.277 599.223 640.892 573.803 627.809 545.581C614.796 517.51 597.398 487.208 579.915 459.195C550.999 412.865 521.982 373.013 512.519 360.227Z" fill="url(#paint0_linear_1194_1020)" stroke="#0199FF" stroke-width="8"/><defs><linearGradient id="paint0_linear_1194_1020" x1="512.5" y1="107" x2="512.5" y2="917" gradientUnits="userSpaceOnUse"><stop stop-color="#0068AD"/><stop offset="0.524038" stop-color="#0099FF"/></linearGradient></defs></svg>`;
|
|
|
|
// ManaChat icon (simplified chat bubble with gradient)
|
|
const chatSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#chatGrad)"/><path d="M512 280C655.6 280 772 380.8 772 504C772 627.2 655.6 728 512 728C483.2 728 455.2 724 428.4 716.4L324 776L348.8 684.4C296.8 640.4 264 580.8 264 516C264 388.8 372.8 280 512 280ZM392 480C375.2 480 362 493.2 362 510C362 526.8 375.2 540 392 540C408.8 540 422 526.8 422 510C422 493.2 408.8 480 392 480ZM512 480C495.2 480 482 493.2 482 510C482 526.8 495.2 540 512 540C528.8 540 542 526.8 542 510C542 493.2 528.8 480 512 480ZM632 480C615.2 480 602 493.2 602 510C602 526.8 615.2 540 632 540C648.8 540 662 526.8 662 510C662 493.2 648.8 480 632 480Z" fill="white"/><defs><linearGradient id="chatGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#0ea5e9"/><stop offset="1" stop-color="#0284c7"/></linearGradient></defs></svg>`;
|
|
|
|
// Presi icon (presentation/slides icon with gradient)
|
|
const presiSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#presiGrad)"/><rect x="280" y="300" width="464" height="344" rx="24" fill="white"/><rect x="320" y="340" width="180" height="120" rx="8" fill="#f97316" fill-opacity="0.3"/><rect x="320" y="480" width="120" height="16" rx="4" fill="#f97316" fill-opacity="0.5"/><rect x="320" y="512" width="200" height="12" rx="3" fill="#f97316" fill-opacity="0.3"/><rect x="320" y="536" width="160" height="12" rx="3" fill="#f97316" fill-opacity="0.3"/><circle cx="620" cy="400" r="60" fill="#f97316"/><rect x="580" y="480" width="100" height="80" rx="8" fill="#f97316" fill-opacity="0.4"/><path d="M512 688L512 744" stroke="white" stroke-width="24" stroke-linecap="round"/><circle cx="512" cy="784" r="32" fill="white"/><defs><linearGradient id="presiGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#f97316"/><stop offset="1" stop-color="#ea580c"/></linearGradient></defs></svg>`;
|
|
|
|
// Cards icon (cards/flashcards with gradient)
|
|
const cardsSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#deckGrad)"/><rect x="280" y="340" width="320" height="420" rx="24" fill="white" transform="rotate(-8 280 340)"/><rect x="340" y="280" width="320" height="420" rx="24" fill="white" transform="rotate(4 340 280)"/><rect x="380" y="300" width="320" height="420" rx="24" fill="white"/><rect x="420" y="380" width="240" height="20" rx="4" fill="#8b5cf6" fill-opacity="0.6"/><rect x="420" y="420" width="180" height="16" rx="4" fill="#8b5cf6" fill-opacity="0.4"/><rect x="420" y="450" width="200" height="16" rx="4" fill="#8b5cf6" fill-opacity="0.4"/><rect x="420" y="520" width="240" height="120" rx="8" fill="#8b5cf6" fill-opacity="0.2"/><defs><linearGradient id="deckGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#8b5cf6"/><stop offset="1" stop-color="#7c3aed"/></linearGradient></defs></svg>`;
|
|
|
|
// Picture icon (image/gallery with gradient)
|
|
const pictureSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#pictureGrad)"/><rect x="260" y="300" width="504" height="424" rx="24" fill="white"/><circle cx="380" cy="420" r="50" fill="#22c55e" fill-opacity="0.6"/><path d="M260 600L420 480L520 580L620 460L764 600V700C764 713.255 753.255 724 740 724H284C270.745 724 260 713.255 260 700V600Z" fill="#22c55e" fill-opacity="0.4"/><defs><linearGradient id="pictureGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#22c55e"/><stop offset="1" stop-color="#16a34a"/></linearGradient></defs></svg>`;
|
|
|
|
// Zitare icon (quote/inspiration with gradient)
|
|
const zitareSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#quoteGrad)"/><path d="M340 360C340 338.909 356.909 322 378 322H486C507.091 322 524 338.909 524 360V468C524 489.091 507.091 506 486 506H420L360 580V506H378C356.909 506 340 489.091 340 468V360Z" fill="white"/><path d="M500 440C500 418.909 516.909 402 538 402H646C667.091 402 684 418.909 684 440V548C684 569.091 667.091 586 646 586H580L520 660V586H538C516.909 586 500 569.091 500 548V440Z" fill="white" fill-opacity="0.7"/><rect x="300" y="680" width="424" height="16" rx="4" fill="white" fill-opacity="0.6"/><rect x="340" y="712" width="344" height="12" rx="3" fill="white" fill-opacity="0.4"/><defs><linearGradient id="quoteGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#f59e0b"/><stop offset="1" stop-color="#d97706"/></linearGradient></defs></svg>`;
|
|
|
|
// WiseKeep icon (wisdom/lightbulb with gradient)
|
|
const wisekeepSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#wiseGrad)"/><path d="M512 240C408.954 240 324 324.954 324 428C324 495.636 360.727 554.545 416 588.364V652C416 674.091 434.909 692 457 692H567C589.091 692 608 674.091 608 652V588.364C663.273 554.545 700 495.636 700 428C700 324.954 615.046 240 512 240Z" fill="white"/><rect x="432" y="720" width="160" height="24" rx="12" fill="white"/><rect x="456" y="760" width="112" height="20" rx="10" fill="white"/><path d="M512 340V500M432 420H592" stroke="#6366f1" stroke-width="24" stroke-linecap="round"/><defs><linearGradient id="wiseGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#6366f1"/><stop offset="1" stop-color="#4f46e5"/></linearGradient></defs></svg>`;
|
|
|
|
// Moodlit icon (colorful gradient circle)
|
|
const moodlitSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0)"><rect x="103" y="103" width="819" height="819" rx="409.5" fill="white"/><g filter="url(#filter0)"><circle cx="611" cy="250" r="314" fill="#D10000"/></g><g filter="url(#filter1)"><circle cx="231" cy="393" r="314" fill="#D17A00"/></g><g filter="url(#filter2)"><circle cx="735" cy="625" r="314" fill="#FFEA00"/></g><g filter="url(#filter3)"><circle cx="409" cy="844" r="314" fill="#0033FF"/></g></g><rect x="107" y="107" width="811" height="811" rx="405.5" stroke="white" stroke-opacity="0.2" stroke-width="8"/><defs><filter id="filter0" x="-2" y="-363" width="1226" height="1226" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur stdDeviation="149" result="effect1"/></filter><filter id="filter1" x="-382" y="-220" width="1226" height="1226" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur stdDeviation="149" result="effect1"/></filter><filter id="filter2" x="122" y="12" width="1226" height="1226" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur stdDeviation="149" result="effect1"/></filter><filter id="filter3" x="-204" y="231" width="1226" height="1226" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur stdDeviation="149" result="effect1"/></filter><clipPath id="clip0"><rect x="103" y="103" width="819" height="819" rx="409.5" fill="white"/></clipPath></defs></svg>`;
|
|
|
|
// Nutriphi icon (nutrition/heart with gradient)
|
|
const nutriphiSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#nutriGrad)"/><path d="M512 760C512 760 280 600 280 420C280 340 344 280 424 280C472 280 512 308 512 308C512 308 552 280 600 280C680 280 744 340 744 420C744 600 512 760 512 760Z" fill="white"/><path d="M512 280V200" stroke="white" stroke-width="24" stroke-linecap="round"/><path d="M512 200C512 200 560 160 600 180" stroke="white" stroke-width="24" stroke-linecap="round"/><defs><linearGradient id="nutriGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#10b981"/><stop offset="1" stop-color="#059669"/></linearGradient></defs></svg>`;
|
|
|
|
// Contacts icon (address book/person with gradient)
|
|
const contactsSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#contactsGrad)"/><circle cx="512" cy="380" r="100" fill="white"/><path d="M320 620C320 540 408 480 512 480C616 480 704 540 704 620V680C704 702.091 685.091 720 663 720H361C338.909 720 320 702.091 320 680V620Z" fill="white"/><rect x="240" y="300" width="24" height="80" rx="12" fill="white" fill-opacity="0.6"/><rect x="240" y="420" width="24" height="80" rx="12" fill="white" fill-opacity="0.6"/><rect x="240" y="540" width="24" height="80" rx="12" fill="white" fill-opacity="0.6"/><defs><linearGradient id="contactsGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#3b82f6"/><stop offset="1" stop-color="#2563eb"/></linearGradient></defs></svg>`;
|
|
|
|
// Calendar icon (calendar with gradient)
|
|
const calendarSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#calendarGrad)"/><rect x="260" y="320" width="504" height="424" rx="24" fill="white"/><rect x="260" y="320" width="504" height="100" rx="24" fill="white"/><rect x="260" y="396" width="504" height="24" fill="#0ea5e9" fill-opacity="0.3"/><rect x="340" y="260" width="24" height="100" rx="12" fill="white"/><rect x="660" y="260" width="24" height="100" rx="12" fill="white"/><rect x="300" y="480" width="80" height="60" rx="8" fill="#0ea5e9" fill-opacity="0.2"/><rect x="400" y="480" width="80" height="60" rx="8" fill="#0ea5e9" fill-opacity="0.2"/><rect x="500" y="480" width="80" height="60" rx="8" fill="#0ea5e9"/><rect x="600" y="480" width="80" height="60" rx="8" fill="#0ea5e9" fill-opacity="0.2"/><rect x="300" y="560" width="80" height="60" rx="8" fill="#0ea5e9" fill-opacity="0.2"/><rect x="400" y="560" width="80" height="60" rx="8" fill="#0ea5e9" fill-opacity="0.2"/><rect x="500" y="560" width="80" height="60" rx="8" fill="#0ea5e9" fill-opacity="0.2"/><rect x="600" y="560" width="80" height="60" rx="8" fill="#0ea5e9" fill-opacity="0.2"/><rect x="300" y="640" width="80" height="60" rx="8" fill="#0ea5e9" fill-opacity="0.2"/><rect x="400" y="640" width="80" height="60" rx="8" fill="#0ea5e9" fill-opacity="0.2"/><rect x="500" y="640" width="80" height="60" rx="8" fill="#0ea5e9" fill-opacity="0.2"/><rect x="600" y="640" width="80" height="60" rx="8" fill="#0ea5e9" fill-opacity="0.2"/><defs><linearGradient id="calendarGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#0ea5e9"/><stop offset="1" stop-color="#0284c7"/></linearGradient></defs></svg>`;
|
|
|
|
// Storage icon (cloud storage with gradient)
|
|
const storageSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#storageGrad)"/><path d="M720 520C720 448.471 662.529 391 591 391C584.614 391 578.337 391.479 572.195 392.404C546.867 332.088 487.173 290 418 290C328.157 290 256 362.157 256 452C256 461.033 256.748 469.887 258.179 478.5C214.762 497.476 184 540.728 184 591C184 658.32 238.68 713 306 713H680C749.32 713 804 658.32 804 591C804 547.831 779.054 510.325 742.5 491.5C734.321 503.137 728 516.893 728 532V536C728 567.48 755.482 593 789 593" stroke="white" stroke-width="40" stroke-linecap="round" stroke-linejoin="round"/><path d="M512 500V700M512 700L420 608M512 700L604 608" stroke="white" stroke-width="40" stroke-linecap="round" stroke-linejoin="round"/><defs><linearGradient id="storageGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#3b82f6"/><stop offset="1" stop-color="#1d4ed8"/></linearGradient></defs></svg>`;
|
|
|
|
// Clock icon (analog clock with gradient)
|
|
const clockSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#clockGrad)"/><circle cx="512" cy="512" r="280" stroke="white" stroke-width="40"/><circle cx="512" cy="512" r="20" fill="white"/><path d="M512 300V400" stroke="white" stroke-width="24" stroke-linecap="round"/><path d="M512 624V724" stroke="white" stroke-width="24" stroke-linecap="round"/><path d="M300 512H400" stroke="white" stroke-width="24" stroke-linecap="round"/><path d="M624 512H724" stroke="white" stroke-width="24" stroke-linecap="round"/><path d="M512 512V340" stroke="white" stroke-width="32" stroke-linecap="round"/><path d="M512 512L620 580" stroke="white" stroke-width="24" stroke-linecap="round"/><circle cx="662" cy="280" r="40" fill="white" fill-opacity="0.3"/><path d="M662 260V280L678 296" stroke="white" stroke-width="8" stroke-linecap="round"/><defs><linearGradient id="clockGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#f59e0b"/><stop offset="1" stop-color="#d97706"/></linearGradient></defs></svg>`;
|
|
|
|
// Todo icon (checkbox/task list with gradient)
|
|
const todoSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#todoGrad)"/><rect x="280" y="300" width="464" height="424" rx="24" fill="white"/><circle cx="360" cy="400" r="28" stroke="#8b5cf6" stroke-width="8"/><path d="M348 400L356 408L372 392" stroke="#8b5cf6" stroke-width="8" stroke-linecap="round" stroke-linejoin="round"/><rect x="420" y="384" width="280" height="24" rx="6" fill="#8b5cf6" fill-opacity="0.3"/><circle cx="360" cy="512" r="28" stroke="#8b5cf6" stroke-width="8" fill="#8b5cf6"/><path d="M348 512L356 520L372 504" stroke="white" stroke-width="8" stroke-linecap="round" stroke-linejoin="round"/><rect x="420" y="496" width="200" height="24" rx="6" fill="#8b5cf6" fill-opacity="0.5"/><circle cx="360" cy="624" r="28" stroke="#8b5cf6" stroke-width="8"/><rect x="420" y="608" width="240" height="24" rx="6" fill="#8b5cf6" fill-opacity="0.3"/><defs><linearGradient id="todoGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#8b5cf6"/><stop offset="1" stop-color="#7c3aed"/></linearGradient></defs></svg>`;
|
|
|
|
// Mail icon (envelope with gradient)
|
|
const mailSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#mailGrad)"/><rect x="240" y="320" width="544" height="384" rx="24" fill="white"/><path d="M240 380L512 540L784 380" stroke="#6366f1" stroke-width="24" stroke-linecap="round" stroke-linejoin="round"/><rect x="320" y="520" width="200" height="16" rx="4" fill="#6366f1" fill-opacity="0.3"/><rect x="320" y="560" width="160" height="12" rx="3" fill="#6366f1" fill-opacity="0.2"/><rect x="320" y="592" width="240" height="12" rx="3" fill="#6366f1" fill-opacity="0.2"/><defs><linearGradient id="mailGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#6366f1"/><stop offset="1" stop-color="#4f46e5"/></linearGradient></defs></svg>`;
|
|
|
|
// Inventory icon (box/package with gradient)
|
|
const inventorySvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#inventoryGrad)"/><path d="M280 380L512 260L744 380V644L512 764L280 644V380Z" fill="white"/><path d="M512 500V764M280 380L512 500L744 380" stroke="#14b8a6" stroke-width="24" stroke-linejoin="round"/><path d="M396 320L628 440" stroke="#14b8a6" stroke-width="16" stroke-linecap="round"/><rect x="460" y="560" width="104" height="80" rx="8" fill="#14b8a6" fill-opacity="0.3"/><defs><linearGradient id="inventoryGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#14b8a6"/><stop offset="1" stop-color="#0d9488"/></linearGradient></defs></svg>`;
|
|
|
|
// Questions icon (question mark with magnifying glass)
|
|
const questionsSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#questionsGrad)"/><circle cx="480" cy="440" r="180" stroke="white" stroke-width="40"/><path d="M620 580L740 700" stroke="white" stroke-width="48" stroke-linecap="round"/><path d="M440 360C440 332 462 310 490 310C520 310 550 330 550 370C550 420 490 430 490 480" stroke="white" stroke-width="32" stroke-linecap="round"/><circle cx="490" cy="540" r="20" fill="white"/><defs><linearGradient id="questionsGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#8b5cf6"/><stop offset="1" stop-color="#7c3aed"/></linearGradient></defs></svg>`;
|
|
|
|
// Matrix icon (network/federated chat with purple gradient)
|
|
const matrixSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#matrixGrad)"/><circle cx="512" cy="400" r="80" fill="white"/><circle cx="340" cy="580" r="60" fill="white" fill-opacity="0.8"/><circle cx="684" cy="580" r="60" fill="white" fill-opacity="0.8"/><circle cx="420" cy="720" r="50" fill="white" fill-opacity="0.6"/><circle cx="604" cy="720" r="50" fill="white" fill-opacity="0.6"/><path d="M512 480V640M512 640L420 700M512 640L604 700" stroke="white" stroke-width="16" stroke-linecap="round"/><path d="M450 440L370 540M574 440L654 540" stroke="white" stroke-width="16" stroke-linecap="round"/><path d="M340 640L400 700M684 640L624 700" stroke="white" stroke-width="12" stroke-linecap="round" stroke-opacity="0.6"/><defs><linearGradient id="matrixGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#8b5cf6"/><stop offset="1" stop-color="#7c3aed"/></linearGradient></defs></svg>`;
|
|
|
|
// CityCorners icon (map pin with blue gradient)
|
|
const citycornersSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#ccGrad)"/><path d="M512 200C408.3 200 324 284.3 324 388C324 536 512 800 512 800C512 800 700 536 700 388C700 284.3 615.7 200 512 200ZM512 468C467.8 468 432 432.2 432 388C432 343.8 467.8 308 512 308C556.2 308 592 343.8 592 388C592 432.2 556.2 468 512 468Z" fill="white"/><circle cx="512" cy="388" r="60" fill="#2563eb" fill-opacity="0.4"/><defs><linearGradient id="ccGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#2563eb"/><stop offset="1" stop-color="#1d4ed8"/></linearGradient></defs></svg>`;
|
|
|
|
// Taktik icon (clock with play button, amber gradient)
|
|
const timesSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#timesGrad)"/><circle cx="512" cy="480" r="220" stroke="white" stroke-width="40"/><path d="M512 340V480L600 560" stroke="white" stroke-width="36" stroke-linecap="round" stroke-linejoin="round"/><circle cx="512" cy="480" r="20" fill="white"/><path d="M480 700L560 740L480 780Z" fill="white" fill-opacity="0.6"/><defs><linearGradient id="timesGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#f59e0b"/><stop offset="1" stop-color="#d97706"/></linearGradient></defs></svg>`;
|
|
|
|
// Calc icon (calculator with pink gradient)
|
|
const calcSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#calcGrad)"/><rect x="320" y="260" width="384" height="504" rx="32" fill="white"/><rect x="360" y="300" width="304" height="100" rx="16" fill="#ec4899" fill-opacity="0.2"/><rect x="380" y="330" width="200" height="16" rx="4" fill="#ec4899" fill-opacity="0.5"/><rect x="380" y="358" width="120" height="24" rx="4" fill="#ec4899" fill-opacity="0.7"/><rect x="360" y="440" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><rect x="440" y="440" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><rect x="520" y="440" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><rect x="600" y="440" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.3"/><rect x="360" y="508" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><rect x="440" y="508" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><rect x="520" y="508" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><rect x="600" y="508" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.3"/><rect x="360" y="576" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><rect x="440" y="576" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><rect x="520" y="576" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><rect x="600" y="576" width="64" height="120" rx="12" fill="#ec4899"/><rect x="360" y="644" width="144" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><rect x="520" y="644" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><defs><linearGradient id="calcGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#ec4899"/><stop offset="1" stop-color="#db2777"/></linearGradient></defs></svg>`;
|
|
|
|
// Context icon (document/knowledge with sky blue gradient)
|
|
const contextSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#contextGrad)"/><rect x="300" y="240" width="424" height="544" rx="24" fill="white"/><path d="M400 400H624" stroke="#0ea5e9" stroke-width="24" stroke-linecap="round"/><path d="M400 480H580" stroke="#0ea5e9" stroke-width="24" stroke-linecap="round" stroke-opacity="0.6"/><path d="M400 560H540" stroke="#0ea5e9" stroke-width="24" stroke-linecap="round" stroke-opacity="0.4"/><path d="M400 640H600" stroke="#0ea5e9" stroke-width="24" stroke-linecap="round" stroke-opacity="0.3"/><path d="M620 240V380H760" stroke="white" stroke-width="24" stroke-linecap="round" stroke-linejoin="round"/><path d="M620 240L760 380" stroke="#0ea5e9" stroke-width="16" stroke-linecap="round" stroke-opacity="0.3"/><circle cx="680" cy="620" r="100" fill="#0ea5e9" fill-opacity="0.2" stroke="white" stroke-width="16"/><path d="M660 620L680 640L720 600" stroke="white" stroke-width="16" stroke-linecap="round" stroke-linejoin="round"/><defs><linearGradient id="contextGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#0ea5e9"/><stop offset="1" stop-color="#0284c7"/></linearGradient></defs></svg>`;
|
|
|
|
/**
|
|
* App icons as data URLs
|
|
* Use these directly in <img src={APP_ICONS.memoro}> or CSS background-image
|
|
*/
|
|
export const APP_ICONS = {
|
|
memoro: svgToDataUrl(memoroSvg),
|
|
mana: svgToDataUrl(manaSvg),
|
|
chat: svgToDataUrl(chatSvg),
|
|
presi: svgToDataUrl(presiSvg),
|
|
cards: svgToDataUrl(cardsSvg),
|
|
picture: svgToDataUrl(pictureSvg),
|
|
zitare: svgToDataUrl(zitareSvg),
|
|
wisekeep: svgToDataUrl(wisekeepSvg),
|
|
moodlit: svgToDataUrl(moodlitSvg),
|
|
nutriphi: svgToDataUrl(nutriphiSvg),
|
|
contacts: svgToDataUrl(contactsSvg),
|
|
calendar: svgToDataUrl(calendarSvg),
|
|
storage: svgToDataUrl(storageSvg),
|
|
clock: svgToDataUrl(clockSvg),
|
|
todo: svgToDataUrl(todoSvg),
|
|
mail: svgToDataUrl(mailSvg),
|
|
inventory: svgToDataUrl(inventorySvg),
|
|
questions: svgToDataUrl(questionsSvg),
|
|
matrix: svgToDataUrl(matrixSvg),
|
|
context: svgToDataUrl(contextSvg),
|
|
citycorners: svgToDataUrl(citycornersSvg),
|
|
times: svgToDataUrl(timesSvg),
|
|
calc: svgToDataUrl(calcSvg),
|
|
uload: svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="ug" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#6366f1"/><stop offset="100%" style="stop-color:#818cf8"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#ug)"/><path d="M35 45a10 10 0 0 1 10-10h0a10 10 0 0 1 0 20h0M65 55a10 10 0 0 1-10 10h0a10 10 0 0 1 0-20h0M42 58l16-16" stroke="white" stroke-width="5" stroke-linecap="round" fill="none"/></svg>`
|
|
),
|
|
news: svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="ng" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#10b981"/><stop offset="100%" style="stop-color:#34d399"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#ng)"/><rect x="22" y="25" width="56" height="50" rx="4" stroke="white" stroke-width="4" fill="none"/><line x1="30" y1="38" x2="55" y2="38" stroke="white" stroke-width="3" stroke-linecap="round"/><line x1="30" y1="48" x2="70" y2="48" stroke="white" stroke-width="3" stroke-linecap="round"/><line x1="30" y1="58" x2="65" y2="58" stroke="white" stroke-width="3" stroke-linecap="round"/></svg>`
|
|
),
|
|
guides: svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="gg" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#0d9488"/><stop offset="100%" style="stop-color:#0f766e"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#gg)"/><rect x="18" y="25" width="28" height="50" rx="3" fill="white" fill-opacity="0.15"/><rect x="54" y="25" width="28" height="50" rx="3" fill="white" fill-opacity="0.15"/><rect x="46" y="25" width="8" height="50" fill="white" fill-opacity="0.25"/><circle cx="27" cy="40" r="4" fill="white" fill-opacity="0.9"/><rect x="34" y="37" width="11" height="3" rx="1.5" fill="white" fill-opacity="0.6"/><circle cx="27" cy="52" r="4" fill="white" fill-opacity="0.55"/><rect x="34" y="49" width="9" height="3" rx="1.5" fill="white" fill-opacity="0.4"/><circle cx="27" cy="64" r="4" fill="white" fill-opacity="0.3"/><rect x="34" y="61" width="10" height="3" rx="1.5" fill="white" fill-opacity="0.25"/><path d="M60 52l6 7 12-14" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg>`
|
|
),
|
|
music: svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="mk" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#ec4899"/><stop offset="100%" style="stop-color:#db2777"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#mk)"/><circle cx="35" cy="62" r="10" stroke="white" stroke-width="4" fill="none"/><circle cx="65" cy="58" r="10" stroke="white" stroke-width="4" fill="none"/><path d="M45 62V30l30-6v28" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" fill="none"/><rect x="47" y="30" width="8" height="4" rx="1" fill="white" fill-opacity="0.5"/><rect x="57" y="27" width="8" height="4" rx="1" fill="white" fill-opacity="0.5"/></svg>`
|
|
),
|
|
photos: svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="ph" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#8b5cf6"/><stop offset="100%" style="stop-color:#7c3aed"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#ph)"/><rect x="20" y="28" width="60" height="44" rx="5" stroke="white" stroke-width="4" fill="none"/><circle cx="40" cy="44" r="6" stroke="white" stroke-width="3" fill="none"/><path d="M20 60l16-14 12 10 14-12 18 16" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg>`
|
|
),
|
|
planta: svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="pl" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#22c55e"/><stop offset="100%" style="stop-color:#16a34a"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#pl)"/><path d="M50 72V42" stroke="white" stroke-width="4" stroke-linecap="round"/><path d="M50 52c-12-2-20-14-18-24 10 0 20 8 18 24z" fill="white" fill-opacity="0.9"/><path d="M50 42c10-4 22-2 24 10-10 2-22-2-24-10z" fill="white" fill-opacity="0.7"/><path d="M38 72h24" stroke="white" stroke-width="4" stroke-linecap="round"/></svg>`
|
|
),
|
|
skilltree: svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="sk" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#f59e0b"/><stop offset="100%" style="stop-color:#d97706"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#sk)"/><circle cx="50" cy="30" r="8" fill="white"/><circle cx="30" cy="55" r="7" fill="white" fill-opacity="0.8"/><circle cx="70" cy="55" r="7" fill="white" fill-opacity="0.8"/><circle cx="20" cy="75" r="6" fill="white" fill-opacity="0.5"/><circle cx="42" cy="75" r="6" fill="white" fill-opacity="0.5"/><circle cx="58" cy="75" r="6" fill="white" fill-opacity="0.5"/><circle cx="80" cy="75" r="6" fill="white" fill-opacity="0.5"/><path d="M50 38v0L30 48M50 38L70 48M30 62L20 69M30 62L42 69M70 62L58 69M70 62L80 69" stroke="white" stroke-width="3" stroke-linecap="round"/></svg>`
|
|
),
|
|
habits: svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="hb" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#8b5cf6"/><stop offset="100%" style="stop-color:#6d28d9"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#hb)"/><path d="M30 55l8 8 16-16" stroke="white" stroke-width="5" stroke-linecap="round" stroke-linejoin="round" fill="none"/><circle cx="50" cy="50" r="24" stroke="white" stroke-width="4" fill="none"/><path d="M50 26v6M50 68v6M26 50h6M68 50h6" stroke="white" stroke-width="3" stroke-linecap="round"/></svg>`
|
|
),
|
|
notes: svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="nt" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#f59e0b"/><stop offset="100%" style="stop-color:#d97706"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#nt)"/><rect x="28" y="22" width="44" height="56" rx="4" stroke="white" stroke-width="4" fill="none"/><path d="M38 36h24M38 46h24M38 56h16" stroke="white" stroke-width="3" stroke-linecap="round"/></svg>`
|
|
),
|
|
dreams: svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="dr" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#6366f1"/><stop offset="100%" style="stop-color:#312e81"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#dr)"/><path d="M62 30a22 22 0 1 0 18 34 18 18 0 0 1-18-34z" fill="white"/><circle cx="32" cy="38" r="1.6" fill="white"/><circle cx="26" cy="58" r="1.2" fill="white" fill-opacity="0.8"/><circle cx="40" cy="68" r="1.4" fill="white" fill-opacity="0.7"/><circle cx="22" cy="46" r="1" fill="white" fill-opacity="0.6"/></svg>`
|
|
),
|
|
cycles: svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="cy" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#ec4899"/><stop offset="100%" style="stop-color:#be185d"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#cy)"/><circle cx="50" cy="50" r="26" stroke="white" stroke-width="4" fill="none"/><path d="M50 24a26 26 0 0 1 22 40" stroke="white" stroke-width="4" stroke-linecap="round" fill="none"/><circle cx="72" cy="64" r="3.5" fill="white"/><circle cx="50" cy="50" r="9" fill="white"/></svg>`
|
|
),
|
|
finance: svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="fn" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#22c55e"/><stop offset="100%" style="stop-color:#16a34a"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#fn)"/><circle cx="50" cy="50" r="22" stroke="white" stroke-width="4" fill="none"/><path d="M50 34v32M42 42c0-4 3.5-6 8-6s8 2 8 6-3.5 5-8 5-8 2-8 6 3.5 6 8 6 8-2 8-6" stroke="white" stroke-width="3" stroke-linecap="round" fill="none"/></svg>`
|
|
),
|
|
places: svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="plc" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#0ea5e9"/><stop offset="100%" style="stop-color:#0284c7"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#plc)"/><path d="M50 20c-14 0-25 11-25 25 0 20 25 38 25 38s25-18 25-38c0-14-11-25-25-25zm0 34a9 9 0 1 1 0-18 9 9 0 0 1 0 18z" fill="white"/></svg>`
|
|
),
|
|
arcade: svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="ar" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#ef4444"/><stop offset="100%" style="stop-color:#dc2626"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#ar)"/><rect x="25" y="30" width="50" height="35" rx="5" stroke="white" stroke-width="4" fill="none"/><path d="M38 65v10M62 65v10M32 75h36" stroke="white" stroke-width="4" stroke-linecap="round"/><circle cx="60" cy="44" r="4" fill="white"/><circle cx="68" cy="50" r="3" fill="white" fill-opacity="0.7"/><path d="M35 44h10M40 39v10" stroke="white" stroke-width="3" stroke-linecap="round"/></svg>`
|
|
),
|
|
events: svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="ev" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#f43f5e"/><stop offset="100%" style="stop-color:#be123c"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#ev)"/><path d="M22 78l14-44 30 30-44 14z" fill="white"/><path d="M36 34c4-6 12-8 18-4M50 22c4-2 10 0 12 6M62 28c6-2 12 2 12 10" stroke="white" stroke-width="3" stroke-linecap="round" fill="none"/><circle cx="74" cy="46" r="2.5" fill="white"/><circle cx="80" cy="58" r="2" fill="white" fill-opacity="0.8"/><circle cx="68" cy="62" r="2" fill="white" fill-opacity="0.7"/></svg>`
|
|
),
|
|
} as const;
|
|
|
|
export type AppIconId = keyof typeof APP_ICONS;
|