fix(ui): improve responsive layouts and refine API access page
- Fix overflow, clipped controls, and toolbar overlap in narrow windows - Improve responsive layouts across usage, OAuth, agents, settings, and dialogs - Unify API category navigation and compact provider rows and actions - Preserve inherited provider priorities instead of displaying zero - Add responsive layout regression tests and dense provider fixtures - Bump proxy core version from 8.0.6 to 8.0.10
This commit is contained in:
1 parent
c7d58128b9
commit
5a5eab96e2
17 files changed
+1798
-153
No files matched your search
@@ -2058,7 +2058,7 @@ export function AgentsPage({ embedded = false, onConfigurationApplied }: AgentsP
|
||||
disabled={busy}
|
||||
>
|
||||
<span className="agent-client-icon"><AgentMark definition={agent} /></span>
|
||||
<span><strong>{agent.name}</strong><small>{listStatusText(status)}</small></span>
|
||||
<span><strong title={agent.name}>{agent.name}</strong><small title={listStatusText(status)}>{listStatusText(status)}</small></span>
|
||||
{status?.installed ? (
|
||||
<i className="agent-installed-indicator" title={t('agents.clientDetected')} aria-hidden="true" />
|
||||
) : null}
|
||||
|
||||
+16
-17
@@ -336,7 +336,7 @@ const rowFromRecord = (
|
||||
disabled: grouped ? providerGroupStatus(record) === 'disabled' : definitionFor(section).openAi
|
||||
? readBoolean(record, 'disabled')
|
||||
: excludedModels.some((model) => model.trim() === '*'),
|
||||
priority: readNumber(record, 'priority'),
|
||||
priority: record.priority == null ? null : readNumber(record, 'priority'),
|
||||
authIndex: entry
|
||||
? readString(entry, 'auth-index', 'authIndex')
|
||||
: readString(record, 'auth-index', 'authIndex'),
|
||||
@@ -1477,6 +1477,7 @@ export function ApiAccessPage() {
|
||||
type="button"
|
||||
key={definition.id}
|
||||
className={definition.id === activeCategory ? 'active' : ''}
|
||||
aria-pressed={definition.id === activeCategory}
|
||||
onClick={() => {
|
||||
setActiveCategory(definition.id);
|
||||
feedback.clearNotice();
|
||||
@@ -1496,6 +1497,10 @@ export function ApiAccessPage() {
|
||||
<h2 title={t(activeDefinition.labelKey)}>{t(activeDefinition.labelKey)}</h2>
|
||||
<span>{t('apiAccess.groups.summary', { count: rows.length })}</span>
|
||||
</div>
|
||||
<div className="management-toolbar compact-toolbar api-access-search">
|
||||
<Search size={16} aria-hidden="true" />
|
||||
<input value={filter} onChange={(event) => setFilter(event.currentTarget.value)} placeholder={t('apiAccess.search')} aria-label={t('apiAccess.search')} />
|
||||
</div>
|
||||
<div className="api-access-heading-tools">
|
||||
<button type="button" className="secondary-button compact-button" onClick={() => void loadProviders()} disabled={loading || busy}>
|
||||
<RefreshCw size={16} aria-hidden="true" />
|
||||
@@ -1505,10 +1510,6 @@ export function ApiAccessPage() {
|
||||
<Plus size={16} aria-hidden="true" />
|
||||
{t('apiAccess.groups.add')}
|
||||
</button>
|
||||
<div className="management-toolbar compact-toolbar">
|
||||
<Search size={16} aria-hidden="true" />
|
||||
<input value={filter} onChange={(event) => setFilter(event.currentTarget.value)} placeholder={t('apiAccess.search')} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1545,21 +1546,20 @@ export function ApiAccessPage() {
|
||||
<div className="provider-row-main">
|
||||
<div className="provider-row-title">
|
||||
<strong title={row.name}>{row.name}</strong>
|
||||
{row.remark ? <span>{row.remark}</span> : null}
|
||||
{providerGroupStatus(row.record) === 'partial' ? <span className="state-pill">{t('apiAccess.groups.partial')}</span> : null}
|
||||
{row.remark ? <span title={row.remark}>{row.remark}</span> : null}
|
||||
</div>
|
||||
<code title={t('apiAccess.keys.count', { count: row.apiKeys.length })}>
|
||||
{row.apiKeys.length > 1
|
||||
? t('apiAccess.keys.summary', { key: maskSecret(row.apiKey), count: row.apiKeys.length })
|
||||
: maskSecret(row.apiKey)}
|
||||
</code>
|
||||
<span className="provider-row-url" title={row.baseUrl || undefined}>{row.baseUrl || t('apiAccess.defaultUrl')}</span>
|
||||
{row.models.length > 0 ? <span className="provider-row-models">{t('apiAccess.models.summary', { count: row.models.length })}</span> : null}
|
||||
</div>
|
||||
{row.priority === null ? null : (
|
||||
<div className="provider-row-meta">
|
||||
<span>{t('apiAccess.priorityValue', { priority: row.priority })}</span>
|
||||
<code title={t('apiAccess.keys.count', { count: row.apiKeys.length })}>
|
||||
{row.apiKeys.length > 1
|
||||
? t('apiAccess.keys.summary', { key: maskSecret(row.apiKey), count: row.apiKeys.length })
|
||||
: maskSecret(row.apiKey)}
|
||||
</code>
|
||||
{row.models.length > 0 ? <span className="provider-row-models">{t('apiAccess.models.summary', { count: row.models.length })}</span> : null}
|
||||
{row.priority === null ? null : <span>{t('apiAccess.priorityValue', { priority: row.priority })}</span>}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="provider-row-actions">
|
||||
<button
|
||||
type="button"
|
||||
@@ -1582,7 +1582,6 @@ export function ApiAccessPage() {
|
||||
<span className="switch-track" />
|
||||
</span>
|
||||
</label>
|
||||
{providerGroupStatus(row.record) === 'partial' ? <span className="state-pill">{t('apiAccess.groups.partial')}</span> : null}
|
||||
<button type="button" className="icon-button quiet" onClick={() => openEdit(row)} disabled={busy} title={t('common.edit')} aria-label={t('common.edit')}>
|
||||
<Edit3 size={16} aria-hidden="true" />
|
||||
</button>
|
||||
|
||||
@@ -2616,22 +2616,26 @@ function PricingView({
|
||||
</span>
|
||||
</div>
|
||||
<div className="usage-pricing-actions">
|
||||
<input
|
||||
value={search}
|
||||
onChange={(event) => setSearch(event.currentTarget.value)}
|
||||
placeholder={t('usage.pricing.search')}
|
||||
aria-label={t('usage.pricing.search')}
|
||||
/>
|
||||
<button type="button" className="secondary-button" onClick={() => setDraft(emptyPriceDraft())}>
|
||||
{t('usage.pricing.add')}
|
||||
</button>
|
||||
<select value={syncSource} onChange={(event) => changeSyncSource(event.currentTarget.value as 'models-dev' | 'litellm')} aria-label={t('usage.pricing.syncSource')}>
|
||||
<option value="models-dev">Models.dev</option>
|
||||
<option value="litellm">LiteLLM</option>
|
||||
</select>
|
||||
<button type="button" className="primary-button" disabled={syncing} onClick={() => void previewPrices()}>
|
||||
{syncing ? t('usage.pricing.syncing') : t('usage.pricing.sync')}
|
||||
</button>
|
||||
<div className="usage-pricing-action-group">
|
||||
<input
|
||||
value={search}
|
||||
onChange={(event) => setSearch(event.currentTarget.value)}
|
||||
placeholder={t('usage.pricing.search')}
|
||||
aria-label={t('usage.pricing.search')}
|
||||
/>
|
||||
<button type="button" className="secondary-button" onClick={() => setDraft(emptyPriceDraft())}>
|
||||
{t('usage.pricing.add')}
|
||||
</button>
|
||||
</div>
|
||||
<div className="usage-pricing-action-group">
|
||||
<select value={syncSource} onChange={(event) => changeSyncSource(event.currentTarget.value as 'models-dev' | 'litellm')} aria-label={t('usage.pricing.syncSource')}>
|
||||
<option value="models-dev">Models.dev</option>
|
||||
<option value="litellm">LiteLLM</option>
|
||||
</select>
|
||||
<button type="button" className="primary-button" disabled={syncing} onClick={() => void previewPrices()}>
|
||||
{syncing ? t('usage.pricing.syncing') : t('usage.pricing.sync')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2749,7 +2753,7 @@ function PricingView({
|
||||
) : null}
|
||||
|
||||
{visibleRows.length ? (
|
||||
<div className="usage-table-wrap usage-pricing-table-wrap">
|
||||
<div className="usage-table-wrap usage-pricing-table-wrap" tabIndex={0} role="region" aria-label={t('usage.tab.pricing')}>
|
||||
<table className="usage-pricing-table">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -2768,7 +2772,7 @@ function PricingView({
|
||||
{visibleRows.map((row) => (
|
||||
<tr key={row.model}>
|
||||
<td>
|
||||
<strong>{row.model}</strong>
|
||||
<strong title={row.model}>{row.model}</strong>
|
||||
</td>
|
||||
<td>{compactNumber(row.requests)}</td>
|
||||
<td>{compactNumber(row.totalTokens)}</td>
|
||||
|
||||
+58
-29
@@ -9787,16 +9787,13 @@ body.table-col-resizing * {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.usage-pricing-panel {
|
||||
min-height: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* Pricing Tab */
|
||||
.usage-pricing-panel {
|
||||
display: grid;
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-content: start;
|
||||
min-height: 0;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
gap: 14px;
|
||||
padding: 16px;
|
||||
border: 1px solid var(--theme-e3e1db);
|
||||
@@ -9936,6 +9933,7 @@ body.table-col-resizing * {
|
||||
|
||||
.usage-pricing-toolbar {
|
||||
display: flex;
|
||||
flex: none;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 14px;
|
||||
@@ -9944,6 +9942,7 @@ body.table-col-resizing * {
|
||||
|
||||
.usage-pricing-summary {
|
||||
display: grid;
|
||||
flex: 1 1 240px;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
@@ -9961,13 +9960,26 @@ body.table-col-resizing * {
|
||||
|
||||
.usage-pricing-actions {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
flex: 1 1 560px;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.usage-pricing-action-group {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
flex: 1 1 250px;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.usage-pricing-actions input,
|
||||
.usage-pricing-actions select {
|
||||
min-width: 180px;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
flex: 1 1 0;
|
||||
height: 34px;
|
||||
padding: 0 10px;
|
||||
border: 1px solid var(--theme-d5d2cb);
|
||||
@@ -9979,7 +9991,10 @@ body.table-col-resizing * {
|
||||
|
||||
.usage-pricing-actions button,
|
||||
.usage-price-editor-actions button {
|
||||
flex: none;
|
||||
min-height: 34px;
|
||||
height: 34px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.usage-price-sync-dialog {
|
||||
@@ -10035,6 +10050,10 @@ body.table-col-resizing * {
|
||||
|
||||
.usage-price-editor {
|
||||
display: grid;
|
||||
min-height: 0;
|
||||
flex: 0 1 auto;
|
||||
max-height: 50%;
|
||||
overflow: auto;
|
||||
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
|
||||
gap: 10px;
|
||||
padding: 14px;
|
||||
@@ -10073,13 +10092,26 @@ body.table-col-resizing * {
|
||||
}
|
||||
|
||||
.usage-pricing-table-wrap {
|
||||
min-height: 380px;
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
.usage-pricing-table-wrap::-webkit-scrollbar,
|
||||
.usage-pricing-table-wrap::-webkit-scrollbar:horizontal {
|
||||
display: block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.usage-pricing-table-wrap::-webkit-scrollbar-thumb {
|
||||
border-radius: 4px;
|
||||
background: var(--border-primary);
|
||||
}
|
||||
|
||||
.usage-pricing-table {
|
||||
width: 100%;
|
||||
min-width: 980px;
|
||||
border-collapse: collapse;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
font-size: var(--font-size-meta);
|
||||
}
|
||||
|
||||
@@ -10105,7 +10137,22 @@ body.table-col-resizing * {
|
||||
|
||||
.usage-pricing-table th:first-child,
|
||||
.usage-pricing-table td:first-child {
|
||||
text-align: center;
|
||||
position: sticky;
|
||||
left: 0;
|
||||
min-width: 180px;
|
||||
max-width: 240px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
box-shadow: 1px 0 0 var(--border-color);
|
||||
}
|
||||
|
||||
.usage-pricing-table td:first-child {
|
||||
z-index: 1;
|
||||
background: var(--bg-primary);
|
||||
}
|
||||
|
||||
.usage-pricing-table th:first-child {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.usage-price-row-actions {
|
||||
@@ -11271,24 +11318,6 @@ body.table-col-resizing * {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.usage-pricing-toolbar {
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.usage-pricing-actions {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.usage-pricing-actions input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.usage-price-editor {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.thinking-alias-workbench {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
@@ -2976,11 +2976,6 @@
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.usage-topbar {
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.usage-tabs {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
@@ -2996,42 +2991,16 @@
|
||||
padding-inline: 12px;
|
||||
}
|
||||
|
||||
.usage-topbar-actions {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.usage-events-summary-left,
|
||||
.usage-events-summary-right {
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.usage-collector-state {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.usage-analysis-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.usage-pricing-toolbar {
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.usage-pricing-actions {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.usage-pricing-actions input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.usage-price-editor {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.auth-files-toolbar {
|
||||
grid-template-columns: 18px minmax(0, 1fr);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
@import '../styles.css';
|
||||
@import './feature-pages.css';
|
||||
@import './ui-refinements.css';
|
||||
@import './responsive-shell-usage.css';
|
||||
@import './responsive-providers.css';
|
||||
@import './responsive-agents.css';
|
||||
@import './responsive-settings.css';
|
||||
@@ -0,0 +1,244 @@
|
||||
/* Use the space left for the workbench, including the app sidebar and padding. */
|
||||
.agents-page:not(.agents-page-embedded) {
|
||||
container: agent-workspace / inline-size;
|
||||
}
|
||||
|
||||
@container agent-workspace (max-width: 760px) {
|
||||
.app-shell:has(.agents-page:not(.agents-page-embedded)) .agent-workbench {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
grid-template-rows: auto minmax(0, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.app-shell:has(.agents-page:not(.agents-page-embedded)) .agent-client-list {
|
||||
height: auto;
|
||||
max-height: none;
|
||||
gap: 6px;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
.agents-page:not(.agents-page-embedded) .agent-list-items {
|
||||
display: grid;
|
||||
flex: none;
|
||||
grid-auto-flow: column;
|
||||
grid-auto-columns: 192px;
|
||||
grid-template-columns: none;
|
||||
grid-template-rows: auto;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
padding: 0 0 4px;
|
||||
scrollbar-gutter: auto;
|
||||
scroll-snap-type: x proximity;
|
||||
}
|
||||
|
||||
.agents-page:not(.agents-page-embedded) .agent-list-items button {
|
||||
min-height: 58px;
|
||||
scroll-snap-align: start;
|
||||
}
|
||||
|
||||
.agents-page:not(.agents-page-embedded) .agent-list-items strong,
|
||||
.agents-page:not(.agents-page-embedded) .agent-list-items small {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.agent-save-bar,
|
||||
.agent-codex-save-actions,
|
||||
.agent-signin-label,
|
||||
.agent-section-heading-actions {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.agent-save-bar .agent-save-feedback {
|
||||
flex-basis: 180px;
|
||||
}
|
||||
|
||||
.agent-save-actions button,
|
||||
.agent-management-actions button {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.agent-section-heading > div:first-child,
|
||||
.agent-claude-code-disable-compact > span:first-child {
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
@container agent-panel (max-width: 640px) {
|
||||
.agent-desktop-models > .agent-section-heading {
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.agent-desktop-models > .agent-section-heading > .agent-section-heading-actions {
|
||||
width: 100%;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.agent-desktop-model-fields {
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.agent-desktop-model-field:first-child {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.agent-desktop-model-actions {
|
||||
height: 44px;
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
.agent-status-grid,
|
||||
.agent-status-grid.dual-install-status-grid,
|
||||
.agent-status-grid.pi-status-grid {
|
||||
grid-template-columns: repeat(auto-fit, minmax(min(100%, 140px), 1fr));
|
||||
}
|
||||
|
||||
.codex-session-overview-head,
|
||||
.codex-session-list-head {
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.codex-session-selection-actions {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.codex-session-pagination {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
@container agent-panel (max-width: 420px) {
|
||||
.agent-subpage-tabs {
|
||||
width: fit-content;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.agent-subpage-tabs button {
|
||||
flex: none;
|
||||
width: auto;
|
||||
padding-inline: 10px;
|
||||
}
|
||||
|
||||
.agent-signin-explanation dl > div {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.codex-session-meta,
|
||||
.codex-session-row:has(.codex-session-checkbox) .codex-session-meta {
|
||||
grid-template-columns: auto minmax(0, 1fr);
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.codex-session-meta time {
|
||||
grid-column: 1 / -1;
|
||||
justify-self: start;
|
||||
}
|
||||
}
|
||||
|
||||
/* Catalog forms must respond to the editor width, not the whole dialog. */
|
||||
.codex-catalog-editor {
|
||||
container: catalog-editor / inline-size;
|
||||
}
|
||||
|
||||
.codex-catalog-sidebar,
|
||||
.codex-catalog-form > label,
|
||||
.codex-catalog-models > button {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.codex-catalog-model-heading,
|
||||
.codex-catalog-footer,
|
||||
.codex-catalog-footer > div:last-child,
|
||||
.codex-catalog-confirm > div > div {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.codex-catalog-model-heading > button {
|
||||
flex: none;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.codex-catalog-footer > div:last-child {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.codex-catalog-hint,
|
||||
.codex-catalog-heading p {
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
@container catalog-editor (max-width: 500px) {
|
||||
.codex-catalog-form,
|
||||
.harness-reasoning-levels {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep the model list beside the editor on small desktop windows so it does
|
||||
not consume most of the dialog's available height. */
|
||||
@media (min-width: 600px) and (max-width: 900px) {
|
||||
.codex-catalog-body,
|
||||
.harness-catalog-dialog .codex-catalog-body {
|
||||
grid-template-columns: 180px minmax(0, 1fr);
|
||||
grid-template-rows: minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.codex-catalog-sidebar {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
grid-template-rows: auto minmax(0, 1fr) auto;
|
||||
gap: 8px;
|
||||
padding: 10px;
|
||||
border-right: 1px solid var(--theme-d5d2cb);
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.harness-catalog-dialog .codex-catalog-sidebar {
|
||||
grid-template-rows: auto auto minmax(0, 1fr) auto;
|
||||
}
|
||||
|
||||
.codex-catalog-sidebar > *,
|
||||
.harness-catalog-dialog .codex-catalog-sidebar > * {
|
||||
grid-column: 1;
|
||||
grid-row: auto;
|
||||
}
|
||||
|
||||
.codex-catalog-footer {
|
||||
flex-direction: row;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.codex-catalog-footer > div:last-child {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.agent-backup-modal {
|
||||
container: agent-backup / inline-size;
|
||||
}
|
||||
|
||||
.agent-backup-modal footer {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.agent-backup-columns nav {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.agent-backup-columns nav button {
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
@container agent-backup (max-width: 680px) {
|
||||
.agent-backup-columns {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.agent-backup-columns nav {
|
||||
max-height: 160px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,435 @@
|
||||
/* Keep API navigation above the list at every width. */
|
||||
.api-access-page .real-provider-workbench {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.api-access-page .provider-category-panel {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, minmax(0, 1fr));
|
||||
gap: 4px;
|
||||
height: auto;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.api-access-page .provider-category-panel button {
|
||||
grid-template-columns: 24px minmax(0, auto) auto;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
height: 50px;
|
||||
min-height: 50px;
|
||||
padding: 8px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.api-access-page .provider-category-panel button.active {
|
||||
background: var(--ui-accent-soft);
|
||||
border-color: color-mix(in srgb, var(--ui-accent) 20%, transparent);
|
||||
color: var(--ui-accent);
|
||||
}
|
||||
|
||||
.api-access-page .provider-category-panel .provider-logo {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.api-access-page .provider-category-panel span {
|
||||
white-space: normal;
|
||||
overflow-wrap: normal;
|
||||
overflow: hidden;
|
||||
text-overflow: clip;
|
||||
}
|
||||
|
||||
.api-access-page .provider-category-panel strong {
|
||||
justify-self: center;
|
||||
min-width: 22px;
|
||||
padding: 2px 5px;
|
||||
border-radius: 6px;
|
||||
background: var(--bg-secondary);
|
||||
color: var(--text-quaternary);
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.api-access-page .provider-category-panel .active strong {
|
||||
background: color-mix(in srgb, var(--ui-accent) 10%, var(--bg-primary));
|
||||
color: var(--ui-accent);
|
||||
}
|
||||
|
||||
.api-access-page .provider-resource-panel {
|
||||
container: provider-resources / inline-size;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.api-access-page .management-panel-heading {
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(180px, 1fr) auto;
|
||||
grid-template-areas: 'title search actions';
|
||||
gap: 14px 24px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.api-access-page .management-panel-heading > div:first-child {
|
||||
grid-area: title;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.api-access-page .api-access-search {
|
||||
grid-area: search;
|
||||
width: 100%;
|
||||
max-width: 440px;
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
.api-access-page .api-access-heading-tools {
|
||||
grid-area: actions;
|
||||
display: flex;
|
||||
width: auto;
|
||||
flex: none;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.api-access-page .api-access-heading-tools > button {
|
||||
flex: 0 0 auto;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.api-access-page .real-provider-list {
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.api-access-page .real-provider-row {
|
||||
grid-template-columns: 24px minmax(0, 1fr) auto;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
min-height: 104px;
|
||||
padding: 16px 0;
|
||||
}
|
||||
|
||||
.api-access-page .real-provider-row:last-child {
|
||||
border-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.api-access-page .provider-drag-handle {
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
width: 24px;
|
||||
min-width: 24px;
|
||||
height: 32px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
align-self: start;
|
||||
border-color: transparent;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.api-access-page .provider-row-main {
|
||||
grid-column: 2;
|
||||
grid-row: 1;
|
||||
gap: 7px;
|
||||
}
|
||||
|
||||
.api-access-page .provider-row-title {
|
||||
align-items: baseline;
|
||||
flex-wrap: wrap;
|
||||
gap: 2px 10px;
|
||||
}
|
||||
|
||||
.api-access-page .provider-row-title strong {
|
||||
max-width: 100%;
|
||||
font-size: 15px;
|
||||
line-height: 22px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.api-access-page .provider-row-title > span:not(.state-pill) {
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
color: var(--text-quaternary);
|
||||
font-size: 12px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.api-access-page .provider-row-title .state-pill {
|
||||
min-height: 22px;
|
||||
padding: 1px 7px;
|
||||
font-size: 11px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.api-access-page .provider-row-main > .provider-row-url {
|
||||
overflow: hidden;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.api-access-page .provider-row-meta {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
gap: 6px 12px;
|
||||
padding: 0;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.api-access-page .provider-row-meta code {
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
overflow-wrap: anywhere;
|
||||
color: var(--text-quaternary);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.api-access-page .provider-row-meta span {
|
||||
flex: none;
|
||||
color: var(--text-quaternary);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.api-access-page .provider-row-actions {
|
||||
grid-column: 3;
|
||||
grid-row: 1;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
max-width: 340px;
|
||||
}
|
||||
|
||||
.api-access-page .provider-enabled-control {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.api-access-page .provider-row-actions .icon-button {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
min-width: 32px;
|
||||
}
|
||||
|
||||
/* Compact tabs keep every category visible instead of wrapping a lone tab. */
|
||||
@container workspace (max-width: 820px) {
|
||||
.api-access-page .provider-category-panel button {
|
||||
grid-template-columns: 24px auto;
|
||||
grid-template-rows: 24px auto;
|
||||
gap: 4px 8px;
|
||||
height: auto;
|
||||
min-height: 68px;
|
||||
}
|
||||
|
||||
.api-access-page .provider-category-panel span {
|
||||
grid-column: 1 / -1;
|
||||
grid-row: 2;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
white-space: normal;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
|
||||
.api-access-page .provider-category-panel strong {
|
||||
grid-column: 2;
|
||||
grid-row: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@container provider-resources (max-width: 720px) {
|
||||
.api-access-page .management-panel-heading {
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
grid-template-areas: 'title actions' 'search search';
|
||||
column-gap: 12px;
|
||||
}
|
||||
|
||||
.api-access-page .api-access-search {
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
|
||||
@container provider-resources (max-width: 580px) {
|
||||
.api-access-page .real-provider-row {
|
||||
grid-template-columns: 24px minmax(0, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.api-access-page .provider-row-actions {
|
||||
grid-column: 2;
|
||||
grid-row: 2;
|
||||
max-width: none;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep controls compact while allowing complete groups to move to the next line. */
|
||||
.auth-files-page .management-heading-actions {
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.auth-files-page .management-heading-actions button {
|
||||
flex: 0 0 auto;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.auth-files-page .real-auth-files-panel {
|
||||
container: credential-files / inline-size;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.auth-files-page .auth-files-toolbar select {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
@container credential-files (max-width: 680px) {
|
||||
.auth-files-page .auth-files-toolbar {
|
||||
grid-template-columns: 18px minmax(0, 1fr) minmax(0, 1fr);
|
||||
gap: 0 9px;
|
||||
}
|
||||
|
||||
.auth-files-page .auth-files-toolbar input {
|
||||
grid-column: 2 / -1;
|
||||
}
|
||||
|
||||
.auth-files-page .auth-files-toolbar select:first-of-type {
|
||||
grid-column: 1 / 3;
|
||||
}
|
||||
|
||||
.auth-files-page .auth-files-toolbar select:last-of-type {
|
||||
grid-column: 3;
|
||||
}
|
||||
|
||||
.auth-files-page .auth-files-toolbar select {
|
||||
border-top: 1px solid var(--theme-e3e1db);
|
||||
border-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.oauth-login-page > .oauth-grid {
|
||||
grid-template-columns: repeat(auto-fit, minmax(min(360px, 100%), 1fr));
|
||||
}
|
||||
|
||||
.oauth-browser-picker {
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.oauth-browser-picker select {
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
flex: 0 1 240px;
|
||||
}
|
||||
|
||||
.oauth-card .oauth-auth-url-actions,
|
||||
.oauth-card .management-card-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.oauth-card .management-card-actions > button {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.oauth-card .oauth-callback-row {
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
}
|
||||
|
||||
.oauth-card .oauth-callback-row > button {
|
||||
width: auto;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.quota-group-heading {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.quota-group-heading .quota-group-actions {
|
||||
flex: 1 1 280px;
|
||||
}
|
||||
|
||||
.quota-group-actions .muted-summary {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.real-quota-row > div:first-child {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.real-quota-row small,
|
||||
.quota-reset-credit-summary span {
|
||||
min-width: 0;
|
||||
white-space: normal;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
/* Optional key selectors must not shift fixed dialog grid tracks onto the model list. */
|
||||
.model-discovery-dialog.provider-health-dialog {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: min(660px, calc(100dvh - 48px));
|
||||
min-height: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.provider-health-dialog > :not(.provider-health-model-list) {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.provider-health-dialog .provider-health-model-list {
|
||||
flex: 1 1 180px;
|
||||
min-height: 100px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.provider-health-dialog .model-discovery-header > div {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.provider-health-dialog .model-discovery-header span {
|
||||
white-space: normal;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.provider-health-dialog .provider-health-key-selector {
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.model-discovery-dialog .model-discovery-toolbar,
|
||||
.model-discovery-dialog .model-discovery-actions,
|
||||
.model-discovery-dialog .model-transfer-summary {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.model-discovery-dialog .model-discovery-toolbar > span {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.api-provider-dialog .provider-group-heading,
|
||||
.api-provider-dialog .model-config-heading,
|
||||
.api-provider-dialog .thinking-level-heading {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
@container workspace (max-width: 760px) {
|
||||
.oauth-browser-picker {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.auth-files-page .management-heading-actions,
|
||||
.quota-group-heading .quota-group-actions {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,342 @@
|
||||
/* Keep each section responsive to its available content width, including the
|
||||
sidebar and the narrower cards in the two-column home layout. */
|
||||
.home-quick-actions {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
@container workspace (max-width: 1080px) {
|
||||
.home-quick-actions {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@container workspace (max-width: 480px) {
|
||||
.home-quick-actions {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.client-api-panel {
|
||||
container: home-api / inline-size;
|
||||
}
|
||||
|
||||
.client-api-panel .client-api-heading {
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.client-api-panel .client-api-heading > div {
|
||||
flex: 1 1 260px;
|
||||
}
|
||||
|
||||
.client-api-panel .client-api-key-actions {
|
||||
max-width: 100%;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
.client-api-key-code {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@container home-api (max-width: 480px) {
|
||||
.client-api-card {
|
||||
height: auto;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.client-api-card-heading {
|
||||
flex: none;
|
||||
width: auto;
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* The download source is one control group: move the group together, then let
|
||||
the select shrink while the action retains a readable label. */
|
||||
.version-management-page > .version-list {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.version-source-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px 24px;
|
||||
}
|
||||
|
||||
.version-source-copy {
|
||||
flex: 1 1 240px;
|
||||
}
|
||||
|
||||
.version-source-control {
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
width: min(360px, 100%);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.version-source-control label,
|
||||
.version-source-control select {
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.version-source-add-button {
|
||||
grid-column: auto;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@container workspace (max-width: 620px) {
|
||||
.app-release-notes-heading {
|
||||
flex-wrap: wrap;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.app-release-notes-body {
|
||||
padding: 0 16px 16px;
|
||||
}
|
||||
|
||||
.app-release-notes-markdown {
|
||||
gap: 14px 12px;
|
||||
}
|
||||
|
||||
.app-release-notes-markdown > .release-notes-category {
|
||||
max-width: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Settings have variable-length descriptions; fixed row heights and controls
|
||||
sized from the window instead of the workspace can make adjacent cards overlap. */
|
||||
.config-page .config-panel-heading,
|
||||
.config-page .config-heading-actions,
|
||||
.config-page .config-network-section-heading,
|
||||
.config-page .config-proxy-heading {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.config-page .config-panel-heading {
|
||||
gap: 10px 14px;
|
||||
}
|
||||
|
||||
.config-page .config-heading-actions {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.config-keys-panel {
|
||||
grid-template-rows: auto minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.config-network-grid {
|
||||
grid-auto-rows: minmax(154px, auto);
|
||||
}
|
||||
|
||||
.config-network-field small,
|
||||
.config-diagnostics-setting-copy,
|
||||
.config-software-setting-copy {
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.config-diagnostics-actions,
|
||||
.config-management-actions {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
@container workspace (max-width: 900px) {
|
||||
.config-network-grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.config-diagnostics-toggle-grid {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@container workspace (max-width: 700px) {
|
||||
.config-diagnostics-fields {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.config-software-setting-row {
|
||||
gap: 16px;
|
||||
padding: 15px 16px;
|
||||
}
|
||||
|
||||
.config-software-close-row {
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.config-software-select {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
padding-left: 54px;
|
||||
}
|
||||
|
||||
.config-diagnostics-footer,
|
||||
.config-management-form-footer {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.config-diagnostics-actions {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
@container workspace (max-width: 560px) {
|
||||
.config-network-grid,
|
||||
.config-diagnostics-fields {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.config-network-grid {
|
||||
grid-auto-rows: auto;
|
||||
}
|
||||
|
||||
.config-software-select {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.config-heading-title h2 {
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
|
||||
/* Alias routes should keep their names readable before metadata and actions
|
||||
wrap onto a second line. The editor uses its own width inside a modal. */
|
||||
.thinking-alias-list-panel {
|
||||
container: alias-list / inline-size;
|
||||
}
|
||||
|
||||
.thinking-alias-dialog {
|
||||
container: alias-editor / inline-size;
|
||||
}
|
||||
|
||||
.thinking-alias-field {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
@container alias-list (max-width: 560px) {
|
||||
.thinking-alias-row {
|
||||
grid-template-columns: minmax(0, 1fr) 34px;
|
||||
}
|
||||
|
||||
.thinking-alias-route {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.thinking-alias-badges {
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
@container alias-editor (max-width: 580px) {
|
||||
.thinking-effort-options {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep novice-mode actions compact at intermediate widths. Existing phone
|
||||
rules made every action full-width even when two controls easily fit. */
|
||||
.simple-mode-topbar,
|
||||
.simple-mode-topbar-right,
|
||||
.simple-mode-brand-title,
|
||||
.simple-mode-choice-title,
|
||||
.simple-mode-api-model-heading,
|
||||
.simple-mode-api-model-selection-heading {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.simple-mode-topbar-left,
|
||||
.simple-mode-topbar-right,
|
||||
.simple-mode-brand,
|
||||
.simple-mode-brand-text {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.simple-mode-topbar-left {
|
||||
flex: 1 1 340px;
|
||||
}
|
||||
|
||||
.simple-mode-topbar-right {
|
||||
flex: 0 1 auto;
|
||||
justify-content: flex-end;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.simple-mode-topbar-right > *,
|
||||
.simple-mode-guide-toggle {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.simple-mode-choice-title strong,
|
||||
.simple-mode-brand-title strong {
|
||||
white-space: normal;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.simple-mode-provider-card-foot {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.simple-mode-field .text-input,
|
||||
.simple-mode-field .select-input {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
@container workspace (max-width: 720px) {
|
||||
.simple-mode-topbar-left,
|
||||
.simple-mode-topbar-right {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.simple-mode-topbar-right {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.simple-mode-choice-grid,
|
||||
.simple-mode-api-fields {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.simple-mode-api-actions,
|
||||
.simple-mode-task-footer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.simple-mode-api-actions button,
|
||||
.simple-mode-task-footer > .primary-button,
|
||||
.simple-mode-task-footer > .secondary-button {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.simple-mode-task-footer > .primary-button {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@container workspace (max-width: 520px) {
|
||||
.simple-mode-api-model-options {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.simple-mode-step-status-track {
|
||||
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.simple-mode-step-status-connector {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.simple-mode-step-status-copy strong,
|
||||
.simple-mode-step-status-copy small {
|
||||
white-space: normal;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
/* Keep footer controls reachable when desktop navigation exceeds the height. */
|
||||
@media (min-width: 901px) {
|
||||
.sidebar-brand,
|
||||
.sidebar-bottom {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.sidebar > .nav-section {
|
||||
min-height: 0;
|
||||
margin-bottom: 18px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
}
|
||||
|
||||
/* Let toolbar rows keep their height instead of overlapping the table. */
|
||||
.usage-events-summary {
|
||||
flex: none;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.usage-events-summary-left,
|
||||
.usage-events-summary-right {
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.usage-events-summary-right {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.usage-pagination-controls {
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.usage-topbar,
|
||||
.usage-filter-panel {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.usage-page-navigation,
|
||||
.usage-topbar-actions {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.usage-tabs,
|
||||
.config-subpage-tabs,
|
||||
.oauth-subpage-tabs {
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.usage-tabs button,
|
||||
.config-subpage-tabs button,
|
||||
.oauth-subpage-tabs button {
|
||||
flex-shrink: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.usage-topbar-actions {
|
||||
min-width: 0;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.usage-collector-state {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.usage-collector-state > span:last-child {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.usage-section-heading {
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.usage-section-heading > div {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.usage-section-heading strong {
|
||||
white-space: normal;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.usage-custom-range input {
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.usage-pricing-table-wrap:focus-visible {
|
||||
outline: 2px solid var(--ui-accent);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
.usage-pricing-panel {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.usage-price-editor {
|
||||
min-height: 160px;
|
||||
max-height: min(320px, 40vh);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.usage-storage-limit-editor {
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.usage-storage-limit-editor label {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.usage-storage-limit-editor input {
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
max-width: 168px;
|
||||
}
|
||||
|
||||
.usage-storage-limit-editor button {
|
||||
flex: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@container workspace (max-width: 760px) {
|
||||
.usage-overview-layout {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
grid-template-rows: max-content minmax(280px, 1fr) auto;
|
||||
}
|
||||
|
||||
.usage-health-panel {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.usage-data-management-action {
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.usage-data-management-action > div:first-child {
|
||||
min-width: 0;
|
||||
flex: 1 1 260px;
|
||||
}
|
||||
}
|
||||
|
||||
@container workspace (max-width: 540px) {
|
||||
.usage-events-summary-right {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.usage-storage-limit-editor {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.usage-storage-limit-editor .primary-button {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 761px) {
|
||||
.usage-events-panel > .usage-table-wrap,
|
||||
.usage-events-panel > .usage-empty {
|
||||
min-height: 0;
|
||||
}
|
||||
}
|
||||
@@ -387,40 +387,6 @@ body, html, #root {
|
||||
font-weight: var(--font-weight-semibold);
|
||||
}
|
||||
|
||||
/* API access toolbar */
|
||||
.api-access-page .management-panel-heading {
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.api-access-heading-tools {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
flex: 1 1 420px;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.api-access-heading-tools .compact-toolbar {
|
||||
width: min(280px, 100%);
|
||||
flex: 1 1 180px;
|
||||
}
|
||||
|
||||
|
||||
@container workspace (max-width: 760px) {
|
||||
.api-access-heading-tools {
|
||||
width: 100%;
|
||||
flex-basis: 100%;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.api-access-heading-tools .compact-toolbar {
|
||||
flex-basis: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* 7. OAuth Management Page Polish */
|
||||
.oauth-management-page .management-header h1 {
|
||||
display: none;
|
||||
@@ -618,13 +584,18 @@ body, html, #root {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.usage-records-page .usage-filter-group {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
grid-template-columns: repeat(6, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.usage-records-page .usage-filter-item {
|
||||
flex: 1 1 150px;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 0;
|
||||
min-width: 132px;
|
||||
max-width: 210px;
|
||||
min-width: 0;
|
||||
height: 36px;
|
||||
padding: 0 8px;
|
||||
border: 1px solid var(--border-color);
|
||||
@@ -688,6 +659,18 @@ body, html, #root {
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
@container workspace (max-width: 880px) {
|
||||
.usage-records-page .usage-filter-group {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@container workspace (max-width: 520px) {
|
||||
.usage-records-page .usage-filter-group {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
.usage-records-page .usage-section-heading strong {
|
||||
color: #1d1d1f;
|
||||
font-weight: 650;
|
||||
|
||||
Reference in new issue
Block a user