@@ -729,21 +729,28 @@ function setTab(tab: SettingsTab): void {
729729 class =" listing-row"
730730 :class =" { off: !isSkillEnabled(skill.name) }"
731731 >
732- <div class =" listing-main" >
733- <span class =" listing-name mono" >{{ skill.name }}</span >
734- <span v-if =" skill.disableModelInvocation" class =" tag" >{{ t('settings.skills.slashOnly') }}</span >
735- <span class =" listing-desc" >{{ skill.description }}</span >
736- <button
737- type =" button"
738- class =" switch sm"
739- role =" switch"
740- :class =" { on: isSkillEnabled(skill.name) }"
741- :aria-checked =" isSkillEnabled(skill.name)"
742- :aria-label =" t('settings.skills.toggleAria', { name: skill.name })"
743- @click =" toggleSkill(skill.name)"
744- >
745- <span class =" knob" />
746- </button >
732+ <div class =" listing-top" >
733+ <div class =" listing-main" >
734+ <svg class =" listing-glyph" viewBox =" 0 0 24 24" fill =" none" stroke =" currentColor" stroke-width =" 1.5" aria-hidden =" true" >
735+ <path d =" M12 3l2.1 4.9 5.4.5-4.1 3.6 1.2 5.3L12 14.6 7.4 17.3l1.2-5.3L4.5 8.4l5.4-.5L12 3z" stroke-linejoin =" round" />
736+ </svg >
737+ <span class =" listing-name mono" >{{ skill.name }}</span >
738+ <span v-if =" skill.disableModelInvocation" class =" tag" >{{ t('settings.skills.slashOnly') }}</span >
739+ <span class =" listing-desc" >{{ skill.description }}</span >
740+ </div >
741+ <div class =" row-actions" >
742+ <button
743+ type =" button"
744+ class =" switch sm"
745+ role =" switch"
746+ :class =" { on: isSkillEnabled(skill.name) }"
747+ :aria-checked =" isSkillEnabled(skill.name)"
748+ :aria-label =" t('settings.skills.toggleAria', { name: skill.name })"
749+ @click =" toggleSkill(skill.name)"
750+ >
751+ <span class =" knob" />
752+ </button >
753+ </div >
747754 </div >
748755 </div >
749756 </div >
@@ -765,16 +772,31 @@ function setTab(tab: SettingsTab): void {
765772 <p v-else-if =" (connectors?.length ?? 0) === 0" class =" sec-empty" >{{ t('settings.connectors.empty') }}</p >
766773 <div v-else class =" listing" >
767774 <div v-for =" connector in connectors" :key =" connector.id" class =" listing-row" >
768- <div class =" listing-main" >
769- <span class =" dot" :class =" `s-${connector.status}`" aria-hidden =" true" />
770- <span class =" listing-name" >{{ connector.name }}</span >
771- <span class =" tag" >{{ connector.transport }}</span >
772- <span class =" listing-meta" >{{ t('settings.connectors.tools', { count: connector.toolCount }) }}</span >
773- <button type =" button" class =" act" @click =" emit('restartConnector', connector.id)" >
774- {{ t('settings.connectors.restart') }}
775- </button >
775+ <div class =" listing-top" >
776+ <div class =" listing-main" >
777+ <svg class =" listing-glyph" viewBox =" 0 0 24 24" fill =" none" stroke =" currentColor" stroke-width =" 1.5" aria-hidden =" true" >
778+ <path d =" M9 3v5M15 3v5M6 8h12v3a6 6 0 0 1-12 0V8zM12 17v4" stroke-linecap =" round" />
779+ </svg >
780+ <span class =" listing-name" >{{ connector.name }}</span >
781+ <span class =" tag" >{{ connector.transport }}</span >
782+ <span class =" listing-desc" >{{ t(`settings.connectors.status.${connector.status}`) }}</span >
783+ <span class =" listing-meta" >{{ t('settings.connectors.tools', { count: connector.toolCount }) }}</span >
784+ </div >
785+ <div class =" row-actions" >
786+ <span class =" dot" :class =" `s-${connector.status}`" aria-hidden =" true" />
787+ <button
788+ type =" button"
789+ class =" icon-btn"
790+ :title =" t('settings.connectors.restart')"
791+ :aria-label =" t('settings.connectors.restart')"
792+ @click =" emit('restartConnector', connector.id)"
793+ >
794+ <svg viewBox =" 0 0 24 24" fill =" none" stroke =" currentColor" stroke-width =" 1.5" aria-hidden =" true" >
795+ <path d =" M20 12a8 8 0 1 1-2.6-5.9M20 4v5h-5" stroke-linecap =" round" stroke-linejoin =" round" />
796+ </svg >
797+ </button >
798+ </div >
776799 </div >
777- <p class =" listing-desc" >{{ t(`settings.connectors.status.${connector.status}`) }}</p >
778800 <p v-if =" connector.lastError" class =" listing-error" >{{ connector.lastError }}</p >
779801 </div >
780802 </div >
@@ -800,22 +822,29 @@ function setTab(tab: SettingsTab): void {
800822 class =" listing-row"
801823 :class =" { off: !plugin.enabled }"
802824 >
803- <div class =" listing-main" >
804- <span class =" listing-name" >{{ plugin.displayName }}</span >
805- <span v-if =" plugin.version" class =" tag" >{{ plugin.version }}</span >
806- <span class =" tag" >{{ plugin.source }}</span >
807- <span class =" listing-meta" >{{ t('settings.plugins.counts', { skills: plugin.skillCount, servers: plugin.mcpServerCount }) }}</span >
808- <button
809- type =" button"
810- class =" switch sm"
811- role =" switch"
812- :class =" { on: plugin.enabled }"
813- :aria-checked =" plugin.enabled"
814- :aria-label =" t('settings.plugins.toggleAria', { name: plugin.displayName })"
815- @click =" emit('setPluginEnabled', { pluginId: plugin.id, enabled: !plugin.enabled })"
816- >
817- <span class =" knob" />
818- </button >
825+ <div class =" listing-top" >
826+ <div class =" listing-main" >
827+ <svg class =" listing-glyph" viewBox =" 0 0 24 24" fill =" none" stroke =" currentColor" stroke-width =" 1.5" aria-hidden =" true" >
828+ <path d =" M10 4a2 2 0 1 1 4 0v1h3a1 1 0 0 1 1 1v3h1a2 2 0 1 1 0 4h-1v3a1 1 0 0 1-1 1h-3v-1a2 2 0 1 0-4 0v1H6a1 1 0 0 1-1-1v-3H4a2 2 0 1 1 0-4h1V6a1 1 0 0 1 1-1h4V4z" stroke-linejoin =" round" />
829+ </svg >
830+ <span class =" listing-name" >{{ plugin.displayName }}</span >
831+ <span v-if =" plugin.version" class =" tag" >{{ plugin.version }}</span >
832+ <span class =" tag" >{{ plugin.source }}</span >
833+ <span class =" listing-meta" >{{ t('settings.plugins.counts', { skills: plugin.skillCount, servers: plugin.mcpServerCount }) }}</span >
834+ </div >
835+ <div class =" row-actions" >
836+ <button
837+ type =" button"
838+ class =" switch sm"
839+ role =" switch"
840+ :class =" { on: plugin.enabled }"
841+ :aria-checked =" plugin.enabled"
842+ :aria-label =" t('settings.plugins.toggleAria', { name: plugin.displayName })"
843+ @click =" emit('setPluginEnabled', { pluginId: plugin.id, enabled: !plugin.enabled })"
844+ >
845+ <span class =" knob" />
846+ </button >
847+ </div >
819848 </div >
820849 <p v-if =" plugin.hasErrors" class =" listing-error" >{{ t('settings.plugins.hasErrors') }}</p >
821850 </div >
@@ -837,14 +866,20 @@ function setTab(tab: SettingsTab): void {
837866 <p v-if =" (subagents?.length ?? 0) === 0" class =" sec-empty" >{{ t('settings.subagents.empty') }}</p >
838867 <div v-else class =" listing" >
839868 <div v-for =" agent in subagents" :key =" agent.name" class =" listing-row" >
840- <div class =" listing-main" >
841- <span class =" listing-name mono" >{{ agent.name }}</span >
842- <span class =" tag" >{{ agent.source }}</span >
843- <span class =" tag" >{{ t('settings.subagents.tools', { count: agent.tools.length }) }}</span >
844- <span v-if =" agent.model" class =" listing-meta" >{{ agent.model }}</span >
845- <span v-if =" agent.effort" class =" tag" >{{ agent.effort }}</span >
869+ <div class =" listing-top" >
870+ <div class =" listing-main" >
871+ <svg class =" listing-glyph" viewBox =" 0 0 24 24" fill =" none" stroke =" currentColor" stroke-width =" 1.5" aria-hidden =" true" >
872+ <rect x =" 4" y =" 8" width =" 16" height =" 11" rx =" 3" />
873+ <path d =" M12 4v4M9 13h.01M15 13h.01" stroke-linecap =" round" />
874+ </svg >
875+ <span class =" listing-name mono" >{{ agent.name }}</span >
876+ <span class =" tag" >{{ agent.source }}</span >
877+ <span class =" tag" >{{ t('settings.subagents.tools', { count: agent.tools.length }) }}</span >
878+ <span v-if =" agent.effort" class =" tag" >{{ agent.effort }}</span >
879+ <span v-if =" agent.model" class =" listing-meta" >{{ agent.model }}</span >
880+ </div >
846881 </div >
847- <p v-if =" agent.description" class =" listing-desc" >{{ agent.description }}</p >
882+ <p v-if =" agent.description" class =" listing-desc listing-indent " >{{ agent.description }}</p >
848883 </div >
849884 </div >
850885 </section >
@@ -871,11 +906,16 @@ function setTab(tab: SettingsTab): void {
871906 :key =" `${group.event}/${index}`"
872907 class =" listing-row"
873908 >
874- <div class =" listing-main" >
875- <span class =" listing-name mono" >{{ hook.matcher ?? '*' }}</span >
876- <span class =" tag" >{{ hook.type ?? 'command' }}</span >
877- <span v-if =" hook.async === true" class =" tag" >{{ t('settings.hooks.async') }}</span >
878- <span v-if =" hook.timeout !== undefined" class =" listing-meta" >{{ t('settings.hooks.timeout', { seconds: hook.timeout }) }}</span >
909+ <div class =" listing-top" >
910+ <div class =" listing-main" >
911+ <svg class =" listing-glyph" viewBox =" 0 0 24 24" fill =" none" stroke =" currentColor" stroke-width =" 1.5" aria-hidden =" true" >
912+ <path d =" M13 3L5 14h6l-2 7 8-11h-6l2-7z" stroke-linejoin =" round" />
913+ </svg >
914+ <span class =" listing-name mono" >{{ hook.matcher ?? '*' }}</span >
915+ <span class =" tag" >{{ hook.type ?? 'command' }}</span >
916+ <span v-if =" hook.async === true" class =" tag" >{{ t('settings.hooks.async') }}</span >
917+ <span v-if =" hook.timeout !== undefined" class =" listing-meta" >{{ t('settings.hooks.timeout', { seconds: hook.timeout }) }}</span >
918+ </div >
879919 </div >
880920 <p class =" listing-path mono" >{{ hook.command ?? hook.url ?? '—' }}</p >
881921 </div >
@@ -917,9 +957,11 @@ function setTab(tab: SettingsTab): void {
917957 <p v-if =" usageByModel.length === 0" class =" sec-empty" >{{ t('settings.usage.empty') }}</p >
918958 <div v-else class =" listing" >
919959 <div v-for =" entry in usageByModel" :key =" entry.model" class =" listing-row" >
920- <div class =" listing-main" >
921- <span class =" listing-name" >{{ entry.model }}</span >
922- <span class =" listing-meta" >{{ entry.share }}</span >
960+ <div class =" listing-top" >
961+ <div class =" listing-main" >
962+ <span class =" listing-name" >{{ entry.model }}</span >
963+ <span class =" listing-meta" >{{ entry.share }}</span >
964+ </div >
923965 </div >
924966 <div class =" usage-bar" ><span :style =" { width: entry.share }" /></div >
925967 </div >
@@ -1353,69 +1395,110 @@ function setTab(tab: SettingsTab): void {
13531395.listing {
13541396 display : flex ;
13551397 flex-direction : column ;
1356- gap : 6 px ;
1398+ gap : 2 px ;
13571399}
13581400.listing-head {
13591401 margin : 14px 0 6px ;
13601402 font-size : calc (var (--ui-font-size ) - 2px );
13611403 font-weight : 600 ;
13621404 color : var (--muted );
13631405}
1406+ /* Rows are flat rather than carded: the leading glyph, the name and the right
1407+ action cluster carry the structure, so a border would only add noise. */
13641408.listing-row {
1365- padding : 8px 12px ;
1366- border : 1px solid var (--line );
1367- border-radius : 10px ;
1368- background : var (--panel );
1409+ display : flex ;
1410+ flex-direction : column ;
1411+ padding : 5px 0 ;
13691412}
1370- /* A disabled skill stays readable but clearly recedes. */
1371- .listing-row.off .listing-name ,
1372- .listing-row.off .listing-desc {
1373- color : var (--faint );
1413+ .listing-top {
1414+ display : flex ;
1415+ align-items : center ;
1416+ gap : 12px ;
1417+ min-width : 0 ;
13741418}
1419+ /* Only the content fades when an entry is off — the switch that turns it back
1420+ on has to stay at full contrast. */
1421+ .listing-row.off .listing-main { opacity : 0.5 ; }
13751422.listing-main {
13761423 display : flex ;
13771424 align-items : center ;
13781425 gap : 8px ;
1426+ flex : 1 ;
13791427 min-width : 0 ;
13801428}
1429+ .row-actions {
1430+ display : flex ;
1431+ flex : none ;
1432+ align-items : center ;
1433+ gap : 4px ;
1434+ }
1435+ .listing-glyph {
1436+ flex : none ;
1437+ width : 15px ;
1438+ height : 15px ;
1439+ color : var (--faint );
1440+ }
13811441.listing-name {
1382- font-weight : 600 ;
1442+ flex : none ;
1443+ font-weight : 500 ;
13831444 color : var (--ink );
13841445}
13851446.listing-meta {
1386- margin-left : auto ;
1447+ flex : none ;
13871448 font-size : calc (var (--ui-font-size ) - 2px );
1388- color : var (--muted );
1449+ color : var (--faint );
13891450}
13901451.listing-desc ,
13911452.listing-path ,
13921453.listing-error {
1393- margin : 3 px 0 0 ;
1454+ margin : 2 px 0 0 ;
13941455 font-size : calc (var (--ui-font-size ) - 2px );
13951456 color : var (--muted );
13961457}
1397- /* On the skills page the description shares the row with the name, so it
1398- truncates instead of wrapping — the switch must stay on the same line . */
1458+ /* Inside a row the description shares the line with the name, so it truncates
1459+ instead of wrapping and pushes the meta text to the right edge . */
13991460.listing-main .listing-desc {
1400- margin : 0 0 0 auto ;
1401- padding-left : 10px ;
1461+ margin : 0 ;
14021462 min-width : 0 ;
14031463 overflow : hidden ;
14041464 text-overflow : ellipsis ;
14051465 white-space : nowrap ;
1466+ color : var (--faint );
14061467}
1468+ .listing-main .listing-meta { margin-left : auto ; }
14071469.listing-path {
1470+ padding-left : 27px ;
14081471 color : var (--faint );
14091472 word-break : break-all ;
14101473}
1474+ .listing-error { padding-left : 27px ; }
1475+ .listing-indent { padding-left : 27px ; }
1476+
1477+ /* Ghost icon button for the per-row actions — no chrome until hover. */
1478+ .icon-btn {
1479+ display : flex ;
1480+ flex : none ;
1481+ align-items : center ;
1482+ justify-content : center ;
1483+ width : 24px ;
1484+ height : 24px ;
1485+ padding : 0 ;
1486+ border : none ;
1487+ border-radius : 7px ;
1488+ background : transparent ;
1489+ color : var (--faint );
1490+ cursor : pointer ;
1491+ }
1492+ .icon-btn svg { width : 15px ; height : 15px ; }
1493+ .icon-btn :hover { background : var (--soft ); color : var (--ink ); }
14111494.listing-error {
14121495 color : var (--err );
14131496}
14141497.tag {
14151498 flex : none ;
14161499 padding : 1px 6px ;
14171500 border-radius : 5px ;
1418- border : 1 px solid var (--line );
1501+ background : var (--soft );
14191502 font-size : calc (var (--ui-font-size ) - 3px );
14201503 color : var (--muted );
14211504}
0 commit comments