[READ-ONLY] a fast, modern browser for the npm registry

refactor: replace carbon icons (#1454)

authored by

Marcus Blättermann and committed by
GitHub
9e345ef7 cb1b4a46

+385 -442
+12 -12
app/components/AppHeader.vue
··· 23 23 keyshortcut: 'c', 24 24 type: 'link', 25 25 external: false, 26 - iconClass: 'i-carbon:compare', 26 + iconClass: 'i-lucide:git-compare', 27 27 }, 28 28 { 29 29 name: 'Settings', ··· 32 32 keyshortcut: ',', 33 33 type: 'link', 34 34 external: false, 35 - iconClass: 'i-carbon:settings', 35 + iconClass: 'i-lucide:settings', 36 36 }, 37 37 ]) 38 38 ··· 55 55 to: { name: 'about' }, 56 56 type: 'link', 57 57 external: false, 58 - iconClass: 'i-carbon:information', 58 + iconClass: 'i-lucide:info', 59 59 }, 60 60 { 61 61 name: 'Privacy Policy', ··· 63 63 to: { name: 'privacy' }, 64 64 type: 'link', 65 65 external: false, 66 - iconClass: 'i-carbon:security', 66 + iconClass: 'i-lucide:shield-check', 67 67 }, 68 68 { 69 69 name: 'Accessibility', ··· 71 71 to: { name: 'accessibility' }, 72 72 type: 'link', 73 73 external: false, 74 - iconClass: 'i-carbon:accessibility-alt', 74 + iconClass: 'i-custom:a11y', 75 75 }, 76 76 ], 77 77 }, ··· 90 90 target: '_blank', 91 91 type: 'link', 92 92 external: true, 93 - iconClass: 'i-carbon:document', 93 + iconClass: 'i-lucide:file-text', 94 94 }, 95 95 { 96 96 name: 'Source', ··· 99 99 target: '_blank', 100 100 type: 'link', 101 101 external: true, 102 - iconClass: 'i-carbon:logo-github', 102 + iconClass: 'i-simple-icons:github', 103 103 }, 104 104 { 105 105 name: 'Social', ··· 108 108 target: '_blank', 109 109 type: 'link', 110 110 external: true, 111 - iconClass: 'i-carbon:logo-bluesky', 111 + iconClass: 'i-simple-icons:bluesky', 112 112 }, 113 113 { 114 114 name: 'Chat', ··· 117 117 target: '_blank', 118 118 type: 'link', 119 119 external: true, 120 - iconClass: 'i-carbon:chat', 120 + iconClass: 'i-lucide:message-circle', 121 121 }, 122 122 ], 123 123 }, 124 124 ]) 125 125 126 126 const showFullSearch = shallowRef(false) 127 - const showMobileMenu = shallowRef(false) 127 + const showMobileMenu = shallowRef(true) 128 128 const { env } = useAppConfig().buildInfo 129 129 130 130 // On mobile, clicking logo+search button expands search ··· 288 288 :aria-expanded="showMobileMenu" 289 289 @click="expandMobileSearch" 290 290 v-if="!isSearchExpanded && !isOnHomePage" 291 - classicon="i-carbon:search" 291 + classicon="i-lucide:search" 292 292 /> 293 293 294 294 <!-- Mobile: Menu button (always visible, click to open menu) --> ··· 298 298 :aria-label="$t('nav.open_menu')" 299 299 :aria-expanded="showMobileMenu" 300 300 @click="showMobileMenu = !showMobileMenu" 301 - classicon="i-carbon:menu" 301 + classicon="i-lucide:menu" 302 302 /> 303 303 </nav> 304 304
+4 -4
app/components/BlueskyPostEmbed.client.vue
··· 83 83 <div class="text-sm text-fg-subtle truncate">@{{ post.author.handle }}</div> 84 84 </div> 85 85 <span 86 - class="i-carbon:logo-bluesky w-5 h-5 text-fg-subtle ms-auto shrink-0" 86 + class="i-simple-icons:bluesky w-5 h-5 text-fg-subtle ms-auto shrink-0" 87 87 aria-hidden="true" 88 88 /> 89 89 </div> ··· 112 112 <div class="flex items-center gap-4 text-sm text-fg-subtle"> 113 113 <DateTime :datetime="post.record.createdAt" date-style="medium" /> 114 114 <span v-if="post.likeCount" class="flex items-center gap-1"> 115 - <span class="i-carbon:favorite w-3.5 h-3.5" aria-hidden="true" /> 115 + <span class="i-lucide:heart w-3.5 h-3.5" aria-hidden="true" /> 116 116 {{ post.likeCount }} 117 117 </span> 118 118 <span v-if="post.repostCount" class="flex items-center gap-1"> 119 - <span class="i-carbon:repeat w-3.5 h-3.5" aria-hidden="true" /> 119 + <span class="i-lucide:repeat w-3.5 h-3.5" aria-hidden="true" /> 120 120 {{ post.repostCount }} 121 121 </span> 122 122 <span v-if="post.replyCount" class="flex items-center gap-1"> 123 - <span class="i-carbon:chat w-3.5 h-3.5" aria-hidden="true" /> 123 + <span class="i-lucide:message-circle w-3.5 h-3.5" aria-hidden="true" /> 124 124 {{ post.replyCount }} 125 125 </span> 126 126 </div>
+4 -4
app/components/CallToAction.vue
··· 3 3 { 4 4 id: 'github', 5 5 href: 'https://repo.npmx.dev', 6 - icon: 'i-carbon:logo-github', 6 + icon: 'i-simple-icons:github', 7 7 titleKey: $t('about.get_involved.contribute.title'), 8 8 descriptionKey: $t('about.get_involved.contribute.description'), 9 9 ctaKey: $t('about.get_involved.contribute.cta'), ··· 11 11 { 12 12 id: 'discord', 13 13 href: 'https://chat.npmx.dev', 14 - icon: 'i-carbon:chat', 14 + icon: 'i-lucide:message-circle', 15 15 titleKey: $t('about.get_involved.community.title'), 16 16 descriptionKey: $t('about.get_involved.community.description'), 17 17 ctaKey: $t('about.get_involved.community.cta'), ··· 19 19 { 20 20 id: 'bluesky', 21 21 href: 'https://social.npmx.dev', 22 - icon: 'i-carbon:logo-bluesky', 22 + icon: 'i-simple-icons:bluesky', 23 23 titleKey: $t('about.get_involved.follow.title'), 24 24 descriptionKey: $t('about.get_involved.follow.description'), 25 25 ctaKey: $t('about.get_involved.follow.cta'), ··· 55 55 class="text-sm text-fg-muted group-hover:text-fg inline-flex items-center gap-1 mt-auto focus-visible:outline-none" 56 56 > 57 57 {{ link.ctaKey }} 58 - <span class="i-carbon:arrow-right rtl-flip w-3 h-3" aria-hidden="true" /> 58 + <span class="i-lucide:arrow-right rtl-flip w-3 h-3" aria-hidden="true" /> 59 59 <span class="absolute z-0 inset-0" aria-hidden="true" /> 60 60 </a> 61 61 </div>
+1 -1
app/components/Code/FileTree.vue
··· 59 59 :aria-pressed="isNodeActive(node)" 60 60 :style="{ paddingLeft: `${depth * 12 + 12}px` }" 61 61 @click="toggleDir(node.path)" 62 - :classicon="isExpanded(node.path) ? 'i-carbon:chevron-down' : 'i-carbon:chevron-right'" 62 + :classicon="isExpanded(node.path) ? 'i-lucide:chevron-down' : 'i-lucide:chevron-right'" 63 63 > 64 64 <svg 65 65 class="size-[1em] me-1 shrink-0"
+2 -2
app/components/Code/MobileTreeDrawer.vue
··· 32 32 class="md:hidden fixed bottom-4 inset-ie-4 z-45" 33 33 :aria-label="$t('code.toggle_tree')" 34 34 @click="isOpen = !isOpen" 35 - :classicon="isOpen ? 'i-carbon:close' : 'i-carbon:folder'" 35 + :classicon="isOpen ? 'i-lucide:x' : 'i-lucide:folder'" 36 36 /> 37 37 38 38 <!-- Backdrop --> ··· 68 68 <ButtonBase 69 69 :aria-label="$t('code.close_tree')" 70 70 @click="isOpen = false" 71 - classicon="i-carbon-close" 71 + classicon="i-lucide:x" 72 72 /> 73 73 </div> 74 74 <CodeFileTree
+2 -6
app/components/CollapsibleSection.vue
··· 92 92 :aria-label="ariaLabel" 93 93 @click="toggle" 94 94 > 95 - <span 96 - v-if="isLoading" 97 - class="i-carbon:rotate-180 w-3 h-3 motion-safe:animate-spin" 98 - aria-hidden="true" 99 - /> 95 + <span v-if="isLoading" class="i-svg-spinners:ring-resize w-3 h-3" aria-hidden="true" /> 100 96 <span 101 97 v-else 102 98 class="w-3 h-3 transition-transform duration-200" 103 - :class="isOpen ? 'i-carbon:chevron-down' : 'i-carbon:chevron-right'" 99 + :class="isOpen ? 'i-lucide:chevron-down' : 'i-lucide:chevron-right'" 104 100 aria-hidden="true" 105 101 /> 106 102 </button>
+1 -1
app/components/ColumnPicker.vue
··· 75 75 aria-haspopup="true" 76 76 :aria-controls="menuId" 77 77 @click.stop="isOpen = !isOpen" 78 - classicon="i-carbon-column" 78 + classicon="i-lucide:columns-3-cog" 79 79 > 80 80 {{ $t('filters.columns.title') }} 81 81 </ButtonBase>
+2 -2
app/components/Compare/ComparisonGrid.vue
··· 50 50 </LinkBase> 51 51 <TooltipApp v-if="col.replacement" :text="getReplacementTooltip(col)" position="bottom"> 52 52 <span 53 - class="i-carbon:idea w-3.5 h-3.5 text-amber-500 shrink-0 cursor-help" 53 + class="i-lucide:lightbulb w-3.5 h-3.5 text-amber-500 shrink-0 cursor-help" 54 54 role="img" 55 55 :aria-label="$t('package.replacement.title')" 56 56 /> ··· 69 69 {{ $t('compare.no_dependency.label') }} 70 70 <TooltipApp interactive position="bottom"> 71 71 <span 72 - class="i-carbon:idea w-3.5 h-3.5 text-amber-500 shrink-0 cursor-help" 72 + class="i-lucide:lightbulb w-3.5 h-3.5 text-amber-500 shrink-0 cursor-help" 73 73 role="img" 74 74 :aria-label="$t('compare.no_dependency.tooltip_title')" 75 75 />
+2 -5
app/components/Compare/FacetCard.vue
··· 77 77 <span class="text-xs text-fg-muted uppercase tracking-wider font-medium">{{ label }}</span> 78 78 <TooltipApp v-if="description" :text="description" position="top"> 79 79 <span 80 - class="i-carbon:information w-3 h-3 text-fg-subtle" 80 + class="i-lucide:info w-3 h-3 text-fg-subtle" 81 81 :title="description" 82 82 aria-hidden="true" 83 83 /> ··· 111 111 <span class="relative min-w-0 text-end"> 112 112 <!-- Loading state --> 113 113 <template v-if="isCellLoading(index)"> 114 - <span 115 - class="i-carbon:circle-dash w-4 h-4 text-fg-subtle motion-safe:animate-spin" 116 - aria-hidden="true" 117 - /> 114 + <span class="i-svg-spinners:ring-resize w-4 h-4 text-fg-subtle" aria-hidden="true" /> 118 115 </template> 119 116 120 117 <!-- No data -->
+2 -5
app/components/Compare/FacetRow.vue
··· 93 93 <div class="comparison-label flex items-center gap-1.5 px-4 py-3 border-b border-border"> 94 94 <span class="text-xs text-fg-muted uppercase tracking-wider">{{ label }}</span> 95 95 <TooltipApp v-if="description" :text="description" position="top"> 96 - <span class="i-carbon:information w-3 h-3 text-fg-subtle cursor-help" aria-hidden="true" /> 96 + <span class="i-lucide:info w-3 h-3 text-fg-subtle cursor-help" aria-hidden="true" /> 97 97 </TooltipApp> 98 98 </div> 99 99 ··· 114 114 115 115 <!-- Loading state --> 116 116 <template v-if="isCellLoading(index)"> 117 - <span 118 - class="i-carbon:circle-dash w-4 h-4 text-fg-subtle motion-safe:animate-spin" 119 - aria-hidden="true" 120 - /> 117 + <span class="i-svg-spinners:ring-resize w-4 h-4 text-fg-subtle" aria-hidden="true" /> 121 118 </template> 122 119 123 120 <!-- No data -->
+2 -2
app/components/Compare/FacetSelector.vue
··· 82 82 facet.comingSoon 83 83 ? undefined 84 84 : isFacetSelected(facet.id) 85 - ? 'i-carbon:checkmark' 86 - : 'i-carbon:add' 85 + ? 'i-lucide:check' 86 + : 'i-lucide:plus' 87 87 " 88 88 > 89 89 {{ facet.label }}
+3 -3
app/components/Compare/PackageSelector.vue
··· 199 199 <!-- No dependency display --> 200 200 <template v-if="pkg === NO_DEPENDENCY_ID"> 201 201 <span class="text-sm text-accent italic flex items-center gap-1.5"> 202 - <span class="i-carbon:clean w-3.5 h-3.5" aria-hidden="true" /> 202 + <span class="i-lucide:leaf w-3.5 h-3.5" aria-hidden="true" /> 203 203 {{ $t('compare.no_dependency.label') }} 204 204 </span> 205 205 </template> ··· 214 214 }) 215 215 " 216 216 @click="removePackage(pkg)" 217 - classicon="i-carbon:close" 217 + classicon="i-lucide:x" 218 218 /> 219 219 </TagStatic> 220 220 </div> ··· 273 273 @click="addPackage(NO_DEPENDENCY_ID)" 274 274 > 275 275 <span class="text-sm text-accent italic flex items-center gap-2"> 276 - <span class="i-carbon:clean w-4 h-4" aria-hidden="true" /> 276 + <span class="i-lucide:leaf w-4 h-4" aria-hidden="true" /> 277 277 {{ $t('compare.no_dependency.typeahead_title') }} 278 278 </span> 279 279 <span class="text-xs text-fg-muted truncate mt-0.5">
+1 -1
app/components/Compare/ReplacementSuggestion.vue
··· 31 31 > 32 32 <span 33 33 class="w-4 h-4 flex-shrink-0 mt-0.5" 34 - :class="variant === 'nodep' ? 'i-carbon:idea' : 'i-carbon:information'" 34 + :class="variant === 'nodep' ? 'i-lucide:lightbulb' : 'i-lucide:info'" 35 35 /> 36 36 <div class="min-w-0 flex-1"> 37 37 <p class="font-medium">{{ packageName }}: {{ $t('package.replacement.title') }}</p>
+1 -1
app/components/DependencyPathPopup.vue
··· 72 72 :aria-expanded="isOpen" 73 73 @click.stop="togglePopup" 74 74 > 75 - <span class="i-carbon:tree-view w-3 h-3" aria-hidden="true" /> 75 + <span class="i-lucide:network w-3 h-3" aria-hidden="true" /> 76 76 <span>{{ $t('package.vulnerabilities.path') }}</span> 77 77 </button> 78 78
+1 -1
app/components/Filter/Chips.vue
··· 25 25 :aria-label="$t('filters.remove_filter', { label: chip.label })" 26 26 @click="emit('remove', chip)" 27 27 > 28 - <span class="i-carbon-close w-3 h-3" aria-hidden="true" /> 28 + <span class="i-lucide:x w-3 h-3" aria-hidden="true" /> 29 29 </button> 30 30 </TagStatic> 31 31 </TransitionGroup>
+2 -2
app/components/Filter/Panel.vue
··· 193 193 @click="isExpanded = !isExpanded" 194 194 > 195 195 <span class="flex items-center gap-2 text-sm font-mono text-fg shrink-0"> 196 - <span class="i-carbon-filter w-4 h-4" aria-hidden="true" /> 196 + <span class="i-lucide:funnel w-4 h-4" aria-hidden="true" /> 197 197 {{ $t('filters.title') }} 198 198 </span> 199 199 <span v-if="!isExpanded && hasActiveFilters" class="text-xs font-mono text-fg-muted truncate"> 200 200 {{ filterSummary }} 201 201 </span> 202 202 <span 203 - class="i-carbon-chevron-down w-4 h-4 text-fg-subtle transition-transform duration-200 shrink-0 ms-auto" 203 + class="i-lucide:chevron-down w-4 h-4 text-fg-subtle transition-transform duration-200 shrink-0 ms-auto" 204 204 :class="{ 'rotate-180': isExpanded }" 205 205 aria-hidden="true" 206 206 />
+8 -8
app/components/Header/AccountMenu.client.vue
··· 83 83 v-else-if="isNpmConnected" 84 84 class="w-6 h-6 rounded-full bg-bg-muted ring-2 ring-bg flex items-center justify-center" 85 85 > 86 - <span class="i-carbon-terminal w-3 h-3 text-fg-muted" aria-hidden="true" /> 86 + <span class="i-lucide:terminal w-3 h-3 text-fg-muted" aria-hidden="true" /> 87 87 </span> 88 88 89 89 <!-- Atmosphere avatar (second/front, overlapping) --> ··· 101 101 class="w-6 h-6 rounded-full bg-bg-muted ring-2 ring-bg flex items-center justify-center" 102 102 :class="hasBothConnections ? 'relative z-10' : ''" 103 103 > 104 - <span class="i-carbon-cloud w-3 h-3 text-fg-muted" aria-hidden="true" /> 104 + <span class="i-lucide:at-sign w-3 h-3 text-fg-muted" aria-hidden="true" /> 105 105 </span> 106 106 </span> 107 107 ··· 112 112 113 113 <!-- Chevron --> 114 114 <span 115 - class="i-carbon-chevron-down w-3 h-3 transition-transform duration-200" 115 + class="i-lucide:chevron-down w-3 h-3 transition-transform duration-200" 116 116 :class="{ 'rotate-180': isOpen }" 117 117 aria-hidden="true" 118 118 /> ··· 161 161 v-else 162 162 class="w-8 h-8 rounded-full bg-bg-muted flex items-center justify-center" 163 163 > 164 - <span class="i-carbon-terminal w-4 h-4 text-fg-muted" aria-hidden="true" /> 164 + <span class="i-lucide:terminal w-4 h-4 text-fg-muted" aria-hidden="true" /> 165 165 </span> 166 166 <span class="flex-1 min-w-0"> 167 167 <span class="font-mono text-sm text-fg truncate block">~{{ npmUser }}</span> ··· 203 203 v-else 204 204 class="w-8 h-8 rounded-full bg-bg-muted flex items-center justify-center" 205 205 > 206 - <span class="i-carbon-cloud w-4 h-4 text-fg-muted" aria-hidden="true" /> 206 + <span class="i-lucide:at-sign w-4 h-4 text-fg-muted" aria-hidden="true" /> 207 207 </span> 208 208 <span class="flex-1 min-w-0"> 209 209 <span class="font-mono text-sm text-fg truncate block" ··· 231 231 <span class="w-8 h-8 rounded-full bg-bg-muted flex items-center justify-center"> 232 232 <span 233 233 v-if="isNpmConnecting" 234 - class="i-carbon-circle-dash w-4 h-4 text-yellow-500 animate-spin" 234 + class="i-svg-spinners:ring-resize w-4 h-4 text-yellow-500 animate-spin" 235 235 aria-hidden="true" 236 236 /> 237 - <span v-else class="i-carbon-terminal w-4 h-4 text-fg-muted" aria-hidden="true" /> 237 + <span v-else class="i-lucide:terminal w-4 h-4 text-fg-muted" aria-hidden="true" /> 238 238 </span> 239 239 <span class="flex-1 min-w-0"> 240 240 <span class="font-mono text-sm text-fg block"> ··· 255 255 @click="openAuthModal" 256 256 > 257 257 <span class="w-8 h-8 rounded-full bg-bg-muted flex items-center justify-center"> 258 - <span class="i-carbon-cloud w-4 h-4 text-fg-muted" aria-hidden="true" /> 258 + <span class="i-lucide:at-sign w-4 h-4 text-fg-muted" aria-hidden="true" /> 259 259 </span> 260 260 <span class="flex-1 min-w-0"> 261 261 <span class="font-mono text-sm text-fg block">
+1 -1
app/components/Header/AccountMenu.server.vue
··· 4 4 class="inline-flex gap-x-1 items-center justify-center font-mono border border-border rounded-md text-sm px-4 py-2 bg-transparent text-fg border-none" 5 5 > 6 6 <span class="font-mono text-sm text-fg-muted">{{ $t('account_menu.connect') }}</span> 7 - <span class="i-carbon-chevron-down w-3 h-3 text-fg-muted" aria-hidden="true" /> 7 + <span class="i-lucide:chevron-down w-3 h-3 text-fg-muted" aria-hidden="true" /> 8 8 </div> 9 9 </div> 10 10 </template>
+1 -1
app/components/Header/AuthModal.client.vue
··· 132 132 type="button" 133 133 class="w-full" 134 134 @click="handleBlueskySignIn" 135 - classicon="i-carbon:logo-bluesky" 135 + classicon="i-simple-icons:bluesky" 136 136 > 137 137 {{ $t('auth.modal.connect_bluesky') }} 138 138 </ButtonBase>
+3 -3
app/components/Header/ConnectorModal.vue
··· 121 121 :aria-label="copied ? $t('connector.modal.copied') : $t('connector.modal.copy_command')" 122 122 @click="copy('pnpm npmx-connector')" 123 123 class="ms-auto" 124 - :classicon="copied ? 'i-carbon:checkmark text-green-500' : 'i-carbon:copy'" 124 + :classicon="copied ? 'i-lucide:check text-green-500' : 'i-lucide:copy'" 125 125 /> 126 126 </div> 127 127 ··· 142 142 class="ms-auto text-fg-subtle p-1.5 -m-1.5 hover:text-fg transition-colors duration-200 focus-visible:outline-accent/70 rounded" 143 143 @click="copyCommand" 144 144 > 145 - <span v-if="!copied" class="i-carbon:copy block w-5 h-5" aria-hidden="true" /> 145 + <span v-if="!copied" class="i-lucide:copy block w-5 h-5" aria-hidden="true" /> 146 146 <span 147 147 v-else 148 - class="i-carbon:checkmark block w-5 h-5 text-green-500" 148 + class="i-lucide:check block w-5 h-5 text-green-500" 149 149 aria-hidden="true" 150 150 /> 151 151 </button>
+5 -5
app/components/Header/MobileMenu.client.vue
··· 99 99 :aria-label="$t('common.close')" 100 100 @click="closeMenu" 101 101 > 102 - <span class="i-carbon:close w-5 h-5" aria-hidden="true" /> 102 + <span class="i-lucide:x w-5 h-5" aria-hidden="true" /> 103 103 </button> 104 104 </div> 105 105 ··· 130 130 v-else 131 131 class="w-5 h-5 rounded-full bg-bg-muted flex items-center justify-center" 132 132 > 133 - <span class="i-carbon-terminal w-3 h-3 text-fg-muted" aria-hidden="true" /> 133 + <span class="i-lucide:terminal w-3 h-3 text-fg-muted" aria-hidden="true" /> 134 134 </span> 135 135 <span class="flex-1">~{{ npmUser }}</span> 136 136 <span class="w-2 h-2 rounded-full bg-green-500" aria-hidden="true" /> ··· 155 155 v-else 156 156 class="w-5 h-5 rounded-full bg-bg-muted flex items-center justify-center" 157 157 > 158 - <span class="i-carbon-cloud w-3 h-3 text-fg-muted" aria-hidden="true" /> 158 + <span class="i-lucide:at-sign w-3 h-3 text-fg-muted" aria-hidden="true" /> 159 159 </span> 160 160 <span class="flex-1 truncate">@{{ atprotoUser.handle }}</span> 161 161 </button> ··· 168 168 @click="handleShowAuth" 169 169 > 170 170 <span class="w-5 h-5 rounded-full bg-bg-muted flex items-center justify-center"> 171 - <span class="i-carbon-cloud w-3 h-3 text-fg-muted" aria-hidden="true" /> 171 + <span class="i-lucide:at-sign w-3 h-3 text-fg-muted" aria-hidden="true" /> 172 172 </span> 173 173 <span class="flex-1">{{ $t('account_menu.connect_atmosphere') }}</span> 174 174 </button> ··· 211 211 {{ link.label }} 212 212 <span 213 213 v-if="link.external" 214 - class="i-carbon:launch rtl-flip w-3 h-3 ms-auto text-fg-subtle" 214 + class="i-lucide:external-link rtl-flip w-3 h-3 ms-auto text-fg-subtle" 215 215 aria-hidden="true" 216 216 /> 217 217 </NuxtLink>
+2 -2
app/components/Header/OrgsDropdown.vue
··· 63 63 > 64 64 {{ $t('header.orgs') }} 65 65 <span 66 - class="i-carbon-chevron-down w-3 h-3 transition-transform duration-200" 66 + class="i-lucide:chevron-down w-3 h-3 transition-transform duration-200" 67 67 :class="{ 'rotate-180': isOpen }" 68 68 aria-hidden="true" 69 69 /> ··· 112 112 class="link-subtle font-mono text-xs inline-flex items-center gap-1" 113 113 > 114 114 {{ $t('header.orgs_dropdown.view_all') }} 115 - <span class="i-carbon:arrow-right rtl-flip w-3 h-3" aria-hidden="true" /> 115 + <span class="i-lucide:arrow-right rtl-flip w-3 h-3" aria-hidden="true" /> 116 116 </NuxtLink> 117 117 </div> 118 118 </div>
+2 -2
app/components/Header/PackagesDropdown.vue
··· 63 63 > 64 64 {{ $t('header.packages') }} 65 65 <span 66 - class="i-carbon-chevron-down w-3 h-3 transition-transform duration-200" 66 + class="i-lucide:chevron-down w-3 h-3 transition-transform duration-200" 67 67 :class="{ 'rotate-180': isOpen }" 68 68 aria-hidden="true" 69 69 /> ··· 112 112 class="link-subtle font-mono text-xs inline-flex items-center gap-1" 113 113 > 114 114 {{ $t('header.packages_dropdown.view_all') }} 115 - <span class="i-carbon:arrow-right rtl-flip w-3 h-3" aria-hidden="true" /> 115 + <span class="i-lucide:arrow-right rtl-flip w-3 h-3" aria-hidden="true" /> 116 116 </NuxtLink> 117 117 </div> 118 118 </div>
+1 -1
app/components/LicenseDisplay.vue
··· 28 28 </template> 29 29 <span 30 30 v-if="hasAnyValidLicense" 31 - class="i-carbon-scales w-3.5 h-3.5 text-fg-subtle flex-shrink-0 self-center" 31 + class="i-lucide:scale w-3.5 h-3.5 text-fg-subtle flex-shrink-0 self-center" 32 32 aria-hidden="true" 33 33 /> 34 34 </span>
+2 -2
app/components/Link/Base.vue
··· 101 101 <!-- automatically show icon indicating external link --> 102 102 <span 103 103 v-if="isLinkExternal && !classicon" 104 - class="i-carbon:launch rtl-flip size-[1em] opacity-50" 104 + class="i-lucide:external-link rtl-flip size-[1em] opacity-50" 105 105 aria-hidden="true" 106 106 /> 107 107 <span 108 108 v-else-if="isLinkAnchor && isLink" 109 - class="i-carbon:link size-[1em] opacity-0 group-hover/link:opacity-100 transition-opacity duration-200" 109 + class="i-lucide:link size-[1em] opacity-0 group-hover/link:opacity-100 transition-opacity duration-200" 110 110 aria-hidden="true" 111 111 /> 112 112 <kbd
+1 -1
app/components/Modal.client.vue
··· 57 57 type="button" 58 58 :aria-label="$t('common.close')" 59 59 @click="handleModalClose" 60 - classicon="i-carbon-close" 60 + classicon="i-lucide:x" 61 61 /> 62 62 </div> 63 63 <!-- Modal body content -->
+6 -6
app/components/Org/MembersPanel.vue
··· 304 304 <!-- Header --> 305 305 <div class="flex items-center justify-between p-4 border-b border-border"> 306 306 <h2 id="members-heading" class="font-mono text-sm font-medium flex items-center gap-2"> 307 - <span class="i-carbon:user-multiple w-4 h-4 text-fg-muted" aria-hidden="true" /> 307 + <span class="i-lucide:users w-4 h-4 text-fg-muted" aria-hidden="true" /> 308 308 {{ $t('org.members.title') }} 309 309 <span v-if="memberList.length > 0" class="text-fg-muted">({{ memberList.length }})</span> 310 310 </h2> ··· 316 316 @click="refreshData" 317 317 > 318 318 <span 319 - class="i-carbon:renew w-4 h-4" 319 + class="i-lucide:refresh-ccw w-4 h-4" 320 320 :class="{ 'motion-safe:animate-spin': isLoading || isLoadingTeams }" 321 321 aria-hidden="true" 322 322 /> ··· 327 327 <div class="flex flex-wrap items-center gap-2 p-3 border-b border-border bg-bg"> 328 328 <div class="flex-1 min-w-[150px] relative"> 329 329 <span 330 - class="absolute inset-is-2 top-1/2 -translate-y-1/2 i-carbon:search w-3.5 h-3.5 text-fg-subtle" 330 + class="absolute inset-is-2 top-1/2 -translate-y-1/2 i-lucide:search w-3.5 h-3.5 text-fg-subtle" 331 331 aria-hidden="true" 332 332 /> 333 333 <label for="members-search" class="sr-only">{{ $t('org.members.filter_label') }}</label> ··· 407 407 <!-- Loading state --> 408 408 <div v-if="isLoading && memberList.length === 0" class="p-8 text-center"> 409 409 <span 410 - class="i-carbon:rotate-180 w-5 h-5 text-fg-muted animate-spin mx-auto" 410 + class="i-svg-spinners:ring-resize w-5 h-5 text-fg-muted animate-spin mx-auto" 411 411 aria-hidden="true" 412 412 /> 413 413 <p class="font-mono text-sm text-fg-muted mt-2">{{ $t('org.members.loading') }}</p> ··· 486 486 :aria-label="$t('org.members.remove_from_org', { name: member.name })" 487 487 @click="handleRemoveMember(member.name)" 488 488 > 489 - <span class="i-carbon:close w-4 h-4" aria-hidden="true" /> 489 + <span class="i-lucide:x w-4 h-4" aria-hidden="true" /> 490 490 </button> 491 491 </div> 492 492 </div> ··· 572 572 :aria-label="$t('org.members.cancel_add')" 573 573 @click="showAddMember = false" 574 574 > 575 - <span class="i-carbon:close w-4 h-4" aria-hidden="true" /> 575 + <span class="i-lucide:x w-4 h-4" aria-hidden="true" /> 576 576 </button> 577 577 </div> 578 578 </form>
+15 -15
app/components/Org/OperationsQueue.vue
··· 158 158 function getStatusIcon(status: string): string { 159 159 switch (status) { 160 160 case 'pending': 161 - return 'i-carbon:time' 161 + return 'i-lucide:clock' 162 162 case 'approved': 163 - return 'i-carbon:checkmark' 163 + return 'i-lucide:check' 164 164 case 'running': 165 - return 'i-carbon:rotate-180' 165 + return 'i-svg-spinners:ring-resize' 166 166 case 'completed': 167 - return 'i-carbon:checkmark-filled' 167 + return 'i-lucide:check-filled' 168 168 case 'failed': 169 - return 'i-carbon:close-filled' 169 + return 'i-lucide:x-filled' 170 170 default: 171 - return 'i-carbon:help' 171 + return 'i-lucide:circle-question-mark' 172 172 } 173 173 } 174 174 ··· 211 211 :aria-label="$t('operations.queue.refresh')" 212 212 @click="refreshState" 213 213 > 214 - <span class="i-carbon:renew w-4 h-4" aria-hidden="true" /> 214 + <span class="i-lucide:refresh-ccw w-4 h-4" aria-hidden="true" /> 215 215 </button> 216 216 </div> 217 217 </div> ··· 283 283 :aria-label="$t('operations.queue.approve_operation')" 284 284 @click="approveOperation(op.id)" 285 285 > 286 - <span class="i-carbon:checkmark w-4 h-4" aria-hidden="true" /> 286 + <span class="i-lucide:check w-4 h-4" aria-hidden="true" /> 287 287 </button> 288 288 <button 289 289 v-if="op.status !== 'running'" ··· 292 292 :aria-label="$t('operations.queue.remove_operation')" 293 293 @click="removeOperation(op.id)" 294 294 > 295 - <span class="i-carbon-close w-4 h-4" aria-hidden="true" /> 295 + <span class="i-lucide:x w-4 h-4" aria-hidden="true" /> 296 296 </button> 297 297 </div> 298 298 </li> ··· 305 305 role="alert" 306 306 > 307 307 <div class="flex items-center gap-2 mb-2"> 308 - <span class="i-carbon:locked w-4 h-4 text-amber-400 shrink-0" aria-hidden="true" /> 308 + <span class="i-lucide:lock w-4 h-4 text-amber-400 shrink-0" aria-hidden="true" /> 309 309 <span class="font-mono text-sm text-amber-400"> 310 310 {{ $t('operations.queue.otp_prompt') }} 311 311 </span> ··· 384 384 class="flex-1 px-4 py-2 font-mono text-sm text-accent bg-accent/10 border border-accent/30 rounded-md transition-colors duration-200 hover:bg-accent/20" 385 385 @click="handleOpenAuthUrl" 386 386 > 387 - <span class="i-carbon:launch w-4 h-4 inline-block me-1" aria-hidden="true" /> 387 + <span class="i-lucide:external-link w-4 h-4 inline-block me-1" aria-hidden="true" /> 388 388 {{ $t('operations.queue.open_web_auth') }} 389 389 </button> 390 390 </div> ··· 395 395 class="flex items-center gap-2 font-mono text-xs text-fg-muted hover:text-fg transition-colors duration-200 select-none" 396 396 > 397 397 <span 398 - class="i-carbon:chevron-right rtl-flip w-3 h-3 transition-transform duration-200 [[open]>&]:rotate-90" 398 + class="i-lucide:chevron-right rtl-flip w-3 h-3 transition-transform duration-200 [[open]>&]:rotate-90" 399 399 aria-hidden="true" 400 400 /> 401 401 {{ $t('operations.queue.log') }} ({{ completedOperations.length }}) ··· 410 410 <span 411 411 :class=" 412 412 op.status === 'completed' 413 - ? 'i-carbon:checkmark-filled text-green-500' 414 - : 'i-carbon:close-filled text-red-500' 413 + ? 'i-lucide:check-filled text-green-500' 414 + : 'i-lucide:x-filled text-red-500' 415 415 " 416 416 class="w-3.5 h-3.5 shrink-0 mt-0.5" 417 417 aria-hidden="true" ··· 431 431 :aria-label="$t('operations.queue.remove_from_log')" 432 432 @click="removeOperation(op.id)" 433 433 > 434 - <span class="i-carbon:close w-3 h-3" aria-hidden="true" /> 434 + <span class="i-lucide:x w-3 h-3" aria-hidden="true" /> 435 435 </button> 436 436 </li> 437 437 </ul>
+10 -13
app/components/Org/TeamsPanel.vue
··· 259 259 <!-- Header --> 260 260 <div class="flex items-center justify-start p-4 border-b border-border"> 261 261 <h2 id="teams-heading" class="font-mono text-sm font-medium flex items-center gap-2"> 262 - <span class="i-carbon:group w-4 h-4 text-fg-muted" aria-hidden="true" /> 262 + <span class="i-lucide:users w-4 h-4 text-fg-muted" aria-hidden="true" /> 263 263 {{ $t('org.teams.title') }} 264 264 <span v-if="teams.length > 0" class="text-fg-muted">({{ teams.length }})</span> 265 265 </h2> ··· 272 272 @click="loadTeams" 273 273 > 274 274 <span 275 - class="i-carbon:renew w-4 h-4" 275 + class="i-lucide:refresh-ccw w-4 h-4" 276 276 :class="{ 'animate-spin': isLoadingTeams }" 277 277 aria-hidden="true" 278 278 /> ··· 283 283 <div class="flex items-center gap-2 p-3 border-b border-border bg-bg"> 284 284 <div class="flex-1 relative"> 285 285 <span 286 - class="absolute inset-is-2 top-1/2 -translate-y-1/2 i-carbon:search w-3.5 h-3.5 text-fg-subtle" 286 + class="absolute inset-is-2 top-1/2 -translate-y-1/2 i-lucide:search w-3.5 h-3.5 text-fg-subtle" 287 287 aria-hidden="true" 288 288 /> 289 289 <label for="teams-search" class="sr-only">{{ $t('org.teams.filter_label') }}</label> ··· 328 328 329 329 <!-- Loading state --> 330 330 <div v-if="isLoadingTeams && teams.length === 0" class="p-8 text-center"> 331 - <span 332 - class="i-carbon:rotate-180 w-5 h-5 text-fg-muted motion-safe:animate-spin mx-auto" 333 - aria-hidden="true" 334 - /> 331 + <span class="i-svg-spinners:ring-resize w-5 h-5 text-fg-muted mx-auto" aria-hidden="true" /> 335 332 <p class="font-mono text-sm text-fg-muted mt-2">{{ $t('org.teams.loading') }}</p> 336 333 </div> 337 334 ··· 371 368 <span 372 369 class="w-4 h-4 transition-transform duration-200 rtl-flip" 373 370 :class="[ 374 - expandedTeams.has(teamName) ? 'i-carbon:chevron-down' : 'i-carbon:chevron-right', 371 + expandedTeams.has(teamName) ? 'i-lucide:chevron-down' : 'i-lucide:chevron-right', 375 372 'text-fg-muted', 376 373 ]" 377 374 aria-hidden="true" ··· 388 385 </span> 389 386 <span 390 387 v-if="isLoadingUsers[teamName]" 391 - class="i-carbon:rotate-180 w-3 h-3 text-fg-muted motion-safe:animate-spin" 388 + class="i-svg-spinners:ring-resize w-3 h-3 text-fg-muted" 392 389 aria-hidden="true" 393 390 /> 394 391 </button> ··· 399 396 :aria-label="$t('org.teams.delete_team', { name: teamName })" 400 397 @click.stop="handleDestroyTeam(teamName)" 401 398 > 402 - <span class="i-carbon:trash-can w-4 h-4" aria-hidden="true" /> 399 + <span class="i-lucide:trash w-4 h-4" aria-hidden="true" /> 403 400 </button> 404 401 </div> 405 402 ··· 433 430 :aria-label="$t('org.teams.remove_user', { user })" 434 431 @click="handleRemoveUser(teamName, user)" 435 432 > 436 - <span class="i-carbon:close w-3.5 h-3.5" aria-hidden="true" /> 433 + <span class="i-lucide:x w-3.5 h-3.5" aria-hidden="true" /> 437 434 </button> 438 435 </li> 439 436 </ul> ··· 470 467 :aria-label="$t('org.teams.cancel_add_user')" 471 468 @click="showAddUserFor = null" 472 469 > 473 - <span class="i-carbon:close w-4 h-4" aria-hidden="true" /> 470 + <span class="i-lucide:x w-4 h-4" aria-hidden="true" /> 474 471 </button> 475 472 </form> 476 473 </div> ··· 528 525 :aria-label="$t('org.teams.cancel_create')" 529 526 @click="showCreateTeam = false" 530 527 > 531 - <span class="i-carbon:close w-4 h-4" aria-hidden="true" /> 528 + <span class="i-lucide:x w-4 h-4" aria-hidden="true" /> 532 529 </button> 533 530 </form> 534 531 </div>
+6 -6
app/components/Package/AccessControls.vue
··· 163 163 @click="loadCollaborators" 164 164 > 165 165 <span 166 - class="i-carbon-renew w-3.5 h-3.5" 166 + class="i-lucide:refresh-ccw w-3.5 h-3.5" 167 167 :class="{ 'motion-safe:animate-spin': isLoadingCollaborators }" 168 168 aria-hidden="true" 169 169 /> ··· 173 173 <!-- Loading state --> 174 174 <div v-if="isLoadingCollaborators && collaboratorList.length === 0" class="py-4 text-center"> 175 175 <span 176 - class="i-carbon-rotate-180 w-4 h-4 text-fg-muted animate-spin mx-auto" 176 + class="i-svg-spinners:ring-resize w-4 h-4 text-fg-muted animate-spin mx-auto" 177 177 aria-hidden="true" 178 178 /> 179 179 </div> ··· 197 197 <div class="flex items-center gap-2 min-w-0"> 198 198 <span 199 199 v-if="collab.isTeam" 200 - class="i-carbon-group w-3.5 h-3.5 text-fg-subtle shrink-0" 200 + class="i-lucide:users w-3.5 h-3.5 text-fg-subtle shrink-0" 201 201 aria-hidden="true" 202 202 /> 203 203 <span 204 204 v-else 205 - class="i-carbon-user w-3.5 h-3.5 text-fg-subtle shrink-0" 205 + class="i-lucide:user w-3.5 h-3.5 text-fg-subtle shrink-0" 206 206 aria-hidden="true" 207 207 /> 208 208 <span class="font-mono text-sm text-fg-muted truncate"> ··· 229 229 :aria-label="$t('package.access.revoke_access', { name: collab.displayName })" 230 230 @click="handleRevokeAccess(collab.name)" 231 231 > 232 - <span class="i-carbon-close w-3.5 h-3.5" aria-hidden="true" /> 232 + <span class="i-lucide:x w-3.5 h-3.5" aria-hidden="true" /> 233 233 </button> 234 234 <span v-else class="text-xs text-fg-subtle"> {{ $t('package.access.owner') }} </span> 235 235 </li> ··· 289 289 :aria-label="$t('package.access.cancel_grant')" 290 290 @click="showGrantAccess = false" 291 291 > 292 - <span class="i-carbon-close w-4 h-4" aria-hidden="true" /> 292 + <span class="i-lucide:x w-4 h-4" aria-hidden="true" /> 293 293 </button> 294 294 </div> 295 295 </form>
+2 -2
app/components/Package/Card.vue
··· 118 118 <div class="flex items-center gap-1.5"> 119 119 <dt class="sr-only">{{ $t('package.card.weekly_downloads') }}</dt> 120 120 <dd class="flex items-center gap-1.5"> 121 - <span class="i-carbon:chart-line w-3.5 h-3.5" aria-hidden="true" /> 121 + <span class="i-lucide:chart-line w-3.5 h-3.5" aria-hidden="true" /> 122 122 <span class="font-mono">{{ $n(result.downloads.weekly) }}/w</span> 123 123 </dd> 124 124 </div> ··· 152 152 v-if="result.downloads?.weekly" 153 153 class="text-fg-subtle gap-2 flex items-center justify-end" 154 154 > 155 - <span class="i-carbon:chart-line w-3.5 h-3.5" aria-hidden="true" /> 155 + <span class="i-lucide:chart-line w-3.5 h-3.5" aria-hidden="true" /> 156 156 <span class="font-mono text-xs"> 157 157 {{ $n(result.downloads.weekly) }} {{ $t('common.per_week') }} 158 158 </span>
+5 -5
app/components/Package/ClaimPackageModal.vue
··· 158 158 <div 159 159 class="flex items-center gap-3 p-4 bg-green-500/10 border border-green-500/20 rounded-lg" 160 160 > 161 - <span class="i-carbon-checkmark-filled text-green-500 w-6 h-6" aria-hidden="true" /> 161 + <span class="i-lucide:check-filled text-green-500 w-6 h-6" aria-hidden="true" /> 162 162 <div> 163 163 <p class="font-mono text-sm text-fg">{{ $t('claim.modal.success') }}</p> 164 164 <p class="text-xs text-fg-muted"> ··· 226 226 v-if="checkResult.available" 227 227 class="flex items-center gap-3 p-4 bg-green-500/10 border border-green-500/20 rounded-lg" 228 228 > 229 - <span class="i-carbon-checkmark-filled text-green-500 w-5 h-5" aria-hidden="true" /> 229 + <span class="i-lucide:check-filled text-green-500 w-5 h-5" aria-hidden="true" /> 230 230 <p class="font-mono text-sm text-fg">{{ $t('claim.modal.available') }}</p> 231 231 </div> 232 232 ··· 234 234 v-else 235 235 class="flex items-center gap-3 p-4 bg-red-500/10 border border-red-500/20 rounded-lg" 236 236 > 237 - <span class="i-carbon-close-filled text-red-500 w-5 h-5" aria-hidden="true" /> 237 + <span class="i-lucide:x-filled text-red-500 w-5 h-5" aria-hidden="true" /> 238 238 <p class="font-mono text-sm text-fg">{{ $t('claim.modal.taken') }}</p> 239 239 </div> 240 240 </div> ··· 266 266 > 267 267 <span 268 268 v-if="pkg.similarity === 'exact-match'" 269 - class="i-carbon-warning-filled text-red-500 w-4 h-4 mt-0.5 shrink-0" 269 + class="i-lucide:circle-alert text-red-500 w-4 h-4 mt-0.5 shrink-0" 270 270 aria-hidden="true" 271 271 /> 272 272 <span 273 273 v-else-if="pkg.similarity === 'very-similar'" 274 - class="i-carbon-warning text-yellow-500 w-4 h-4 mt-0.5 shrink-0" 274 + class="i-lucide:circle-alert text-yellow-500 w-4 h-4 mt-0.5 shrink-0" 275 275 aria-hidden="true" 276 276 /> 277 277 <span v-else class="w-4 h-4 shrink-0" />
+1 -1
app/components/Package/Compatibility.vue
··· 23 23 } 24 24 25 25 function getIcon(engine: string): string { 26 - return engineIcons[engine] || 'i-carbon:code' 26 + return engineIcons[engine] || 'i-lucide:code' 27 27 } 28 28 29 29 const sortedEngines = computed(() => {
+3 -3
app/components/Package/Dependencies.vue
··· 102 102 aria-hidden="true" 103 103 :text="getOutdatedTooltip(outdatedDeps[dep], $t)" 104 104 > 105 - <span class="i-carbon:warning-alt w-3 h-3" /> 105 + <span class="i-lucide:circle-alert w-3 h-3" /> 106 106 </TooltipApp> 107 107 <LinkBase 108 108 v-if="getVulnerableDepInfo(dep)" ··· 110 110 class="shrink-0" 111 111 :class="SEVERITY_TEXT_COLORS[getHighestSeverity(getVulnerableDepInfo(dep)!.counts)]" 112 112 :title="`${getVulnerableDepInfo(dep)!.counts.total} vulnerabilities`" 113 - classicon="i-carbon:security" 113 + classicon="i-lucide:shield-check" 114 114 > 115 115 <span class="sr-only">{{ $t('package.dependencies.view_vulnerabilities') }}</span> 116 116 </LinkBase> ··· 119 119 :to="packageRoute(dep, getDeprecatedDepInfo(dep)!.version)" 120 120 class="shrink-0 text-purple-700 dark:text-purple-500" 121 121 :title="getDeprecatedDepInfo(dep)!.message" 122 - classicon="i-carbon:warning-hex" 122 + classicon="i-lucide:octagon-alert" 123 123 > 124 124 <span class="sr-only">{{ $t('package.deprecated.label') }}</span> 125 125 </LinkBase>
+2 -2
app/components/Package/DeprecatedTree.vue
··· 54 54 @click="isExpanded = !isExpanded" 55 55 > 56 56 <span class="flex items-center gap-2 min-w-0"> 57 - <span class="i-carbon-warning-hex w-4 h-4 shrink-0" aria-hidden="true" /> 57 + <span class="i-lucide:octagon-alert w-4 h-4 shrink-0" aria-hidden="true" /> 58 58 <span class="font-mono text-sm font-medium truncate"> 59 59 {{ $t('package.deprecated.tree_found', analysisData!.deprecatedPackages.length) }} 60 60 </span> 61 61 </span> 62 62 <span 63 - class="i-carbon-chevron-down w-4 h-4 transition-transform duration-200 shrink-0" 63 + class="i-lucide:chevron-down w-4 h-4 transition-transform duration-200 shrink-0" 64 64 :class="{ 'rotate-180': isExpanded }" 65 65 aria-hidden="true" 66 66 />
+3 -3
app/components/Package/InstallScripts.vue
··· 61 61 <CollapsibleSection 62 62 :title="$t('package.install_scripts.title')" 63 63 id="installScripts" 64 - icon="i-carbon:warning-alt w-3 h-3 text-yellow-500" 64 + icon="i-lucide:circle-alert w-3 h-3 text-yellow-500" 65 65 > 66 66 <!-- Script list: name as label, content below --> 67 67 <dl class="space-y-2 m-0"> ··· 99 99 @click="isExpanded = !isExpanded" 100 100 > 101 101 <span 102 - class="i-carbon:chevron-right rtl-flip w-3 h-3 transition-transform duration-200" 102 + class="i-lucide:chevron-right rtl-flip w-3 h-3 transition-transform duration-200" 103 103 :class="{ 'rotate-90': isExpanded }" 104 104 aria-hidden="true" 105 105 /> ··· 139 139 aria-hidden="true" 140 140 :text="getOutdatedTooltip(outdatedNpxDeps[dep], $t)" 141 141 > 142 - <span class="i-carbon:warning-alt w-3 h-3" /> 142 + <span class="i-lucide:circle-alert w-3 h-3" /> 143 143 </TooltipApp> 144 144 <span 145 145 class="font-mono text-xs text-end truncate"
+1 -1
app/components/Package/ListControls.vue
··· 59 59 class="absolute h-full w-10 flex items-center justify-center text-fg-subtle pointer-events-none" 60 60 aria-hidden="true" 61 61 > 62 - <div class="i-carbon:search w-4 h-4" /> 62 + <div class="i-lucide:search w-4 h-4" /> 63 63 </div> 64 64 <InputBase 65 65 id="package-filter"
+2 -2
app/components/Package/ListToolbar.vue
··· 194 194 class="w-4 h-4 block transition-transform duration-200" 195 195 :class=" 196 196 currentSort.direction === 'asc' 197 - ? 'i-carbon-sort-ascending' 198 - : 'i-carbon-sort-descending' 197 + ? 'i-lucide:arrow-down-narrow-wide' 198 + : 'i-lucide:arrow-down-wide-narrow' 199 199 " 200 200 aria-hidden="true" 201 201 />
+2 -2
app/components/Package/Maintainers.vue
··· 228 228 " 229 229 @click="handleRemoveOwner(maintainer.name)" 230 230 > 231 - <span class="i-carbon-close w-3.5 h-3.5" aria-hidden="true" /> 231 + <span class="i-lucide:x w-3.5 h-3.5" aria-hidden="true" /> 232 232 </ButtonBase> 233 233 </li> 234 234 </ul> ··· 270 270 <ButtonBase 271 271 :aria-label="$t('package.maintainers.cancel_add')" 272 272 @click="showAddOwner = false" 273 - classicon="i-carbon-close" 273 + classicon="i-lucide:x" 274 274 /> 275 275 </form> 276 276 </div>
+2 -2
app/components/Package/ManagerSelect.vue
··· 111 111 > 112 112 </template> 113 113 <span 114 - class="i-carbon:chevron-down w-3 h-3" 114 + class="i-lucide:chevron-down w-3 h-3" 115 115 :class="[ 116 116 { 'rotate-180': isOpen }, 117 117 prefersReducedMotion ? '' : 'transition-transform duration-200', ··· 162 162 <span>{{ pm.label }}</span> 163 163 <span 164 164 v-if="selectedPM === pm.id" 165 - class="i-carbon:checkmark w-3 h-3 text-accent ms-auto" 165 + class="i-lucide:check w-3 h-3 text-accent ms-auto" 166 166 aria-hidden="true" 167 167 /> 168 168 </li>
+4 -14
app/components/Package/MetricsBadges.vue
··· 63 63 variant="button-secondary" 64 64 size="small" 65 65 :to="typesHref" 66 - classicon="i-carbon:checkmark" 66 + classicon="i-lucide:check" 67 67 > 68 68 {{ $t('package.metrics.types_label') }} 69 69 </LinkBase> ··· 72 72 :variant="hasTypes && !isLoading ? 'default' : 'ghost'" 73 73 :tabindex="0" 74 74 :classicon=" 75 - isLoading 76 - ? 'i-carbon:circle-dash motion-safe:animate-spin' 77 - : hasTypes 78 - ? 'i-carbon:checkmark' 79 - : 'i-carbon:close' 75 + isLoading ? 'i-svg-spinners:ring-resize ' : hasTypes ? 'i-lucide:check' : 'i-lucide:x' 80 76 " 81 77 > 82 78 {{ $t('package.metrics.types_label') }} ··· 94 90 tabindex="0" 95 91 :variant="hasEsm && !isLoading ? 'default' : 'ghost'" 96 92 :classicon=" 97 - isLoading 98 - ? 'i-carbon:circle-dash motion-safe:animate-spin' 99 - : hasEsm 100 - ? 'i-carbon:checkmark' 101 - : 'i-carbon:close' 93 + isLoading ? 'i-svg-spinners:ring-resize ' : hasEsm ? 'i-lucide:check' : 'i-lucide:x' 102 94 " 103 95 > 104 96 ESM ··· 112 104 <TagStatic 113 105 tabindex="0" 114 106 :variant="isLoading ? 'ghost' : 'default'" 115 - :classicon=" 116 - isLoading ? 'i-carbon:circle-dash motion-safe:animate-spin' : 'i-carbon:checkmark' 117 - " 107 + :classicon="isLoading ? 'i-svg-spinners:ring-resize ' : 'i-lucide:check'" 118 108 > 119 109 CJS 120 110 </TagStatic>
+4 -4
app/components/Package/Playgrounds.vue
··· 16 16 'vue-playground': 'i-simple-icons:vuedotjs', 17 17 'nuxt-new': 'i-simple-icons:nuxtdotjs', 18 18 'vite-new': 'i-simple-icons:vite', 19 - 'jsfiddle': 'i-carbon:code', 19 + 'jsfiddle': 'i-lucide:code', 20 20 } 21 21 22 22 // Map provider id to color class ··· 33 33 } 34 34 35 35 function getIcon(provider: string): string { 36 - return providerIcons[provider] || 'i-carbon:play' 36 + return providerIcons[provider] || 'i-lucide:play' 37 37 } 38 38 39 39 function getColor(provider: string): string { ··· 145 145 @keydown="handleKeydown" 146 146 > 147 147 <span class="flex items-center gap-2"> 148 - <span class="i-carbon:play w-4 h-4 shrink-0 text-fg-muted" aria-hidden="true" /> 148 + <span class="i-lucide:play w-4 h-4 shrink-0 text-fg-muted" aria-hidden="true" /> 149 149 <span class="text-fg-muted" 150 150 >{{ $t('package.playgrounds.choose') }} ({{ links.length }})</span 151 151 > 152 152 </span> 153 153 <span 154 - class="i-carbon:chevron-down w-3 h-3 text-fg-subtle transition-transform duration-200 motion-reduce:transition-none" 154 + class="i-lucide:chevron-down w-3 h-3 text-fg-subtle transition-transform duration-200 motion-reduce:transition-none" 155 155 :class="{ 'rotate-180': isOpen }" 156 156 aria-hidden="true" 157 157 />
+5 -5
app/components/Package/Replacement.vue
··· 21 21 class="border border-amber-600/40 bg-amber-500/10 rounded-lg px-3 py-2 text-base text-amber-800 dark:text-amber-400" 22 22 > 23 23 <h2 class="font-medium mb-1 flex items-center gap-2"> 24 - <span class="i-carbon-idea w-4 h-4" aria-hidden="true" /> 24 + <span class="i-lucide:lightbulb w-4 h-4" aria-hidden="true" /> 25 25 {{ $t('package.replacement.title') }} 26 26 </h2> 27 27 <p class="text-sm m-0"> ··· 50 50 class="inline-flex items-center gap-1 ms-1 underline underline-offset-4 decoration-amber-600/60 dark:decoration-amber-400/50 hover:decoration-fg transition-colors" 51 51 > 52 52 {{ $t('package.replacement.community') }} 53 - <span class="i-carbon-launch w-3 h-3" aria-hidden="true" /> 53 + <span class="i-lucide:external-link w-3 h-3" aria-hidden="true" /> 54 54 </a> 55 55 </template> 56 56 <template #replacement> ··· 70 70 class="inline-flex items-center gap-1 ms-1 underline underline-offset-4 decoration-amber-600/60 dark:decoration-amber-400/50 hover:decoration-fg transition-colors" 71 71 > 72 72 {{ $t('package.replacement.community') }} 73 - <span class="i-carbon-launch w-3 h-3" aria-hidden="true" /> 73 + <span class="i-lucide:external-link w-3 h-3" aria-hidden="true" /> 74 74 </a> 75 75 </template> 76 76 </i18n-t> ··· 85 85 class="inline-flex items-center gap-1 ms-1 underline underline-offset-4 decoration-amber-600/60 dark:decoration-amber-400/50 hover:decoration-fg transition-colors" 86 86 > 87 87 {{ $t('package.replacement.mdn') }} 88 - <span class="i-carbon-launch w-3 h-3" aria-hidden="true" /> 88 + <span class="i-lucide:external-link w-3 h-3" aria-hidden="true" /> 89 89 </a> 90 90 <a 91 91 v-if="docPath" ··· 95 95 class="inline-flex items-center gap-1 ms-1 underline underline-offset-4 decoration-amber-600/60 dark:decoration-amber-400/50 hover:decoration-fg transition-colors" 96 96 > 97 97 {{ $t('package.replacement.learn_more') }} 98 - <span class="i-carbon-launch w-3 h-3" aria-hidden="true" /> 98 + <span class="i-lucide:external-link w-3 h-3" aria-hidden="true" /> 99 99 </a> 100 100 </p> 101 101 </div>
+8 -8
app/components/Package/Skeleton.vue
··· 208 208 class="text-xs font-mono text-fg-subtle uppercase tracking-wider flex items-center gap-2" 209 209 > 210 210 <span class="w-4 h-4 flex items-center justify-center shrink-0"> 211 - <span class="i-carbon:chevron-down w-3 h-3" aria-hidden="true" /> 211 + <span class="i-lucide:chevron-down w-3 h-3" aria-hidden="true" /> 212 212 </span> 213 213 {{ $t('package.downloads.title') }} 214 214 </h2> ··· 245 245 class="text-xs font-mono text-fg-subtle uppercase tracking-wider flex items-center gap-2" 246 246 > 247 247 <span class="w-4 h-4 flex items-center justify-center shrink-0"> 248 - <span class="i-carbon:chevron-down w-3 h-3" aria-hidden="true" /> 248 + <span class="i-lucide:chevron-down w-3 h-3" aria-hidden="true" /> 249 249 </span> 250 250 {{ $t('package.compatibility') }} 251 251 </h2> ··· 265 265 class="text-xs font-mono text-fg-subtle uppercase tracking-wider flex items-center gap-2" 266 266 > 267 267 <span class="w-4 h-4 flex items-center justify-center shrink-0"> 268 - <span class="i-carbon:chevron-down w-3 h-3" aria-hidden="true" /> 268 + <span class="i-lucide:chevron-down w-3 h-3" aria-hidden="true" /> 269 269 </span> 270 270 {{ $t('package.skeleton.versions') }} 271 271 </h2> ··· 274 274 <!-- Version rows with expand chevron + version + tag + date --> 275 275 <div v-for="i in 4" :key="i" class="flex items-center gap-2 px-1"> 276 276 <span class="w-4 h-4 flex items-center justify-center shrink-0"> 277 - <span class="i-carbon:chevron-right w-3 h-3 text-fg-subtle" aria-hidden="true" /> 277 + <span class="i-lucide:chevron-right w-3 h-3 text-fg-subtle" aria-hidden="true" /> 278 278 </span> 279 279 <div class="flex-1 py-1.5 min-w-0 flex gap-2 justify-between items-center"> 280 280 <div> ··· 290 290 <!-- Other versions row --> 291 291 <div class="flex items-center gap-2 p-1"> 292 292 <span class="w-4 h-4 flex items-center justify-center shrink-0"> 293 - <span class="i-carbon:chevron-right w-3 h-3 text-fg-subtle" aria-hidden="true" /> 293 + <span class="i-lucide:chevron-right w-3 h-3 text-fg-subtle" aria-hidden="true" /> 294 294 </span> 295 295 <SkeletonInline class="h-3 w-28" /> 296 296 </div> ··· 304 304 class="text-xs font-mono text-fg-subtle uppercase tracking-wider flex items-center gap-2" 305 305 > 306 306 <span class="w-4 h-4 flex items-center justify-center shrink-0"> 307 - <span class="i-carbon:chevron-down w-3 h-3" aria-hidden="true" /> 307 + <span class="i-lucide:chevron-down w-3 h-3" aria-hidden="true" /> 308 308 </span> 309 309 {{ $t('package.skeleton.dependencies') }} 310 310 </h2> ··· 336 336 class="text-xs font-mono text-fg-subtle uppercase tracking-wider flex items-center gap-2" 337 337 > 338 338 <span class="w-4 h-4 flex items-center justify-center shrink-0"> 339 - <span class="i-carbon:chevron-down w-3 h-3" aria-hidden="true" /> 339 + <span class="i-lucide:chevron-down w-3 h-3" aria-hidden="true" /> 340 340 </span> 341 341 {{ $t('package.skeleton.keywords') }} 342 342 </h2> ··· 358 358 class="text-xs font-mono text-fg-subtle uppercase tracking-wider flex items-center gap-2" 359 359 > 360 360 <span class="w-4 h-4 flex items-center justify-center shrink-0"> 361 - <span class="i-carbon:chevron-down w-3 h-3" aria-hidden="true" /> 361 + <span class="i-lucide:chevron-down w-3 h-3" aria-hidden="true" /> 362 362 </span> 363 363 {{ $t('package.skeleton.maintainers') }} 364 364 </h2>
+8 -8
app/components/Package/SkillsModal.vue
··· 110 110 class="inline-flex items-center gap-1 text-xs text-fg-subtle hover:text-fg transition-colors shrink-0" 111 111 > 112 112 {{ $t('package.skills.learn_more') }} 113 - <span class="i-carbon:arrow-right w-3 h-3" /> 113 + <span class="i-lucide:arrow-right w-3 h-3" /> 114 114 </a> 115 115 </div> 116 116 ··· 159 159 @click="toggleSkill(skill.dirName)" 160 160 > 161 161 <span 162 - class="i-carbon:chevron-right w-3 h-3 text-fg-subtle shrink-0 transition-transform duration-200" 162 + class="i-lucide:chevron-right w-3 h-3 text-fg-subtle shrink-0 transition-transform duration-200" 163 163 :class="{ 'rotate-90': expandedSkills.has(skill.dirName) }" 164 164 aria-hidden="true" 165 165 /> ··· 171 171 :text="getWarningTooltip(skill)" 172 172 to="#skills-modal" 173 173 > 174 - <span class="i-carbon:warning w-3.5 h-3.5 text-amber-500" /> 174 + <span class="i-lucide:circle-alert w-3.5 h-3.5 text-amber-500" /> 175 175 </TooltipApp> 176 176 </button> 177 177 ··· 193 193 <!-- File counts & warnings --> 194 194 <div class="flex flex-wrap items-center gap-x-3 gap-y-1 text-xs"> 195 195 <span v-if="skill.fileCounts?.scripts" class="text-fg-subtle"> 196 - <span class="i-carbon:script size-3 align-[-2px] me-0.5" />{{ 196 + <span class="i-lucide:file-code size-3 align-[-2px] me-0.5" />{{ 197 197 $t( 198 198 'package.skills.file_counts.scripts', 199 199 { count: skill.fileCounts.scripts }, ··· 202 202 }} 203 203 </span> 204 204 <span v-if="skill.fileCounts?.references" class="text-fg-subtle"> 205 - <span class="i-carbon:document size-3 align-[-2px] me-0.5" />{{ 205 + <span class="i-lucide:file-text size-3 align-[-2px] me-0.5" />{{ 206 206 $t( 207 207 'package.skills.file_counts.refs', 208 208 { count: skill.fileCounts.references }, ··· 211 211 }} 212 212 </span> 213 213 <span v-if="skill.fileCounts?.assets" class="text-fg-subtle"> 214 - <span class="i-carbon:image size-3 align-[-2px] me-0.5" />{{ 214 + <span class="i-lucide:image size-3 align-[-2px] me-0.5" />{{ 215 215 $t( 216 216 'package.skills.file_counts.assets', 217 217 { count: skill.fileCounts.assets }, ··· 221 221 </span> 222 222 <template v-for="warning in skill.warnings" :key="warning.message"> 223 223 <span class="text-amber-500"> 224 - <span class="i-carbon:warning size-3 align-[-2px] me-0.5" />{{ 224 + <span class="i-lucide:circle-alert size-3 align-[-2px] me-0.5" />{{ 225 225 warning.message 226 226 }} 227 227 </span> ··· 234 234 class="inline-flex items-center gap-1 text-xs text-fg-subtle hover:text-fg transition-colors" 235 235 @click.stop 236 236 > 237 - <span class="i-carbon:code size-3" />{{ $t('package.skills.view_source') }} 237 + <span class="i-lucide:code size-3" />{{ $t('package.skills.view_source') }} 238 238 </NuxtLink> 239 239 </div> 240 240 </div>
+18 -6
app/components/Package/Table.vue
··· 139 139 <template v-if="isSortable('name')"> 140 140 <span 141 141 v-if="isColumnSorted('name')" 142 - class="i-carbon-caret-down w-3 h-3" 142 + class="i-lucide:chevron-down w-3 h-3" 143 143 :class="getSortDirection('name') === 'asc' ? 'rotate-180' : ''" 144 144 aria-hidden="true" 145 145 /> 146 - <span v-else class="i-carbon-caret-sort w-3 h-3 opacity-30" aria-hidden="true" /> 146 + <span 147 + v-else 148 + class="i-lucide:chevrons-up-down w-3 h-3 opacity-30" 149 + aria-hidden="true" 150 + /> 147 151 </template> 148 152 </span> 149 153 </th> ··· 189 193 <template v-if="isSortable('downloads')"> 190 194 <span 191 195 v-if="isColumnSorted('downloads')" 192 - class="i-carbon-caret-down w-3 h-3" 196 + class="i-lucide:caret-down w-3 h-3" 193 197 :class="getSortDirection('downloads') === 'asc' ? 'rotate-180' : ''" 194 198 aria-hidden="true" 195 199 /> 196 - <span v-else class="i-carbon-caret-sort w-3 h-3 opacity-30" aria-hidden="true" /> 200 + <span 201 + v-else 202 + class="i-lucide:chevrons-up-down w-3 h-3 opacity-30" 203 + aria-hidden="true" 204 + /> 197 205 </template> 198 206 </span> 199 207 </th> ··· 223 231 <template v-if="isSortable('updated')"> 224 232 <span 225 233 v-if="isColumnSorted('updated')" 226 - class="i-carbon-caret-down w-3 h-3" 234 + class="i-lucide:caret-down w-3 h-3" 227 235 :class="getSortDirection('updated') === 'asc' ? 'rotate-180' : ''" 228 236 aria-hidden="true" 229 237 /> 230 - <span v-else class="i-carbon-caret-sort w-3 h-3 opacity-30" aria-hidden="true" /> 238 + <span 239 + v-else 240 + class="i-lucide:chevrons-up-down w-3 h-3 opacity-30" 241 + aria-hidden="true" 242 + /> 231 243 </template> 232 244 </span> 233 245 </th>
+2 -2
app/components/Package/TableRow.vue
··· 187 187 <!-- Security --> 188 188 <td v-if="isColumnVisible('security')" class="py-2 px-3"> 189 189 <span v-if="result.flags?.insecure" class="text-syntax-kw"> 190 - <span class="i-carbon-warning w-4 h-4" aria-hidden="true" /> 190 + <span class="i-lucide:circle-alert w-4 h-4" aria-hidden="true" /> 191 191 <span class="sr-only">{{ $t('filters.table.security_warning') }}</span> 192 192 </span> 193 193 <span v-else-if="result.flags !== undefined" class="text-provider-nuxt"> 194 - <span class="i-carbon-checkmark w-4 h-4" aria-hidden="true" /> 194 + <span class="i-lucide:check w-4 h-4" aria-hidden="true" /> 195 195 <span class="sr-only">{{ $t('filters.table.secure') }}</span> 196 196 </span> 197 197 <span v-else class="text-fg-subtle"> - </span>
+15 -27
app/components/Package/TrendsChart.vue
··· 1490 1490 </label> 1491 1491 <div class="relative flex items-center"> 1492 1492 <span 1493 - class="absolute inset-is-2 i-carbon:calendar w-4 h-4 text-fg-subtle shrink-0 pointer-events-none" 1493 + class="absolute inset-is-2 i-lucide:calendar w-4 h-4 text-fg-subtle shrink-0 pointer-events-none" 1494 1494 aria-hidden="true" 1495 1495 /> 1496 1496 <InputBase ··· 1510 1510 </label> 1511 1511 <div class="relative flex items-center"> 1512 1512 <span 1513 - class="absolute inset-is-2 i-carbon:calendar w-4 h-4 text-fg-subtle shrink-0 pointer-events-none" 1513 + class="absolute inset-is-2 i-lucide:calendar w-4 h-4 text-fg-subtle shrink-0 pointer-events-none" 1514 1514 aria-hidden="true" 1515 1515 /> 1516 1516 <InputBase ··· 1532 1532 class="self-end flex items-center justify-center px-2.5 py-1.75 border border-transparent rounded-md text-fg-subtle hover:text-fg transition-colors hover:border-border focus-visible:outline-accent/70 sm:mb-0" 1533 1533 @click="resetDateRange" 1534 1534 > 1535 - <span class="i-carbon:reset w-5 h-5" aria-hidden="true" /> 1535 + <span class="i-lucide:undo-2 w-5 h-5" aria-hidden="true" /> 1536 1536 </button> 1537 1537 </div> 1538 1538 </div> ··· 1661 1661 </template> 1662 1662 1663 1663 <template #menuIcon="{ isOpen }"> 1664 - <span v-if="isOpen" class="i-carbon:close w-6 h-6" aria-hidden="true" /> 1665 - <span v-else class="i-carbon:overflow-menu-vertical w-6 h-6" aria-hidden="true" /> 1664 + <span v-if="isOpen" class="i-lucide:x w-6 h-6" aria-hidden="true" /> 1665 + <span v-else class="i-lucide:ellipsis-vertical w-6 h-6" aria-hidden="true" /> 1666 1666 </template> 1667 1667 <template #optionCsv> 1668 - <span 1669 - class="i-carbon:csv w-6 h-6 text-fg-subtle" 1670 - style="pointer-events: none" 1671 - aria-hidden="true" 1672 - /> 1668 + <span class="text-fg-subtle font-mono pointer-events-none">CSV</span> 1673 1669 </template> 1674 1670 <template #optionImg> 1675 - <span 1676 - class="i-carbon:png w-6 h-6 text-fg-subtle" 1677 - style="pointer-events: none" 1678 - aria-hidden="true" 1679 - /> 1671 + <span class="text-fg-subtle font-mono pointer-events-none">PNG</span> 1680 1672 </template> 1681 1673 <template #optionSvg> 1682 - <span 1683 - class="i-carbon:svg w-6 h-6 text-fg-subtle" 1684 - style="pointer-events: none" 1685 - aria-hidden="true" 1686 - /> 1674 + <span class="text-fg-subtle font-mono pointer-events-none">SVG</span> 1687 1675 </template> 1688 1676 1689 1677 <template #annotator-action-close> 1690 1678 <span 1691 - class="i-carbon:close w-6 h-6 text-fg-subtle" 1679 + class="i-lucide:x w-6 h-6 text-fg-subtle" 1692 1680 style="pointer-events: none" 1693 1681 aria-hidden="true" 1694 1682 /> 1695 1683 </template> 1696 1684 <template #annotator-action-color="{ color }"> 1697 - <span class="i-carbon:color-palette w-6 h-6" :style="{ color }" aria-hidden="true" /> 1685 + <span class="i-lucide:palette w-6 h-6" :style="{ color }" aria-hidden="true" /> 1698 1686 </template> 1699 1687 <template #annotator-action-undo> 1700 1688 <span 1701 - class="i-carbon:undo w-6 h-6 text-fg-subtle" 1689 + class="i-lucide:undo-2 w-6 h-6 text-fg-subtle" 1702 1690 style="pointer-events: none" 1703 1691 aria-hidden="true" 1704 1692 /> 1705 1693 </template> 1706 1694 <template #annotator-action-redo> 1707 1695 <span 1708 - class="i-carbon:redo w-6 h-6 text-fg-subtle" 1696 + class="i-lucide:redo-2 w-6 h-6 text-fg-subtle" 1709 1697 style="pointer-events: none" 1710 1698 aria-hidden="true" 1711 1699 /> 1712 1700 </template> 1713 1701 <template #annotator-action-delete> 1714 1702 <span 1715 - class="i-carbon:trash-can w-6 h-6 text-fg-subtle" 1703 + class="i-lucide:trash w-6 h-6 text-fg-subtle" 1716 1704 style="pointer-events: none" 1717 1705 aria-hidden="true" 1718 1706 /> ··· 1720 1708 <template #optionAnnotator="{ isAnnotator }"> 1721 1709 <span 1722 1710 v-if="isAnnotator" 1723 - class="i-carbon:edit-off w-6 h-6 text-fg-subtle" 1711 + class="i-lucide:pen-off w-6 h-6 text-fg-subtle" 1724 1712 style="pointer-events: none" 1725 1713 aria-hidden="true" 1726 1714 /> 1727 1715 <span 1728 1716 v-else 1729 - class="i-carbon:edit w-6 h-6 text-fg-subtle" 1717 + class="i-lucide:pen w-6 h-6 text-fg-subtle" 1730 1718 style="pointer-events: none" 1731 1719 aria-hidden="true" 1732 1720 />
+16 -30
app/components/Package/VersionDistribution.vue
··· 388 388 </label> 389 389 <div class="relative flex items-center"> 390 390 <span 391 - class="absolute inset-is-2 i-carbon:calendar w-4 h-4 text-fg-subtle shrink-0 pointer-events-none" 391 + class="absolute inset-is-2 i-lucide:calendar w-4 h-4 text-fg-subtle shrink-0 pointer-events-none" 392 392 aria-hidden="true" 393 393 /> 394 394 <InputBase ··· 419 419 </label> 420 420 <div class="relative flex items-center"> 421 421 <span 422 - class="absolute inset-is-2 i-carbon:calendar w-4 h-4 text-fg-subtle shrink-0 pointer-events-none" 422 + class="absolute inset-is-2 i-lucide:calendar w-4 h-4 text-fg-subtle shrink-0 pointer-events-none" 423 423 aria-hidden="true" 424 424 /> 425 425 <InputBase ··· 523 523 524 524 <!-- Contextual menu icon --> 525 525 <template #menuIcon="{ isOpen }"> 526 - <span v-if="isOpen" class="i-carbon:close w-6 h-6" aria-hidden="true" /> 527 - <span v-else class="i-carbon:overflow-menu-vertical w-6 h-6" aria-hidden="true" /> 526 + <span v-if="isOpen" class="i-lucide:x w-6 h-6" aria-hidden="true" /> 527 + <span v-else class="i-lucide:ellipsis-vertical w-6 h-6" aria-hidden="true" /> 528 528 </template> 529 529 530 530 <!-- Export options --> 531 531 <template #optionCsv> 532 - <span 533 - class="i-carbon:csv w-6 h-6 text-fg-subtle" 534 - style="pointer-events: none" 535 - aria-hidden="true" 536 - /> 532 + <span class="text-fg-subtle font-mono pointer-events-none">CSV</span> 537 533 </template> 538 - 539 534 <template #optionImg> 540 - <span 541 - class="i-carbon:png w-6 h-6 text-fg-subtle" 542 - style="pointer-events: none" 543 - aria-hidden="true" 544 - /> 535 + <span class="text-fg-subtle font-mono pointer-events-none">PNG</span> 545 536 </template> 546 - 547 537 <template #optionSvg> 548 - <span 549 - class="i-carbon:svg w-6 h-6 text-fg-subtle" 550 - style="pointer-events: none" 551 - aria-hidden="true" 552 - /> 538 + <span class="text-fg-subtle font-mono pointer-events-none">SVG</span> 553 539 </template> 554 540 555 541 <!-- Annotator action icons --> 556 542 <template #annotator-action-close> 557 543 <span 558 - class="i-carbon:close w-6 h-6 text-fg-subtle" 544 + class="i-lucide:x w-6 h-6 text-fg-subtle" 559 545 style="pointer-events: none" 560 546 aria-hidden="true" 561 547 /> 562 548 </template> 563 549 564 550 <template #annotator-action-color="{ color }"> 565 - <span class="i-carbon:color-palette w-6 h-6" :style="{ color }" aria-hidden="true" /> 551 + <span class="i-lucide:palette w-6 h-6" :style="{ color }" aria-hidden="true" /> 566 552 </template> 567 553 568 554 <template #annotator-action-undo> 569 555 <span 570 - class="i-carbon:undo w-6 h-6 text-fg-subtle" 556 + class="i-lucide:undo-2 w-6 h-6 text-fg-subtle" 571 557 style="pointer-events: none" 572 558 aria-hidden="true" 573 559 /> ··· 575 561 576 562 <template #annotator-action-redo> 577 563 <span 578 - class="i-carbon:redo w-6 h-6 text-fg-subtle" 564 + class="i-lucide:redo-2 w-6 h-6 text-fg-subtle" 579 565 style="pointer-events: none" 580 566 aria-hidden="true" 581 567 /> ··· 583 569 584 570 <template #annotator-action-delete> 585 571 <span 586 - class="i-carbon:trash-can w-6 h-6 text-fg-subtle" 572 + class="i-lucide:trash w-6 h-6 text-fg-subtle" 587 573 style="pointer-events: none" 588 574 aria-hidden="true" 589 575 /> ··· 592 578 <template #optionAnnotator="{ isAnnotator }"> 593 579 <span 594 580 v-if="isAnnotator" 595 - class="i-carbon:edit-off w-6 h-6 text-fg-subtle" 581 + class="i-lucide:pen-off w-6 h-6 text-fg-subtle" 596 582 style="pointer-events: none" 597 583 aria-hidden="true" 598 584 /> 599 585 <span 600 586 v-else 601 - class="i-carbon:edit w-6 h-6 text-fg-subtle" 587 + class="i-lucide:pen w-6 h-6 text-fg-subtle" 602 588 style="pointer-events: none" 603 589 aria-hidden="true" 604 590 /> ··· 614 600 <!-- No-data state --> 615 601 <div v-if="!hasData && !pending && !error" class="flex items-center justify-center h-full"> 616 602 <div class="text-sm text-fg-subtle font-mono text-center flex flex-col items-center gap-2"> 617 - <span class="i-carbon:data-vis-4 w-8 h-8" /> 603 + <span class="i-lucide:database w-8 h-8" /> 618 604 <p>{{ $t('package.trends.no_data') }}</p> 619 605 </div> 620 606 </div> ··· 622 608 <!-- Error state --> 623 609 <div v-if="error" class="flex items-center justify-center h-full" role="alert"> 624 610 <div class="text-sm text-fg-subtle font-mono text-center flex flex-col items-center gap-2"> 625 - <span class="i-carbon:warning-hex w-8 h-8 text-red-400" /> 611 + <span class="i-lucide:octagon-alert w-8 h-8 text-red-400" /> 626 612 <p>{{ error.message }}</p> 627 613 <p class="text-xs">Package: {{ packageName }}</p> 628 614 </div>
+13 -13
app/components/Package/Versions.vue
··· 477 477 variant="secondary" 478 478 class="text-fg-subtle hover:text-fg transition-colors min-w-6 min-h-6 -m-1 p-1 rounded" 479 479 :title="$t('package.downloads.community_distribution')" 480 - classicon="i-carbon:load-balancer-network" 480 + classicon="i-lucide:file-stack" 481 481 @click="openDistributionModal" 482 482 > 483 483 <span class="sr-only">{{ $t('package.downloads.community_distribution') }}</span> ··· 561 561 > 562 562 <span 563 563 v-if="loadingTags.has(row.tag)" 564 - class="i-carbon:rotate-180 w-3 h-3 motion-safe:animate-spin" 564 + class="i-svg-spinners:ring-resize w-3 h-3" 565 565 data-testid="loading-spinner" 566 566 aria-hidden="true" 567 567 /> ··· 569 569 v-else 570 570 class="w-3 h-3 transition-transform duration-200 rtl-flip" 571 571 :class=" 572 - expandedTags.has(row.tag) ? 'i-carbon:chevron-down' : 'i-carbon:chevron-right' 572 + expandedTags.has(row.tag) ? 'i-lucide:chevron-down' : 'i-lucide:chevron-right' 573 573 " 574 574 aria-hidden="true" 575 575 /> ··· 595 595 }) 596 596 : row.primaryVersion.version 597 597 " 598 - :classicon="row.primaryVersion.deprecated ? 'i-carbon-warning-hex' : undefined" 598 + :classicon="row.primaryVersion.deprecated ? 'i-lucide:octagon-alert' : undefined" 599 599 > 600 600 <span dir="ltr" class="block truncate"> 601 601 {{ row.primaryVersion.version }} ··· 659 659 }) 660 660 : v.version 661 661 " 662 - :classicon="v.deprecated ? 'i-carbon-warning-hex' : undefined" 662 + :classicon="v.deprecated ? 'i-lucide:octagon-alert' : undefined" 663 663 > 664 664 <span dir="ltr" class="block truncate"> 665 665 {{ v.version }} ··· 718 718 > 719 719 <span 720 720 v-if="otherVersionsLoading" 721 - class="i-carbon:rotate-180 w-3 h-3 motion-safe:animate-spin" 721 + class="i-svg-spinners:ring-resize w-3 h-3" 722 722 data-testid="loading-spinner" 723 723 aria-hidden="true" 724 724 /> 725 725 <span 726 726 v-else 727 727 class="w-3 h-3 transition-transform duration-200 rtl-flip" 728 - :class="otherVersionsExpanded ? 'i-carbon:chevron-down' : 'i-carbon:chevron-right'" 728 + :class="otherVersionsExpanded ? 'i-lucide:chevron-down' : 'i-lucide:chevron-right'" 729 729 aria-hidden="true" 730 730 /> 731 731 </span> ··· 769 769 }) 770 770 : row.primaryVersion.version 771 771 " 772 - :classicon="row.primaryVersion.deprecated ? 'i-carbon-warning-hex' : undefined" 772 + :classicon="row.primaryVersion.deprecated ? 'i-lucide:octagon-alert' : undefined" 773 773 > 774 774 <span dir="ltr" class="block truncate"> 775 775 {{ row.primaryVersion.version }} ··· 829 829 class="w-3 h-3 transition-transform duration-200 rtl-flip" 830 830 :class=" 831 831 expandedMajorGroups.has(group.groupKey) 832 - ? 'i-carbon:chevron-down' 833 - : 'i-carbon:chevron-right' 832 + ? 'i-lucide:chevron-down' 833 + : 'i-lucide:chevron-right' 834 834 " 835 835 aria-hidden="true" 836 836 /> ··· 853 853 : group.versions[0]?.version 854 854 " 855 855 :classicon=" 856 - group.versions[0]?.deprecated ? 'i-carbon-warning-hex' : undefined 856 + group.versions[0]?.deprecated ? 'i-lucide:octagon-alert' : undefined 857 857 " 858 858 > 859 859 <span dir="ltr" class="block truncate"> ··· 918 918 : group.versions[0]?.version 919 919 " 920 920 :classicon=" 921 - group.versions[0]?.deprecated ? 'i-carbon-warning-hex' : undefined 921 + group.versions[0]?.deprecated ? 'i-lucide:octagon-alert' : undefined 922 922 " 923 923 > 924 924 <span dir="ltr" class="block truncate"> ··· 984 984 }) 985 985 : v.version 986 986 " 987 - :classicon="v.deprecated ? 'i-carbon-warning-hex' : undefined" 987 + :classicon="v.deprecated ? 'i-lucide:octagon-alert' : undefined" 988 988 > 989 989 <span dir="ltr" class="block truncate"> 990 990 {{ v.version }}
+4 -4
app/components/Package/VulnerabilityTree.vue
··· 84 84 @click="isExpanded = !isExpanded" 85 85 > 86 86 <span class="flex items-center gap-2 min-w-0"> 87 - <span class="i-carbon:warning-alt w-4 h-4 shrink-0" aria-hidden="true" /> 87 + <span class="i-lucide:circle-alert w-4 h-4 shrink-0" aria-hidden="true" /> 88 88 <span class="font-mono text-sm font-medium truncate"> 89 89 {{ 90 90 $t( ··· 102 102 <span class="flex items-center gap-2 shrink-0"> 103 103 <span class="text-xs op-90 dark:op-80 hidden sm:inline">{{ summaryText }}</span> 104 104 <span 105 - class="i-carbon:chevron-down w-4 h-4 transition-transform duration-200" 105 + class="i-lucide:chevron-down w-4 h-4 transition-transform duration-200" 106 106 :class="{ 'rotate-180': isExpanded }" 107 107 aria-hidden="true" 108 108 /> ··· 199 199 v-if="vulnTree!.failedQueries" 200 200 class="px-4 py-2 text-xs text-fg-subtle border-t border-border flex items-center gap-2" 201 201 > 202 - <span class="i-carbon:warning w-3 h-3" aria-hidden="true" /> 202 + <span class="i-lucide:circle-alert w-3 h-3" aria-hidden="true" /> 203 203 <span>{{ $t('package.vulnerabilities.packages_failed', vulnTree!.failedQueries) }}</span> 204 204 </div> 205 205 </div> ··· 214 214 <section v-else-if="status === 'error'" aria-labelledby="vuln-tree-error"> 215 215 <div class="rounded-lg border border-border bg-bg-subtle px-4 py-3"> 216 216 <div class="flex items-center gap-2"> 217 - <span class="i-carbon:warning w-4 h-4 text-fg-subtle" aria-hidden="true" /> 217 + <span class="i-lucide:circle-alert w-4 h-4 text-fg-subtle" aria-hidden="true" /> 218 218 <span class="text-sm text-fg-muted"> 219 219 {{ $t('package.vulnerabilities.scan_failed') }} 220 220 </span>
+1 -1
app/components/Package/WeeklyDownloadStats.vue
··· 256 256 @click="openChartModal" 257 257 class="text-fg-subtle hover:text-fg transition-colors duration-200 inline-flex items-center justify-center min-w-6 min-h-6 -m-1 p-1 focus-visible:outline-accent/70 rounded" 258 258 :title="$t('package.downloads.analyze')" 259 - classicon="i-carbon:data-analytics" 259 + classicon="i-lucide:chart-line" 260 260 > 261 261 <span class="sr-only">{{ $t('package.downloads.analyze') }}</span> 262 262 </ButtonBase>
+1 -1
app/components/PackageProvenanceSection.vue
··· 18 18 <div class="space-y-1"> 19 19 <p class="flex items-start gap-2 text-sm text-fg m-0"> 20 20 <span 21 - class="i-lucide-shield-check w-4 h-4 shrink-0 text-emerald-500 mt-0.5" 21 + class="i-lucide:shield-check w-4 h-4 shrink-0 text-emerald-500 mt-0.5" 22 22 aria-hidden="true" 23 23 /> 24 24 <i18n-t keypath="package.provenance_section.built_and_signed_on" tag="span">
+2 -2
app/components/PaginationControls.vue
··· 197 197 :aria-label="$t('filters.pagination.previous')" 198 198 @click="goPrev" 199 199 > 200 - <span class="i-carbon-chevron-left block rtl-flip w-4 h-4" aria-hidden="true" /> 200 + <span class="i-lucide:chevron-left block rtl-flip w-4 h-4" aria-hidden="true" /> 201 201 </button> 202 202 203 203 <!-- Page numbers --> ··· 227 227 :aria-label="$t('filters.pagination.next')" 228 228 @click="goNext" 229 229 > 230 - <span class="i-carbon-chevron-right block rtl-flip w-4 h-4" aria-hidden="true" /> 230 + <span class="i-lucide:chevron-right block rtl-flip w-4 h-4" aria-hidden="true" /> 231 231 </button> 232 232 </nav> 233 233 </div>
+2 -2
app/components/ProvenanceBadge.vue
··· 35 35 class="inline-flex items-center justify-center gap-1 text-xs font-mono text-fg-muted hover:text-fg transition-colors duration-200 min-w-6 min-h-6" 36 36 :title="title" 37 37 > 38 - <span class="i-lucide-shield-check shrink-0" :class="compact ? 'w-3.5 h-3.5' : 'w-4 h-4'" /> 38 + <span class="i-lucide:shield-check shrink-0" :class="compact ? 'w-3.5 h-3.5' : 'w-4 h-4'" /> 39 39 <span v-if="!compact" class="sr-only sm:not-sr-only">{{ 40 40 $t('badges.provenance.verified') 41 41 }}</span> ··· 45 45 class="inline-flex items-center gap-1 text-xs font-mono text-fg-muted" 46 46 :title="title" 47 47 > 48 - <span class="i-lucide-shield-check shrink-0" :class="compact ? 'w-3.5 h-3.5' : 'w-4 h-4'" /> 48 + <span class="i-lucide:shield-check shrink-0" :class="compact ? 'w-3.5 h-3.5' : 'w-4 h-4'" /> 49 49 <span v-if="!compact" class="sr-only sm:not-sr-only">{{ 50 50 $t('badges.provenance.verified') 51 51 }}</span>
+13 -13
app/components/Readme.vue
··· 30 30 const icon = copyTarget.querySelector('span') 31 31 if (!icon) return 32 32 33 - const originalIcon = 'i-carbon:copy' 34 - const successIcon = 'i-carbon:checkmark' 33 + const originalIcon = 'i-lucide:copy' 34 + const successIcon = 'i-lucide:check' 35 35 36 36 icon.classList.remove(originalIcon) 37 37 icon.classList.add(successIcon) ··· 147 147 .readme :deep(a[target='_blank']:not(:has(img))::after) { 148 148 /* I don't know what kind of sorcery this is, but it ensures this icon can't wrap to a new line on its own. */ 149 149 content: '__'; 150 - @apply inline i-carbon:launch rtl-flip ms-1 opacity-50; 150 + @apply inline i-lucide:external-link rtl-flip ms-1 opacity-50; 151 151 } 152 152 153 153 .readme :deep(code) { ··· 313 313 } 314 314 .readme :deep(blockquote[data-callout='note']::after) { 315 315 background-color: #3b82f6; 316 - -webkit-mask: icon('i-lucide-info') no-repeat; 317 - mask: icon('i-lucide-info') no-repeat; 316 + -webkit-mask: icon('i-lucide:info') no-repeat; 317 + mask: icon('i-lucide:info') no-repeat; 318 318 } 319 319 320 320 /* Tip - green */ ··· 328 328 } 329 329 .readme :deep(blockquote[data-callout='tip']::after) { 330 330 background-color: #22c55e; 331 - -webkit-mask: icon('i-lucide-lightbulb') no-repeat; 332 - mask: icon('i-lucide-lightbulb') no-repeat; 331 + -webkit-mask: icon('i-lucide:lightbulb') no-repeat; 332 + mask: icon('i-lucide:lightbulb') no-repeat; 333 333 } 334 334 335 335 /* Important - purple */ ··· 343 343 } 344 344 .readme :deep(blockquote[data-callout='important']::after) { 345 345 background-color: var(--syntax-fn); 346 - -webkit-mask: icon('i-lucide-pin') no-repeat; 347 - mask: icon('i-lucide-pin') no-repeat; 346 + -webkit-mask: icon('i-lucide:pin') no-repeat; 347 + mask: icon('i-lucide:pin') no-repeat; 348 348 } 349 349 350 350 /* Warning - yellow/orange */ ··· 358 358 } 359 359 .readme :deep(blockquote[data-callout='warning']::after) { 360 360 background-color: #eab308; 361 - -webkit-mask: icon('i-lucide-triangle-alert') no-repeat; 362 - mask: icon('i-lucide-triangle-alert') no-repeat; 361 + -webkit-mask: icon('i-lucide:triangle-alert') no-repeat; 362 + mask: icon('i-lucide:triangle-alert') no-repeat; 363 363 } 364 364 365 365 /* Caution - red */ ··· 373 373 } 374 374 .readme :deep(blockquote[data-callout='caution']::after) { 375 375 background-color: #ef4444; 376 - -webkit-mask: icon('i-lucide-circle-alert') no-repeat; 377 - mask: icon('i-lucide-circle-alert') no-repeat; 376 + -webkit-mask: icon('i-lucide:circle-alert') no-repeat; 377 + mask: icon('i-lucide:circle-alert') no-repeat; 378 378 } 379 379 380 380 /* Table wrapper for horizontal scroll on mobile */
+2 -2
app/components/ReadmeTocDropdown.vue
··· 151 151 :aria-controls="listboxId" 152 152 @click="toggle" 153 153 @keydown="handleKeydown" 154 - classicon="i-carbon:list" 154 + classicon="i-lucide:list" 155 155 class="px-2.5" 156 156 block 157 157 > 158 158 <span 159 - class="i-carbon:chevron-down w-3 h-3" 159 + class="i-lucide:chevron-down w-3 h-3" 160 160 :class="[ 161 161 { 'rotate-180': isOpen }, 162 162 prefersReducedMotion ? '' : 'transition-transform duration-200',
+2 -2
app/components/ScrollToTop.client.vue
··· 42 42 :aria-label="$t('common.scroll_to_top')" 43 43 @click="scrollToTop" 44 44 > 45 - <span class="i-carbon:arrow-up w-5 h-5" aria-hidden="true" /> 45 + <span class="i-lucide:arrow-up w-5 h-5" aria-hidden="true" /> 46 46 </button> 47 47 48 48 <!-- JS fallback for browsers without scroll-state support --> ··· 62 62 :aria-label="$t('common.scroll_to_top')" 63 63 @click="scrollToTop" 64 64 > 65 - <span class="i-carbon:arrow-up w-5 h-5" aria-hidden="true" /> 65 + <span class="i-lucide:arrow-up w-5 h-5" aria-hidden="true" /> 66 66 </button> 67 67 </Transition> 68 68 </template>
+4 -4
app/components/SearchProviderToggle.client.vue
··· 30 30 aria-haspopup="true" 31 31 size="small" 32 32 class="border-none w-8 h-8 !px-0 justify-center" 33 - classicon="i-carbon:settings" 33 + classicon="i-lucide:settings" 34 34 @click="isOpen = !isOpen" 35 35 /> 36 36 ··· 64 64 " 65 65 > 66 66 <span 67 - class="i-carbon:catalog w-4 h-4 mt-0.5 shrink-0" 67 + class="i-simple-icons:npm w-4 h-4 mt-0.5 shrink-0" 68 68 :class="searchProviderValue !== 'algolia' ? 'text-accent' : 'text-fg-muted'" 69 69 aria-hidden="true" 70 70 /> ··· 96 96 " 97 97 > 98 98 <span 99 - class="i-carbon:search w-4 h-4 mt-0.5 shrink-0" 99 + class="i-simple-icons:algolia w-4 h-4 mt-0.5 shrink-0" 100 100 :class="searchProviderValue === 'algolia' ? 'text-accent' : 'text-fg-muted'" 101 101 aria-hidden="true" 102 102 /> ··· 125 125 class="text-xs text-fg-subtle hover:text-fg-muted transition-colors inline-flex items-center gap-1 px-2" 126 126 > 127 127 {{ $t('search.algolia_disclaimer') }} 128 - <span class="i-carbon:launch w-3 h-3" aria-hidden="true" /> 128 + <span class="i-lucide:external-link w-3 h-3" aria-hidden="true" /> 129 129 </a> 130 130 </div> 131 131 </div>
+1 -1
app/components/SearchProviderToggle.server.vue
··· 1 1 <template> 2 2 <div class="relative"> 3 3 <div class="flex items-center justify-center w-8 h-8 rounded-md text-fg-subtle"> 4 - <span class="i-carbon:settings w-4 h-4" aria-hidden="true" /> 4 + <span class="i-lucide:settings w-4 h-4" aria-hidden="true" /> 5 5 </div> 6 6 </div> 7 7 </template>
+1 -1
app/components/SearchSuggestionCard.vue
··· 62 62 </div> 63 63 64 64 <span 65 - class="i-carbon:arrow-right rtl-flip w-4 h-4 text-fg-subtle group-hover:text-fg transition-colors shrink-0" 65 + class="i-lucide:arrow-right rtl-flip w-4 h-4 text-fg-subtle group-hover:text-fg transition-colors shrink-0" 66 66 aria-hidden="true" 67 67 /> 68 68 </NuxtLink>
+1 -1
app/components/Select/Field.vue
··· 69 69 </SelectBase> 70 70 <span 71 71 aria-hidden="true" 72 - class="block i-carbon:chevron-down absolute top-1/2 -translate-y-1/2 text-fg-subtle pointer-events-none group-hover/select:text-fg group-focus-within/select:text-fg" 72 + class="block i-lucide:chevron-down absolute top-1/2 -translate-y-1/2 text-fg-subtle pointer-events-none group-hover/select:text-fg group-focus-within/select:text-fg" 73 73 :class="[SELECT_FIELD_ICON_SIZES[size]]" 74 74 /> 75 75 </div>
+1 -1
app/components/Settings/AccentColorPicker.vue
··· 55 55 :aria-label="$t('settings.clear_accent')" 56 56 @change="setAccentColor(null)" 57 57 /> 58 - <span class="i-carbon-error size-4 text-bg" aria-hidden="true" /> 58 + <span class="i-lucide:ban size-4 text-bg" aria-hidden="true" /> 59 59 </label> 60 60 </fieldset> 61 61 </template>
+2 -2
app/components/Settings/TranslationHelper.vue
··· 122 122 rel="noopener noreferrer" 123 123 class="inline-flex items-center gap-1.5 px-2.5 py-1.5 text-xs bg-bg hover:bg-bg-subtle border border-border rounded-md transition-colors focus-visible:outline-accent/70" 124 124 > 125 - <span class="i-carbon-edit w-3.5 h-3.5" aria-hidden="true" /> 125 + <span class="i-lucide:pen w-3.5 h-3.5" aria-hidden="true" /> 126 126 {{ $t('i18n.edit_on_github') }} 127 127 </a> 128 128 ··· 132 132 rel="noopener noreferrer" 133 133 class="inline-flex items-center gap-1.5 px-2.5 py-1.5 text-xs text-fg-muted hover:text-fg rounded transition-colors focus-visible:outline-accent/70" 134 134 > 135 - <span class="i-carbon-document w-3.5 h-3.5" aria-hidden="true" /> 135 + <span class="i-lucide:file-text w-3.5 h-3.5" aria-hidden="true" /> 136 136 {{ $t('i18n.view_guide') }} 137 137 </a> 138 138 </div>
+2 -2
app/components/Terminal/Install.vue
··· 219 219 class="text-fg-subtle hover:text-fg-muted text-xs transition-colors focus-visible:outline-accent/70 rounded select-none" 220 220 :title="$t('package.get_started.view_types', { package: typesPackageName })" 221 221 > 222 - <span class="i-carbon:arrow-right rtl-flip w-3 h-3 align-middle" aria-hidden="true" /> 222 + <span class="i-lucide:arrow-right rtl-flip w-3 h-3 align-middle" aria-hidden="true" /> 223 223 <span class="sr-only">View {{ typesPackageName }}</span> 224 224 </NuxtLink> 225 225 </div> ··· 271 271 :to="packageRoute(createPackageInfo.packageName)" 272 272 class="inline-flex items-center justify-center min-w-6 min-h-6 -m-1 p-1 text-fg-muted hover:text-fg text-xs transition-colors focus-visible:outline-2 focus-visible:outline-accent/70 rounded" 273 273 > 274 - <span class="i-carbon:information w-3 h-3" aria-hidden="true" /> 274 + <span class="i-lucide:info w-3 h-3" aria-hidden="true" /> 275 275 <span class="sr-only">{{ 276 276 $t('package.create.view', { packageName: createPackageInfo.packageName }) 277 277 }}</span>
+1 -1
app/components/UserCombobox.vue
··· 204 204 role="status" 205 205 aria-live="polite" 206 206 > 207 - <span class="i-carbon:information w-3 h-3 me-1 align-middle" aria-hidden="true" /> 207 + <span class="i-lucide:info w-3 h-3 me-1 align-middle" aria-hidden="true" /> 208 208 {{ 209 209 $t('user.combobox.press_enter_to_add', { 210 210 username: inputValue.trim().replace(/^@/, ''),
+3 -3
app/components/VersionSelector.vue
··· 484 484 latest 485 485 </span> 486 486 <span 487 - class="i-carbon:chevron-down w-3.5 h-3.5 transition-[transform] duration-200 motion-reduce:transition-none" 487 + class="i-lucide:chevron-down w-3.5 h-3.5 transition-[transform] duration-200 motion-reduce:transition-none" 488 488 :class="{ 'rotate-180': isOpen }" 489 489 aria-hidden="true" 490 490 /> ··· 540 540 > 541 541 <span 542 542 v-if="group.isLoading" 543 - class="i-carbon:rotate-180 w-3 h-3 motion-safe:animate-spin" 543 + class="i-svg-spinners:ring-resize w-3 h-3" 544 544 aria-hidden="true" 545 545 /> 546 546 <span 547 547 v-else 548 548 class="w-3 h-3 transition-transform duration-200 rtl-flip" 549 - :class="group.isExpanded ? 'i-carbon:chevron-down' : 'i-carbon:chevron-right'" 549 + :class="group.isExpanded ? 'i-lucide:chevron-down' : 'i-lucide:chevron-right'" 550 550 aria-hidden="true" 551 551 /> 552 552 </button>
+2 -2
app/components/ViewModeToggle.vue
··· 18 18 :aria-label="$t('filters.view_mode.cards')" 19 19 @click="viewMode = 'cards'" 20 20 > 21 - <span class="i-carbon-horizontal-view w-4 h-4" aria-hidden="true" /> 21 + <span class="i-lucide:rows-2 w-4 h-4" aria-hidden="true" /> 22 22 <span class="sr-only">{{ $t('filters.view_mode.cards') }}</span> 23 23 </button> 24 24 <button ··· 29 29 :aria-label="$t('filters.view_mode.table')" 30 30 @click="viewMode = 'table'" 31 31 > 32 - <span class="i-carbon-table-split w-4 h-4" aria-hidden="true" /> 32 + <span class="i-lucide:table w-4 h-4" aria-hidden="true" /> 33 33 <span class="sr-only">{{ $t('filters.view_mode.table') }}</span> 34 34 </button> 35 35 </div>
+3 -3
app/pages/about.vue
··· 61 61 @click="router.back()" 62 62 v-if="canGoBack" 63 63 > 64 - <span class="i-carbon:arrow-left rtl-flip w-4 h-4" aria-hidden="true" /> 64 + <span class="i-lucide:arrow-left rtl-flip w-4 h-4" aria-hidden="true" /> 65 65 <span class="hidden sm:inline">{{ $t('nav.back') }}</span> 66 66 </button> 67 67 </div> ··· 207 207 :to="person.sponsors_url" 208 208 no-underline 209 209 no-external-icon 210 - classicon="i-carbon:favorite" 210 + classicon="i-lucide:heart" 211 211 class="relative z-10 text-xs text-fg-muted hover:text-pink-400 mt-0.5" 212 212 :aria-label="$t('about.team.sponsor_aria', { name: person.login })" 213 213 > ··· 215 215 </LinkBase> 216 216 </div> 217 217 <span 218 - class="i-carbon:launch rtl-flip w-3.5 h-3.5 text-fg-muted opacity-50 shrink-0 self-start mt-0.5" 218 + class="i-lucide:external-link rtl-flip w-3.5 h-3.5 text-fg-muted opacity-50 shrink-0 self-start mt-0.5" 219 219 aria-hidden="true" 220 220 /> 221 221 </li>
+2 -2
app/pages/accessibility.vue
··· 31 31 @click="router.back()" 32 32 v-if="canGoBack" 33 33 > 34 - <span class="i-carbon:arrow-left rtl-flip w-4 h-4" aria-hidden="true" /> 34 + <span class="i-lucide:arrow-left rtl-flip w-4 h-4" aria-hidden="true" /> 35 35 <span class="sr-only sm:not-sr-only">{{ $t('nav.back') }}</span> 36 36 </button> 37 37 </div> ··· 132 132 class="inline-flex items-center gap-1 text-fg-muted hover:text-fg underline decoration-fg-subtle/50 hover:decoration-fg" 133 133 > 134 134 {{ $t('a11y.contact.link') }} 135 - <span class="i-carbon:launch rtl-flip w-4 h-4" aria-hidden="true" /> 135 + <span class="i-lucide:external-link rtl-flip w-4 h-4" aria-hidden="true" /> 136 136 </a> 137 137 </template> 138 138 </i18n-t>
+5 -2
app/pages/compare.vue
··· 121 121 @click="router.back()" 122 122 v-if="canGoBack" 123 123 > 124 - <span class="i-carbon:arrow-left rtl-flip w-4 h-4" aria-hidden="true" /> 124 + <span class="i-lucide:arrow-left rtl-flip w-4 h-4" aria-hidden="true" /> 125 125 <span class="hidden sm:inline">{{ $t('nav.back') }}</span> 126 126 </button> 127 127 </div> ··· 257 257 v-else 258 258 class="text-center px-1.5 py-16 border border-dashed border-border-hover rounded-lg" 259 259 > 260 - <div class="i-carbon:compare w-12 h-12 text-fg-subtle mx-auto mb-4" aria-hidden="true" /> 260 + <div 261 + class="i-lucide:git-compare w-12 h-12 text-fg-subtle mx-auto mb-4" 262 + aria-hidden="true" 263 + /> 261 264 <h2 class="font-mono text-lg text-fg-muted mb-2"> 262 265 {{ $t('compare.packages.empty_title') }} 263 266 </h2>
+1 -1
app/pages/index.vue
··· 93 93 type="submit" 94 94 variant="primary" 95 95 class="absolute inset-ie-2 border-transparent" 96 - classicon="i-carbon:search" 96 + classicon="i-lucide:search" 97 97 > 98 98 <span class="sr-only sm:not-sr-only"> 99 99 {{ $t('search.button') }}
+2 -2
app/pages/org/[org].vue
··· 182 182 class="link-subtle font-mono text-sm inline-flex items-center gap-1.5" 183 183 :title="$t('common.view_on_npm')" 184 184 > 185 - <span class="i-carbon:logo-npm w-4 h-4" aria-hidden="true" /> 185 + <span class="i-simple-icons:npm w-4 h-4" aria-hidden="true" /> 186 186 npm 187 187 </a> 188 188 </nav> ··· 190 190 class="text-fg-subtle text-xs mt-1 flex items-center gap-1.5 justify-end cursor-help" 191 191 :title="$t('common.vanity_downloads_hint', { count: filteredCount }, filteredCount)" 192 192 > 193 - <span class="i-carbon:chart-line w-3.5 h-3.5" aria-hidden="true" /> 193 + <span class="i-lucide:chart-line w-3.5 h-3.5" aria-hidden="true" /> 194 194 <span class="font-mono" 195 195 >{{ $n(totalWeeklyDownloads) }} {{ $t('common.per_week') }}</span 196 196 >
+5 -5
app/pages/package-code/[[org]]/[packageName]/v/[version]/[...filePath].vue
··· 256 256 { 257 257 key: 'preview', 258 258 label: $t('code.markdown_view_mode.preview'), 259 - icon: 'i-carbon-view', 259 + icon: 'i-lucide:eye', 260 260 }, 261 261 { 262 262 key: 'code', 263 263 label: $t('code.markdown_view_mode.code'), 264 - icon: 'i-carbon-code', 264 + icon: 'i-lucide:code', 265 265 }, 266 266 ] as const 267 267 ··· 463 463 class="px-2 py-1 font-mono text-xs text-fg-muted bg-bg-subtle border border-border rounded hover:text-fg hover:border-border-hover transition-colors inline-flex items-center gap-1" 464 464 > 465 465 {{ $t('code.raw') }} 466 - <span class="i-carbon:launch w-3 h-3" /> 466 + <span class="i-lucide:external-link w-3 h-3" /> 467 467 </a> 468 468 </div> 469 469 </div> ··· 486 486 487 487 <!-- File too large warning --> 488 488 <div v-else-if="isViewingFile && isFileTooLarge" class="py-20 text-center"> 489 - <div class="i-carbon:document w-12 h-12 mx-auto text-fg-subtle mb-4" /> 489 + <div class="i-lucide:file-text w-12 h-12 mx-auto text-fg-subtle mb-4" /> 490 490 <p class="text-fg-muted mb-2">{{ $t('code.file_too_large') }}</p> 491 491 <p class="text-fg-subtle text-sm mb-4"> 492 492 {{ ··· 541 541 542 542 <!-- Error loading file --> 543 543 <div v-else-if="filePath && fileStatus === 'error'" class="py-20 text-center" role="alert"> 544 - <div class="i-carbon:warning-alt w-8 h-8 mx-auto text-fg-subtle mb-4" /> 544 + <div class="i-lucide:circle-alert w-8 h-8 mx-auto text-fg-subtle mb-4" /> 545 545 <p class="text-fg-muted mb-2">{{ $t('code.failed_to_load') }}</p> 546 546 <p class="text-fg-subtle text-sm mb-4">{{ $t('code.unavailable_hint') }}</p> 547 547 <LinkBase
+34 -46
app/pages/package/[[org]]/[name].vue
··· 395 395 const { meta: repoMeta, repoRef, stars, starsLink, forks, forksLink } = useRepoMeta(repositoryUrl) 396 396 397 397 const PROVIDER_ICONS: Record<string, string> = { 398 - github: 'i-carbon:logo-github', 398 + github: 'i-simple-icons:github', 399 399 gitlab: 'i-simple-icons:gitlab', 400 400 bitbucket: 'i-simple-icons:bitbucket', 401 401 codeberg: 'i-simple-icons:codeberg', ··· 404 404 gitee: 'i-simple-icons:gitee', 405 405 sourcehut: 'i-simple-icons:sourcehut', 406 406 tangled: 'i-custom:tangled', 407 - radicle: 'i-carbon:network-3', // Radicle is a P2P network, using network icon 407 + radicle: 'i-lucide:network', // Radicle is a P2P network, using network icon 408 408 } 409 409 410 410 const repoProviderIcon = computed(() => { 411 411 const provider = repoRef.value?.provider 412 - if (!provider) return 'i-carbon:logo-github' 413 - return PROVIDER_ICONS[provider] ?? 'i-carbon:code' 412 + if (!provider) return 'i-simple-icons:github' 413 + return PROVIDER_ICONS[provider] ?? 'i-lucide:code' 414 414 }) 415 415 416 416 const homepageUrl = computed(() => { ··· 692 692 :aria-label="copiedPkgName ? $t('common.copied') : $t('package.copy_name')" 693 693 > 694 694 <span 695 - :class="copiedPkgName ? 'i-carbon:checkmark' : 'i-carbon:copy'" 695 + :class="copiedPkgName ? 'i-lucide:check' : 'i-lucide:copy'" 696 696 class="w-3.5 h-3.5" 697 697 aria-hidden="true" 698 698 /> ··· 706 706 <!-- Version resolution indicator (e.g., "latest → 4.2.0") --> 707 707 <template v-if="requestedVersion && resolvedVersion !== requestedVersion"> 708 708 <span class="font-mono text-fg-muted text-sm" dir="ltr">{{ requestedVersion }}</span> 709 - <span class="i-carbon:arrow-right rtl-flip w-3 h-3" aria-hidden="true" /> 709 + <span class="i-lucide:arrow-right rtl-flip w-3 h-3" aria-hidden="true" /> 710 710 </template> 711 711 712 712 <LinkBase ··· 735 735 size="small" 736 736 to="#provenance" 737 737 :aria-label="$t('package.provenance_section.view_more_details')" 738 - classicon="i-lucide-shield-check" 738 + classicon="i-lucide:shield-check" 739 739 /> 740 740 </TooltipApp> 741 741 </template> ··· 760 760 v-if="docsLink" 761 761 :to="docsLink" 762 762 aria-keyshortcuts="d" 763 - classicon="i-carbon:document" 763 + classicon="i-lucide:file-text" 764 764 > 765 765 {{ $t('package.links.docs') }} 766 766 </LinkBase> ··· 769 769 variant="button-secondary" 770 770 :to="codeLink" 771 771 aria-keyshortcuts="." 772 - classicon="i-carbon:code" 772 + classicon="i-lucide:code" 773 773 > 774 774 {{ $t('package.links.code') }} 775 775 </LinkBase> ··· 777 777 variant="button-secondary" 778 778 :to="{ name: 'compare', query: { packages: pkg.name } }" 779 779 aria-keyshortcuts="c" 780 - classicon="i-carbon:compare" 780 + classicon="i-lucide:git-compare" 781 781 > 782 782 {{ $t('package.links.compare') }} 783 783 </LinkBase> ··· 818 818 :aria-pressed="likesData?.userHasLiked" 819 819 :classicon=" 820 820 likesData?.userHasLiked 821 - ? 'i-lucide-heart-minus text-red-500' 822 - : 'i-lucide-heart-plus' 821 + ? 'i-lucide:heart-minus text-red-500' 822 + : 'i-lucide:heart-plus' 823 823 " 824 824 > 825 825 <span 826 826 v-if="isLoadingLikeData" 827 - class="i-carbon-circle-dash w-3 h-3 motion-safe:animate-spin my-0.5" 827 + class="i-svg-spinners:ring-resize w-3 h-3 my-0.5" 828 828 aria-hidden="true" 829 829 /> 830 830 <span v-else> ··· 862 862 </LinkBase> 863 863 </li> 864 864 <li v-if="repositoryUrl && repoMeta && starsLink"> 865 - <LinkBase :to="starsLink" classicon="i-carbon:star"> 865 + <LinkBase :to="starsLink" classicon="i-lucide:star"> 866 866 {{ compactNumberFormatter.format(stars) }} 867 867 </LinkBase> 868 868 </li> 869 869 <li v-if="forks && forksLink"> 870 - <LinkBase :to="forksLink" classicon="i-carbon:fork"> 870 + <LinkBase :to="forksLink" classicon="i-lucide:git-fork"> 871 871 {{ compactNumberFormatter.format(forks) }} 872 872 </LinkBase> 873 873 </li> 874 874 <li class="basis-full sm:hidden" /> 875 875 <li v-if="homepageUrl"> 876 - <LinkBase :to="homepageUrl" classicon="i-carbon:link"> 876 + <LinkBase :to="homepageUrl" classicon="i-lucide:link"> 877 877 {{ $t('package.links.homepage') }} 878 878 </LinkBase> 879 879 </li> 880 880 <li v-if="displayVersion?.bugs?.url"> 881 - <LinkBase :to="displayVersion.bugs.url" classicon="i-carbon:warning"> 881 + <LinkBase :to="displayVersion.bugs.url" classicon="i-lucide:circle-alert"> 882 882 {{ $t('package.links.issues') }} 883 883 </LinkBase> 884 884 </li> ··· 886 886 <LinkBase 887 887 :to="`https://www.npmjs.com/package/${pkg.name}`" 888 888 :title="$t('common.view_on_npm')" 889 - classicon="i-carbon:logo-npm" 889 + classicon="i-simple-icons:npm" 890 890 > 891 891 npm 892 892 </LinkBase> ··· 901 901 </LinkBase> 902 902 </li> 903 903 <li v-if="fundingUrl"> 904 - <LinkBase :to="fundingUrl" classicon="i-carbon:favorite"> 904 + <LinkBase :to="fundingUrl" classicon="i-lucide:heart"> 905 905 {{ $t('package.links.fund') }} 906 906 </LinkBase> 907 907 </li> ··· 962 962 " 963 963 class="inline-flex items-center gap-1 text-fg-subtle" 964 964 > 965 - <span 966 - class="i-carbon:circle-dash w-3 h-3 motion-safe:animate-spin" 967 - aria-hidden="true" 968 - /> 965 + <span class="i-svg-spinners:ring-resize w-3 h-3" aria-hidden="true" /> 969 966 </span> 970 967 <span v-else-if="totalDepsCount !== null">{{ 971 968 numberFormatter.format(totalDepsCount) ··· 983 980 size="small" 984 981 :to="`https://npmgraph.js.org/?q=${pkg.name}`" 985 982 :title="$t('package.stats.view_dependency_graph')" 986 - classicon="i-carbon:network-3" 983 + classicon="i-lucide:network -rotate-90" 987 984 > 988 985 <span class="sr-only">{{ $t('package.stats.view_dependency_graph') }}</span> 989 986 </LinkBase> ··· 993 990 size="small" 994 991 :to="`https://node-modules.dev/grid/depth#install=${pkg.name}${resolvedVersion ? `@${resolvedVersion}` : ''}`" 995 992 :title="$t('package.stats.inspect_dependency_tree')" 996 - classicon="i-carbon:tree-view" 993 + classicon="i-lucide:table" 997 994 > 998 995 <span class="sr-only">{{ $t('package.stats.inspect_dependency_tree') }}</span> 999 996 </LinkBase> ··· 1009 1006 tabindex="0" 1010 1007 class="inline-flex items-center justify-center min-w-6 min-h-6 -m-1 p-1 text-fg-subtle cursor-help focus-visible:outline-2 focus-visible:outline-accent/70 rounded" 1011 1008 > 1012 - <span class="i-carbon:information w-3 h-3" aria-hidden="true" /> 1009 + <span class="i-lucide:info w-3 h-3" aria-hidden="true" /> 1013 1010 </span> 1014 1011 </TooltipApp> 1015 1012 </dt> ··· 1030 1027 v-if="installSizeStatus === 'pending'" 1031 1028 class="inline-flex items-center gap-1 text-fg-subtle" 1032 1029 > 1033 - <span 1034 - class="i-carbon:circle-dash w-3 h-3 motion-safe:animate-spin" 1035 - aria-hidden="true" 1036 - /> 1030 + <span class="i-svg-spinners:ring-resize w-3 h-3" aria-hidden="true" /> 1037 1031 </span> 1038 1032 <span v-else-if="installSize?.totalSize" dir="ltr"> 1039 1033 {{ bytesFormatter.format(installSize.totalSize) }} ··· 1053 1047 v-if="vulnTreeStatus === 'pending' || vulnTreeStatus === 'idle'" 1054 1048 class="inline-flex items-center gap-1 text-fg-subtle" 1055 1049 > 1056 - <span 1057 - class="i-carbon:circle-dash w-3 h-3 motion-safe:animate-spin" 1058 - aria-hidden="true" 1059 - /> 1050 + <span class="i-svg-spinners:ring-resize w-3 h-3" aria-hidden="true" /> 1060 1051 </span> 1061 1052 <span v-else-if="vulnTreeStatus === 'success'"> 1062 1053 <span v-if="hasVulnerabilities" class="text-amber-700 dark:text-amber-500"> 1063 1054 {{ numberFormatter.format(vulnCount) }} 1064 1055 </span> 1065 1056 <span v-else class="inline-flex items-center gap-1 text-fg-muted"> 1066 - <span class="i-carbon:checkmark w-3 h-3" aria-hidden="true" /> 1057 + <span class="i-lucide:check w-3 h-3" aria-hidden="true" /> 1067 1058 {{ numberFormatter.format(0) }} 1068 1059 </span> 1069 1060 </span> ··· 1149 1140 class="mb-4 rounded-lg border border-amber-600/40 bg-amber-500/10 px-4 py-3 text-amber-700 dark:text-amber-400" 1150 1141 > 1151 1142 <h3 class="m-0 flex items-center gap-2 font-mono text-sm font-medium"> 1152 - <span class="i-carbon:warning-alt w-4 h-4 shrink-0" aria-hidden="true" /> 1143 + <span class="i-lucide:circle-alert w-4 h-4 shrink-0" aria-hidden="true" /> 1153 1144 {{ $t('package.security_downgrade.title') }} 1154 1145 </h3> 1155 1146 <p class="mt-2 mb-0 text-sm"> ··· 1169 1160 rel="noopener noreferrer" 1170 1161 class="inline-flex items-center gap-1 rounded-sm underline underline-offset-4 decoration-amber-600/60 dark:decoration-amber-400/50 hover:decoration-fg focus-visible:decoration-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/70 transition-colors" 1171 1162 >{{ $t('package.security_downgrade.provenance_link_text') 1172 - }}<span class="i-carbon-launch w-3 h-3" aria-hidden="true" 1163 + }}<span class="i-lucide:external-link w-3 h-3" aria-hidden="true" 1173 1164 /></a> 1174 1165 </template> 1175 1166 </i18n-t> ··· 1189 1180 rel="noopener noreferrer" 1190 1181 class="inline-flex items-center gap-1 rounded-sm underline underline-offset-4 decoration-amber-600/60 dark:decoration-amber-400/50 hover:decoration-fg focus-visible:decoration-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/70 transition-colors" 1191 1182 >{{ $t('package.security_downgrade.trusted_publishing_link_text') 1192 - }}<span class="i-carbon-launch w-3 h-3" aria-hidden="true" 1183 + }}<span class="i-lucide:external-link w-3 h-3" aria-hidden="true" 1193 1184 /></a> 1194 1185 </template> 1195 1186 </i18n-t> ··· 1209 1200 rel="noopener noreferrer" 1210 1201 class="inline-flex items-center gap-1 rounded-sm underline underline-offset-4 decoration-amber-600/60 dark:decoration-amber-400/50 hover:decoration-fg focus-visible:decoration-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/70 transition-colors" 1211 1202 >{{ $t('package.security_downgrade.provenance_link_text') 1212 - }}<span class="i-carbon-launch w-3 h-3" aria-hidden="true" 1203 + }}<span class="i-lucide:external-link w-3 h-3" aria-hidden="true" 1213 1204 /></a> 1214 1205 </template> 1215 1206 <template #trustedPublishing> ··· 1219 1210 rel="noopener noreferrer" 1220 1211 class="inline-flex items-center gap-1 rounded-sm underline underline-offset-4 decoration-amber-600/60 dark:decoration-amber-400/50 hover:decoration-fg focus-visible:decoration-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/70 transition-colors" 1221 1212 >{{ $t('package.security_downgrade.trusted_publishing_link_text') 1222 - }}<span class="i-carbon-launch w-3 h-3" aria-hidden="true" 1213 + }}<span class="i-lucide:external-link w-3 h-3" aria-hidden="true" 1223 1214 /></a> 1224 1215 </template> 1225 1216 </i18n-t> ··· 1284 1275 :aria-label=" 1285 1276 copiedReadme ? $t('common.copied') : $t('package.readme.copy_as_markdown') 1286 1277 " 1287 - :classicon="copiedReadme ? 'i-carbon:checkmark' : 'i-simple-icons:markdown'" 1278 + :classicon="copiedReadme ? 'i-lucide:check' : 'i-simple-icons:markdown'" 1288 1279 > 1289 1280 {{ copiedReadme ? $t('common.copied') : $t('common.copy') }} 1290 1281 </ButtonBase> ··· 1320 1311 v-if="provenanceStatus === 'pending'" 1321 1312 class="mt-8 flex items-center gap-2 text-fg-subtle text-sm" 1322 1313 > 1323 - <span 1324 - class="i-carbon-circle-dash w-4 h-4 motion-safe:animate-spin" 1325 - aria-hidden="true" 1326 - /> 1314 + <span class="i-svg-spinners:ring-resize w-4 h-4" aria-hidden="true" /> 1327 1315 <span>{{ $t('package.provenance_section.title') }}…</span> 1328 1316 </div> 1329 1317 <PackageProvenanceSection ··· 1336 1324 v-else-if="provenanceStatus === 'error'" 1337 1325 class="mt-8 flex items-center gap-2 text-fg-subtle text-sm" 1338 1326 > 1339 - <span class="i-carbon:warning w-4 h-4" aria-hidden="true" /> 1327 + <span class="i-lucide:circle-alert w-4 h-4" aria-hidden="true" /> 1340 1328 <span>{{ $t('package.provenance_section.error_loading') }}</span> 1341 1329 </div> 1342 1330 </section>
+5 -5
app/pages/privacy.vue
··· 33 33 @click="router.back()" 34 34 v-if="canGoBack" 35 35 > 36 - <span class="i-carbon:arrow-left rtl-flip w-4 h-4" aria-hidden="true" /> 36 + <span class="i-lucide:arrow-left rtl-flip w-4 h-4" aria-hidden="true" /> 37 37 <span class="sr-only sm:not-sr-only">{{ $t('nav.back') }}</span> 38 38 </button> 39 39 </div> ··· 183 183 class="inline-flex items-center gap-1 text-fg-muted hover:text-fg underline decoration-fg-subtle/50 hover:decoration-fg" 184 184 > 185 185 {{ $t('privacy_policy.cookies.management.chrome') }} 186 - <span class="i-carbon:launch rtl-flip w-4 h-4" aria-hidden="true" /> 186 + <span class="i-lucide:external-link rtl-flip w-4 h-4" aria-hidden="true" /> 187 187 </a> 188 188 </li> 189 189 <li class="flex items-start gap-3"> ··· 195 195 class="inline-flex items-center gap-1 text-fg-muted hover:text-fg underline decoration-fg-subtle/50 hover:decoration-fg" 196 196 > 197 197 {{ $t('privacy_policy.cookies.management.firefox') }} 198 - <span class="i-carbon:launch rtl-flip w-4 h-4" aria-hidden="true" /> 198 + <span class="i-lucide:external-link rtl-flip w-4 h-4" aria-hidden="true" /> 199 199 </a> 200 200 </li> 201 201 <li class="flex items-start gap-3"> ··· 207 207 class="inline-flex items-center gap-1 text-fg-muted hover:text-fg underline decoration-fg-subtle/50 hover:decoration-fg" 208 208 > 209 209 {{ $t('privacy_policy.cookies.management.edge') }} 210 - <span class="i-carbon:launch rtl-flip w-4 h-4" aria-hidden="true" /> 210 + <span class="i-lucide:external-link rtl-flip w-4 h-4" aria-hidden="true" /> 211 211 </a> 212 212 </li> 213 213 </ul> ··· 333 333 class="inline-flex items-center gap-1 text-fg-muted hover:text-fg underline decoration-fg-subtle/50 hover:decoration-fg" 334 334 > 335 335 {{ $t('privacy_policy.contact.link') }} 336 - <span class="i-carbon:launch rtl-flip w-4 h-4" aria-hidden="true" /> 336 + <span class="i-lucide:external-link rtl-flip w-4 h-4" aria-hidden="true" /> 337 337 </a> 338 338 </template> 339 339 </i18n-t>
+13 -13
app/pages/recharging.vue
··· 47 47 // Icons that tile across the banner, repeating to fill. 48 48 // Classes must be written out statically so UnoCSS can detect them at build time. 49 49 const icons = [ 50 - 'i-carbon:snowflake', 51 - 'i-carbon:mountain', 52 - 'i-carbon:tree', 53 - 'i-carbon:cafe', 54 - 'i-carbon:book', 55 - 'i-carbon:music', 56 - 'i-carbon:snowflake', 57 - 'i-carbon:star', 58 - 'i-carbon:moon', 50 + 'i-lucide:snowflake', 51 + 'i-lucide:mountain', 52 + 'i-lucide:tree-pine', 53 + 'i-lucide:coffee', 54 + 'i-lucide:book', 55 + 'i-lucide:music', 56 + 'i-lucide:snowflake', 57 + 'i-lucide:star', 58 + 'i-lucide:moon', 59 59 ] as const 60 60 61 61 // --- .ics calendar reminder --- ··· 122 122 @click="router.back()" 123 123 v-if="canGoBack" 124 124 > 125 - <span class="i-carbon:arrow-left rtl-flip w-4 h-4" aria-hidden="true" /> 125 + <span class="i-lucide:arrow-left rtl-flip w-4 h-4" aria-hidden="true" /> 126 126 <span class="sr-only sm:not-sr-only">{{ $t('nav.back') }}</span> 127 127 </button> 128 128 </div> ··· 205 205 @click="pokeLog" 206 206 > 207 207 <span 208 - class="absolute inset-0 i-carbon:fire w-5 h-5 sm:w-6 sm:h-6 text-orange-400 transition-opacity duration-400" 208 + class="absolute inset-0 i-lucide:flame-kindling w-5 h-5 sm:w-6 sm:h-6 text-orange-400 transition-opacity duration-400" 209 209 :class="fireVisible ? 'opacity-100' : 'opacity-0'" 210 210 /> 211 211 <span 212 - class="absolute inset-0 i-carbon:campsite w-5 h-5 sm:w-6 sm:h-6 transition-colors duration-400" 212 + class="absolute inset-0 i-lucide:tent w-5 h-5 sm:w-6 sm:h-6 transition-colors duration-400" 213 213 :class="fireVisible ? 'text-amber-700' : ''" 214 214 /> 215 215 </button> ··· 240 240 </p> 241 241 242 242 <!-- Add to calendar button --> 243 - <ButtonBase classicon="i-carbon:calendar" @click="downloadIcs"> 243 + <ButtonBase classicon="i-lucide:calendar" @click="downloadIcs"> 244 244 {{ $t('vacations.return.add_to_calendar') }} 245 245 </ButtonBase> 246 246 </div>
+3 -3
app/pages/settings.vue
··· 55 55 @click="router.back()" 56 56 v-if="canGoBack" 57 57 > 58 - <span class="i-carbon:arrow-left rtl-flip w-4 h-4" aria-hidden="true" /> 58 + <span class="i-lucide:arrow-left rtl-flip w-4 h-4" aria-hidden="true" /> 59 59 <span class="sr-only sm:not-sr-only">{{ $t('nav.back') }}</span> 60 60 </button> 61 61 </div> ··· 199 199 class="inline-flex items-center gap-1 text-xs text-fg-subtle hover:text-fg-muted transition-colors mt-2" 200 200 > 201 201 {{ $t('search.algolia_disclaimer') }} 202 - <span class="i-carbon:launch w-3 h-3" aria-hidden="true" /> 202 + <span class="i-lucide:external-link w-3 h-3" aria-hidden="true" /> 203 203 </a> 204 204 </div> 205 205 </div> ··· 254 254 rel="noopener noreferrer" 255 255 class="inline-flex items-center gap-2 text-sm text-fg-muted hover:text-fg transition-colors duration-200 focus-visible:outline-accent/70 rounded" 256 256 > 257 - <span class="i-carbon:logo-github w-4 h-4" aria-hidden="true" /> 257 + <span class="i-simple-icons:github w-4 h-4" aria-hidden="true" /> 258 258 {{ $t('settings.help_translate') }} 259 259 </a> 260 260 </template>
+2 -2
app/pages/~[username]/index.vue
··· 158 158 class="link-subtle font-mono text-sm inline-flex items-center gap-1.5" 159 159 :title="$t('common.view_on_npm')" 160 160 > 161 - <span class="i-carbon:logo-npm w-4 h-4" aria-hidden="true" /> 161 + <span class="i-simple-icons:npm w-4 h-4" aria-hidden="true" /> 162 162 npm 163 163 </a> 164 164 </nav> ··· 166 166 class="text-fg-subtle text-xs mt-1 flex items-center gap-1.5 justify-end cursor-help" 167 167 :title="$t('common.vanity_downloads_hint', { count: filteredCount }, filteredCount)" 168 168 > 169 - <span class="i-carbon:chart-line w-3.5 h-3.5" aria-hidden="true" /> 169 + <span class="i-lucide:chart-line w-3.5 h-3.5" aria-hidden="true" /> 170 170 <span class="font-mono" 171 171 >{{ $n(totalWeeklyDownloads) }} {{ $t('common.per_week') }}</span 172 172 >
+2 -2
app/pages/~[username]/orgs.vue
··· 140 140 id="back-to-profile" 141 141 class="link-subtle font-mono text-sm inline-flex items-center gap-1.5" 142 142 > 143 - <span class="i-carbon:arrow-left rtl-flip w-4 h-4" aria-hidden="true" /> 143 + <span class="i-lucide:arrow-left rtl-flip w-4 h-4" aria-hidden="true" /> 144 144 {{ $t('user.orgs_page.back_to_profile') }} 145 145 </NuxtLink> 146 146 </nav> ··· 224 224 <!-- Stats --> 225 225 <div class="flex items-center gap-4 text-sm text-fg-muted"> 226 226 <div class="flex items-center gap-1.5"> 227 - <span class="i-carbon:cube w-4 h-4" aria-hidden="true" /> 227 + <span class="i-lucide:box w-4 h-4" aria-hidden="true" /> 228 228 <span v-if="org.packageCount !== null"> 229 229 {{ 230 230 $t(
+3 -3
app/utils/file-icons.ts
··· 1 1 /** 2 2 * Get icon class for a file based on its name/extension. 3 - * Uses vscode-icons and carbon icons. 3 + * Uses vscode-icons and lucide icons. 4 4 * 5 5 * Based on this file, a sprite file (<ORIGIN_URL>/file-tree-sprite.svg) is generated on postinstall 6 6 * @see /scripts/generate-file-tree-sprite.ts ··· 314 314 export const DEFAULT_ICON = 'vscode-icons-default-file' 315 315 316 316 export const ADDITIONAL_ICONS = { 317 - 'folder': 'carbon-folder', 318 - 'folder-open': 'carbon-folder-open', 317 + 'folder': 'lucide-folder', 318 + 'folder-open': 'lucide-folder-open', 319 319 } 320 320 321 321 /**
+1 -1
docs/content/1.getting-started/.navigation.yml
··· 1 1 title: Getting Started 2 - icon: i-lucide-rocket 2 + icon: i-lucide:rocket
+1 -1
docs/content/1.getting-started/1.introduction.md
··· 2 2 title: Introduction 3 3 description: Learn what npmx.dev is and why you should use it 4 4 navigation: 5 - icon: i-lucide-house 5 + icon: i-lucide:house 6 6 --- 7 7 8 8 npmx.dev provides a better way to browse the npm registry.
+1 -1
docs/content/1.getting-started/2.quick-start.md
··· 2 2 title: Quick Start 3 3 description: Start using npmx.dev in seconds 4 4 navigation: 5 - icon: i-lucide-zap 5 + icon: i-lucide:zap 6 6 --- 7 7 8 8 npmx.dev works in your browser with no installation required.
+1 -1
docs/content/2.guide/.navigation.yml
··· 1 1 title: Guide 2 - icon: i-lucide-book-open 2 + icon: i-lucide:book-open
+2 -2
docs/content/2.guide/1.features.md
··· 2 2 title: Features 3 3 description: Explore all the features npmx.dev offers 4 4 navigation: 5 - icon: i-lucide-sparkles 5 + icon: i-lucide:sparkles 6 6 --- 7 7 8 8 npmx.dev provides a comprehensive set of features for browsing npm packages. ··· 85 85 | ------------------------------------------------------------------------------ | -------------------------------------------- | 86 86 | :icon{name="i-simple-icons-stackblitz"} [StackBlitz](https://stackblitz.com) | Browser-based IDE with instant environments | 87 87 | :icon{name="i-simple-icons-codesandbox"} [CodeSandbox](https://codesandbox.io) | Online code editor and prototyping tool | 88 - | :icon{name="i-lucide-pen-tool"} [CodePen](https://codepen.io) | Social development environment for front-end | 88 + | :icon{name="i-lucide:pen-tool"} [CodePen](https://codepen.io) | Social development environment for front-end | 89 89 | :icon{name="i-simple-icons-jsfiddle"} [JSFiddle](https://jsfiddle.net) | Online editor for web snippets | 90 90 | :icon{name="i-simple-icons-replit"} [Replit](https://replit.com) | Collaborative browser-based IDE | 91 91
+1 -1
docs/content/2.guide/2.keyboard-shortcuts.md
··· 2 2 title: Keyboard Shortcuts 3 3 description: Navigate npmx.dev efficiently with keyboard shortcuts 4 4 navigation: 5 - icon: i-lucide-keyboard 5 + icon: i-lucide:keyboard 6 6 --- 7 7 8 8 npmx.dev supports keyboard navigation for faster browsing.
+1 -1
docs/content/2.guide/3.url-structure.md
··· 2 2 title: URL Structure 3 3 description: Understand how URLs work in npmx.dev 4 4 navigation: 5 - icon: i-lucide-link 5 + icon: i-lucide:link 6 6 --- 7 7 8 8 npmx.dev supports npm-compatible URLs and simpler alternatives.
+1 -1
docs/content/3.faq/.navigation.yml
··· 1 1 title: FAQ 2 - icon: i-lucide-circle-help 2 + icon: i-lucide:circle-help
+1 -1
docs/content/3.faq/1.troubleshooting.md
··· 2 2 title: Troubleshooting 3 3 description: Common issues and how to resolve them 4 4 navigation: 5 - icon: i-lucide-wrench 5 + icon: i-lucide:wrench 6 6 --- 7 7 8 8 Solutions to common issues when using npmx.dev.
+1 -1
docs/content/3.faq/2.comparison.md
··· 2 2 title: Comparison 3 3 description: How npmx.dev compares to npmjs.com 4 4 navigation: 5 - icon: i-lucide-git-compare 5 + icon: i-lucide:git-compare 6 6 --- 7 7 8 8 A feature comparison between npmx.dev and npmjs.com.
+7 -7
docs/content/index.md
··· 15 15 to: /getting-started/introduction 16 16 color: neutral 17 17 size: xl 18 - trailingIcon: i-lucide-arrow-right 18 + trailingIcon: i-lucide:arrow-right 19 19 - label: View on GitHub 20 20 to: https://github.com/npmx-dev/npmx.dev 21 21 target: \_blank ··· 30 30 31 31 ::u-page-section{title="What you can do"} 32 32 #features 33 - :::u-page-feature{icon="i-lucide-search" to="/guide/features" title="Search packages" description="Fast package search with instant results, infinite scroll, and keyboard navigation."} 33 + :::u-page-feature{icon="i-lucide:search" to="/guide/features" title="Search packages" description="Fast package search with instant results, infinite scroll, and keyboard navigation."} 34 34 ::: 35 35 36 - :::u-page-feature{icon="i-lucide-code" to="/guide/features" title="Browse source code" description="View package source code with syntax highlighting and permalink to specific lines."} 36 + :::u-page-feature{icon="i-lucide:code" to="/guide/features" title="Browse source code" description="View package source code with syntax highlighting and permalink to specific lines."} 37 37 ::: 38 38 39 - :::u-page-feature{icon="i-lucide-link" to="/guide/url-structure" title="Use familiar URLs" description="Replace npmjs.com with npmx.dev in any URL and it just works."} 39 + :::u-page-feature{icon="i-lucide:link" to="/guide/url-structure" title="Use familiar URLs" description="Replace npmjs.com with npmx.dev in any URL and it just works."} 40 40 ::: 41 41 42 - :::u-page-feature{icon="i-lucide-keyboard" to="/guide/keyboard-shortcuts" title="Navigate with keyboard" description="Press / to search, . for code viewer, arrow keys to navigate results."} 42 + :::u-page-feature{icon="i-lucide:keyboard" to="/guide/keyboard-shortcuts" title="Navigate with keyboard" description="Press / to search, . for code viewer, arrow keys to navigate results."} 43 43 ::: 44 44 45 - :::u-page-feature{icon="i-lucide-shield-check" to="/guide/features" title="Check security" description="Vulnerability warnings from OSV database and provenance indicators for verified builds."} 45 + :::u-page-feature{icon="i-lucide:shield-check" to="/guide/features" title="Check security" description="Vulnerability warnings from OSV database and provenance indicators for verified builds."} 46 46 ::: 47 47 48 - :::u-page-feature{icon="i-lucide-moon" to="/guide/features" title="Enjoy dark mode" description="Dark mode by default for a better viewing experience."} 48 + :::u-page-feature{icon="i-lucide:moon" to="/guide/features" title="Enjoy dark mode" description="Dark mode by default for a better viewing experience."} 49 49 ::: 50 50 ::
-1
package.json
··· 54 54 "@atproto/oauth-client-node": "^0.3.15", 55 55 "@deno/doc": "jsr:^0.189.1", 56 56 "@floating-ui/vue": "1.1.10", 57 - "@iconify-json/carbon": "1.2.18", 58 57 "@iconify-json/lucide": "1.2.87", 59 58 "@iconify-json/simple-icons": "1.2.68", 60 59 "@iconify-json/svg-spinners": "1.2.4",
-10
pnpm-lock.yaml
··· 35 35 '@floating-ui/vue': 36 36 specifier: 1.1.10 37 37 version: 1.1.10(vue@3.5.27(typescript@5.9.3)) 38 - '@iconify-json/carbon': 39 - specifier: 1.2.18 40 - version: 1.2.18 41 38 '@iconify-json/lucide': 42 39 specifier: 1.2.87 43 40 version: 1.2.87 ··· 1537 1534 '@humanwhocodes/retry@0.4.3': 1538 1535 resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} 1539 1536 engines: {node: '>=18.18'} 1540 - 1541 - '@iconify-json/carbon@1.2.18': 1542 - resolution: {integrity: sha512-Grb13E6r/RqTEV4Sqd/BQR2FUt57U2WLuticJ5H8JbTdHLop1LmdePu3EJJA3Xi8DcWRbD6OnC133hKfOwlgtg==} 1543 1537 1544 1538 '@iconify-json/lucide@1.2.87': 1545 1539 resolution: {integrity: sha512-wxYIAp0f8Uw0rJa6BMWMaRbiHk3yV4XczA38GKXFlqyZtTdmHM1QOF4NZw5xpMlRDzbh2MnB7wjteLeFnn/ciQ==} ··· 11137 11131 '@humanwhocodes/module-importer@1.0.1': {} 11138 11132 11139 11133 '@humanwhocodes/retry@0.4.3': {} 11140 - 11141 - '@iconify-json/carbon@1.2.18': 11142 - dependencies: 11143 - '@iconify/types': 2.0.0 11144 11134 11145 11135 '@iconify-json/lucide@1.2.87': 11146 11136 dependencies:
+2 -2
scripts/generate-file-tree-sprite.ts
··· 1 - import type { IconifyJSON } from '@iconify-json/carbon' 1 + import type { IconifyJSON } from '@iconify-json/lucide' 2 2 import { promises as fs } from 'node:fs' 3 3 import { fileURLToPath } from 'node:url' 4 4 import path from 'node:path' ··· 15 15 const outputStagePath = path.join(rootDir, 'public-dev', 'file-tree-sprite.svg') 16 16 const outputProdPath = path.join(rootDir, 'public-prod', 'file-tree-sprite.svg') 17 17 18 - const COLLECTION_NAMES = ['carbon', 'lucide', 'simple-icons', 'svg-spinners', 'vscode-icons'] 18 + const COLLECTION_NAMES = ['lucide', 'simple-icons', 'svg-spinners', 'vscode-icons'] 19 19 20 20 const COLLECTION_REGEXP = new RegExp(`^(${COLLECTION_NAMES.join('|')})-(.+)$`) 21 21
+2 -2
server/utils/readme.ts
··· 395 395 const html = highlightCodeSync(shiki, text, lang || 'text') 396 396 // Add copy button 397 397 return `<div class="readme-code-block" > 398 - <button type="button" class="readme-copy-button" aria-label="Copy code" check-icon="i-carbon:checkmark" copy-icon="i-carbon:copy" data-copy> 399 - <span class="i-carbon:copy" aria-hidden="true"></span> 398 + <button type="button" class="readme-copy-button" aria-label="Copy code" check-icon="i-lucide:check" copy-icon="i-lucide:copy" data-copy> 399 + <span class="i-lucide:copy" aria-hidden="true"></span> 400 400 <span class="sr-only">Copy code</span> 401 401 </button> 402 402 ${html}
+3 -3
test/nuxt/components/LicenseDisplay.spec.ts
··· 27 27 const component = await mountSuspended(LicenseDisplay, { 28 28 props: { license: 'MIT' }, 29 29 }) 30 - const icon = component.find('.i-carbon-scales') 30 + const icon = component.find('.i-lucide\\:scale') 31 31 expect(icon.exists()).toBe(true) 32 32 }) 33 33 ··· 35 35 const component = await mountSuspended(LicenseDisplay, { 36 36 props: { license: 'CustomLicense' }, 37 37 }) 38 - const icon = component.find('.i-carbon-scales') 38 + const icon = component.find('.i-lucide\\:scale') 39 39 expect(icon.exists()).toBe(false) 40 40 }) 41 41 }) ··· 105 105 const component = await mountSuspended(LicenseDisplay, { 106 106 props: { license: 'CustomLicense OR MIT' }, 107 107 }) 108 - const icon = component.find('.i-carbon-scales') 108 + const icon = component.find('.i-lucide\\:scale') 109 109 expect(icon.exists()).toBe(true) 110 110 }) 111 111 })
+1 -1
test/nuxt/components/PackageVersions.spec.ts
··· 920 920 }) 921 921 922 922 // Find chevron icons inside buttons 923 - const chevronIcons = component.findAll('button span.i-carbon\\:chevron-right') 923 + const chevronIcons = component.findAll('button span.i-lucide\\:chevron-right') 924 924 expect(chevronIcons.length).toBeGreaterThan(0) 925 925 for (const icon of chevronIcons) { 926 926 expect(icon.attributes('aria-hidden')).toBe('true')
+1 -1
test/nuxt/components/VersionSelector.spec.ts
··· 544 544 545 545 // Should show loading spinner (motion-safe:animate-spin is applied) 546 546 await vi.waitFor(() => { 547 - const spinner = component.find('.i-carbon\\:rotate-180') 547 + const spinner = component.find('.i-svg-spinners\\:ring-resize') 548 548 expect(spinner.exists()).toBe(true) 549 549 }) 550 550
+4 -4
test/nuxt/components/compare/FacetRow.spec.ts
··· 33 33 description: 'Number of downloads per week', 34 34 }, 35 35 }) 36 - expect(component.find('.i-carbon\\:information').exists()).toBe(true) 36 + expect(component.find('.i-lucide\\:info').exists()).toBe(true) 37 37 }) 38 38 39 39 it('does not render description icon when not provided', async () => { 40 40 const component = await mountSuspended(FacetRow, { 41 41 props: baseProps, 42 42 }) 43 - expect(component.find('.i-carbon\\:information').exists()).toBe(false) 43 + expect(component.find('.i-lucide\\:info').exists()).toBe(false) 44 44 }) 45 45 }) 46 46 ··· 80 80 }, 81 81 }) 82 82 // All cells should show loading spinner 83 - expect(component.findAll('.i-carbon\\:circle-dash').length).toBe(2) 83 + expect(component.findAll('.i-svg-spinners\\:ring-resize').length).toBe(2) 84 84 }) 85 85 86 86 it('renders loading state for specific column loading', async () => { ··· 92 92 }, 93 93 }) 94 94 // Only second cell should show loading spinner 95 - const spinners = component.findAll('.i-carbon\\:circle-dash') 95 + const spinners = component.findAll('.i-svg-spinners\\:ring-resize') 96 96 expect(spinners.length).toBe(1) 97 97 }) 98 98 })
+4 -4
test/nuxt/components/compare/FacetSelector.spec.ts
··· 152 152 153 153 const component = await mountSuspended(FacetSelector) 154 154 155 - expect(component.find('.i-carbon\\:checkmark').exists()).toBe(true) 155 + expect(component.find('.i-lucide\\:check').exists()).toBe(true) 156 156 }) 157 157 158 158 it('shows add icon for unselected facets', async () => { ··· 161 161 162 162 const component = await mountSuspended(FacetSelector) 163 163 164 - expect(component.find('.i-carbon\\:add').exists()).toBe(true) 164 + expect(component.find('.i-lucide\\:plus').exists()).toBe(true) 165 165 }) 166 166 167 167 it('applies aria-pressed for selected state', async () => { ··· 211 211 const comingSoonButton = buttons.find(b => b.text().includes(comingSoonFacetLabel)) 212 212 213 213 // Should not have checkmark or add icon 214 - expect(comingSoonButton?.find('.i-carbon\\:checkmark').exists()).toBe(false) 215 - expect(comingSoonButton?.find('.i-carbon\\:add').exists()).toBe(false) 214 + expect(comingSoonButton?.find('.i-lucide\\:check').exists()).toBe(false) 215 + expect(comingSoonButton?.find('.i-lucide\\:plus').exists()).toBe(false) 216 216 }) 217 217 218 218 it('does not call toggleFacet when comingSoon facet is clicked', async () => {
+2 -4
test/nuxt/components/compare/PackageSelector.spec.ts
··· 54 54 55 55 const removeButtons = component 56 56 .findAll('button') 57 - .filter(b => b.find('.i-carbon\\:close').exists()) 57 + .filter(b => b.find('.i-lucide\\:x').exists()) 58 58 expect(removeButtons.length).toBe(2) 59 59 }) 60 60 ··· 65 65 }, 66 66 }) 67 67 68 - const removeButton = component 69 - .findAll('button') 70 - .find(b => b.find('.i-carbon\\:close').exists()) 68 + const removeButton = component.findAll('button').find(b => b.find('.i-lucide\\:x').exists()) 71 69 await removeButton!.trigger('click') 72 70 73 71 const emitted = component.emitted('update:modelValue')
+2
uno.config.ts
··· 16 16 '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 25"><path fill="currentColor" d="M16.346 24.11c-.785-.007-1.384-.235-2.034-.632-.932-.49-1.643-1.314-2.152-2.222-.808 1.003-1.888 1.611-3.097 1.955-.515.15-1.416.301-2.911-.24-2.154-.724-3.723-2.965-3.545-5.25-.033-.946.313-1.875.802-2.674-1.305-.7-2.37-1.876-2.777-3.318-.248-.79-.237-1.64-.146-2.452.327-1.916 1.764-3.582 3.615-4.182.738-1.683 2.35-2.938 4.176-3.193a5.54 5.54 0 0 1 3.528.7C13.351.89 16.043.383 18.1 1.436c1.568.75 2.69 2.312 2.962 4.015 1.492.598 2.749 1.817 3.242 3.365.33.958.34 2.013.127 2.997-.382 1.536-1.465 2.842-2.868 3.557.003.273.901 2.243.751 3.73-.033 1.858-1.211 3.62-2.846 4.475-.954.557-2.085.546-3.12.535m-4.47-5.35c1.322-.148 2.19-1.3 2.862-2.339.319-.473.562-1.002.803-1.506.314.287.58.828 1.075.957.522.163 1.133.03 1.453-.443.611-1.14.31-2.517-.046-3.699-.22-.679-.507-1.375-1.054-1.856.116-.823-.372-1.66-1.065-2.09-.592.47-1.491.468-2.061-.037-1.093 1.115-2.095 1.078-3.063.195-.217-.199-.632 1.212-2.088.413-.837.7-1.485 1.375-2.06 2.346-.559 1.046-1.143 1.976-1.194 3.113-.024.664.495 1.36 1.198 1.306.703.063 1.182-.63 1.714-.917.08.928.169 1.924.482 2.829.36 1.171 1.627 1.916 2.825 1.745zm.687-3.498c-.644-.394-.334-1.25-.36-1.871.064-.75.115-1.538.453-2.221.356-.487 1.226-.3 1.265.326-.026.628-.314 1.254-.28 1.905-.075.544.054 1.155-.186 1.653-.198.275-.6.355-.892.208m-2.81-.358c-.605-.329-.413-1.156-.508-1.73.08-.666.014-1.51.571-1.978.545-.38 1.287.271 1.03.869-.276.755-.096 1.58-.09 2.346a.712.712 0 0 1-1.002.493"/></svg>', 17 17 'vlt': 18 18 '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.9991 5.03666C7.9991 5.46387 7.93211 5.87545 7.80808 6.26145C7.45933 7.34674 7.1975 8.58253 7.7669 9.57009L10.389 14.1177C10.7072 14.6697 11.3617 14.9108 11.9989 14.9108V14.9108V14.9108C12.6352 14.9108 13.2886 14.6699 13.6064 14.1187L16.2301 9.5682C16.7993 8.58097 16.5379 7.34565 16.1895 6.26064C16.0656 5.87488 15.9987 5.46358 15.9987 5.03666C15.9987 2.82777 17.7894 1.03711 19.9983 1.03711C22.2071 1.03711 23.9978 2.82777 23.9978 5.03666C23.9978 7.24555 22.2071 9.03621 19.9983 9.03621V9.03621C19.3609 9.03621 18.7062 9.27733 18.3878 9.82951L15.7661 14.3766C15.1967 15.3642 15.4586 16.6001 15.8074 17.6854C15.9314 18.0715 15.9984 18.4831 15.9984 18.9104C15.9984 21.1193 14.2078 22.9099 11.9989 22.9099C9.79001 22.9099 7.99935 21.1193 7.99935 18.9104C7.99935 18.4834 8.06626 18.072 8.19016 17.6862C8.53863 16.6012 8.80017 15.3657 8.23092 14.3785L5.60752 9.8285C5.28961 9.27712 4.63601 9.03621 3.99955 9.03621V9.03621C1.79066 9.03621 0 7.24555 0 5.03666C0 2.82777 1.79066 1.03711 3.99955 1.03711C6.20844 1.03711 7.9991 2.82777 7.9991 5.03666Z" fill="currentColor"></path></svg>', 19 + 'a11y': 20 + '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="6" r="1"/><path d="m9 18 3-5 3 5"/><path d="m8 10 8 0"/><path d="M12 10v4"/></svg>', 19 21 } 20 22 21 23 export default defineConfig({