assets: preserve supplied Felis icon kit

This commit is contained in:
Lemon-miaow committed 2026-10-04 23:50:01 +08:00
1 parent 61b283ae2f
commit a002607d47
54 files changed
+733

No files matched your search

Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 KiB

After

Width:  |  Height:  |  Size: 34 KiB

+79
View File
@@ -0,0 +1,79 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1040" height="640" viewBox="110 445 1040 640" role="img" aria-labelledby="title desc">
<title id="title">Felis</title>
<desc id="desc">A fluffy ivory kitten with sage green ears and eyes, pink cheeks, and green whiskers.</desc>
<defs>
<linearGradient id="rim" x1="250" y1="460" x2="940" y2="1090" gradientUnits="userSpaceOnUse">
<stop stop-color="#91bd86"/>
<stop offset=".5" stop-color="#8bbd83"/>
<stop offset="1" stop-color="#74ae77"/>
</linearGradient>
<linearGradient id="ear" x1="220" y1="540" x2="1010" y2="800" gradientUnits="userSpaceOnUse">
<stop stop-color="#83b57e"/>
<stop offset=".48" stop-color="#8cbd83"/>
<stop offset="1" stop-color="#80b47b"/>
</linearGradient>
<linearGradient id="earShade" x1="220" y1="610" x2="365" y2="740" gradientUnits="userSpaceOnUse">
<stop stop-color="#71aa75" stop-opacity=".32"/>
<stop offset="1" stop-color="#a6cb91" stop-opacity="0"/>
</linearGradient>
<linearGradient id="furShade" x1="220" y1="570" x2="1010" y2="1085" gradientUnits="userSpaceOnUse">
<stop stop-color="#e6ecda"/>
<stop offset=".52" stop-color="#e8eddf"/>
<stop offset="1" stop-color="#e4ebd8"/>
</linearGradient>
<radialGradient id="fur" cx=".48" cy=".56" r=".75">
<stop stop-color="#fdfbf4"/>
<stop offset="1" stop-color="#fcfaf3"/>
</radialGradient>
<linearGradient id="eye" x1="411" y1="860" x2="843" y2="993" gradientUnits="userSpaceOnUse">
<stop stop-color="#65a26c"/>
<stop offset=".48" stop-color="#6ba770"/>
<stop offset="1" stop-color="#63a16b"/>
</linearGradient>
<radialGradient id="cheek" cx=".45" cy=".42" r=".7">
<stop stop-color="#ffd2d2"/>
<stop offset="1" stop-color="#ffcccc"/>
</radialGradient>
<linearGradient id="whisker" x1="201" y1="1015" x2="282" y2="1015" gradientUnits="userSpaceOnUse">
<stop stop-color="#92bf87"/>
<stop offset="1" stop-color="#62a16c"/>
</linearGradient>
</defs>
<g id="felis">
<!-- Ear rims sit behind the pale ear fur and the forehead. -->
<path fill="url(#rim)" d="M174 633C176 566 202 481 233 459C263 438 329 462 384 484C443 509 488 550 517 580C553 560 601 548 643 549L631 569C666 566 704 573 734 583C792 517 880 470 949 454C977 448 1008 447 1024 462C1057 490 1075 568 1078 632L1027 801L935 777L749 625L509 624L315 774L218 814Z"/>
<path fill="url(#rim)" d="M194 782C188 799 191 821 199 837C187 854 175 869 163 882L220 866L265 800Z"/>
<path fill="url(#rim)" d="M1020 800C1037 815 1050 806 1062 786C1064 809 1059 829 1051 843L1080 882L1034 861Z"/>
<path fill="url(#furShade)" d="M236 479C211 512 189 568 177 623C168 678 173 743 191 785C199 805 210 815 225 812L258 778L386 651L285 518Z"/>
<path fill="url(#furShade)" d="M1018 480C1049 520 1067 578 1078 632C1083 689 1076 749 1059 789C1050 809 1036 814 1022 802L974 752L884 647L968 522Z"/>
<path fill="url(#fur)" d="M235 479C243 463 267 467 289 472C364 489 451 543 501 606L501 800L234 797C205 730 203 598 240 496C235 493 231 487 235 479Z"/>
<path fill="url(#fur)" d="M1018 479C1008 460 982 465 960 470C885 486 803 533 756 598L756 800L1019 796C1043 725 1042 596 1011 494C1017 491 1021 485 1018 479Z"/>
<path fill="url(#ear)" d="M234 797C215 752 215 693 222 651C229 606 244 557 261 542C274 531 284 533 296 547C326 581 356 630 374 684C353 664 329 655 293 649C299 672 308 686 323 694C289 719 257 759 234 797Z"/>
<path fill="url(#earShade)" d="M261 542C269 544 282 565 294 588C309 620 325 649 338 666C322 658 308 653 293 649C299 672 308 686 323 694C287 720 257 759 234 797C216 752 215 693 222 651C229 606 244 557 261 542Z"/>
<path fill="url(#ear)" d="M1019 796C1038 750 1036 688 1029 646C1021 600 1008 554 990 540C978 529 968 533 956 547C925 581 896 628 878 681C900 662 922 653 961 647C954 671 945 684 929 692C966 717 996 757 1019 796Z"/>
<path fill="#a6cb91" opacity=".64" d="M265 712C274 693 290 681 306 678C311 685 316 690 323 694C301 695 281 701 265 712Z"/>
<path fill="#a4c990" opacity=".64" d="M929 692C936 688 942 682 947 676C965 678 976 688 983 701C966 694 949 691 929 692Z"/>
<!-- Green fur tips show around the ivory face. -->
<path fill="url(#rim)" d="M111 896C117 926 132 948 153 959C132 984 118 1018 117 1048C139 1014 156 992 184 974L228 916Z"/>
<path fill="url(#rim)" d="M1145 916C1132 939 1113 953 1090 960C1113 989 1127 1020 1133 1053C1106 1019 1087 996 1057 977L1017 914Z"/>
<!-- One continuous face silhouette keeps the exported outline clean. -->
<path fill="url(#fur)" d="M118 1085C120 1037 141 989 174 953C142 941 121 922 111 896C156 891 193 871 221 839C244 813 264 789 287 772C268 778 251 785 234 797C255 759 287 719 323 694C308 686 299 672 293 649C329 655 353 664 374 684C394 654 443 624 501 606C544 579 591 558 637 551C627 567 614 580 599 592C656 566 729 580 797 614C827 632 855 656 878 681C900 662 922 653 961 647C954 671 945 684 929 692C966 717 996 757 1019 796C1038 833 1058 866 1083 887C1104 905 1126 913 1145 916C1129 935 1107 945 1079 948C1111 990 1129 1037 1133 1085Z"/>
<path fill="url(#furShade)" d="M668 633C692 632 711 639 720 654C730 670 735 687 740 703Z"/>
<path fill="url(#furShade)" d="M111 896C144 905 173 908 212 901L174 953C142 941 121 922 111 896Z"/>
<path fill="url(#furShade)" d="M163 882C192 861 209 840 225 812L244 794C258 784 271 777 287 772C246 827 212 868 163 882Z"/>
<path fill="url(#furShade)" d="M1037 887C1074 901 1107 914 1145 916C1129 935 1107 945 1079 948Z"/>
<path fill="url(#furShade)" d="M118 1085C121 1054 133 1023 151 997C146 1034 151 1063 172 1085Z"/>
<path fill="url(#furShade)" d="M1081 1085C1094 1069 1101 1049 1103 1028C1115 1045 1120 1063 1122 1085Z"/>
<ellipse fill="url(#eye)" cx="454" cy="922" rx="43.5" ry="66"/>
<ellipse fill="url(#eye)" cx="800.5" cy="922" rx="43.5" ry="66"/>
<path fill="url(#eye)" d="M591 971C591 960 610 955 626 955C642 955 661 960 661 971C661 987 642 1009 626 1009C610 1009 591 987 591 971Z"/>
<ellipse fill="url(#cheek)" cx="364.5" cy="1015.5" rx="56.5" ry="38"/>
<ellipse fill="url(#cheek)" cx="889.5" cy="1015.5" rx="56.5" ry="38"/>
<path fill="url(#whisker)" d="M204 980C225 972 259 974 278 981C283 983 283 988 278 988C251 986 228 988 208 994C200 996 196 983 204 980Z"/>
<path fill="url(#whisker)" d="M204 1036C224 1022 251 1016 274 1015C280 1015 281 1021 275 1023C251 1030 230 1040 212 1050C204 1055 194 1043 204 1036Z"/>
<g transform="translate(1254 0) scale(-1 1)">
<path fill="url(#whisker)" d="M204 980C225 972 259 974 278 981C283 983 283 988 278 988C251 986 228 988 208 994C200 996 196 983 204 980Z"/>
<path fill="url(#whisker)" d="M204 1036C224 1022 251 1016 274 1015C280 1015 281 1021 275 1023C251 1030 230 1040 212 1050C204 1055 194 1043 204 1036Z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.7 KiB

+29
View File
@@ -0,0 +1,29 @@
# Felis 图标
基于参考图片手工临摹。矢量文件仅使用路径、形状、渐变和蒙版,没有嵌入位图。所有彩色导出均来自 [`../felis-logo.svg`](../felis-logo.svg)。
| 文件 | 用途 |
| --- | --- |
| `../felis-logo.svg` | 1040 × 640 紧裁透明矢量原稿 |
| `../felis-logo.png` | README 用图,保留现有 540 × 341 尺寸 |
| `felis-reference.svg` / `.png` | 保留参考图的 1254 × 1254 白底构图 |
| `felis-icon.svg` | 居中的方形透明图标 |
| `felis-app.svg` / `.png` | 浅绿圆角应用图标,1024 × 1024 |
| `felis-app-dark.svg` / `.png` | 深绿圆角应用图标,1024 × 1024 |
| `felis-maskable.svg` / `.png` | 不透明方形背景,猫脸位于中心安全圆内 |
| `felis-monochrome.svg` | 紧裁黑色单色版,眼睛和鼻子镂空 |
| `felis-mask.svg` | 方形单色版,供 Safari 固定标签使用 |
| `png/icon-{size}.png` | 透明图标:16、20、24、32、40、48、64、96、128、180、192、256、512、1024 px |
| `felis.ico` | Windows 多分辨率图标:16、24、32、48、64、128、256 px |
| `felis.icns` / `felis.iconset/` | macOS 图标及 16、32、128、256、512 pt 的 1× / 2× PNG |
| `preview.png` | 图标套装预览 |
网页资源已放入 `panel/public/`,并由 `panel/index.html` 引用:SVG / ICO / PNG favicon、180 px Apple Touch Icon、Safari 固定标签图标,以及 192 / 512 px 普通和 maskable 图标。`site.webmanifest` 提供应用名称和图标元数据,不提供离线缓存。
修改矢量原稿后可重新导出;需要 Node.js 和 `sharp`,macOS 的 ICNS 导出还使用系统 `iconutil`。在仓库根目录运行:
```sh
NODE_PATH=/path/to/node_modules node scripts/generate-icons.cjs
```
`NODE_PATH` 指向已安装 `sharp` 的 `node_modules`。导出工具不会增加面板的运行依赖;非 macOS 平台仍会生成其余格式和 `iconset`。
Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

+77
View File
@@ -0,0 +1,77 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024" role="img" aria-label="Felis">
<defs>
<linearGradient id="rim" x1="250" y1="460" x2="940" y2="1090" gradientUnits="userSpaceOnUse">
<stop stop-color="#91bd86"/>
<stop offset=".5" stop-color="#8bbd83"/>
<stop offset="1" stop-color="#74ae77"/>
</linearGradient>
<linearGradient id="ear" x1="220" y1="540" x2="1010" y2="800" gradientUnits="userSpaceOnUse">
<stop stop-color="#83b57e"/>
<stop offset=".48" stop-color="#8cbd83"/>
<stop offset="1" stop-color="#80b47b"/>
</linearGradient>
<linearGradient id="earShade" x1="220" y1="610" x2="365" y2="740" gradientUnits="userSpaceOnUse">
<stop stop-color="#71aa75" stop-opacity=".32"/>
<stop offset="1" stop-color="#a6cb91" stop-opacity="0"/>
</linearGradient>
<linearGradient id="furShade" x1="220" y1="570" x2="1010" y2="1085" gradientUnits="userSpaceOnUse">
<stop stop-color="#e6ecda"/>
<stop offset=".52" stop-color="#e8eddf"/>
<stop offset="1" stop-color="#e4ebd8"/>
</linearGradient>
<radialGradient id="fur" cx=".48" cy=".56" r=".75">
<stop stop-color="#fdfbf4"/>
<stop offset="1" stop-color="#fcfaf3"/>
</radialGradient>
<linearGradient id="eye" x1="411" y1="860" x2="843" y2="993" gradientUnits="userSpaceOnUse">
<stop stop-color="#65a26c"/>
<stop offset=".48" stop-color="#6ba770"/>
<stop offset="1" stop-color="#63a16b"/>
</linearGradient>
<radialGradient id="cheek" cx=".45" cy=".42" r=".7">
<stop stop-color="#ffd2d2"/>
<stop offset="1" stop-color="#ffcccc"/>
</radialGradient>
<linearGradient id="whisker" x1="201" y1="1015" x2="282" y2="1015" gradientUnits="userSpaceOnUse">
<stop stop-color="#92bf87"/>
<stop offset="1" stop-color="#62a16c"/>
</linearGradient>
</defs>
<rect width="1024" height="1024" rx="224" fill="#253d31"/><g transform="translate(64 236.30769230769226) scale(0.8615384615384616) translate(-110 -445)"><g id="felis">
<!-- Ear rims sit behind the pale ear fur and the forehead. -->
<path fill="url(#rim)" d="M174 633C176 566 202 481 233 459C263 438 329 462 384 484C443 509 488 550 517 580C553 560 601 548 643 549L631 569C666 566 704 573 734 583C792 517 880 470 949 454C977 448 1008 447 1024 462C1057 490 1075 568 1078 632L1027 801L935 777L749 625L509 624L315 774L218 814Z"/>
<path fill="url(#rim)" d="M194 782C188 799 191 821 199 837C187 854 175 869 163 882L220 866L265 800Z"/>
<path fill="url(#rim)" d="M1020 800C1037 815 1050 806 1062 786C1064 809 1059 829 1051 843L1080 882L1034 861Z"/>
<path fill="url(#furShade)" d="M236 479C211 512 189 568 177 623C168 678 173 743 191 785C199 805 210 815 225 812L258 778L386 651L285 518Z"/>
<path fill="url(#furShade)" d="M1018 480C1049 520 1067 578 1078 632C1083 689 1076 749 1059 789C1050 809 1036 814 1022 802L974 752L884 647L968 522Z"/>
<path fill="url(#fur)" d="M235 479C243 463 267 467 289 472C364 489 451 543 501 606L501 800L234 797C205 730 203 598 240 496C235 493 231 487 235 479Z"/>
<path fill="url(#fur)" d="M1018 479C1008 460 982 465 960 470C885 486 803 533 756 598L756 800L1019 796C1043 725 1042 596 1011 494C1017 491 1021 485 1018 479Z"/>
<path fill="url(#ear)" d="M234 797C215 752 215 693 222 651C229 606 244 557 261 542C274 531 284 533 296 547C326 581 356 630 374 684C353 664 329 655 293 649C299 672 308 686 323 694C289 719 257 759 234 797Z"/>
<path fill="url(#earShade)" d="M261 542C269 544 282 565 294 588C309 620 325 649 338 666C322 658 308 653 293 649C299 672 308 686 323 694C287 720 257 759 234 797C216 752 215 693 222 651C229 606 244 557 261 542Z"/>
<path fill="url(#ear)" d="M1019 796C1038 750 1036 688 1029 646C1021 600 1008 554 990 540C978 529 968 533 956 547C925 581 896 628 878 681C900 662 922 653 961 647C954 671 945 684 929 692C966 717 996 757 1019 796Z"/>
<path fill="#a6cb91" opacity=".64" d="M265 712C274 693 290 681 306 678C311 685 316 690 323 694C301 695 281 701 265 712Z"/>
<path fill="#a4c990" opacity=".64" d="M929 692C936 688 942 682 947 676C965 678 976 688 983 701C966 694 949 691 929 692Z"/>
<!-- Green fur tips show around the ivory face. -->
<path fill="url(#rim)" d="M111 896C117 926 132 948 153 959C132 984 118 1018 117 1048C139 1014 156 992 184 974L228 916Z"/>
<path fill="url(#rim)" d="M1145 916C1132 939 1113 953 1090 960C1113 989 1127 1020 1133 1053C1106 1019 1087 996 1057 977L1017 914Z"/>
<!-- One continuous face silhouette keeps the exported outline clean. -->
<path fill="url(#fur)" d="M118 1085C120 1037 141 989 174 953C142 941 121 922 111 896C156 891 193 871 221 839C244 813 264 789 287 772C268 778 251 785 234 797C255 759 287 719 323 694C308 686 299 672 293 649C329 655 353 664 374 684C394 654 443 624 501 606C544 579 591 558 637 551C627 567 614 580 599 592C656 566 729 580 797 614C827 632 855 656 878 681C900 662 922 653 961 647C954 671 945 684 929 692C966 717 996 757 1019 796C1038 833 1058 866 1083 887C1104 905 1126 913 1145 916C1129 935 1107 945 1079 948C1111 990 1129 1037 1133 1085Z"/>
<path fill="url(#furShade)" d="M668 633C692 632 711 639 720 654C730 670 735 687 740 703Z"/>
<path fill="url(#furShade)" d="M111 896C144 905 173 908 212 901L174 953C142 941 121 922 111 896Z"/>
<path fill="url(#furShade)" d="M163 882C192 861 209 840 225 812L244 794C258 784 271 777 287 772C246 827 212 868 163 882Z"/>
<path fill="url(#furShade)" d="M1037 887C1074 901 1107 914 1145 916C1129 935 1107 945 1079 948Z"/>
<path fill="url(#furShade)" d="M118 1085C121 1054 133 1023 151 997C146 1034 151 1063 172 1085Z"/>
<path fill="url(#furShade)" d="M1081 1085C1094 1069 1101 1049 1103 1028C1115 1045 1120 1063 1122 1085Z"/>
<ellipse fill="url(#eye)" cx="454" cy="922" rx="43.5" ry="66"/>
<ellipse fill="url(#eye)" cx="800.5" cy="922" rx="43.5" ry="66"/>
<path fill="url(#eye)" d="M591 971C591 960 610 955 626 955C642 955 661 960 661 971C661 987 642 1009 626 1009C610 1009 591 987 591 971Z"/>
<ellipse fill="url(#cheek)" cx="364.5" cy="1015.5" rx="56.5" ry="38"/>
<ellipse fill="url(#cheek)" cx="889.5" cy="1015.5" rx="56.5" ry="38"/>
<path fill="url(#whisker)" d="M204 980C225 972 259 974 278 981C283 983 283 988 278 988C251 986 228 988 208 994C200 996 196 983 204 980Z"/>
<path fill="url(#whisker)" d="M204 1036C224 1022 251 1016 274 1015C280 1015 281 1021 275 1023C251 1030 230 1040 212 1050C204 1055 194 1043 204 1036Z"/>
<g transform="translate(1254 0) scale(-1 1)">
<path fill="url(#whisker)" d="M204 980C225 972 259 974 278 981C283 983 283 988 278 988C251 986 228 988 208 994C200 996 196 983 204 980Z"/>
<path fill="url(#whisker)" d="M204 1036C224 1022 251 1016 274 1015C280 1015 281 1021 275 1023C251 1030 230 1040 212 1050C204 1055 194 1043 204 1036Z"/>
</g>
</g></g>
</svg>

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

+77
View File
@@ -0,0 +1,77 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024" role="img" aria-label="Felis">
<defs>
<linearGradient id="rim" x1="250" y1="460" x2="940" y2="1090" gradientUnits="userSpaceOnUse">
<stop stop-color="#91bd86"/>
<stop offset=".5" stop-color="#8bbd83"/>
<stop offset="1" stop-color="#74ae77"/>
</linearGradient>
<linearGradient id="ear" x1="220" y1="540" x2="1010" y2="800" gradientUnits="userSpaceOnUse">
<stop stop-color="#83b57e"/>
<stop offset=".48" stop-color="#8cbd83"/>
<stop offset="1" stop-color="#80b47b"/>
</linearGradient>
<linearGradient id="earShade" x1="220" y1="610" x2="365" y2="740" gradientUnits="userSpaceOnUse">
<stop stop-color="#71aa75" stop-opacity=".32"/>
<stop offset="1" stop-color="#a6cb91" stop-opacity="0"/>
</linearGradient>
<linearGradient id="furShade" x1="220" y1="570" x2="1010" y2="1085" gradientUnits="userSpaceOnUse">
<stop stop-color="#e6ecda"/>
<stop offset=".52" stop-color="#e8eddf"/>
<stop offset="1" stop-color="#e4ebd8"/>
</linearGradient>
<radialGradient id="fur" cx=".48" cy=".56" r=".75">
<stop stop-color="#fdfbf4"/>
<stop offset="1" stop-color="#fcfaf3"/>
</radialGradient>
<linearGradient id="eye" x1="411" y1="860" x2="843" y2="993" gradientUnits="userSpaceOnUse">
<stop stop-color="#65a26c"/>
<stop offset=".48" stop-color="#6ba770"/>
<stop offset="1" stop-color="#63a16b"/>
</linearGradient>
<radialGradient id="cheek" cx=".45" cy=".42" r=".7">
<stop stop-color="#ffd2d2"/>
<stop offset="1" stop-color="#ffcccc"/>
</radialGradient>
<linearGradient id="whisker" x1="201" y1="1015" x2="282" y2="1015" gradientUnits="userSpaceOnUse">
<stop stop-color="#92bf87"/>
<stop offset="1" stop-color="#62a16c"/>
</linearGradient>
</defs>
<rect width="1024" height="1024" rx="224" fill="#e9f1e3"/><g transform="translate(64 236.30769230769226) scale(0.8615384615384616) translate(-110 -445)"><g id="felis">
<!-- Ear rims sit behind the pale ear fur and the forehead. -->
<path fill="url(#rim)" d="M174 633C176 566 202 481 233 459C263 438 329 462 384 484C443 509 488 550 517 580C553 560 601 548 643 549L631 569C666 566 704 573 734 583C792 517 880 470 949 454C977 448 1008 447 1024 462C1057 490 1075 568 1078 632L1027 801L935 777L749 625L509 624L315 774L218 814Z"/>
<path fill="url(#rim)" d="M194 782C188 799 191 821 199 837C187 854 175 869 163 882L220 866L265 800Z"/>
<path fill="url(#rim)" d="M1020 800C1037 815 1050 806 1062 786C1064 809 1059 829 1051 843L1080 882L1034 861Z"/>
<path fill="url(#furShade)" d="M236 479C211 512 189 568 177 623C168 678 173 743 191 785C199 805 210 815 225 812L258 778L386 651L285 518Z"/>
<path fill="url(#furShade)" d="M1018 480C1049 520 1067 578 1078 632C1083 689 1076 749 1059 789C1050 809 1036 814 1022 802L974 752L884 647L968 522Z"/>
<path fill="url(#fur)" d="M235 479C243 463 267 467 289 472C364 489 451 543 501 606L501 800L234 797C205 730 203 598 240 496C235 493 231 487 235 479Z"/>
<path fill="url(#fur)" d="M1018 479C1008 460 982 465 960 470C885 486 803 533 756 598L756 800L1019 796C1043 725 1042 596 1011 494C1017 491 1021 485 1018 479Z"/>
<path fill="url(#ear)" d="M234 797C215 752 215 693 222 651C229 606 244 557 261 542C274 531 284 533 296 547C326 581 356 630 374 684C353 664 329 655 293 649C299 672 308 686 323 694C289 719 257 759 234 797Z"/>
<path fill="url(#earShade)" d="M261 542C269 544 282 565 294 588C309 620 325 649 338 666C322 658 308 653 293 649C299 672 308 686 323 694C287 720 257 759 234 797C216 752 215 693 222 651C229 606 244 557 261 542Z"/>
<path fill="url(#ear)" d="M1019 796C1038 750 1036 688 1029 646C1021 600 1008 554 990 540C978 529 968 533 956 547C925 581 896 628 878 681C900 662 922 653 961 647C954 671 945 684 929 692C966 717 996 757 1019 796Z"/>
<path fill="#a6cb91" opacity=".64" d="M265 712C274 693 290 681 306 678C311 685 316 690 323 694C301 695 281 701 265 712Z"/>
<path fill="#a4c990" opacity=".64" d="M929 692C936 688 942 682 947 676C965 678 976 688 983 701C966 694 949 691 929 692Z"/>
<!-- Green fur tips show around the ivory face. -->
<path fill="url(#rim)" d="M111 896C117 926 132 948 153 959C132 984 118 1018 117 1048C139 1014 156 992 184 974L228 916Z"/>
<path fill="url(#rim)" d="M1145 916C1132 939 1113 953 1090 960C1113 989 1127 1020 1133 1053C1106 1019 1087 996 1057 977L1017 914Z"/>
<!-- One continuous face silhouette keeps the exported outline clean. -->
<path fill="url(#fur)" d="M118 1085C120 1037 141 989 174 953C142 941 121 922 111 896C156 891 193 871 221 839C244 813 264 789 287 772C268 778 251 785 234 797C255 759 287 719 323 694C308 686 299 672 293 649C329 655 353 664 374 684C394 654 443 624 501 606C544 579 591 558 637 551C627 567 614 580 599 592C656 566 729 580 797 614C827 632 855 656 878 681C900 662 922 653 961 647C954 671 945 684 929 692C966 717 996 757 1019 796C1038 833 1058 866 1083 887C1104 905 1126 913 1145 916C1129 935 1107 945 1079 948C1111 990 1129 1037 1133 1085Z"/>
<path fill="url(#furShade)" d="M668 633C692 632 711 639 720 654C730 670 735 687 740 703Z"/>
<path fill="url(#furShade)" d="M111 896C144 905 173 908 212 901L174 953C142 941 121 922 111 896Z"/>
<path fill="url(#furShade)" d="M163 882C192 861 209 840 225 812L244 794C258 784 271 777 287 772C246 827 212 868 163 882Z"/>
<path fill="url(#furShade)" d="M1037 887C1074 901 1107 914 1145 916C1129 935 1107 945 1079 948Z"/>
<path fill="url(#furShade)" d="M118 1085C121 1054 133 1023 151 997C146 1034 151 1063 172 1085Z"/>
<path fill="url(#furShade)" d="M1081 1085C1094 1069 1101 1049 1103 1028C1115 1045 1120 1063 1122 1085Z"/>
<ellipse fill="url(#eye)" cx="454" cy="922" rx="43.5" ry="66"/>
<ellipse fill="url(#eye)" cx="800.5" cy="922" rx="43.5" ry="66"/>
<path fill="url(#eye)" d="M591 971C591 960 610 955 626 955C642 955 661 960 661 971C661 987 642 1009 626 1009C610 1009 591 987 591 971Z"/>
<ellipse fill="url(#cheek)" cx="364.5" cy="1015.5" rx="56.5" ry="38"/>
<ellipse fill="url(#cheek)" cx="889.5" cy="1015.5" rx="56.5" ry="38"/>
<path fill="url(#whisker)" d="M204 980C225 972 259 974 278 981C283 983 283 988 278 988C251 986 228 988 208 994C200 996 196 983 204 980Z"/>
<path fill="url(#whisker)" d="M204 1036C224 1022 251 1016 274 1015C280 1015 281 1021 275 1023C251 1030 230 1040 212 1050C204 1055 194 1043 204 1036Z"/>
<g transform="translate(1254 0) scale(-1 1)">
<path fill="url(#whisker)" d="M204 980C225 972 259 974 278 981C283 983 283 988 278 988C251 986 228 988 208 994C200 996 196 983 204 980Z"/>
<path fill="url(#whisker)" d="M204 1036C224 1022 251 1016 274 1015C280 1015 281 1021 275 1023C251 1030 230 1040 212 1050C204 1055 194 1043 204 1036Z"/>
</g>
</g></g>
</svg>

After

Width:  |  Height:  |  Size: 6.7 KiB

+77
View File
@@ -0,0 +1,77 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024" role="img" aria-label="Felis">
<defs>
<linearGradient id="rim" x1="250" y1="460" x2="940" y2="1090" gradientUnits="userSpaceOnUse">
<stop stop-color="#91bd86"/>
<stop offset=".5" stop-color="#8bbd83"/>
<stop offset="1" stop-color="#74ae77"/>
</linearGradient>
<linearGradient id="ear" x1="220" y1="540" x2="1010" y2="800" gradientUnits="userSpaceOnUse">
<stop stop-color="#83b57e"/>
<stop offset=".48" stop-color="#8cbd83"/>
<stop offset="1" stop-color="#80b47b"/>
</linearGradient>
<linearGradient id="earShade" x1="220" y1="610" x2="365" y2="740" gradientUnits="userSpaceOnUse">
<stop stop-color="#71aa75" stop-opacity=".32"/>
<stop offset="1" stop-color="#a6cb91" stop-opacity="0"/>
</linearGradient>
<linearGradient id="furShade" x1="220" y1="570" x2="1010" y2="1085" gradientUnits="userSpaceOnUse">
<stop stop-color="#e6ecda"/>
<stop offset=".52" stop-color="#e8eddf"/>
<stop offset="1" stop-color="#e4ebd8"/>
</linearGradient>
<radialGradient id="fur" cx=".48" cy=".56" r=".75">
<stop stop-color="#fdfbf4"/>
<stop offset="1" stop-color="#fcfaf3"/>
</radialGradient>
<linearGradient id="eye" x1="411" y1="860" x2="843" y2="993" gradientUnits="userSpaceOnUse">
<stop stop-color="#65a26c"/>
<stop offset=".48" stop-color="#6ba770"/>
<stop offset="1" stop-color="#63a16b"/>
</linearGradient>
<radialGradient id="cheek" cx=".45" cy=".42" r=".7">
<stop stop-color="#ffd2d2"/>
<stop offset="1" stop-color="#ffcccc"/>
</radialGradient>
<linearGradient id="whisker" x1="201" y1="1015" x2="282" y2="1015" gradientUnits="userSpaceOnUse">
<stop stop-color="#92bf87"/>
<stop offset="1" stop-color="#62a16c"/>
</linearGradient>
</defs>
<g transform="translate(64 236.30769230769226) scale(0.8615384615384616) translate(-110 -445)"><g id="felis">
<!-- Ear rims sit behind the pale ear fur and the forehead. -->
<path fill="url(#rim)" d="M174 633C176 566 202 481 233 459C263 438 329 462 384 484C443 509 488 550 517 580C553 560 601 548 643 549L631 569C666 566 704 573 734 583C792 517 880 470 949 454C977 448 1008 447 1024 462C1057 490 1075 568 1078 632L1027 801L935 777L749 625L509 624L315 774L218 814Z"/>
<path fill="url(#rim)" d="M194 782C188 799 191 821 199 837C187 854 175 869 163 882L220 866L265 800Z"/>
<path fill="url(#rim)" d="M1020 800C1037 815 1050 806 1062 786C1064 809 1059 829 1051 843L1080 882L1034 861Z"/>
<path fill="url(#furShade)" d="M236 479C211 512 189 568 177 623C168 678 173 743 191 785C199 805 210 815 225 812L258 778L386 651L285 518Z"/>
<path fill="url(#furShade)" d="M1018 480C1049 520 1067 578 1078 632C1083 689 1076 749 1059 789C1050 809 1036 814 1022 802L974 752L884 647L968 522Z"/>
<path fill="url(#fur)" d="M235 479C243 463 267 467 289 472C364 489 451 543 501 606L501 800L234 797C205 730 203 598 240 496C235 493 231 487 235 479Z"/>
<path fill="url(#fur)" d="M1018 479C1008 460 982 465 960 470C885 486 803 533 756 598L756 800L1019 796C1043 725 1042 596 1011 494C1017 491 1021 485 1018 479Z"/>
<path fill="url(#ear)" d="M234 797C215 752 215 693 222 651C229 606 244 557 261 542C274 531 284 533 296 547C326 581 356 630 374 684C353 664 329 655 293 649C299 672 308 686 323 694C289 719 257 759 234 797Z"/>
<path fill="url(#earShade)" d="M261 542C269 544 282 565 294 588C309 620 325 649 338 666C322 658 308 653 293 649C299 672 308 686 323 694C287 720 257 759 234 797C216 752 215 693 222 651C229 606 244 557 261 542Z"/>
<path fill="url(#ear)" d="M1019 796C1038 750 1036 688 1029 646C1021 600 1008 554 990 540C978 529 968 533 956 547C925 581 896 628 878 681C900 662 922 653 961 647C954 671 945 684 929 692C966 717 996 757 1019 796Z"/>
<path fill="#a6cb91" opacity=".64" d="M265 712C274 693 290 681 306 678C311 685 316 690 323 694C301 695 281 701 265 712Z"/>
<path fill="#a4c990" opacity=".64" d="M929 692C936 688 942 682 947 676C965 678 976 688 983 701C966 694 949 691 929 692Z"/>
<!-- Green fur tips show around the ivory face. -->
<path fill="url(#rim)" d="M111 896C117 926 132 948 153 959C132 984 118 1018 117 1048C139 1014 156 992 184 974L228 916Z"/>
<path fill="url(#rim)" d="M1145 916C1132 939 1113 953 1090 960C1113 989 1127 1020 1133 1053C1106 1019 1087 996 1057 977L1017 914Z"/>
<!-- One continuous face silhouette keeps the exported outline clean. -->
<path fill="url(#fur)" d="M118 1085C120 1037 141 989 174 953C142 941 121 922 111 896C156 891 193 871 221 839C244 813 264 789 287 772C268 778 251 785 234 797C255 759 287 719 323 694C308 686 299 672 293 649C329 655 353 664 374 684C394 654 443 624 501 606C544 579 591 558 637 551C627 567 614 580 599 592C656 566 729 580 797 614C827 632 855 656 878 681C900 662 922 653 961 647C954 671 945 684 929 692C966 717 996 757 1019 796C1038 833 1058 866 1083 887C1104 905 1126 913 1145 916C1129 935 1107 945 1079 948C1111 990 1129 1037 1133 1085Z"/>
<path fill="url(#furShade)" d="M668 633C692 632 711 639 720 654C730 670 735 687 740 703Z"/>
<path fill="url(#furShade)" d="M111 896C144 905 173 908 212 901L174 953C142 941 121 922 111 896Z"/>
<path fill="url(#furShade)" d="M163 882C192 861 209 840 225 812L244 794C258 784 271 777 287 772C246 827 212 868 163 882Z"/>
<path fill="url(#furShade)" d="M1037 887C1074 901 1107 914 1145 916C1129 935 1107 945 1079 948Z"/>
<path fill="url(#furShade)" d="M118 1085C121 1054 133 1023 151 997C146 1034 151 1063 172 1085Z"/>
<path fill="url(#furShade)" d="M1081 1085C1094 1069 1101 1049 1103 1028C1115 1045 1120 1063 1122 1085Z"/>
<ellipse fill="url(#eye)" cx="454" cy="922" rx="43.5" ry="66"/>
<ellipse fill="url(#eye)" cx="800.5" cy="922" rx="43.5" ry="66"/>
<path fill="url(#eye)" d="M591 971C591 960 610 955 626 955C642 955 661 960 661 971C661 987 642 1009 626 1009C610 1009 591 987 591 971Z"/>
<ellipse fill="url(#cheek)" cx="364.5" cy="1015.5" rx="56.5" ry="38"/>
<ellipse fill="url(#cheek)" cx="889.5" cy="1015.5" rx="56.5" ry="38"/>
<path fill="url(#whisker)" d="M204 980C225 972 259 974 278 981C283 983 283 988 278 988C251 986 228 988 208 994C200 996 196 983 204 980Z"/>
<path fill="url(#whisker)" d="M204 1036C224 1022 251 1016 274 1015C280 1015 281 1021 275 1023C251 1030 230 1040 212 1050C204 1055 194 1043 204 1036Z"/>
<g transform="translate(1254 0) scale(-1 1)">
<path fill="url(#whisker)" d="M204 980C225 972 259 974 278 981C283 983 283 988 278 988C251 986 228 988 208 994C200 996 196 983 204 980Z"/>
<path fill="url(#whisker)" d="M204 1036C224 1022 251 1016 274 1015C280 1015 281 1021 275 1023C251 1030 230 1040 212 1050C204 1055 194 1043 204 1036Z"/>
</g>
</g></g>
</svg>

After

Width:  |  Height:  |  Size: 6.6 KiB

+4
View File
@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024" role="img" aria-label="Felis">
<defs><mask id="shape" maskUnits="userSpaceOnUse" x="110" y="445" width="1040" height="640"><path fill="#fff" d="M174 633C176 566 202 481 233 459C263 438 329 462 384 484C443 509 488 550 517 580C553 560 601 548 643 549L631 569C666 566 704 573 734 583C792 517 880 470 949 454C977 448 1008 447 1024 462C1057 490 1075 568 1078 632L1027 801L935 777L749 625L509 624L315 774L218 814Z"/><path fill="#fff" d="M194 782C188 799 191 821 199 837C187 854 175 869 163 882L220 866L265 800Z"/><path fill="#fff" d="M1020 800C1037 815 1050 806 1062 786C1064 809 1059 829 1051 843L1080 882L1034 861Z"/><path fill="#fff" d="M236 479C211 512 189 568 177 623C168 678 173 743 191 785C199 805 210 815 225 812L258 778L386 651L285 518Z"/><path fill="#fff" d="M1018 480C1049 520 1067 578 1078 632C1083 689 1076 749 1059 789C1050 809 1036 814 1022 802L974 752L884 647L968 522Z"/><path fill="#fff" d="M235 479C243 463 267 467 289 472C364 489 451 543 501 606L501 800L234 797C205 730 203 598 240 496C235 493 231 487 235 479Z"/><path fill="#fff" d="M1018 479C1008 460 982 465 960 470C885 486 803 533 756 598L756 800L1019 796C1043 725 1042 596 1011 494C1017 491 1021 485 1018 479Z"/><path fill="#fff" d="M234 797C215 752 215 693 222 651C229 606 244 557 261 542C274 531 284 533 296 547C326 581 356 630 374 684C353 664 329 655 293 649C299 672 308 686 323 694C289 719 257 759 234 797Z"/><path fill="#fff" d="M261 542C269 544 282 565 294 588C309 620 325 649 338 666C322 658 308 653 293 649C299 672 308 686 323 694C287 720 257 759 234 797C216 752 215 693 222 651C229 606 244 557 261 542Z"/><path fill="#fff" d="M1019 796C1038 750 1036 688 1029 646C1021 600 1008 554 990 540C978 529 968 533 956 547C925 581 896 628 878 681C900 662 922 653 961 647C954 671 945 684 929 692C966 717 996 757 1019 796Z"/><path fill="#fff" d="M265 712C274 693 290 681 306 678C311 685 316 690 323 694C301 695 281 701 265 712Z"/><path fill="#fff" d="M929 692C936 688 942 682 947 676C965 678 976 688 983 701C966 694 949 691 929 692Z"/><path fill="#fff" d="M111 896C117 926 132 948 153 959C132 984 118 1018 117 1048C139 1014 156 992 184 974L228 916Z"/><path fill="#fff" d="M1145 916C1132 939 1113 953 1090 960C1113 989 1127 1020 1133 1053C1106 1019 1087 996 1057 977L1017 914Z"/><path fill="#fff" d="M118 1085C120 1037 141 989 174 953C142 941 121 922 111 896C156 891 193 871 221 839C244 813 264 789 287 772C268 778 251 785 234 797C255 759 287 719 323 694C308 686 299 672 293 649C329 655 353 664 374 684C394 654 443 624 501 606C544 579 591 558 637 551C627 567 614 580 599 592C656 566 729 580 797 614C827 632 855 656 878 681C900 662 922 653 961 647C954 671 945 684 929 692C966 717 996 757 1019 796C1038 833 1058 866 1083 887C1104 905 1126 913 1145 916C1129 935 1107 945 1079 948C1111 990 1129 1037 1133 1085Z"/><path fill="#fff" d="M668 633C692 632 711 639 720 654C730 670 735 687 740 703Z"/><path fill="#fff" d="M111 896C144 905 173 908 212 901L174 953C142 941 121 922 111 896Z"/><path fill="#fff" d="M163 882C192 861 209 840 225 812L244 794C258 784 271 777 287 772C246 827 212 868 163 882Z"/><path fill="#fff" d="M1037 887C1074 901 1107 914 1145 916C1129 935 1107 945 1079 948Z"/><path fill="#fff" d="M118 1085C121 1054 133 1023 151 997C146 1034 151 1063 172 1085Z"/><path fill="#fff" d="M1081 1085C1094 1069 1101 1049 1103 1028C1115 1045 1120 1063 1122 1085Z"/><path fill="#fff" d="M591 971C591 960 610 955 626 955C642 955 661 960 661 971C661 987 642 1009 626 1009C610 1009 591 987 591 971Z"/><path fill="#fff" d="M204 980C225 972 259 974 278 981C283 983 283 988 278 988C251 986 228 988 208 994C200 996 196 983 204 980Z"/><path fill="#fff" d="M204 1036C224 1022 251 1016 274 1015C280 1015 281 1021 275 1023C251 1030 230 1040 212 1050C204 1055 194 1043 204 1036Z"/><path fill="#fff" d="M204 980C225 972 259 974 278 981C283 983 283 988 278 988C251 986 228 988 208 994C200 996 196 983 204 980Z"/><path fill="#fff" d="M204 1036C224 1022 251 1016 274 1015C280 1015 281 1021 275 1023C251 1030 230 1040 212 1050C204 1055 194 1043 204 1036Z"/><ellipse fill="#000" cx="454" cy="922" rx="43.5" ry="66"/><ellipse fill="#000" cx="800.5" cy="922" rx="43.5" ry="66"/><path fill="#000" d="M591 971C591 960 610 955 626 955C642 955 661 960 661 971C661 987 642 1009 626 1009C610 1009 591 987 591 971Z"/></mask></defs>
<g transform="translate(64 236.30769230769226) scale(0.8615384615384616) translate(-110 -445)"><rect x="110" y="445" width="1040" height="640" fill="#000" mask="url(#shape)"/></g>
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

+77
View File
@@ -0,0 +1,77 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024" role="img" aria-label="Felis">
<defs>
<linearGradient id="rim" x1="250" y1="460" x2="940" y2="1090" gradientUnits="userSpaceOnUse">
<stop stop-color="#91bd86"/>
<stop offset=".5" stop-color="#8bbd83"/>
<stop offset="1" stop-color="#74ae77"/>
</linearGradient>
<linearGradient id="ear" x1="220" y1="540" x2="1010" y2="800" gradientUnits="userSpaceOnUse">
<stop stop-color="#83b57e"/>
<stop offset=".48" stop-color="#8cbd83"/>
<stop offset="1" stop-color="#80b47b"/>
</linearGradient>
<linearGradient id="earShade" x1="220" y1="610" x2="365" y2="740" gradientUnits="userSpaceOnUse">
<stop stop-color="#71aa75" stop-opacity=".32"/>
<stop offset="1" stop-color="#a6cb91" stop-opacity="0"/>
</linearGradient>
<linearGradient id="furShade" x1="220" y1="570" x2="1010" y2="1085" gradientUnits="userSpaceOnUse">
<stop stop-color="#e6ecda"/>
<stop offset=".52" stop-color="#e8eddf"/>
<stop offset="1" stop-color="#e4ebd8"/>
</linearGradient>
<radialGradient id="fur" cx=".48" cy=".56" r=".75">
<stop stop-color="#fdfbf4"/>
<stop offset="1" stop-color="#fcfaf3"/>
</radialGradient>
<linearGradient id="eye" x1="411" y1="860" x2="843" y2="993" gradientUnits="userSpaceOnUse">
<stop stop-color="#65a26c"/>
<stop offset=".48" stop-color="#6ba770"/>
<stop offset="1" stop-color="#63a16b"/>
</linearGradient>
<radialGradient id="cheek" cx=".45" cy=".42" r=".7">
<stop stop-color="#ffd2d2"/>
<stop offset="1" stop-color="#ffcccc"/>
</radialGradient>
<linearGradient id="whisker" x1="201" y1="1015" x2="282" y2="1015" gradientUnits="userSpaceOnUse">
<stop stop-color="#92bf87"/>
<stop offset="1" stop-color="#62a16c"/>
</linearGradient>
</defs>
<rect width="1024" height="1024" fill="#e9f1e3"/><g transform="translate(172 302.7692307692308) scale(0.6538461538461539) translate(-110 -445)"><g id="felis">
<!-- Ear rims sit behind the pale ear fur and the forehead. -->
<path fill="url(#rim)" d="M174 633C176 566 202 481 233 459C263 438 329 462 384 484C443 509 488 550 517 580C553 560 601 548 643 549L631 569C666 566 704 573 734 583C792 517 880 470 949 454C977 448 1008 447 1024 462C1057 490 1075 568 1078 632L1027 801L935 777L749 625L509 624L315 774L218 814Z"/>
<path fill="url(#rim)" d="M194 782C188 799 191 821 199 837C187 854 175 869 163 882L220 866L265 800Z"/>
<path fill="url(#rim)" d="M1020 800C1037 815 1050 806 1062 786C1064 809 1059 829 1051 843L1080 882L1034 861Z"/>
<path fill="url(#furShade)" d="M236 479C211 512 189 568 177 623C168 678 173 743 191 785C199 805 210 815 225 812L258 778L386 651L285 518Z"/>
<path fill="url(#furShade)" d="M1018 480C1049 520 1067 578 1078 632C1083 689 1076 749 1059 789C1050 809 1036 814 1022 802L974 752L884 647L968 522Z"/>
<path fill="url(#fur)" d="M235 479C243 463 267 467 289 472C364 489 451 543 501 606L501 800L234 797C205 730 203 598 240 496C235 493 231 487 235 479Z"/>
<path fill="url(#fur)" d="M1018 479C1008 460 982 465 960 470C885 486 803 533 756 598L756 800L1019 796C1043 725 1042 596 1011 494C1017 491 1021 485 1018 479Z"/>
<path fill="url(#ear)" d="M234 797C215 752 215 693 222 651C229 606 244 557 261 542C274 531 284 533 296 547C326 581 356 630 374 684C353 664 329 655 293 649C299 672 308 686 323 694C289 719 257 759 234 797Z"/>
<path fill="url(#earShade)" d="M261 542C269 544 282 565 294 588C309 620 325 649 338 666C322 658 308 653 293 649C299 672 308 686 323 694C287 720 257 759 234 797C216 752 215 693 222 651C229 606 244 557 261 542Z"/>
<path fill="url(#ear)" d="M1019 796C1038 750 1036 688 1029 646C1021 600 1008 554 990 540C978 529 968 533 956 547C925 581 896 628 878 681C900 662 922 653 961 647C954 671 945 684 929 692C966 717 996 757 1019 796Z"/>
<path fill="#a6cb91" opacity=".64" d="M265 712C274 693 290 681 306 678C311 685 316 690 323 694C301 695 281 701 265 712Z"/>
<path fill="#a4c990" opacity=".64" d="M929 692C936 688 942 682 947 676C965 678 976 688 983 701C966 694 949 691 929 692Z"/>
<!-- Green fur tips show around the ivory face. -->
<path fill="url(#rim)" d="M111 896C117 926 132 948 153 959C132 984 118 1018 117 1048C139 1014 156 992 184 974L228 916Z"/>
<path fill="url(#rim)" d="M1145 916C1132 939 1113 953 1090 960C1113 989 1127 1020 1133 1053C1106 1019 1087 996 1057 977L1017 914Z"/>
<!-- One continuous face silhouette keeps the exported outline clean. -->
<path fill="url(#fur)" d="M118 1085C120 1037 141 989 174 953C142 941 121 922 111 896C156 891 193 871 221 839C244 813 264 789 287 772C268 778 251 785 234 797C255 759 287 719 323 694C308 686 299 672 293 649C329 655 353 664 374 684C394 654 443 624 501 606C544 579 591 558 637 551C627 567 614 580 599 592C656 566 729 580 797 614C827 632 855 656 878 681C900 662 922 653 961 647C954 671 945 684 929 692C966 717 996 757 1019 796C1038 833 1058 866 1083 887C1104 905 1126 913 1145 916C1129 935 1107 945 1079 948C1111 990 1129 1037 1133 1085Z"/>
<path fill="url(#furShade)" d="M668 633C692 632 711 639 720 654C730 670 735 687 740 703Z"/>
<path fill="url(#furShade)" d="M111 896C144 905 173 908 212 901L174 953C142 941 121 922 111 896Z"/>
<path fill="url(#furShade)" d="M163 882C192 861 209 840 225 812L244 794C258 784 271 777 287 772C246 827 212 868 163 882Z"/>
<path fill="url(#furShade)" d="M1037 887C1074 901 1107 914 1145 916C1129 935 1107 945 1079 948Z"/>
<path fill="url(#furShade)" d="M118 1085C121 1054 133 1023 151 997C146 1034 151 1063 172 1085Z"/>
<path fill="url(#furShade)" d="M1081 1085C1094 1069 1101 1049 1103 1028C1115 1045 1120 1063 1122 1085Z"/>
<ellipse fill="url(#eye)" cx="454" cy="922" rx="43.5" ry="66"/>
<ellipse fill="url(#eye)" cx="800.5" cy="922" rx="43.5" ry="66"/>
<path fill="url(#eye)" d="M591 971C591 960 610 955 626 955C642 955 661 960 661 971C661 987 642 1009 626 1009C610 1009 591 987 591 971Z"/>
<ellipse fill="url(#cheek)" cx="364.5" cy="1015.5" rx="56.5" ry="38"/>
<ellipse fill="url(#cheek)" cx="889.5" cy="1015.5" rx="56.5" ry="38"/>
<path fill="url(#whisker)" d="M204 980C225 972 259 974 278 981C283 983 283 988 278 988C251 986 228 988 208 994C200 996 196 983 204 980Z"/>
<path fill="url(#whisker)" d="M204 1036C224 1022 251 1016 274 1015C280 1015 281 1021 275 1023C251 1030 230 1040 212 1050C204 1055 194 1043 204 1036Z"/>
<g transform="translate(1254 0) scale(-1 1)">
<path fill="url(#whisker)" d="M204 980C225 972 259 974 278 981C283 983 283 988 278 988C251 986 228 988 208 994C200 996 196 983 204 980Z"/>
<path fill="url(#whisker)" d="M204 1036C224 1022 251 1016 274 1015C280 1015 281 1021 275 1023C251 1030 230 1040 212 1050C204 1055 194 1043 204 1036Z"/>
</g>
</g></g>
</svg>

After

Width:  |  Height:  |  Size: 6.7 KiB

+4
View File
@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1040" height="640" viewBox="110 445 1040 640" role="img" aria-label="Felis">
<defs><mask id="shape" maskUnits="userSpaceOnUse" x="110" y="445" width="1040" height="640"><path fill="#fff" d="M174 633C176 566 202 481 233 459C263 438 329 462 384 484C443 509 488 550 517 580C553 560 601 548 643 549L631 569C666 566 704 573 734 583C792 517 880 470 949 454C977 448 1008 447 1024 462C1057 490 1075 568 1078 632L1027 801L935 777L749 625L509 624L315 774L218 814Z"/><path fill="#fff" d="M194 782C188 799 191 821 199 837C187 854 175 869 163 882L220 866L265 800Z"/><path fill="#fff" d="M1020 800C1037 815 1050 806 1062 786C1064 809 1059 829 1051 843L1080 882L1034 861Z"/><path fill="#fff" d="M236 479C211 512 189 568 177 623C168 678 173 743 191 785C199 805 210 815 225 812L258 778L386 651L285 518Z"/><path fill="#fff" d="M1018 480C1049 520 1067 578 1078 632C1083 689 1076 749 1059 789C1050 809 1036 814 1022 802L974 752L884 647L968 522Z"/><path fill="#fff" d="M235 479C243 463 267 467 289 472C364 489 451 543 501 606L501 800L234 797C205 730 203 598 240 496C235 493 231 487 235 479Z"/><path fill="#fff" d="M1018 479C1008 460 982 465 960 470C885 486 803 533 756 598L756 800L1019 796C1043 725 1042 596 1011 494C1017 491 1021 485 1018 479Z"/><path fill="#fff" d="M234 797C215 752 215 693 222 651C229 606 244 557 261 542C274 531 284 533 296 547C326 581 356 630 374 684C353 664 329 655 293 649C299 672 308 686 323 694C289 719 257 759 234 797Z"/><path fill="#fff" d="M261 542C269 544 282 565 294 588C309 620 325 649 338 666C322 658 308 653 293 649C299 672 308 686 323 694C287 720 257 759 234 797C216 752 215 693 222 651C229 606 244 557 261 542Z"/><path fill="#fff" d="M1019 796C1038 750 1036 688 1029 646C1021 600 1008 554 990 540C978 529 968 533 956 547C925 581 896 628 878 681C900 662 922 653 961 647C954 671 945 684 929 692C966 717 996 757 1019 796Z"/><path fill="#fff" d="M265 712C274 693 290 681 306 678C311 685 316 690 323 694C301 695 281 701 265 712Z"/><path fill="#fff" d="M929 692C936 688 942 682 947 676C965 678 976 688 983 701C966 694 949 691 929 692Z"/><path fill="#fff" d="M111 896C117 926 132 948 153 959C132 984 118 1018 117 1048C139 1014 156 992 184 974L228 916Z"/><path fill="#fff" d="M1145 916C1132 939 1113 953 1090 960C1113 989 1127 1020 1133 1053C1106 1019 1087 996 1057 977L1017 914Z"/><path fill="#fff" d="M118 1085C120 1037 141 989 174 953C142 941 121 922 111 896C156 891 193 871 221 839C244 813 264 789 287 772C268 778 251 785 234 797C255 759 287 719 323 694C308 686 299 672 293 649C329 655 353 664 374 684C394 654 443 624 501 606C544 579 591 558 637 551C627 567 614 580 599 592C656 566 729 580 797 614C827 632 855 656 878 681C900 662 922 653 961 647C954 671 945 684 929 692C966 717 996 757 1019 796C1038 833 1058 866 1083 887C1104 905 1126 913 1145 916C1129 935 1107 945 1079 948C1111 990 1129 1037 1133 1085Z"/><path fill="#fff" d="M668 633C692 632 711 639 720 654C730 670 735 687 740 703Z"/><path fill="#fff" d="M111 896C144 905 173 908 212 901L174 953C142 941 121 922 111 896Z"/><path fill="#fff" d="M163 882C192 861 209 840 225 812L244 794C258 784 271 777 287 772C246 827 212 868 163 882Z"/><path fill="#fff" d="M1037 887C1074 901 1107 914 1145 916C1129 935 1107 945 1079 948Z"/><path fill="#fff" d="M118 1085C121 1054 133 1023 151 997C146 1034 151 1063 172 1085Z"/><path fill="#fff" d="M1081 1085C1094 1069 1101 1049 1103 1028C1115 1045 1120 1063 1122 1085Z"/><path fill="#fff" d="M591 971C591 960 610 955 626 955C642 955 661 960 661 971C661 987 642 1009 626 1009C610 1009 591 987 591 971Z"/><path fill="#fff" d="M204 980C225 972 259 974 278 981C283 983 283 988 278 988C251 986 228 988 208 994C200 996 196 983 204 980Z"/><path fill="#fff" d="M204 1036C224 1022 251 1016 274 1015C280 1015 281 1021 275 1023C251 1030 230 1040 212 1050C204 1055 194 1043 204 1036Z"/><path fill="#fff" d="M204 980C225 972 259 974 278 981C283 983 283 988 278 988C251 986 228 988 208 994C200 996 196 983 204 980Z"/><path fill="#fff" d="M204 1036C224 1022 251 1016 274 1015C280 1015 281 1021 275 1023C251 1030 230 1040 212 1050C204 1055 194 1043 204 1036Z"/><ellipse fill="#000" cx="454" cy="922" rx="43.5" ry="66"/><ellipse fill="#000" cx="800.5" cy="922" rx="43.5" ry="66"/><path fill="#000" d="M591 971C591 960 610 955 626 955C642 955 661 960 661 971C661 987 642 1009 626 1009C610 1009 591 987 591 971Z"/></mask></defs>
<rect x="110" y="445" width="1040" height="640" fill="#000" mask="url(#shape)"/>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

+77
View File
@@ -0,0 +1,77 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1254" height="1254" viewBox="0 0 1254 1254" role="img" aria-label="Felis">
<defs>
<linearGradient id="rim" x1="250" y1="460" x2="940" y2="1090" gradientUnits="userSpaceOnUse">
<stop stop-color="#91bd86"/>
<stop offset=".5" stop-color="#8bbd83"/>
<stop offset="1" stop-color="#74ae77"/>
</linearGradient>
<linearGradient id="ear" x1="220" y1="540" x2="1010" y2="800" gradientUnits="userSpaceOnUse">
<stop stop-color="#83b57e"/>
<stop offset=".48" stop-color="#8cbd83"/>
<stop offset="1" stop-color="#80b47b"/>
</linearGradient>
<linearGradient id="earShade" x1="220" y1="610" x2="365" y2="740" gradientUnits="userSpaceOnUse">
<stop stop-color="#71aa75" stop-opacity=".32"/>
<stop offset="1" stop-color="#a6cb91" stop-opacity="0"/>
</linearGradient>
<linearGradient id="furShade" x1="220" y1="570" x2="1010" y2="1085" gradientUnits="userSpaceOnUse">
<stop stop-color="#e6ecda"/>
<stop offset=".52" stop-color="#e8eddf"/>
<stop offset="1" stop-color="#e4ebd8"/>
</linearGradient>
<radialGradient id="fur" cx=".48" cy=".56" r=".75">
<stop stop-color="#fdfbf4"/>
<stop offset="1" stop-color="#fcfaf3"/>
</radialGradient>
<linearGradient id="eye" x1="411" y1="860" x2="843" y2="993" gradientUnits="userSpaceOnUse">
<stop stop-color="#65a26c"/>
<stop offset=".48" stop-color="#6ba770"/>
<stop offset="1" stop-color="#63a16b"/>
</linearGradient>
<radialGradient id="cheek" cx=".45" cy=".42" r=".7">
<stop stop-color="#ffd2d2"/>
<stop offset="1" stop-color="#ffcccc"/>
</radialGradient>
<linearGradient id="whisker" x1="201" y1="1015" x2="282" y2="1015" gradientUnits="userSpaceOnUse">
<stop stop-color="#92bf87"/>
<stop offset="1" stop-color="#62a16c"/>
</linearGradient>
</defs>
<rect width="1254" height="1254" fill="#fff"/><g id="felis">
<!-- Ear rims sit behind the pale ear fur and the forehead. -->
<path fill="url(#rim)" d="M174 633C176 566 202 481 233 459C263 438 329 462 384 484C443 509 488 550 517 580C553 560 601 548 643 549L631 569C666 566 704 573 734 583C792 517 880 470 949 454C977 448 1008 447 1024 462C1057 490 1075 568 1078 632L1027 801L935 777L749 625L509 624L315 774L218 814Z"/>
<path fill="url(#rim)" d="M194 782C188 799 191 821 199 837C187 854 175 869 163 882L220 866L265 800Z"/>
<path fill="url(#rim)" d="M1020 800C1037 815 1050 806 1062 786C1064 809 1059 829 1051 843L1080 882L1034 861Z"/>
<path fill="url(#furShade)" d="M236 479C211 512 189 568 177 623C168 678 173 743 191 785C199 805 210 815 225 812L258 778L386 651L285 518Z"/>
<path fill="url(#furShade)" d="M1018 480C1049 520 1067 578 1078 632C1083 689 1076 749 1059 789C1050 809 1036 814 1022 802L974 752L884 647L968 522Z"/>
<path fill="url(#fur)" d="M235 479C243 463 267 467 289 472C364 489 451 543 501 606L501 800L234 797C205 730 203 598 240 496C235 493 231 487 235 479Z"/>
<path fill="url(#fur)" d="M1018 479C1008 460 982 465 960 470C885 486 803 533 756 598L756 800L1019 796C1043 725 1042 596 1011 494C1017 491 1021 485 1018 479Z"/>
<path fill="url(#ear)" d="M234 797C215 752 215 693 222 651C229 606 244 557 261 542C274 531 284 533 296 547C326 581 356 630 374 684C353 664 329 655 293 649C299 672 308 686 323 694C289 719 257 759 234 797Z"/>
<path fill="url(#earShade)" d="M261 542C269 544 282 565 294 588C309 620 325 649 338 666C322 658 308 653 293 649C299 672 308 686 323 694C287 720 257 759 234 797C216 752 215 693 222 651C229 606 244 557 261 542Z"/>
<path fill="url(#ear)" d="M1019 796C1038 750 1036 688 1029 646C1021 600 1008 554 990 540C978 529 968 533 956 547C925 581 896 628 878 681C900 662 922 653 961 647C954 671 945 684 929 692C966 717 996 757 1019 796Z"/>
<path fill="#a6cb91" opacity=".64" d="M265 712C274 693 290 681 306 678C311 685 316 690 323 694C301 695 281 701 265 712Z"/>
<path fill="#a4c990" opacity=".64" d="M929 692C936 688 942 682 947 676C965 678 976 688 983 701C966 694 949 691 929 692Z"/>
<!-- Green fur tips show around the ivory face. -->
<path fill="url(#rim)" d="M111 896C117 926 132 948 153 959C132 984 118 1018 117 1048C139 1014 156 992 184 974L228 916Z"/>
<path fill="url(#rim)" d="M1145 916C1132 939 1113 953 1090 960C1113 989 1127 1020 1133 1053C1106 1019 1087 996 1057 977L1017 914Z"/>
<!-- One continuous face silhouette keeps the exported outline clean. -->
<path fill="url(#fur)" d="M118 1085C120 1037 141 989 174 953C142 941 121 922 111 896C156 891 193 871 221 839C244 813 264 789 287 772C268 778 251 785 234 797C255 759 287 719 323 694C308 686 299 672 293 649C329 655 353 664 374 684C394 654 443 624 501 606C544 579 591 558 637 551C627 567 614 580 599 592C656 566 729 580 797 614C827 632 855 656 878 681C900 662 922 653 961 647C954 671 945 684 929 692C966 717 996 757 1019 796C1038 833 1058 866 1083 887C1104 905 1126 913 1145 916C1129 935 1107 945 1079 948C1111 990 1129 1037 1133 1085Z"/>
<path fill="url(#furShade)" d="M668 633C692 632 711 639 720 654C730 670 735 687 740 703Z"/>
<path fill="url(#furShade)" d="M111 896C144 905 173 908 212 901L174 953C142 941 121 922 111 896Z"/>
<path fill="url(#furShade)" d="M163 882C192 861 209 840 225 812L244 794C258 784 271 777 287 772C246 827 212 868 163 882Z"/>
<path fill="url(#furShade)" d="M1037 887C1074 901 1107 914 1145 916C1129 935 1107 945 1079 948Z"/>
<path fill="url(#furShade)" d="M118 1085C121 1054 133 1023 151 997C146 1034 151 1063 172 1085Z"/>
<path fill="url(#furShade)" d="M1081 1085C1094 1069 1101 1049 1103 1028C1115 1045 1120 1063 1122 1085Z"/>
<ellipse fill="url(#eye)" cx="454" cy="922" rx="43.5" ry="66"/>
<ellipse fill="url(#eye)" cx="800.5" cy="922" rx="43.5" ry="66"/>
<path fill="url(#eye)" d="M591 971C591 960 610 955 626 955C642 955 661 960 661 971C661 987 642 1009 626 1009C610 1009 591 987 591 971Z"/>
<ellipse fill="url(#cheek)" cx="364.5" cy="1015.5" rx="56.5" ry="38"/>
<ellipse fill="url(#cheek)" cx="889.5" cy="1015.5" rx="56.5" ry="38"/>
<path fill="url(#whisker)" d="M204 980C225 972 259 974 278 981C283 983 283 988 278 988C251 986 228 988 208 994C200 996 196 983 204 980Z"/>
<path fill="url(#whisker)" d="M204 1036C224 1022 251 1016 274 1015C280 1015 281 1021 275 1023C251 1030 230 1040 212 1050C204 1055 194 1043 204 1036Z"/>
<g transform="translate(1254 0) scale(-1 1)">
<path fill="url(#whisker)" d="M204 980C225 972 259 974 278 981C283 983 283 988 278 988C251 986 228 988 208 994C200 996 196 983 204 980Z"/>
<path fill="url(#whisker)" d="M204 1036C224 1022 251 1016 274 1015C280 1015 281 1021 275 1023C251 1030 230 1040 212 1050C204 1055 194 1043 204 1036Z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 631 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 772 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

+8
View File
@@ -3,6 +3,14 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#65a26c" />
<link rel="icon" href="/favicon.ico" sizes="any" />
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<link rel="icon" href="/favicon-32x32.png" type="image/png" sizes="32x32" />
<link rel="icon" href="/favicon-16x16.png" type="image/png" sizes="16x16" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180" />
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#65a26c" />
<link rel="manifest" href="/site.webmanifest" />
<title>Felis · Console</title>
<script>
try {
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

+77
View File
@@ -0,0 +1,77 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024" role="img" aria-label="Felis">
<defs>
<linearGradient id="rim" x1="250" y1="460" x2="940" y2="1090" gradientUnits="userSpaceOnUse">
<stop stop-color="#91bd86"/>
<stop offset=".5" stop-color="#8bbd83"/>
<stop offset="1" stop-color="#74ae77"/>
</linearGradient>
<linearGradient id="ear" x1="220" y1="540" x2="1010" y2="800" gradientUnits="userSpaceOnUse">
<stop stop-color="#83b57e"/>
<stop offset=".48" stop-color="#8cbd83"/>
<stop offset="1" stop-color="#80b47b"/>
</linearGradient>
<linearGradient id="earShade" x1="220" y1="610" x2="365" y2="740" gradientUnits="userSpaceOnUse">
<stop stop-color="#71aa75" stop-opacity=".32"/>
<stop offset="1" stop-color="#a6cb91" stop-opacity="0"/>
</linearGradient>
<linearGradient id="furShade" x1="220" y1="570" x2="1010" y2="1085" gradientUnits="userSpaceOnUse">
<stop stop-color="#e6ecda"/>
<stop offset=".52" stop-color="#e8eddf"/>
<stop offset="1" stop-color="#e4ebd8"/>
</linearGradient>
<radialGradient id="fur" cx=".48" cy=".56" r=".75">
<stop stop-color="#fdfbf4"/>
<stop offset="1" stop-color="#fcfaf3"/>
</radialGradient>
<linearGradient id="eye" x1="411" y1="860" x2="843" y2="993" gradientUnits="userSpaceOnUse">
<stop stop-color="#65a26c"/>
<stop offset=".48" stop-color="#6ba770"/>
<stop offset="1" stop-color="#63a16b"/>
</linearGradient>
<radialGradient id="cheek" cx=".45" cy=".42" r=".7">
<stop stop-color="#ffd2d2"/>
<stop offset="1" stop-color="#ffcccc"/>
</radialGradient>
<linearGradient id="whisker" x1="201" y1="1015" x2="282" y2="1015" gradientUnits="userSpaceOnUse">
<stop stop-color="#92bf87"/>
<stop offset="1" stop-color="#62a16c"/>
</linearGradient>
</defs>
<g transform="translate(64 236.30769230769226) scale(0.8615384615384616) translate(-110 -445)"><g id="felis">
<!-- Ear rims sit behind the pale ear fur and the forehead. -->
<path fill="url(#rim)" d="M174 633C176 566 202 481 233 459C263 438 329 462 384 484C443 509 488 550 517 580C553 560 601 548 643 549L631 569C666 566 704 573 734 583C792 517 880 470 949 454C977 448 1008 447 1024 462C1057 490 1075 568 1078 632L1027 801L935 777L749 625L509 624L315 774L218 814Z"/>
<path fill="url(#rim)" d="M194 782C188 799 191 821 199 837C187 854 175 869 163 882L220 866L265 800Z"/>
<path fill="url(#rim)" d="M1020 800C1037 815 1050 806 1062 786C1064 809 1059 829 1051 843L1080 882L1034 861Z"/>
<path fill="url(#furShade)" d="M236 479C211 512 189 568 177 623C168 678 173 743 191 785C199 805 210 815 225 812L258 778L386 651L285 518Z"/>
<path fill="url(#furShade)" d="M1018 480C1049 520 1067 578 1078 632C1083 689 1076 749 1059 789C1050 809 1036 814 1022 802L974 752L884 647L968 522Z"/>
<path fill="url(#fur)" d="M235 479C243 463 267 467 289 472C364 489 451 543 501 606L501 800L234 797C205 730 203 598 240 496C235 493 231 487 235 479Z"/>
<path fill="url(#fur)" d="M1018 479C1008 460 982 465 960 470C885 486 803 533 756 598L756 800L1019 796C1043 725 1042 596 1011 494C1017 491 1021 485 1018 479Z"/>
<path fill="url(#ear)" d="M234 797C215 752 215 693 222 651C229 606 244 557 261 542C274 531 284 533 296 547C326 581 356 630 374 684C353 664 329 655 293 649C299 672 308 686 323 694C289 719 257 759 234 797Z"/>
<path fill="url(#earShade)" d="M261 542C269 544 282 565 294 588C309 620 325 649 338 666C322 658 308 653 293 649C299 672 308 686 323 694C287 720 257 759 234 797C216 752 215 693 222 651C229 606 244 557 261 542Z"/>
<path fill="url(#ear)" d="M1019 796C1038 750 1036 688 1029 646C1021 600 1008 554 990 540C978 529 968 533 956 547C925 581 896 628 878 681C900 662 922 653 961 647C954 671 945 684 929 692C966 717 996 757 1019 796Z"/>
<path fill="#a6cb91" opacity=".64" d="M265 712C274 693 290 681 306 678C311 685 316 690 323 694C301 695 281 701 265 712Z"/>
<path fill="#a4c990" opacity=".64" d="M929 692C936 688 942 682 947 676C965 678 976 688 983 701C966 694 949 691 929 692Z"/>
<!-- Green fur tips show around the ivory face. -->
<path fill="url(#rim)" d="M111 896C117 926 132 948 153 959C132 984 118 1018 117 1048C139 1014 156 992 184 974L228 916Z"/>
<path fill="url(#rim)" d="M1145 916C1132 939 1113 953 1090 960C1113 989 1127 1020 1133 1053C1106 1019 1087 996 1057 977L1017 914Z"/>
<!-- One continuous face silhouette keeps the exported outline clean. -->
<path fill="url(#fur)" d="M118 1085C120 1037 141 989 174 953C142 941 121 922 111 896C156 891 193 871 221 839C244 813 264 789 287 772C268 778 251 785 234 797C255 759 287 719 323 694C308 686 299 672 293 649C329 655 353 664 374 684C394 654 443 624 501 606C544 579 591 558 637 551C627 567 614 580 599 592C656 566 729 580 797 614C827 632 855 656 878 681C900 662 922 653 961 647C954 671 945 684 929 692C966 717 996 757 1019 796C1038 833 1058 866 1083 887C1104 905 1126 913 1145 916C1129 935 1107 945 1079 948C1111 990 1129 1037 1133 1085Z"/>
<path fill="url(#furShade)" d="M668 633C692 632 711 639 720 654C730 670 735 687 740 703Z"/>
<path fill="url(#furShade)" d="M111 896C144 905 173 908 212 901L174 953C142 941 121 922 111 896Z"/>
<path fill="url(#furShade)" d="M163 882C192 861 209 840 225 812L244 794C258 784 271 777 287 772C246 827 212 868 163 882Z"/>
<path fill="url(#furShade)" d="M1037 887C1074 901 1107 914 1145 916C1129 935 1107 945 1079 948Z"/>
<path fill="url(#furShade)" d="M118 1085C121 1054 133 1023 151 997C146 1034 151 1063 172 1085Z"/>
<path fill="url(#furShade)" d="M1081 1085C1094 1069 1101 1049 1103 1028C1115 1045 1120 1063 1122 1085Z"/>
<ellipse fill="url(#eye)" cx="454" cy="922" rx="43.5" ry="66"/>
<ellipse fill="url(#eye)" cx="800.5" cy="922" rx="43.5" ry="66"/>
<path fill="url(#eye)" d="M591 971C591 960 610 955 626 955C642 955 661 960 661 971C661 987 642 1009 626 1009C610 1009 591 987 591 971Z"/>
<ellipse fill="url(#cheek)" cx="364.5" cy="1015.5" rx="56.5" ry="38"/>
<ellipse fill="url(#cheek)" cx="889.5" cy="1015.5" rx="56.5" ry="38"/>
<path fill="url(#whisker)" d="M204 980C225 972 259 974 278 981C283 983 283 988 278 988C251 986 228 988 208 994C200 996 196 983 204 980Z"/>
<path fill="url(#whisker)" d="M204 1036C224 1022 251 1016 274 1015C280 1015 281 1021 275 1023C251 1030 230 1040 212 1050C204 1055 194 1043 204 1036Z"/>
<g transform="translate(1254 0) scale(-1 1)">
<path fill="url(#whisker)" d="M204 980C225 972 259 974 278 981C283 983 283 988 278 988C251 986 228 988 208 994C200 996 196 983 204 980Z"/>
<path fill="url(#whisker)" d="M204 1036C224 1022 251 1016 274 1015C280 1015 281 1021 275 1023C251 1030 230 1040 212 1050C204 1055 194 1043 204 1036Z"/>
</g>
</g></g>
</svg>

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

+4
View File
@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024" role="img" aria-label="Felis">
<defs><mask id="shape" maskUnits="userSpaceOnUse" x="110" y="445" width="1040" height="640"><path fill="#fff" d="M174 633C176 566 202 481 233 459C263 438 329 462 384 484C443 509 488 550 517 580C553 560 601 548 643 549L631 569C666 566 704 573 734 583C792 517 880 470 949 454C977 448 1008 447 1024 462C1057 490 1075 568 1078 632L1027 801L935 777L749 625L509 624L315 774L218 814Z"/><path fill="#fff" d="M194 782C188 799 191 821 199 837C187 854 175 869 163 882L220 866L265 800Z"/><path fill="#fff" d="M1020 800C1037 815 1050 806 1062 786C1064 809 1059 829 1051 843L1080 882L1034 861Z"/><path fill="#fff" d="M236 479C211 512 189 568 177 623C168 678 173 743 191 785C199 805 210 815 225 812L258 778L386 651L285 518Z"/><path fill="#fff" d="M1018 480C1049 520 1067 578 1078 632C1083 689 1076 749 1059 789C1050 809 1036 814 1022 802L974 752L884 647L968 522Z"/><path fill="#fff" d="M235 479C243 463 267 467 289 472C364 489 451 543 501 606L501 800L234 797C205 730 203 598 240 496C235 493 231 487 235 479Z"/><path fill="#fff" d="M1018 479C1008 460 982 465 960 470C885 486 803 533 756 598L756 800L1019 796C1043 725 1042 596 1011 494C1017 491 1021 485 1018 479Z"/><path fill="#fff" d="M234 797C215 752 215 693 222 651C229 606 244 557 261 542C274 531 284 533 296 547C326 581 356 630 374 684C353 664 329 655 293 649C299 672 308 686 323 694C289 719 257 759 234 797Z"/><path fill="#fff" d="M261 542C269 544 282 565 294 588C309 620 325 649 338 666C322 658 308 653 293 649C299 672 308 686 323 694C287 720 257 759 234 797C216 752 215 693 222 651C229 606 244 557 261 542Z"/><path fill="#fff" d="M1019 796C1038 750 1036 688 1029 646C1021 600 1008 554 990 540C978 529 968 533 956 547C925 581 896 628 878 681C900 662 922 653 961 647C954 671 945 684 929 692C966 717 996 757 1019 796Z"/><path fill="#fff" d="M265 712C274 693 290 681 306 678C311 685 316 690 323 694C301 695 281 701 265 712Z"/><path fill="#fff" d="M929 692C936 688 942 682 947 676C965 678 976 688 983 701C966 694 949 691 929 692Z"/><path fill="#fff" d="M111 896C117 926 132 948 153 959C132 984 118 1018 117 1048C139 1014 156 992 184 974L228 916Z"/><path fill="#fff" d="M1145 916C1132 939 1113 953 1090 960C1113 989 1127 1020 1133 1053C1106 1019 1087 996 1057 977L1017 914Z"/><path fill="#fff" d="M118 1085C120 1037 141 989 174 953C142 941 121 922 111 896C156 891 193 871 221 839C244 813 264 789 287 772C268 778 251 785 234 797C255 759 287 719 323 694C308 686 299 672 293 649C329 655 353 664 374 684C394 654 443 624 501 606C544 579 591 558 637 551C627 567 614 580 599 592C656 566 729 580 797 614C827 632 855 656 878 681C900 662 922 653 961 647C954 671 945 684 929 692C966 717 996 757 1019 796C1038 833 1058 866 1083 887C1104 905 1126 913 1145 916C1129 935 1107 945 1079 948C1111 990 1129 1037 1133 1085Z"/><path fill="#fff" d="M668 633C692 632 711 639 720 654C730 670 735 687 740 703Z"/><path fill="#fff" d="M111 896C144 905 173 908 212 901L174 953C142 941 121 922 111 896Z"/><path fill="#fff" d="M163 882C192 861 209 840 225 812L244 794C258 784 271 777 287 772C246 827 212 868 163 882Z"/><path fill="#fff" d="M1037 887C1074 901 1107 914 1145 916C1129 935 1107 945 1079 948Z"/><path fill="#fff" d="M118 1085C121 1054 133 1023 151 997C146 1034 151 1063 172 1085Z"/><path fill="#fff" d="M1081 1085C1094 1069 1101 1049 1103 1028C1115 1045 1120 1063 1122 1085Z"/><path fill="#fff" d="M591 971C591 960 610 955 626 955C642 955 661 960 661 971C661 987 642 1009 626 1009C610 1009 591 987 591 971Z"/><path fill="#fff" d="M204 980C225 972 259 974 278 981C283 983 283 988 278 988C251 986 228 988 208 994C200 996 196 983 204 980Z"/><path fill="#fff" d="M204 1036C224 1022 251 1016 274 1015C280 1015 281 1021 275 1023C251 1030 230 1040 212 1050C204 1055 194 1043 204 1036Z"/><path fill="#fff" d="M204 980C225 972 259 974 278 981C283 983 283 988 278 988C251 986 228 988 208 994C200 996 196 983 204 980Z"/><path fill="#fff" d="M204 1036C224 1022 251 1016 274 1015C280 1015 281 1021 275 1023C251 1030 230 1040 212 1050C204 1055 194 1043 204 1036Z"/><ellipse fill="#000" cx="454" cy="922" rx="43.5" ry="66"/><ellipse fill="#000" cx="800.5" cy="922" rx="43.5" ry="66"/><path fill="#000" d="M591 971C591 960 610 955 626 955C642 955 661 960 661 971C661 987 642 1009 626 1009C610 1009 591 987 591 971Z"/></mask></defs>
<g transform="translate(64 236.30769230769226) scale(0.8615384615384616) translate(-110 -445)"><rect x="110" y="445" width="1040" height="640" fill="#000" mask="url(#shape)"/></g>
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

+15
View File
@@ -0,0 +1,15 @@
{
"name": "Felis Console",
"short_name": "Felis",
"start_url": "/",
"scope": "/",
"display": "standalone",
"background_color": "#e9f1e3",
"theme_color": "#65a26c",
"icons": [
{ "src": "icons/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any" },
{ "src": "icons/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any" },
{ "src": "icons/icon-maskable-192.png", "sizes": "192x192", "type": "image/png", "purpose": "maskable" },
{ "src": "icons/icon-maskable-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
]
}
+128
View File
@@ -0,0 +1,128 @@
#!/usr/bin/env node
// Requires sharp. On macOS, iconutil also exports the ICNS from the iconset.
const fs = require("node:fs/promises");
const path = require("node:path");
const { execFileSync } = require("node:child_process");
const sharp = require("sharp");
const root = path.resolve(__dirname, "..");
const assets = path.join(root, "docs/assets");
const kit = path.join(assets, "icons");
const web = path.join(root, "panel/public");
const sizes = [16, 20, 24, 32, 40, 48, 64, 96, 128, 180, 192, 256, 512, 1024];
function svg(defs, content, viewBox = "0 0 1024 1024", width = 1024, height = width) {
return `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="${viewBox}" role="img" aria-label="Felis">\n${defs}\n${content}\n</svg>\n`;
}
function place(art, width = 896) {
const scale = width / 1040;
return `<g transform="translate(${(1024 - width) / 2} ${(1024 - 640 * scale) / 2}) scale(${scale}) translate(-110 -445)">${art}</g>`;
}
async function render(source, size, destination, background) {
let image = sharp(Buffer.from(source), { density: 192 }).resize(size, size);
if (background) image = image.flatten({ background });
const png = await image.png().toBuffer();
await fs.writeFile(destination, png);
return png;
}
async function main() {
await Promise.all([kit, `${kit}/png`, `${kit}/felis.iconset`, `${web}/icons`].map((dir) => fs.mkdir(dir, { recursive: true })));
const source = await fs.readFile(`${assets}/felis-logo.svg`, "utf8");
const defs = source.match(/<defs>[\s\S]*?<\/defs>/)[0];
const art = source.match(/<g id="felis">[\s\S]*<\/g>/)[0];
const icon = svg(defs, place(art));
const tile = '<rect width="1024" height="1024" rx="224" fill="#e9f1e3"/>';
const app = svg(defs, tile + place(art));
const dark = svg(defs, tile.replace("#e9f1e3", "#253d31") + place(art));
// The entire cat fits inside the central 80% diameter safe circle.
const maskable = svg(defs, '<rect width="1024" height="1024" fill="#e9f1e3"/>' + place(art, 680));
const reference = svg(defs, '<rect width="1254" height="1254" fill="#fff"/>' + art, "0 0 1254 1254", 1254);
// White unions the original filled shapes; black knocks out facial features.
const silhouette = [...art.matchAll(/<path[^>]*\sd="([^"]+)"[^>]*\/>/g)]
.map((match) => `<path fill="#fff" d="${match[1]}"/>`).join("");
const cutouts = [...art.matchAll(/<(?:ellipse|path)\b[^>]*fill="url\(#eye\)"[^>]*\/>/g)]
.map((match) => match[0].replace('fill="url(#eye)"', 'fill="#000"')).join("");
const monoDefs = `<defs><mask id="shape" maskUnits="userSpaceOnUse" x="110" y="445" width="1040" height="640">${silhouette}${cutouts}</mask></defs>`;
const monoArt = '<rect x="110" y="445" width="1040" height="640" fill="#000" mask="url(#shape)"/>';
const mono = svg(monoDefs, monoArt, "110 445 1040 640", 1040, 640);
const mask = svg(monoDefs, place(monoArt));
for (const [name, value] of Object.entries({
"felis-icon.svg": icon, "felis-app.svg": app, "felis-app-dark.svg": dark,
"felis-maskable.svg": maskable, "felis-monochrome.svg": mono,
"felis-mask.svg": mask, "felis-reference.svg": reference,
})) await fs.writeFile(`${kit}/${name}`, value);
const pngs = new Map();
for (const size of sizes) pngs.set(size, await render(icon, size, `${kit}/png/icon-${size}.png`));
await render(app, 1024, `${kit}/felis-app.png`);
await render(dark, 1024, `${kit}/felis-app-dark.png`);
await render(maskable, 512, `${kit}/felis-maskable.png`);
await render(reference, 1254, `${kit}/felis-reference.png`);
await sharp(Buffer.from(source), { density: 192 }).resize(540, 341, { fit: "contain", background: "#00000000" }).png().toFile(`${assets}/felis-logo.png`);
const icoSizes = [16, 24, 32, 48, 64, 128, 256];
const directory = Buffer.alloc(6 + 16 * icoSizes.length);
directory.writeUInt16LE(1, 2);
directory.writeUInt16LE(icoSizes.length, 4);
let offset = directory.length;
icoSizes.forEach((size, index) => {
const data = pngs.get(size);
const entry = 6 + index * 16;
directory[entry] = directory[entry + 1] = size === 256 ? 0 : size;
directory.writeUInt16LE(1, entry + 4);
directory.writeUInt16LE(32, entry + 6);
directory.writeUInt32LE(data.length, entry + 8);
directory.writeUInt32LE(offset, entry + 12);
offset += data.length;
});
await fs.writeFile(`${kit}/felis.ico`, Buffer.concat([directory, ...icoSizes.map((size) => pngs.get(size))]));
for (const size of [16, 32, 128, 256, 512]) {
await render(app, size, `${kit}/felis.iconset/icon_${size}x${size}.png`);
await render(app, size * 2, `${kit}/felis.iconset/icon_${size}x${size}@2x.png`);
}
if (process.platform === "darwin") execFileSync("iconutil", ["-c", "icns", `${kit}/felis.iconset`, "-o", `${kit}/felis.icns`]);
await fs.writeFile(`${web}/favicon.svg`, icon);
await fs.copyFile(`${kit}/felis.ico`, `${web}/favicon.ico`);
for (const size of [16, 32]) await fs.writeFile(`${web}/favicon-${size}x${size}.png`, pngs.get(size));
await fs.writeFile(`${web}/safari-pinned-tab.svg`, mask);
await render(app, 180, `${web}/apple-touch-icon.png`, "#e9f1e3");
for (const size of [192, 512]) {
await render(app, size, `${web}/icons/icon-${size}.png`);
await render(maskable, size, `${web}/icons/icon-maskable-${size}.png`, "#e9f1e3");
}
const background = Buffer.from(`<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="1000">
<rect width="1200" height="1000" fill="#f7f9f5"/>
<g font-family="Arial, sans-serif" fill="#253d31">
<text x="48" y="64" font-size="30" font-weight="700">Felis / Icon Kit</text>
<text x="48" y="99" font-size="16" fill="#60745e">SVG paths · transparent PNG · ICO · ICNS · web icons</text>
<rect x="48" y="128" width="700" height="475" rx="24" fill="#fff"/>
<text x="76" y="166" font-size="15">VECTOR TRACE</text>
<rect x="776" y="128" width="376" height="475" rx="24" fill="#253d31"/>
<text x="804" y="166" font-size="15" fill="#e9f1e3">ON DARK</text>
<text x="48" y="654" font-size="15">APP / LIGHT</text>
<text x="294" y="654" font-size="15">APP / DARK</text>
<text x="540" y="654" font-size="15">MASKABLE</text>
<text x="786" y="654" font-size="15">MONOCHROME</text>
<text x="48" y="956" font-size="15" fill="#60745e">16 / 24 / 32 / 48 / 64 / 128 px</text>
</g></svg>`);
const large = await sharp(Buffer.from(source), { density: 192 }).resize(644, 396).png().toBuffer();
const onDark = await sharp(Buffer.from(source), { density: 192 }).resize(328, 202).png().toBuffer();
const previews = await Promise.all([app, dark, maskable, mask].map((value) => sharp(Buffer.from(value), { density: 192 }).resize(210, 210).png().toBuffer()));
const layers = [{ input: large, left: 76, top: 184 }, { input: onDark, left: 800, top: 277 },
...previews.map((input, index) => ({ input, left: 48 + index * 246, top: 682 }))];
let left = 420;
for (const size of [16, 24, 32, 48, 64, 128]) {
layers.push({ input: pngs.get(size), left, top: 978 - size });
left += size + 32;
}
await sharp(background).composite(layers).png().toFile(`${kit}/preview.png`);
console.log(`Generated Felis icons in ${kit} and ${web}`);
}
main().catch((error) => { console.error(error); process.exitCode = 1; });