finai/frontend/app/style.css

828 lines
13 KiB
CSS

:root {
--bg: #f3f6f4;
--ink: #14211d;
--muted: #66756f;
--line: #d9e3df;
--panel: rgba(255, 255, 255, .94);
--brand: #126854;
--brand-dark: #0b3a31;
--brand-soft: #e7f4ef;
--blue: #1c7f9e;
--warn: #b56a1a;
--danger: #b64a45;
--shadow: 0 18px 48px rgba(20, 33, 29, .09);
}
* {
box-sizing: border-box;
}
html, body {
height: 100vh;
overflow: hidden;
}
body {
margin: 0;
color: var(--ink);
background:
linear-gradient(180deg, rgba(255,255,255,.84), rgba(243,246,244,.96)),
repeating-linear-gradient(90deg, rgba(18,104,84,.045) 0, rgba(18,104,84,.045) 1px, transparent 1px, transparent 30px);
font-family: "Microsoft YaHei", "PingFang SC", "Noto Sans CJK SC", sans-serif;
letter-spacing: 0;
}
button, input, textarea, select {
font: inherit;
}
button {
cursor: pointer;
}
.app-shell {
display: grid;
grid-template-columns: 260px minmax(0, 1fr);
height: 100vh;
overflow: hidden;
}
.sidebar {
padding: 20px 14px;
display: grid;
grid-template-rows: auto auto 1fr;
gap: 20px;
background: #10251f;
color: #f4fbf8;
overflow-y: auto;
min-height: 0;
}
.brand {
display: flex;
gap: 12px;
align-items: center;
padding: 0 6px;
}
.brand-mark {
width: 38px;
height: 38px;
display: grid;
place-items: center;
border-radius: 8px;
background: #b8eadb;
color: #10251f;
font-weight: 900;
}
.brand-title {
font-size: 15px;
font-weight: 800;
}
.brand-subtitle {
margin-top: 3px;
color: rgba(244,251,248,.58);
font-size: 11px;
}
.nav {
display: grid;
gap: 6px;
}
.nav-item {
height: 42px;
display: flex;
align-items: center;
gap: 10px;
padding: 0 10px;
color: rgba(244,251,248,.82);
background: transparent;
border: 0;
border-radius: 8px;
text-align: left;
}
.nav-item.active {
color: #082018;
background: #c7f0e4;
font-weight: 800;
}
.nav-icon {
width: 24px;
height: 24px;
display: grid;
place-items: center;
border: 1px solid currentColor;
border-radius: 7px;
font-size: 12px;
}
.login-panel {
align-self: end;
padding: 12px;
border: 1px solid rgba(255,255,255,.12);
border-radius: 8px;
background: rgba(255,255,255,.06);
}
.login-panel label {
display: grid;
gap: 6px;
margin-bottom: 10px;
color: rgba(244,251,248,.62);
font-size: 12px;
}
.login-panel input {
width: 100%;
height: 34px;
padding: 0 9px;
color: #fff;
background: rgba(255,255,255,.08);
border: 1px solid rgba(255,255,255,.18);
border-radius: 8px;
}
.login-actions {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
}
.login-state {
margin-top: 10px;
color: #b8eadb;
font-size: 12px;
}
.login-state strong,
.login-state span {
display: block;
}
.login-state strong {
color: #f4fbf8;
font-size: 14px;
}
.login-state span {
margin-top: 4px;
color: rgba(244,251,248,.66);
}
.logout-btn {
width: 100%;
height: 34px;
margin-top: 12px;
color: #f4fbf8;
background: rgba(255,255,255,.08);
border: 1px solid rgba(255,255,255,.18);
border-radius: 8px;
font-weight: 800;
}
.logout-btn:hover {
border-color: rgba(255,255,255,.36);
background: rgba(255,255,255,.13);
}
.main {
min-width: 0;
min-height: 0;
display: grid;
grid-template-rows: 72px minmax(0, 1fr);
overflow: hidden;
}
.topbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
padding: 0 24px;
background: rgba(255,255,255,.86);
border-bottom: 1px solid var(--line);
backdrop-filter: blur(12px);
}
.topbar h1 {
margin: 0;
font-size: 19px;
}
.topbar p {
margin: 5px 0 0;
color: var(--muted);
font-size: 12px;
}
.top-actions {
display: flex;
align-items: center;
gap: 10px;
}
.status-badge {
display: inline-flex;
align-items: center;
min-height: 30px;
padding: 0 10px;
border: 1px solid var(--line);
border-radius: 8px;
color: var(--brand);
background: var(--brand-soft);
font-size: 12px;
font-weight: 700;
}
.status-badge.muted {
color: var(--muted);
background: #fbfcfc;
}
.icon-btn, .ghost-btn, .primary-btn {
height: 36px;
border-radius: 8px;
border: 1px solid var(--line);
background: #fff;
color: var(--ink);
font-weight: 800;
}
.icon-btn {
width: 36px;
display: grid;
place-items: center;
}
.ghost-btn {
padding: 0 12px;
}
.primary-btn {
padding: 0 15px;
color: #fff;
border-color: var(--brand);
background: var(--brand);
}
.view {
display: none;
min-height: 0;
padding: 20px;
overflow: hidden;
}
.view.is-visible {
display: grid;
height: 100%;
}
.chat-layout {
grid-template-columns: minmax(240px, 290px) minmax(420px, 1fr);
gap: 16px;
min-height: 0;
}
.bubble-body {
white-space: pre-wrap;
}
.bubble-references {
margin-top: 10px;
padding-top: 10px;
border-top: 1px dashed var(--line);
font-size: 12px;
}
.bubble-references-title {
margin-bottom: 6px;
color: var(--muted);
font-size: 12px;
font-weight: 700;
}
.bubble-references-body {
display: grid;
gap: 4px;
}
.bubble-reference-item {
padding: 2px 0;
}
.bubble-reference-item summary {
display: flex;
align-items: center;
gap: 6px;
cursor: pointer;
color: var(--brand-dark);
font-weight: 600;
list-style: none;
user-select: none;
}
.bubble-reference-item summary::-webkit-details-marker { display: none; }
.bubble-reference-item summary::marker { content: ""; }
.bubble-reference-item summary::before {
content: "▸";
display: inline-block;
width: 12px;
color: var(--muted);
transition: transform .15s;
}
.bubble-reference-item[open] summary::before {
transform: rotate(90deg);
}
.bubble-reference-item summary .ref-icon {
display: inline-block;
width: 14px;
text-align: center;
}
.ref-snippet {
margin-top: 6px;
padding: 8px 10px;
border: 1px solid var(--line);
border-radius: 6px;
background: #fff;
color: var(--ink);
white-space: pre-wrap;
line-height: 1.6;
font-size: 12px;
}
.conversation-panel, .chat-panel, .admin-view, .table-wrap, .usage-board {
min-width: 0;
min-height: 0;
background: var(--panel);
border: 1px solid var(--line);
border-radius: 8px;
box-shadow: var(--shadow);
}
.conversation-panel {
display: grid;
grid-template-rows: auto minmax(0, 1fr);
overflow: hidden;
}
.panel-head, .section-toolbar {
min-height: 62px;
display: flex;
justify-content: space-between;
align-items: center;
gap: 14px;
padding: 14px 16px;
border-bottom: 1px solid var(--line);
}
.panel-head.compact {
min-height: 56px;
}
.panel-head h2, .section-toolbar h2 {
margin: 0;
font-size: 15px;
}
.panel-head p, .section-toolbar p {
margin: 4px 0 0;
color: var(--muted);
font-size: 12px;
}
.session-list, .reference-list {
display: block;
overflow-y: auto;
min-height: 0;
}
.session-item {
display: flex;
align-items: stretch;
border-top: 1px solid var(--line);
background: transparent;
}
.session-item.active {
background: var(--brand-soft);
border-left: 3px solid var(--brand);
}
.session-body {
flex: 1;
min-width: 0;
padding: 12px 8px 12px 14px;
border: 0;
background: transparent;
text-align: left;
cursor: pointer;
}
.session-item.active .session-body {
padding-left: 11px;
}
.session-delete {
width: 30px;
flex-shrink: 0;
display: grid;
place-items: center;
border: 0;
background: transparent;
color: var(--muted);
font-size: 18px;
line-height: 1;
opacity: 0;
transition: opacity .15s, color .15s, background .15s;
}
.session-item:hover .session-delete,
.session-delete:focus-visible {
opacity: 1;
}
.session-delete:hover {
color: var(--danger);
background: rgba(182, 74, 69, .08);
}
.session-title {
font-size: 13px;
font-weight: 800;
}
.session-meta {
margin-top: 5px;
color: var(--muted);
font-size: 12px;
}
.chat-panel {
display: grid;
grid-template-rows: minmax(0, 1fr) auto;
overflow: hidden;
}
.messages {
padding: 16px;
overflow-y: auto;
min-height: 0;
}
.empty-state {
min-height: 260px;
display: grid;
place-items: center;
color: var(--muted);
text-align: center;
}
.message {
display: grid;
gap: 8px;
margin-bottom: 16px;
}
.message.user {
justify-items: end;
}
.bubble {
max-width: 88%;
padding: 13px 14px;
border: 1px solid var(--line);
border-radius: 8px;
background: #fbfcfc;
line-height: 1.7;
font-size: 14px;
white-space: pre-wrap;
}
.message.user .bubble {
color: #fff;
border-color: var(--brand);
background: var(--brand);
}
.composer {
display: grid;
grid-template-columns: 1fr auto;
gap: 10px;
padding: 14px;
border-top: 1px solid var(--line);
background: #fbfcfc;
}
.composer textarea {
resize: vertical;
min-height: 54px;
max-height: 140px;
padding: 10px 12px;
border: 1px solid #cfdcd7;
border-radius: 8px;
}
.reference-card {
padding: 12px 14px;
border-top: 1px solid var(--line);
}
.reference-card strong {
display: block;
font-size: 13px;
}
.reference-card p {
margin: 6px 0 0;
color: var(--muted);
font-size: 12px;
line-height: 1.55;
}
.stat-strip {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
padding: 14px;
border-top: 1px solid var(--line);
}
.stat-strip div, .usage-board div {
padding: 12px;
border: 1px solid var(--line);
border-radius: 8px;
background: #fbfcfc;
}
.stat-strip strong, .usage-board strong {
display: block;
font-size: 22px;
}
.stat-strip span, .usage-board span {
color: var(--muted);
font-size: 12px;
}
.admin-view {
align-content: start;
padding: 0;
overflow: auto;
}
.audit-grid {
min-height: 0;
}
.inline-form {
display: flex;
gap: 8px;
flex-wrap: wrap;
justify-content: flex-end;
}
.inline-form input, .inline-form select {
height: 36px;
padding: 0 10px;
border: 1px solid var(--line);
border-radius: 8px;
background: #fff;
}
.modal-backdrop {
position: fixed;
inset: 0;
z-index: 20;
display: grid;
place-items: center;
padding: 22px;
background: rgba(10, 24, 20, .46);
backdrop-filter: blur(10px);
}
.modal-backdrop[hidden] {
display: none;
}
.modal {
width: min(620px, 100%);
overflow: hidden;
border: 1px solid rgba(255,255,255,.52);
border-radius: 8px;
background: #fff;
box-shadow: 0 24px 70px rgba(8, 22, 18, .24);
}
.modal-head {
min-height: 66px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 14px;
padding: 16px 18px;
border-bottom: 1px solid var(--line);
}
.modal-head h2 {
margin: 0;
font-size: 16px;
}
.modal-head p {
margin: 5px 0 0;
color: var(--muted);
font-size: 12px;
}
.modal-body {
display: grid;
gap: 14px;
padding: 18px;
}
.drop-zone {
min-height: 190px;
display: grid;
place-items: center;
gap: 8px;
padding: 22px;
text-align: center;
border: 1px dashed #97b5ab;
border-radius: 8px;
background:
linear-gradient(135deg, rgba(18,104,84,.08), rgba(28,127,158,.08)),
#fbfcfc;
}
.drop-zone.is-dragging,
.drop-zone.has-file {
border-color: var(--brand);
background: var(--brand-soft);
}
.drop-icon {
width: 40px;
height: 40px;
display: grid;
place-items: center;
color: #fff;
background: var(--brand);
border-radius: 8px;
font-size: 22px;
font-weight: 900;
}
.drop-zone strong {
font-size: 15px;
}
.drop-zone small {
color: var(--muted);
}
.modal-grid {
display: grid;
grid-template-columns: 1fr 160px;
gap: 12px;
}
.modal-grid label {
display: grid;
gap: 6px;
color: var(--muted);
font-size: 12px;
}
.modal-grid input,
.modal-grid select {
height: 38px;
padding: 0 10px;
color: var(--ink);
border: 1px solid var(--line);
border-radius: 8px;
background: #fff;
}
.modal-actions {
display: flex;
justify-content: flex-end;
gap: 8px;
}
.table-wrap {
margin: 16px;
overflow: auto;
box-shadow: none;
}
table {
width: 100%;
border-collapse: collapse;
font-size: 13px;
}
th, td {
padding: 12px 14px;
border-bottom: 1px solid var(--line);
text-align: left;
vertical-align: middle;
}
th {
color: var(--muted);
background: #fbfcfc;
font-weight: 800;
}
.tag {
display: inline-flex;
min-height: 24px;
align-items: center;
margin: 2px 4px 2px 0;
padding: 0 8px;
border-radius: 8px;
background: var(--brand-soft);
color: var(--brand);
font-size: 12px;
font-weight: 700;
}
.audit-grid {
display: grid;
gap: 16px;
}
.usage-board {
margin: 16px 16px 0;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
padding: 14px;
box-shadow: none;
}
.toast {
position: fixed;
right: 18px;
bottom: 18px;
max-width: min(360px, calc(100vw - 36px));
padding: 12px 14px;
color: #fff;
background: var(--brand-dark);
border-radius: 8px;
box-shadow: var(--shadow);
opacity: 0;
transform: translateY(12px);
pointer-events: none;
transition: .2s ease;
}
.toast.show {
opacity: 1;
transform: translateY(0);
}
@media (max-width: 1120px) {
.chat-layout {
grid-template-columns: 240px minmax(0, 1fr);
}
}
@media (max-width: 760px) {
html, body {
overflow: auto;
}
.app-shell {
grid-template-columns: 1fr;
height: auto;
overflow: visible;
}
.main, .view {
overflow: visible;
}
.chat-layout, .usage-board {
grid-template-columns: 1fr;
}
.topbar, .section-toolbar {
align-items: flex-start;
flex-direction: column;
}
.composer {
grid-template-columns: 1fr;
}
}