fuzzyworld

fuzzyworld-tools / files / server / site / _icons.css

_icons.css

Blame: the commit that last changed each line · file · history

510a1337 2026-10-28 Pavel Safronov1/* =============================================================================
2 FuzzyWorld Icon System
3
4 Icon classes using inline SVG data URIs.
5 All icons are self-contained and work without external dependencies.
6
7 Usage:
8 <span class="icon icon-vscode"></span>
9 <a href="..." class="icon-link icon-github">GitHub</a>
10
11 For links that go to external sites:
12 <a href="https://..." class="external">Link text</a>
13 This will automatically add the external icon via ::after
14 ============================================================================= */
15
16/* ---------------------------------------------------------------------
17 Icon Base Styles
18 --------------------------------------------------------------------- */
19
20.icon {
21 display: inline-block;
22 width: 1em;
23 height: 1em;
24 vertical-align: -0.125em;
25 fill: currentColor;
26 flex-shrink: 0;
27 background-size: contain;
28 background-repeat: no-repeat;
29 background-position: center;
30}
31
32/* Icon with text - adds proper spacing */
33.icon-text {
34 display: inline-flex;
35 align-items: center;
36 gap: 0.25em;
37}
38
39.icon-text .icon {
40 width: 0.9em;
41 height: 0.9em;
42}
43
44/* ---------------------------------------------------------------------
45 External Link Indicator
46 Automatically added to external links (not fuzzyworld.net)
47 --------------------------------------------------------------------- */
48
49a[href^="http"]:not([href*="fuzzyworld.net"]):not(.no-external)::after,
50a[href^="mailto:"]::after,
51a[href^="vscode://"]::after {
52 content: " ";
53 display: inline-block;
54 width: 0.8em;
55 height: 0.8em;
56 vertical-align: 0.05em;
57 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'/%3E%3Cpolyline points='15 3 21 3 21 9'/%3E%3Cline x1='10' y1='14' x2='21' y2='3'/%3E%3C/svg%3E");
58 opacity: 0.6;
59}
60
61/* Disable external icon for specific links */
62.no-external::after {
63 content: none;
64}
65
66/* ---------------------------------------------------------------------
67 Brand & Platform Icons
68 --------------------------------------------------------------------- */
69
70/* FuzzyWorld logo placeholder */
71.icon-fuzzyworld::before {
72 content: "f";
73 font-weight: 700;
74 font-size: 1.2em;
75 letter-spacing: -0.02em;
76}
77
78/* VS Code Icon - Simple V in a diamond */
79.icon-vscode {
80 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='currentColor' d='M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5'/%3E%3C/svg%3E");
81}
82
83/* GitHub Octocat Icon */
84.icon-github {
85 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3E%3Cpath d='M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.163.798-.254.798-.554 0-.297-.006-.597-.006-.898 0-.297.006-.597.006-.898.598-.162.797-.66 7.983-1.178.708-.518 1.116-1.357 1.116-2.272 0-.298-.006-.598-.006-.898 0-.298.006-.598.006-.898.598-.163.797-.662 7.983-1.179.708-.518 1.116-1.356 1.116-2.272 0-.897-.006-1.796-.006-2.694 0-.298-.006-.598-.006-.898 0-.298.006-.598.006-.898.598-.163.797-.662 7.983-1.179.708-.518 1.116-1.357 1.116-2.272 0-.897-.006-1.796-.006-2.694 0-.297-.006-.597-.006-.897 0-.297.006-.597.006-.897.598-.162.797-.66 7.983-1.178.708-.518 1.116-1.357 1.116-2.272 0-.898-.006-1.797-.006-2.695C13.438 1.6 14 0 12 0zm0 2.157c6.626 0 12 5.373 12 12s-5.374 12-12 12S0 17.373 0 12 5.374 0 12 0zm-3.35 15.257l-2.077-2.077-1.116 1.116 2.077 2.077 1.116-1.116zm1.116-2.592l-1.116-1.116-1.116 1.116 1.116 1.116 1.116-1.116z'/%3E%3C/svg%3E");
86}
87
88/* Git Icon */
89.icon-git {
90 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3E%3Cpath d='M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.163.798-.254.798-.554 0-.297-.006-.597-.006-.898 0-.297.006-.597.006-.898.598-.162.797-.66 7.983-1.178.708-.518 1.116-1.357 1.116-2.272 0-.298-.006-.598-.006-.898 0-.298.006-.598.006-.898.598-.163.797-.662 7.983-1.179.708-.518 1.116-1.356 1.116-2.272 0-.897-.006-1.796-.006-2.694 0-.298-.006-.598-.006-.898 0-.298.006-.598.006-.898.598-.163.797-.662 7.983-1.179.708-.518 1.116-1.357 1.116-2.272C6.811 2.57 5.373 1.5 12 1.5c6.626 0 12 5.373 12 12s-5.374 12-12 12z'/%3E%3C/svg%3E");
91}
92
93/* Code Icon */
94.icon-code {
95 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3E%3Cpath d='m15.5 10.5-2-2-2 2-2-2-2 2-2-2-2 2 2 2-2-2 2 2 2-2 2-2 2-2-2 2 2z'/%3E%3C/svg%3E");
96}
97
98/* ---------------------------------------------------------------------
99 File & Directory Icons
100 --------------------------------------------------------------------- */
101
102/* Folder Icon */
103.icon-folder {
104 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3E%3Cpath d='M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2-3h9a2 2 0 0 1 2 2z'/%3E%3C/svg%3E");
105}
106
107/* File Icon */
108.icon-file {
109 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3E%3Cpath d='M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z'/%3E%3Cpolyline points='14 2 14 8 20 8'/%3E%3Cline x1='16' y1='13' x2='8' y2='13'/%3E%3Cline x1='16' y1='17' x2='8' y2='17'/%3E%3Cpath d='M10 20h4'/%3E%3C/svg%3E");
110}
111
112/* File Code Icon */
113.icon-file-code {
114 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3E%3Cpath d='M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V8z'/%3E%3Cpolyline points='14 2 14 8 20 8'/%3E%3Cline x1='16' y1='13' x2='8' y2='13'/%3E%3Cline x1='16' y1='17' x2='8' y2='17'/%3E%3Cpolyline points='10 9 9 9 8 9'/%3E%3Cpolyline points='17 9 18 9 19 9'/%3E%3C/svg%3E");
115}
116
117/* Image Icon */
118.icon-image {
119 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3E%3Cpath d='M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h18a2 2 0 0 1 2 2v14zM10 15l5-5-5-5v10z'/%3E%3C/svg%3E");
120}
121
122/* Markdown Icon */
123.icon-markdown {
124 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3E%3Cpath d='M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z'/%3E%3Cpolyline points='14 2 14 8 20 8'/%3E%3Cline x1='16' y1='13' x2='8' y2='13'/%3E%3Cline x1='16' y1='17' x2='8' y2='17'/%3E%3Cpolyline points='10 9 9 9 8 9'/%3E%3Cpolyline points='17 9 18 9 19 9'/%3E%3C/svg%3E");
125}
126
127/* ---------------------------------------------------------------------
128 UI & Status Icons
129 --------------------------------------------------------------------- */
130
131/* Checkmark / Success Icon */
132.icon-check {
133 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
134}
135
136/* X / Error Icon */
137.icon-x {
138 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'/%3E%3Cline x1='6' y1='6' x2='18' y2='18'/%3E%3C/svg%3E");
139}
140
141/* Circle / Running Icon (spinner-like) */
142.icon-circle {
143 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3C/svg%3E");
144}
145
146/* Alert / Warning Icon */
147.icon-alert {
148 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='12' y1='8' x2='12' y2='12'/%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'/%3E%3C/svg%3E");
149}
150
151/* Clock / Time Icon */
152.icon-clock {
153 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpolyline points='12 6 12 12 16 14'/%3E%3C/svg%3E");
154}
155
156/* Arrow Right (for navigation) */
157.icon-arrow-right {
158 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'/%3E%3Cpolyline points='12 5 19 12 12 19'/%3E%3C/svg%3E");
159}
160
161/* Arrow Up Right (external link style) */
162.icon-arrow-up-right {
163 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='7' y1='17' x2='17' y2='7'/%3E%3Cpolyline points='7 7 17 7 17 17'/%3E%3C/svg%3E");
164}
165
166/* ---------------------------------------------------------------------
167 Application Icons
168 --------------------------------------------------------------------- */
169
170/* App Icon (generic) */
171.icon-app {
172 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3E%3Cpath d='M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z'/%3E%3Cpath d='M12 6l4 4-4 4-4-4 4-4z'/%3E%3C/svg%3E");
173}
174
175/* Web Icon */
176.icon-web {
177 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='2' y1='12' x2='22' y2='12'/%3E%3Cpath d='M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z'/%3E%3C/svg%3E");
178}
179
180/* ---------------------------------------------------------------------
181 Helper Classes for Icon + Text Combinations
182 --------------------------------------------------------------------- */
183
184/* VS Code link with icon */
185.vscode-link {
186 display: inline-flex;
187 align-items: center;
188 gap: 0.35em;
189}
190
191.vscode-link::before {
192 content: "";
193 display: inline-block;
194 width: 1em;
195 height: 1em;
196 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='currentColor' d='M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5'/%3E%3C/svg%3E");
197 background-size: contain;
198 background-repeat: no-repeat;
199 background-position: center;
200}
201
202/* Clone command icon */
203.clone-icon::before {
204 content: "";
205 display: inline-block;
206 width: 1em;
207 height: 1em;
208 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3E%3Cpath d='M16 22s2-4-2-4-2 4-2 4-4-2-2-4-2 4-2 4-4-2-2 4-6-4 2-2 4 2 2 6-4-2-2 4 6-2 4 2 2 4 6 4'/%3E%3C/svg%3E");
209 background-size: contain;
210 background-repeat: no-repeat;
211 background-position: center;
212}