mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-17 04:59:41 +02:00
Mirror sibling to firsts: das *letzte* Mal, das du etwas getan hast — markiert oder rückwirkend erkannt. Plan: docs/plans/lasts-module.md. M1 Skelett — Dexie v51 lasts-Tabelle, Encryption-Registry, Per-Space- Welcome-Seed, Empty-State ListView. Kategorien aus firsts/types.ts nach \$lib/data/milestones/categories.ts extrahiert (Re-Exports halten firsts-API stabil). M2 CRUD + DetailView — StatusTabs (Vermutet/Bestätigt/Aufgehoben), Quick-Add mit Mode-Toggle, always-editable DetailView mit Lifecycle- Buttons (Bestätigen, Aufheben mit Inline-Note), 44 i18n-Keys × 5 Locales. M3 Inbox + Inferenz — Dexie v52 lastsCooldown (12-Monate-Cooldown, deterministische ID), Source-Registry-Pattern in inference/, places- Source mit Heuristik visitCount>=5 Span>=180d Silence>=365d. InboxView mit Akzeptieren/Verwerfen + manueller Scan. contacts/habits → M3.b sobald jeweilige Frequenz-Felder existieren. M4 AI-Tools — 5 Tools im AI_TOOL_CATALOG (create_last, confirm_last, reclaim_last, list_lasts, suggest_lasts), Webapp-Executor mit Vault- Locked-Handling. Server-Drift-Test 4/4, Schema-Test 6/6. M5 Reminders + Settings — Pivot zu In-App-DueBanner statt OS-Push (kein PWA-Push-System im Repo). Pure date-math (12 Vitest cases), Settings- Store mit 4 Toggles, DueBanner mit max-N rendering, Test-Banner-Knopf. M6 Visibility + Unlisted-Sharing — VisibilityPicker + SharedLinkControls in DetailView, buildLastBlob mit reflective-core whitelist (reclaimed Lasts gehärtet ausgeblockt), SharedLastView public-render, Share- Dispatcher kennt 'lasts'. M7 Meilensteine-Aggregator — Cross-modul firsts vereinigt mit lasts Timeline + Year-Recap. Pure aggregator (mergeMilestones, buildMilestonesRecap), 12 Vitest cases. /milestones und /milestones/recap/[year] Routes, Cross-Link in lasts/ListView. Validation: 0 errors / 0 warnings (svelte-check 7645 files), 24/24 tests, i18n-parity 39x5 aligned (+2 namespaces), i18n-keys baseline- equal, crypto 211 tables. LOCAL TIER PATCH: lasts ist 'guest' für Testing — vor Release auf 'beta' setzen (packages/shared-branding/src/mana-apps.ts). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
312 lines
69 KiB
TypeScript
312 lines
69 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>`;
|
|
|
|
// Quotes icon (quote/inspiration with gradient)
|
|
const quotesSvg = `<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>`;
|
|
|
|
// Food icon (nutrition/heart with gradient)
|
|
const foodSvg = `<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(#foodGrad)"/><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="foodGrad" 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>`;
|
|
|
|
// 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>`;
|
|
|
|
// Comic icon — speech bubble with a lightning-bolt panel marker on
|
|
// orange→red gradient. Sits warm between Picture (green) and Wardrobe
|
|
// (rose) so the Mana launcher reads as a coherent creative family.
|
|
const comicSvg = `<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(#comicGrad)"/><path d="M260 340c0-33 27-60 60-60h384c33 0 60 27 60 60v288c0 33-27 60-60 60H480l-108 90v-90h-52c-33 0-60-27-60-60V340z" fill="white"/><path d="M540 370l-90 156h72l-30 128 108-172h-78l28-112h-10z" fill="#ea580c"/><circle cx="360" cy="460" r="18" fill="#ea580c" fill-opacity="0.35"/><circle cx="410" cy="460" r="18" fill="#ea580c" fill-opacity="0.35"/><circle cx="460" cy="460" r="18" fill="#ea580c" fill-opacity="0.35"/><defs><linearGradient id="comicGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#f97316"/><stop offset="1" stop-color="#dc2626"/></linearGradient></defs></svg>`;
|
|
|
|
// Wardrobe icon — T-shirt on hanger with rose-violet gradient.
|
|
// Rose/violet to sit between Picture (green) and Calc (pink) without
|
|
// clashing; the hanger loop sits on the shoulder line so the silhouette
|
|
// reads as "clothing" at any scale.
|
|
const wardrobeSvg = `<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(#wardrobeGrad)"/><path d="M512 246c-34 0-62 28-62 62 0 15 6 28 15 37l-113 58c-14 7-22 22-22 37v40l-40 28c-10 7-13 20-8 31l20 40c5 10 16 16 27 13l46-12v256c0 18 14 32 32 32h250c18 0 32-14 32-32V580l46 12c11 3 22-3 27-13l20-40c5-11 2-24-8-31l-40-28v-40c0-15-8-30-22-37l-113-58c9-9 15-22 15-37 0-34-28-62-62-62zm0 44c18 0 32 14 32 32s-14 32-32 32-32-14-32-32 14-32 32-32z" fill="white"/><path d="M420 450c0 50 41 90 92 90s92-40 92-90" stroke="#be185d" stroke-width="6" stroke-linecap="round" fill="none" stroke-opacity="0.25"/><defs><linearGradient id="wardrobeGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#e11d48"/><stop offset="1" stop-color="#a21caf"/></linearGradient></defs></svg>`;
|
|
|
|
// Augur icon — open eye with a small star in the iris and three drifting
|
|
// dots ("signs in the air") on indigo→violet gradient. Sits in the cosmic
|
|
// family next to Dreams (indigo) and Cards (violet) so the launcher reads
|
|
// as "the seeing/oracular cluster". The eye is symmetric and abstract on
|
|
// purpose: not a religious or zodiac symbol, just "watch".
|
|
const augurSvg = `<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(#augurGrad)"/><path d="M260 512c0 0 112-148 252-148s252 148 252 148-112 148-252 148S260 512 260 512z" fill="white"/><circle cx="512" cy="512" r="86" fill="#4338ca"/><circle cx="512" cy="512" r="34" fill="#0f0a3d"/><path d="M512 470l8 26h27l-22 16 8 26-21-16-21 16 8-26-22-16h27z" fill="white"/><circle cx="320" cy="320" r="14" fill="white" fill-opacity="0.55"/><circle cx="700" cy="290" r="10" fill="white" fill-opacity="0.45"/><circle cx="740" cy="720" r="12" fill="white" fill-opacity="0.5"/><circle cx="290" cy="700" r="8" fill="white" fill-opacity="0.4"/><defs><linearGradient id="augurGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#4338ca"/><stop offset="1" stop-color="#7c3aed"/></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),
|
|
quiz: svgToDataUrl(
|
|
// Speech-bubble question mark with a small checkmark — quiz / answer.
|
|
// Pink→fuchsia gradient to stand apart from the purple Cards icon.
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="qz" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#ec4899"/><stop offset="100%" style="stop-color:#a21caf"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#qz)"/><path d="M22 34a8 8 0 0 1 8-8h40a8 8 0 0 1 8 8v24a8 8 0 0 1-8 8H42l-12 10v-10h0a8 8 0 0 1-8-8V34z" fill="white"/><path d="M42 42c0-5 4-8 8-8s8 3 8 8c0 4-4 5-6 7-1 1-2 3-2 5" stroke="#a21caf" stroke-width="3.5" stroke-linecap="round" fill="none"/><circle cx="50" cy="60" r="2.4" fill="#a21caf"/><path d="M60 72l5 5 11-11" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg>`
|
|
),
|
|
picture: svgToDataUrl(pictureSvg),
|
|
quotes: svgToDataUrl(quotesSvg),
|
|
wisekeep: svgToDataUrl(wisekeepSvg),
|
|
moodlit: svgToDataUrl(moodlitSvg),
|
|
food: svgToDataUrl(foodSvg),
|
|
contacts: svgToDataUrl(contactsSvg),
|
|
calendar: svgToDataUrl(calendarSvg),
|
|
storage: svgToDataUrl(storageSvg),
|
|
clock: svgToDataUrl(clockSvg),
|
|
todo: svgToDataUrl(todoSvg),
|
|
mail: svgToDataUrl(mailSvg),
|
|
inventory: svgToDataUrl(inventorySvg),
|
|
wardrobe: svgToDataUrl(wardrobeSvg),
|
|
comic: svgToDataUrl(comicSvg),
|
|
augur: svgToDataUrl(augurSvg),
|
|
questions: svgToDataUrl(questionsSvg),
|
|
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>`
|
|
),
|
|
'news-research': svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="nr" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#0891b2"/><stop offset="100%" style="stop-color:#22d3ee"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#nr)"/><path d="M30 30a6 6 0 0 0-6 6v6M30 30a6 6 0 0 1 6 6v0M30 30v0" stroke="white" stroke-width="3" fill="none" stroke-linecap="round"/><circle cx="30" cy="30" r="3" fill="white"/><circle cx="52" cy="52" r="18" stroke="white" stroke-width="4" fill="none"/><line x1="65" y1="65" x2="78" y2="78" stroke="white" stroke-width="5" stroke-linecap="round"/><line x1="44" y1="50" x2="58" y2="50" stroke="white" stroke-width="3" stroke-linecap="round"/><line x1="44" y1="56" x2="54" y2="56" stroke="white" stroke-width="3" stroke-linecap="round"/></svg>`
|
|
),
|
|
'research-lab': svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="rl" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#8b5cf6"/><stop offset="100%" style="stop-color:#a78bfa"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#rl)"/><path d="M42 22h16v14l12 26a10 10 0 0 1-9 14H39a10 10 0 0 1-9-14l12-26V22z" fill="white" fill-opacity="0.2" stroke="white" stroke-width="3" stroke-linejoin="round"/><line x1="38" y1="22" x2="62" y2="22" stroke="white" stroke-width="4" stroke-linecap="round"/><circle cx="42" cy="58" r="2.5" fill="white"/><circle cx="55" cy="64" r="2" fill="white" fill-opacity="0.7"/><circle cx="48" cy="70" r="2.5" fill="white" fill-opacity="0.9"/></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>`
|
|
),
|
|
plants: 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>`
|
|
),
|
|
journal: svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="jn" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#6366f1"/><stop offset="100%" style="stop-color:#4338ca"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#jn)"/><rect x="30" y="20" width="40" height="60" rx="4" stroke="white" stroke-width="4" fill="none"/><path d="M26 24v52" stroke="white" stroke-width="4" stroke-linecap="round"/><path d="M40 36h20M40 46h16M40 56h12" 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>`
|
|
),
|
|
period: 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>`
|
|
),
|
|
body: svgToDataUrl(
|
|
// Dumbbell + heart-pulse hybrid: training (barbell) + body (pulse line).
|
|
// Red→orange gradient to set it apart from the green health-adjacent
|
|
// modules (plants, food) and the pink period icon.
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="bd" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#ef4444"/><stop offset="100%" style="stop-color:#f97316"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#bd)"/><rect x="18" y="42" width="6" height="16" rx="2" fill="white"/><rect x="76" y="42" width="6" height="16" rx="2" fill="white"/><rect x="24" y="46" width="4" height="8" rx="1" fill="white" fill-opacity="0.85"/><rect x="72" y="46" width="4" height="8" rx="1" fill="white" fill-opacity="0.85"/><rect x="28" y="48" width="44" height="4" rx="2" fill="white"/><path d="M30 70h12l4-8 6 16 4-10 6 6h12" stroke="white" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg>`
|
|
),
|
|
firsts: svgToDataUrl(
|
|
// Sparkle/star burst — represents a special "first time" moment.
|
|
// Warm amber→rose gradient to evoke excitement and novelty.
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="fi" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#f59e0b"/><stop offset="100%" style="stop-color:#e11d48"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#fi)"/><path d="M50 18l5 14 14-5-10 11 10 11-14-5-5 14-5-14-14 5 10-11-10-11 14 5z" fill="white"/><circle cx="28" cy="70" r="4" fill="white" fill-opacity="0.6"/><circle cx="72" cy="68" r="3" fill="white" fill-opacity="0.5"/><circle cx="38" cy="80" r="2.5" fill="white" fill-opacity="0.4"/><circle cx="65" cy="82" r="2" fill="white" fill-opacity="0.35"/></svg>`
|
|
),
|
|
lasts: svgToDataUrl(
|
|
// Hourglass with a single falling grain — the moment something
|
|
// passes for the last time. Indigo→slate gradient for the
|
|
// contemplative, retrospective tone (mirror to firsts' warm amber).
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="la" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#6366f1"/><stop offset="100%" style="stop-color:#475569"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#la)"/><path d="M32 22h36" stroke="white" stroke-width="4" stroke-linecap="round"/><path d="M32 78h36" stroke="white" stroke-width="4" stroke-linecap="round"/><path d="M34 24c0 14 16 22 16 26s-16 12-16 26" stroke="white" stroke-width="3" fill="none" stroke-linecap="round"/><path d="M66 24c0 14-16 22-16 26s16 12 16 26" stroke="white" stroke-width="3" fill="none" stroke-linecap="round"/><path d="M40 30h20l-10 16z" fill="white" fill-opacity="0.85"/><path d="M40 70h20l-10-16z" fill="white" fill-opacity="0.35"/><circle cx="50" cy="55" r="2" fill="white"/></svg>`
|
|
),
|
|
drink: svgToDataUrl(
|
|
// Water drop + glass — represents beverage tracking.
|
|
// Blue→cyan gradient for the hydration theme.
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="dk" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#3b82f6"/><stop offset="100%" style="stop-color:#06b6d4"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#dk)"/><path d="M35 28h30l-4 48a10 10 0 0 1-10 9h-2a10 10 0 0 1-10-9L35 28z" fill="white" fill-opacity="0.9"/><path d="M39 52c0-4 5-6 11-6s11 2 11 6v12a8 8 0 0 1-8 7h-6a8 8 0 0 1-8-7V52z" fill="#3b82f6" fill-opacity="0.35"/><path d="M33 28h34" stroke="white" stroke-width="4" stroke-linecap="round"/><circle cx="72" cy="36" r="3" fill="white" fill-opacity="0.6"/><circle cx="68" cy="46" r="2" fill="white" fill-opacity="0.4"/><circle cx="74" cy="54" r="2.5" fill="white" fill-opacity="0.3"/></svg>`
|
|
),
|
|
who: svgToDataUrl(
|
|
// Theatre mask silhouette in front of a question mark — references
|
|
// the "guess who's behind the disguise" mechanic. Purple gradient.
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="wh" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#a855f7"/><stop offset="100%" style="stop-color:#7c3aed"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#wh)"/><path d="M58 30c-3-2-7-3-11-3-12 0-22 9-22 21 0 7 4 13 9 17l-3 11 11-5c2 0 3 1 5 1 12 0 22-9 22-21 0-7-4-13-11-21z" fill="white" fill-opacity="0.18"/><path d="M50 28c-4 0-8 1-11 3-7 8-11 14-11 21 0 12 10 21 22 21 12 0 22-9 22-21s-10-24-22-24z" fill="white"/><circle cx="44" cy="48" r="2.6" fill="#7c3aed"/><circle cx="60" cy="48" r="2.6" fill="#7c3aed"/><path d="M44 60c2 3 4 4 6 4s4-1 6-4" stroke="#7c3aed" stroke-width="2.5" stroke-linecap="round" fill="none"/><text x="76" y="42" font-family="system-ui" font-size="22" font-weight="700" fill="white" fill-opacity="0.85">?</text></svg>`
|
|
),
|
|
recipes: svgToDataUrl(
|
|
// Cooking pot with steam — represents recipe collection.
|
|
// Orange→amber gradient for a warm kitchen feel.
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="rc" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#f97316"/><stop offset="100%" style="stop-color:#d97706"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#rc)"/><ellipse cx="50" cy="56" rx="24" ry="6" fill="white" fill-opacity="0.2"/><path d="M28 50h44v18a14 14 0 0 1-14 14H42a14 14 0 0 1-14-14V50z" fill="white" fill-opacity="0.9"/><rect x="26" y="47" width="48" height="6" rx="3" fill="white"/><path d="M22 50h-4a2 2 0 0 1 0-4h4" stroke="white" stroke-width="2.5" stroke-linecap="round" fill="none"/><path d="M78 50h4a2 2 0 0 0 0-4h-4" stroke="white" stroke-width="2.5" stroke-linecap="round" fill="none"/><path d="M40 38c0-4 3-6 3-10" stroke="white" stroke-width="2.5" stroke-linecap="round" fill="none" opacity="0.7"/><path d="M50 36c0-4 3-6 3-10" stroke="white" stroke-width="2.5" stroke-linecap="round" fill="none" opacity="0.7"/><path d="M60 38c0-4 3-6 3-10" stroke="white" stroke-width="2.5" stroke-linecap="round" fill="none" opacity="0.7"/></svg>`
|
|
),
|
|
stretch: svgToDataUrl(
|
|
// Person in a stretch pose — represents guided stretching / flexibility.
|
|
// Emerald→teal gradient for the health/wellness theme.
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="st" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#10b981"/><stop offset="100%" style="stop-color:#0d9488"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#st)"/><circle cx="50" cy="26" r="7" fill="white"/><path d="M50 35v18" stroke="white" stroke-width="4" stroke-linecap="round"/><path d="M50 53l-16 18" stroke="white" stroke-width="4" stroke-linecap="round"/><path d="M50 53l16 18" stroke="white" stroke-width="4" stroke-linecap="round"/><path d="M32 40l18 5 18-5" stroke="white" stroke-width="4" stroke-linecap="round" fill="none"/><path d="M26 34l6 6" stroke="white" stroke-width="3" stroke-linecap="round"/><path d="M74 34l-6 6" stroke="white" stroke-width="3" stroke-linecap="round"/></svg>`
|
|
),
|
|
meditate: svgToDataUrl(
|
|
// Person in lotus meditation pose with radiating calm.
|
|
// Violet→indigo gradient for the mindfulness/calm theme.
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="md" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#8b5cf6"/><stop offset="100%" style="stop-color:#6366f1"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#md)"/><circle cx="50" cy="28" r="7" fill="white"/><path d="M50 36v14" stroke="white" stroke-width="4" stroke-linecap="round"/><path d="M36 44c4 2 9 3 14 3s10-1 14-3" stroke="white" stroke-width="3.5" stroke-linecap="round" fill="none"/><path d="M32 47l-6-5" stroke="white" stroke-width="3" stroke-linecap="round"/><path d="M68 47l6-5" stroke="white" stroke-width="3" stroke-linecap="round"/><path d="M38 56c-6 4-10 8-10 12 0 6 10 10 22 10s22-4 22-10c0-4-4-8-10-12" stroke="white" stroke-width="3.5" stroke-linecap="round" fill="none"/><path d="M42 56l-4 10h24l-4-10" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" fill="white" fill-opacity="0.2"/><circle cx="50" cy="50" r="28" stroke="white" stroke-width="1.5" fill="none" opacity="0.2"/><circle cx="50" cy="50" r="36" stroke="white" stroke-width="1" fill="none" opacity="0.1"/></svg>`
|
|
),
|
|
sleep: svgToDataUrl(
|
|
// Moon with stars — represents sleep / night time.
|
|
// Indigo→purple gradient for the nighttime/rest theme.
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="sl" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#6366f1"/><stop offset="100%" style="stop-color:#7c3aed"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#sl)"/><path d="M62 24c-18 2-32 17-32 35 0 19 16 35 35 35 12 0 22-6 28-14-4 2-9 3-14 3-19 0-35-16-35-35 0-10 4-18 10-24z" fill="white" fill-opacity="0.9"/><circle cx="68" cy="28" r="2.5" fill="white" fill-opacity="0.7"/><circle cx="78" cy="38" r="1.5" fill="white" fill-opacity="0.5"/><circle cx="58" cy="18" r="1.5" fill="white" fill-opacity="0.5"/><circle cx="82" cy="24" r="2" fill="white" fill-opacity="0.6"/></svg>`
|
|
),
|
|
mood: svgToDataUrl(
|
|
// Smiley face — represents mood/emotion tracking.
|
|
// Warm amber→rose gradient for the emotional/feelings theme.
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="mo" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#f59e0b"/><stop offset="100%" style="stop-color:#f43f5e"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#mo)"/><circle cx="50" cy="50" r="28" fill="white" fill-opacity="0.9"/><circle cx="40" cy="44" r="3.5" fill="#f59e0b"/><circle cx="60" cy="44" r="3.5" fill="#f59e0b"/><path d="M38 58c3 5 7 7 12 7s9-2 12-7" stroke="#f59e0b" stroke-width="3" stroke-linecap="round" fill="none"/></svg>`
|
|
),
|
|
// ── Companion Brain ─────────────────────────────────
|
|
myday: svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="md" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#F59E0B"/><stop offset="100%" style="stop-color:#F97316"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#md)"/><circle cx="50" cy="44" r="16" fill="white" fill-opacity="0.9"/><line x1="50" y1="20" x2="50" y2="26" stroke="white" stroke-width="3" stroke-linecap="round" opacity="0.7"/><line x1="50" y1="62" x2="50" y2="68" stroke="white" stroke-width="3" stroke-linecap="round" opacity="0.7"/><line x1="26" y1="44" x2="32" y2="44" stroke="white" stroke-width="3" stroke-linecap="round" opacity="0.7"/><line x1="68" y1="44" x2="74" y2="44" stroke="white" stroke-width="3" stroke-linecap="round" opacity="0.7"/><rect x="24" y="74" width="52" height="4" rx="2" fill="white" fill-opacity="0.5"/><rect x="30" y="82" width="40" height="3" rx="1.5" fill="white" fill-opacity="0.3"/></svg>`
|
|
),
|
|
activity: svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="es" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#6366F1"/><stop offset="100%" style="stop-color:#8B5CF6"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#es)"/><polyline points="20,55 35,40 50,50 65,30 80,45" fill="none" stroke="white" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round" opacity="0.9"/><circle cx="35" cy="40" r="3" fill="white"/><circle cx="50" cy="50" r="3" fill="white"/><circle cx="65" cy="30" r="3" fill="white"/><circle cx="80" cy="45" r="3" fill="white"/><rect x="24" y="66" width="52" height="3" rx="1.5" fill="white" fill-opacity="0.4"/><rect x="24" y="74" width="36" height="3" rx="1.5" fill="white" fill-opacity="0.3"/></svg>`
|
|
),
|
|
companion: svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="cp" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#8B5CF6"/><stop offset="100%" style="stop-color:#A78BFA"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#cp)"/><rect x="25" y="28" width="50" height="36" rx="8" fill="white" fill-opacity="0.9"/><circle cx="40" cy="44" r="4" fill="#8B5CF6"/><circle cx="60" cy="44" r="4" fill="#8B5CF6"/><rect x="40" y="52" width="20" height="3" rx="1.5" fill="#8B5CF6" opacity="0.5"/><polygon points="35,64 45,64 38,76" fill="white" fill-opacity="0.9"/></svg>`
|
|
),
|
|
goals: svgToDataUrl(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="gl" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#10B981"/><stop offset="100%" style="stop-color:#059669"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#gl)"/><circle cx="50" cy="46" r="24" fill="none" stroke="white" stroke-width="3.5" opacity="0.4"/><circle cx="50" cy="46" r="16" fill="none" stroke="white" stroke-width="3" opacity="0.6"/><circle cx="50" cy="46" r="8" fill="none" stroke="white" stroke-width="2.5" opacity="0.8"/><circle cx="50" cy="46" r="3" fill="white"/><rect x="28" y="78" width="44" height="4" rx="2" fill="white" fill-opacity="0.4"/></svg>`
|
|
),
|
|
wetter: svgToDataUrl(
|
|
// Sun partially behind cloud with rain drops — weather / forecast.
|
|
// Sky-blue gradient for the weather theme.
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="wt" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#38bdf8"/><stop offset="100%" style="stop-color:#0284c7"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#wt)"/><circle cx="62" cy="32" r="14" fill="white" fill-opacity="0.9"/><line x1="62" y1="12" x2="62" y2="18" stroke="white" stroke-width="2.5" stroke-linecap="round" opacity="0.7"/><line x1="62" y1="46" x2="62" y2="52" stroke="white" stroke-width="2.5" stroke-linecap="round" opacity="0.5"/><line x1="42" y1="32" x2="48" y2="32" stroke="white" stroke-width="2.5" stroke-linecap="round" opacity="0.7"/><line x1="76" y1="32" x2="82" y2="32" stroke="white" stroke-width="2.5" stroke-linecap="round" opacity="0.7"/><line x1="48" y1="18" x2="52" y2="22" stroke="white" stroke-width="2.5" stroke-linecap="round" opacity="0.6"/><line x1="76" y1="18" x2="72" y2="22" stroke="white" stroke-width="2.5" stroke-linecap="round" opacity="0.6"/><path d="M28 56a14 14 0 0 1 14-14h0a14 14 0 0 1 13 9 10 10 0 0 1 11 10 10 10 0 0 1-10 10H30a10 10 0 0 1-10-10 10 10 0 0 1 8-5z" fill="white" fill-opacity="0.95"/><line x1="34" y1="76" x2="30" y2="84" stroke="white" stroke-width="2.5" stroke-linecap="round" opacity="0.7"/><line x1="46" y1="76" x2="42" y2="84" stroke="white" stroke-width="2.5" stroke-linecap="round" opacity="0.7"/><line x1="58" y1="76" x2="54" y2="84" stroke="white" stroke-width="2.5" stroke-linecap="round" opacity="0.7"/></svg>`
|
|
),
|
|
library: svgToDataUrl(
|
|
// Stack of books (left) + a book with a spine/pages motif (right) — the
|
|
// "Bibliothek" theme covering books/movies/series/comics. Purple→fuchsia
|
|
// gradient sits next to music/photos/picture in the Kreativität & Medien row.
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="lb" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#a855f7"/><stop offset="100%" style="stop-color:#d946ef"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#lb)"/><rect x="22" y="28" width="10" height="44" rx="2" fill="white" fill-opacity="0.95"/><rect x="34" y="24" width="10" height="48" rx="2" fill="white" fill-opacity="0.8"/><rect x="46" y="30" width="10" height="42" rx="2" fill="white" fill-opacity="0.95"/><rect x="58" y="28" width="22" height="44" rx="3" fill="white"/><rect x="62" y="34" width="4" height="4" fill="#a855f7"/><rect x="72" y="34" width="4" height="4" fill="#a855f7"/><rect x="62" y="44" width="4" height="4" fill="#a855f7"/><rect x="72" y="44" width="4" height="4" fill="#a855f7"/><rect x="62" y="54" width="4" height="4" fill="#a855f7"/><rect x="72" y="54" width="4" height="4" fill="#a855f7"/><rect x="62" y="64" width="4" height="4" fill="#a855f7"/><rect x="72" y="64" width="4" height="4" fill="#a855f7"/><rect x="20" y="74" width="62" height="4" rx="2" fill="white" fill-opacity="0.5"/></svg>`
|
|
),
|
|
articles: svgToDataUrl(
|
|
// Bookmark ribbon tucked into a folded document corner — "Für später
|
|
// gemerkt". Orange→amber gradient sets it apart from news (emerald)
|
|
// and news-research (cyan) in the Wissen & Recherche row.
|
|
`<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:#f97316"/><stop offset="100%" style="stop-color:#f59e0b"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#ar)"/><path d="M28 22h30l18 18v38a4 4 0 0 1-4 4H28a4 4 0 0 1-4-4V26a4 4 0 0 1 4-4z" fill="white" fill-opacity="0.95"/><path d="M58 22v14a4 4 0 0 0 4 4h14" fill="none" stroke="#f97316" stroke-width="2" stroke-opacity="0.35"/><rect x="32" y="48" width="26" height="3" rx="1.5" fill="#f97316" fill-opacity="0.6"/><rect x="32" y="56" width="22" height="3" rx="1.5" fill="#f97316" fill-opacity="0.45"/><rect x="32" y="64" width="24" height="3" rx="1.5" fill="#f97316" fill-opacity="0.6"/><path d="M62 54v22l8-6 8 6V54a4 4 0 0 0-4-4h-8a4 4 0 0 0-4 4z" fill="#f97316"/></svg>`
|
|
),
|
|
writing: svgToDataUrl(
|
|
// Fountain-pen nib writing on a lined sheet — the "Ghostwriter"
|
|
// theme. Sky→cyan gradient sits next to chat (sky) and storage
|
|
// (blue) without clashing, while standing apart from articles
|
|
// (orange) and library (purple) in the text/media family.
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="wr" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#0ea5e9"/><stop offset="100%" style="stop-color:#06b6d4"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#wr)"/><rect x="20" y="22" width="44" height="56" rx="4" fill="white" fill-opacity="0.95"/><line x1="26" y1="34" x2="56" y2="34" stroke="#0ea5e9" stroke-width="2" stroke-opacity="0.5" stroke-linecap="round"/><line x1="26" y1="42" x2="52" y2="42" stroke="#0ea5e9" stroke-width="2" stroke-opacity="0.35" stroke-linecap="round"/><line x1="26" y1="50" x2="56" y2="50" stroke="#0ea5e9" stroke-width="2" stroke-opacity="0.35" stroke-linecap="round"/><line x1="26" y1="58" x2="48" y2="58" stroke="#0ea5e9" stroke-width="2" stroke-opacity="0.35" stroke-linecap="round"/><path d="M62 72l14-14 8 8-14 14-10 2 2-10z" fill="white"/><path d="M74 60l8 8" stroke="#0ea5e9" stroke-width="2" stroke-linecap="round" stroke-opacity="0.6"/><path d="M60 74l4 4" stroke="#0ea5e9" stroke-width="2" stroke-linecap="round" stroke-opacity="0.6"/></svg>`
|
|
),
|
|
invoices: svgToDataUrl(
|
|
// Document with a QR-code corner (CH QR-Bill) + a diagonal amount line.
|
|
// Emerald→teal sits next to finance green in the Arbeit & Finanzen row.
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="iv" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#059669"/><stop offset="100%" style="stop-color:#14b8a6"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#iv)"/><path d="M28 22h34l14 14v42a4 4 0 0 1-4 4H28a4 4 0 0 1-4-4V26a4 4 0 0 1 4-4z" fill="white" fill-opacity="0.95"/><path d="M62 22v10a4 4 0 0 0 4 4h10" fill="none" stroke="#059669" stroke-width="2" stroke-opacity="0.35"/><rect x="32" y="44" width="24" height="3" rx="1" fill="#059669" fill-opacity="0.6"/><rect x="32" y="52" width="20" height="3" rx="1" fill="#059669" fill-opacity="0.45"/><rect x="32" y="60" width="28" height="3" rx="1" fill="#059669" fill-opacity="0.6"/><rect x="60" y="58" width="14" height="14" rx="1" fill="#059669"/><rect x="62" y="60" width="3" height="3" fill="white"/><rect x="69" y="60" width="3" height="3" fill="white"/><rect x="62" y="67" width="3" height="3" fill="white"/><rect x="66" y="64" width="2" height="2" fill="white"/><rect x="69" y="67" width="3" height="3" fill="white"/></svg>`
|
|
),
|
|
broadcast: svgToDataUrl(
|
|
// Megaphone / loudspeaker with three radiating sound arcs.
|
|
// Indigo→cyan gradient sets it apart from mail (blue) and invoices
|
|
// (emerald) while staying in the "communication" colour family.
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="bc" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#6366f1"/><stop offset="100%" style="stop-color:#06b6d4"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#bc)"/><path d="M32 42v16l14 4v-24l-14 4z" fill="white" fill-opacity="0.95"/><path d="M46 38l26-10v44l-26-10z" fill="white"/><path d="M42 62v14a3 3 0 0 0 3 3h4a3 3 0 0 0 3-3V64" fill="white" fill-opacity="0.85"/><path d="M78 40c4 2 6 5 6 10s-2 8-6 10" fill="none" stroke="white" stroke-width="2.5" stroke-linecap="round" opacity="0.8"/><path d="M84 32c6 3 10 9 10 18s-4 15-10 18" fill="none" stroke="white" stroke-width="2.5" stroke-linecap="round" opacity="0.5"/></svg>`
|
|
),
|
|
agents: svgToDataUrl(
|
|
// Smiling robot head with antenna dot — represents the AI agents that
|
|
// carry out autonomous missions. Violet→fuchsia gradient sits next to
|
|
// companion in the AI Workbench family.
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="ag" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#8b5cf6"/><stop offset="100%" style="stop-color:#d946ef"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#ag)"/><line x1="50" y1="20" x2="50" y2="28" stroke="white" stroke-width="3" stroke-linecap="round"/><circle cx="50" cy="18" r="3" fill="white"/><rect x="24" y="30" width="52" height="40" rx="10" fill="white"/><circle cx="38" cy="48" r="5" fill="#8b5cf6"/><circle cx="62" cy="48" r="5" fill="#8b5cf6"/><circle cx="39" cy="47" r="1.5" fill="white"/><circle cx="63" cy="47" r="1.5" fill="white"/><path d="M38 60c3 3 7 4 12 4s9-1 12-4" stroke="#8b5cf6" stroke-width="3" stroke-linecap="round" fill="none"/><rect x="34" y="72" width="10" height="8" rx="2" fill="white" fill-opacity="0.9"/><rect x="56" y="72" width="10" height="8" rx="2" fill="white" fill-opacity="0.9"/><line x1="22" y1="46" x2="28" y2="46" stroke="white" stroke-width="3" stroke-linecap="round" opacity="0.7"/><line x1="72" y1="46" x2="78" y2="46" stroke="white" stroke-width="3" stroke-linecap="round" opacity="0.7"/></svg>`
|
|
),
|
|
timeline: svgToDataUrl(
|
|
// Vertical event-dots with connecting line — timeline/history axis.
|
|
// Amber→orange gradient so it stands apart from the blue Activity icon
|
|
// while still reading as "chronological" in the AI Workbench family.
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="tl" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#f59e0b"/><stop offset="100%" style="stop-color:#ea580c"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#tl)"/><line x1="34" y1="22" x2="34" y2="78" stroke="white" stroke-width="3" stroke-linecap="round" opacity="0.55"/><circle cx="34" cy="30" r="5" fill="white"/><circle cx="34" cy="50" r="5" fill="white"/><circle cx="34" cy="70" r="5" fill="white"/><rect x="44" y="26" width="32" height="8" rx="2" fill="white" fill-opacity="0.95"/><rect x="44" y="46" width="26" height="8" rx="2" fill="white" fill-opacity="0.8"/><rect x="44" y="66" width="30" height="8" rx="2" fill="white" fill-opacity="0.9"/></svg>`
|
|
),
|
|
website: svgToDataUrl(
|
|
// Browser window with three stacked content blocks — the "Baukasten"
|
|
// theme. Indigo→violet gradient, sibling to broadcast (communication
|
|
// family) but leaning more towards the creative-publishing cluster.
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="wb" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#6366f1"/><stop offset="100%" style="stop-color:#8b5cf6"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#wb)"/><rect x="18" y="22" width="64" height="56" rx="5" fill="white"/><rect x="18" y="22" width="64" height="10" rx="5" fill="white" fill-opacity="0.75"/><circle cx="25" cy="27" r="1.8" fill="#6366f1" fill-opacity="0.5"/><circle cx="31" cy="27" r="1.8" fill="#6366f1" fill-opacity="0.5"/><circle cx="37" cy="27" r="1.8" fill="#6366f1" fill-opacity="0.5"/><rect x="24" y="38" width="52" height="12" rx="2" fill="#6366f1" fill-opacity="0.85"/><rect x="24" y="54" width="24" height="18" rx="2" fill="#6366f1" fill-opacity="0.35"/><rect x="52" y="54" width="24" height="8" rx="2" fill="#6366f1" fill-opacity="0.55"/><rect x="52" y="64" width="24" height="8" rx="2" fill="#6366f1" fill-opacity="0.45"/></svg>`
|
|
),
|
|
spaces: svgToDataUrl(
|
|
// Three people-silhouettes clustered in the tile — the Spaces primitive
|
|
// is about shared workspaces, so the icon emphasises "group". Teal→indigo
|
|
// gradient sits next to contacts (green) and chat (indigo) in the
|
|
// communication family without competing with either.
|
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><linearGradient id="sp" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#14b8a6"/><stop offset="100%" style="stop-color:#6366f1"/></linearGradient></defs><rect width="100" height="100" rx="22" fill="url(#sp)"/><circle cx="30" cy="38" r="9" fill="white" fill-opacity="0.85"/><path d="M14 70c0-9 7-16 16-16s16 7 16 16v4H14v-4z" fill="white" fill-opacity="0.85"/><circle cx="70" cy="38" r="9" fill="white" fill-opacity="0.85"/><path d="M54 70c0-9 7-16 16-16s16 7 16 16v4H54v-4z" fill="white" fill-opacity="0.85"/><circle cx="50" cy="32" r="11" fill="white"/><path d="M30 76c0-11 9-20 20-20s20 9 20 20v4H30v-4z" fill="white"/></svg>`
|
|
),
|
|
} as const;
|
|
|
|
export type AppIconId = keyof typeof APP_ICONS;
|