diff --git a/src/components/config/ConfigSection.module.scss b/src/components/config/ConfigSection.module.scss index 4f7315f..c7f8a46 100644 --- a/src/components/config/ConfigSection.module.scss +++ b/src/components/config/ConfigSection.module.scss @@ -1,44 +1,53 @@ @use '../../styles/mixins' as *; -@use '../../styles/variables' as *; .section { display: grid; - grid-template-columns: minmax(0, 220px) minmax(0, 1fr); - gap: 24px; - padding: 26px 0; - border-top: 1px solid color-mix(in srgb, var(--border-color) 76%, transparent); - scroll-margin-top: 112px; - - &:first-child { - border-top: none; - padding-top: 0; - } + grid-template-columns: minmax(0, 178px) minmax(0, 1fr); + gap: clamp(18px, 2.2vw, 30px); + height: clamp(520px, calc(100dvh - var(--header-height, 64px) - 250px), 780px); + min-width: 0; + box-sizing: border-box; + overflow-y: auto; + overscroll-behavior: auto; + padding: clamp(20px, 2.4vw, 28px); + border: 1px solid var(--border-color); + border-radius: 8px; + background: color-mix(in srgb, var(--bg-primary) 82%, transparent); + scroll-margin-top: 104px; + scroll-snap-align: start; + scroll-snap-stop: always; + scrollbar-width: thin; @include mobile { grid-template-columns: minmax(0, 1fr); - gap: 18px; - padding: 22px 0; - scroll-margin-top: 88px; + gap: 14px; + height: clamp(420px, calc(100dvh - var(--header-height, 64px) - 260px), 680px); + padding: 16px; + scroll-margin-top: 92px; } } .header { position: sticky; - top: 104px; + top: 0; align-self: start; display: flex; flex-direction: column; gap: 14px; + z-index: 1; + padding-bottom: 4px; + background: color-mix(in srgb, var(--bg-primary) 88%, transparent); @include mobile { position: static; + background: transparent; } } .titleRow { display: flex; align-items: center; - gap: 12px; + gap: 8px; min-width: 0; } @@ -46,17 +55,14 @@ display: inline-flex; align-items: center; justify-content: center; - min-width: 42px; - height: 42px; - padding: 0 12px; - border-radius: 14px; - background: - linear-gradient(180deg, color-mix(in srgb, var(--bg-primary) 92%, transparent), transparent), - color-mix(in srgb, var(--primary-color) 11%, var(--bg-secondary)); - border: 1px solid color-mix(in srgb, var(--primary-color) 18%, var(--border-color)); - color: var(--primary-hover); - font-size: 12px; - font-weight: 700; + min-width: 32px; + height: 28px; + padding: 0 8px; + border: 1px solid var(--border-color); + border-radius: 6px; + color: var(--text-secondary); + font-size: 11px; + font-weight: 750; letter-spacing: 0.08em; } @@ -64,11 +70,9 @@ display: inline-flex; align-items: center; justify-content: center; - width: 38px; - height: 38px; - border-radius: 14px; - background: color-mix(in srgb, var(--bg-secondary) 88%, transparent); - border: 1px solid color-mix(in srgb, var(--border-color) 80%, transparent); + width: 28px; + height: 28px; + border-radius: 6px; color: var(--text-secondary); flex: 0 0 auto; } @@ -82,18 +86,19 @@ .title { margin: 0; - font-size: clamp(20px, 2vw, 25px); - line-height: 1.08; - font-weight: 700; color: var(--text-primary); + font-size: clamp(18px, 1.6vw, 22px); + font-weight: 680; + line-height: 1.18; + letter-spacing: 0; } .description { margin: 0; - max-width: 34ch; + max-width: 30ch; color: var(--text-secondary); - font-size: 14px; - line-height: 1.7; + font-size: 13px; + line-height: 1.65; @include mobile { max-width: none; diff --git a/src/components/config/VisualConfigEditor.module.scss b/src/components/config/VisualConfigEditor.module.scss index 737b5f8..ee03622 100644 --- a/src/components/config/VisualConfigEditor.module.scss +++ b/src/components/config/VisualConfigEditor.module.scss @@ -4,10 +4,10 @@ .visualEditor { display: flex; flex-direction: column; - gap: $spacing-xl; + gap: 18px; :global(.form-group) { - gap: 8px; + gap: 7px; margin-bottom: 0; } @@ -15,46 +15,47 @@ color: var(--text-secondary); font-size: 12px; font-weight: 700; - letter-spacing: 0.04em; + letter-spacing: 0.02em; } :global(.input) { - min-height: 48px; - border-radius: 16px; - background: color-mix(in srgb, var(--bg-primary) 92%, transparent); - border-color: color-mix(in srgb, var(--border-color) 84%, transparent); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08); + min-height: 42px; + border-radius: 8px; + background: var(--bg-secondary); + border-color: var(--border-color); + box-shadow: none; } :global(.input:focus) { background: var(--bg-primary); - border-color: var(--primary-color); + border-color: var(--text-primary); + box-shadow: 0 0 0 2px color-mix(in srgb, var(--text-primary) 12%, transparent); } :global(textarea.input) { - min-height: 120px; + min-height: 112px; } :global(.hint) { color: var(--text-secondary); font-size: 12px; - line-height: 1.6; + line-height: 1.55; } :global(.error-box) { - border-radius: 14px; + border-radius: 8px; } :global(.item-list) { - gap: 12px; - margin-top: 10px; + gap: 8px; + margin-top: 8px; } :global(.item-row) { - border-radius: 18px; - padding: 14px 16px; - background: color-mix(in srgb, var(--bg-primary) 78%, transparent); - border-color: color-mix(in srgb, var(--border-color) 86%, transparent); + border-radius: 8px; + padding: 12px; + background: transparent; + border-color: var(--border-color); } :global(.item-row .item-meta) { @@ -66,8 +67,9 @@ } :global(.pill) { - background: color-mix(in srgb, var(--bg-secondary) 84%, transparent); - border: 1px solid color-mix(in srgb, var(--border-color) 84%, transparent); + border: 1px solid var(--border-color); + border-radius: 6px; + background: transparent; color: var(--text-secondary); } } @@ -97,19 +99,19 @@ .expandableToggle { position: absolute; - right: 6px; + right: 7px; top: 50%; + z-index: 1; transform: translateY(-50%); + padding: 2px; + border: 0; background: none; - border: none; - cursor: pointer; + color: var(--text-secondary); font-size: 10px; line-height: 1; - padding: 2px; - color: var(--text-secondary, #999); - opacity: 0.5; - transition: opacity 0.15s; - z-index: 1; + cursor: pointer; + opacity: 0.58; + transition: opacity 0.15s ease; &:hover { opacity: 1; @@ -122,76 +124,46 @@ } .expandableInputExpanded .expandableToggle { - top: 8px; + top: 9px; + right: 12px; transform: none; - right: 14px; } .overview { - position: relative; - overflow: hidden; - display: flex; - flex-direction: column; - gap: 18px; - border-radius: 30px; - border: 1px solid color-mix(in srgb, var(--border-color) 78%, transparent); - background: - radial-gradient( - circle at top right, - color-mix(in srgb, var(--primary-color) 12%, transparent), - transparent 36% - ), - linear-gradient( - 135deg, - color-mix(in srgb, var(--bg-primary) 94%, transparent), - color-mix(in srgb, var(--bg-secondary) 96%, transparent) - ); - padding: clamp(22px, 3vw, 30px); - - &::before { - content: ''; - position: absolute; - inset: 0 auto auto 0; - width: min(220px, 44vw); - height: min(220px, 44vw); - background: radial-gradient( - circle, - color-mix(in srgb, var(--primary-color) 16%, transparent), - transparent 72% - ); - opacity: 0.6; - pointer-events: none; - } + display: grid; + grid-template-columns: minmax(0, 1fr); + gap: 10px; + padding: 0 0 18px; + border-bottom: 1px solid var(--border-color); } .overviewHeader { - position: relative; display: flex; align-items: center; - justify-content: space-between; - gap: 12px; min-width: 0; + + @include mobile { + align-items: stretch; + } } .overviewMeta { display: flex; flex-wrap: wrap; - gap: 10px; + gap: 6px; } .overviewPill { display: inline-flex; align-items: center; - gap: 6px; - min-height: 34px; - padding: 0 14px; - border-radius: 999px; - border: 1px solid color-mix(in srgb, var(--border-color) 84%, transparent); - background: color-mix(in srgb, var(--bg-primary) 82%, transparent); + min-height: 28px; + padding: 0 9px; + border: 1px solid var(--border-color); + border-radius: 6px; color: var(--text-secondary); font-size: 12px; font-weight: 700; - letter-spacing: 0.04em; + line-height: 1.2; } .overviewPillWarning { @@ -200,93 +172,14 @@ background: var(--warning-bg); } -.overviewFocusList { - position: relative; - display: grid; - grid-template-columns: repeat(3, minmax(0, 1fr)); - gap: 12px; - - @media (max-width: 1200px) { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } - - @include mobile { - grid-template-columns: minmax(0, 1fr); - } -} - -.overviewFocusLink { - @include button-reset; - display: flex; - align-items: flex-start; - gap: 14px; - width: 100%; - padding: 14px 16px; - border-radius: 20px; - border: 1px solid color-mix(in srgb, var(--border-color) 70%, transparent); - background: color-mix(in srgb, var(--bg-primary) 74%, transparent); - text-align: left; - transition: - transform 0.18s ease, - border-color 0.18s ease, - background-color 0.18s ease; - - &:hover { - transform: translateY(-1px); - border-color: color-mix(in srgb, var(--primary-color) 26%, var(--border-color)); - background: color-mix(in srgb, var(--bg-primary) 92%, transparent); - } -} - -.overviewFocusLinkActive { - border-color: color-mix(in srgb, var(--primary-color) 28%, var(--border-color)); - background: color-mix(in srgb, var(--bg-primary) 92%, transparent); -} - -.focusIcon { - display: inline-flex; - align-items: center; - justify-content: center; - width: 40px; - height: 40px; - border-radius: 14px; - background: color-mix(in srgb, var(--primary-color) 10%, var(--bg-secondary)); - color: var(--primary-hover); - flex: 0 0 auto; -} - -.focusCopy { +.workspace { display: flex; flex-direction: column; - gap: 4px; + gap: 14px; min-width: 0; -} - -.focusTitle { - color: var(--text-primary); - font-size: 15px; - font-weight: 700; - line-height: 1.2; -} - -.focusDescription { - color: var(--text-secondary); - font-size: 13px; - line-height: 1.55; -} - -.workspace { - display: grid; - grid-template-columns: minmax(0, 280px) minmax(0, 1fr); - gap: 24px; - align-items: start; - - @media (max-width: 1024px) { - grid-template-columns: minmax(0, 1fr); - } @include mobile { - gap: 16px; + gap: 12px; } } @@ -295,57 +188,45 @@ @include mobile { position: sticky; - top: calc(var(--header-height, 64px) + 12px); + top: calc(var(--header-height, 64px) + 10px); z-index: 4; display: block; margin-bottom: 4px; + background: color-mix(in srgb, var(--bg-secondary) 92%, transparent); } } .mobileSectionNavScroller { - display: flex; - gap: 8px; - overflow-x: auto; - padding: 4px 2px 10px; - scrollbar-width: none; - - &::-webkit-scrollbar { - display: none; - } + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 6px; + overflow: visible; + padding: 2px 0 8px; } .mobileSectionNavButton { @include button-reset; display: inline-flex; align-items: center; - gap: 8px; - min-width: max-content; - flex: 0 0 auto; - padding: 10px 14px; - border-radius: 999px; - border: 1px solid color-mix(in srgb, var(--border-color) 84%, transparent); - background: color-mix(in srgb, var(--bg-primary) 88%, transparent); - box-shadow: 0 18px 36px -30px rgba(0, 0, 0, 0.28); - white-space: nowrap; + gap: 7px; + min-width: 0; + width: 100%; + padding: 9px 10px; + border: 1px solid var(--border-color); + border-radius: 8px; + background: var(--bg-primary); + text-align: left; } .mobileSectionNavButtonActive { - border-color: color-mix(in srgb, var(--primary-color) 24%, var(--border-color)); - background: color-mix(in srgb, var(--bg-primary) 96%, transparent); + border-color: var(--text-primary); + background: color-mix(in srgb, var(--text-primary) 6%, transparent); } .mobileSectionNavIndex { - display: inline-flex; - align-items: center; - justify-content: center; - min-width: 28px; - height: 28px; - padding: 0 8px; - border-radius: 999px; - background: color-mix(in srgb, var(--bg-secondary) 88%, transparent); - color: var(--text-secondary); + color: var(--text-tertiary); font-size: 11px; - font-weight: 700; + font-weight: 750; letter-spacing: 0.08em; } @@ -353,16 +234,17 @@ color: var(--text-primary); font-size: 13px; font-weight: 700; + line-height: 1.25; } .mobileSectionNavBadge { display: inline-flex; align-items: center; justify-content: center; - min-width: 22px; - height: 22px; + min-width: 20px; + height: 20px; padding: 0 6px; - border-radius: 999px; + border-radius: 6px; background: var(--warning-bg); border: 1px solid var(--warning-border); color: var(--warning-text); @@ -371,142 +253,68 @@ } .sidebar { - position: relative; - align-self: start; - - @media (max-width: 1024px) { - position: static; - } + position: sticky; + top: calc(var(--header-height, 64px) + 12px); + z-index: 5; + align-self: stretch; + min-width: 0; @include mobile { display: none; } } -.sidebarPlaceholder { - min-height: 1px; -} - .sidebarRail { - max-height: calc(100vh - var(--header-height, 64px) - 36px); - overflow-y: auto; - overflow-x: hidden; - padding: 12px; - border-radius: 26px; - border: 1px solid color-mix(in srgb, var(--border-color) 84%, transparent); - background: color-mix(in srgb, var(--bg-primary) 76%, transparent); - --glass-blur: 14px; - backdrop-filter: var(--glass-backdrop-filter); - -webkit-backdrop-filter: var(--glass-backdrop-filter); - box-shadow: 0 24px 56px -34px rgba(0, 0, 0, 0.42); - -ms-overflow-style: none; - scrollbar-width: none; - - &::-webkit-scrollbar { - display: none; - } -} - -.floatingSidebarContainer { - position: fixed; - left: 0; - top: 0; - will-change: transform, width, max-height; - z-index: 45; - opacity: 0; - pointer-events: none; - transition: opacity 0.18s ease; - - @media (max-width: 1024px) { - display: none; - } -} - -.floatingSidebarRail { - max-height: inherit; - overflow-y: auto; - overflow-x: hidden; - padding: 12px; - border-radius: 26px; - border: 1px solid color-mix(in srgb, var(--border-color) 84%, transparent); - background: color-mix(in srgb, var(--bg-primary) 96%, transparent); - box-shadow: 0 24px 56px -34px rgba(0, 0, 0, 0.42); - -ms-overflow-style: none; - scrollbar-width: none; - - &::-webkit-scrollbar { - display: none; - } + padding: 0 0 12px; + border-bottom: 1px solid var(--border-color); + background: color-mix(in srgb, var(--bg-secondary) 88%, transparent); } .navList { - display: flex; - flex-direction: column; + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; + min-width: 0; - @media (max-width: 1024px) { - flex-direction: row; - overflow-x: auto; - padding-bottom: 4px; - scrollbar-width: none; - - &::-webkit-scrollbar { - display: none; - } + @include tablet { + grid-template-columns: repeat(2, minmax(0, 1fr)); } } .navButton { @include button-reset; display: flex; - align-items: flex-start; - gap: 14px; + align-items: center; + gap: 10px; width: 100%; - padding: 14px; - border-radius: 20px; - border: 1px solid transparent; + min-height: 48px; + padding: 9px 11px; + border: 1px solid var(--border-color); + border-radius: 8px; background: transparent; color: inherit; text-align: left; transition: - transform 0.18s ease, - background-color 0.18s ease, - border-color 0.18s ease; + background-color 0.15s ease, + border-color 0.15s ease, + color 0.15s ease; &:hover { - transform: translateX(2px); - background: color-mix(in srgb, var(--bg-secondary) 86%, transparent); - border-color: color-mix(in srgb, var(--border-color) 88%, transparent); - } - - @media (max-width: 1024px) { - min-width: 232px; - flex: 0 0 auto; - - &:hover { - transform: translateY(-1px); - } + background: color-mix(in srgb, var(--text-primary) 5%, transparent); } } .navButtonActive { - background: color-mix(in srgb, var(--bg-primary) 92%, transparent); - border-color: color-mix(in srgb, var(--primary-color) 24%, var(--border-color)); - box-shadow: 0 18px 36px -30px rgba(0, 0, 0, 0.32); + border-color: var(--text-primary); + background: color-mix(in srgb, var(--text-primary) 6%, transparent); } .navIndex { - display: inline-flex; - align-items: center; - justify-content: center; - min-width: 34px; - height: 34px; - border-radius: 12px; - background: color-mix(in srgb, var(--bg-secondary) 88%, transparent); - border: 1px solid color-mix(in srgb, var(--border-color) 84%, transparent); - color: var(--text-secondary); + min-width: 24px; + padding-top: 2px; + color: var(--text-tertiary); font-size: 11px; - font-weight: 700; + font-weight: 750; letter-spacing: 0.08em; flex: 0 0 auto; } @@ -514,7 +322,6 @@ .navMain { display: flex; flex-direction: column; - gap: 6px; min-width: 0; flex: 1; } @@ -522,14 +329,14 @@ .navHeadingRow { display: flex; align-items: center; - gap: 10px; + gap: 8px; min-width: 0; } .navLabelWrap { display: inline-flex; align-items: center; - gap: 8px; + gap: 7px; min-width: 0; } @@ -537,53 +344,64 @@ display: inline-flex; align-items: center; justify-content: center; - color: var(--primary-hover); + width: 16px; + color: var(--text-secondary); flex: 0 0 auto; } .navLabel { color: var(--text-primary); - font-size: 15px; + font-size: 13px; font-weight: 700; - line-height: 1.2; -} - -.navDescription { - color: var(--text-secondary); - font-size: 12px; - line-height: 1.55; + line-height: 1.25; } .navBadge { display: inline-flex; align-items: center; justify-content: center; - min-width: 28px; - height: 28px; - padding: 0 10px; - border-radius: 999px; + min-width: 22px; + height: 22px; + padding: 0 7px; + border-radius: 6px; background: var(--warning-bg); border: 1px solid var(--warning-border); color: var(--warning-text); - font-size: 12px; + font-size: 11px; font-weight: 700; flex: 0 0 auto; } .sections { display: flex; - flex-direction: column; + gap: 0; + width: 100%; + max-width: 100%; min-width: 0; - padding: clamp(20px, 3vw, 30px); - border-radius: 32px; - border: 1px solid color-mix(in srgb, var(--border-color) 84%, transparent); - background: color-mix(in srgb, var(--bg-primary) 76%, transparent); + overflow-x: auto; + overflow-y: hidden; + align-items: stretch; + padding: 0 0 12px; + scroll-padding-left: 0; + scroll-snap-type: x mandatory; + scrollbar-gutter: stable; + scrollbar-width: thin; + + @include mobile { + padding-bottom: 10px; + } + + > * { + flex: 0 0 100%; + width: 100%; + max-width: 100%; + } } .sectionGrid { display: grid; - grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); - gap: 16px; + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); + gap: 14px; @include mobile { grid-template-columns: minmax(0, 1fr); @@ -593,23 +411,24 @@ .sectionStack { display: flex; flex-direction: column; - gap: 16px; + gap: 14px; } .divider { height: 1px; - background: color-mix(in srgb, var(--border-color) 84%, transparent); + background: var(--border-color); } .toggleRow { display: grid; grid-template-columns: minmax(0, 1fr) auto; - gap: 16px; + gap: 14px; align-items: center; - padding: 16px 18px; - border-radius: 18px; - border: 1px solid color-mix(in srgb, var(--border-color) 82%, transparent); - background: color-mix(in srgb, var(--bg-primary) 84%, transparent); + min-height: 74px; + padding: 14px; + border: 1px solid var(--border-color); + border-radius: 8px; + background: transparent; @include mobile { grid-template-columns: minmax(0, 1fr); @@ -619,27 +438,27 @@ .toggleCopy { display: flex; flex-direction: column; - gap: 6px; + gap: 5px; min-width: 0; } .toggleTitle { color: var(--text-primary); - font-size: 15px; + font-size: 14px; font-weight: 700; - line-height: 1.2; + line-height: 1.25; } .toggleDescription { color: var(--text-secondary); - font-size: 13px; - line-height: 1.6; + font-size: 12px; + line-height: 1.55; } .fieldShell { display: flex; flex-direction: column; - gap: 8px; + gap: 7px; min-width: 0; } @@ -647,7 +466,7 @@ color: var(--text-secondary); font-size: 12px; font-weight: 700; - letter-spacing: 0.04em; + letter-spacing: 0.02em; } .fieldControl { @@ -657,47 +476,46 @@ .fieldHint { color: var(--text-secondary); font-size: 12px; - line-height: 1.6; + line-height: 1.55; } .inlinePill { position: absolute; - right: 10px; + right: 8px; top: 50%; transform: translateY(-50%); display: inline-flex; align-items: center; - min-height: 26px; - padding: 0 10px; - border-radius: 999px; - border: 1px solid color-mix(in srgb, var(--border-color) 82%, transparent); - background: color-mix(in srgb, var(--bg-primary) 92%, transparent); + min-height: 24px; + padding: 0 8px; + border: 1px solid var(--border-color); + border-radius: 6px; + background: var(--bg-primary); color: var(--text-secondary); font-size: 11px; font-weight: 700; - letter-spacing: 0.04em; } .subsection { display: flex; flex-direction: column; - gap: 14px; - padding: 18px 20px; - border-radius: 24px; - border: 1px solid color-mix(in srgb, var(--border-color) 82%, transparent); - background: color-mix(in srgb, var(--bg-primary) 84%, transparent); + gap: 12px; + padding: 16px; + border: 1px solid var(--border-color); + border-radius: 8px; + background: transparent; } .subsectionHeader { display: flex; flex-direction: column; - gap: 6px; + gap: 5px; } .subsectionTitle { margin: 0; color: var(--text-primary); - font-size: 16px; + font-size: 15px; font-weight: 700; line-height: 1.25; } @@ -705,62 +523,47 @@ .subsectionDescription { margin: 0; color: var(--text-secondary); - font-size: 13px; - line-height: 1.65; -} - -.sectionIssueBadge { - display: inline-flex; - align-items: center; - justify-content: center; - min-width: 28px; - height: 28px; - padding: 0 10px; - border-radius: 999px; - background: var(--warning-bg); - border: 1px solid var(--warning-border); - color: var(--warning-text); font-size: 12px; - font-weight: 700; + line-height: 1.6; } .blockHeaderRow { display: flex; align-items: center; justify-content: space-between; - gap: 12px; + gap: 10px; flex-wrap: wrap; } .blockStack { display: flex; flex-direction: column; - gap: 12px; + gap: 10px; } .ruleCard { display: flex; flex-direction: column; gap: 12px; - padding: 14px; - border-radius: 20px; - border: 1px solid color-mix(in srgb, var(--border-color) 84%, transparent); - background: color-mix(in srgb, var(--bg-primary) 88%, transparent); + padding: 12px; + border: 1px solid var(--border-color); + border-radius: 8px; + background: color-mix(in srgb, var(--bg-secondary) 64%, transparent); } .ruleCardHeader { display: flex; align-items: center; justify-content: space-between; - gap: 12px; + gap: 10px; flex-wrap: wrap; } .ruleCardTitle { color: var(--text-primary); - font-size: 15px; + font-size: 14px; font-weight: 700; - line-height: 1.2; + line-height: 1.25; } .blockLabel { @@ -768,7 +571,6 @@ font-size: 12px; font-weight: 700; line-height: 1.4; - letter-spacing: 0.04em; } .actionRow { @@ -777,12 +579,12 @@ } .emptyState { - border: 1px dashed color-mix(in srgb, var(--border-color) 84%, transparent); - border-radius: 18px; - padding: 18px 16px; + border: 1px dashed var(--border-color); + border-radius: 8px; + padding: 16px; color: var(--text-secondary); text-align: center; - background: color-mix(in srgb, var(--bg-secondary) 88%, transparent); + background: transparent; } .stringList { @@ -813,7 +615,7 @@ display: grid; grid-template-columns: 1fr 140px 1fr auto; gap: 8px; - align-items: center; + align-items: start; } .payloadRuleParamGroup { @@ -823,7 +625,7 @@ } .payloadJsonInput { - min-height: 120px; + min-height: 112px; resize: vertical; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', @@ -841,6 +643,10 @@ align-items: center; } +.payloadRowActionButton { + flex: 0 0 auto; +} + .apiKeyModalInputRow { display: flex; gap: 8px; @@ -871,27 +677,13 @@ @include mobile { .overview { - gap: 14px; - padding: 18px; - border-radius: 24px; - } - - .overviewFocusLink { - padding: 12px 14px; - } - - .sections { - border-radius: 26px; - padding: 16px; - } - - .subsection { - padding: 16px; - border-radius: 20px; + padding-bottom: 14px; } + .subsection, + .ruleCard, .toggleRow { - padding: 14px 16px; + padding: 14px; } .blockHeaderRow, @@ -917,14 +709,9 @@ } @media (max-width: 380px) { - .overview, - .sections { - padding: 14px; - } - .subsection, .ruleCard, .toggleRow { - padding: 14px; + padding: 12px; } } diff --git a/src/components/config/VisualConfigEditor.tsx b/src/components/config/VisualConfigEditor.tsx index 9dc45a1..e45b904 100644 --- a/src/components/config/VisualConfigEditor.tsx +++ b/src/components/config/VisualConfigEditor.tsx @@ -1,5 +1,4 @@ import { - useLayoutEffect, useCallback, useEffect, useId, @@ -9,7 +8,6 @@ import { type ComponentType, type ReactNode, } from 'react'; -import { createPortal } from 'react-dom'; import { useTranslation } from 'react-i18next'; import { usePageTransitionLayer } from '@/components/common/PageTransitionLayer'; import { Input } from '@/components/ui/Input'; @@ -21,9 +19,7 @@ import { IconKey, IconSatellite, IconSettings, - IconShield, IconTimer, - IconTrendingUp, type IconProps, } from '@/components/ui/icons'; import { ConfigSection } from '@/components/config/ConfigSection'; @@ -46,11 +42,8 @@ import styles from './VisualConfigEditor.module.scss'; type VisualSectionId = | 'server' - | 'tls' - | 'remote' | 'auth' | 'system' - | 'network' | 'quota' | 'streaming' | 'payload'; @@ -58,7 +51,6 @@ type VisualSectionId = type VisualSection = { id: VisualSectionId; title: string; - description: string; icon: ComponentType; errorCount: number; }; @@ -181,8 +173,6 @@ export function VisualConfigEditor({ const pageTransitionLayer = usePageTransitionLayer(); const isCurrentLayer = pageTransitionLayer ? pageTransitionLayer.isCurrentLayer : true; const isMobile = useMediaQuery('(max-width: 768px)'); - const isFloatingSidebar = useMediaQuery('(min-width: 1025px)'); - const shouldRenderFloatingSidebar = !isMobile && isFloatingSidebar && isCurrentLayer; const routingStrategyLabelId = useId(); const routingStrategyHintId = `${routingStrategyLabelId}-hint`; const keepaliveInputId = useId(); @@ -192,9 +182,6 @@ export function VisualConfigEditor({ const nonstreamKeepaliveHintId = `${nonstreamKeepaliveInputId}-hint`; const nonstreamKeepaliveErrorId = `${nonstreamKeepaliveInputId}-error`; const [activeSectionId, setActiveSectionId] = useState('server'); - const workspaceRef = useRef(null); - const sidebarAnchorRef = useRef(null); - const floatingSidebarRef = useRef(null); const sectionRefs = useRef>>({}); const mobileNavScrollerRef = useRef(null); const mobileNavButtonRefs = useRef>>( @@ -258,56 +245,35 @@ export function VisualConfigEditor({ { id: 'server', title: t('config_management.visual.sections.server.title'), - description: t('config_management.visual.sections.server.description'), icon: IconSettings, errorCount: countErrors(['port']), }, - { - id: 'tls', - title: t('config_management.visual.sections.tls.title'), - description: t('config_management.visual.sections.tls.description'), - icon: IconShield, - errorCount: 0, - }, - { - id: 'remote', - title: t('config_management.visual.sections.remote.title'), - description: t('config_management.visual.sections.remote.description'), - icon: IconSatellite, - errorCount: 0, - }, { id: 'auth', title: t('config_management.visual.sections.auth.title'), - description: t('config_management.visual.sections.auth.description'), icon: IconKey, errorCount: 0, }, { id: 'system', title: t('config_management.visual.sections.system.title'), - description: t('config_management.visual.sections.system.description'), icon: IconDiamond, - errorCount: countErrors(['logsMaxTotalSizeMb']), - }, - { - id: 'network', - title: t('config_management.visual.sections.network.title'), - description: t('config_management.visual.sections.network.description'), - icon: IconTrendingUp, - errorCount: countErrors(['requestRetry', 'maxRetryCredentials', 'maxRetryInterval']), + errorCount: countErrors([ + 'logsMaxTotalSizeMb', + 'requestRetry', + 'maxRetryCredentials', + 'maxRetryInterval', + ]), }, { id: 'quota', title: t('config_management.visual.sections.quota.title'), - description: t('config_management.visual.sections.quota.description'), icon: IconTimer, errorCount: 0, }, { id: 'streaming', title: t('config_management.visual.sections.streaming.title'), - description: t('config_management.visual.sections.streaming.description'), icon: IconSatellite, errorCount: countErrors([ 'streaming.keepaliveSeconds', @@ -318,7 +284,6 @@ export function VisualConfigEditor({ { id: 'payload', title: t('config_management.visual.sections.payload.title'), - description: t('config_management.visual.sections.payload.description'), icon: IconCode, errorCount: hasPayloadValidationErrors ? 1 : 0, }, @@ -328,10 +293,7 @@ export function VisualConfigEditor({ const hasValidationIssues = sections.some((section) => section.errorCount > 0) || hasPayloadValidationErrors; - const focusSections = useMemo( - () => sections.filter((section) => ['server', 'network', 'payload'].includes(section.id)), - [sections] - ); + const activeSection = sections.find((section) => section.id === activeSectionId) ?? sections[0]; useEffect(() => { if (!isCurrentLayer) return undefined; @@ -383,104 +345,13 @@ export function VisualConfigEditor({ const handleSectionJump = useCallback((sectionId: VisualSectionId) => { setActiveSectionId(sectionId); - sectionRefs.current[sectionId]?.scrollIntoView({ behavior: 'smooth', block: 'start' }); + sectionRefs.current[sectionId]?.scrollIntoView({ + behavior: 'smooth', + block: 'nearest', + inline: 'start', + }); }, []); - useLayoutEffect(() => { - const floatingElement = floatingSidebarRef.current; - const anchorElement = sidebarAnchorRef.current; - const workspaceElement = workspaceRef.current; - if (!floatingElement) return undefined; - - const clearFloatingStyles = () => { - floatingElement.style.removeProperty('transform'); - floatingElement.style.removeProperty('width'); - floatingElement.style.removeProperty('max-height'); - floatingElement.style.removeProperty('opacity'); - floatingElement.style.removeProperty('pointer-events'); - }; - - if (!shouldRenderFloatingSidebar || !anchorElement || !workspaceElement) { - clearFloatingStyles(); - return undefined; - } - - /* ---- Cache header height – recomputed only on resize ---- */ - const computeHeaderHeight = () => { - const header = document.querySelector('.main-header') as HTMLElement | null; - if (header) return header.getBoundingClientRect().height; - - const raw = getComputedStyle(document.documentElement).getPropertyValue('--header-height'); - const parsed = Number.parseFloat(raw); - return Number.isFinite(parsed) ? parsed : 64; - }; - let headerHeight = computeHeaderHeight(); - - /* ---- Cache content scroller – resolved once ---- */ - const contentScroller = document.querySelector('.content') as HTMLElement | null; - - /* ---- Cache floating height from previous frame ---- */ - let cachedFloatingHeight = floatingElement.getBoundingClientRect().height || 200; - - let frameId = 0; - - const updateFloatingPosition = () => { - frameId = 0; - - const anchorRect = anchorElement.getBoundingClientRect(); - const workspaceRect = workspaceElement.getBoundingClientRect(); - const stickyTop = headerHeight + 20; - const viewportPadding = 16; - const maxTop = workspaceRect.bottom - cachedFloatingHeight; - const unclampedTop = Math.min(Math.max(anchorRect.top, stickyTop), maxTop); - const top = Math.max(unclampedTop, viewportPadding); - const left = Math.max(anchorRect.left, viewportPadding); - const width = Math.max( - Math.min(anchorRect.width, window.innerWidth - left - viewportPadding), - 220 - ); - const maxHeight = Math.max(window.innerHeight - top - viewportPadding, 160); - const isVisible = workspaceRect.bottom > stickyTop + 24 && anchorRect.top < window.innerHeight; - - floatingElement.style.transform = `translate3d(${left}px, ${top}px, 0)`; - floatingElement.style.width = `${width}px`; - floatingElement.style.maxHeight = `${maxHeight}px`; - floatingElement.style.opacity = isVisible ? '1' : '0'; - floatingElement.style.pointerEvents = isVisible ? 'auto' : 'none'; - }; - - const requestPositionUpdate = () => { - if (frameId) cancelAnimationFrame(frameId); - frameId = requestAnimationFrame(updateFloatingPosition); - }; - - const handleResize = () => { - headerHeight = computeHeaderHeight(); - cachedFloatingHeight = floatingElement.getBoundingClientRect().height || cachedFloatingHeight; - requestPositionUpdate(); - }; - - requestPositionUpdate(); - - window.addEventListener('resize', handleResize); - window.addEventListener('scroll', requestPositionUpdate, { passive: true }); - contentScroller?.addEventListener('scroll', requestPositionUpdate, { passive: true }); - - const resizeObserver = - typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(requestPositionUpdate); - resizeObserver?.observe(anchorElement); - resizeObserver?.observe(workspaceElement); - - return () => { - if (frameId) cancelAnimationFrame(frameId); - resizeObserver?.disconnect(); - window.removeEventListener('resize', handleResize); - window.removeEventListener('scroll', requestPositionUpdate); - contentScroller?.removeEventListener('scroll', requestPositionUpdate); - clearFloatingStyles(); - }; - }, [shouldRenderFloatingSidebar]); - const navContent = (
{sections.map((section, index) => { @@ -510,7 +381,6 @@ export function VisualConfigEditor({ ) : null} - {section.description} ); @@ -526,6 +396,7 @@ export function VisualConfigEditor({ {t('config_management.visual.quick_jump', { defaultValue: '快速跳转' })} + {activeSection?.title} {hasValidationIssues ? ( {t('config_management.visual.validation.validation_blocked')} @@ -533,39 +404,9 @@ export function VisualConfigEditor({ ) : null}
- -
- {focusSections.map((section) => { - const Icon = section.icon; - - return ( - - ); - })} -
-
+
{isMobile ? (
) : null} -
); } diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index efb38ee..9b85760 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -1139,8 +1139,7 @@ "switch_project_desc": "Automatically switch to another project when quota is exceeded", "switch_preview_model": "Switch to Preview Model", "switch_preview_model_desc": "Switch to preview model version when quota is exceeded", - "antigravity_credits": "Antigravity Credits Retry", - "antigravity_credits_desc": "Retry once with enabledCreditTypes=[\"GOOGLE_ONE_AI\"] when Antigravity returns quota_exhausted 429" + "antigravity_credits": "Use Antigravity Credits" }, "streaming": { "title": "Streaming Configuration", diff --git a/src/i18n/locales/ru.json b/src/i18n/locales/ru.json index ac66e2a..a829ab3 100644 --- a/src/i18n/locales/ru.json +++ b/src/i18n/locales/ru.json @@ -1136,8 +1136,7 @@ "switch_project_desc": "Автоматически переходить на другой проект при превышении квоты", "switch_preview_model": "Переключить на preview-модель", "switch_preview_model_desc": "Переключаться на preview-версию модели при превышении квоты", - "antigravity_credits": "Повтор Antigravity Credits", - "antigravity_credits_desc": "При ответе Antigravity quota_exhausted 429 повторять запрос один раз с enabledCreditTypes=[\"GOOGLE_ONE_AI\"]" + "antigravity_credits": "Использовать Antigravity Credits" }, "streaming": { "title": "Настройки стриминга", diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index 4af342d..3750d37 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -1139,8 +1139,7 @@ "switch_project_desc": "配额耗尽时自动切换到其他项目", "switch_preview_model": "切换预览模型", "switch_preview_model_desc": "配额耗尽时切换到预览版本模型", - "antigravity_credits": "Antigravity Credits 重试", - "antigravity_credits_desc": "Antigravity 返回 quota_exhausted 429 时,使用 enabledCreditTypes=[\"GOOGLE_ONE_AI\"] 重试一次" + "antigravity_credits": "使用Antigravity Credits" }, "streaming": { "title": "流式传输配置", diff --git a/src/i18n/locales/zh-TW.json b/src/i18n/locales/zh-TW.json index ec31ad9..94be1c7 100644 --- a/src/i18n/locales/zh-TW.json +++ b/src/i18n/locales/zh-TW.json @@ -1165,8 +1165,7 @@ "switch_project_desc": "配額耗盡時自動切換到其他專案", "switch_preview_model": "切換預覽模型", "switch_preview_model_desc": "配額耗盡時切換到預覽版本模型", - "antigravity_credits": "Antigravity Credits 重試", - "antigravity_credits_desc": "Antigravity 回傳 quota_exhausted 429 時,使用 enabledCreditTypes=[\"GOOGLE_ONE_AI\"] 重試一次" + "antigravity_credits": "使用Antigravity Credits" }, "streaming": { "title": "串流傳輸設定", diff --git a/src/pages/ConfigPage.module.scss b/src/pages/ConfigPage.module.scss index b8b4c1f..731c5ed 100644 --- a/src/pages/ConfigPage.module.scss +++ b/src/pages/ConfigPage.module.scss @@ -2,11 +2,12 @@ @use '../styles/variables' as *; .container { - width: 100%; + width: min(100%, 1480px); min-height: 100%; display: flex; flex-direction: column; - gap: $spacing-lg; + gap: clamp(18px, 2.4vw, 28px); + margin: 0 auto; overflow-y: auto; padding-bottom: calc( var(--config-action-bar-height, 0px) + 16px + env(safe-area-inset-bottom) + #{$spacing-md} @@ -14,189 +15,73 @@ } .pageHeader { - position: relative; - overflow: hidden; - display: grid; - grid-template-columns: minmax(0, 1.2fr) auto; - gap: 24px; - align-items: end; - padding: clamp(22px, 3vw, 30px); - border-radius: 30px; - border: 1px solid color-mix(in srgb, var(--border-color) 82%, transparent); - background: - radial-gradient( - circle at top right, - color-mix(in srgb, var(--primary-color) 14%, transparent), - transparent 34% - ), - linear-gradient( - 135deg, - color-mix(in srgb, var(--bg-primary) 94%, transparent), - color-mix(in srgb, var(--bg-secondary) 96%, transparent) - ); - - &::before { - content: ''; - position: absolute; - inset: 0 auto auto 0; - width: min(260px, 48vw); - height: min(260px, 48vw); - background: radial-gradient( - circle, - color-mix(in srgb, var(--primary-color) 12%, transparent), - transparent 70% - ); - pointer-events: none; - opacity: 0.7; - } - - @include mobile { - grid-template-columns: minmax(0, 1fr); - align-items: stretch; - gap: 16px; - } + display: flex; + align-items: flex-start; } .pageHeaderCopy { - position: relative; display: flex; flex-direction: column; - gap: 12px; + gap: 10px; min-width: 0; -} - -.pageEyebrow { - color: var(--text-secondary); - font-size: 12px; - font-weight: 700; - letter-spacing: 0.08em; - text-transform: uppercase; + width: min(100%, 360px); } .pageTitle { - margin: 0; - color: var(--text-primary); - font-size: clamp(32px, 4vw, 52px); - line-height: 0.95; - letter-spacing: -0.04em; -} - -.description { - margin: 0; - max-width: 46rem; - color: var(--text-secondary); - font-size: 15px; - line-height: 1.7; -} - -.pageMeta { - position: relative; - display: flex; - flex-direction: column; - align-items: flex-end; - gap: 12px; - min-width: 0; - - @include mobile { - align-items: stretch; - } -} - -.statusBadge { - display: inline-flex; - align-items: center; - justify-content: center; - min-height: 38px; - padding: 0 14px; - border-radius: 999px; - border: 1px solid color-mix(in srgb, var(--border-color) 82%, transparent); - background: color-mix(in srgb, var(--bg-primary) 86%, transparent); - color: var(--text-primary); - font-size: 13px; + font-size: 28px; font-weight: 700; - text-align: center; - - @include mobile { - width: 100%; - } + color: var(--text-primary); + margin: 0; } .tabBar { - display: flex; - align-items: center; - gap: 4px; - padding: 4px; - border-radius: 999px; - background: color-mix(in srgb, var(--bg-primary) 82%, transparent); - border: 1px solid color-mix(in srgb, var(--border-color) 82%, transparent); - width: fit-content; - max-width: 100%; - overflow-x: auto; - scrollbar-width: none; - - &::-webkit-scrollbar { - display: none; - } - - @include mobile { - width: 100%; - } + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 2px; + padding: 2px; + border: 1px solid var(--border-color); + border-radius: 8px; + background: color-mix(in srgb, var(--bg-primary) 72%, transparent); } .tabItem { @include button-reset; - padding: 10px 16px; - border-radius: 999px; + min-height: 38px; + padding: 0 12px; + border-radius: 6px; border: 1px solid transparent; color: var(--text-secondary); - font-size: 14px; - font-weight: 700; + font-size: 13px; + font-weight: 650; + line-height: 1.25; white-space: nowrap; transition: color 0.15s ease, background-color 0.15s ease, - border-color 0.15s ease, - transform 0.15s ease; + border-color 0.15s ease; &:hover:not(:disabled) { color: var(--text-primary); - background: color-mix(in srgb, var(--bg-secondary) 92%, transparent); - border-color: color-mix(in srgb, var(--border-color) 88%, transparent); + background: color-mix(in srgb, var(--text-primary) 5%, transparent); } &:disabled { - opacity: 0.6; + opacity: 0.58; cursor: not-allowed; - transform: none; - } - - @include mobile { - flex: 1; - text-align: center; } } .tabActive { - color: var(--text-primary); - background: var(--bg-primary); - border-color: color-mix(in srgb, var(--primary-color) 24%, var(--border-color)); - box-shadow: 0 16px 32px -28px rgba(0, 0, 0, 0.3); + color: var(--bg-primary); + background: var(--text-primary); + border-color: var(--text-primary); } .workspaceShell { display: flex; flex-direction: column; gap: $spacing-lg; - padding: clamp(18px, 3vw, 28px); - border-radius: 32px; - border: 1px solid color-mix(in srgb, var(--border-color) 82%, transparent); - background: color-mix(in srgb, var(--bg-primary) 74%, transparent); - box-shadow: var(--shadow); - - @include mobile { - padding: 16px; - border-radius: 28px; - } + min-width: 0; } .content { @@ -209,25 +94,26 @@ .sourceWorkspace { display: flex; flex-direction: column; - gap: 16px; + gap: 12px; min-height: 0; } .sourceToolbar { - display: flex; + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 8px; align-items: center; - gap: $spacing-sm; - padding-bottom: 16px; - border-bottom: 1px solid color-mix(in srgb, var(--border-color) 80%, transparent); + padding: 8px; + border: 1px solid var(--border-color); + border-radius: 8px; + background: color-mix(in srgb, var(--bg-primary) 76%, transparent); @include mobile { - flex-direction: column; - align-items: stretch; + grid-template-columns: minmax(0, 1fr); } } .searchInputWrapper { - flex: 1; min-width: 0; position: relative; display: flex; @@ -240,28 +126,28 @@ } .searchInput { - flex: 1; - border-radius: 16px !important; - padding-right: 132px !important; + min-height: 38px !important; + border-radius: 6px !important; + padding-right: 128px !important; + background: var(--bg-secondary) !important; } .searchRight { display: inline-flex; align-items: center; - gap: 8px; + gap: 6px; } .searchCount { display: inline-flex; align-items: center; - min-height: 28px; - padding: 0 10px; - border-radius: 999px; - background: color-mix(in srgb, var(--bg-primary) 88%, transparent); - border: 1px solid color-mix(in srgb, var(--border-color) 84%, transparent); + min-height: 26px; + padding: 0 8px; + border-radius: 6px; + border: 1px solid var(--border-color); color: var(--text-secondary); font-size: 12px; - font-weight: 700; + font-weight: 650; pointer-events: none; white-space: nowrap; } @@ -271,12 +157,12 @@ display: inline-flex; align-items: center; justify-content: center; - width: 34px; - height: 34px; - border-radius: 999px; - background: var(--primary-color); - border: 1px solid var(--primary-color); - color: #fff; + width: 30px; + height: 30px; + border-radius: 6px; + border: 1px solid var(--text-primary); + background: var(--text-primary); + color: var(--bg-primary); transition: background-color $transition-fast, border-color $transition-fast, @@ -288,7 +174,7 @@ } &:disabled { - opacity: 0.5; + opacity: 0.45; cursor: not-allowed; } } @@ -299,11 +185,11 @@ flex-shrink: 0; button { - min-width: 36px; - width: 36px; - height: 36px; + min-width: 38px; + width: 38px; + height: 38px; padding: 0 !important; - border-radius: 999px; + border-radius: 6px; } @include mobile { @@ -319,21 +205,23 @@ .editorWrapper { width: 100%; flex: 0 0 auto; - height: clamp(420px, 64vh, 980px); - border: 1px solid color-mix(in srgb, var(--border-color) 84%, transparent); - border-radius: 28px; + height: clamp(500px, 70vh, 1040px); + border: 1px solid var(--border-color); + border-radius: 8px; overflow: hidden; - background: color-mix(in srgb, var(--bg-primary) 90%, transparent); + background: var(--bg-primary); @supports (height: 100dvh) { - height: clamp(420px, 64dvh, 980px); + height: clamp(500px, 70dvh, 1040px); } :global { .cm-editor { height: 100%; - font-size: 14px; - font-family: 'Consolas', 'Monaco', 'Menlo', monospace; + font-size: 13px; + font-family: + ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', + monospace; background: transparent; } @@ -345,8 +233,8 @@ } .cm-gutters { - border-right: 1px solid color-mix(in srgb, var(--border-color) 84%, transparent); - background: color-mix(in srgb, var(--bg-secondary) 88%, transparent); + border-right: 1px solid var(--border-color); + background: color-mix(in srgb, var(--bg-secondary) 86%, transparent); } .cm-lineNumbers .cm-gutterElement { @@ -355,35 +243,22 @@ color: var(--text-muted); } - .cm-activeLine { - background: var(--bg-hover); - } - + .cm-activeLine, .cm-activeLineGutter { - background: var(--bg-hover); + background: color-mix(in srgb, var(--text-primary) 5%, transparent); } .cm-selectionMatch { - background: rgba(255, 193, 7, 0.3); + background: rgba(224, 170, 20, 0.24); } .cm-searchMatch { - background: rgba(255, 193, 7, 0.4); - outline: 1px solid rgba(255, 193, 7, 0.6); + background: rgba(224, 170, 20, 0.32); + outline: 1px solid rgba(224, 170, 20, 0.48); } .cm-searchMatch-selected { - background: rgba(255, 152, 0, 0.5); - } - - [data-theme='dark'] & { - .cm-gutters { - background: var(--bg-tertiary); - } - - .cm-selectionMatch { - background: rgba(255, 193, 7, 0.2); - } + background: rgba(198, 87, 70, 0.32); } } } @@ -396,8 +271,8 @@ .saved { color: var(--success-color); - background: color-mix(in srgb, var(--success-color) 12%, var(--bg-primary)); - border-color: color-mix(in srgb, var(--success-color) 28%, var(--border-color)); + background: color-mix(in srgb, var(--success-color) 10%, transparent); + border-color: color-mix(in srgb, var(--success-color) 34%, var(--border-color)); } .error { @@ -420,17 +295,14 @@ .floatingActionList { display: inline-flex; align-items: center; - gap: 8px; - padding: 8px 10px; - --glass-blur: 12px; - background: var(--glass-bg); - backdrop-filter: var(--glass-backdrop-filter); - -webkit-backdrop-filter: var(--glass-backdrop-filter); - border: 1px solid var(--glass-border); - border-radius: 999px; - box-shadow: var(--shadow-lg); + gap: 6px; + padding: 6px; max-width: inherit; overflow-x: auto; + border: 1px solid var(--border-color); + border-radius: 8px; + background: color-mix(in srgb, var(--bg-primary) 92%, transparent); + box-shadow: var(--shadow-lg); scrollbar-width: none; &::-webkit-scrollbar { @@ -442,16 +314,16 @@ display: inline-flex; align-items: center; min-width: 0; - min-height: 28px; + min-height: 34px; padding: 0 10px; - border-radius: 999px; + border-radius: 6px; border: 1px solid transparent; - background: color-mix(in srgb, var(--text-primary) 6%, transparent); color: var(--text-primary); font-size: 11px; font-weight: 700; + line-height: 1.2; text-align: center; - max-width: min(280px, 46vw); + max-width: min(300px, 46vw); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @@ -469,28 +341,24 @@ display: flex; align-items: center; justify-content: center; - width: 40px; - height: 40px; - border-radius: 999px; - cursor: pointer; + width: 38px; + height: 38px; + border-radius: 6px; color: var(--text-primary); + cursor: pointer; transition: - background-color 0.2s ease, - transform 0.15s ease; + background-color 0.15s ease, + color 0.15s ease, + opacity 0.15s ease; &:hover:not(:disabled) { - background: color-mix(in srgb, var(--text-primary) 10%, transparent); - transform: scale(1.08); - } - - &:active:not(:disabled) { - transform: scale(0.95); + background: var(--text-primary); + color: var(--bg-primary); } &:disabled { - opacity: 0.5; + opacity: 0.45; cursor: not-allowed; - transform: none; } } @@ -502,7 +370,7 @@ height: 7px; border-radius: 999px; background: var(--warning-color); - box-shadow: 0 0 0 2px rgba($warning-color, 0.25); + box-shadow: 0 0 0 2px var(--bg-primary); } @media (max-width: 1200px) { @@ -511,21 +379,8 @@ max-width: calc(100vw - 16px); } - .floatingActionList { - gap: 6px; - padding: 8px 10px; - } - .floatingStatus { max-width: min(180px, 40vw); - font-size: 10px; - padding: 0 8px; - } - - .floatingActionButton { - width: 38px; - height: 38px; - flex: 0 0 auto; } } @@ -533,11 +388,8 @@ .floatingStatus { max-width: min(132px, 38vw); } -} -@media (max-width: 380px) { - .pageHeader, - .workspaceShell { - padding: 14px; + .searchInput { + padding-right: 108px !important; } } diff --git a/src/pages/ConfigPage.tsx b/src/pages/ConfigPage.tsx index c51067f..2e902df 100644 --- a/src/pages/ConfigPage.tsx +++ b/src/pages/ConfigPage.tsx @@ -500,26 +500,11 @@ export function ConfigPage() {
); - const pageEyebrow = - activeTab === 'visual' - ? t('config_management.tabs.visual', { defaultValue: '可视化编辑' }) - : t('config_management.tabs.source', { defaultValue: '源文件编辑' }); - const pageDescription = - activeTab === 'visual' - ? t('config_management.visual.notice') - : t('config_management.description'); - return (
- {pageEyebrow}

{t('config_management.title')}

-

{pageDescription}

-
- -
-
{getStatusText()}