myke69's picture
Add files using upload-large-folder tool
3752e5d verified
Raw
History Blame Contribute Delete
21.3 kB
:root {
--ink: #1c2333;
--ink-soft: #5b6478;
--line: #e3e7ef;
--bg: #f6f7fa;
--card: #ffffff;
--accent: #1f4fd8;
--high: #c92a2a;
--med: #d9750b;
--low: #5b6478;
--hl: rgba(255, 196, 0, 0.45);
}
* { box-sizing: border-box; }
html, body, #root { height: 100%; margin: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
color: var(--ink);
background: var(--bg);
}
.app { display: flex; flex-direction: column; height: 100vh; }
/* top bar */
.topbar {
display: flex; align-items: center; justify-content: space-between;
padding: 10px 20px; background: var(--card); border-bottom: 1px solid var(--line);
}
.brand {
display: flex; align-items: center; gap: 12px; text-align: left;
background: none; border: none; padding: 0; font: inherit; color: inherit;
cursor: pointer;
}
.brand:hover .brand-mark { background: #1a44bd; }
.brand-mark {
display: inline-flex; align-items: center; justify-content: center;
width: 36px; height: 36px; border-radius: 9px; background: var(--accent);
color: #fff; font-size: 20px; font-weight: 700;
}
.brand strong { display: block; font-size: 15px; }
.brand small { color: var(--ink-soft); font-size: 12px; }
.upload-btn {
background: var(--accent); color: #fff; padding: 9px 16px; border-radius: 8px;
font-size: 14px; font-weight: 600; cursor: pointer;
}
.upload-btn input { display: none; }
.banner { padding: 8px 20px; font-size: 13px; }
.banner.error { background: #fdecec; color: var(--high); }
.banner.warn { background: #fdf3e3; color: var(--med); }
/* empty / loading state */
.empty { flex: 1; display: flex; align-items: center; justify-content: center; }
.empty-card { max-width: 560px; padding: 40px; }
.empty-card h1 { margin: 0 0 12px; font-size: 30px; }
.empty-card p { font-size: 15px; line-height: 1.55; color: var(--ink); }
.muted { color: var(--ink-soft); font-size: 13px; }
.existing { margin-top: 18px; display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.existing-btn {
border: 1px solid var(--line); background: var(--card); border-radius: 8px;
padding: 8px 14px; font-size: 13px; cursor: pointer; color: var(--accent); font-weight: 600;
}
.existing-btn:hover { background: #f4f7ff; }
.pad { padding: 16px; }
/* main layout */
.layout { flex: 1; display: grid; grid-template-columns: minmax(480px, 46%) 1fr; min-height: 0; }
.left { display: flex; flex-direction: column; min-height: 0; border-right: 1px solid var(--line); }
.right { min-height: 0; background: #888e9c; }
/* summary strip */
.summary { display: flex; gap: 10px; padding: 12px 16px 0; }
.stat {
background: var(--card); border: 1px solid var(--line); border-radius: 10px;
padding: 8px 14px; flex: 1; min-width: 0;
}
.stat b { display: block; font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stat small { color: var(--ink-soft); font-size: 11px; }
.stat.num { flex: 0 0 auto; text-align: center; }
.stat.num b { font-size: 20px; }
.stat.danger b { color: var(--high); }
/* tabs */
.tabs { display: flex; gap: 4px; padding: 12px 16px 0; }
.tabs button {
border: 1px solid var(--line); border-bottom: none; background: #eef0f5;
padding: 8px 16px; border-radius: 8px 8px 0 0; font-size: 13px; font-weight: 600;
color: var(--ink-soft); cursor: pointer;
}
.tabs button.active { background: var(--card); color: var(--ink); }
.pill {
background: var(--line); border-radius: 99px; padding: 1px 7px;
font-size: 11px; margin-left: 6px;
}
.panel {
flex: 1; overflow: auto; background: var(--card);
border-top: 1px solid var(--line); margin: 0 16px 16px; border: 1px solid var(--line);
border-radius: 0 10px 10px 10px;
}
/* risk cards */
.risk-list { display: flex; flex-direction: column; }
.risk-card {
text-align: left; background: none; border: none; border-bottom: 1px solid var(--line);
padding: 14px 16px; cursor: pointer; font: inherit; color: inherit;
}
.risk-card:hover { background: #f4f7ff; }
.risk-card.active { background: #eef3ff; box-shadow: inset 3px 0 0 var(--accent); }
.risk-head { display: flex; align-items: center; gap: 10px; }
.level { font-size: 11px; font-weight: 800; padding: 2px 8px; border-radius: 5px; color: #fff; }
.level.HIGH { background: var(--high); }
.level.MEDIUM { background: var(--med); }
.level.LOW { background: var(--low); }
.risk-title { font-weight: 700; font-size: 14px; flex: 1; }
.sev { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ink-soft); }
.sev-bar { width: 54px; height: 6px; background: var(--line); border-radius: 4px; overflow: hidden; display: inline-block; }
.sev-bar span { display: block; height: 100%; background: linear-gradient(90deg, var(--med), var(--high)); }
.finding { margin: 8px 0 4px; font-size: 13px; line-height: 1.5; }
.baseline, .reco { margin: 4px 0; font-size: 12.5px; line-height: 1.45; color: var(--ink-soft); }
.reco b, .baseline b { color: var(--ink); }
.source { margin-top: 8px; font-size: 12px; color: var(--accent); font-weight: 600; }
/* obligations table */
.register { width: 100%; border-collapse: collapse; font-size: 13px; }
.register th {
text-align: left; padding: 10px 12px; font-size: 11px; text-transform: uppercase;
letter-spacing: 0.04em; color: var(--ink-soft); border-bottom: 1px solid var(--line);
position: sticky; top: 0; background: var(--card); z-index: 1;
}
.register td { padding: 10px 12px; border-bottom: 1px solid var(--line); vertical-align: top; }
.register tbody tr { cursor: pointer; }
.register tbody tr:hover { background: #f4f7ff; }
.register tbody tr.active { background: #eef3ff; box-shadow: inset 3px 0 0 var(--accent); }
.party { font-weight: 600; white-space: nowrap; max-width: 160px; overflow: hidden; text-overflow: ellipsis; }
.deadline { white-space: nowrap; font-variant-numeric: tabular-nums; }
.clause-ref { color: var(--accent); font-weight: 700; white-space: nowrap; }
.type-chip {
font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 99px;
background: #eef0f5; color: var(--ink-soft); white-space: nowrap;
}
.t-payment { background: #e7f5ee; color: #0b7a45; }
.t-deliverable { background: #e8f0fe; color: var(--accent); }
.t-renewal_termination { background: #fdf3e3; color: var(--med); }
.t-compliance { background: #f3e8fd; color: #7a3ccc; }
.t-service_level { background: #e3f6f9; color: #0b7285; }
/* key dates */
.timeline { display: flex; flex-direction: column; }
.date-row {
display: flex; align-items: center; gap: 12px; text-align: left;
background: none; border: none; border-bottom: 1px solid var(--line);
padding: 12px 16px; cursor: pointer; font: inherit; color: inherit;
}
.date-row:hover { background: #f4f7ff; }
.date-row.active { background: #eef3ff; box-shadow: inset 3px 0 0 var(--accent); }
.dot { width: 10px; height: 10px; border-radius: 50%; background: var(--low); flex: 0 0 auto; }
.date-row.overdue .dot, .date-row.critical .dot { background: var(--high); }
.date-row.soon .dot { background: var(--med); }
.date-row.ok .dot { background: #2f9e44; }
.date-col { width: 96px; flex: 0 0 auto; }
.date-col b { display: block; font-size: 13px; font-variant-numeric: tabular-nums; }
.date-col small { color: var(--ink-soft); font-size: 11px; }
.date-label { flex: 1; font-size: 13px; line-height: 1.4; }
.date-label small { display: block; color: var(--ink-soft); font-size: 11.5px; }
.date-label .derivation { color: var(--accent); }
.urgency-chip {
font-size: 10.5px; font-weight: 800; padding: 2px 8px; border-radius: 99px;
background: var(--line); color: var(--ink-soft); white-space: nowrap;
}
.urgency-chip.overdue, .urgency-chip.critical { background: #fdecec; color: var(--high); }
.urgency-chip.soon { background: #fdf3e3; color: var(--med); }
.urgency-chip.ok { background: #e7f5ee; color: #0b7a45; }
/* PDF viewer */
.pdf-container { height: 100%; overflow: auto; padding: 18px; }
.pdf-loading { color: #fff; padding: 30px; text-align: center; }
.pdf-page {
position: relative; margin: 0 auto 18px; background: #fff;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);
}
.pdf-page canvas { display: block; }
.hl {
position: absolute; background: var(--hl); border-radius: 2px;
pointer-events: none; mix-blend-mode: multiply;
animation: pulse 0.9s ease-in-out 2;
}
@keyframes pulse {
0%, 100% { outline: 2px solid rgba(255, 160, 0, 0); }
50% { outline: 2px solid rgba(255, 160, 0, 0.9); }
}
.page-num {
position: absolute; right: 8px; bottom: 6px; font-size: 11px; color: var(--ink-soft);
}
/* topbar actions + export toolbar */
.topbar-actions { display: flex; align-items: center; gap: 10px; }
.nav-btn {
border: 1px solid var(--line); background: var(--card); border-radius: 8px;
padding: 8px 14px; font-size: 14px; font-weight: 600; color: var(--accent);
cursor: pointer;
}
.nav-btn:hover, .nav-btn.active { background: #eef3ff; }
.nav-btn.signout { color: var(--ink-soft); }
.nav-btn.signout:hover { color: var(--high); background: #fdecec; }
.toolbar { display: flex; gap: 8px; padding: 10px 16px 0; }
.tool-btn {
border: 1px solid var(--line); background: var(--card); border-radius: 8px;
padding: 6px 12px; font-size: 12.5px; font-weight: 600; color: var(--ink);
cursor: pointer; text-decoration: none;
}
.tool-btn:hover { background: #f4f7ff; border-color: var(--accent); color: var(--accent); }
/* login */
.login-card { background: var(--card); border: 1px solid var(--line); border-radius: 14px; }
.login-brand { margin-bottom: 12px; }
.login-card input[type="password"],
.login-card input[type="text"] {
width: 100%; padding: 10px 12px; margin-top: 10px; font-size: 15px;
border: 1px solid var(--line); border-radius: 8px;
}
.login-error { margin-top: 10px; font-size: 13px; color: var(--high); }
.login-submit { display: block; width: 100%; margin-top: 14px; border: none; font-size: 15px; }
.login-submit:disabled { opacity: 0.6; cursor: default; }
/* portfolio */
.portfolio { flex: 1; overflow: auto; padding-bottom: 24px; }
.portfolio-cols {
display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px;
padding: 0 16px; align-items: start;
}
.portfolio-col h2 { font-size: 14px; margin: 16px 0 8px; padding: 0 2px; }
.portfolio-col .panel { margin: 0; border-radius: 10px; max-height: 52vh; overflow: auto; }
.contracts-panel { padding: 4px 0; }
.contract-row { display: flex; align-items: center; border-bottom: 1px solid var(--line); }
.contract-row:last-child { border-bottom: none; }
.contract-open {
flex: 1; text-align: left; background: none; border: none; cursor: pointer;
padding: 10px 14px; font: inherit; color: inherit;
}
.contract-open:hover { background: #f4f7ff; }
.contract-open b { display: block; font-size: 13.5px; }
.contract-open small { display: block; margin-top: 2px; }
.contract-delete {
border: none; background: none; color: var(--ink-soft); cursor: pointer;
font-size: 14px; padding: 10px 14px;
}
.contract-delete:hover { color: var(--high); }
/* ── Risk Heatmap ─────────────────────────────────────────────── */
.heatmap-wrap { padding: 14px 16px; overflow-x: auto; }
.heatmap-legend {
display: flex; align-items: center; gap: 10px; font-size: 12px;
color: var(--ink-soft); margin-bottom: 12px;
}
.hm-dot { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }
.hm-high { background: rgba(201,42,42,0.75); }
.hm-med { background: rgba(217,117,11,0.75); }
.hm-low { background: rgba(91,100,120,0.60); }
.hm-hint { margin-left: 6px; }
.heatmap { border-collapse: collapse; width: 100%; font-size: 13px; }
.hm-cat-hdr {
text-align: left; padding: 8px 12px; font-size: 11px; text-transform: uppercase;
letter-spacing: 0.04em; color: var(--ink-soft); border-bottom: 2px solid var(--line);
white-space: nowrap;
}
.hm-col-hdr {
text-align: center; padding: 8px 14px; font-size: 11px; font-weight: 800;
letter-spacing: 0.04em; border-bottom: 2px solid var(--line); white-space: nowrap;
}
.hm-col-high { color: var(--high); }
.hm-col-medium { color: var(--med); }
.hm-col-low { color: var(--low); }
.hm-cat {
padding: 9px 12px; font-size: 13px; border-bottom: 1px solid var(--line);
white-space: nowrap; font-weight: 500;
}
.hm-cell {
text-align: center; padding: 9px 14px; font-size: 14px; font-weight: 700;
border-bottom: 1px solid var(--line); border-left: 1px solid var(--line);
transition: filter 0.1s;
}
.hm-cell:hover { filter: brightness(0.92); }
.hm-empty { color: #ccc; font-weight: 400; }
.hm-total {
text-align: center; padding: 9px 12px; font-size: 13px; font-weight: 600;
border-bottom: 1px solid var(--line); border-left: 1px solid var(--line);
color: var(--ink-soft);
}
/* ── Defined Terms (Glossary) ────────────────────────────────── */
.definitions { display: flex; flex-direction: column; height: 100%; }
.def-search-row {
display: flex; align-items: center; gap: 10px;
padding: 12px 16px; border-bottom: 1px solid var(--line);
}
.def-search {
flex: 1; padding: 7px 10px; font-size: 13px;
border: 1px solid var(--line); border-radius: 8px; outline: none;
}
.def-search:focus { border-color: var(--accent); }
.def-count { font-size: 12px; color: var(--ink-soft); white-space: nowrap; }
.def-list { flex: 1; overflow: auto; }
.def-row {
display: flex; align-items: baseline; gap: 12px;
padding: 11px 16px; border-bottom: 1px solid var(--line);
font-size: 13px;
}
.def-row:hover { background: #f4f7ff; }
.def-term { font-weight: 700; color: var(--accent); white-space: nowrap; flex: 0 0 auto; }
.def-definition { flex: 1; color: var(--ink); line-height: 1.4; }
.def-jump {
border: none; background: none; color: var(--accent); font-size: 12px;
font-weight: 600; cursor: pointer; white-space: nowrap; padding: 0;
}
.def-jump:hover { text-decoration: underline; }
/* ── Contract Chat ───────────────────────────────────────────── */
.chat-wrap { display: flex; flex-direction: column; height: 100%; }
.chat-messages { flex: 1; overflow-y: auto; padding: 12px 14px; display: flex; flex-direction: column; gap: 10px; }
.chat-msg { display: flex; flex-direction: column; gap: 4px; }
.chat-msg.user { align-items: flex-end; }
.chat-msg.bot { align-items: flex-start; }
.chat-bubble {
max-width: 88%; padding: 10px 14px; border-radius: 14px;
font-size: 13.5px; line-height: 1.5;
}
.chat-msg.user .chat-bubble {
background: var(--accent); color: #fff; border-bottom-right-radius: 4px;
}
.chat-msg.bot .chat-bubble {
background: #f0f2f7; color: var(--ink); border-bottom-left-radius: 4px;
}
.chat-para { margin: 0 0 6px; }
.chat-para:last-child { margin-bottom: 0; }
.chat-thinking {
display: flex; align-items: center; min-width: 48px;
}
.dot-pulse {
display: inline-block; width: 8px; height: 8px; border-radius: 50%;
background: var(--ink-soft); animation: dotpulse 1.2s infinite ease-in-out;
}
@keyframes dotpulse {
0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); }
40% { opacity: 1; transform: scale(1); }
}
.chat-citations { display: flex; flex-wrap: wrap; gap: 6px; padding-left: 4px; }
.cite-label { font-size: 11px; color: var(--ink-soft); align-self: center; }
.citation-chip {
border: 1px solid var(--accent); background: #eef3ff; color: var(--accent);
font-size: 12px; font-weight: 600; padding: 3px 10px; border-radius: 99px;
cursor: pointer;
}
.citation-chip:hover { background: var(--accent); color: #fff; }
.chat-suggestions { display: flex; flex-direction: column; gap: 6px; padding: 4px 0; }
.suggestion-chip {
align-self: flex-start; border: 1px solid var(--line); background: var(--card);
color: var(--ink); font-size: 12.5px; padding: 6px 12px; border-radius: 99px;
cursor: pointer; text-align: left;
}
.suggestion-chip:hover { border-color: var(--accent); color: var(--accent); background: #eef3ff; }
.chat-input-row {
display: flex; gap: 8px; padding: 10px 12px;
border-top: 1px solid var(--line); background: var(--card);
}
.chat-input {
flex: 1; padding: 9px 12px; font-size: 14px;
border: 1px solid var(--line); border-radius: 10px; outline: none;
}
.chat-input:focus { border-color: var(--accent); }
.chat-send {
background: var(--accent); color: #fff; border: none; border-radius: 10px;
width: 40px; font-size: 18px; font-weight: 700; cursor: pointer;
}
.chat-send:disabled { opacity: 0.4; cursor: default; }
.chat-send:not(:disabled):hover { background: #1a44bd; }
/* ── Contract Compare (modal) ────────────────────────────────── */
.compare-modal-backdrop {
position: absolute; inset: 0; background: rgba(28,35,51,0.45);
display: flex; align-items: stretch; z-index: 100;
}
.compare-modal {
background: var(--card); width: 100%; display: flex; flex-direction: column;
overflow: hidden;
}
.compare-overlay { display: flex; flex-direction: column; height: 100%; }
.compare-header {
display: flex; align-items: center; justify-content: space-between;
padding: 14px 20px; border-bottom: 1px solid var(--line);
}
.compare-title { margin: 0; font-size: 17px; }
.compare-close {
border: 1px solid var(--line); background: none; border-radius: 8px;
padding: 6px 12px; font-size: 13px; cursor: pointer; color: var(--ink-soft);
}
.compare-close:hover { color: var(--high); border-color: var(--high); }
.compare-controls {
display: flex; align-items: center; gap: 12px;
padding: 12px 20px; border-bottom: 1px solid var(--line); flex-wrap: wrap;
}
.compare-label {
font-size: 11px; font-weight: 800; padding: 2px 8px; border-radius: 5px;
background: var(--accent); color: #fff;
}
.compare-filename { font-size: 13px; font-weight: 600; }
.compare-vs { font-size: 13px; color: var(--ink-soft); font-weight: 600; }
.compare-contract-a, .compare-contract-b { display: flex; align-items: center; gap: 8px; }
.compare-select {
padding: 7px 10px; font-size: 13px; border: 1px solid var(--line);
border-radius: 8px; outline: none; min-width: 180px;
}
.compare-run-btn {
background: var(--accent); color: #fff; border: none; border-radius: 8px;
padding: 8px 18px; font-size: 13px; font-weight: 700; cursor: pointer;
}
.compare-run-btn:disabled { opacity: 0.5; cursor: default; }
.compare-run-btn:not(:disabled):hover { background: #1a44bd; }
.compare-summary-bar {
display: flex; gap: 12px; padding: 10px 20px; flex-wrap: wrap;
border-bottom: 1px solid var(--line); background: #f9fafc;
}
.csb-item {
font-size: 12.5px; font-weight: 600; padding: 3px 10px;
border-radius: 99px; background: var(--line); color: var(--ink-soft);
}
.csb-only-a { background: #e8f0fe; color: var(--accent); }
.csb-only-b { background: #f3e8fd; color: #7a3ccc; }
.csb-worse { background: #fdecec; color: var(--high); }
.csb-better { background: #e7f5ee; color: #0b7a45; }
.compare-results { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
.compare-table-wrap { flex: 1; overflow: auto; }
.compare-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.compare-table th {
position: sticky; top: 0; background: var(--card); z-index: 2;
text-align: left; padding: 10px 14px; font-size: 11px; text-transform: uppercase;
letter-spacing: 0.04em; color: var(--ink-soft); border-bottom: 2px solid var(--line);
}
.ct-cat-hdr { width: 160px; }
.ct-side-hdr { width: 38%; }
.ct-delta-hdr { width: 70px; text-align: center; }
.ct-row { border-bottom: 1px solid var(--line); }
.ct-row:hover { background: #f8f9fc; }
.ct-only-a { background: #f0f5ff; }
.ct-only-b { background: #f7f0ff; }
.ct-cat { padding: 10px 14px; vertical-align: top; }
.ct-cat b { display: block; font-size: 13px; }
.ct-only-badge {
display: inline-block; font-size: 10px; font-weight: 700; padding: 1px 6px;
border-radius: 4px; background: var(--line); color: var(--ink-soft); margin-top: 3px;
}
.ct-side-cell { padding: 10px 14px; vertical-align: top; border-left: 1px solid var(--line); }
.cmp-side { display: flex; flex-direction: column; gap: 4px; }
.cmp-clause-name { font-size: 13px; font-weight: 500; color: var(--ink); }
.cmp-risk { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; }
.cmp-risk-dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; }
.cmp-sev { font-weight: 400; color: var(--ink-soft); }
.cmp-absent { font-size: 12px; color: #bbb; }
.ct-delta { text-align: center; padding: 10px 14px; border-left: 1px solid var(--line); vertical-align: top; }
.delta-worse { color: var(--high); font-weight: 800; font-size: 13px; }
.delta-better { color: #0b7a45; font-weight: 800; font-size: 13px; }
.delta-same { color: var(--ink-soft); font-size: 13px; }
.ct-na { color: #ccc; }