Spaces:
Running
Running
| """ | |
| UI 样式模块 - CSS 样式定义 | |
| """ | |
| CSS = """ | |
| :root, | |
| .gradio-container { | |
| --rosa-bg: #f8fafc; | |
| --rosa-surface: #ffffff; | |
| --rosa-surface-2: #f1f5f9; | |
| --rosa-border: #e2e8f0; | |
| --rosa-border-soft: #cbd5e1; | |
| --rosa-text: #0f172a; | |
| --rosa-text-muted: #475569; | |
| --rosa-text-muted-2: #94a3b8; | |
| --rosa-code-active-bg: #dbeafe; | |
| --rosa-code-active-text: #1d4ed8; | |
| --rosa-code-token-bg: #fef3c7; | |
| --rosa-code-token-border: #f59e0b; | |
| --rosa-card-shadow: none; | |
| --rosa-float-bg: #f59e0b; | |
| --rosa-float-text: #1f2937; | |
| --rosa-legend-text: #475569; | |
| /* Code Highlight Colors (Light) */ | |
| --rosa-tok-keyword: #7c3aed; | |
| --rosa-tok-builtin: #0ea5e9; | |
| --rosa-tok-number: #f97316; | |
| --rosa-tok-string: #10b981; | |
| --rosa-tok-comment: #64748b; | |
| --rosa-blue: #3b82f6; | |
| --rosa-sky: #38bdf8; | |
| --rosa-violet: #a855f7; | |
| --rosa-amber: #f59e0b; | |
| --rosa-cyan: #06b6d4; | |
| --rosa-green: #22c55e; | |
| --rosa-green-soft: rgba(34, 197, 94, 0.16); | |
| --rosa-red: #ef4444; | |
| --rosa-red-soft: rgba(239, 68, 68, 0.14); | |
| --rosa-blue-soft: rgba(59, 130, 246, 0.08); | |
| --rosa-violet-soft: rgba(168, 85, 247, 0.08); | |
| } | |
| .rosa-theme-dark, | |
| :root.rosa-theme-dark { | |
| --rosa-bg: #0b1220; | |
| --rosa-surface: #0f172a; | |
| --rosa-surface-2: #1e293b; | |
| --rosa-border: #334155; | |
| --rosa-border-soft: #475569; | |
| --rosa-text: #f1f5f9; | |
| --rosa-text-muted: #cbd5e1; | |
| --rosa-text-muted-2: #94a3b8; | |
| --rosa-code-active-bg: rgba(59, 130, 246, 0.2); | |
| --rosa-code-active-text: #bfdbfe; | |
| --rosa-code-token-bg: rgba(245, 158, 11, 0.2); | |
| --rosa-code-token-border: #fbbf24; | |
| --rosa-card-shadow: 0 10px 28px rgba(0, 0, 0, 0.5); | |
| --rosa-float-bg: #fbbf24; | |
| --rosa-float-text: #111827; | |
| --rosa-legend-text: #cbd5e1; | |
| /* Code Highlight Colors (Dark) */ | |
| --rosa-tok-keyword: #c4b5fd; | |
| --rosa-tok-builtin: #7dd3fc; | |
| --rosa-tok-number: #fdba74; | |
| --rosa-tok-string: #6ee7b7; | |
| --rosa-tok-comment: #94a3b8; | |
| --rosa-blue: #60a5fa; | |
| --rosa-sky: #7dd3fc; | |
| --rosa-violet: #c084fc; | |
| --rosa-amber: #fbbf24; | |
| --rosa-cyan: #67e8f9; | |
| --rosa-green: #4ade80; | |
| --rosa-green-soft: rgba(74, 222, 128, 0.2); | |
| --rosa-red: #f87171; | |
| --rosa-red-soft: rgba(248, 113, 113, 0.2); | |
| --rosa-blue-soft: rgba(96, 165, 250, 0.2); | |
| --rosa-violet-soft: rgba(192, 132, 252, 0.2); | |
| } | |
| body, | |
| .gradio-container { | |
| background: var(--rosa-bg) !important; | |
| color: var(--rosa-text) !important; | |
| } | |
| .rosa-theme-dark { | |
| color-scheme: dark; | |
| } | |
| /* 覆盖 Gradio 内置 CSS 变量 */ | |
| :root, | |
| .gradio-container, | |
| .rosa-theme-dark, | |
| .rosa-theme-dark .gradio-container { | |
| --body-background-fill: var(--rosa-bg) !important; | |
| --block-background-fill: var(--rosa-surface) !important; | |
| --block-border-color: var(--rosa-border) !important; | |
| --block-label-background-fill: var(--rosa-surface) !important; | |
| --block-label-text-color: var(--rosa-text) !important; | |
| --block-title-text-color: var(--rosa-text) !important; | |
| --input-background-fill: var(--rosa-surface-2) !important; | |
| --input-border-color: var(--rosa-border) !important; | |
| --input-text-color: var(--rosa-text) !important; | |
| --body-text-color: var(--rosa-text) !important; | |
| --body-text-color-subdued: var(--rosa-text-muted) !important; | |
| --background-fill-primary: var(--rosa-surface) !important; | |
| --background-fill-secondary: var(--rosa-surface-2) !important; | |
| --border-color-primary: var(--rosa-border) !important; | |
| --border-color-accent: var(--rosa-blue) !important; | |
| --color-accent: var(--rosa-blue) !important; | |
| --color-accent-soft: var(--rosa-blue-soft) !important; | |
| --button-primary-background-fill: var(--rosa-blue) !important; | |
| --button-primary-text-color: #f8fafc !important; | |
| --button-secondary-background-fill: var(--rosa-surface-2) !important; | |
| --button-secondary-text-color: var(--rosa-text) !important; | |
| --button-secondary-border-color: var(--rosa-border) !important; | |
| --neutral-50: var(--rosa-surface) !important; | |
| --neutral-100: var(--rosa-surface-2) !important; | |
| --neutral-200: var(--rosa-border) !important; | |
| --neutral-300: var(--rosa-border-soft) !important; | |
| --neutral-400: var(--rosa-text-muted-2) !important; | |
| --neutral-500: var(--rosa-text-muted) !important; | |
| --neutral-600: var(--rosa-text-muted) !important; | |
| --neutral-700: var(--rosa-text) !important; | |
| --neutral-800: var(--rosa-text) !important; | |
| --neutral-900: var(--rosa-text) !important; | |
| --neutral-950: var(--rosa-text) !important; | |
| --panel-background-fill: var(--rosa-surface) !important; | |
| --checkbox-background-color: var(--rosa-surface-2) !important; | |
| --checkbox-border-color: var(--rosa-border) !important; | |
| --slider-color: var(--rosa-blue) !important; | |
| } | |
| /* Gradio 按钮 */ | |
| .gradio-container button:not(.secondary), | |
| .gradio-container .primary, | |
| .gradio-container button[variant="primary"] { | |
| background: var(--rosa-blue) !important; | |
| color: #f8fafc !important; | |
| border: 1px solid var(--rosa-blue) !important; | |
| } | |
| .gradio-container button.secondary, | |
| .gradio-container button:not([variant="primary"]):not(.primary) { | |
| background: var(--rosa-surface-2) !important; | |
| color: var(--rosa-text) !important; | |
| border: 1px solid var(--rosa-border) !important; | |
| } | |
| /* Gradio 输入框和文本区域 */ | |
| .gradio-container input[type="text"], | |
| .gradio-container input[type="number"], | |
| .gradio-container textarea { | |
| background: var(--rosa-surface-2) !important; | |
| color: var(--rosa-text) !important; | |
| border: 1px solid var(--rosa-border) !important; | |
| border-radius: 8px !important; | |
| font-family: inherit; | |
| } | |
| .gradio-container input[readonly], | |
| .gradio-container textarea[readonly], | |
| .gradio-container textarea[disabled] { | |
| background: var(--rosa-surface-2) !important; | |
| color: var(--rosa-text) !important; | |
| opacity: 1 !important; | |
| -webkit-text-fill-color: var(--rosa-text) !important; | |
| cursor: text !important; | |
| } | |
| .gradio-container ::placeholder, | |
| .gradio-container input::placeholder, | |
| .gradio-container textarea::placeholder { | |
| color: var(--rosa-text-muted) !important; | |
| opacity: 0.8; | |
| } | |
| .gradio-container input[type="text"]:focus, | |
| .gradio-container input[type="number"]:focus, | |
| .gradio-container textarea:focus { | |
| outline: none !important; | |
| border-color: var(--rosa-blue) !important; | |
| box-shadow: 0 0 0 2px var(--rosa-blue-soft) !important; | |
| } | |
| /* Gradio 滑块 */ | |
| .gradio-container input[type="range"] { | |
| accent-color: var(--rosa-blue); | |
| } | |
| .gradio-container .gr-box, | |
| .gradio-container .gr-panel, | |
| .gradio-container .gr-form { | |
| background: var(--rosa-surface) !important; | |
| border-color: var(--rosa-border) !important; | |
| } | |
| /* Gradio 标签 */ | |
| .gradio-container label, | |
| .gradio-container .label, | |
| .gradio-container span.label { | |
| color: var(--rosa-text) !important; | |
| } | |
| /* Gradio 输出框 */ | |
| .gradio-container .output-class, | |
| .gradio-container .gr-text-output { | |
| background: var(--rosa-surface-2) !important; | |
| color: var(--rosa-text) !important; | |
| border: 1px solid var(--rosa-border) !important; | |
| } | |
| /* Gradio checkbox */ | |
| .gradio-container input[type="checkbox"] { | |
| accent-color: var(--rosa-blue); | |
| } | |
| .page-header { | |
| text-align: center; | |
| margin-bottom: 18px; | |
| color: var(--rosa-text); | |
| } | |
| .rosa-hidden { | |
| display: none !important; | |
| } | |
| .page-title { | |
| font-size: 30px; | |
| font-weight: 700; | |
| letter-spacing: 0.4px; | |
| margin-bottom: 6px; | |
| } | |
| .page-subtitle { | |
| font-size: 14px; | |
| color: var(--rosa-text-muted); | |
| } | |
| .rosa-shell { | |
| display: flex; | |
| gap: 24px; | |
| align-items: flex-start; | |
| justify-content: center; | |
| flex-wrap: wrap; | |
| position: relative; | |
| } | |
| .rosa-pane { | |
| flex: 3 1 520px; | |
| min-width: 320px; | |
| } | |
| .rosa-code-pane { | |
| flex: 2 1 320px; | |
| min-width: 300px; | |
| } | |
| .quick-code-details { | |
| margin-top: 8px; | |
| } | |
| .quick-code-details > summary { | |
| cursor: pointer; | |
| user-select: none; | |
| padding: 8px 10px; | |
| border: 1px dashed var(--rosa-border-soft); | |
| border-radius: 12px; | |
| background: var(--rosa-surface); | |
| color: var(--rosa-text); | |
| font-weight: 600; | |
| } | |
| .quick-code-details[open] > summary { | |
| margin-bottom: 10px; | |
| } | |
| .quick-code-details > summary::-webkit-details-marker { | |
| display: none; | |
| } | |
| .quick-code-details .rosa-code { | |
| max-height: 420px; | |
| } | |
| #rosa-vis .rosa-card { | |
| background: var(--rosa-surface); | |
| border-radius: 18px; | |
| padding: 24px; | |
| color: var(--rosa-text); | |
| box-shadow: var(--rosa-card-shadow); | |
| border: 1px solid var(--rosa-border); | |
| text-align: center; | |
| position: relative; | |
| } | |
| #rosa-vis .rosa-rows { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 20px; | |
| align-items: center; | |
| } | |
| #rosa-vis .rosa-row { | |
| display: flex; | |
| align-items: center; | |
| gap: 14px; | |
| flex-wrap: wrap; | |
| justify-content: center; | |
| width: 100%; | |
| } | |
| #rosa-vis .rosa-row.k-row { | |
| margin-bottom: 0; | |
| } | |
| #rosa-vis .row-label { | |
| min-width: 36px; | |
| font-size: 12px; | |
| color: var(--rosa-text-muted); | |
| text-transform: uppercase; | |
| letter-spacing: 0.2px; | |
| text-align: center; | |
| } | |
| #rosa-vis .row-cells { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 6px; | |
| justify-content: center; | |
| max-width: 100%; | |
| min-width: 0; | |
| } | |
| #rosa-vis .cell { | |
| width: 30px; | |
| height: 30px; | |
| border-radius: 8px; | |
| background: var(--rosa-surface-2); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-weight: 600; | |
| transition: transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease, color 0.18s ease; | |
| color: var(--rosa-text); | |
| box-shadow: none; | |
| } | |
| #rosa-vis .cell.active { | |
| background: var(--rosa-blue); | |
| color: #f8fafc; | |
| box-shadow: none; | |
| } | |
| #rosa-vis .cell.suffix { | |
| background: var(--rosa-sky); | |
| color: #0b1220; | |
| } | |
| #rosa-vis .cell.k-window { | |
| background: var(--rosa-violet); | |
| color: #0b1220; | |
| } | |
| #rosa-vis .cell.v-pick { | |
| background: var(--rosa-amber); | |
| color: #1f2937; | |
| } | |
| #rosa-vis .cell.out, | |
| #rosa-vis .cell.out-fixed { | |
| background: var(--rosa-amber); | |
| color: #1f2937; | |
| } | |
| #rosa-vis .cell.filled { | |
| box-shadow: none; | |
| } | |
| #rosa-vis .rosa-overlay { | |
| position: absolute; | |
| inset: 0; | |
| pointer-events: none; | |
| z-index: 5; | |
| } | |
| #rosa-vis .overlay-svg { | |
| position: absolute; | |
| inset: 0; | |
| width: 100%; | |
| height: 100%; | |
| pointer-events: none; | |
| } | |
| #rosa-vis .overlay-box-layer { | |
| position: absolute; | |
| inset: 0; | |
| pointer-events: none; | |
| } | |
| #rosa-vis .overlay-box { | |
| position: absolute; | |
| border: 2px solid var(--rosa-blue); | |
| border-radius: 10px; | |
| box-shadow: 0 6px 16px rgba(15, 23, 42, 0.16); | |
| box-sizing: border-box; | |
| background: transparent; | |
| transition: border-color 0.18s ease, background 0.18s ease; | |
| } | |
| #rosa-vis .overlay-hover-layer { | |
| position: absolute; | |
| inset: 0; | |
| pointer-events: auto; | |
| z-index: 6; | |
| } | |
| #rosa-vis .overlay-hover-box { | |
| position: absolute; | |
| background: transparent; | |
| pointer-events: auto; | |
| cursor: pointer; | |
| } | |
| #rosa-vis .overlay-box[data-label="t"] { | |
| --overlay-label: "t"; | |
| } | |
| #rosa-vis .overlay-box[data-label="kkk[j:j+w]"] { | |
| --overlay-label: "kkk[j:j+w]"; | |
| } | |
| #rosa-vis .overlay-box.t-box { | |
| border-color: var(--rosa-blue); | |
| background: var(--rosa-blue-soft); | |
| } | |
| #rosa-vis .overlay-box.k-box { | |
| border-color: var(--rosa-violet); | |
| background: var(--rosa-violet-soft); | |
| } | |
| #rosa-vis .overlay-box.try-match { | |
| border-color: var(--rosa-green); | |
| background: var(--rosa-green-soft); | |
| } | |
| #rosa-vis .overlay-box.try-miss { | |
| border-color: var(--rosa-red); | |
| background: var(--rosa-red-soft); | |
| } | |
| #rosa-vis .overlay-ray { | |
| position: absolute; | |
| inset: 0; | |
| width: 100%; | |
| height: 100%; | |
| pointer-events: none; | |
| } | |
| #rosa-vis .overlay-ray-line { | |
| stroke: var(--rosa-cyan); | |
| stroke-width: 2; | |
| fill: none; | |
| stroke-linecap: round; | |
| } | |
| #rosa-vis .overlay-label { | |
| position: absolute; | |
| top: -12px; | |
| right: 0; | |
| font-size: 11px; | |
| padding: 0; | |
| background: transparent; | |
| color: var(--rosa-text); | |
| letter-spacing: 0.2px; | |
| white-space: nowrap; | |
| display: none; | |
| } | |
| #rosa-vis .overlay-label.t-label { | |
| color: var(--rosa-blue); | |
| } | |
| #rosa-vis .overlay-label.k-label { | |
| color: var(--rosa-violet); | |
| } | |
| .v-float { | |
| position: fixed; | |
| z-index: 9999; | |
| border-radius: 8px; | |
| background: var(--rosa-float-bg); | |
| color: var(--rosa-float-text); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-weight: 600; | |
| box-shadow: 0 10px 24px rgba(15, 23, 42, 0.2); | |
| pointer-events: none; | |
| transition: transform 0.35s ease, opacity 0.35s ease; | |
| opacity: 1; | |
| } | |
| #rosa-vis .rosa-legend { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 12px; | |
| margin-bottom: 12px; | |
| font-size: 12px; | |
| color: var(--rosa-legend-text); | |
| justify-content: center; | |
| } | |
| #rosa-vis .legend-item { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 6px; | |
| } | |
| #rosa-vis .legend-dot { | |
| width: 12px; | |
| height: 12px; | |
| border-radius: 4px; | |
| } | |
| #rosa-vis .legend-suffix { | |
| background: var(--rosa-sky); | |
| } | |
| #rosa-vis .legend-window { | |
| background: var(--rosa-violet); | |
| } | |
| #rosa-vis .legend-match { | |
| background: var(--rosa-green); | |
| } | |
| #rosa-vis .legend-v { | |
| background: var(--rosa-amber); | |
| } | |
| #rosa-vis .legend-out { | |
| background: var(--rosa-amber); | |
| } | |
| #rosa-vis .index-row { | |
| padding-bottom: 8px; | |
| border-bottom: 1px dashed var(--rosa-border); | |
| } | |
| #rosa-vis .index-cells { | |
| gap: 6px; | |
| } | |
| #rosa-vis .index-cell { | |
| width: 30px; | |
| text-align: center; | |
| font-size: 11px; | |
| color: var(--rosa-text-muted-2); | |
| font-variant-numeric: tabular-nums; | |
| } | |
| .rosa-code { | |
| background: var(--rosa-surface); | |
| border: 1px solid var(--rosa-border); | |
| border-radius: 12px; | |
| padding: 12px; | |
| font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; | |
| font-size: 12px; | |
| color: var(--rosa-text); | |
| max-height: 520px; | |
| overflow: auto; | |
| } | |
| .rosa-code .code-line { | |
| display: flex; | |
| gap: 10px; | |
| padding: 2px 6px; | |
| border-radius: 6px; | |
| } | |
| .rosa-code .line-no { | |
| flex: 0 0 36px; | |
| width: 36px; | |
| text-align: left; | |
| color: var(--rosa-text-muted-2); | |
| user-select: none; | |
| font-variant-numeric: tabular-nums; | |
| } | |
| .rosa-code .line-text { | |
| white-space: pre; | |
| flex: 1; | |
| } | |
| .rosa-code .code-line.active { | |
| background: var(--rosa-code-active-bg); | |
| color: var(--rosa-code-active-text); | |
| } | |
| .rosa-code .code-line.active .line-no { | |
| color: var(--rosa-code-active-text); | |
| } | |
| .rosa-code .tok-keyword { | |
| color: var(--rosa-tok-keyword); | |
| font-weight: 600; | |
| } | |
| .rosa-code .tok-builtin { | |
| color: var(--rosa-tok-builtin); | |
| } | |
| .rosa-code .tok-number { | |
| color: var(--rosa-tok-number); | |
| } | |
| .rosa-code .tok-string { | |
| color: var(--rosa-tok-string); | |
| } | |
| .rosa-code .tok-comment { | |
| color: var(--rosa-tok-comment); | |
| font-style: italic; | |
| } | |
| .rosa-code .code-token { | |
| border-bottom: 1px dashed var(--rosa-text-muted-2); | |
| padding: 0 1px; | |
| } | |
| .rosa-code .code-token.active { | |
| background: var(--rosa-code-token-bg); | |
| border-radius: 4px; | |
| border-bottom-color: var(--rosa-code-token-border); | |
| } | |
| """ | |