/**
 * Side card settings section chrome (DSH-native tokens throughout):
 * - the section is a column of GROUP CONTAINER cards (the PluginCard recipe:
 *   l2 hairline, 16px radius, layer-3 fill) with a heading + inventory count
 *   badge (the settings catalogHeading recipe), opening with a one-line
 *   intro (the DSH section heading+intro recipe);
 * - 常规 holds full-width settings rows (the DSH settings-row recipe:
 *   title/desc left + control right, hairline separators) whose toggles are
 *   custom switches — a real checkbox (native semantics and focus) driving
 *   a styled track/thumb;
 * - the feature inventories are responsive GRIDS of small toggle cards
 *   (auto-fill columns — several cards per row, wrapping): icon chip +
 *   title + type id, the card's on/off state IS its visual state
 *   (enabled = softened brand border + tinted fill + a compact brand
 *   switch knob at the far right — the card itself is the toggle;
 *   disabled = neutral hairline + dimmed, no knob); every card shares a
 *   uniform min-height so rows stay equal whether or not they carry a
 *   settings strip;
 * - features that declare related settings carry a labeled SETTINGS STRIP
 *   across the card's bottom edge (gear icon + text, hairline-separated)
 *   opening a native Modal (wider than the primitive default) whose rows
 *   follow the same row recipe with switch controls and a Done footer;
 * - the width input stays a native settings row (a value, not a switch).
 */

.section {
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: 100%;
  max-width: 760px;
  /* The DSH settings shell's `.options` area owns vertical scrolling. Keep
     this page a plain content column like Plugins → Plugin list so its
     scrollbar stays at the shell edge instead of being inset by the options
     area's right padding. */
}

/* One-line section intro (the DSH section heading+intro recipe). */
.intro {
  margin: 0;
  padding: 0 2px;
  font-size: 13px;
  line-height: 20px;
  color: var(--dsw-alias-label-tertiary);
}

/* Group container: the DSH card recipe (PluginCard) — l2 hairline, r16,
   layer-3 fill; holds its own heading + stacked rows / card grid. */
.group {
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 20px;
  box-sizing: border-box;
  border: 1px solid var(--dsw-alias-border-l2);
  border-radius: 16px;
  background: var(--dsw-alias-bg-layer-3);
}

/* Group heading: 13/600 + the inventory count badge (the settings
   catalogHeading recipe: count in tabular-nums, tertiary). */
.groupHeading {
  display: flex;
  align-items: baseline;
  gap: 7px;
  padding: 0 2px 6px;
  font-size: 13px;
  line-height: 20px;
  font-weight: 600;
  color: var(--dsw-alias-label-primary);
}

/* The inventory count: a soft-accent pill (the versionBadgeTag token recipe)
   so the count reads as metadata, not as part of the heading text. */
.count {
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--dsw-alias-accent-soft, var(--dsw-alias-bg-layer-2));
  font-size: 11px;
  line-height: 16px;
  font-weight: 500;
  color: var(--dsw-alias-label-secondary);
  font-variant-numeric: tabular-nums;
}

/* Responsive inventory: as many small cards per row as the width allows. */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 12px;
}

/* One small toggle card (visual chrome; the interactive part is .cardMain).
   A uniform min-height keeps every inventory card the same height across
   rows whether or not it carries a settings strip (strip cards are
   naturally taller); overflow:hidden clips the strip to the card's radius. */
.card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 106px;
  overflow: hidden;
  border-radius: 12px;
  border: 1px solid var(--dsw-alias-border-l2);
  background: transparent;
  font: inherit;
  color: inherit;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease;
}

/* Hover affordance on disabled cards only (enabled cards are already lit). */
.card:not(.cardOn):hover {
  background: var(--dsw-alias-interactive-bg-hover);
  border-color: var(--dsw-alias-label-dimmed);
}

/* Enabled = highlighted: a SOFTENED brand border (color-mix, the icon-chip
   precedent) + tinted fill — full-strength brand reads harsh at card scale. */
.cardOn {
  border-color: color-mix(in srgb, var(--dsw-alias-button-primary-fill) 45%, transparent);
  background: var(--dsw-alias-interactive-bg-active);
}

/* The card's switch: the whole main area (top row + desc) flips the feature.
   flex:1 lets the main area absorb the extra height of the uniform card
   (cards without a settings strip stretch to match the strip cards). */
.cardMain {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 6px;
  width: 100%;
  padding: 12px;
  border: 0;
  border-radius: inherit;
  background: transparent;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.cardMain:focus-visible,
.cardSettings:focus-visible,
.rowGear:focus-visible {
  outline: 2px solid var(--dsw-alias-border-l4);
  outline-offset: 2px;
}

.cardTop {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  min-height: 28px;
}

/* The icon sits in a rounded chip: brand-tinted while the card is on,
   neutral (layer-2 fill + hairline) while off. */
.cardIconChip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 28px;
  height: 28px;
  border-radius: 8px;
  border: 1px solid var(--dsw-alias-border-l2);
  background: var(--dsw-alias-bg-layer-2);
  color: var(--dsw-alias-label-tertiary);
}

.cardOn .cardIconChip {
  border-color: color-mix(in srgb, var(--dsw-alias-button-primary-fill) 35%, transparent);
  background: color-mix(in srgb, var(--dsw-alias-button-primary-fill) 12%, transparent);
  color: var(--dsw-alias-button-primary-fill);
}

.cardTitle {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  line-height: 20px;
  font-weight: 600;
  color: var(--dsw-alias-label-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cardOn .cardTitle {
  color: var(--dsw-alias-label-primary);
}

/* The compact on/off switch knob at the card's far right (enabled only):
   the card itself is the toggle (aria-pressed on .cardMain), so this is a
   PURELY VISUAL switch — same track/thumb geometry as the row switches,
   one size down. Off cards show no knob (neutral card = off). */
.cardSwitch {
  display: inline-flex;
  align-items: center;
  flex: none;
}

.cardSwitchTrack {
  display: inline-flex;
  align-items: center;
  width: 30px;
  height: 16px;
  padding: 2px;
  box-sizing: border-box;
  border-radius: 8px;
  background: var(--dsw-alias-bg-layer-2);
  border: 1px solid var(--dsw-alias-border-l2);
  transition: background 0.15s ease, border-color 0.15s ease;
}

.cardSwitchThumb {
  display: block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--dsw-alias-label-tertiary);
  transition: transform 0.15s ease, background 0.15s ease;
}

.cardOn .cardSwitchTrack {
  border-color: var(--dsw-alias-button-primary-fill);
  background: var(--dsw-alias-button-primary-fill);
}

.cardOn .cardSwitchThumb {
  transform: translateX(14px);
  background: var(--dsw-alias-bg-layer-3);
}

.cardDesc {
  font-size: 11px;
  line-height: 16px;
  color: var(--dsw-alias-label-tertiary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The "add plugin" card: same grid cell / chrome as the inventory cards
   (it shares .card), but a DASHED border — the repo's first dashed surface;
   the hover accent follows the existing drag-drop dashed outlines
   (sidebar.module.css .dropCenter / .tabBarDrop). */
.addCard {
  align-items: flex-start;
  padding: 12px;
  border-style: dashed;
  border-color: var(--dsw-alias-border-l2);
  text-align: left;
}

.addCard:hover {
  background: var(--dsw-alias-interactive-bg-hover);
  border-color: var(--dsw-alias-interactive-bg-hover-accent);
  color: var(--dsw-alias-label-primary);
}

.addCard:hover .cardTitle {
  color: var(--dsw-alias-label-primary);
}

.addCard:hover .cardIconChip {
  border-color: color-mix(in srgb, var(--dsw-alias-button-primary-fill) 35%, transparent);
  color: var(--dsw-alias-button-primary-fill);
}

.addCard:focus-visible {
  outline: 2px solid var(--dsw-alias-border-l4);
  outline-offset: 2px;
}

.cardOn .cardDesc {
  color: var(--dsw-alias-label-secondary);
}

/* The settings strip: a labeled full-width footer across the card's bottom
   edge (gear icon + "功能设置" text), hairline-separated from the toggle
   area. This is the SECONDARY settings entry — it must be discoverable at
   rest (not a hover-only ghost), so it keeps a steady secondary-ink label
   and answers hover with the brand-accent tint + brand ink. */
.cardSettings {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: 6px 12px;
  border: 0;
  border-top: 1px solid var(--dsw-alias-border-l1);
  background: transparent;
  color: var(--dsw-alias-label-secondary);
  font: inherit;
  font-size: 11px;
  line-height: 16px;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}

.cardOn .cardSettings {
  border-top-color: color-mix(in srgb, var(--dsw-alias-button-primary-fill) 18%, transparent);
}

.cardSettings:hover {
  background: var(--dsw-alias-interactive-bg-hover-accent);
  color: var(--dsw-alias-brand-primary);
}

/* The gear icon button on a general settings ROW (the position-compat
   row's "customize the strip height" entry): a bordered chip (not a ghost)
   so it reads as a control at rest; hover answers with the accent tint. */
.rowGear {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 1px solid var(--dsw-alias-border-l2);
  border-radius: 6px;
  background: transparent;
  color: var(--dsw-alias-label-secondary);
  cursor: pointer;
  flex: none;
  transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}

.rowGear:hover {
  border-color: var(--dsw-alias-interactive-bg-hover-accent);
  background: var(--dsw-alias-interactive-bg-hover-accent);
  color: var(--dsw-alias-brand-primary);
}

/* Settings-row recipe (the DSH General section rows): title/desc left,
   control right, hairline separators (stripped on the last row). */
.row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 2px;
  border-bottom: 1px solid var(--dsw-alias-border-l2);
}

.row:last-child {
  border-bottom: none;
}

.rowText {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.title {
  font-size: 14px;
  line-height: 22px;
  color: var(--dsw-alias-label-primary);
}

.desc {
  font-size: 12px;
  line-height: 18px;
  color: var(--dsw-alias-label-tertiary);
}

/* Custom switch: a real checkbox (native semantics + focus, visually
   hidden) driving a styled 36x20 track with a sliding thumb. */
.switch {
  position: relative;
  display: inline-flex;
  flex: none;
  cursor: pointer;
}

.switchInput {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
}

.switchTrack {
  display: inline-flex;
  align-items: center;
  width: 36px;
  height: 20px;
  padding: 2px;
  box-sizing: border-box;
  border-radius: 10px;
  border: 1px solid var(--dsw-alias-border-l2);
  background: var(--dsw-alias-bg-layer-2);
  transition: background 0.15s ease, border-color 0.15s ease;
}

.switchThumb {
  display: block;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--dsw-alias-label-tertiary);
  transition: transform 0.15s ease, background 0.15s ease;
}

.switch:hover .switchTrack {
  border-color: var(--dsw-alias-label-dimmed);
}

.switchInput:checked + .switchTrack {
  border-color: var(--dsw-alias-button-primary-fill);
  background: var(--dsw-alias-button-primary-fill);
}

.switchInput:checked + .switchTrack .switchThumb {
  transform: translateX(16px);
  background: var(--dsw-alias-bg-layer-3);
}

.switchInput:focus-visible + .switchTrack {
  outline: 2px solid var(--dsw-alias-state-business-primary);
  outline-offset: 2px;
}

.control {
  flex: none;
  display: flex;
  align-items: center;
  gap: 6px;
}

.percentInput {
  width: 76px;
}

/* Text/number rows in the settings popup: the free-form input (e.g. the
   terminal font family) gets a generous width; numeric rows (font size)
   keep the compact width of the general number inputs. */
.typedInput {
  width: 200px;
}

.typedInputNumber {
  width: 76px;
}

/* Select rows: the closed anchor is a compact button (selected option's
   icon when the options carry icons, plus title and a chevron); the dropdown
   itself is the primitives Menu (portal). */
.selectAnchor {
  display: flex;
  align-items: center;
  gap: 6px;
  max-width: 220px;
  padding: 4px 8px;
  border: 1px solid var(--dsw-alias-border-l2);
  border-radius: 8px;
  background: var(--dsw-alias-bg-layer-3);
  color: var(--dsw-alias-label-primary);
  font-size: 13px;
  line-height: 20px;
  cursor: pointer;
}

.selectAnchor:hover {
  border-color: var(--dsw-alias-label-dimmed);
}

.selectAnchorIcon {
  display: inline-flex;
  flex: none;
}

.selectAnchorText {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* One big-icon option card inside the select dropdown. */
.selectOption {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 200px;
}

.selectOptionIcon {
  display: inline-flex;
  flex: none;
  color: var(--dsw-alias-label-secondary);
}

.selectOptionText {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.suffix {
  font-size: 14px;
  line-height: 22px;
  color: var(--dsw-alias-label-secondary);
}

/* The multi-line custom-CSS input (scheme `custom`): monospace, generous
   height, resizable — same surface tokens as the typed inputs. */
.cssTextArea {
  width: 100%;
  box-sizing: border-box;
  min-height: 120px;
  padding: 8px 10px;
  border: 1px solid var(--dsw-alias-border-l2);
  border-radius: 8px;
  background: var(--dsw-alias-bg-layer-3);
  color: var(--dsw-alias-label-primary);
  font-family: var(--ds-font-family-code, monospace);
  font-size: 12px;
  line-height: 1.6;
  resize: vertical;
}

.cssTextArea:focus-visible {
  outline: 2px solid var(--dsw-alias-state-business-primary);
  outline-offset: 2px;
}

/* Secondary settings popup: a wider dialog than the primitive default (the
   dialog portals to document.body; the doubled class keeps the width rule
   above the primitive's .dialog regardless of stylesheet order). */
.popupDialog.popupDialog {
  width: min(460px, 100%);
}

/* Popup rows: each setting gets the same outer chrome as a plugin-list
   PluginCard (l2 hairline, 12px radius, layer-3 fill). The row's title,
   description and control geometry stay unchanged inside that frame.
   The body scrolls INTERNALLY once a feature declares many rows (e.g.
   Terminal's six) — the dialog shell and its Done footer stay put; a thin
   token-driven scrollbar makes the scrollable region discoverable.
   box-sizing:border-box keeps width:100% + the scrollbar gutter from
   overflowing horizontally (a content-box width would add the 4px pad and
   show a horizontal scrollbar); overflow-x:hidden is the belt-and-braces
   guarantee that rows always FILL the width and never slide sideways. */
.popupRows {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
  box-sizing: border-box;
  max-height: min(52vh, 440px);
  overflow-y: auto;
  overflow-x: hidden;
  padding-right: 4px;
  scrollbar-width: thin;
  scrollbar-color: var(--dsw-alias-scrollbar-bg-l2, transparent) transparent;
}

.popupRows::-webkit-scrollbar {
  width: 6px;
}

.popupRows::-webkit-scrollbar-thumb {
  border-radius: 3px;
  background: var(--dsw-alias-scrollbar-bg-l2, var(--dsw-alias-border-l2));
}

.popupRows::-webkit-scrollbar-thumb:hover {
  background: var(--dsw-alias-scrollbar-hover-l2, var(--dsw-alias-label-dimmed));
}

.popupRow {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-width: 0;
  padding: 12px 14px;
  border: 1px solid var(--dsw-alias-border-l2);
  border-radius: 12px;
  background: var(--dsw-alias-bg-layer-3);
  transition: border-color 0.16s, background 0.16s;
}

.popupRow:hover {
  border-color: var(--dsw-alias-label-dimmed);
}

/* The popup's Done button: the settings primary-button recipe
   (PluginCard .save: label-primary fill, inverted surface text). */
.done {
  appearance: none;
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 5px 14px;
  font: inherit;
  font-size: 13px;
  line-height: 1.5;
  cursor: pointer;
  background: var(--dsw-alias-label-primary);
  color: var(--dsw-alias-bg-layer-3);
}

.done:focus-visible {
  outline: 2px solid var(--dsw-alias-brand-primary);
  outline-offset: 1px;
}

.error {
  padding: 10px 0 2px;
  font-size: 12px;
  line-height: 17px;
  color: var(--dsw-alias-state-error-primary);
}

/* ── "Add plugin" modal ──────────────────────────────────────────────── */

/* A wide dialog like the settings popup (doubled class keeps the width
   rule above the primitive's .dialog regardless of stylesheet order). */
.pluginModal.pluginModal {
  width: min(560px, 100%);
}

.pluginList {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 100%;
}

/* The GitHub topic entry: a full-width secondary BUTTON (not a link — it
   opens a real new browser tab via window.open, bypassing the sidebar
   link takeover). */
.pluginTopicBtn {
  width: 100%;
  appearance: none;
  border: 1px solid var(--dsw-alias-border-l2);
  border-radius: 8px;
  padding: 6px 12px;
  font: inherit;
  font-size: 12px;
  line-height: 18px;
  color: var(--dsw-alias-label-secondary);
  background: var(--dsw-alias-bg-layer-1);
  cursor: pointer;
}

.pluginTopicBtn:hover {
  background: var(--dsw-alias-interactive-bg-hover);
  border-color: var(--dsw-alias-interactive-bg-hover-accent);
  color: var(--dsw-alias-label-primary);
}

.pluginTopicBtn:focus-visible {
  outline: 2px solid var(--dsw-alias-border-l4);
  outline-offset: 1px;
}

.pluginEmpty {
  padding: 20px 2px;
  font-size: 12px;
  line-height: 18px;
  color: var(--dsw-alias-label-tertiary);
}

/* One catalog entry: name + install button on the head row, description,
   then the install command in a mono block (the exact script that gets
   pre-typed into the terminal — review it here before installing). */
.pluginEntry {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px;
  border: 1px solid var(--dsw-alias-border-l2);
  border-radius: 12px;
  background: var(--dsw-alias-bg-layer-1);
}

.pluginEntryHead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.pluginEntryActions {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: none;
}

/* The per-entry "jump" button: opens the plugin repo in a REAL new browser
   tab (window.open — a button, so the sidebar link takeover cannot reroute
   it). Secondary style, quieter than the Install button. */
.pluginJumpBtn {
  flex: none;
  appearance: none;
  border: 1px solid var(--dsw-alias-border-l2);
  border-radius: 8px;
  padding: 3px 12px;
  font: inherit;
  font-size: 12px;
  line-height: 1.5;
  cursor: pointer;
  background: transparent;
  color: var(--dsw-alias-label-secondary);
}

.pluginJumpBtn:hover {
  background: var(--dsw-alias-interactive-bg-hover);
  border-color: var(--dsw-alias-interactive-bg-hover-accent);
  color: var(--dsw-alias-label-primary);
}

.pluginJumpBtn:focus-visible {
  outline: 2px solid var(--dsw-alias-border-l4);
  outline-offset: 1px;
}

/* The plugin name: a BUTTON (not an anchor — an anchor would be caught by
   the sidebar link takeover at document capture, ignoring target=_blank)
   styled like a link; opens the repo in a real new browser tab. */
.pluginName {
  appearance: none;
  min-width: 0;
  padding: 0;
  border: 0;
  background: transparent;
  font: inherit;
  font-size: 13px;
  line-height: 20px;
  font-weight: 600;
  color: var(--dsw-alias-label-primary);
  text-align: left;
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}

.pluginName:hover {
  text-decoration: underline;
  color: var(--dsw-alias-button-primary-fill);
}

.pluginDesc {
  font-size: 12px;
  line-height: 18px;
  color: var(--dsw-alias-label-secondary);
}

.pluginInstall {
  display: block;
  padding: 6px 10px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  line-height: 16px;
  color: var(--dsw-alias-label-secondary);
  background: var(--dsw-alias-bg-layer-2);
  border: 1px solid var(--dsw-alias-border-l1);
  border-radius: 8px;
  overflow-x: auto;
  white-space: nowrap;
}

/* The per-entry copy button: copies the install script to the
   clipboard (the settings primary-button recipe, smaller than .done). */
.pluginCopyBtn {
  flex: none;
  appearance: none;
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 3px 12px;
  font: inherit;
  font-size: 12px;
  line-height: 1.5;
  cursor: pointer;
  background: var(--dsw-alias-label-primary);
  color: var(--dsw-alias-bg-layer-3);
}

.pluginCopyBtn:hover {
  background: var(--dsw-alias-button-primary-hover);
}

.pluginCopyBtn:focus-visible {
  outline: 2px solid var(--dsw-alias-brand-primary);
  outline-offset: 1px;
}

@media (prefers-reduced-motion: reduce) {
  .card,
  .cardSettings,
  .cardSwitchTrack,
  .cardSwitchThumb,
  .rowGear,
  .popupRow,
  .switchTrack,
  .switchThumb {
    transition: none;
  }
}

/* The managing plugin's identity badge: name + version pill, token-driven
   (labels via --dsw-alias-label-*, surface via --dsw-alias-bg-layer-2). */
.versionBadge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  align-self: flex-start;
  padding: 4px 12px 4px 14px;
  border-radius: 999px;
  border: 1px solid var(--dsw-alias-border-l2);
  background: var(--dsw-alias-bg-layer-2);
  font-size: 12px;
  line-height: 18px;
}

.versionBadgeName {
  color: var(--dsw-alias-label-primary);
  font-weight: 600;
}

.versionBadgeTag {
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--dsw-alias-accent-soft, var(--dsw-alias-border-l2));
  color: var(--dsw-alias-label-secondary);
  font-variant-numeric: tabular-nums;
}

/* Catalog search input: a compact text field above the list (token-driven).
   The entries list below it scrolls INDEPENDENTLY — with many plugins the
   modal stays navigable instead of growing unbounded. */
.pluginSearch {
  width: 100%;
  box-sizing: border-box;
  appearance: none;
  border: 1px solid var(--dsw-alias-border-l2);
  border-radius: 8px;
  padding: 6px 10px;
  font: inherit;
  font-size: 12px;
  line-height: 18px;
  color: var(--dsw-alias-label-primary);
  background: var(--dsw-alias-bg-layer-1);
}

.pluginSearch::placeholder {
  color: var(--dsw-alias-label-tertiary);
}

.pluginSearch:focus-visible {
  outline: 2px solid var(--dsw-alias-border-l4);
  outline-offset: 1px;
}

/* The entries area scrolls within the modal once the catalog grows past
   the viewport (max-height + own scrollbar keeps the modal shell fixed). */
.pluginEntries {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 46vh;
  overflow-y: auto;
  overflow-x: hidden;
  padding-right: 2px;
}

/* One catalog group: optional category heading above its stacked entries. */
.pluginGroup {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.pluginGroupHeading {
  font-size: 12px;
  line-height: 18px;
  font-weight: 600;
  color: var(--dsw-alias-label-secondary);
  padding: 2px 2px 0;
}

/* Open-with settings panel: one custom editor row (name + URL template +
   VSCode-family checkbox + remove) and the row-validity hint. */
.openWithEditorRow {
  display: grid;
  grid-template-columns: 1fr 1.5fr auto auto;
  gap: 8px;
  align-items: center;
  min-width: 0;
}

.openWithEditorInput,
.openWithEditorTemplate {
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
  padding: 5px 8px;
  border: 1px solid var(--dsw-alias-border-l2);
  border-radius: 8px;
  background: var(--dsw-alias-bg-layer-3);
  color: var(--dsw-alias-label-primary);
  font: inherit;
  font-size: 13px;
  line-height: 20px;
}

.openWithEditorInput:focus-visible,
.openWithEditorTemplate:focus-visible {
  outline: 2px solid var(--dsw-alias-state-business-primary);
  outline-offset: 1px;
}

.openWithFamily {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  color: var(--dsw-alias-label-secondary);
  white-space: nowrap;
  cursor: pointer;
}

.openWithRemove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px;
  border: none;
  border-radius: 8px;
  background: none;
  color: var(--dsw-alias-label-tertiary);
  cursor: pointer;
}

.openWithRemove:hover {
  color: var(--dsw-alias-state-error-primary);
  background: var(--dsw-alias-bg-layer-2);
}

.openWithHint {
  font-size: 12px;
  line-height: 17px;
  color: var(--dsw-alias-state-error-primary);
  padding: 0 2px;
}
