fix(observability): 導入標題尺度 token 與 modal 樣式
Some checks failed
CD Pipeline / deploy (push) Has been cancelled

This commit is contained in:
OoO
2026-05-05 14:54:17 +08:00
parent 668d98cd3c
commit ccd26415f3
9 changed files with 26 additions and 15 deletions

View File

@@ -19,6 +19,8 @@
--obs-shadow: 0 18px 44px rgba(70, 46, 28, 0.09);
--obs-dot:
radial-gradient(circle, rgba(201, 100, 66, 0.18) 1px, transparent 1.3px);
--obs-title-size: clamp(1.9rem, 3.2vw, 2.75rem);
--obs-value-size: clamp(1.45rem, 2.8vw, 2.25rem);
}
.momo-observability-mode .momo-content {
@@ -581,6 +583,15 @@
height: 8px;
}
.momo-observability-mode .obs-modal-preview {
border: 1px solid rgba(201, 100, 66, 0.14);
border-radius: 14px;
background:
linear-gradient(135deg, rgba(255, 252, 247, 0.94), rgba(255, 248, 241, 0.84)),
var(--obs-dot);
background-size: auto, 13px 13px;
}
.momo-observability-mode .quality-distribution-cell {
width: 200px;
}

View File

@@ -5,7 +5,7 @@
{% block ewooo_content %}
<style>
.agent-hero,.agent-panel,.agent-table-shell{border:1px solid var(--obs-line);border-radius:26px;background:var(--obs-card);box-shadow:0 16px 38px rgba(70,46,28,.08)}
.agent-hero{padding:clamp(1.2rem,2.4vw,2rem);background:radial-gradient(circle at 12% 14%,rgba(201,100,66,.18),transparent 24rem),radial-gradient(circle at 88% 8%,rgba(79,111,143,.14),transparent 22rem),linear-gradient(135deg,rgba(255,248,239,.98),rgba(255,255,255,.74))}.agent-kicker{color:var(--obs-accent);font-size:.76rem;letter-spacing:.13em;text-transform:uppercase;font-weight:850}.agent-title{margin:.45rem 0 .25rem;font-family:'Noto Sans TC','Inter',sans-serif;font-size:clamp(2rem,4vw,3.8rem);letter-spacing:-.055em;line-height:.98}.agent-subtitle{color:var(--obs-muted);max-width:870px;line-height:1.7}.agent-filter{display:flex;gap:.55rem;flex-wrap:wrap;margin-top:1rem;padding:.8rem;border:1px solid var(--obs-line);border-radius:20px;background:rgba(255,255,255,.58)}.agent-command{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.75rem;margin-top:1rem}.agent-signal{padding:.95rem;border:1px solid var(--obs-line);border-radius:20px;background:rgba(255,255,255,.62)}.agent-label{color:var(--obs-muted);font-size:.72rem;letter-spacing:.1em;text-transform:uppercase}.agent-value{display:block;margin-top:.28rem;font-size:clamp(1.45rem,2.8vw,2.35rem);font-weight:880;letter-spacing:-.045em}.agent-grid{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(330px,.8fr);gap:1rem;margin-top:1rem}.agent-stack{display:grid;gap:1rem}.agent-panel-head,.agent-table-title{display:flex;justify-content:space-between;align-items:flex-start;gap:1rem;padding:1.05rem 1.1rem .25rem}.agent-panel-title,.agent-table-title h3{margin:.15rem 0 0;font-size:1.1rem;font-weight:850;letter-spacing:-.025em}.agent-panel-body{padding:1rem 1.1rem 1.1rem}.agent-table-shell{overflow:hidden;margin-top:1rem}.agent-card{padding:.9rem;border:1px solid var(--obs-line);border-radius:20px;background:rgba(255,255,255,.58);margin-bottom:.75rem}.agent-card-top{display:flex;justify-content:space-between;gap:.8rem;align-items:start}.agent-meter{height:7px;border-radius:999px;background:rgba(86,64,48,.1);overflow:hidden;margin-top:.65rem}.agent-meter span{display:block;height:100%;background:var(--obs-accent)}.rec-card{padding:.85rem;border:1px solid var(--obs-line);border-radius:18px;background:rgba(255,255,255,.58);margin-bottom:.7rem}.status-good{color:var(--obs-green)}.status-warn{color:var(--obs-amber)}.status-bad{color:var(--obs-red)}.status-blue{color:var(--obs-blue)}@media(max-width:1100px){.agent-command{grid-template-columns:repeat(2,minmax(0,1fr))}.agent-grid{grid-template-columns:1fr}}@media(max-width:720px){.agent-command{grid-template-columns:1fr}}
.agent-hero{padding:clamp(1.2rem,2.4vw,2rem);background:radial-gradient(circle at 12% 14%,rgba(201,100,66,.18),transparent 24rem),radial-gradient(circle at 88% 8%,rgba(79,111,143,.14),transparent 22rem),linear-gradient(135deg,rgba(255,248,239,.98),rgba(255,255,255,.74))}.agent-kicker{color:var(--obs-accent);font-size:.76rem;letter-spacing:.13em;text-transform:uppercase;font-weight:850}.agent-title{margin:.45rem 0 .25rem;font-family:'Noto Sans TC','Inter',sans-serif;font-size:var(--obs-title-size);letter-spacing:-.055em;line-height:.98}.agent-subtitle{color:var(--obs-muted);max-width:870px;line-height:1.7}.agent-filter{display:flex;gap:.55rem;flex-wrap:wrap;margin-top:1rem;padding:.8rem;border:1px solid var(--obs-line);border-radius:20px;background:rgba(255,255,255,.58)}.agent-command{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.75rem;margin-top:1rem}.agent-signal{padding:.95rem;border:1px solid var(--obs-line);border-radius:20px;background:rgba(255,255,255,.62)}.agent-label{color:var(--obs-muted);font-size:.72rem;letter-spacing:.1em;text-transform:uppercase}.agent-value{display:block;margin-top:.28rem;font-size:var(--obs-value-size);font-weight:880;letter-spacing:-.045em}.agent-grid{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(330px,.8fr);gap:1rem;margin-top:1rem}.agent-stack{display:grid;gap:1rem}.agent-panel-head,.agent-table-title{display:flex;justify-content:space-between;align-items:flex-start;gap:1rem;padding:1.05rem 1.1rem .25rem}.agent-panel-title,.agent-table-title h3{margin:.15rem 0 0;font-size:1.1rem;font-weight:850;letter-spacing:-.025em}.agent-panel-body{padding:1rem 1.1rem 1.1rem}.agent-table-shell{overflow:hidden;margin-top:1rem}.agent-card{padding:.9rem;border:1px solid var(--obs-line);border-radius:20px;background:rgba(255,255,255,.58);margin-bottom:.75rem}.agent-card-top{display:flex;justify-content:space-between;gap:.8rem;align-items:start}.agent-meter{height:7px;border-radius:999px;background:rgba(86,64,48,.1);overflow:hidden;margin-top:.65rem}.agent-meter span{display:block;height:100%;background:var(--obs-accent)}.rec-card{padding:.85rem;border:1px solid var(--obs-line);border-radius:18px;background:rgba(255,255,255,.58);margin-bottom:.7rem}.status-good{color:var(--obs-green)}.status-warn{color:var(--obs-amber)}.status-bad{color:var(--obs-red)}.status-blue{color:var(--obs-blue)}@media(max-width:1100px){.agent-command{grid-template-columns:repeat(2,minmax(0,1fr))}.agent-grid{grid-template-columns:1fr}}@media(max-width:720px){.agent-command{grid-template-columns:1fr}}
</style>
<div class="container-fluid mt-3">

View File

@@ -18,14 +18,14 @@
linear-gradient(135deg, rgba(255,248,239,.98), rgba(255,255,255,.72));
}
.calls-kicker { color: var(--obs-accent); font-size:.76rem; letter-spacing:.13em; text-transform:uppercase; font-weight:800; }
.calls-title { margin:.45rem 0 .25rem; font-family:'Noto Sans TC','Inter',sans-serif; font-size:clamp(2rem,4vw,3.8rem); letter-spacing:-.055em; line-height:.98; }
.calls-title { margin:.45rem 0 .25rem; font-family:'Noto Sans TC','Inter',sans-serif; font-size:var(--obs-title-size); letter-spacing:-.055em; line-height:.98; }
.calls-subtitle { color:var(--obs-muted); max-width:830px; line-height:1.7; }
.calls-actions { display:flex; flex-wrap:wrap; gap:.6rem; margin-top:1rem; align-items:center; }
.calls-filter { display:flex; flex-wrap:wrap; gap:.5rem; padding:.8rem; border:1px solid var(--obs-line); border-radius:20px; background:rgba(255,255,255,.58); }
.calls-command { display:grid; grid-template-columns:repeat(6,minmax(0,1fr)); gap:.75rem; margin-top:1rem; }
.calls-signal { padding:.9rem; border:1px solid var(--obs-line); border-radius:20px; background:rgba(255,255,255,.62); min-height:116px; }
.calls-label { color:var(--obs-muted); font-size:.72rem; letter-spacing:.1em; text-transform:uppercase; }
.calls-value { display:block; margin-top:.28rem; font-size:clamp(1.35rem,2.5vw,2.1rem); font-weight:880; letter-spacing:-.045em; }
.calls-value { display:block; margin-top:.28rem; font-size:var(--obs-value-size); font-weight:880; letter-spacing:-.045em; }
.calls-note { color:var(--obs-muted); font-size:.8rem; margin-top:.25rem; }
.calls-grid { display:grid; grid-template-columns:minmax(0,1.25fr) minmax(330px,.75fr); gap:1rem; margin-top:1rem; }
.calls-stack { display:grid; gap:1rem; }

View File

@@ -7,13 +7,13 @@
.gov-hero, .gov-panel, .gov-table-shell { border:1px solid var(--obs-line); border-radius:26px; background:var(--obs-card); box-shadow:0 16px 38px rgba(70,46,28,.08); }
.gov-hero { padding:clamp(1.2rem,2.4vw,2rem); background:radial-gradient(circle at 12% 14%, rgba(201,100,66,.18), transparent 24rem), radial-gradient(circle at 90% 8%, rgba(184,121,47,.16), transparent 22rem), linear-gradient(135deg,rgba(255,248,239,.98),rgba(255,255,255,.74)); }
.gov-kicker { color:var(--obs-accent); font-size:.76rem; letter-spacing:.13em; text-transform:uppercase; font-weight:850; }
.gov-title { margin:.45rem 0 .25rem; font-family:'Noto Sans TC','Inter',sans-serif; font-size:clamp(2rem,4vw,3.8rem); letter-spacing:-.055em; line-height:.98; }
.gov-title { margin:.45rem 0 .25rem; font-family:'Noto Sans TC','Inter',sans-serif; font-size:var(--obs-title-size); letter-spacing:-.055em; line-height:.98; }
.gov-subtitle { color:var(--obs-muted); max-width:850px; line-height:1.7; }
.gov-actions { display:flex; flex-wrap:wrap; gap:.6rem; align-items:center; margin-top:1rem; }
.gov-command { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:.75rem; margin-top:1rem; }
.gov-signal { padding:.95rem; border:1px solid var(--obs-line); border-radius:20px; background:rgba(255,255,255,.62); }
.gov-label { color:var(--obs-muted); font-size:.72rem; letter-spacing:.1em; text-transform:uppercase; }
.gov-value { display:block; margin-top:.28rem; font-size:clamp(1.45rem,2.8vw,2.35rem); font-weight:880; letter-spacing:-.045em; }
.gov-value { display:block; margin-top:.28rem; font-size:var(--obs-value-size); font-weight:880; letter-spacing:-.045em; }
.gov-note { color:var(--obs-muted); font-size:.8rem; margin-top:.25rem; }
.gov-grid { display:grid; grid-template-columns:minmax(0,1.18fr) minmax(330px,.82fr); gap:1rem; margin-top:1rem; }
.gov-stack { display:grid; gap:1rem; }

View File

@@ -18,12 +18,12 @@
linear-gradient(135deg, rgba(255, 248, 239, 0.98), rgba(255, 255, 255, 0.72));
}
.runtime-kicker { color: var(--obs-accent); font-size: .76rem; letter-spacing: .13em; text-transform: uppercase; font-weight: 800; }
.runtime-title { margin: .45rem 0 .25rem; font-family:'Noto Sans TC','Inter',sans-serif; font-size: clamp(2rem, 4vw, 3.8rem); letter-spacing: -.055em; line-height: .98; }
.runtime-title { margin: .45rem 0 .25rem; font-family:'Noto Sans TC','Inter',sans-serif; font-size:var(--obs-title-size); letter-spacing: -.055em; line-height: .98; }
.runtime-subtitle { color: var(--obs-muted); max-width: 820px; line-height: 1.7; }
.runtime-command { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .8rem; margin-top: 1.2rem; }
.runtime-signal { padding: .95rem; border: 1px solid var(--obs-line); border-radius: 20px; background: rgba(255,255,255,.62); }
.runtime-label { color: var(--obs-muted); font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; }
.runtime-value { display: block; margin-top: .28rem; font-size: clamp(1.65rem, 3vw, 2.45rem); font-weight: 880; letter-spacing: -.045em; }
.runtime-value { display: block; margin-top: .28rem; font-size:var(--obs-value-size); font-weight: 880; letter-spacing: -.045em; }
.runtime-main { display: grid; grid-template-columns: minmax(0, 1.22fr) minmax(330px, .78fr); gap: 1rem; margin-top: 1rem; }
.runtime-stack { display: grid; gap: 1rem; }
.runtime-panel-head { display:flex; justify-content:space-between; align-items:flex-start; gap:1rem; padding:1.05rem 1.1rem .2rem; }

View File

@@ -5,7 +5,7 @@
{% block ewooo_content %}
<style>
.ppt-hero,.ppt-panel,.ppt-table-shell{border:1px solid var(--obs-line);border-radius:26px;background:var(--obs-card);box-shadow:0 16px 38px rgba(70,46,28,.08)}
.ppt-hero{padding:clamp(1.2rem,2.4vw,2rem);background:radial-gradient(circle at 12% 14%,rgba(201,100,66,.18),transparent 24rem),radial-gradient(circle at 88% 8%,rgba(79,111,143,.14),transparent 22rem),linear-gradient(135deg,rgba(255,248,239,.98),rgba(255,255,255,.74))}.ppt-kicker{color:var(--obs-accent);font-size:.76rem;letter-spacing:.13em;text-transform:uppercase;font-weight:850}.ppt-title{margin:.45rem 0 .25rem;font-family:'Noto Sans TC','Inter',sans-serif;font-size:clamp(2rem,4vw,3.8rem);letter-spacing:-.055em;line-height:.98}.ppt-subtitle{color:var(--obs-muted);max-width:860px;line-height:1.7}.ppt-command{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.75rem;margin-top:1rem}.ppt-signal{padding:.95rem;border:1px solid var(--obs-line);border-radius:20px;background:rgba(255,255,255,.62)}.ppt-label{color:var(--obs-muted);font-size:.72rem;letter-spacing:.1em;text-transform:uppercase}.ppt-value{display:block;margin-top:.28rem;font-size:clamp(1.45rem,2.8vw,2.35rem);font-weight:880;letter-spacing:-.045em}.ppt-grid{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(330px,.8fr);gap:1rem;margin-top:1rem}.ppt-stack{display:grid;gap:1rem}.ppt-panel-head,.ppt-table-title{display:flex;justify-content:space-between;align-items:flex-start;gap:1rem;padding:1.05rem 1.1rem .25rem}.ppt-panel-title,.ppt-table-title h3{margin:.15rem 0 0;font-size:1.1rem;font-weight:850;letter-spacing:-.025em}.ppt-panel-body{padding:1rem 1.1rem 1.1rem}.ppt-table-shell{overflow:hidden;margin-top:1rem}.ppt-mini-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.7rem}.ppt-mini{padding:.85rem;border:1px solid var(--obs-line);border-radius:18px;background:rgba(255,255,255,.58)}.ppt-mini strong{display:block;margin-top:.24rem;font-size:1.35rem;letter-spacing:-.04em}.fix-card{padding:.85rem;border:1px solid var(--obs-line);border-radius:18px;background:rgba(255,255,255,.58);margin-bottom:.7rem}.status-good{color:var(--obs-green)}.status-warn{color:var(--obs-amber)}.status-bad{color:var(--obs-red)}.status-blue{color:var(--obs-blue)}@media(max-width:1100px){.ppt-command{grid-template-columns:repeat(2,minmax(0,1fr))}.ppt-grid{grid-template-columns:1fr}}@media(max-width:720px){.ppt-command,.ppt-mini-grid{grid-template-columns:1fr}}
.ppt-hero{padding:clamp(1.2rem,2.4vw,2rem);background:radial-gradient(circle at 12% 14%,rgba(201,100,66,.18),transparent 24rem),radial-gradient(circle at 88% 8%,rgba(79,111,143,.14),transparent 22rem),linear-gradient(135deg,rgba(255,248,239,.98),rgba(255,255,255,.74))}.ppt-kicker{color:var(--obs-accent);font-size:.76rem;letter-spacing:.13em;text-transform:uppercase;font-weight:850}.ppt-title{margin:.45rem 0 .25rem;font-family:'Noto Sans TC','Inter',sans-serif;font-size:var(--obs-title-size);letter-spacing:-.055em;line-height:.98}.ppt-subtitle{color:var(--obs-muted);max-width:860px;line-height:1.7}.ppt-command{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.75rem;margin-top:1rem}.ppt-signal{padding:.95rem;border:1px solid var(--obs-line);border-radius:20px;background:rgba(255,255,255,.62)}.ppt-label{color:var(--obs-muted);font-size:.72rem;letter-spacing:.1em;text-transform:uppercase}.ppt-value{display:block;margin-top:.28rem;font-size:var(--obs-value-size);font-weight:880;letter-spacing:-.045em}.ppt-grid{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(330px,.8fr);gap:1rem;margin-top:1rem}.ppt-stack{display:grid;gap:1rem}.ppt-panel-head,.ppt-table-title{display:flex;justify-content:space-between;align-items:flex-start;gap:1rem;padding:1.05rem 1.1rem .25rem}.ppt-panel-title,.ppt-table-title h3{margin:.15rem 0 0;font-size:1.1rem;font-weight:850;letter-spacing:-.025em}.ppt-panel-body{padding:1rem 1.1rem 1.1rem}.ppt-table-shell{overflow:hidden;margin-top:1rem}.ppt-mini-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.7rem}.ppt-mini{padding:.85rem;border:1px solid var(--obs-line);border-radius:18px;background:rgba(255,255,255,.58)}.ppt-mini strong{display:block;margin-top:.24rem;font-size:1.35rem;letter-spacing:-.04em}.fix-card{padding:.85rem;border:1px solid var(--obs-line);border-radius:18px;background:rgba(255,255,255,.58);margin-bottom:.7rem}.status-good{color:var(--obs-green)}.status-warn{color:var(--obs-amber)}.status-bad{color:var(--obs-red)}.status-blue{color:var(--obs-blue)}@media(max-width:1100px){.ppt-command{grid-template-columns:repeat(2,minmax(0,1fr))}.ppt-grid{grid-template-columns:1fr}}@media(max-width:720px){.ppt-command,.ppt-mini-grid{grid-template-columns:1fr}}
</style>
<div class="container-fluid mt-3">

View File

@@ -7,12 +7,12 @@
.gate-hero, .gate-panel, .gate-table-shell, .episode-card { border:1px solid var(--obs-line); border-radius:26px; background:var(--obs-card); box-shadow:0 16px 38px rgba(70,46,28,.08); }
.gate-hero { padding:clamp(1.2rem,2.4vw,2rem); background:radial-gradient(circle at 12% 14%, rgba(201,100,66,.18), transparent 24rem), radial-gradient(circle at 88% 8%, rgba(79,111,143,.14), transparent 22rem), linear-gradient(135deg,rgba(255,248,239,.98),rgba(255,255,255,.74)); }
.gate-kicker { color:var(--obs-accent); font-size:.76rem; letter-spacing:.13em; text-transform:uppercase; font-weight:850; }
.gate-title { margin:.45rem 0 .25rem; font-family:'Noto Sans TC','Inter',sans-serif; font-size:clamp(2rem,4vw,3.8rem); letter-spacing:-.055em; line-height:.98; }
.gate-title { margin:.45rem 0 .25rem; font-family:'Noto Sans TC','Inter',sans-serif; font-size:var(--obs-title-size); letter-spacing:-.055em; line-height:.98; }
.gate-subtitle { color:var(--obs-muted); max-width:880px; line-height:1.7; }
.gate-command { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:.75rem; margin-top:1rem; }
.gate-signal { padding:.95rem; border:1px solid var(--obs-line); border-radius:20px; background:rgba(255,255,255,.62); }
.gate-label { color:var(--obs-muted); font-size:.72rem; letter-spacing:.1em; text-transform:uppercase; }
.gate-value { display:block; margin-top:.28rem; font-size:clamp(1.45rem,2.8vw,2.35rem); font-weight:880; letter-spacing:-.045em; }
.gate-value { display:block; margin-top:.28rem; font-size:var(--obs-value-size); font-weight:880; letter-spacing:-.045em; }
.gate-grid { display:grid; grid-template-columns:minmax(0,1.16fr) minmax(330px,.84fr); gap:1rem; margin-top:1rem; }
.gate-stack { display:grid; gap:1rem; }
.gate-panel-head, .gate-table-title { display:flex; justify-content:space-between; align-items:flex-start; gap:1rem; padding:1.05rem 1.1rem .25rem; }

View File

@@ -6,8 +6,8 @@
<style>
.quality-hero,.quality-panel,.quality-table-shell{border:1px solid var(--obs-line);border-radius:26px;background:var(--obs-card);box-shadow:0 16px 38px rgba(70,46,28,.08)}
.quality-hero{padding:clamp(1.2rem,2.4vw,2rem);background:radial-gradient(circle at 12% 14%,rgba(201,100,66,.18),transparent 24rem),radial-gradient(circle at 88% 8%,rgba(79,111,143,.14),transparent 22rem),linear-gradient(135deg,rgba(255,248,239,.98),rgba(255,255,255,.74))}
.quality-kicker{color:var(--obs-accent);font-size:.76rem;letter-spacing:.13em;text-transform:uppercase;font-weight:850}.quality-title{margin:.45rem 0 .25rem;font-family:'Noto Sans TC','Inter',sans-serif;font-size:clamp(2rem,4vw,3.8rem);letter-spacing:-.055em;line-height:.98}.quality-subtitle{color:var(--obs-muted);max-width:860px;line-height:1.7}
.quality-filter{display:flex;gap:.55rem;flex-wrap:wrap;margin-top:1rem;padding:.8rem;border:1px solid var(--obs-line);border-radius:20px;background:rgba(255,255,255,.58)}.quality-command{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.75rem;margin-top:1rem}.quality-signal{padding:.95rem;border:1px solid var(--obs-line);border-radius:20px;background:rgba(255,255,255,.62)}.quality-label{color:var(--obs-muted);font-size:.72rem;letter-spacing:.1em;text-transform:uppercase}.quality-value{display:block;margin-top:.28rem;font-size:clamp(1.45rem,2.8vw,2.35rem);font-weight:880;letter-spacing:-.045em}
.quality-kicker{color:var(--obs-accent);font-size:.76rem;letter-spacing:.13em;text-transform:uppercase;font-weight:850}.quality-title{margin:.45rem 0 .25rem;font-family:'Noto Sans TC','Inter',sans-serif;font-size:var(--obs-title-size);letter-spacing:-.055em;line-height:.98}.quality-subtitle{color:var(--obs-muted);max-width:860px;line-height:1.7}
.quality-filter{display:flex;gap:.55rem;flex-wrap:wrap;margin-top:1rem;padding:.8rem;border:1px solid var(--obs-line);border-radius:20px;background:rgba(255,255,255,.58)}.quality-command{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.75rem;margin-top:1rem}.quality-signal{padding:.95rem;border:1px solid var(--obs-line);border-radius:20px;background:rgba(255,255,255,.62)}.quality-label{color:var(--obs-muted);font-size:.72rem;letter-spacing:.1em;text-transform:uppercase}.quality-value{display:block;margin-top:.28rem;font-size:var(--obs-value-size);font-weight:880;letter-spacing:-.045em}
.quality-grid{display:grid;grid-template-columns:minmax(0,1.18fr) minmax(330px,.82fr);gap:1rem;margin-top:1rem}.quality-stack{display:grid;gap:1rem}.quality-panel-head,.quality-table-title{display:flex;justify-content:space-between;align-items:flex-start;gap:1rem;padding:1.05rem 1.1rem .25rem}.quality-panel-title,.quality-table-title h3{margin:.15rem 0 0;font-size:1.1rem;font-weight:850;letter-spacing:-.025em}.quality-panel-body{padding:1rem 1.1rem 1.1rem}.quality-table-shell{overflow:hidden;margin-top:1rem}.quality-mini-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.7rem}.quality-mini{padding:.85rem;border:1px solid var(--obs-line);border-radius:18px;background:rgba(255,255,255,.58)}.quality-mini strong{display:block;margin-top:.24rem;font-size:1.35rem;letter-spacing:-.04em}.root-card{padding:.85rem;border:1px solid var(--obs-line);border-radius:18px;background:rgba(255,255,255,.58);margin-bottom:.7rem}.status-good{color:var(--obs-green)}.status-warn{color:var(--obs-amber)}.status-bad{color:var(--obs-red)}.status-blue{color:var(--obs-blue)}
@media(max-width:1100px){.quality-command{grid-template-columns:repeat(2,minmax(0,1fr))}.quality-grid{grid-template-columns:1fr}}@media(max-width:720px){.quality-command,.quality-mini-grid{grid-template-columns:1fr}}
</style>

View File

@@ -6,9 +6,9 @@
<style>
.qa-hero,.qa-panel,.qa-table-shell{border:1px solid var(--obs-line);border-radius:26px;background:var(--obs-card);box-shadow:0 16px 38px rgba(70,46,28,.08)}
.qa-hero{padding:clamp(1.2rem,2.4vw,2rem);background:radial-gradient(circle at 12% 14%,rgba(201,100,66,.18),transparent 24rem),radial-gradient(circle at 88% 8%,rgba(79,111,143,.14),transparent 22rem),linear-gradient(135deg,rgba(255,248,239,.98),rgba(255,255,255,.74))}
.qa-kicker{color:var(--obs-accent);font-size:.76rem;letter-spacing:.13em;text-transform:uppercase;font-weight:850}.qa-title{margin:.45rem 0 .25rem;font-family:'Noto Sans TC','Inter',sans-serif;font-size:clamp(2rem,4vw,3.8rem);letter-spacing:-.055em;line-height:.98}.qa-subtitle{color:var(--obs-muted);max-width:860px;line-height:1.7}
.qa-kicker{color:var(--obs-accent);font-size:.76rem;letter-spacing:.13em;text-transform:uppercase;font-weight:850}.qa-title{margin:.45rem 0 .25rem;font-family:'Noto Sans TC','Inter',sans-serif;font-size:var(--obs-title-size);letter-spacing:-.055em;line-height:.98}.qa-subtitle{color:var(--obs-muted);max-width:860px;line-height:1.7}
.qa-filter{display:flex;flex-wrap:wrap;gap:.55rem;margin-top:1rem;padding:.8rem;border:1px solid var(--obs-line);border-radius:20px;background:rgba(255,255,255,.58)}
.qa-command{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.75rem;margin-top:1rem}.qa-signal{padding:.95rem;border:1px solid var(--obs-line);border-radius:20px;background:rgba(255,255,255,.62)}.qa-label{color:var(--obs-muted);font-size:.72rem;letter-spacing:.1em;text-transform:uppercase}.qa-value{display:block;margin-top:.28rem;font-size:clamp(1.45rem,2.8vw,2.35rem);font-weight:880;letter-spacing:-.045em}.qa-note{color:var(--obs-muted);font-size:.8rem;margin-top:.25rem}
.qa-command{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.75rem;margin-top:1rem}.qa-signal{padding:.95rem;border:1px solid var(--obs-line);border-radius:20px;background:rgba(255,255,255,.62)}.qa-label{color:var(--obs-muted);font-size:.72rem;letter-spacing:.1em;text-transform:uppercase}.qa-value{display:block;margin-top:.28rem;font-size:var(--obs-value-size);font-weight:880;letter-spacing:-.045em}.qa-note{color:var(--obs-muted);font-size:.8rem;margin-top:.25rem}
.qa-grid{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(330px,.8fr);gap:1rem;margin-top:1rem}.qa-stack{display:grid;gap:1rem}.qa-panel-head,.qa-table-title{display:flex;justify-content:space-between;align-items:flex-start;gap:1rem;padding:1.05rem 1.1rem .25rem}.qa-panel-title,.qa-table-title h3{margin:.15rem 0 0;font-size:1.1rem;font-weight:850;letter-spacing:-.025em}.qa-panel-body{padding:1rem 1.1rem 1.1rem}.qa-table-shell{overflow:hidden;margin-top:1rem}.status-good{color:var(--obs-green)}.status-warn{color:var(--obs-amber)}.status-bad{color:var(--obs-red)}.status-blue{color:var(--obs-blue)}
.caller-card{padding:.85rem;border:1px solid var(--obs-line);border-radius:18px;background:rgba(255,255,255,.58);margin-bottom:.65rem}.caller-top{display:flex;justify-content:space-between;gap:.8rem}.caller-meter{height:7px;border-radius:999px;background:rgba(86,64,48,.1);overflow:hidden;margin-top:.55rem}.caller-meter span{display:block;height:100%;background:var(--obs-accent)}
@media(max-width:1100px){.qa-command{grid-template-columns:repeat(2,minmax(0,1fr))}.qa-grid{grid-template-columns:1fr}}@media(max-width:720px){.qa-command{grid-template-columns:1fr}}
@@ -40,7 +40,7 @@
<div class="modal fade" id="hitsModal" tabindex="-1"><div class="modal-dialog modal-lg"><div class="modal-content"><div class="modal-header"><h5 class="modal-title"><i class="fas fa-eye me-2"></i>RAG 命中內容</h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div><div class="modal-body" id="hitsModalBody"><div class="text-center"><i class="fas fa-spinner fa-spin"></i> 載入中...</div></div></div></div></div>
<script>
async function showHits(queryId){const modalEl=document.getElementById('hitsModal');const body=document.getElementById('hitsModalBody');body.innerHTML='<div class="text-center"><i class="fas fa-spinner fa-spin"></i> 載入中...</div>';const modal=new bootstrap.Modal(modalEl);modal.show();try{const r=await fetch(`/observability/rag_queries/${queryId}/hits`);const d=await r.json();if(!d.ok){body.innerHTML=`<div class="alert alert-danger">❌ ${d.error||'載入失敗'}</div>`;return;}let html=`<div class="mb-3"><small class="text-muted">查詢 #${d.query_id} · 門檻 ${d.threshold} · 命中 ${d.hit_count}</small><div class="p-2 mt-1" style="background:rgba(255,255,255,.62);border-radius:14px;"><small><strong>查詢內容:</strong></small><br><code>${escapeHtml(d.query_text||'')}</code></div></div>`;if(d.hits.length===0){html+='<div class="alert alert-warning">無 hits 詳細資料</div>';}else{html+='<h6 class="mb-2">Top hits 內容預覽:</h6>';d.hits.forEach(h=>{html+=`<div class="mb-2 p-2" style="background:rgba(255,255,255,.62);border-radius:14px;"><div class="mb-1"><span class="badge bg-light text-dark me-1">#${h.id}</span><span class="badge bg-info me-1">${escapeHtml(h.insight_type||'')}</span>${h.period?`<span class="badge bg-secondary me-1">${escapeHtml(h.period)}</span>`:''}${h.product_sku?`<small class="text-muted me-1">SKU: ${escapeHtml(h.product_sku)}</small>`:''}<small class="text-muted">${h.created_at}</small></div><small>${escapeHtml(h.content||'')}${h.content&&h.content.length>=300?'…':''}</small></div>`;});}body.innerHTML=html;}catch(e){body.innerHTML=`<div class="alert alert-danger">❌ 載入錯誤:${e}</div>`;}}
async function showHits(queryId){const modalEl=document.getElementById('hitsModal');const body=document.getElementById('hitsModalBody');body.innerHTML='<div class="text-center"><i class="fas fa-spinner fa-spin"></i> 載入中...</div>';const modal=new bootstrap.Modal(modalEl);modal.show();try{const r=await fetch(`/observability/rag_queries/${queryId}/hits`);const d=await r.json();if(!d.ok){body.innerHTML=`<div class="alert alert-danger">❌ ${d.error||'載入失敗'}</div>`;return;}let html=`<div class="mb-3"><small class="text-muted">查詢 #${d.query_id} · 門檻 ${d.threshold} · 命中 ${d.hit_count}</small><div class="p-2 mt-1 obs-modal-preview"><small><strong>查詢內容:</strong></small><br><code>${escapeHtml(d.query_text||'')}</code></div></div>`;if(d.hits.length===0){html+='<div class="alert alert-warning">無 hits 詳細資料</div>';}else{html+='<h6 class="mb-2">Top hits 內容預覽:</h6>';d.hits.forEach(h=>{html+=`<div class="mb-2 p-2 obs-modal-preview"><div class="mb-1"><span class="badge bg-light text-dark me-1">#${h.id}</span><span class="badge bg-info me-1">${escapeHtml(h.insight_type||'')}</span>${h.period?`<span class="badge bg-secondary me-1">${escapeHtml(h.period)}</span>`:''}${h.product_sku?`<small class="text-muted me-1">SKU: ${escapeHtml(h.product_sku)}</small>`:''}<small class="text-muted">${h.created_at}</small></div><small>${escapeHtml(h.content||'')}${h.content&&h.content.length>=300?'…':''}</small></div>`;});}body.innerHTML=html;}catch(e){body.innerHTML=`<div class="alert alert-danger">❌ 載入錯誤:${e}</div>`;}}
function escapeHtml(s){if(!s)return'';return s.replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));}
</script>
{% endblock %}