Files
easyai-ai-gateway/apps/web/src/styles.css
T
chengcheng 8ca68eb3cd fix: 为失效 OIDC 事务提供安全重试
细分回调事务、状态和授权响应错误,提供脱敏诊断编号与显式重新登录入口,避免失效事务形成重试循环。
2026-07-13 22:50:09 +08:00

1034 lines
20 KiB
CSS

@import "tailwindcss";
@source "../node_modules/streamdown/dist/*.js";
@source "../node_modules/@streamdown/code/dist/*.js";
@source "../node_modules/@streamdown/math/dist/*.js";
@source "../node_modules/@streamdown/mermaid/dist/*.js";
@source "../node_modules/@streamdown/cjk/dist/*.js";
@import './styles/ui.css';
@import './styles/pages.css';
@import './styles/admin-capabilities.css';
@import './styles/pricing.css';
@import './styles/api-docs.css';
@import './styles/landing.css';
@import './styles/playground.css';
@theme inline {
--font-sans: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-destructive: var(--destructive);
--color-ring: var(--ring);
--color-surface: var(--surface);
--color-surface-subtle: var(--surface-subtle);
--color-text-strong: var(--text-strong);
--color-text-normal: var(--text-normal);
--color-text-soft: var(--text-soft);
--text-xs: 0.75rem;
--text-sm: 0.8125rem;
--text-base: 0.875rem;
--text-md: 0.9375rem;
--text-lg: 1rem;
--text-xl: 1.125rem;
--text-2xl: 1.375rem;
--text-3xl: 1.875rem;
--radius-sm: 7px;
--radius-md: 8px;
--radius-lg: 10px;
--radius-xl: 12px;
--shadow-card: 0 1px 2px rgba(16, 24, 40, 0.06);
--shadow-dialog: 0 22px 60px rgba(16, 24, 40, 0.16);
}
:root {
--background: #ffffff;
--foreground: #09090b;
--card: #ffffff;
--card-foreground: #09090b;
--surface: #ffffff;
--surface-subtle: #fafafa;
--surface-muted: #f4f4f5;
--muted: #f4f4f5;
--muted-foreground: #71717a;
--border: #e4e4e7;
--border-subtle: #e4e4e7;
--input: #e4e4e7;
--primary: #18181b;
--primary-foreground: #ffffff;
--secondary: #f4f4f5;
--secondary-foreground: #18181b;
--destructive: #dc2626;
--destructive-foreground: #ffffff;
--accent: #f4f4f5;
--accent-foreground: #18181b;
--popover: #ffffff;
--popover-foreground: #09090b;
--ring: #a1a1aa;
--text-strong: #09090b;
--text-normal: #27272a;
--text-soft: #71717a;
--text-faint: #a1a1aa;
--font-size-xs: 12px;
--font-size-sm: 13px;
--font-size-base: 14px;
--font-size-md: 15px;
--font-size-lg: 16px;
--font-size-xl: 18px;
--font-size-2xl: 22px;
--line-height-tight: 1.2;
--line-height-normal: 1.55;
--font-weight-regular: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-strong: 650;
--control-height-sm: 32px;
--control-height: 40px;
--control-radius: 6px;
--card-radius: 12px;
--focus-ring: 0 0 0 3px rgba(24, 24, 27, 0.12);
--shadow-soft: none;
--shadow-panel: none;
color: var(--foreground);
background: var(--background);
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
min-width: 320px;
min-height: 100vh;
color: var(--text-normal);
font-size: var(--font-size-base);
font-weight: var(--font-weight-regular);
line-height: var(--line-height-normal);
background: var(--background);
}
button,
input,
select,
textarea {
font: inherit;
color: inherit;
}
button {
cursor: pointer;
}
button:disabled {
cursor: not-allowed;
opacity: 0.52;
}
h1,
h2,
h3,
p {
margin: 0;
}
h1 {
color: var(--text-strong);
font-size: 1.75rem;
font-weight: var(--font-weight-semibold);
line-height: 1.15;
}
h2,
h3 {
color: var(--text-strong);
font-weight: var(--font-weight-semibold);
}
b,
strong {
font-weight: var(--font-weight-semibold);
}
.eyebrow {
margin-bottom: 5px;
color: var(--muted-foreground);
font-size: 0.75rem;
font-weight: var(--font-weight-semibold);
text-transform: uppercase;
}
.authPage {
width: min(980px, calc(100vw - 32px));
margin: 0 auto;
padding: 28px 0 48px;
}
.authBrand,
.brandBlock {
display: flex;
align-items: center;
gap: 12px;
}
.authBrand {
margin-bottom: 28px;
}
.brandMark {
display: grid;
width: 38px;
height: 38px;
place-items: center;
border-radius: var(--card-radius);
background: var(--primary);
color: #fff;
font-size: var(--font-size-sm);
font-weight: var(--font-weight-semibold);
}
.authShell {
display: grid;
min-height: 560px;
align-items: center;
}
.authCard {
width: min(720px, 100%);
margin: 0 auto;
}
.authContent,
.pageStack,
.statGrid,
.contentGrid,
.modelCatalog,
.capabilityCard,
.endpointCard,
.modelMeta,
.profileGrid,
.balanceCard,
.docStack,
.taskPreview {
display: grid;
gap: 14px;
}
.taskRecordFilters {
grid-template-columns: minmax(240px, 1.4fr) minmax(150px, 0.65fr) minmax(330px, 1.2fr) auto;
gap: 10px;
}
.taskRecordRangeLabel {
min-width: 0;
}
.taskRecordViewport {
--sh-table-viewport-gap: 10px;
--sh-table-viewport-height: calc(100dvh - 90px);
margin-bottom: -52px;
}
.taskRecordSearchBox {
display: grid;
grid-template-columns: 18px minmax(0, 1fr);
align-items: center;
gap: 8px;
min-height: 32px;
padding-left: 10px;
border: 1px solid var(--input);
border-radius: var(--control-radius);
box-shadow: 0 1px 2px rgba(16, 24, 40, 0.04);
}
.taskRecordSearchBox svg {
color: var(--text-soft);
}
.taskRecordSearchBox .shInput {
border: 0;
box-shadow: none;
}
.taskRecordTable .shTableRow {
grid-template-columns: minmax(190px, 0.9fr) minmax(220px, 1fr) minmax(94px, 0.4fr) minmax(280px, 1.45fr) minmax(104px, 0.42fr) minmax(118px, 0.44fr) minmax(126px, 0.55fr) minmax(150px, 0.66fr) minmax(154px, 0.62fr) minmax(82px, 0.36fr) minmax(98px, 0.42fr) minmax(150px, 0.66fr) minmax(130px, 0.54fr);
min-width: 1904px;
align-items: start;
}
.taskRecordPrimaryCell {
display: grid;
min-width: 0;
gap: 3px;
}
.taskRecordPrimaryCell strong,
.taskRecordPrimaryCell small {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.taskRecordPrimaryCell strong {
color: var(--text-strong);
font-weight: var(--font-weight-semibold);
}
.taskRecordPrimaryCell small {
color: var(--text-soft);
font-size: var(--font-size-xs);
}
.taskRecordIdentityCell {
gap: 6px;
}
.taskRecordIdLine,
.taskRecordRequestLine {
display: grid;
min-width: 0;
align-items: center;
gap: 6px;
}
.taskRecordIdLine {
grid-template-columns: 28px minmax(0, 1fr);
}
.taskRecordRequestLine {
grid-template-columns: minmax(0, 1fr) 28px;
}
.taskRecordIdLine > span {
color: var(--text-soft);
font-size: var(--font-size-xs);
}
.taskRecordIdLine code,
.taskRecordRequestLine code {
overflow: hidden;
min-width: 0;
color: var(--text-normal);
font-family: var(--font-mono);
font-size: var(--font-size-xs);
text-overflow: ellipsis;
white-space: nowrap;
}
.taskRecordRequestLine .shButton {
width: 28px;
min-height: 28px;
}
.taskRecordTokenCell {
overflow: visible;
white-space: normal;
}
.taskRecordTokenUsage {
display: grid;
gap: 2px;
line-height: 1.3;
}
.taskRecordModelCell {
overflow: visible;
white-space: normal;
}
.taskRecordModelCell .taskRecordPrimaryCell strong,
.taskRecordModelCell .taskRecordPrimaryCell small {
overflow: visible;
text-overflow: clip;
white-space: normal;
word-break: break-word;
}
.taskRecordAttemptCell {
overflow: visible;
white-space: normal;
}
.taskRecordParamCell {
overflow: visible;
white-space: normal;
}
.taskRecordAttemptCount {
display: inline-flex;
align-items: center;
justify-content: flex-start;
min-height: 1.5rem;
padding: 0;
border: 0;
background: transparent;
color: var(--text-strong);
cursor: default;
font: inherit;
font-weight: var(--font-weight-medium);
}
.taskRecordAttemptAntPopover {
z-index: 1200;
}
.taskRecordAttemptPopover {
display: grid;
width: min(34rem, calc(100vw - 2rem));
gap: 0.6rem;
}
.taskRecordAttemptDetail {
display: grid;
min-width: 0;
gap: 0.35rem;
padding-bottom: 0.6rem;
border-bottom: 1px solid var(--border);
}
.taskRecordAttemptDetail:last-child {
padding-bottom: 0;
border-bottom: 0;
}
.taskRecordAttemptDetailHeader {
display: flex;
min-width: 0;
align-items: center;
justify-content: space-between;
gap: 0.5rem;
}
.taskRecordAttemptDetailHeader strong {
min-width: 0;
color: var(--text-strong);
font-weight: var(--font-weight-semibold);
overflow-wrap: anywhere;
}
.taskRecordAttemptDetail small {
color: var(--text-soft);
font-size: var(--font-size-xs);
line-height: 1.4;
}
.taskRecordAttemptError {
color: var(--destructive);
font-size: var(--font-size-xs);
line-height: 1.45;
overflow-wrap: anywhere;
}
.taskRecordAttemptTrace {
display: grid;
gap: 0.25rem;
padding-top: 0.1rem;
}
.taskRecordAttemptTraceItem {
color: var(--text-soft);
font-size: var(--font-size-xs);
line-height: 1.45;
overflow-wrap: anywhere;
}
.taskParamConversionEmpty {
color: var(--text-soft);
font-size: var(--font-size-xs);
}
.taskParamConversionTrigger {
display: inline-flex;
align-items: center;
gap: 0.35rem;
min-height: 1.5rem;
padding: 0;
border: 0;
background: transparent;
color: var(--text-strong);
cursor: default;
font: inherit;
font-weight: var(--font-weight-medium);
}
.taskParamConversionTrigger svg {
color: var(--primary);
}
.taskParamConversionAntPopover {
z-index: 1200;
}
.taskParamConversionPopover {
display: grid;
width: min(42rem, calc(100vw - 2rem));
max-height: min(34rem, calc(100vh - 7rem));
overflow-y: auto;
gap: 0.65rem;
}
.taskParamConversionPopoverHeader,
.taskParamConversionLogHeader,
.taskParamConversionChangeTop {
display: flex;
min-width: 0;
align-items: center;
justify-content: space-between;
gap: 0.5rem;
}
.taskParamConversionPopoverHeader strong,
.taskParamConversionLogHeader strong,
.taskParamConversionChangeTop strong {
min-width: 0;
color: var(--text-strong);
font-weight: var(--font-weight-semibold);
overflow-wrap: anywhere;
}
.taskParamConversionPopoverHeader small,
.taskParamConversionLog small,
.taskParamConversionChange small {
color: var(--text-soft);
font-size: var(--font-size-xs);
line-height: 1.4;
}
.taskParamConversionState {
color: var(--text-soft);
font-size: var(--font-size-sm);
}
.taskParamConversionState.error {
color: var(--destructive);
}
.taskParamConversionLog {
display: grid;
min-width: 0;
gap: 0.5rem;
padding-top: 0.65rem;
border-top: 1px solid var(--border);
}
.taskParamConversionLogHeader {
align-items: flex-start;
}
.taskParamConversionLogTitleBlock {
display: grid;
min-width: 0;
gap: 0.15rem;
}
.taskParamConversionLogTitleBlock strong {
line-height: 1.3;
}
.taskParamConversionLogTitleBlock small {
max-width: 32rem;
overflow: hidden;
color: var(--text-soft);
font-family: var(--font-mono);
font-size: var(--font-size-xs);
line-height: 1.35;
text-overflow: ellipsis;
white-space: nowrap;
}
.taskParamConversionCountBadge {
flex: 0 0 auto;
white-space: nowrap;
}
.taskParamConversionChange {
display: grid;
gap: 0.28rem;
padding: 0.5rem;
border: 1px solid var(--border-subtle);
border-radius: var(--radius-sm);
background: var(--surface-subtle);
color: var(--text-normal);
font-size: var(--font-size-xs);
line-height: 1.45;
overflow-wrap: anywhere;
}
.taskParamConversionChange code,
.taskParamConversionSummaryPaths code {
color: var(--text-soft);
font-family: var(--font-mono);
font-size: var(--font-size-xs);
overflow-wrap: anywhere;
white-space: normal;
}
.taskParamConversionSummaryPaths {
display: flex;
flex-wrap: wrap;
gap: 0.35rem;
}
.taskRecordJsonButton {
width: 100%;
justify-content: flex-start;
}
.walletMetricGrid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 10px;
}
.walletTransactionViewport {
--sh-table-viewport-gap: 10px;
--sh-table-viewport-height: calc(100dvh - 90px);
margin-bottom: -52px;
}
.walletTransactionFilters {
grid-template-columns: minmax(260px, 1.2fr) minmax(360px, 1.1fr) auto;
gap: 10px;
}
.walletTransactionTable .shTableRow {
grid-template-columns: minmax(150px, 0.65fr) minmax(220px, 1fr) minmax(180px, 0.82fr) minmax(136px, 0.62fr) minmax(148px, 0.68fr) minmax(154px, 0.7fr) minmax(116px, 0.52fr) minmax(140px, 0.62fr) minmax(250px, 1.14fr);
min-width: 1494px;
align-items: start;
}
.walletTransactionPrimaryCell,
.walletTransactionRef {
display: grid;
min-width: 0;
gap: 3px;
line-height: 1.3;
}
.walletTransactionPrimaryCell strong,
.walletTransactionPrimaryCell small,
.walletTransactionRef small {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.walletTransactionPrimaryCell strong {
color: var(--text-strong);
font-weight: var(--font-weight-semibold);
}
.walletTransactionPrimaryCell small,
.walletTransactionRef small {
color: var(--text-soft);
font-size: var(--font-size-xs);
}
.walletTransactionModelCell,
.walletTransactionPlatformCell,
.walletTransactionTokenCell {
overflow: visible;
white-space: normal;
}
.walletTransactionModelCell .walletTransactionPrimaryCell strong,
.walletTransactionModelCell .walletTransactionPrimaryCell small,
.walletTransactionPlatformCell .walletTransactionPrimaryCell strong,
.walletTransactionPlatformCell .walletTransactionPrimaryCell small {
overflow: visible;
text-overflow: clip;
white-space: normal;
word-break: break-word;
}
.walletTransactionAmount {
color: #166534;
font-weight: var(--font-weight-semibold);
}
.walletTransactionAmount[data-direction="debit"] {
color: #b42318;
}
.walletBalanceChange {
display: grid;
gap: 2px;
color: var(--text-soft);
line-height: 1.3;
}
.walletTransactionRef code {
display: block;
overflow: hidden;
color: var(--text-normal);
font-family: var(--font-mono);
font-size: var(--font-size-xs);
text-overflow: ellipsis;
white-space: nowrap;
}
.taskJsonDialog {
width: min(920px, 100%);
}
.taskJsonDialogBody {
grid-template-columns: minmax(0, 1fr);
padding: 0;
}
.taskJsonPreview {
overflow: auto;
max-height: min(620px, calc(100vh - 188px));
margin: 0;
padding: 16px 18px;
background: var(--surface-subtle);
color: var(--text-normal);
font-family: var(--font-mono);
font-size: 0.75rem;
line-height: 1.5;
white-space: pre-wrap;
word-break: break-word;
}
.appShell {
min-height: 100vh;
}
.appShell[data-page="playground"] {
display: grid;
height: 100dvh;
min-height: 0;
grid-template-rows: auto minmax(0, 1fr);
overflow: hidden;
}
.brandBlock {
min-width: 210px;
}
.brandBlock strong {
display: block;
color: var(--text-strong);
font-size: var(--font-size-md);
font-weight: var(--font-weight-semibold);
}
.brandBlock span,
.endpointCard span,
.modelMeta span,
.infoItem span,
.balanceCard span,
.docNote span,
.capabilityCard small {
color: var(--muted-foreground);
font-size: var(--font-size-sm);
}
.topNav {
display: flex;
align-items: center;
gap: 2px;
padding: 3px;
border: 1px solid var(--border);
border-radius: 999px;
background: rgba(255, 255, 255, 0.72);
}
.topNavItem {
display: flex;
min-height: 34px;
align-items: center;
gap: 7px;
padding: 0 14px;
border: 0;
border-radius: 999px;
background: transparent;
color: var(--text-soft);
font-size: var(--font-size-sm);
font-weight: var(--font-weight-medium);
white-space: nowrap;
}
.topNavItem:hover,
.topNavItem[data-active="true"] {
background: #ffffff;
color: var(--text-strong);
box-shadow: var(--shadow-soft);
}
.workspaceShell {
min-width: 0;
}
.appShell[data-page="playground"] .workspaceShell {
min-height: 0;
overflow: hidden;
}
.appTopbar {
position: sticky;
top: 0;
z-index: 2;
display: flex;
min-height: 64px;
align-items: center;
justify-content: space-between;
gap: 16px;
padding: 0 26px;
border-bottom: 1px solid var(--border);
background: rgba(255, 255, 255, 0.88);
box-shadow: 0 1px 0 rgba(16, 24, 40, 0.03);
backdrop-filter: blur(12px);
}
.topbarActions {
display: flex;
min-width: 0;
align-items: center;
justify-content: flex-end;
gap: 10px;
}
.health,
.tokenInline {
display: inline-flex;
align-items: center;
gap: 8px;
color: var(--muted-foreground);
font-size: var(--font-size-sm);
font-weight: var(--font-weight-medium);
}
.health span {
width: 9px;
height: 9px;
border-radius: 50%;
background: #d92d20;
}
.health[data-ok="true"] span {
background: #14805e;
}
.tokenInline input {
width: min(320px, 32vw);
min-height: 34px;
padding: 0 10px;
border: 1px solid var(--input);
border-radius: var(--control-radius);
background: var(--surface);
color: var(--text-normal);
}
.contentShell {
width: min(1480px, calc(100vw - 40px));
margin: 0 auto;
padding: 26px 24px 52px;
}
.pageHeader {
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: 16px;
}
.pageHeader p:not(.eyebrow) {
margin-top: 8px;
color: var(--text-soft);
font-size: var(--font-size-base);
}
.notice,
.inlineNotice {
padding: 12px 14px;
border: 1px solid #f0d4d4;
border-radius: 8px;
background: #fff7f7;
color: #9f2f2f;
font-size: var(--font-size-sm);
}
.oidcCallbackNotice {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.oidcCallbackMessage {
display: grid;
gap: 4px;
}
.oidcCallbackMessage small {
color: inherit;
opacity: 0.72;
}
.statGrid {
grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
}
.contentGrid.two {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.contentGrid.three {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.contentGrid.five {
grid-template-columns: repeat(5, minmax(0, 1fr));
}
.contentGrid.wideLeft {
grid-template-columns: minmax(0, 1.25fr) minmax(320px, 0.75fr);
}
.contentGrid.compact {
gap: 10px;
}
.infoGrid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
gap: 10px;
}
.infoGrid.compact .infoItem {
padding: 10px;
}
.spanTwo {
grid-column: 1 / -1;
}
.statCard {
min-height: 92px;
padding: 15px;
border: 1px solid var(--border);
border-radius: var(--card-radius);
background: var(--surface);
box-shadow: var(--shadow-soft);
}
.statCard[data-tone="blue"] { border-color: #d8e0ea; }
.statCard[data-tone="green"] { border-color: #d7e7df; }
.statCard[data-tone="violet"] { border-color: #e0dce9; }
.statCard[data-tone="amber"] { border-color: #ebe0cc; }
.statCard[data-tone="cyan"] { border-color: #d5e4e8; }
.statCard[data-tone="rose"] { border-color: #ead8df; }
.statCard span {
color: var(--text-soft);
font-size: var(--font-size-sm);
}
.statCard strong,
.capabilityCard strong,
.balanceCard strong {
display: block;
margin-top: 10px;
color: var(--text-strong);
font-size: 1.5rem;
font-weight: var(--font-weight-semibold);
line-height: var(--line-height-tight);
}
.capabilityCard {
grid-template-columns: 42px minmax(0, 1fr);
align-items: center;
}
.iconBox {
display: grid;
width: 38px;
height: 38px;
place-items: center;
border: 1px solid var(--border);
border-radius: var(--card-radius);
background: var(--surface);
color: var(--text-strong);
}
.infoItem,
.docNote {
display: grid;
gap: 5px;
padding: 12px;
border: 1px solid var(--border);
border-radius: var(--control-radius);
background: var(--surface-subtle);
}
@media (max-width: 980px) {
.contentShell {
width: 100%;
}
.contentGrid.two,
.contentGrid.three,
.contentGrid.five,
.contentGrid.wideLeft,
.formGrid.two {
grid-template-columns: 1fr;
}
.appTopbar,
.pageHeader {
align-items: flex-start;
flex-direction: column;
}
.topNav,
.topbarActions {
width: 100%;
flex-wrap: wrap;
justify-content: flex-start;
}
.tokenInline,
.tokenInline input {
width: 100%;
}
.taskRecordFilters {
grid-template-columns: 1fr;
}
.walletTransactionFilters {
grid-template-columns: 1fr;
}
.walletMetricGrid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.shTableFooter {
align-items: flex-start;
flex-direction: column;
}
.shTablePageActions {
flex-wrap: wrap;
}
}
@media (max-width: 560px) {
.walletMetricGrid {
grid-template-columns: 1fr;
}
}