Implements the design in zurich-kotak-leaddesk across every screen. Foundation: Source Sans 3 bundled from src/assets/fonts (no Google Fonts request), 15px root, navy/blue/amber/teal/red palette where blue is the AI, amber a person, teal the customer and red is reserved for risk; flat white 10px cards on a grey canvas, no shadows. Shell: 56px navy masthead (Z wordmark, Lead Desk, user), 232px white nav grouped Needs you / Scheduled / History with coloured count pills and the closed stages folded. Overview: the hero says who holds each open lead (stacked bar + legend) beside the renewals-at-risk card; five KPIs incl. Closed to date; Waiting on a person queue with owner dots and "N more with the AI"; Pipeline by stage with owner-coloured bars; Renewal exposure with tabs, dropdown filters and a Holding it column. Lead: back button, id line, holder pill; one attention banner (amber your turn / blocked, red stalled, blue with the AI, teal with the customer) that carries its button; four facts with a confidence bar; navy steps rail whose current step takes its holder's colour; timeline as an avatar gutter with title, stage pill, by-line + AI tag and text-link actions (See reasoning · N steps, Hear the call, Open thread); side column flows. Lists: card with search + hide-closed toggle, columns Customer / Stage / Renewal due / Holding it / Premium / Last activity, stalled rows get a red inset, closed rows dim, person-gated queues split into Your turn / With the AI group rows. src/api/holder.js is the single rule for holder tone + label so the table cells, the overview and the lead header cannot disagree. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
146 lines
4.6 KiB
CSS
146 lines
4.6 KiB
CSS
.shell {
|
|
min-height: 100vh;
|
|
display: flex;
|
|
flex-direction: column;
|
|
background: var(--zk-tint);
|
|
}
|
|
|
|
/* ── Masthead ─────────────────────────────────────────────────────────────── */
|
|
.shell__top {
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 30;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 22px;
|
|
height: 56px;
|
|
padding: 0 24px;
|
|
background: var(--zk-navy);
|
|
color: #fff;
|
|
}
|
|
|
|
.mast__logo { display: flex; align-items: center; gap: 10px; }
|
|
.mast__z {
|
|
width: 30px; height: 30px; border-radius: 50%;
|
|
background: #fff; color: var(--zk-navy);
|
|
font-weight: 700; font-size: 17px;
|
|
display: grid; place-items: center;
|
|
}
|
|
.mast__word b { display: block; font-weight: 700; font-size: 17px; letter-spacing: .06em; line-height: 1.15; }
|
|
.mast__word b span { font-weight: 500; letter-spacing: 0; }
|
|
.mast__word small { display: block; font-size: 11.5px; opacity: .75; margin-top: -1px; letter-spacing: .02em; }
|
|
|
|
.mast__sep { width: 1px; height: 26px; background: rgba(255, 255, 255, .22); }
|
|
|
|
.mast__app { font-size: 17px; font-weight: 600; }
|
|
.mast__app span { font-weight: 400; opacity: .7; margin-left: 8px; font-size: 15px; }
|
|
|
|
.mast__user { margin-left: auto; }
|
|
|
|
/* ── Frame ────────────────────────────────────────────────────────────────── */
|
|
.shell__body { display: flex; flex: 1; min-height: 0; align-items: stretch; }
|
|
|
|
.shell__nav {
|
|
position: sticky;
|
|
top: 56px;
|
|
align-self: flex-start;
|
|
width: 232px;
|
|
flex: none;
|
|
min-height: calc(100vh - 56px);
|
|
max-height: calc(100vh - 56px);
|
|
overflow-y: auto;
|
|
overscroll-behavior: contain;
|
|
background: #fff;
|
|
border-right: 1px solid var(--zk-line);
|
|
padding: 20px 12px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 2px;
|
|
}
|
|
|
|
.nav__h {
|
|
margin: 0;
|
|
padding: 18px 12px 6px;
|
|
font-size: var(--fs-3xs);
|
|
font-weight: 600;
|
|
letter-spacing: .04em;
|
|
text-transform: uppercase;
|
|
color: var(--zk-grey);
|
|
}
|
|
.nav__group { display: flex; flex-direction: column; gap: 2px; }
|
|
|
|
.nav__link {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 9px 12px;
|
|
border-radius: var(--r-sm);
|
|
font-size: var(--fs-sm);
|
|
font-weight: 500;
|
|
color: var(--zk-muted);
|
|
text-decoration: none;
|
|
cursor: pointer;
|
|
transition: background var(--t-fast), color var(--t-fast);
|
|
}
|
|
.nav__link:hover { background: var(--zk-tint); color: var(--zk-ink); }
|
|
.nav__link.is-on {
|
|
background: var(--zk-tint-blue);
|
|
color: var(--zk-navy);
|
|
font-weight: 600;
|
|
box-shadow: inset 3px 0 0 var(--zk-blue);
|
|
}
|
|
.nav__name { min-width: 0; line-height: 1.35; }
|
|
|
|
/* The count is who is being waited on: red a person urgently, amber the
|
|
customer, grey the calendar or history. */
|
|
.nav__n {
|
|
margin-left: auto;
|
|
font-size: var(--fs-2xs);
|
|
font-weight: 600;
|
|
padding: 1px 8px;
|
|
border-radius: var(--r-pill);
|
|
font-variant-numeric: tabular-nums;
|
|
background: var(--zk-line-soft);
|
|
color: var(--zk-muted);
|
|
}
|
|
.nav__n--red { background: var(--zk-danger-tint); color: var(--zk-danger); }
|
|
.nav__n--amber { background: var(--zk-amber-tint); color: var(--zk-amber); }
|
|
.nav__n--blue { background: var(--zk-tint-blue); color: var(--zk-blue); }
|
|
|
|
/* Closed folds. The summary IS a nav row; a chevron says it opens. */
|
|
.nav__fold > summary { list-style: none; }
|
|
.nav__fold > summary::-webkit-details-marker { display: none; }
|
|
.nav__fold > summary .nav__name::before {
|
|
content: '';
|
|
display: inline-block;
|
|
width: 5px; height: 5px;
|
|
margin: 0 8px 1px 0;
|
|
border-right: 1.5px solid var(--zk-grey);
|
|
border-bottom: 1.5px solid var(--zk-grey);
|
|
transform: rotate(-45deg);
|
|
transition: transform var(--t-fast);
|
|
}
|
|
.nav__fold[open] > summary .nav__name::before { transform: rotate(45deg); }
|
|
.nav__sub { display: flex; flex-direction: column; gap: 2px; padding-left: 12px; }
|
|
|
|
/* ── Canvas ───────────────────────────────────────────────────────────────── */
|
|
.shell__main {
|
|
flex: 1;
|
|
min-width: 0;
|
|
width: 100%;
|
|
background: var(--zk-tint);
|
|
padding: 28px 32px 40px;
|
|
}
|
|
|
|
@media (max-width: 900px) {
|
|
.shell__body { flex-direction: column; }
|
|
.shell__nav {
|
|
position: static; width: 100%; min-height: 0; max-height: none;
|
|
border-right: 0; border-bottom: 1px solid var(--zk-line);
|
|
flex-direction: row; flex-wrap: wrap; padding: 10px 12px;
|
|
}
|
|
.nav__h { display: none; }
|
|
.nav__group { flex-direction: row; flex-wrap: wrap; }
|
|
.shell__main { padding: 20px 16px 48px; }
|
|
}
|