dsh-model-think-level 1.0.7 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,4 +5,4 @@
5
5
  * `bre-`. Uses CSS variables for theme awareness where the host provides them.
6
6
  */
7
7
  /** The stylesheet text, inserted once into <head> by the client apply(). */
8
- export declare const STYLES = "\n/* The injector's mount wrapper. It \u2014 not the editor inside it \u2014 is the item\n placed into the official row disclosure's repeat(auto-fit, minmax(160px,1fr))\n grid (context window and max tokens take two cells), so the span belongs\n here: on the editor itself it would target the wrapper's block box and be\n ignored, squeezing the block into one cell. */\n.bre-effort-slot {\n grid-column: 1 / -1;\n}\n/* The slot wrapper is a plain column: the master thinking switch sits in it,\n directly above the card it gates. */\n.bre-effort-editor {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin: 8px 0 4px;\n}\n/* The \u601D\u8003\u5F3A\u5EA6 card proper \u2014 rendered only while the master switch is on. */\n.bre-effort-card {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px 12px;\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-2);\n box-sizing: border-box;\n}\n.bre-effort-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n.bre-effort-title {\n font-size: 12px;\n font-weight: 600;\n color: var(--dsw-alias-label-secondary);\n}\n.bre-link-button {\n background: none;\n border: none;\n padding: 2px 6px;\n font-size: 12px;\n color: var(--dsw-alias-link);\n cursor: pointer;\n border-radius: 4px;\n}\n.bre-link-button:hover { text-decoration: underline; }\n.bre-link-button:disabled { opacity: 0.5; cursor: default; text-decoration: none; }\n.bre-auto-effort {\n /* Seated in the OFFICIAL catalogue head, among the host's own controls, so it\n wears THEIR metrics instead of the plugin's blue underlined link look\n (user request: \"\u4E0D\u8981\u8D85\u94FE\u63A5\u6837\u5F0F\uFF0C\u8DDF\u53E6\u5916\u4E24\u4E2A\u4FDD\u6301\u4E00\u81F4\"). These values mirror\n the host's own linkButton rule; the seat cannot simply take that class,\n because it would then answer the probe that finds the anchor it sits after.\n No extra margin: the head's own 12px gap already spaces it exactly like the\n controls beside it. */\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n height: 28px;\n padding: 0 10px;\n border: none;\n border-radius: var(--dsw-radius-sm, 8px);\n background: none;\n color: var(--dsw-alias-label-tertiary, #6b7280);\n font: inherit;\n font-size: 12px;\n line-height: 18px;\n cursor: pointer;\n flex: none;\n}\n.bre-auto-effort:hover {\n background: var(--dsw-alias-interactive-bg-hover, #2631480f);\n color: var(--dsw-alias-label-secondary, #374151);\n}\n.bre-effort-grid {\n /* Exactly two equal columns mirroring the official capacity pair the editor\n sits under; an odd row count leaves the last cell in the left column,\n so the left side carries the extra level. */\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 4px 16px;\n}\n.bre-effort-row {\n display: grid;\n grid-template-columns: 20px 76px minmax(0, 1fr);\n align-items: center;\n gap: 6px;\n font-size: 12px;\n}\n.bre-effort-row input[type='checkbox'] {\n /* Bigger than the browser default (~13px): a tap/point target that does\n not require precision, in the theme accent when checked. */\n width: 18px;\n height: 18px;\n margin: 0;\n accent-color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n}\n.bre-effort-level { color: var(--dsw-alias-label-tertiary); }\n.bre-effort-wire {\n box-sizing: border-box;\n min-width: 0;\n height: 24px;\n padding: 0 6px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 4px;\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 12px;\n}\n.bre-effort-wire:focus {\n outline: none;\n border-color: var(--dsw-alias-brand-primary);\n}\n.bre-effort-empty { min-height: 24px; }\n.bre-effort-actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n}\n.bre-secondary-button {\n height: 26px;\n padding: 0 12px;\n border-radius: 6px;\n font-size: 12px;\n cursor: pointer;\n border: 0.5px solid var(--dsw-alias-border-l3);\n}\n.bre-secondary-button:disabled { opacity: 0.5; cursor: default; }\n.bre-secondary-button { background: transparent; color: inherit; }\n.bre-effort-message { font-size: 12px; margin: 0; }\n.bre-effort-message.bre-error { color: #c62828; }\n.bre-effort-message.bre-info { color: var(--dsw-alias-link); }\n.bre-effort-note { font-size: 11px; margin: 0; color: var(--dsw-alias-label-tertiary); }\n/* ---- Input-modality section ---- */\n.bre-modality {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.bre-modality-row {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n}\n.bre-modality-row input[type='checkbox'] {\n width: 18px;\n height: 18px;\n margin: 0;\n accent-color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n}\n.bre-modality-clear { margin-left: auto; }\n.bre-modality-note { font-size: 11px; margin: 0; color: var(--dsw-alias-label-tertiary); }\n/* The master thinking switch, which lives OUTSIDE the card it gates: with it\n off that card is not rendered at all, so nothing here has to be hidden. */\n.bre-thinking-switch { margin: 0; }\n/* ---- Endpoint-compatibility controls ----\n Same shape as the official capacity fields the editor sits under: a caption\n above the control, the control capped at the official enum width (a field\n width dropdown reads as a text field the user is expected to fill), and a\n hint line beneath. Tokens are the official ones \u2014 the plugin's own --dsh-*\n names are defined nowhere in this app, so their light-mode literals used to\n render in both themes. */\n.bre-compat {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n.bre-compat-row {\n display: flex;\n flex-direction: column;\n gap: 4px;\n min-width: 0;\n}\n.bre-compat-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n.bre-compat-label {\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n}\n.bre-compat-hint {\n font-size: 11px;\n line-height: 16px;\n color: var(--dsw-alias-label-tertiary);\n}\n.bre-select, .bre-text-input {\n box-sizing: border-box;\n width: 100%;\n max-width: 240px;\n height: 32px;\n padding: 0 10px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 14px;\n line-height: 22px;\n}\n.bre-text-input::placeholder { color: var(--dsw-alias-label-dimmed); }\n.bre-select:focus, .bre-text-input:focus {\n outline: none;\n border-color: var(--dsw-alias-brand-primary);\n}\n.bre-select:disabled, .bre-text-input:disabled { opacity: 0.6; cursor: default; }\n.bre-select {\n cursor: pointer;\n /* The OS arrow sits flush against the right edge; the official select swaps\n it for the shared 12px chevron inset on the same right pad. Data-URI SVGs\n cannot resolve CSS variables, so the stroke is the caption gray both\n themes share. */\n appearance: none;\n padding-right: 32px;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 12px center;\n background-size: 12px 12px;\n}\n.bre-error { color: var(--dsw-alias-state-error-primary); }\n/* ---- Zoned suggestion display ---- */\n.bre-suggestion {\n display: flex;\n flex-direction: column;\n gap: 3px;\n}\n.bre-reference {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: 4px 14px;\n padding: 6px 8px;\n border: 1px dashed var(--dsw-alias-border-l3);\n border-radius: 6px;\n font-size: 11px;\n color: var(--dsw-alias-label-tertiary);\n}\n.bre-reference-title { font-weight: 600; }\n.bre-reference-values { display: inline-flex; gap: 14px; }\n/* ---- Composer model-menu slider (mounted inside the OFFICIAL menu) ----\n Visuals ported VERBATIM from HanaAyane's dsh-reasoning-effort (MIT) \u2014 the\n only deliberate difference is the chibi-runner \"big fish\" knob, which is\n dropped so the knob is always the white circle. Class names are re-\n prefixed bre- (the upstream's re- prefix would clash while both plugins\n are installed); every color/size/animation value stays upstream's. */\n.bre-slider-body {\n /* The replicated popover body. The official menu shell carries padding: 4px\n (ModelSelect.module.css), so pull the replica flush to the box. overflow\n stays VISIBLE: an open list is laid out inside the body, so nothing ever\n has to escape it, and the rows' own hover radius needs no clipping. */\n overflow: visible;\n margin: -4px;\n padding: 8px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n/* The official menu is content-sized; while the replicated popover body is\n live, its box takes the upstream .re-model-menu width. The class is added\n by the mount and removed when the slider is switched off. */\n.bre-model-menu-host {\n width: min(340px, calc(100vw - 32px));\n min-width: 0;\n}\n/* The official trigger keeps ownership of its model/effort children. The\n provider prefix is a pseudo-element so host React updates, focus handling and\n the click target remain untouched.\n\n Scoped to the composer, which owns the only button that carries this stamp.\n The settings sidebar's account button is ALSO an [aria-haspopup=\"menu\"]\n button, so an unscoped rule paints the prefix onto the account row the\n moment a stale stamp lands there \u2014 and a stamp that escaped the composer\n must render nothing rather than relabel a host control. The seat anchor is\n listed too, so a shell that renders the trigger outside the card body still\n gets the prefix. */\n[data-composer-card] button[data-bre-provider]::before,\n[data-slot=\"conversation.input.model\"] button[data-bre-provider]::before {\n content: attr(data-bre-provider) \" \u00B7 \";\n flex: none;\n color: var(--dsw-alias-label-secondary);\n font-weight: 400;\n white-space: nowrap;\n}\n\n/* ---- Model / reasoning-level rows ----\n Presentation follows dsh-tauri-model-config's settings rows\n (src/client/models/styles.ts: .zGbnIq_rowCard / .zGbnIq_rowHead /\n .zGbnIq_iconButton): hairline separators between rows and a list opening\n under the row it belongs to. Re-prefixed bre- and routed through the tokens\n this file already uses. */\n/* Layout only \u2014 it deliberately paints NO background, border, radius or\n overflow clip. The replica is mounted inside the OFFICIAL menu, and that\n shell already draws its own surface (MenuSurface: a [data-menu-material]\n panel whose .material child paints --dsw-menu-surface-fill, i.e.\n --dsw-specific-menu, under backdrop-filter: var(--dsw-menu-backdrop-filter),\n rounded by --dsw-radius-lg and outlined by --dsw-elevation-prominent).\n A second opaque card in here shows that official surface as a grey frame\n around it \u2014 two stacked surfaces where every other menu in the app has one. */\n.bre-card {\n display: flex;\n flex-direction: column;\n}\n.bre-row-control {\n appearance: none;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n min-height: 38px;\n padding: 0 10px;\n border: 0;\n /* Matches the official menu cells (.u91W7W_cell / .u91W7W_option use\n --dsw-radius-md, 8px here) and the .bre-option rows below, now that the\n surface behind the rows is the menu's own and hover is no longer clipped\n by a card. */\n border-radius: 8px;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n transition: background 120ms ease;\n}\n.bre-row-control:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, rgba(120, 125, 140, .09));\n}\n.bre-row-control.is-open { background: var(--dsw-alias-fill-tertiary, rgba(120, 125, 140, .09)); }\n.bre-row-control:disabled { cursor: default; opacity: .6; }\n.bre-row-control:focus-visible {\n outline: none;\n box-shadow: inset 0 0 0 2px var(--dsw-alias-border-l3);\n}\n.bre-row-label {\n flex: none;\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary);\n}\n.bre-row-value {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n text-align: right;\n font-size: 13px;\n line-height: 20px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n.bre-row-value.is-muted { font-weight: 400; color: var(--dsw-alias-label-tertiary); }\n.bre-divider { height: 1px; margin: 0 10px; background: var(--dsw-alias-border-l4); }\n.bre-panel {\n display: flex;\n flex-direction: column;\n gap: 2px;\n max-height: 220px;\n overflow-y: auto;\n padding: 2px 6px 8px;\n}\n/* Provider column + model column of the model list, side by side. The height is\n FIXED: switching provider must not resize the card, or every click would need\n another same-frame re-place and any missed one shows as a jump. */\n.bre-panel-models {\n flex-direction: row;\n align-items: stretch;\n gap: 0;\n height: 240px;\n max-height: none;\n overflow: hidden;\n padding: 4px 6px 8px;\n}\n.bre-providers {\n flex: none;\n display: flex;\n flex-direction: column;\n gap: 2px;\n width: 112px;\n overflow-y: auto;\n padding-right: 2px;\n}\n.bre-provider-models {\n flex: 1 1 auto;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n overflow-y: auto;\n margin-left: 6px;\n padding-left: 6px;\n border-left: 1px solid var(--dsw-alias-border-l4);\n}\n.bre-option,\n.bre-provider {\n appearance: none;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n min-height: 30px;\n padding: 0 8px;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: inherit;\n font: inherit;\n font-size: 13px;\n line-height: 20px;\n text-align: left;\n cursor: pointer;\n transition: background 120ms ease, color 120ms ease;\n}\n/* The provider cell carries its chevron hard against the right edge. */\n.bre-provider { gap: 4px; padding: 0 4px 0 8px; }\n.bre-option:hover:not(:disabled),\n.bre-provider:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, rgba(120, 125, 140, .09));\n}\n.bre-option:disabled,\n.bre-provider:disabled { cursor: default; opacity: .6; }\n.bre-option:focus-visible,\n.bre-provider:focus-visible {\n outline: none;\n box-shadow: inset 0 0 0 2px var(--dsw-alias-border-l3);\n}\n.bre-option-name {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bre-option.is-active {\n color: var(--dsw-static-deepseek-500, #4d70ff);\n font-weight: 500;\n background: var(--dsw-alias-fill-tertiary, rgba(120, 125, 140, .09));\n}\n/* The open provider is the highlighted one; the provider of the CURRENT model\n keeps the accent so the column says where the selection lives. */\n.bre-provider.is-open { background: var(--dsw-alias-fill-tertiary, rgba(120, 125, 140, .09)); }\n.bre-provider.is-current .bre-option-name {\n color: var(--dsw-static-deepseek-500, #4d70ff);\n font-weight: 500;\n}\n.bre-provider .bre-row-chevron { width: 14px; height: 14px; font-size: 14px; }\n/* Capability badges on a model row (image input / thinking). Muted so the name\n stays the brightest thing in the row; the badge's own title carries the copy. */\n.bre-option-tags {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n color: var(--dsw-alias-label-tertiary);\n}\n.bre-option.is-active .bre-option-tags { color: var(--dsw-static-deepseek-500, #4d70ff); }\n.bre-tag { display: inline-flex; align-items: center; }\n.bre-tag-icon { display: block; width: 13px; height: 13px; }\n.bre-option-check { flex: none; width: 14px; height: 14px; }\n.bre-empty { padding: 6px 8px; font-size: 12px; color: var(--dsw-alias-label-tertiary); }\n/* ---- Truncated-label tooltip (custom, replaces the native title) ----\n A self-drawn bubble instead of the OS tooltip, which the page cannot style\n and which reads harsh next to the menu. Fixed-positioned on <body> so the\n menu's own overflow/clip cannot cut it, aligned under the truncated span,\n capped to the viewport with wrap for very long names. */\n.bre-tip {\n position: fixed;\n z-index: 2147483647;\n max-width: min(360px, calc(100vw - 24px));\n box-sizing: border-box;\n padding: 5px 9px;\n border-radius: 8px;\n background: var(--dsw-alias-bg-module-platform, #232630);\n color: var(--dsw-alias-label-primary, #f2f3f5);\n font-size: 12px;\n line-height: 18px;\n overflow-wrap: anywhere;\n white-space: normal;\n pointer-events: none;\n box-shadow: 0 4px 16px rgba(0, 0, 0, .22);\n animation: bre-tip-in 120ms ease-out;\n}\nbody:not([data-ds-dark-theme]) .bre-tip {\n background: #ffffff;\n color: var(--dsw-alias-label-primary, #1f2329);\n box-shadow: 0 4px 16px rgba(0, 0, 0, .14), 0 0 0 .5px var(--dsw-alias-border-l4, rgba(0, 0, 0, .1));\n}\n@keyframes bre-tip-in {\n from { opacity: 0; transform: translateY(-2px); }\n to { opacity: 1; transform: translateY(0); }\n}\n@media (prefers-reduced-motion: reduce) {\n .bre-tip { animation: none; }\n}\n.bre-slider-advanced {\n /* upstream .re-advanced: the padded area that hosts the slider */\n padding: 14px;\n}\n.bre-effort {\n display: flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n height: 32px;\n color: var(--dsw-alias-label-secondary);\n user-select: none;\n box-sizing: border-box;\n}\n.bre-effort-slider {\n --bre-progress: 50%;\n position: relative;\n width: 100%;\n height: 30px;\n flex: 1 1 auto;\n border-radius: 999px;\n isolation: isolate;\n transition: filter 180ms ease;\n}\n.bre-effort-track {\n position: absolute;\n inset: 0;\n overflow: hidden;\n border-radius: inherit;\n background: linear-gradient(100deg, #03040a 0%, #071126 22%, #101d4c 45%, #302262 70%, #5d35a0 100%);\n box-shadow:\n inset 0 1px 0 rgba(189, 199, 255, .15),\n inset 0 -1px 0 rgba(0, 0, 0, .55),\n 0 3px 10px rgba(12, 17, 55, .34);\n}\n.bre-effort-track::after {\n content: \"\";\n position: absolute;\n inset: 0;\n background:\n radial-gradient(circle at 18% 45%, rgba(82, 130, 255, .12), transparent 24%),\n linear-gradient(90deg, rgba(0, 0, 0, .28), transparent 42%, rgba(168, 113, 255, .12));\n pointer-events: none;\n}\n.bre-effort-fx {\n position: absolute;\n z-index: 1;\n inset: 0;\n overflow: hidden;\n border-radius: inherit;\n pointer-events: none;\n}\n.bre-effort-canvas {\n position: absolute;\n z-index: 2;\n inset: 0;\n width: 100%;\n height: 100%;\n opacity: 1;\n image-rendering: pixelated;\n mix-blend-mode: screen;\n transition: filter 140ms ease;\n}\n.bre-effort-flare {\n position: absolute;\n z-index: 3;\n top: 50%;\n left: var(--bre-progress);\n width: 78px;\n height: 46px;\n border-radius: 50%;\n background: radial-gradient(ellipse at 100% 50%, rgba(255,255,255,.96) 0 4%, rgba(188,189,255,.8) 11%, rgba(106,87,255,.5) 28%, rgba(105,31,255,.2) 49%, transparent 74%);\n filter: blur(2px) saturate(1.25);\n mix-blend-mode: screen;\n transform: translate(-100%, -50%);\n transition: left 70ms linear, filter 140ms ease;\n pointer-events: none;\n}\n.bre-effort-flare::before,\n.bre-effort-flare::after {\n content: \"\";\n position: absolute;\n inset: 50% auto auto 100%;\n border-radius: 999px;\n transform: translate(-50%, -50%);\n}\n.bre-effort-flare::before {\n width: 52px;\n height: 1px;\n background: linear-gradient(90deg, transparent, rgba(100,160,255,.42), #f1ecff, rgba(193,82,255,.65), transparent);\n box-shadow: 0 0 7px #9b7cff, 0 0 13px rgba(72,132,255,.64);\n}\n.bre-effort-flare::after {\n width: 1px;\n height: 20px;\n background: linear-gradient(180deg, transparent, rgba(196,190,255,.84), transparent);\n box-shadow: 0 0 7px #9c7cff;\n}\n.bre-effort-knob {\n position: absolute;\n z-index: 4;\n top: 50%;\n left: clamp(14px, var(--bre-progress), calc(100% - 14px));\n width: 28px;\n height: 28px;\n border: 1px solid rgba(255,255,255,.94);\n border-radius: 50%;\n background: #fff;\n box-shadow:\n 0 0 0 2px rgba(92,105,255,.12),\n 0 0 14px rgba(121,82,255,.48),\n 0 2px 7px rgba(0,0,0,.3);\n transform: translate(-50%, -50%);\n transition: left 190ms cubic-bezier(.22,1,.36,1), transform 160ms ease, box-shadow 180ms ease;\n pointer-events: none;\n}\n.bre-effort-input {\n position: absolute;\n z-index: 5;\n inset: -5px 0;\n width: 100%;\n height: calc(100% + 10px);\n margin: 0;\n opacity: 0;\n cursor: grab;\n touch-action: none;\n}\n.bre-effort-input:active { cursor: grabbing; }\n.bre-effort-input:focus-visible + .bre-effort-knob {\n outline: 2px solid var(--dsw-static-blue-400);\n outline-offset: 2px;\n}\n.bre-effort.is-dragging .bre-effort-canvas {\n filter: saturate(1.45) brightness(1.28) contrast(1.06);\n}\n.bre-effort.is-dragging .bre-effort-flare {\n filter: blur(1.5px) saturate(1.6) brightness(1.42);\n transition: none;\n}\n.bre-effort.is-dragging .bre-effort-knob {\n transform: translate(-50%, -50%) scale(1.07);\n transition: none;\n box-shadow:\n 0 0 0 3px rgba(113,115,255,.25),\n 0 0 20px rgba(74,145,255,.86),\n 0 0 31px rgba(171,53,255,.66),\n 0 3px 8px rgba(0,0,0,.32);\n}\n.bre-effort-slider[data-top] .bre-effort-track {\n animation: bre-effort-dark-breathe 1.9s ease-in-out infinite;\n}\n.bre-effort-slider[data-top] .bre-effort-knob {\n box-shadow:\n 0 0 0 3px rgba(119,99,255,.18),\n 0 0 22px rgba(135,78,255,.76),\n 0 0 34px rgba(53,121,255,.34),\n 0 3px 8px rgba(0,0,0,.3);\n}\n.bre-effort.is-error .bre-effort-slider {\n outline: 1px solid var(--dsw-alias-state-error-secondary);\n outline-offset: 2px;\n}\n.bre-effort.is-busy { opacity: .72; }\n.bre-effort-sr {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\nbody:not([data-ds-dark-theme]) .bre-effort-slider {\n filter: none;\n}\nbody:not([data-ds-dark-theme]) .bre-effort-track {\n background: var(--dsw-static-blue-75, #e5f0ff);\n box-shadow:\n inset 0 1px 0 rgba(255,255,255,.9),\n inset 0 0 0 1px rgba(80,133,194,.14),\n 0 3px 10px rgba(48,101,165,.13);\n}\nbody:not([data-ds-dark-theme]) .bre-effort-track::before {\n content: \"\";\n position: absolute;\n z-index: 0;\n inset: 0 auto 0 0;\n width: var(--bre-progress);\n border-radius: inherit;\n background: linear-gradient(90deg, #fff 0%, #e2f0ff 20%, #a8d0fb 57%, #438fdf 100%);\n transition: width 190ms cubic-bezier(.22,1,.36,1);\n}\nbody:not([data-ds-dark-theme]) .bre-effort-slider[data-top] .bre-effort-track::before {\n background: linear-gradient(90deg, #fff 0%, #d7eaff 18%, #75afea 54%, #0751ad 100%);\n}\nbody:not([data-ds-dark-theme]) .bre-effort.is-dragging .bre-effort-track::before {\n transition: none;\n}\nbody:not([data-ds-dark-theme]) .bre-effort-track::after {\n z-index: 1;\n background: linear-gradient(90deg, rgba(255,255,255,.48), transparent 34%, rgba(23,101,201,.07));\n}\nbody:not([data-ds-dark-theme]) .bre-effort-canvas {\n opacity: .78;\n mix-blend-mode: multiply;\n}\nbody:not([data-ds-dark-theme]) .bre-effort-flare {\n background: radial-gradient(ellipse at 100% 50%, rgba(255,255,255,.98) 0 5%, rgba(204,231,255,.88) 13%, rgba(91,162,241,.48) 31%, rgba(37,111,207,.16) 53%, transparent 75%);\n filter: blur(2px) saturate(1.12);\n}\nbody:not([data-ds-dark-theme]) .bre-effort-flare::before {\n background: linear-gradient(90deg, transparent, rgba(116,177,244,.34), #fff, rgba(66,139,225,.58), transparent);\n box-shadow: 0 0 7px rgba(58,133,222,.5), 0 0 13px rgba(104,176,255,.38);\n}\nbody:not([data-ds-dark-theme]) .bre-effort-flare::after {\n background: linear-gradient(180deg, transparent, rgba(255,255,255,.94), transparent);\n box-shadow: 0 0 7px rgba(64,137,224,.44);\n}\nbody:not([data-ds-dark-theme]) .bre-effort-knob {\n border-color: rgba(126,160,197,.32);\n box-shadow:\n 0 0 0 2px rgba(58,124,207,.09),\n 0 0 13px rgba(48,118,207,.3),\n 0 3px 8px rgba(39,77,119,.18);\n}\nbody:not([data-ds-dark-theme]) .bre-effort-slider[data-top] .bre-effort-track {\n animation-name: bre-effort-light-breathe;\n}\nbody:not([data-ds-dark-theme]) .bre-effort-slider[data-top] .bre-effort-knob,\nbody:not([data-ds-dark-theme]) .bre-effort.is-dragging .bre-effort-knob {\n box-shadow:\n 0 0 0 3px rgba(36,105,192,.15),\n 0 0 20px rgba(25,100,201,.45),\n 0 3px 8px rgba(39,77,119,.18);\n}\n@keyframes bre-effort-dark-breathe {\n 0%, 100% { box-shadow: inset 0 1px 0 rgba(196,204,255,.16), 0 3px 10px rgba(18,25,72,.4); }\n 50% { box-shadow: inset 0 1px 0 rgba(220,214,255,.24), 0 0 21px rgba(111,66,255,.5); }\n}\n@keyframes bre-effort-light-breathe {\n 0%, 100% { box-shadow: inset 0 1px 0 rgba(255,255,255,.9), inset 0 0 0 1px rgba(67,124,193,.16), 0 3px 10px rgba(48,101,165,.13); }\n 50% { box-shadow: inset 0 1px 0 rgba(255,255,255,.96), inset 0 0 0 1px rgba(31,102,190,.22), 0 0 19px rgba(31,105,201,.24); }\n}\n.bre-slider-hint {\n /* upstream re-model-status */\n display: block;\n padding: 14px;\n color: var(--dsw-alias-label-tertiary, #9296a0);\n font-size: 12px;\n text-align: center;\n}\n/* upstream re-model-error: the directory/store error line under the row */\n.bre-model-error {\n margin: 8px;\n padding: 8px 10px;\n border-radius: 8px;\n color: var(--dsw-alias-state-error-primary, #c83e4d);\n background: var(--dsw-alias-state-error-tertiary, rgba(220,55,70,.08));\n font-size: 11px;\n}\n/* upstream .re-menu-separator */\n.bre-menu-separator {\n height: 1px;\n background: var(--dsw-alias-stroke-secondary, rgba(121,126,145,.16));\n}\n/* upstream .re-model-row: name \u00B7 current effort \u203A (click \u2192 official model list) */\n.bre-model-row {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto auto;\n align-items: center;\n gap: 8px;\n min-height: 45px;\n padding: 0 14px;\n width: 100%;\n border: 0;\n color: inherit;\n background: transparent;\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n.bre-model-row:hover { background: var(--dsw-alias-fill-tertiary, rgba(120,125,140,.09)); }\n.bre-model-row-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }\n.bre-model-row-effort { color: var(--dsw-static-deepseek-500, #4d70ff); font-size: 12px; }\n.bre-row-chevron {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n font-size: 18px;\n line-height: 1;\n color: var(--dsw-alias-label-tertiary);\n transform: rotate(0deg);\n transition: transform 120ms ease;\n}\n.bre-row-chevron.is-open { transform: rotate(90deg); }\n@media (prefers-reduced-motion: reduce) {\n .bre-effort-slider[data-top] .bre-effort-track { animation: none; }\n .bre-effort-knob,\n .bre-effort-flare,\n body:not([data-ds-dark-theme]) .bre-effort-track::before { transition: none; }\n}\n/* ---- Models-page slider toggle (boxed setting item) ----\n Item form ported VERBATIM from upstream .re-setting-row; the surrounding\n box is the requested container (border only, transparent background). */\n.bre-slider-setting {\n margin-top: 12px;\n padding: 0 14px;\n border: 1px solid var(--dsw-alias-stroke-secondary, rgba(121,126,145,.2));\n border-radius: 12px;\n background: transparent;\n}\n.bre-slider-setting-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 24px;\n padding: 16px 0;\n /* Upstream .re-setting-row carries a list bottom border because the general\n settings list held TWO rows (the slider + the big-fish toggle). This box\n holds exactly one, so no divider: the box itself is the container. */\n}\n.bre-slider-setting-copy { min-width: 0; }\n.bre-slider-setting-title {\n color: var(--dsw-alias-label-primary, #15171b);\n font-size: 14px;\n font-weight: 400;\n line-height: 22px;\n}\n.bre-slider-setting-description {\n margin-top: 3px;\n color: var(--dsw-alias-label-tertiary, #9296a0);\n font-size: 12px;\n line-height: 18px;\n}\n.bre-slider-setting-control { display: inline-flex; align-items: center; gap: 10px; flex: none; }\n.bre-slider-setting-state { color: var(--dsw-alias-label-secondary, #686c75); font-size: 13px; }\n.bre-slider-setting-switch {\n position: relative;\n width: 38px;\n height: 22px;\n padding: 0;\n border: 0;\n border-radius: 999px;\n background: var(--dsw-alias-fill-quaternary, #c7cbd3);\n cursor: pointer;\n transition: background 150ms ease;\n}\n.bre-slider-setting-switch:hover { filter: brightness(.97); }\n.bre-slider-setting-switch:disabled { cursor: not-allowed; opacity: .45; }\n.bre-slider-setting-switch:focus-visible {\n outline: 2px solid var(--dsw-static-blue-400, #5d83ff);\n outline-offset: 2px;\n}\n.bre-slider-setting-switch.is-on { background: var(--dsw-alias-state-business-primary, #4f73ff); }\n.bre-slider-setting-switch-knob {\n position: absolute;\n top: 2px;\n left: 2px;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n background: #fff;\n box-shadow: 0 1px 4px rgba(0,0,0,.2);\n transition: transform 170ms cubic-bezier(.22,1,.36,1);\n}\n.bre-slider-setting-switch.is-on .bre-slider-setting-switch-knob { transform: translateX(16px); }\n\n/* Model selection search box */\n.bre-model-search-box {\n display: flex;\n flex-direction: column;\n padding: 6px 8px 4px;\n position: sticky;\n top: 0;\n z-index: 2;\n background: var(--dsw-specific-menu, var(--dsw-alias-bg-layer-1, #1e1f22));\n}\n.bre-model-search-box:has(.bre-search-empty),\n.bre-model-search-box.has-empty {\n flex: 1 1 auto;\n}\n.bre-search-input-wrapper {\n display: flex;\n align-items: center;\n position: relative;\n width: 100%;\n height: 32px;\n padding: 0 8px;\n box-sizing: border-box;\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-2, rgba(255, 255, 255, 0.06));\n border: 0.5px solid var(--dsw-alias-border-l4, rgba(255, 255, 255, 0.12));\n color: var(--dsw-alias-label-primary);\n transition: border-color 150ms ease, box-shadow 150ms ease;\n}\n.bre-search-input-wrapper:focus-within {\n border-color: var(--dsw-static-deepseek-500, #4d70ff);\n box-shadow: 0 0 0 2px rgba(77, 112, 255, 0.2);\n}\n.bre-search-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 16px;\n width: 16px;\n height: 16px;\n margin-right: 6px;\n color: var(--dsw-alias-label-tertiary, #81858c);\n pointer-events: none;\n}\n.bre-search-icon svg {\n width: 14px;\n height: 14px;\n}\n.bre-search-input {\n flex: 1 1 auto;\n min-width: 0;\n height: 100%;\n padding: 0;\n border: none;\n outline: none;\n background: transparent;\n color: inherit;\n font: inherit;\n font-size: 13px;\n line-height: 20px;\n}\n.bre-search-input::placeholder {\n color: var(--dsw-alias-label-tertiary, #81858c);\n opacity: 0.85;\n}\n.bre-search-clear {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 18px;\n width: 18px;\n height: 18px;\n margin-left: 4px;\n padding: 0;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--dsw-alias-label-tertiary, #81858c);\n cursor: pointer;\n transition: background 120ms ease, color 120ms ease;\n}\n.bre-search-clear:hover {\n background: var(--dsw-alias-interactive-bg-hover, rgba(255, 255, 255, 0.1));\n color: var(--dsw-alias-label-primary);\n}\n.bre-search-clear svg {\n width: 12px;\n height: 12px;\n}\n.bre-search-empty {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1 1 auto;\n min-height: 180px;\n padding: 24px 16px;\n text-align: center;\n color: var(--dsw-alias-label-tertiary, #81858c);\n font-size: 13px;\n line-height: 20px;\n user-select: none;\n}\n\n/* ---- Request-header section (issue #12). Mounted through the official\n settings.models.provider-card seat, so it sits in the card's own layout\n rather than a disclosure grid.\n\n Every value below was MEASURED off the official Models page's own controls\n in DSH 0.1.7-rc.2 rather than guessed, and each is expressed through the same\n --dsw-alias-* token the host paints with, so a theme switch (light/dark)\n repaints this section along with the page:\n\n provider card radius 20px, 1px var(--dsw-alias-settings-card-stroke)\n editor action save = filled var(--dsw-alias-button-primary-fill), h36,\n radius 12px, 0 14px, 14px; cancel = 1px border, same box\n row action h28, radius 8px, 0 10px, 12px, 1px border\n text link h21, radius 4px, 2px 6px, 12px, link-blue label\n text input radius 12px, 0 10px, 1px var(--dsw-alias-border-l3) ---- */\n/* The provider-card slot's wrapper.\n The official slot mounts us inside a display:contents container, so our own\n root IS a flex item of the card row \u2014 and the row lays its children out with\n a 12px gap. A wrapper that stays in the flow while empty therefore adds one\n phantom gap to EVERY card in the list, which is exactly the height regression\n this rule exists to prevent. Collapsed, the wrapper leaves the flow entirely:\n the card renders as it did before the plugin.\n (Deliberately NOT display:contents here \u2014 that keeps it a gap-participating\n item, which is the bug this rule fixes.)\n Open, it becomes an ordinary block so the section below can lay itself out.\n data-edit lives HERE \u2014 the occurrence component publishes the card's state\n onto its own root, so keying the rule on .bre-headers[data-edit] instead\n would silently never match. */\n.bre-headers-host {\n display: none;\n}\n.bre-headers-host[data-edit=\"1\"] {\n display: block;\n}\n.bre-headers {\n display: flex;\n flex-direction: column;\n gap: 8px;\n /* The card lays its own children out with a 12px gap and no dividers; this\n section is an addition to that column, so it separates itself the same way\n the host separates card sections \u2014 a hairline on the card's own stroke. */\n border-top: 1px solid var(--dsw-alias-border-l2, #0000001a);\n padding-top: 12px;\n\n /* Present ONLY while the provider card is being edited.\n The provider list is a list of providers: a request-header row parked in\n every card, collapsed or not, is noise on a surface the user did not ask\n to configure. The card reveals its editor when the user presses its own\n Edit action, and that is the moment this section belongs on screen \u2014 the\n same gesture that opens the model list opens this.\n\n The visibility is decided by the component (which watches the card and\n sets data-edit on the wrapper), not by a selector: the official editor is\n NOT a sibling of this element \u2014 its container sits in the card row's own\n children, after the row head and this section's own wrapper \u2014 so no\n relative selector can reach it. The wrapper's data-edit is the one fact\n CSS can act on.\n\n Degradation is safe by construction: with no observer (no card ancestor to\n watch) data-edit stays \"0\", the section is never revealed, and the\n official page stays clean rather than leaking a row into every card. */\n display: none;\n}\n.bre-headers-host[data-edit=\"1\"] .bre-headers {\n display: flex;\n}\n/* The collapsed heading is the section's identity while the card is being\n edited: title, configured count, and the \u203A that opens the details. */\n.bre-headers-disclosure {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n padding: 0;\n border: none;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n.bre-headers-disclosure:hover .bre-effort-title {\n color: var(--dsw-alias-label-secondary, #61666b);\n}\n.bre-headers-chevron {\n margin-left: auto;\n padding-right: 2px;\n color: var(--dsw-alias-label-tertiary, #81858c);\n font-size: 14px;\n line-height: 1;\n transition: transform 150ms ease;\n}\n.bre-headers[data-open=\"1\"] .bre-headers-chevron { transform: rotate(90deg); }\n/* How many entries are configured \u2014 the one fact worth showing while closed. */\n.bre-headers-count {\n min-width: 16px;\n padding: 0 5px;\n border-radius: 8px;\n background: var(--dsw-alias-interactive-bg-hover, #2631480f);\n color: var(--dsw-alias-label-secondary, #61666b);\n font-size: 11px;\n line-height: 16px;\n text-align: center;\n}\n.bre-headers-head {\n display: flex;\n align-items: center;\n min-height: 32px;\n padding: 0 8px;\n border-radius: var(--dsw-radius-sm, 8px);\n background: var(--dsw-alias-interactive-bg-hover, #2631480f);\n}\n.bre-headers-head .bre-effort-title {\n color: var(--dsw-alias-label-primary, #0f1115);\n font-weight: 600;\n}\n.bre-headers-edit, .bre-headers-rows {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n/* The titled-section rows the pane is built from: the title row names its\n section (headers first; future advanced sections each carry one), sitting\n under a hairline the way the official page's group titles do. */\n.bre-headers-title-row {\n padding-bottom: 6px;\n border-bottom: 1px solid var(--dsw-alias-border-l2, #0000001a);\n margin-bottom: 2px;\n}\n.bre-headers-title-row .bre-effort-title {\n font-size: 13px;\n line-height: 20px;\n}\n\n.bre-headers-columns,\n.bre-headers-row {\n display: grid;\n grid-template-columns: minmax(120px, 0.9fr) minmax(180px, 1.5fr) 28px;\n align-items: center;\n gap: 8px;\n}\n.bre-headers-columns {\n padding: 0 10px;\n color: var(--dsw-alias-label-tertiary, #81858c);\n font-size: 11px;\n line-height: 16px;\n}\n.bre-headers-row {\n min-height: 40px;\n padding: 4px 6px;\n border: 1px solid var(--dsw-alias-border-l2, #0000001a);\n border-radius: var(--dsw-radius-sm, 8px);\n background: var(--dsw-alias-bg-layer-1, #fff);\n}\n.bre-headers-add {\n align-self: flex-start;\n min-height: 30px;\n padding: 0 10px;\n border: 1px solid var(--dsw-alias-border-l2, #0000001a);\n border-radius: var(--dsw-radius-sm, 8px);\n color: var(--dsw-alias-label-primary, #0f1115);\n}\n.bre-headers-add:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, #2631480f);\n}\n.bre-headers-remove {\n width: 28px;\n padding: 0;\n justify-self: center;\n}\n.bre-headers-rows .bre-headers-name {\n color: var(--dsw-alias-label-secondary, #61666b);\n font-size: 12px;\n word-break: break-all;\n}\n.bre-headers-masked {\n color: var(--dsw-alias-label-tertiary, #81858c);\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n letter-spacing: 0;\n}\n\n/* The section's commit/dismiss pair, matching the official editor's own\n actions: a filled commit and a bordered dismiss, 36px tall at 14px. */\n.bre-headers-edit .bre-primary-button {\n height: 36px;\n padding: 0 14px;\n border: none;\n border-radius: var(--dsw-radius-md, 12px);\n background: var(--dsw-alias-button-primary-fill, #0f1115);\n color: var(--dsw-alias-label-primary-foreground, #fff);\n font-size: 14px;\n font-weight: 400;\n line-height: 1;\n cursor: pointer;\n}\n.bre-headers-edit .bre-primary-button:hover:not(:disabled) {\n background: var(--dsw-alias-button-primary-hover, #43454a);\n}\n.bre-headers-edit .bre-primary-button:disabled { opacity: 0.5; cursor: default; }\n.bre-headers-edit .bre-secondary-button {\n height: 36px;\n padding: 0 14px;\n border: 1px solid var(--dsw-alias-border-l3, #0000001f);\n border-radius: var(--dsw-radius-md, 12px);\n background: transparent;\n color: var(--dsw-alias-label-primary, #0f1115);\n font-size: 14px;\n}\n.bre-headers-edit .bre-secondary-button:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, #2631480f);\n}\n\n/* The row actions and the section's Edit affordance: the official 28px\n bordered small button, and the 21px blue text link the model rows use. */\n.bre-headers-row .bre-link-button {\n height: 28px;\n padding: 2px 8px;\n border: none;\n border-radius: var(--dsw-radius-sm, 8px);\n background: transparent;\n color: var(--dsw-alias-label-secondary, #61666b);\n font-size: 12px;\n line-height: 1;\n}\n.bre-headers-row .bre-link-button:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, #2631480f);\n}\n.bre-headers .bre-effort-head > .bre-link-button {\n height: 28px;\n padding: 0 10px;\n border: 1px solid var(--dsw-alias-border-l2, #0000001a);\n border-radius: var(--dsw-radius-sm, 8px);\n color: var(--dsw-alias-label-primary, #0f1115);\n font-size: 12px;\n text-decoration: none;\n}\n.bre-headers .bre-effort-head > .bre-link-button:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, #2631480f);\n text-decoration: none;\n}\n.bre-headers-edit .bre-link-button {\n color: var(--dsw-alias-label-secondary, #61666b);\n font-size: 12px;\n}\n\n/* The section's own fields, on the official input box. */\n.bre-headers-edit input.bre-text-input {\n height: 32px;\n padding: 0 10px;\n border: 1px solid var(--dsw-alias-border-l3, #0000001f);\n border-radius: var(--dsw-radius-md, 12px);\n background: var(--dsw-alias-bg-layer-1, #fff);\n color: var(--dsw-alias-label-primary, #0f1115);\n font-size: 13px;\n box-sizing: border-box;\n}\n.bre-headers-edit input.bre-text-input:focus {\n border-color: var(--dsw-alias-label-tertiary, #81858c);\n outline: none;\n}\n.bre-headers-edit input.bre-text-input:disabled { opacity: 0.6; cursor: default; }\n\n/* Status copy and the coexistence warnings, on the host's own state colours. */\n.bre-headers .bre-effort-note.bre-warn { color: var(--dsw-alias-state-warn-label, #dd8629); }\n.bre-headers .bre-effort-message.bre-success { color: var(--dsw-alias-state-success-primary, #22c55e); }\n.bre-headers .bre-effort-message.bre-error { color: var(--dsw-alias-state-error-primary, #ec1313); }\n\n@media (max-width: 520px) {\n .bre-headers-columns { display: none; }\n .bre-headers-row {\n grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr) 28px;\n gap: 6px;\n padding: 4px;\n }\n .bre-headers-edit input.bre-text-input {\n padding: 0 8px;\n font-size: 12px;\n }\n}\n\n/* ---- Provider row reordering (Models page) ---- */\n\n/* The whole row header is the drag handle: an 18px grip is a poor thing to\n have to hit, so a drag may start anywhere on the header that is not one of\n the card's own controls (those keep their own cursor, declared below). */\nli[data-bre-row-head='1'] { cursor: grab; }\nli[data-bre-row-head='1']:active { cursor: grabbing; }\nli[data-bre-row-head='1'] button,\nli[data-bre-row-head='1'] a,\nli[data-bre-row-head='1'] input { cursor: pointer; }\n\n/* The grip is mounted as the first child of that header, so it reads as part\n of the row rather than as a control bolted beside it. It is also the button\n that reorders by keyboard. */\n.bre-drag-grip {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n width: 14px;\n height: 20px;\n margin-right: 2px;\n border-radius: 4px;\n color: var(--dsw-alias-label-tertiary, #81858c);\n cursor: grab;\n touch-action: none;\n}\n\n.bre-drag-grip:hover {\n color: var(--dsw-alias-label-secondary, #61666b);\n background: var(--dsw-alias-interactive-bg-hover, #2631480f);\n}\n\n.bre-drag-grip:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.bre-drag-grip:active { cursor: grabbing; }\n\n/* What the pointer carries: the browser's own drag image would be a screenshot\n of a whole card, so we hand it this chip with the provider name instead. */\n.bre-drag-ghost {\n position: fixed;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n max-width: 260px;\n padding: 5px 10px 5px 7px;\n border: 1px solid var(--dsw-alias-border-secondary, #e6e8eb);\n border-radius: 8px;\n background: var(--dsw-alias-bg-elevated, #ffffff);\n box-shadow: 0 6px 18px #0000002e;\n color: var(--dsw-alias-label-primary, #17181a);\n font-size: 13px;\n line-height: 18px;\n pointer-events: none;\n transform: translate(-50%, -50%);\n z-index: 60;\n}\n\n.bre-drag-ghost-name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.bre-drag-ghost svg { color: var(--dsw-alias-label-tertiary, #81858c); }\n\n/* The row the drag is carrying: still in place, visibly the one in hand. */\nli.bre-row-dragging { opacity: .5; }\n\n/* The row the pointer would drop it on \u2014 a secondary cue; the insertion line\n below is the one that says which side. */\nli.bre-row-drop-target { border-color: var(--dsw-alias-brand-primary); }\n\n/* The insertion line. A fixed overlay on the body, never a child of the list\n React owns, so writing it cannot trigger anything in the official section.\n The layer stack matters more than it looks: the provider list lives inside the\n settings dialog, whose overlay is fixed and opaque with z-index 1000, so a\n line in the shell's own range would be drawn behind the dialog and never\n seen. It clears the dialog, and stays under the header's controls. */\n.bre-drop-line {\n position: fixed;\n display: none;\n height: 2px;\n border-radius: 2px;\n background: var(--dsw-alias-brand-primary, #4d6bfe);\n box-shadow: 0 0 0 1px #ffffffb3, 0 1px 4px var(--dsw-alias-brand-primary, #4d6bfe);\n pointer-events: none;\n z-index: 1200;\n}\n\n/* The row slide (a FLIP pass driven from the script) is motion; drop it for a\n reader who asked for less. */\n@media (prefers-reduced-motion: reduce) {\n li[data-bre-row-provider] { transition: none !important; }\n}\n\n@media (max-width: 520px) {\n .bre-drag-grip { width: 18px; height: 24px; }\n .bre-drag-ghost { max-width: 180px; font-size: 12px; }\n}\n\n/* ---- Model rows inside one provider's editor (Models page) ---- */\n\n/* The official model row is a four-column grid (id, display name, two icon\n buttons). Our grip is a fifth child, so the grid needs a leading track to\n hold it \u2014 declared by our own class, because the official rule is a single\n class selector and ours has to win on specificity, not on load order.\n The name must NOT be \"bre-model-row\": that one is this plugin's own composer\n row (see the \".bre-model-row\" block above), and lending it to the host's grid\n would hand that grid our padding, gap, min-height, pointer cursor and hover\n fill along with it. */\n.bre-model-grid[class*=\"modelRow\"] {\n grid-template-columns: auto minmax(0, 1.4fr) minmax(0, 1fr) auto auto;\n}\n\n/* A model row is a grid of inputs, so only the grip drags: the row keeps its\n text cursor and its own click behaviour. The grip takes the height of the\n row's controls, so the pointer has a real target inside a 6px-gap grid. */\n.bre-model-grid > .bre-drag-grip {\n width: 18px;\n height: 24px;\n margin-right: 0;\n}\n\n/* The engine paints the carried row and the row under the pointer with the same\n classes it uses on a provider card; the official model entry carries the\n border, so the drop cue has to land there rather than on the list item. */\ndiv.bre-row-dragging { opacity: .5; }\n[class*=\"modelEntry\"].bre-row-drop-target { border-color: var(--dsw-alias-brand-primary); }\n\n/* The row slide (a FLIP pass driven from the script) is motion; drop it for a\n reader who asked for less. */\n@media (prefers-reduced-motion: reduce) {\n [data-bre-row-model] { transition: none !important; }\n}\n\n/* ---- Provider enable switch (Models page) ---- */\n\n/* Leads the row's own action group (which is pushed right by margin-left:auto),\n in front of the card's buttons, so the destructive one stays last. The knob is\n a pseudo element: no extra node for the official section's tree to trip over. */\n.bre-provider-switch {\n position: relative;\n flex: 0 0 auto;\n width: 30px;\n height: 18px;\n padding: 0;\n border: none;\n border-radius: 9px;\n background: var(--dsw-alias-bg-tertiary, #d7dae0);\n cursor: pointer;\n transition: background 140ms ease;\n}\n\n.bre-provider-switch::after {\n content: '';\n position: absolute;\n top: 2px;\n left: 2px;\n width: 14px;\n height: 14px;\n border-radius: 50%;\n background: var(--dsw-alias-bg-elevated, #ffffff);\n box-shadow: 0 1px 2px #00000026;\n transition: transform 140ms ease;\n}\n\n.bre-provider-switch:not([aria-checked='true']):hover { background: var(--dsw-alias-bg-quaternary, #c9ccd2); }\n\n.bre-provider-switch[aria-checked='true'] { background: var(--dsw-alias-brand-primary, #4d6bfe); }\n\n.bre-provider-switch[aria-checked='true']:hover { background: var(--dsw-alias-brand-primary-hover, #3f5ce8); }\n\n.bre-provider-switch[aria-checked='true']::after { transform: translateX(12px); }\n\n.bre-provider-switch:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary, #4d6bfe);\n outline-offset: 2px;\n}\n\n/* A provider that is switched off stays on the page \u2014 this is the only place it\n can be switched back on \u2014 but it is visibly out of play. The switch itself is\n left at full strength: it is the way back. */\nli.bre-row-disabled [class*=\"rowIdentity\"],\nli.bre-row-disabled [class*=\"rowName\"] { opacity: .5; }\n\n@media (prefers-reduced-motion: reduce) {\n .bre-provider-switch,\n .bre-provider-switch::after { transition: none; }\n}\n\n/* ---- The reserved delete seat (Models page) ---- */\n\n/* A provider the host will not let the user remove renders no delete button, so\n that row's action group \u2014 pushed right by margin-left:auto \u2014 starts further\n right than its neighbours' and the column of buttons lines up raggedly. This\n seat holds the place: it borrows the metrics the official button takes inside\n an action group (.rowActions button is 28px tall / 12px / 0 10px) and the\n dimmed treatment the host gives its own disabled buttons (opacity .4 with a\n default cursor). It is always disabled \u2014 it is the alignment, not an action. */\n.bre-provider-delete {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 28px;\n padding: 0 10px;\n border: none;\n border-radius: var(--dsw-radius-sm, 6px);\n background: 0 0;\n color: var(--dsw-alias-state-error-primary, #e5484d);\n font: inherit;\n font-size: 12px;\n line-height: 18px;\n opacity: .4;\n cursor: default;\n}\n\n/* -----------------------------------------------------------------------\n The provider editor's three tabs.\n\n The official editor lays a provider out as one long column \u2014 identity\n fields, then the model list, then this plugin's request-header section\n one slot up the card. The tab pass (injection/editor-tabs.ts) tags each\n region and stamps the card with the active tab; EVERY visibility decision\n lives here, so the official React tree never moves and a pass failure\n degrades to the untouched one-column editor.\n ----------------------------------------------------------------------- */\n\n/* The segmented control. The plugin's tab-bar component renders it inside the\n request-header mount, which already holds the card's 12px gap slot \u2014 so the\n bar reaches the panes in the card's own rhythm WITHOUT this plugin ever\n inserting a node into the official child list. It stays hidden until the pass\n marks the card: a card the pass could not take over (the DeepSeek account\n editor) keeps that mount visible for its request-header section, and must not\n grow a bar that switches nothing. */\n.bre-editor-tabs {\n display: none;\n gap: 2px;\n padding: 2px;\n border-radius: 10px;\n background: var(--dsw-alias-fill-tertiary, rgba(120, 125, 140, .09));\n}\n\n/* Only a taken-over card shows the bar. */\n.bre-tabbed .bre-editor-tabs { display: flex; }\n\n/* ...and while the takeover is on, the mount holding that bar MUST be visible.\n This is the one place the takeover does not delegate its reveal to the\n official-edit state: the bar lives in here, and gating it on the _editor\n class probe would make the tabs depend on a probe an official redesign can\n break \u2014 with data-edit stuck at 0 the bar would be inside a display:none\n parent and no rule of ours could reach it. The taken-over class is written by\n the pass itself, in the same frame, so it is the trustworthy half of the\n pair. The section's own visibility stays a pane decision (below). */\n.bre-tabbed .bre-headers-host { display: block; }\n\n.bre-editor-tab {\n flex: 1 1 0;\n min-width: 0;\n height: 28px;\n padding: 0 10px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: var(--dsw-alias-label-secondary, #61666b);\n font: inherit;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n cursor: pointer;\n transition: background 140ms ease, color 140ms ease, box-shadow 140ms ease;\n}\n\n.bre-editor-tab:hover { color: var(--dsw-alias-label-primary, #0f1115); }\n\n/* The selected segment lifts out of the track: the page's own surface colour\n plus the card's own hairline, the same elevation the host uses for raised\n controls. Hover on a selected tab stays put \u2014 it is already where you are. */\n.bre-editor-tab[aria-selected='true'],\n.bre-editor-tab[aria-selected='true']:hover {\n background: var(--dsw-alias-bg-layer-1, #fff);\n color: var(--dsw-alias-label-primary, #0f1115);\n box-shadow: 0 1px 2px #0000001a, 0 0 0 1px var(--dsw-alias-border-l2, #0000001a);\n}\n\n.bre-editor-tab:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary, #4d6bfe);\n outline-offset: 1px;\n}\n\n/* An advanced section with no headers mount (pre-first-render, feature off)\n offers an empty pane \u2014 the button steps aside until the mount exists. */\n.bre-editor-tab[hidden] { display: none; }\n\n/* Pane visibility, keyed on the card's active tab. Only the HIDING has to win\n a specificity fight (against the official sheet and the headers host's own\n reveal rule); the active pane keeps whatever display the official layout\n gave it, so showing must not declare a display at all. */\n.bre-tabbed:not([data-bre-tab='provider']) [data-bre-region='provider'],\n.bre-tabbed:not([data-bre-tab='models']) [data-bre-region='models'],\n.bre-tabbed:not([data-bre-tab='advanced']) [data-bre-region='advanced'] {\n display: none !important;\n}\n\n/* The advanced tab: the official body \u2014 fields, model list, action row and the\n editor's own header \u2014 steps aside for the request-header section, which is a\n complete form with its own save/cancel and becomes the pane under the very\n same bar. */\n.bre-tabbed[data-bre-tab='advanced'] [data-bre-editor-body] {\n display: none !important;\n}\n\n/* The advanced pane shows the section for the same reason the mount is shown:\n a pane that is already the active one has no business depending on the\n official-edit probe. The rule above still wins for every other tab, and the\n base bre-headers rule keeps a collapsed card's section hidden \u2014 a card only\n carries the taken-over class while its editor is open. */\n.bre-tabbed[data-bre-tab='advanced'] .bre-headers { display: flex; }\n\n/* The pane is a card, and the section draws it. On the advanced tab the section\n is not an appendage to the fields above it any more \u2014 it is the whole surface\n \u2014 so it takes the inset fill the official module cards use (the add and setup\n cards): the one fill in this system that stays visible on the content card's\n own white in the light theme and reads as raised in the dark one, where every\n theme layer token collapses onto the same value. The hairline goes with it: it\n divided this section from those fields, and here the bar above ends the pane.\n The 12px top margin sets the card off the tab bar above it \u2014 the same gap the\n provider and models panes put between the bar and their own cards \u2014 and the\n 12px padding is the card's inner inset, not the separator. */\n.bre-tabbed[data-bre-tab='advanced'] .bre-headers {\n margin-top: 12px;\n padding: 12px;\n border-top: none;\n border-radius: var(--dsw-radius-lg, 16px);\n background: var(--dsw-alias-bg-module-platform, #f5f6f7);\n}\n\n/* The live editor folds its identity fields and model list into one\n \"Customized\" disclosure. Under the tabs the grouping is the panes' job: the\n group stays expanded (the pass forces it open) and its summary row \u2014 now a\n toggle with nothing left to toggle \u2014 steps aside. */\n.bre-tabbed [data-bre-editor-body] details > summary {\n display: none !important;\n}\n\n/* A region that is NOT a pane. The editor's own header repeats the card row's\n provider name and route tag, and that row is already on screen directly above\n it, so the header is hidden on every tab. No pane rule above can select this\n id, which is what keeps it hidden whichever tab is active. */\n.bre-tabbed [data-bre-region='none'] {\n display: none !important;\n}\n\n/* The Models pane shows the custom model list and the catalogue, and two\n hairlines used to divide it: the \"Customized\" group's separator from the key\n field (which this pane hides) and the catalogue's own, drawn directly above\n its \"Model catalogue\" heading. Neither has anything to divide here \u2014 the tab\n bar already ends the pane above, and the divider between the two lists above\n the catalogue is the group's boundary, not a rule. Both go, with every top\n padding that held content off them (the group's 10px, its body's 12px, the\n catalogue's 12px), so the pane runs from the tab bar into the catalogue with\n only the official editor's own 14px gap between blocks. */\n.bre-tabbed[data-bre-tab='models'] [data-bre-editor-body] details[class*='customized'] {\n border-top: none;\n padding-top: 0;\n}\n\n.bre-tabbed[data-bre-tab='models'] [data-bre-editor-body] details[class*='customized'] > [class*='customizedBody'] {\n padding-top: 0;\n}\n\n/* The catalogue is a section (its heading, title and meta are the divs inside\n it), so this probe hits the ruled box and nothing else. */\n.bre-tabbed[data-bre-tab='models'] [data-bre-editor-body] section[class*='modelCatalog'] {\n border-top: none;\n padding-top: 0;\n}\n\n/* The catalogue heading names a box this pane has already named for the user:\n the Models tab IS the catalogue, so \"\u6A21\u578B\u76EE\u5F55\" says it twice, and\n \"\u5DF2\u81EA\u5B9A\u4E49\u6A21\u578B\u76EE\u5F55\" (the meta line beside it) says nothing at all \u2014 the rows\n below ARE the customized catalogue. Both strings are the host's own, so they\n go by class stem, and the heading takes its title and meta with it. The\n head's own controls (\u6062\u590D\u9ED8\u8BA4\u6A21\u578B / \u83B7\u53D6\u53EF\u7528\u6A21\u578B) are siblings of the heading,\n not children, so they stay \u2014 the auto-adapt seat is anchored to them. */\n.bre-tabbed[data-bre-tab='models'] [data-bre-editor-body] [class*='modelCatalogHeading'] {\n display: none;\n}\n\n/* With the heading gone the head holds only controls, and they read as TWO\n ENDS: \u6062\u590D\u9ED8\u8BA4\u6A21\u578B stays at the left edge while \u83B7\u53D6\u53EF\u7528\u6A21\u578B keeps the\n auto-adapt seat beside it at the far right \u2014 the seat belongs to that link's\n group, it is never a column of its own. The official space-between cannot\n express that once a third child exists: it spreads the three evenly, which\n strands the fetch link in the middle of the card. So the free space is handed\n to the fetch link's own leading auto margin instead \u2014 an auto margin absorbs\n the space BEFORE justify-content is consulted, whatever the official rule\n says. The fetch link is the button the seat sits after, which is also the\n only control present when the provider is not overridden: the pair then\n simply holds the right edge. align-items centres the taller host links\n against the seat. */\n.bre-tabbed[data-bre-tab='models'] [data-bre-editor-body] [class*='modelListHead'] {\n align-items: center;\n}\n.bre-tabbed[data-bre-tab='models'] [data-bre-editor-body] [class*='modelListHead'] > button:has(+ .bre-auto-effort) {\n margin-left: auto;\n}\n\n/* The click's answer, as a bubble at the top of the window that takes itself\n away again. The control is left alone on purpose: its label is what the user\n aimed at, and a button that rewrites itself is a button that moved. The\n bubble is a fixed overlay on the body \u2014 not a child of the head, which is the\n host's flex row and would take a fourth item \u2014 and it clears the settings\n dialog's opaque overlay for the same reason the drop line does. It follows\n the host's own toast in placement and tone, but not in z-index: the settings\n dialog's overlay outranks the toast layer, and this bubble is raised from\n inside that dialog. Pointer-events none keeps it out of the way, the phase\n colours the headline so the outcome reads before the words do, and the\n hold/fade pair is timed by --bre-note-hold, which the script sets from the\n same constant it uses for the dismissal. The fade is counted INSIDE that\n hold, so the bubble is gone when the clock says it is, rather than fading\n after it. */\n.bre-auto-effort-note {\n position: fixed;\n top: 40px;\n left: 50%;\n display: flex;\n flex-direction: column;\n gap: 2px;\n width: max-content;\n max-width: min(640px, calc(100vw - 48px));\n padding: 10px 14px;\n border-radius: 10px;\n background: var(--dsw-alias-toast-bg, #2b2f36);\n color: var(--dsw-alias-toast-label, #f9fafb);\n box-shadow: var(--dsw-shadow-lv3, 0 6px 24px #00000029);\n font-size: 13px;\n line-height: 20px;\n pointer-events: none;\n transform: translateX(-50%);\n animation: bre-note-in 160ms ease-out, bre-note-out 400ms ease calc(var(--bre-note-hold, 3000ms) - 400ms) forwards;\n z-index: 1200;\n}\n/* A pass in flight has no lifetime of its own: it is replaced by its verdict,\n which restarts both animations because the phase changes the rule. */\n.bre-auto-effort-note[data-bre-auto-effort-phase='working'] {\n animation: bre-note-in 160ms ease-out;\n}\n@keyframes bre-note-in {\n from { opacity: 0; transform: translate(-50%, -6px); }\n to { opacity: 1; transform: translate(-50%, 0); }\n}\n@keyframes bre-note-out {\n to { opacity: 0; visibility: hidden; }\n}\n@media (prefers-reduced-motion: reduce) {\n .bre-auto-effort-note {\n animation: bre-note-out 400ms ease calc(var(--bre-note-hold, 3000ms) - 400ms) forwards;\n }\n .bre-auto-effort-note[data-bre-auto-effort-phase='working'] { animation: none; }\n}\n.bre-auto-effort-note-text { font-weight: 500; }\n.bre-auto-effort-note-detail { opacity: .72; }\n/* The attribute is the visibility switch, so it must beat the flex column above. */\n.bre-auto-effort-note-detail[hidden] { display: none; }\n.bre-auto-effort-note[data-bre-auto-effort-phase='working'] .bre-auto-effort-note-text {\n color: var(--dsw-alias-state-business-primary, #6ea8fe);\n}\n.bre-auto-effort-note[data-bre-auto-effort-phase='done'] .bre-auto-effort-note-text {\n color: var(--dsw-alias-state-success-primary, #22c55e);\n}\n.bre-auto-effort-note[data-bre-auto-effort-phase='failed'] .bre-auto-effort-note-text {\n color: var(--dsw-alias-state-error-secondary, #ff8a80);\n}\n\n/* The API-key eye. The official key field is a plain flex column whose input is\n its last in-flow child, so the button hangs on the field's own box and is\n measured against the input's 32px row \u2014 the official markup offers no\n wrapper, and introducing one would mean moving DOM the host owns. The input\n keeps the room the button needs. */\n.bre-key-field { position: relative; }\n\n.bre-key-field > input { padding-right: 34px; }\n\n/* A field the plugin's key list manages hands its input over: the list below\n says the same thing once per key and keeps the pick, the alias and the value\n in one place, so an official box that writes the provider's single key would\n be a second, conflicting way to do it. The input stays in the DOM \u2014 the\n host's form still owns it and the reveal pass still finds it \u2014 so unmanaging\n the field brings the official box back. The marker is what the reveal pass\n stamps on that input; the direct-child form covers the pass that has not run\n yet, and the eye is the button the same pass hangs on the field. */\n.bre-key-managed [data-bre-key-input],\n.bre-key-managed > input,\n.bre-key-managed .bre-key-eye { display: none; }\n\n/* A field that failed validation grows a message line under the input; the eye\n rides above it so it stays on the input it belongs to (18px line + 6px gap). */\n.bre-key-field:has(> p) .bre-key-eye { bottom: 24px; }\n\n.bre-key-eye {\n position: absolute;\n right: 4px;\n bottom: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 32px;\n padding: 0;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: var(--dsw-alias-label-secondary, #6b7280);\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n transition: background 140ms ease, color 140ms ease;\n}\n\n.bre-key-eye:hover {\n color: var(--dsw-alias-label-primary, #0f1115);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.bre-key-eye:focus-visible {\n outline: none;\n box-shadow: inset 0 0 0 2px var(--dsw-alias-border-l3);\n}\n\n/* Resolving a stored key is a same-origin round trip, so the button can be\n busy: it stays in place and dims rather than changing size or disappearing. */\n.bre-key-eye[aria-busy='true'] {\n opacity: 0.55;\n cursor: progress;\n}\n\n.bre-key-eye[hidden] { display: none; }\n\n/* One glyph at a time. The state lives on the button's own attribute, so a\n click swaps the icon without the host re-rendering anything. */\n.bre-key-eye svg[data-bre-icon] { display: none; }\n\n.bre-key-eye[aria-pressed='false'] svg[data-bre-icon='eye'],\n.bre-key-eye[aria-pressed='true'] svg[data-bre-icon='eye-off'] { display: block; }\n\n/* The key list. The plugin mounts it into its own host, a sibling placed right\n after the official key field, so the list sits under the input without\n changing the field's own box: the reveal eye is measured against that box\n (bottom: 0), and a list inside the field would drag the eye down onto the\n list's last row. The margin only covers the case where the card spaces its\n fields with margins instead of a gap. */\n.bre-keys-host {\n display: block;\n min-width: 0;\n margin-top: 4px;\n}\n\n.bre-keys { display: flex; flex-direction: column; gap: 8px; }\n\n/* While the key list is still reading, the panel renders NOTHING (the component\n returns an empty .bre-keys). An empty ruled box \u2014 or a placeholder line that\n then swaps to the list \u2014 would paint one frame of a panel that then visibly\n changes: the \"the key section flashes when you press Edit\" report. :empty\n takes the panel out of the layout until the first answer lands, so the list\n is the first thing the key area ever paints, and nothing under it moves. */\n.bre-keys:empty { display: none; }\n\n/* One ruled container holding the keys and the add entry, the way a settings\n list reads: a single hairline box, and hairlines between rows only. */\n.bre-keys-list {\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n border: 0.5px solid var(--dsw-alias-border-l2, #d5d7dd);\n border-radius: 8px;\n list-style: none;\n overflow: hidden;\n}\n\n.bre-keys-list > li + li { border-top: 0.5px solid var(--dsw-alias-border-l2, #d5d7dd); }\n\n.bre-keys-row {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n padding: 9px 10px;\n}\n\n/* The enable choice closes the row. The radio stays the real input \u2014 so the\n keys of one provider are one group, choosing one clears the rest, and the\n pick is keyboard-reachable \u2014 and the circle is its face; the word beside it\n names the action instead of a state to hunt for. */\n.bre-keys-enable {\n display: inline-flex;\n flex: 0 0 auto;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n}\n\n.bre-keys-enable-text {\n font-size: 11px;\n line-height: 1.5;\n color: var(--dsw-alias-label-secondary, #6b7280);\n}\n\n.bre-keys-enable:has(.bre-keys-enabled:checked) .bre-keys-enable-text {\n color: var(--dsw-alias-label-primary, #0f1115);\n}\n\n.bre-keys-enabled {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n border: 0;\n overflow: hidden;\n white-space: nowrap;\n clip-path: inset(50%);\n}\n\n.bre-keys-mark {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n box-sizing: border-box;\n border: 1px solid var(--dsw-alias-border-l3, #9aa0aa);\n border-radius: 50%;\n color: var(--dsw-alias-bg-layer-1, #ffffff);\n transition: background 120ms ease, border-color 120ms ease;\n}\n\n.bre-keys-mark > svg { width: 12px; height: 12px; }\n\n.bre-keys-enabled:checked + .bre-keys-mark {\n border-color: var(--dsw-alias-label-primary, #0f1115);\n background: var(--dsw-alias-label-primary, #0f1115);\n}\n\n.bre-keys-enabled:focus-visible + .bre-keys-mark {\n outline: none;\n box-shadow: 0 0 0 2px var(--dsw-alias-brand-primary, #3b82f6);\n}\n\n/* With an alias the alias is the row's name and the masked key follows it as a\n quiet code pill; without one the masked key is the name and takes the row's\n measure, so a key is always readable as itself. */\n.bre-keys-alias {\n flex: 0 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 12px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #0f1115);\n}\n\n.bre-keys-mask {\n flex: 0 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n padding: 1px 6px;\n border-radius: 4px;\n background: var(--dsw-alias-interactive-bg-hover, rgba(127, 127, 127, 0.08));\n color: var(--dsw-alias-label-secondary, #6b7280);\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 11px;\n}\n\n.bre-keys-mask-plain {\n flex: 1 1 auto;\n padding: 0;\n background: transparent;\n color: var(--dsw-alias-label-primary, #0f1115);\n font-family: inherit;\n font-size: 12px;\n}\n\n/* The row's three actions, revealed on hover or keyboard focus rather than\n removed, so the row keeps its width and nothing shifts under the pointer.\n Revealing is opacity alone; a pointer that cannot hover simply always sees\n them, because a hidden action there would be an unreachable one. */\n.bre-keys-actions {\n display: inline-flex;\n flex: 0 0 auto;\n align-items: center;\n gap: 10px;\n margin-left: auto;\n opacity: 0;\n pointer-events: none;\n transition: opacity 120ms ease;\n}\n\n.bre-keys-row:hover .bre-keys-actions,\n.bre-keys-row:focus-within .bre-keys-actions {\n opacity: 1;\n pointer-events: auto;\n}\n\n@media (hover: none) {\n .bre-keys-actions { opacity: 1; pointer-events: auto; }\n}\n\n.bre-keys-danger { color: var(--dsw-alias-state-error-primary, #c62828); }\n\n/* The one inline form. It opens under the row it edits, or \u2014 for a new key \u2014 as\n the list's own last item, which is what keeps adding a key in place instead\n of in a dialog that has to be found and dismissed. */\n.bre-keys-form-row { padding: 10px; }\n\n.bre-keys-form { display: flex; flex-direction: column; gap: 8px; }\n\n.bre-keys-form-fields {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 8px;\n}\n\n/* One field means the whole row: the value form holds only the secret, and it\n must not sit in half a row beside an empty half. */\n.bre-keys-form-fields > :only-child { grid-column: 1 / -1; }\n\n/* The shared input caps itself at 240px for the panels it was written for; here\n the field is the measure. */\n.bre-keys-form-fields .bre-text-input { max-width: none; }\n\n.bre-keys-form-actions {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n}\n\n/* The shared primary button is styled inside the headers editor, which is not\n where this form lives, so the key list carries its own compact copy. */\n.bre-keys-form-actions .bre-primary-button {\n height: 28px;\n padding: 0 12px;\n border: 0;\n border-radius: var(--dsw-radius-md, 8px);\n background: var(--dsw-alias-button-primary-fill, #0f1115);\n color: var(--dsw-alias-label-primary-foreground, #ffffff);\n font: inherit;\n font-size: 12px;\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n}\n\n.bre-keys-form-actions .bre-primary-button:hover {\n background: var(--dsw-alias-button-primary-hover, #43454a);\n}\n\n.bre-keys-form-actions .bre-primary-button:disabled { opacity: 0.5; cursor: default; }\n\n.bre-keys-form-actions .bre-primary-button:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--dsw-alias-brand-primary, #3b82f6);\n}\n\n/* The add entry is the list's own last row \u2014 full width, the same shape as the\n keys it adds to \u2014 so the way in and the thing it makes read as one list. */\n.bre-keys-add-row { padding: 0; }\n\n.bre-keys-add {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 9px 10px;\n box-sizing: border-box;\n border: 0;\n background: transparent;\n color: var(--dsw-alias-label-secondary, #6b7280);\n font: inherit;\n font-size: 12px;\n text-align: left;\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n transition: background 120ms ease, color 120ms ease;\n}\n\n.bre-keys-add:hover {\n background: var(--dsw-alias-interactive-bg-hover, rgba(127, 127, 127, 0.08));\n color: var(--dsw-alias-label-primary, #0f1115);\n}\n\n.bre-keys-add:focus-visible {\n outline: none;\n box-shadow: inset 0 0 0 2px var(--dsw-alias-brand-primary, #3b82f6);\n}\n\n.bre-keys-add:disabled { opacity: 0.55; cursor: default; }\n\n.bre-keys-add-mark {\n display: inline-flex;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n}\n\n.bre-keys .bre-effort-message { font-size: 11px; }\n\n@media (prefers-reduced-motion: reduce) {\n .bre-editor-tab { transition: none; }\n .bre-key-eye { transition: none; }\n .bre-keys-mark, .bre-keys-actions, .bre-keys-add { transition: none; }\n}\n";
8
+ export declare const STYLES = "\n/* The injector's mount wrapper. It \u2014 not the editor inside it \u2014 is the item\n placed into the official row disclosure's repeat(auto-fit, minmax(160px,1fr))\n grid (context window and max tokens take two cells), so the span belongs\n here: on the editor itself it would target the wrapper's block box and be\n ignored, squeezing the block into one cell. */\n.bre-effort-slot {\n grid-column: 1 / -1;\n}\n/* The slot wrapper is a plain column: the master thinking switch sits in it,\n directly above the card it gates. */\n.bre-effort-editor {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin: 8px 0 4px;\n}\n/* The \u601D\u8003\u5F3A\u5EA6 card proper \u2014 rendered only while the master switch is on. */\n.bre-effort-card {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px 12px;\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-2);\n box-sizing: border-box;\n}\n.bre-effort-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n.bre-effort-title {\n font-size: 12px;\n font-weight: 600;\n color: var(--dsw-alias-label-secondary);\n}\n.bre-link-button {\n background: none;\n border: none;\n padding: 2px 6px;\n font-size: 12px;\n color: var(--dsw-alias-link);\n cursor: pointer;\n border-radius: 4px;\n}\n.bre-link-button:hover { text-decoration: underline; }\n.bre-link-button:disabled { opacity: 0.5; cursor: default; text-decoration: none; }\n.bre-auto-effort {\n /* Seated in the OFFICIAL catalogue head, among the host's own controls, so it\n wears THEIR metrics instead of the plugin's blue underlined link look\n (user request: \"\u4E0D\u8981\u8D85\u94FE\u63A5\u6837\u5F0F\uFF0C\u8DDF\u53E6\u5916\u4E24\u4E2A\u4FDD\u6301\u4E00\u81F4\"). These values mirror\n the host's own linkButton rule; the seat cannot simply take that class,\n because it would then answer the probe that finds the anchor it sits after.\n No extra margin: the head's own 12px gap already spaces it exactly like the\n controls beside it. */\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n height: 28px;\n padding: 0 10px;\n border: none;\n border-radius: var(--dsw-radius-sm, 8px);\n background: none;\n color: var(--dsw-alias-label-tertiary, #6b7280);\n font: inherit;\n font-size: 12px;\n line-height: 18px;\n cursor: pointer;\n flex: none;\n}\n.bre-auto-effort:hover {\n background: var(--dsw-alias-interactive-bg-hover, #2631480f);\n color: var(--dsw-alias-label-secondary, #374151);\n}\n.bre-effort-grid {\n /* Exactly two equal columns mirroring the official capacity pair the editor\n sits under; an odd row count leaves the last cell in the left column,\n so the left side carries the extra level. */\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 4px 16px;\n}\n.bre-effort-row {\n display: grid;\n grid-template-columns: 20px 76px minmax(0, 1fr);\n align-items: center;\n gap: 6px;\n font-size: 12px;\n}\n.bre-effort-row input[type='checkbox'] {\n /* Bigger than the browser default (~13px): a tap/point target that does\n not require precision, in the theme accent when checked. */\n width: 18px;\n height: 18px;\n margin: 0;\n accent-color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n}\n.bre-effort-level { color: var(--dsw-alias-label-tertiary); }\n.bre-effort-wire {\n box-sizing: border-box;\n min-width: 0;\n height: 24px;\n padding: 0 6px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 4px;\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 12px;\n}\n.bre-effort-wire:focus {\n outline: none;\n border-color: var(--dsw-alias-brand-primary);\n}\n.bre-effort-empty { min-height: 24px; }\n.bre-effort-actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n}\n.bre-secondary-button {\n height: 26px;\n padding: 0 12px;\n border-radius: 6px;\n font-size: 12px;\n cursor: pointer;\n border: 0.5px solid var(--dsw-alias-border-l3);\n}\n.bre-secondary-button:disabled { opacity: 0.5; cursor: default; }\n.bre-secondary-button { background: transparent; color: inherit; }\n.bre-effort-message { font-size: 12px; margin: 0; }\n.bre-effort-message.bre-error { color: #c62828; }\n.bre-effort-message.bre-info { color: var(--dsw-alias-link); }\n.bre-effort-note { font-size: 11px; margin: 0; color: var(--dsw-alias-label-tertiary); }\n/* ---- Input-modality section ---- */\n.bre-modality {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.bre-modality-row {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n}\n.bre-modality-row input[type='checkbox'] {\n width: 18px;\n height: 18px;\n margin: 0;\n accent-color: var(--dsw-alias-brand-primary);\n cursor: pointer;\n}\n.bre-modality-clear { margin-left: auto; }\n.bre-modality-note { font-size: 11px; margin: 0; color: var(--dsw-alias-label-tertiary); }\n/* The master thinking switch, which lives OUTSIDE the card it gates: with it\n off that card is not rendered at all, so nothing here has to be hidden. */\n.bre-thinking-switch { margin: 0; }\n/* ---- Endpoint-compatibility controls ----\n Same shape as the official capacity fields the editor sits under: a caption\n above the control, the control capped at the official enum width (a field\n width dropdown reads as a text field the user is expected to fill), and a\n hint line beneath. Tokens are the official ones \u2014 the plugin's own --dsh-*\n names are defined nowhere in this app, so their light-mode literals used to\n render in both themes. */\n.bre-compat {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n.bre-compat-row {\n display: flex;\n flex-direction: column;\n gap: 4px;\n min-width: 0;\n}\n.bre-compat-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n.bre-compat-label {\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n}\n.bre-compat-hint {\n font-size: 11px;\n line-height: 16px;\n color: var(--dsw-alias-label-tertiary);\n}\n.bre-select, .bre-text-input {\n box-sizing: border-box;\n width: 100%;\n max-width: 240px;\n height: 32px;\n padding: 0 10px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-primary);\n font: inherit;\n font-size: 14px;\n line-height: 22px;\n}\n.bre-text-input::placeholder { color: var(--dsw-alias-label-dimmed); }\n.bre-select:focus, .bre-text-input:focus {\n outline: none;\n border-color: var(--dsw-alias-brand-primary);\n}\n.bre-select:disabled, .bre-text-input:disabled { opacity: 0.6; cursor: default; }\n.bre-select {\n cursor: pointer;\n /* The OS arrow sits flush against the right edge; the official select swaps\n it for the shared 12px chevron inset on the same right pad. Data-URI SVGs\n cannot resolve CSS variables, so the stroke is the caption gray both\n themes share. */\n appearance: none;\n padding-right: 32px;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 12px center;\n background-size: 12px 12px;\n}\n.bre-error { color: var(--dsw-alias-state-error-primary); }\n/* ---- Zoned suggestion display ---- */\n.bre-suggestion {\n display: flex;\n flex-direction: column;\n gap: 3px;\n}\n.bre-reference {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: 4px 14px;\n padding: 6px 8px;\n border: 1px dashed var(--dsw-alias-border-l3);\n border-radius: 6px;\n font-size: 11px;\n color: var(--dsw-alias-label-tertiary);\n}\n.bre-reference-title { font-weight: 600; }\n.bre-reference-values { display: inline-flex; gap: 14px; }\n/* ---- Composer model-menu slider (mounted inside the OFFICIAL menu) ----\n Visuals ported VERBATIM from HanaAyane's dsh-reasoning-effort (MIT) \u2014 the\n only deliberate difference is the chibi-runner \"big fish\" knob, which is\n dropped so the knob is always the white circle. Class names are re-\n prefixed bre- (the upstream's re- prefix would clash while both plugins\n are installed); every color/size/animation value stays upstream's. */\n.bre-slider-body {\n /* The replicated popover body. The official menu shell carries padding: 4px\n (ModelSelect.module.css), so pull the replica flush to the box. overflow\n stays VISIBLE: an open list is laid out inside the body, so nothing ever\n has to escape it, and the rows' own hover radius needs no clipping. */\n overflow: visible;\n margin: -4px;\n padding: 8px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n/* The official menu is content-sized; while the replicated popover body is\n live, its box takes the upstream .re-model-menu width. The class is added\n by the mount and removed when the slider is switched off. */\n.bre-model-menu-host {\n width: min(340px, calc(100vw - 32px));\n min-width: 0;\n}\n/* The official trigger keeps ownership of its model/effort children. The\n provider prefix is a pseudo-element so host React updates, focus handling and\n the click target remain untouched.\n\n Scoped to the composer, which owns the only button that carries this stamp.\n The settings sidebar's account button is ALSO an [aria-haspopup=\"menu\"]\n button, so an unscoped rule paints the prefix onto the account row the\n moment a stale stamp lands there \u2014 and a stamp that escaped the composer\n must render nothing rather than relabel a host control. The seat anchor is\n listed too, so a shell that renders the trigger outside the card body still\n gets the prefix. */\n[data-composer-card] button[data-bre-provider]::before,\n[data-slot=\"conversation.input.model\"] button[data-bre-provider]::before {\n content: attr(data-bre-provider) \" \u00B7 \";\n flex: none;\n color: var(--dsw-alias-label-secondary);\n font-weight: 400;\n white-space: nowrap;\n}\n\n/* ---- Model / reasoning-level rows ----\n Presentation follows dsh-tauri-model-config's settings rows\n (src/client/models/styles.ts: .zGbnIq_rowCard / .zGbnIq_rowHead /\n .zGbnIq_iconButton): hairline separators between rows and a list opening\n under the row it belongs to. Re-prefixed bre- and routed through the tokens\n this file already uses. */\n/* Layout only \u2014 it deliberately paints NO background, border, radius or\n overflow clip. The replica is mounted inside the OFFICIAL menu, and that\n shell already draws its own surface (MenuSurface: a [data-menu-material]\n panel whose .material child paints --dsw-menu-surface-fill, i.e.\n --dsw-specific-menu, under backdrop-filter: var(--dsw-menu-backdrop-filter),\n rounded by --dsw-radius-lg and outlined by --dsw-elevation-prominent).\n A second opaque card in here shows that official surface as a grey frame\n around it \u2014 two stacked surfaces where every other menu in the app has one. */\n.bre-card {\n display: flex;\n flex-direction: column;\n}\n.bre-row-control {\n appearance: none;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n min-height: 38px;\n padding: 0 10px;\n border: 0;\n /* Matches the official menu cells (.u91W7W_cell / .u91W7W_option use\n --dsw-radius-md, 8px here) and the .bre-option rows below, now that the\n surface behind the rows is the menu's own and hover is no longer clipped\n by a card. */\n border-radius: 8px;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n transition: background 120ms ease;\n}\n.bre-row-control:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, rgba(120, 125, 140, .09));\n}\n.bre-row-control.is-open { background: var(--dsw-alias-fill-tertiary, rgba(120, 125, 140, .09)); }\n.bre-row-control:disabled { cursor: default; opacity: .6; }\n.bre-row-control:focus-visible {\n outline: none;\n box-shadow: inset 0 0 0 2px var(--dsw-alias-border-l3);\n}\n.bre-row-label {\n flex: none;\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary);\n}\n.bre-row-value {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n text-align: right;\n font-size: 13px;\n line-height: 20px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n.bre-row-value.is-muted { font-weight: 400; color: var(--dsw-alias-label-tertiary); }\n.bre-divider { height: 1px; margin: 0 10px; background: var(--dsw-alias-border-l4); }\n.bre-panel {\n display: flex;\n flex-direction: column;\n gap: 2px;\n max-height: 220px;\n overflow-y: auto;\n padding: 2px 6px 8px;\n}\n/* Provider column + model column of the model list, side by side. The height is\n FIXED: switching provider must not resize the card, or every click would need\n another same-frame re-place and any missed one shows as a jump. */\n.bre-panel-models {\n flex-direction: row;\n align-items: stretch;\n gap: 0;\n height: 240px;\n max-height: none;\n overflow: hidden;\n padding: 4px 6px 8px;\n}\n.bre-providers {\n flex: none;\n display: flex;\n flex-direction: column;\n gap: 2px;\n width: 112px;\n overflow-y: auto;\n padding-right: 2px;\n}\n.bre-provider-models {\n flex: 1 1 auto;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n overflow-y: auto;\n margin-left: 6px;\n padding-left: 6px;\n border-left: 1px solid var(--dsw-alias-border-l4);\n}\n.bre-option,\n.bre-provider {\n appearance: none;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n min-height: 30px;\n padding: 0 8px;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: inherit;\n font: inherit;\n font-size: 13px;\n line-height: 20px;\n text-align: left;\n cursor: pointer;\n transition: background 120ms ease, color 120ms ease;\n}\n/* The provider cell carries its chevron hard against the right edge. */\n.bre-provider { gap: 4px; padding: 0 4px 0 8px; }\n.bre-option:hover:not(:disabled),\n.bre-provider:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, rgba(120, 125, 140, .09));\n}\n.bre-option:disabled,\n.bre-provider:disabled { cursor: default; opacity: .6; }\n.bre-option:focus-visible,\n.bre-provider:focus-visible {\n outline: none;\n box-shadow: inset 0 0 0 2px var(--dsw-alias-border-l3);\n}\n.bre-option-name {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bre-option.is-active {\n color: var(--dsw-static-deepseek-500, #4d70ff);\n font-weight: 500;\n background: var(--dsw-alias-fill-tertiary, rgba(120, 125, 140, .09));\n}\n/* The open provider is the highlighted one; the provider of the CURRENT model\n keeps the accent so the column says where the selection lives. */\n.bre-provider.is-open { background: var(--dsw-alias-fill-tertiary, rgba(120, 125, 140, .09)); }\n.bre-provider.is-current .bre-option-name {\n color: var(--dsw-static-deepseek-500, #4d70ff);\n font-weight: 500;\n}\n.bre-provider .bre-row-chevron { width: 14px; height: 14px; font-size: 14px; }\n/* Capability badges on a model row (image input / thinking). Muted so the name\n stays the brightest thing in the row; the badge's own title carries the copy. */\n.bre-option-tags {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n color: var(--dsw-alias-label-tertiary);\n}\n.bre-option.is-active .bre-option-tags { color: var(--dsw-static-deepseek-500, #4d70ff); }\n.bre-tag { display: inline-flex; align-items: center; }\n.bre-tag-icon { display: block; width: 13px; height: 13px; }\n.bre-option-check { flex: none; width: 14px; height: 14px; }\n.bre-empty { padding: 6px 8px; font-size: 12px; color: var(--dsw-alias-label-tertiary); }\n/* ---- Truncated-label tooltip (custom, replaces the native title) ----\n A self-drawn bubble instead of the OS tooltip, which the page cannot style\n and which reads harsh next to the menu. Fixed-positioned on <body> so the\n menu's own overflow/clip cannot cut it, aligned under the truncated span,\n capped to the viewport with wrap for very long names. */\n.bre-tip {\n position: fixed;\n z-index: 2147483647;\n max-width: min(360px, calc(100vw - 24px));\n box-sizing: border-box;\n padding: 5px 9px;\n border-radius: 8px;\n background: var(--dsw-alias-bg-module-platform, #232630);\n color: var(--dsw-alias-label-primary, #f2f3f5);\n font-size: 12px;\n line-height: 18px;\n overflow-wrap: anywhere;\n white-space: normal;\n pointer-events: none;\n box-shadow: 0 4px 16px rgba(0, 0, 0, .22);\n animation: bre-tip-in 120ms ease-out;\n}\nbody:not([data-ds-dark-theme]) .bre-tip {\n background: #ffffff;\n color: var(--dsw-alias-label-primary, #1f2329);\n box-shadow: 0 4px 16px rgba(0, 0, 0, .14), 0 0 0 .5px var(--dsw-alias-border-l4, rgba(0, 0, 0, .1));\n}\n@keyframes bre-tip-in {\n from { opacity: 0; transform: translateY(-2px); }\n to { opacity: 1; transform: translateY(0); }\n}\n@media (prefers-reduced-motion: reduce) {\n .bre-tip { animation: none; }\n}\n.bre-slider-advanced {\n /* upstream .re-advanced: the padded area that hosts the slider */\n padding: 14px;\n}\n.bre-effort {\n display: flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n height: 32px;\n color: var(--dsw-alias-label-secondary);\n user-select: none;\n box-sizing: border-box;\n}\n.bre-effort-slider {\n --bre-progress: 50%;\n position: relative;\n width: 100%;\n height: 30px;\n flex: 1 1 auto;\n border-radius: 999px;\n isolation: isolate;\n transition: filter 180ms ease;\n}\n.bre-effort-track {\n position: absolute;\n inset: 0;\n overflow: hidden;\n border-radius: inherit;\n background: linear-gradient(100deg, #03040a 0%, #071126 22%, #101d4c 45%, #302262 70%, #5d35a0 100%);\n box-shadow:\n inset 0 1px 0 rgba(189, 199, 255, .15),\n inset 0 -1px 0 rgba(0, 0, 0, .55),\n 0 3px 10px rgba(12, 17, 55, .34);\n}\n.bre-effort-track::after {\n content: \"\";\n position: absolute;\n inset: 0;\n background:\n radial-gradient(circle at 18% 45%, rgba(82, 130, 255, .12), transparent 24%),\n linear-gradient(90deg, rgba(0, 0, 0, .28), transparent 42%, rgba(168, 113, 255, .12));\n pointer-events: none;\n}\n.bre-effort-fx {\n position: absolute;\n z-index: 1;\n inset: 0;\n overflow: hidden;\n border-radius: inherit;\n pointer-events: none;\n}\n.bre-effort-canvas {\n position: absolute;\n z-index: 2;\n inset: 0;\n width: 100%;\n height: 100%;\n opacity: 1;\n image-rendering: pixelated;\n mix-blend-mode: screen;\n transition: filter 140ms ease;\n}\n.bre-effort-flare {\n position: absolute;\n z-index: 3;\n top: 50%;\n left: var(--bre-progress);\n width: 78px;\n height: 46px;\n border-radius: 50%;\n background: radial-gradient(ellipse at 100% 50%, rgba(255,255,255,.96) 0 4%, rgba(188,189,255,.8) 11%, rgba(106,87,255,.5) 28%, rgba(105,31,255,.2) 49%, transparent 74%);\n filter: blur(2px) saturate(1.25);\n mix-blend-mode: screen;\n transform: translate(-100%, -50%);\n transition: left 70ms linear, filter 140ms ease;\n pointer-events: none;\n}\n.bre-effort-flare::before,\n.bre-effort-flare::after {\n content: \"\";\n position: absolute;\n inset: 50% auto auto 100%;\n border-radius: 999px;\n transform: translate(-50%, -50%);\n}\n.bre-effort-flare::before {\n width: 52px;\n height: 1px;\n background: linear-gradient(90deg, transparent, rgba(100,160,255,.42), #f1ecff, rgba(193,82,255,.65), transparent);\n box-shadow: 0 0 7px #9b7cff, 0 0 13px rgba(72,132,255,.64);\n}\n.bre-effort-flare::after {\n width: 1px;\n height: 20px;\n background: linear-gradient(180deg, transparent, rgba(196,190,255,.84), transparent);\n box-shadow: 0 0 7px #9c7cff;\n}\n.bre-effort-knob {\n position: absolute;\n z-index: 4;\n top: 50%;\n left: clamp(14px, var(--bre-progress), calc(100% - 14px));\n width: 28px;\n height: 28px;\n border: 1px solid rgba(255,255,255,.94);\n border-radius: 50%;\n background: #fff;\n box-shadow:\n 0 0 0 2px rgba(92,105,255,.12),\n 0 0 14px rgba(121,82,255,.48),\n 0 2px 7px rgba(0,0,0,.3);\n transform: translate(-50%, -50%);\n transition: left 190ms cubic-bezier(.22,1,.36,1), transform 160ms ease, box-shadow 180ms ease;\n pointer-events: none;\n}\n.bre-effort-input {\n position: absolute;\n z-index: 5;\n inset: -5px 0;\n width: 100%;\n height: calc(100% + 10px);\n margin: 0;\n opacity: 0;\n cursor: grab;\n touch-action: none;\n}\n.bre-effort-input:active { cursor: grabbing; }\n.bre-effort-input:focus-visible + .bre-effort-knob {\n outline: 2px solid var(--dsw-static-blue-400);\n outline-offset: 2px;\n}\n.bre-effort.is-dragging .bre-effort-canvas {\n filter: saturate(1.45) brightness(1.28) contrast(1.06);\n}\n.bre-effort.is-dragging .bre-effort-flare {\n filter: blur(1.5px) saturate(1.6) brightness(1.42);\n transition: none;\n}\n.bre-effort.is-dragging .bre-effort-knob {\n transform: translate(-50%, -50%) scale(1.07);\n transition: none;\n box-shadow:\n 0 0 0 3px rgba(113,115,255,.25),\n 0 0 20px rgba(74,145,255,.86),\n 0 0 31px rgba(171,53,255,.66),\n 0 3px 8px rgba(0,0,0,.32);\n}\n.bre-effort-slider[data-top] .bre-effort-track {\n animation: bre-effort-dark-breathe 1.9s ease-in-out infinite;\n}\n.bre-effort-slider[data-top] .bre-effort-knob {\n box-shadow:\n 0 0 0 3px rgba(119,99,255,.18),\n 0 0 22px rgba(135,78,255,.76),\n 0 0 34px rgba(53,121,255,.34),\n 0 3px 8px rgba(0,0,0,.3);\n}\n.bre-effort.is-error .bre-effort-slider {\n outline: 1px solid var(--dsw-alias-state-error-secondary);\n outline-offset: 2px;\n}\n.bre-effort.is-busy { opacity: .72; }\n.bre-effort-sr {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\nbody:not([data-ds-dark-theme]) .bre-effort-slider {\n filter: none;\n}\nbody:not([data-ds-dark-theme]) .bre-effort-track {\n background: var(--dsw-static-blue-75, #e5f0ff);\n box-shadow:\n inset 0 1px 0 rgba(255,255,255,.9),\n inset 0 0 0 1px rgba(80,133,194,.14),\n 0 3px 10px rgba(48,101,165,.13);\n}\nbody:not([data-ds-dark-theme]) .bre-effort-track::before {\n content: \"\";\n position: absolute;\n z-index: 0;\n inset: 0 auto 0 0;\n width: var(--bre-progress);\n border-radius: inherit;\n background: linear-gradient(90deg, #fff 0%, #e2f0ff 20%, #a8d0fb 57%, #438fdf 100%);\n transition: width 190ms cubic-bezier(.22,1,.36,1);\n}\nbody:not([data-ds-dark-theme]) .bre-effort-slider[data-top] .bre-effort-track::before {\n background: linear-gradient(90deg, #fff 0%, #d7eaff 18%, #75afea 54%, #0751ad 100%);\n}\nbody:not([data-ds-dark-theme]) .bre-effort.is-dragging .bre-effort-track::before {\n transition: none;\n}\nbody:not([data-ds-dark-theme]) .bre-effort-track::after {\n z-index: 1;\n background: linear-gradient(90deg, rgba(255,255,255,.48), transparent 34%, rgba(23,101,201,.07));\n}\nbody:not([data-ds-dark-theme]) .bre-effort-canvas {\n opacity: .78;\n mix-blend-mode: multiply;\n}\nbody:not([data-ds-dark-theme]) .bre-effort-flare {\n background: radial-gradient(ellipse at 100% 50%, rgba(255,255,255,.98) 0 5%, rgba(204,231,255,.88) 13%, rgba(91,162,241,.48) 31%, rgba(37,111,207,.16) 53%, transparent 75%);\n filter: blur(2px) saturate(1.12);\n}\nbody:not([data-ds-dark-theme]) .bre-effort-flare::before {\n background: linear-gradient(90deg, transparent, rgba(116,177,244,.34), #fff, rgba(66,139,225,.58), transparent);\n box-shadow: 0 0 7px rgba(58,133,222,.5), 0 0 13px rgba(104,176,255,.38);\n}\nbody:not([data-ds-dark-theme]) .bre-effort-flare::after {\n background: linear-gradient(180deg, transparent, rgba(255,255,255,.94), transparent);\n box-shadow: 0 0 7px rgba(64,137,224,.44);\n}\nbody:not([data-ds-dark-theme]) .bre-effort-knob {\n border-color: rgba(126,160,197,.32);\n box-shadow:\n 0 0 0 2px rgba(58,124,207,.09),\n 0 0 13px rgba(48,118,207,.3),\n 0 3px 8px rgba(39,77,119,.18);\n}\nbody:not([data-ds-dark-theme]) .bre-effort-slider[data-top] .bre-effort-track {\n animation-name: bre-effort-light-breathe;\n}\nbody:not([data-ds-dark-theme]) .bre-effort-slider[data-top] .bre-effort-knob,\nbody:not([data-ds-dark-theme]) .bre-effort.is-dragging .bre-effort-knob {\n box-shadow:\n 0 0 0 3px rgba(36,105,192,.15),\n 0 0 20px rgba(25,100,201,.45),\n 0 3px 8px rgba(39,77,119,.18);\n}\n@keyframes bre-effort-dark-breathe {\n 0%, 100% { box-shadow: inset 0 1px 0 rgba(196,204,255,.16), 0 3px 10px rgba(18,25,72,.4); }\n 50% { box-shadow: inset 0 1px 0 rgba(220,214,255,.24), 0 0 21px rgba(111,66,255,.5); }\n}\n@keyframes bre-effort-light-breathe {\n 0%, 100% { box-shadow: inset 0 1px 0 rgba(255,255,255,.9), inset 0 0 0 1px rgba(67,124,193,.16), 0 3px 10px rgba(48,101,165,.13); }\n 50% { box-shadow: inset 0 1px 0 rgba(255,255,255,.96), inset 0 0 0 1px rgba(31,102,190,.22), 0 0 19px rgba(31,105,201,.24); }\n}\n.bre-slider-hint {\n /* upstream re-model-status */\n display: block;\n padding: 14px;\n color: var(--dsw-alias-label-tertiary, #9296a0);\n font-size: 12px;\n text-align: center;\n}\n/* upstream re-model-error: the directory/store error line under the row */\n.bre-model-error {\n margin: 8px;\n padding: 8px 10px;\n border-radius: 8px;\n color: var(--dsw-alias-state-error-primary, #c83e4d);\n background: var(--dsw-alias-state-error-tertiary, rgba(220,55,70,.08));\n font-size: 11px;\n}\n/* upstream .re-menu-separator */\n.bre-menu-separator {\n height: 1px;\n background: var(--dsw-alias-stroke-secondary, rgba(121,126,145,.16));\n}\n/* upstream .re-model-row: name \u00B7 current effort \u203A (click \u2192 official model list) */\n.bre-model-row {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto auto;\n align-items: center;\n gap: 8px;\n min-height: 45px;\n padding: 0 14px;\n width: 100%;\n border: 0;\n color: inherit;\n background: transparent;\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n.bre-model-row:hover { background: var(--dsw-alias-fill-tertiary, rgba(120,125,140,.09)); }\n.bre-model-row-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }\n.bre-model-row-effort { color: var(--dsw-static-deepseek-500, #4d70ff); font-size: 12px; }\n.bre-row-chevron {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n font-size: 18px;\n line-height: 1;\n color: var(--dsw-alias-label-tertiary);\n transform: rotate(0deg);\n transition: transform 120ms ease;\n}\n.bre-row-chevron.is-open { transform: rotate(90deg); }\n@media (prefers-reduced-motion: reduce) {\n .bre-effort-slider[data-top] .bre-effort-track { animation: none; }\n .bre-effort-knob,\n .bre-effort-flare,\n body:not([data-ds-dark-theme]) .bre-effort-track::before { transition: none; }\n}\n/* ---- Models-page slider toggle (boxed setting item) ----\n Item form ported VERBATIM from upstream .re-setting-row; the surrounding\n box is the requested container (border only, transparent background). */\n.bre-slider-setting {\n margin-top: 12px;\n padding: 0 14px;\n border: 1px solid var(--dsw-alias-stroke-secondary, rgba(121,126,145,.2));\n border-radius: 12px;\n background: transparent;\n}\n.bre-slider-setting-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 24px;\n padding: 16px 0;\n /* Upstream .re-setting-row carries a list bottom border because the general\n settings list held TWO rows (the slider + the big-fish toggle). This box\n holds exactly one, so no divider: the box itself is the container. */\n}\n.bre-slider-setting-copy { min-width: 0; }\n.bre-slider-setting-title {\n color: var(--dsw-alias-label-primary, #15171b);\n font-size: 14px;\n font-weight: 400;\n line-height: 22px;\n}\n.bre-slider-setting-description {\n margin-top: 3px;\n color: var(--dsw-alias-label-tertiary, #9296a0);\n font-size: 12px;\n line-height: 18px;\n}\n.bre-slider-setting-control { display: inline-flex; align-items: center; gap: 10px; flex: none; }\n.bre-slider-setting-state { color: var(--dsw-alias-label-secondary, #686c75); font-size: 13px; }\n.bre-slider-setting-switch {\n position: relative;\n width: 38px;\n height: 22px;\n padding: 0;\n border: 0;\n border-radius: 999px;\n background: var(--dsw-alias-fill-quaternary, #c7cbd3);\n cursor: pointer;\n transition: background 150ms ease;\n}\n.bre-slider-setting-switch:hover { filter: brightness(.97); }\n.bre-slider-setting-switch:disabled { cursor: not-allowed; opacity: .45; }\n.bre-slider-setting-switch:focus-visible {\n outline: 2px solid var(--dsw-static-blue-400, #5d83ff);\n outline-offset: 2px;\n}\n.bre-slider-setting-switch.is-on { background: var(--dsw-alias-state-business-primary, #4f73ff); }\n.bre-slider-setting-switch-knob {\n position: absolute;\n top: 2px;\n left: 2px;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n background: #fff;\n box-shadow: 0 1px 4px rgba(0,0,0,.2);\n transition: transform 170ms cubic-bezier(.22,1,.36,1);\n}\n.bre-slider-setting-switch.is-on .bre-slider-setting-switch-knob { transform: translateX(16px); }\n\n/* Model selection search box */\n.bre-model-search-box {\n display: flex;\n flex-direction: column;\n padding: 6px 8px 4px;\n position: sticky;\n top: 0;\n z-index: 2;\n background: var(--dsw-specific-menu, var(--dsw-alias-bg-layer-1, #1e1f22));\n}\n.bre-model-search-box:has(.bre-search-empty),\n.bre-model-search-box.has-empty {\n flex: 1 1 auto;\n}\n.bre-search-input-wrapper {\n display: flex;\n align-items: center;\n position: relative;\n width: 100%;\n height: 32px;\n padding: 0 8px;\n box-sizing: border-box;\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-2, rgba(255, 255, 255, 0.06));\n border: 0.5px solid var(--dsw-alias-border-l4, rgba(255, 255, 255, 0.12));\n color: var(--dsw-alias-label-primary);\n transition: border-color 150ms ease, box-shadow 150ms ease;\n}\n.bre-search-input-wrapper:focus-within {\n border-color: var(--dsw-static-deepseek-500, #4d70ff);\n box-shadow: 0 0 0 2px rgba(77, 112, 255, 0.2);\n}\n.bre-search-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 16px;\n width: 16px;\n height: 16px;\n margin-right: 6px;\n color: var(--dsw-alias-label-tertiary, #81858c);\n pointer-events: none;\n}\n.bre-search-icon svg {\n width: 14px;\n height: 14px;\n}\n.bre-search-input {\n flex: 1 1 auto;\n min-width: 0;\n height: 100%;\n padding: 0;\n border: none;\n outline: none;\n background: transparent;\n color: inherit;\n font: inherit;\n font-size: 13px;\n line-height: 20px;\n}\n.bre-search-input::placeholder {\n color: var(--dsw-alias-label-tertiary, #81858c);\n opacity: 0.85;\n}\n.bre-search-clear {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 18px;\n width: 18px;\n height: 18px;\n margin-left: 4px;\n padding: 0;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--dsw-alias-label-tertiary, #81858c);\n cursor: pointer;\n transition: background 120ms ease, color 120ms ease;\n}\n.bre-search-clear:hover {\n background: var(--dsw-alias-interactive-bg-hover, rgba(255, 255, 255, 0.1));\n color: var(--dsw-alias-label-primary);\n}\n.bre-search-clear svg {\n width: 12px;\n height: 12px;\n}\n.bre-search-empty {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1 1 auto;\n min-height: 180px;\n padding: 24px 16px;\n text-align: center;\n color: var(--dsw-alias-label-tertiary, #81858c);\n font-size: 13px;\n line-height: 20px;\n user-select: none;\n}\n\n/* ---- Request-header section (issue #12). Mounted through the official\n settings.models.provider-card seat, so it sits in the card's own layout\n rather than a disclosure grid.\n\n Every value below was MEASURED off the official Models page's own controls\n in DSH 0.1.7-rc.2 rather than guessed, and each is expressed through the same\n --dsw-alias-* token the host paints with, so a theme switch (light/dark)\n repaints this section along with the page:\n\n provider card radius 20px, 1px var(--dsw-alias-settings-card-stroke)\n editor action save = filled var(--dsw-alias-button-primary-fill), h36,\n radius 12px, 0 14px, 14px; cancel = 1px border, same box\n row action h28, radius 8px, 0 10px, 12px, 1px border\n text link h21, radius 4px, 2px 6px, 12px, link-blue label\n text input radius 12px, 0 10px, 1px var(--dsw-alias-border-l3) ---- */\n/* The provider-card slot's wrapper.\n The official slot mounts us inside a display:contents container, so our own\n root IS a flex item of the card row \u2014 and the row lays its children out with\n a 12px gap. A wrapper that stays in the flow while empty therefore adds one\n phantom gap to EVERY card in the list, which is exactly the height regression\n this rule exists to prevent. Collapsed, the wrapper leaves the flow entirely:\n the card renders as it did before the plugin.\n (Deliberately NOT display:contents here \u2014 that keeps it a gap-participating\n item, which is the bug this rule fixes.)\n Open, it becomes an ordinary block so the section below can lay itself out.\n data-edit lives HERE \u2014 the occurrence component publishes the card's state\n onto its own root, so keying the rule on .bre-headers[data-edit] instead\n would silently never match. */\n.bre-headers-host {\n display: none;\n}\n.bre-headers-host[data-edit=\"1\"] {\n display: block;\n}\n.bre-headers {\n display: flex;\n flex-direction: column;\n gap: 8px;\n /* The card lays its own children out with a 12px gap and no dividers; this\n section is an addition to that column, so it separates itself the same way\n the host separates card sections \u2014 a hairline on the card's own stroke. */\n border-top: 1px solid var(--dsw-alias-border-l2, #0000001a);\n padding-top: 12px;\n\n /* Present ONLY while the provider card is being edited.\n The provider list is a list of providers: a request-header row parked in\n every card, collapsed or not, is noise on a surface the user did not ask\n to configure. The card reveals its editor when the user presses its own\n Edit action, and that is the moment this section belongs on screen \u2014 the\n same gesture that opens the model list opens this.\n\n The visibility is decided by the component (which watches the card and\n sets data-edit on the wrapper), not by a selector: the official editor is\n NOT a sibling of this element \u2014 its container sits in the card row's own\n children, after the row head and this section's own wrapper \u2014 so no\n relative selector can reach it. The wrapper's data-edit is the one fact\n CSS can act on.\n\n Degradation is safe by construction: with no observer (no card ancestor to\n watch) data-edit stays \"0\", the section is never revealed, and the\n official page stays clean rather than leaking a row into every card. */\n display: none;\n}\n.bre-headers-host[data-edit=\"1\"] .bre-headers {\n display: flex;\n}\n/* The collapsed heading is the section's identity while the card is being\n edited: title, configured count, and the \u203A that opens the details. */\n.bre-headers-disclosure {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n padding: 0;\n border: none;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n.bre-headers-disclosure:hover .bre-effort-title {\n color: var(--dsw-alias-label-secondary, #61666b);\n}\n.bre-headers-chevron {\n margin-left: auto;\n padding-right: 2px;\n color: var(--dsw-alias-label-tertiary, #81858c);\n font-size: 14px;\n line-height: 1;\n transition: transform 150ms ease;\n}\n.bre-headers[data-open=\"1\"] .bre-headers-chevron { transform: rotate(90deg); }\n/* How many entries are configured \u2014 the one fact worth showing while closed. */\n.bre-headers-count {\n min-width: 16px;\n padding: 0 5px;\n border-radius: 8px;\n background: var(--dsw-alias-interactive-bg-hover, #2631480f);\n color: var(--dsw-alias-label-secondary, #61666b);\n font-size: 11px;\n line-height: 16px;\n text-align: center;\n}\n.bre-headers-head {\n display: flex;\n align-items: center;\n min-height: 32px;\n padding: 0 8px;\n border-radius: var(--dsw-radius-sm, 8px);\n background: var(--dsw-alias-interactive-bg-hover, #2631480f);\n}\n.bre-headers-head .bre-effort-title {\n color: var(--dsw-alias-label-primary, #0f1115);\n font-weight: 600;\n}\n.bre-headers-edit, .bre-headers-rows {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n/* The titled-section rows the pane is built from: the title row names its\n section (headers first; future advanced sections each carry one), sitting\n under a hairline the way the official page's group titles do.\n The head strip above it is where the headers section draws its title now \u2014\n it is the one title the pane needs, and it is the line the hint reads under\n \u2014 so this rule is the hairline's home alone, for the sections that follow. */\n.bre-headers-title-row {\n padding-bottom: 6px;\n border-bottom: 1px solid var(--dsw-alias-border-l2, #0000001a);\n margin-bottom: 2px;\n}\n.bre-headers-title-row .bre-effort-title {\n font-size: 13px;\n line-height: 20px;\n}\n\n.bre-headers-columns,\n.bre-headers-row {\n display: grid;\n grid-template-columns: minmax(120px, 0.9fr) minmax(180px, 1.5fr) 28px;\n align-items: center;\n gap: 8px;\n}\n.bre-headers-columns {\n padding: 0 10px;\n color: var(--dsw-alias-label-tertiary, #81858c);\n font-size: 11px;\n line-height: 16px;\n}\n.bre-headers-row {\n min-height: 40px;\n padding: 4px 6px;\n border: 1px solid var(--dsw-alias-border-l2, #0000001a);\n border-radius: var(--dsw-radius-sm, 8px);\n background: var(--dsw-alias-bg-layer-1, #fff);\n}\n.bre-headers-add {\n align-self: flex-start;\n min-height: 30px;\n padding: 0 10px;\n border: 1px solid var(--dsw-alias-border-l2, #0000001a);\n border-radius: var(--dsw-radius-sm, 8px);\n color: var(--dsw-alias-label-primary, #0f1115);\n}\n.bre-headers-add:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, #2631480f);\n}\n.bre-headers-remove {\n width: 28px;\n padding: 0;\n justify-self: center;\n}\n.bre-headers-rows .bre-headers-name {\n color: var(--dsw-alias-label-secondary, #61666b);\n font-size: 12px;\n word-break: break-all;\n}\n.bre-headers-masked {\n color: var(--dsw-alias-label-tertiary, #81858c);\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n letter-spacing: 0;\n}\n\n/* The section's commit/dismiss pair, matching the official editor's own\n actions: a filled commit and a bordered dismiss, 36px tall at 14px. */\n.bre-headers-edit .bre-primary-button {\n height: 36px;\n padding: 0 14px;\n border: none;\n border-radius: var(--dsw-radius-md, 12px);\n background: var(--dsw-alias-button-primary-fill, #0f1115);\n color: var(--dsw-alias-label-primary-foreground, #fff);\n font-size: 14px;\n font-weight: 400;\n line-height: 1;\n cursor: pointer;\n}\n.bre-headers-edit .bre-primary-button:hover:not(:disabled) {\n background: var(--dsw-alias-button-primary-hover, #43454a);\n}\n.bre-headers-edit .bre-primary-button:disabled { opacity: 0.5; cursor: default; }\n.bre-headers-edit .bre-secondary-button {\n height: 36px;\n padding: 0 14px;\n border: 1px solid var(--dsw-alias-border-l3, #0000001f);\n border-radius: var(--dsw-radius-md, 12px);\n background: transparent;\n color: var(--dsw-alias-label-primary, #0f1115);\n font-size: 14px;\n}\n.bre-headers-edit .bre-secondary-button:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, #2631480f);\n}\n\n/* The row actions and the section's Edit affordance: the official 28px\n bordered small button, and the 21px blue text link the model rows use. */\n.bre-headers-row .bre-link-button {\n height: 28px;\n padding: 2px 8px;\n border: none;\n border-radius: var(--dsw-radius-sm, 8px);\n background: transparent;\n color: var(--dsw-alias-label-secondary, #61666b);\n font-size: 12px;\n line-height: 1;\n}\n.bre-headers-row .bre-link-button:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, #2631480f);\n}\n.bre-headers .bre-effort-head > .bre-link-button {\n height: 28px;\n padding: 0 10px;\n border: 1px solid var(--dsw-alias-border-l2, #0000001a);\n border-radius: var(--dsw-radius-sm, 8px);\n color: var(--dsw-alias-label-primary, #0f1115);\n font-size: 12px;\n text-decoration: none;\n}\n.bre-headers .bre-effort-head > .bre-link-button:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, #2631480f);\n text-decoration: none;\n}\n.bre-headers-edit .bre-link-button {\n color: var(--dsw-alias-label-secondary, #61666b);\n font-size: 12px;\n}\n\n/* The section's own fields, on the official input box. */\n.bre-headers-edit input.bre-text-input {\n height: 32px;\n padding: 0 10px;\n border: 1px solid var(--dsw-alias-border-l3, #0000001f);\n border-radius: var(--dsw-radius-md, 12px);\n background: var(--dsw-alias-bg-layer-1, #fff);\n color: var(--dsw-alias-label-primary, #0f1115);\n font-size: 13px;\n box-sizing: border-box;\n}\n.bre-headers-edit input.bre-text-input:focus {\n border-color: var(--dsw-alias-label-tertiary, #81858c);\n outline: none;\n}\n.bre-headers-edit input.bre-text-input:disabled { opacity: 0.6; cursor: default; }\n\n/* Status copy and the coexistence warnings, on the host's own state colours. */\n.bre-headers .bre-effort-note.bre-warn { color: var(--dsw-alias-state-warn-label, #dd8629); }\n.bre-headers .bre-effort-message.bre-success { color: var(--dsw-alias-state-success-primary, #22c55e); }\n.bre-headers .bre-effort-message.bre-error { color: var(--dsw-alias-state-error-primary, #ec1313); }\n\n@media (max-width: 520px) {\n .bre-headers-columns { display: none; }\n .bre-headers-row {\n grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr) 28px;\n gap: 6px;\n padding: 4px;\n }\n .bre-headers-edit input.bre-text-input {\n padding: 0 8px;\n font-size: 12px;\n }\n}\n\n/* ---- Provider row reordering (Models page) ---- */\n\n/* The whole row header is the drag handle: an 18px grip is a poor thing to\n have to hit, so a drag may start anywhere on the header that is not one of\n the card's own controls (those keep their own cursor, declared below). */\nli[data-bre-row-head='1'] { cursor: grab; }\nli[data-bre-row-head='1']:active { cursor: grabbing; }\nli[data-bre-row-head='1'] button,\nli[data-bre-row-head='1'] a,\nli[data-bre-row-head='1'] input { cursor: pointer; }\n\n/* The grip is mounted as the first child of that header, so it reads as part\n of the row rather than as a control bolted beside it. It is also the button\n that reorders by keyboard. */\n.bre-drag-grip {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n width: 14px;\n height: 20px;\n margin-right: 2px;\n border-radius: 4px;\n color: var(--dsw-alias-label-tertiary, #81858c);\n cursor: grab;\n touch-action: none;\n}\n\n.bre-drag-grip:hover {\n color: var(--dsw-alias-label-secondary, #61666b);\n background: var(--dsw-alias-interactive-bg-hover, #2631480f);\n}\n\n.bre-drag-grip:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.bre-drag-grip:active { cursor: grabbing; }\n\n/* What the pointer carries: the browser's own drag image would be a screenshot\n of a whole card, so we hand it this chip with the provider name instead. */\n.bre-drag-ghost {\n position: fixed;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n max-width: 260px;\n padding: 5px 10px 5px 7px;\n border: 1px solid var(--dsw-alias-border-secondary, #e6e8eb);\n border-radius: 8px;\n background: var(--dsw-alias-bg-elevated, #ffffff);\n box-shadow: 0 6px 18px #0000002e;\n color: var(--dsw-alias-label-primary, #17181a);\n font-size: 13px;\n line-height: 18px;\n pointer-events: none;\n transform: translate(-50%, -50%);\n z-index: 60;\n}\n\n.bre-drag-ghost-name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.bre-drag-ghost svg { color: var(--dsw-alias-label-tertiary, #81858c); }\n\n/* The row the drag is carrying: still in place, visibly the one in hand. */\nli.bre-row-dragging { opacity: .5; }\n\n/* The row the pointer would drop it on \u2014 a secondary cue; the insertion line\n below is the one that says which side. */\nli.bre-row-drop-target { border-color: var(--dsw-alias-brand-primary); }\n\n/* The insertion line. A fixed overlay on the body, never a child of the list\n React owns, so writing it cannot trigger anything in the official section.\n The layer stack matters more than it looks: the provider list lives inside the\n settings dialog, whose overlay is fixed and opaque with z-index 1000, so a\n line in the shell's own range would be drawn behind the dialog and never\n seen. It clears the dialog, and stays under the header's controls. */\n.bre-drop-line {\n position: fixed;\n display: none;\n height: 2px;\n border-radius: 2px;\n background: var(--dsw-alias-brand-primary, #4d6bfe);\n box-shadow: 0 0 0 1px #ffffffb3, 0 1px 4px var(--dsw-alias-brand-primary, #4d6bfe);\n pointer-events: none;\n z-index: 1200;\n}\n\n/* The row slide (a FLIP pass driven from the script) is motion; drop it for a\n reader who asked for less. */\n@media (prefers-reduced-motion: reduce) {\n li[data-bre-row-provider] { transition: none !important; }\n}\n\n@media (max-width: 520px) {\n .bre-drag-grip { width: 18px; height: 24px; }\n .bre-drag-ghost { max-width: 180px; font-size: 12px; }\n}\n\n/* ---- Model rows inside one provider's editor (Models page) ---- */\n\n/* The official model row is a four-column grid (id, display name, two icon\n buttons). Our grip is a fifth child, so the grid needs a leading track to\n hold it \u2014 declared by our own class, because the official rule is a single\n class selector and ours has to win on specificity, not on load order.\n The name must NOT be \"bre-model-row\": that one is this plugin's own composer\n row (see the \".bre-model-row\" block above), and lending it to the host's grid\n would hand that grid our padding, gap, min-height, pointer cursor and hover\n fill along with it. */\n.bre-model-grid[class*=\"modelRow\"] {\n grid-template-columns: auto minmax(0, 1.4fr) minmax(0, 1fr) auto auto;\n}\n\n/* A model row is a grid of inputs, so only the grip drags: the row keeps its\n text cursor and its own click behaviour. The grip takes the height of the\n row's controls, so the pointer has a real target inside a 6px-gap grid. */\n.bre-model-grid > .bre-drag-grip {\n width: 18px;\n height: 24px;\n margin-right: 0;\n}\n\n/* The engine paints the carried row and the row under the pointer with the same\n classes it uses on a provider card; the official model entry carries the\n border, so the drop cue has to land there rather than on the list item. */\ndiv.bre-row-dragging { opacity: .5; }\n[class*=\"modelEntry\"].bre-row-drop-target { border-color: var(--dsw-alias-brand-primary); }\n\n/* The row slide (a FLIP pass driven from the script) is motion; drop it for a\n reader who asked for less. */\n@media (prefers-reduced-motion: reduce) {\n [data-bre-row-model] { transition: none !important; }\n}\n\n/* The blank a shrinking model list leaves behind, appended to the panel's own\n scroll host (see holdListSlack in models-page-editor): it holds the host's\n scroll RANGE open so deleting a row cannot clamp the view down. Height is\n written inline from the script \u2014 it is the range being held, not a style \u2014\n and the element must never take layout from above or a pointer from the user. */\n.bre-list-slack {\n flex: 0 0 auto;\n pointer-events: none;\n}\n\n/* ---- Provider enable switch (Models page) ---- */\n\n/* Leads the row's own action group (which is pushed right by margin-left:auto),\n in front of the card's buttons, so the destructive one stays last. The knob is\n a pseudo element: no extra node for the official section's tree to trip over. */\n.bre-provider-switch {\n position: relative;\n flex: 0 0 auto;\n width: 30px;\n height: 18px;\n padding: 0;\n border: none;\n border-radius: 9px;\n background: var(--dsw-alias-bg-tertiary, #d7dae0);\n cursor: pointer;\n transition: background 140ms ease;\n}\n\n.bre-provider-switch::after {\n content: '';\n position: absolute;\n top: 2px;\n left: 2px;\n width: 14px;\n height: 14px;\n border-radius: 50%;\n background: var(--dsw-alias-bg-elevated, #ffffff);\n box-shadow: 0 1px 2px #00000026;\n transition: transform 140ms ease;\n}\n\n.bre-provider-switch:not([aria-checked='true']):hover { background: var(--dsw-alias-bg-quaternary, #c9ccd2); }\n\n.bre-provider-switch[aria-checked='true'] { background: var(--dsw-alias-brand-primary, #4d6bfe); }\n\n.bre-provider-switch[aria-checked='true']:hover { background: var(--dsw-alias-brand-primary-hover, #3f5ce8); }\n\n.bre-provider-switch[aria-checked='true']::after { transform: translateX(12px); }\n\n.bre-provider-switch:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary, #4d6bfe);\n outline-offset: 2px;\n}\n\n/* A provider that is switched off stays on the page \u2014 this is the only place it\n can be switched back on \u2014 but it is visibly out of play. The switch itself is\n left at full strength: it is the way back. */\nli.bre-row-disabled [class*=\"rowIdentity\"],\nli.bre-row-disabled [class*=\"rowName\"] { opacity: .5; }\n\n@media (prefers-reduced-motion: reduce) {\n .bre-provider-switch,\n .bre-provider-switch::after { transition: none; }\n}\n\n/* ---- The reserved delete seat (Models page) ---- */\n\n/* A provider the host will not let the user remove renders no delete button, so\n that row's action group \u2014 pushed right by margin-left:auto \u2014 starts further\n right than its neighbours' and the column of buttons lines up raggedly. This\n seat holds the place: it borrows the metrics the official button takes inside\n an action group (.rowActions button is 28px tall / 12px / 0 10px) and the\n dimmed treatment the host gives its own disabled buttons (opacity .4 with a\n default cursor). It is always disabled \u2014 it is the alignment, not an action. */\n.bre-provider-delete {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 28px;\n padding: 0 10px;\n border: none;\n border-radius: var(--dsw-radius-sm, 6px);\n background: 0 0;\n color: var(--dsw-alias-state-error-primary, #e5484d);\n font: inherit;\n font-size: 12px;\n line-height: 18px;\n opacity: .4;\n cursor: default;\n}\n\n/* ---- The folded group of switched-off providers (Models page) ---- */\n\n/* A switched-off provider keeps its row \u2014 that is where it is switched back on \u2014\n but it does not have to stay in the list the user reads. The row keeps its DOM\n slot (the drag pass reads its slots back out of there) and is ordered behind\n the group's control instead, so unfolding shows the group UNDER that control\n rather than scattered through the providers that are on.\n\n !important, because the drag passes write an inline order onto the rows they\n arrange: a folded row is not one of the rows the user is arranging, so the\n tail belongs to this stylesheet, not to the last drag that ran. */\n.bre-row-folded { order: 1001 !important; }\n\n/* The seat: the list item that carries the control, in front of the folded rows\n and behind every provider that is switched on. It is a list item of the host's\n own flex column \u2014 the only place from which a control can head rows inside the\n list \u2014 and it holds no card of its own, only the quiet end of the host's text\n scale. */\n.bre-provider-disabled-seat {\n box-sizing: border-box;\n order: 1000 !important;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.bre-provider-disabled-group {\n box-sizing: border-box;\n display: block;\n width: 100%;\n margin: 4px 0 0;\n padding: 4px 2px;\n border: none;\n background: 0 0;\n color: var(--dsw-alias-label-tertiary, #81858c);\n font: inherit;\n font-size: 12px;\n line-height: 18px;\n text-align: left;\n cursor: pointer;\n}\n\n.bre-provider-disabled-group:hover { color: var(--dsw-alias-label-secondary, #61666b); }\n\n.bre-provider-disabled-group:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary, #4d6bfe);\n outline-offset: 2px;\n}\n\n/* The folded row itself. !important because the official card class decides its\n own display, and this stylesheet's order against the host's is not ours to\n rely on. */\n.bre-row-hidden { display: none !important; }\n\n/* -----------------------------------------------------------------------\n The provider editor's three tabs.\n\n The official editor lays a provider out as one long column \u2014 identity\n fields, then the model list, then this plugin's request-header section\n one slot up the card. The tab pass (injection/editor-tabs.ts) tags each\n region and stamps the card with the active tab; EVERY visibility decision\n lives here, so the official React tree never moves and a pass failure\n degrades to the untouched one-column editor.\n ----------------------------------------------------------------------- */\n\n/* The segmented control. The plugin's tab-bar component renders it inside the\n request-header mount, which already holds the card's 12px gap slot \u2014 so the\n bar reaches the panes in the card's own rhythm WITHOUT this plugin ever\n inserting a node into the official child list. It stays hidden until the pass\n marks the card: a card the pass could not take over (the DeepSeek account\n editor) keeps that mount visible for its request-header section, and must not\n grow a bar that switches nothing. */\n.bre-editor-tabs {\n display: none;\n gap: 2px;\n padding: 2px;\n border-radius: 10px;\n background: var(--dsw-alias-fill-tertiary, rgba(120, 125, 140, .09));\n}\n\n/* Only a taken-over card shows the bar. */\n.bre-tabbed .bre-editor-tabs { display: flex; }\n\n/* ...and while the takeover is on, the mount holding that bar MUST be visible.\n This is the one place the takeover does not delegate its reveal to the\n official-edit state: the bar lives in here, and gating it on the _editor\n class probe would make the tabs depend on a probe an official redesign can\n break \u2014 with data-edit stuck at 0 the bar would be inside a display:none\n parent and no rule of ours could reach it. The taken-over class is written by\n the pass itself, in the same frame, so it is the trustworthy half of the\n pair. The section's own visibility stays a pane decision (below). */\n.bre-tabbed .bre-headers-host { display: block; }\n\n.bre-editor-tab {\n flex: 1 1 0;\n min-width: 0;\n height: 28px;\n padding: 0 10px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: var(--dsw-alias-label-secondary, #61666b);\n font: inherit;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n cursor: pointer;\n transition: background 140ms ease, color 140ms ease, box-shadow 140ms ease;\n}\n\n.bre-editor-tab:hover { color: var(--dsw-alias-label-primary, #0f1115); }\n\n/* The selected segment lifts out of the track: the page's own surface colour\n plus the card's own hairline, the same elevation the host uses for raised\n controls. Hover on a selected tab stays put \u2014 it is already where you are. */\n.bre-editor-tab[aria-selected='true'],\n.bre-editor-tab[aria-selected='true']:hover {\n background: var(--dsw-alias-bg-layer-1, #fff);\n color: var(--dsw-alias-label-primary, #0f1115);\n box-shadow: 0 1px 2px #0000001a, 0 0 0 1px var(--dsw-alias-border-l2, #0000001a);\n}\n\n.bre-editor-tab:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary, #4d6bfe);\n outline-offset: 1px;\n}\n\n/* An advanced section with no headers mount (pre-first-render, feature off)\n offers an empty pane \u2014 the button steps aside until the mount exists. */\n.bre-editor-tab[hidden] { display: none; }\n\n/* Pane visibility, keyed on the card's active tab. Only the HIDING has to win\n a specificity fight (against the official sheet and the headers host's own\n reveal rule); the active pane keeps whatever display the official layout\n gave it, so showing must not declare a display at all. */\n.bre-tabbed:not([data-bre-tab='provider']) [data-bre-region='provider'],\n.bre-tabbed:not([data-bre-tab='models']) [data-bre-region='models'],\n.bre-tabbed:not([data-bre-tab='advanced']) [data-bre-region='advanced'] {\n display: none !important;\n}\n\n/* The advanced tab: the official body \u2014 fields, model list, action row and the\n editor's own header \u2014 steps aside for the request-header section, which is a\n complete form with its own save/cancel and becomes the pane under the very\n same bar. */\n.bre-tabbed[data-bre-tab='advanced'] [data-bre-editor-body] {\n display: none !important;\n}\n\n/* The advanced pane shows the section for the same reason the mount is shown:\n a pane that is already the active one has no business depending on the\n official-edit probe. The rule above still wins for every other tab, and the\n base bre-headers rule keeps a collapsed card's section hidden \u2014 a card only\n carries the taken-over class while its editor is open. */\n.bre-tabbed[data-bre-tab='advanced'] .bre-headers { display: flex; }\n\n/* The pane is a card, and the section draws it. On the advanced tab the section\n is not an appendage to the fields above it any more \u2014 it is the whole surface\n \u2014 so it takes the inset fill the official module cards use (the add and setup\n cards): the one fill in this system that stays visible on the content card's\n own white in the light theme and reads as raised in the dark one, where every\n theme layer token collapses onto the same value. The hairline goes with it: it\n divided this section from those fields, and here the bar above ends the pane.\n The 12px top margin sets the card off the tab bar above it \u2014 the same gap the\n provider and models panes put between the bar and their own cards \u2014 and the\n 12px padding is the card's inner inset, not the separator. */\n.bre-tabbed[data-bre-tab='advanced'] .bre-headers {\n margin-top: 12px;\n padding: 12px;\n border-top: none;\n border-radius: var(--dsw-radius-lg, 16px);\n background: var(--dsw-alias-bg-module-platform, #f5f6f7);\n}\n\n/* The pane's heading is not a fold head. The grey pill, its hover state and\n the \u203A that opens the card section have no job in a pane that is always open\n and named by the tab above it, so the title drops back to plain text. It\n keeps the title row's weight the section uses everywhere else \u2014 the head\n strip and the hint both step aside for it, which is what makes the title\n the line the hint reads under rather than an equal of it. */\n.bre-tabbed[data-bre-tab='advanced'] .bre-headers-head {\n min-height: 0;\n padding: 0;\n background: none;\n}\n.bre-tabbed[data-bre-tab='advanced'] .bre-headers-head .bre-effort-title {\n font-size: 13px;\n line-height: 20px;\n}\n\n/* The live editor folds its identity fields and model list into one\n \"Customized\" disclosure. Under the tabs the grouping is the panes' job: the\n group stays expanded (the pass forces it open) and its summary row \u2014 now a\n toggle with nothing left to toggle \u2014 steps aside. */\n.bre-tabbed [data-bre-editor-body] details > summary {\n display: none !important;\n}\n\n/* A region that is NOT a pane. The editor's own header repeats the card row's\n provider name and route tag, and that row is already on screen directly above\n it, so the header is hidden on every tab. No pane rule above can select this\n id, which is what keeps it hidden whichever tab is active. */\n.bre-tabbed [data-bre-region='none'] {\n display: none !important;\n}\n\n/* The Models pane shows the custom model list and the catalogue, and two\n hairlines used to divide it: the \"Customized\" group's separator from the key\n field (which this pane hides) and the catalogue's own, drawn directly above\n its \"Model catalogue\" heading. Neither has anything to divide here \u2014 the tab\n bar already ends the pane above, and the divider between the two lists above\n the catalogue is the group's boundary, not a rule. Both go, with every top\n padding that held content off them (the group's 10px, its body's 12px, the\n catalogue's 12px), so the pane runs from the tab bar into the catalogue with\n only the official editor's own 14px gap between blocks. */\n.bre-tabbed[data-bre-tab='models'] [data-bre-editor-body] details[class*='customized'] {\n border-top: none;\n padding-top: 0;\n}\n\n.bre-tabbed[data-bre-tab='models'] [data-bre-editor-body] details[class*='customized'] > [class*='customizedBody'] {\n padding-top: 0;\n}\n\n/* The catalogue is a section (its heading, title and meta are the divs inside\n it), so this probe hits the ruled box and nothing else. */\n.bre-tabbed[data-bre-tab='models'] [data-bre-editor-body] section[class*='modelCatalog'] {\n border-top: none;\n padding-top: 0;\n}\n\n/* The catalogue heading names a box this pane has already named for the user:\n the Models tab IS the catalogue, so \"\u6A21\u578B\u76EE\u5F55\" says it twice, and\n \"\u5DF2\u81EA\u5B9A\u4E49\u6A21\u578B\u76EE\u5F55\" (the meta line beside it) says nothing at all \u2014 the rows\n below ARE the customized catalogue. Both strings are the host's own, so they\n go by class stem, and the heading takes its title and meta with it. The\n head's own controls (\u6062\u590D\u9ED8\u8BA4\u6A21\u578B / \u83B7\u53D6\u53EF\u7528\u6A21\u578B) are siblings of the heading,\n not children, so they stay \u2014 the auto-adapt seat is anchored to them. */\n.bre-tabbed[data-bre-tab='models'] [data-bre-editor-body] [class*='modelCatalogHeading'] {\n display: none;\n}\n\n/* With the heading gone the head holds only controls, and they read as TWO\n ENDS: \u6062\u590D\u9ED8\u8BA4\u6A21\u578B stays at the left edge while \u83B7\u53D6\u53EF\u7528\u6A21\u578B keeps the\n auto-adapt seat beside it at the far right \u2014 the seat belongs to that link's\n group, it is never a column of its own. The official space-between cannot\n express that once a third child exists: it spreads the three evenly, which\n strands the fetch link in the middle of the card. So the free space is handed\n to the fetch link's own leading auto margin instead \u2014 an auto margin absorbs\n the space BEFORE justify-content is consulted, whatever the official rule\n says. The fetch link is the button the seat sits after, which is also the\n only control present when the provider is not overridden: the pair then\n simply holds the right edge. align-items centres the taller host links\n against the seat. */\n.bre-tabbed[data-bre-tab='models'] [data-bre-editor-body] [class*='modelListHead'] {\n align-items: center;\n}\n.bre-tabbed[data-bre-tab='models'] [data-bre-editor-body] [class*='modelListHead'] > button:has(+ .bre-auto-effort) {\n margin-left: auto;\n}\n\n/* The click's answer, as a bubble at the top of the window that takes itself\n away again. The control is left alone on purpose: its label is what the user\n aimed at, and a button that rewrites itself is a button that moved. The\n bubble is a fixed overlay on the body \u2014 not a child of the head, which is the\n host's flex row and would take a fourth item \u2014 and it clears the settings\n dialog's opaque overlay for the same reason the drop line does. It follows\n the host's own toast in placement and tone, but not in z-index: the settings\n dialog's overlay outranks the toast layer, and this bubble is raised from\n inside that dialog. Pointer-events none keeps it out of the way, the phase\n colours the headline so the outcome reads before the words do, and the\n hold/fade pair is timed by --bre-note-hold, which the script sets from the\n same constant it uses for the dismissal. The fade is counted INSIDE that\n hold, so the bubble is gone when the clock says it is, rather than fading\n after it. */\n.bre-auto-effort-note {\n position: fixed;\n top: 40px;\n left: 50%;\n display: flex;\n flex-direction: column;\n gap: 2px;\n width: max-content;\n max-width: min(640px, calc(100vw - 48px));\n padding: 10px 14px;\n border-radius: 10px;\n background: var(--dsw-alias-toast-bg, #2b2f36);\n color: var(--dsw-alias-toast-label, #f9fafb);\n box-shadow: var(--dsw-shadow-lv3, 0 6px 24px #00000029);\n font-size: 13px;\n line-height: 20px;\n pointer-events: none;\n transform: translateX(-50%);\n animation: bre-note-in 160ms ease-out, bre-note-out 400ms ease calc(var(--bre-note-hold, 3000ms) - 400ms) forwards;\n z-index: 1200;\n}\n/* A pass in flight has no lifetime of its own: it is replaced by its verdict,\n which restarts both animations because the phase changes the rule. */\n.bre-auto-effort-note[data-bre-auto-effort-phase='working'] {\n animation: bre-note-in 160ms ease-out;\n}\n@keyframes bre-note-in {\n from { opacity: 0; transform: translate(-50%, -6px); }\n to { opacity: 1; transform: translate(-50%, 0); }\n}\n@keyframes bre-note-out {\n to { opacity: 0; visibility: hidden; }\n}\n@media (prefers-reduced-motion: reduce) {\n .bre-auto-effort-note {\n animation: bre-note-out 400ms ease calc(var(--bre-note-hold, 3000ms) - 400ms) forwards;\n }\n .bre-auto-effort-note[data-bre-auto-effort-phase='working'] { animation: none; }\n}\n.bre-auto-effort-note-text { font-weight: 500; }\n.bre-auto-effort-note-detail { opacity: .72; }\n/* The attribute is the visibility switch, so it must beat the flex column above. */\n.bre-auto-effort-note-detail[hidden] { display: none; }\n.bre-auto-effort-note[data-bre-auto-effort-phase='working'] .bre-auto-effort-note-text {\n color: var(--dsw-alias-state-business-primary, #6ea8fe);\n}\n.bre-auto-effort-note[data-bre-auto-effort-phase='done'] .bre-auto-effort-note-text {\n color: var(--dsw-alias-state-success-primary, #22c55e);\n}\n.bre-auto-effort-note[data-bre-auto-effort-phase='failed'] .bre-auto-effort-note-text {\n color: var(--dsw-alias-state-error-secondary, #ff8a80);\n}\n\n/* The API-key eye. The official key field is a plain flex column whose input is\n its last in-flow child, so the button hangs on the field's own box and is\n measured against the input's 32px row \u2014 the official markup offers no\n wrapper, and introducing one would mean moving DOM the host owns. The input\n keeps the room the button needs. */\n.bre-key-field { position: relative; }\n\n.bre-key-field > input { padding-right: 34px; }\n\n/* A field the plugin's key list manages hands its input over: the list below\n says the same thing once per key and keeps the pick, the alias and the value\n in one place, so an official box that writes the provider's single key would\n be a second, conflicting way to do it. The input stays in the DOM \u2014 the\n host's form still owns it and the reveal pass still finds it \u2014 so unmanaging\n the field brings the official box back. The marker is what the reveal pass\n stamps on that input; the direct-child form covers the pass that has not run\n yet, and the eye is the button the same pass hangs on the field. */\n.bre-key-managed [data-bre-key-input],\n.bre-key-managed > input,\n.bre-key-managed .bre-key-eye { display: none; }\n\n/* A field that failed validation grows a message line under the input; the eye\n rides above it so it stays on the input it belongs to (18px line + 6px gap). */\n.bre-key-field:has(> p) .bre-key-eye { bottom: 24px; }\n\n.bre-key-eye {\n position: absolute;\n right: 4px;\n bottom: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 32px;\n padding: 0;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: var(--dsw-alias-label-secondary, #6b7280);\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n transition: background 140ms ease, color 140ms ease;\n}\n\n.bre-key-eye:hover {\n color: var(--dsw-alias-label-primary, #0f1115);\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.bre-key-eye:focus-visible {\n outline: none;\n box-shadow: inset 0 0 0 2px var(--dsw-alias-border-l3);\n}\n\n/* Resolving a stored key is a same-origin round trip, so the button can be\n busy: it stays in place and dims rather than changing size or disappearing. */\n.bre-key-eye[aria-busy='true'] {\n opacity: 0.55;\n cursor: progress;\n}\n\n.bre-key-eye[hidden] { display: none; }\n\n/* One glyph at a time. The state lives on the button's own attribute, so a\n click swaps the icon without the host re-rendering anything. */\n.bre-key-eye svg[data-bre-icon] { display: none; }\n\n.bre-key-eye[aria-pressed='false'] svg[data-bre-icon='eye'],\n.bre-key-eye[aria-pressed='true'] svg[data-bre-icon='eye-off'] { display: block; }\n\n/* The key list. The plugin mounts it into its own host, a sibling placed right\n after the official key field, so the list sits under the input without\n changing the field's own box: the reveal eye is measured against that box\n (bottom: 0), and a list inside the field would drag the eye down onto the\n list's last row. The margin only covers the case where the card spaces its\n fields with margins instead of a gap. */\n.bre-keys-host {\n display: block;\n min-width: 0;\n margin-top: 4px;\n}\n\n.bre-keys { display: flex; flex-direction: column; gap: 8px; }\n\n/* While the key list is still reading, the panel renders NOTHING (the component\n returns an empty .bre-keys). An empty ruled box \u2014 or a placeholder line that\n then swaps to the list \u2014 would paint one frame of a panel that then visibly\n changes: the \"the key section flashes when you press Edit\" report. :empty\n takes the panel out of the layout until the first answer lands, so the list\n is the first thing the key area ever paints, and nothing under it moves. */\n.bre-keys:empty { display: none; }\n\n/* One ruled container holding the keys and the add entry, the way a settings\n list reads: a single hairline box, and hairlines between rows only. */\n.bre-keys-list {\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n border: 0.5px solid var(--dsw-alias-border-l2, #d5d7dd);\n border-radius: 8px;\n list-style: none;\n overflow: hidden;\n}\n\n.bre-keys-list > li + li { border-top: 0.5px solid var(--dsw-alias-border-l2, #d5d7dd); }\n\n.bre-keys-row {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n padding: 9px 10px;\n}\n\n/* The enable choice closes the row. The radio stays the real input \u2014 so the\n keys of one provider are one group, choosing one clears the rest, and the\n pick is keyboard-reachable \u2014 and the circle is its face; the word beside it\n names the action instead of a state to hunt for. */\n.bre-keys-enable {\n display: inline-flex;\n flex: 0 0 auto;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n}\n\n.bre-keys-enable-text {\n font-size: 11px;\n line-height: 1.5;\n color: var(--dsw-alias-label-secondary, #6b7280);\n}\n\n.bre-keys-enable:has(.bre-keys-enabled:checked) .bre-keys-enable-text {\n color: var(--dsw-alias-label-primary, #0f1115);\n}\n\n.bre-keys-enabled {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n border: 0;\n overflow: hidden;\n white-space: nowrap;\n clip-path: inset(50%);\n}\n\n.bre-keys-mark {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n box-sizing: border-box;\n border: 1px solid var(--dsw-alias-border-l3, #9aa0aa);\n border-radius: 50%;\n color: var(--dsw-alias-bg-layer-1, #ffffff);\n transition: background 120ms ease, border-color 120ms ease;\n}\n\n.bre-keys-mark > svg { width: 12px; height: 12px; }\n\n.bre-keys-enabled:checked + .bre-keys-mark {\n border-color: var(--dsw-alias-label-primary, #0f1115);\n background: var(--dsw-alias-label-primary, #0f1115);\n}\n\n.bre-keys-enabled:focus-visible + .bre-keys-mark {\n outline: none;\n box-shadow: 0 0 0 2px var(--dsw-alias-brand-primary, #3b82f6);\n}\n\n/* With an alias the alias is the row's name and the masked key follows it as a\n quiet code pill; without one the masked key is the name and takes the row's\n measure, so a key is always readable as itself. */\n.bre-keys-alias {\n flex: 0 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 12px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #0f1115);\n}\n\n.bre-keys-mask {\n flex: 0 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n padding: 1px 6px;\n border-radius: 4px;\n background: var(--dsw-alias-interactive-bg-hover, rgba(127, 127, 127, 0.08));\n color: var(--dsw-alias-label-secondary, #6b7280);\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 11px;\n}\n\n.bre-keys-mask-plain {\n flex: 1 1 auto;\n padding: 0;\n background: transparent;\n color: var(--dsw-alias-label-primary, #0f1115);\n font-family: inherit;\n font-size: 12px;\n}\n\n/* The row's three actions, revealed on hover or keyboard focus rather than\n removed, so the row keeps its width and nothing shifts under the pointer.\n Revealing is opacity alone; a pointer that cannot hover simply always sees\n them, because a hidden action there would be an unreachable one. */\n.bre-keys-actions {\n display: inline-flex;\n flex: 0 0 auto;\n align-items: center;\n gap: 10px;\n margin-left: auto;\n opacity: 0;\n pointer-events: none;\n transition: opacity 120ms ease;\n}\n\n.bre-keys-row:hover .bre-keys-actions,\n.bre-keys-row:focus-within .bre-keys-actions {\n opacity: 1;\n pointer-events: auto;\n}\n\n@media (hover: none) {\n .bre-keys-actions { opacity: 1; pointer-events: auto; }\n}\n\n.bre-keys-danger { color: var(--dsw-alias-state-error-primary, #c62828); }\n\n/* The one inline form. It opens under the row it edits, or \u2014 for a new key \u2014 as\n the list's own last item, which is what keeps adding a key in place instead\n of in a dialog that has to be found and dismissed. */\n.bre-keys-form-row { padding: 10px; }\n\n.bre-keys-form { display: flex; flex-direction: column; gap: 8px; }\n\n.bre-keys-form-fields {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 8px;\n}\n\n/* One field means the whole row: the value form holds only the secret, and it\n must not sit in half a row beside an empty half. */\n.bre-keys-form-fields > :only-child { grid-column: 1 / -1; }\n\n/* The shared input caps itself at 240px for the panels it was written for; here\n the field is the measure. */\n.bre-keys-form-fields .bre-text-input { max-width: none; }\n\n.bre-keys-form-actions {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n}\n\n/* The shared primary button is styled inside the headers editor, which is not\n where this form lives, so the key list carries its own compact copy. */\n.bre-keys-form-actions .bre-primary-button {\n height: 28px;\n padding: 0 12px;\n border: 0;\n border-radius: var(--dsw-radius-md, 8px);\n background: var(--dsw-alias-button-primary-fill, #0f1115);\n color: var(--dsw-alias-label-primary-foreground, #ffffff);\n font: inherit;\n font-size: 12px;\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n}\n\n.bre-keys-form-actions .bre-primary-button:hover {\n background: var(--dsw-alias-button-primary-hover, #43454a);\n}\n\n.bre-keys-form-actions .bre-primary-button:disabled { opacity: 0.5; cursor: default; }\n\n.bre-keys-form-actions .bre-primary-button:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--dsw-alias-brand-primary, #3b82f6);\n}\n\n/* The add entry is the list's own last row \u2014 full width, the same shape as the\n keys it adds to \u2014 so the way in and the thing it makes read as one list. */\n.bre-keys-add-row { padding: 0; }\n\n.bre-keys-add {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 9px 10px;\n box-sizing: border-box;\n border: 0;\n background: transparent;\n color: var(--dsw-alias-label-secondary, #6b7280);\n font: inherit;\n font-size: 12px;\n text-align: left;\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n transition: background 120ms ease, color 120ms ease;\n}\n\n.bre-keys-add:hover {\n background: var(--dsw-alias-interactive-bg-hover, rgba(127, 127, 127, 0.08));\n color: var(--dsw-alias-label-primary, #0f1115);\n}\n\n.bre-keys-add:focus-visible {\n outline: none;\n box-shadow: inset 0 0 0 2px var(--dsw-alias-brand-primary, #3b82f6);\n}\n\n.bre-keys-add:disabled { opacity: 0.55; cursor: default; }\n\n.bre-keys-add-mark {\n display: inline-flex;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n}\n\n.bre-keys .bre-effort-message { font-size: 11px; }\n\n@media (prefers-reduced-motion: reduce) {\n .bre-editor-tab { transition: none; }\n .bre-key-eye { transition: none; }\n .bre-keys-mark, .bre-keys-actions, .bre-keys-add { transition: none; }\n}\n";