zurich_kotak/src/screens/screens.css
Yashas 4c210c7e09 console: a page to monitor from, and words an operator would use
Three problems, and the first one is the reason the other two were hard
to see.

THERE WAS NO DASHBOARD. "/" redirected to the underwriting queue — one
stage, usually empty, and belonging to somebody else. Every screen in
the app answered "show me this queue"; none answered "how is the book
doing, and is anything waiting on me?", which is the only question a
person has before they have picked a queue.

So: a Today page. Three blocks, in the order somebody cares about them.
What is waiting on a person, as three cards that colour only when they
have something in them. Renewals running out, worst first, capped at 30
days because a renewal six months away is not a thing to look at today.
Then every stage with its count, zeroes included — a stage quietly
receiving nothing is only visible if its zero is on screen.

It is one list call, counted in the browser. That is honest at this size
and it is the same call the queues already make. If the book outgrows it
the answer is a counts endpoint, not a bigger page.

THE WORDS WERE WRITTEN FOR WHOEVER BUILT THE WORKFLOW. "What happens
next" was followed by "these are the only activities this state allows
— but the workflow decides, server-side, whether you may". A failed list
said "this queue has no record view yet". Panels were called "Flow
details". A closed lead read "nothing runs from here". None of that is
wrong; all of it is addressed to the wrong reader.

Now: "What you can do", "Lead details", "History", "This queue could not
be loaded". Queue names say what they want — "Documents needed",
"Underwriter to review", "Payment to confirm". The sidebar group called
"Not yet" says "Not due yet", and "Running by itself" says "The agents
have it", which is the actual claim being made.

THE QUEUE HAD NINE COLUMNS AND LED WITH THE WRONG ONE. Two were internal
vocabulary: attribution status renders "clear" or "contested" and means
nothing to an operator, and the channel is background rather than
something anyone scans a queue for. Both fold into a subtitle under the
customer. That leaves six columns and puts the renewal countdown — the
number that decides whether to act today — second instead of fifth.

Also: the timeline printed a raw slug when a step came back without a
name. It is the screen this product is demonstrated on, so a
"zk-act-doc-reminder" in the middle of an otherwise readable story is
expensive. It now reads as English.
2026-09-07 16:13:13 +05:30

985 lines
21 KiB
CSS

/* ---- page header ---- */
.page__head {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 24px;
margin-bottom: 24px;
}
.page__title {
margin: 0;
font-size: 1.7rem;
font-weight: 500;
letter-spacing: -0.022em;
line-height: 1.2;
color: var(--zk-ink);
}
.page__sub {
margin: 6px 0 0;
max-width: 72ch;
font-size: 0.855rem;
line-height: 1.5;
color: var(--zk-muted);
}
/* The queue depth, as a stat tile rather than a loose number. */
.page__count {
flex: none;
display: flex;
flex-direction: column;
align-items: center;
gap: 1px;
min-width: 84px;
padding: 10px 18px;
border-radius: var(--r-lg);
background: var(--zk-white);
border: 1px solid var(--zk-line);
box-shadow: var(--sh-sm);
}
.page__count strong {
font-size: 1.6rem;
font-weight: 500;
line-height: 1.1;
color: var(--zk-blue);
font-variant-numeric: tabular-nums;
}
.page__count span {
font-size: 0.6rem;
font-weight: 500;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--zk-grey);
}
.empty {
margin: 0;
color: var(--zk-muted);
font-size: 0.88rem;
text-align: center;
padding: 44px 24px;
border-radius: var(--r-lg);
border: 1px dashed var(--zk-line);
background: linear-gradient(180deg, var(--zk-white) 0%, var(--zk-tint) 100%);
}
.notice {
background: var(--zk-white);
border: 1px solid var(--zk-line);
border-left: 3px solid var(--zk-blue);
border-radius: var(--r-xs) var(--r-lg) var(--r-lg) var(--r-xs);
box-shadow: var(--sh-sm);
padding: 18px 22px;
max-width: 64ch;
}
.notice strong {
display: block;
font-weight: 500;
margin-bottom: 7px;
}
.notice p {
margin: 0 0 6px;
font-size: 0.86rem;
color: var(--zk-muted);
line-height: 1.55;
}
.notice__detail {
font-size: 0.76rem !important;
color: var(--zk-grey) !important;
}
.notice code {
font-family: var(--font-mono);
font-size: 0.8em;
background: var(--zk-tint);
border: 1px solid var(--zk-line-soft);
border-radius: var(--r-xs);
padding: 1px 5px;
}
/* ---- queue table ---- */
.gridwrap {
background: var(--zk-white);
border: 1px solid var(--zk-line);
border-radius: var(--r-lg);
box-shadow: var(--sh-sm);
overflow: hidden;
overflow-x: auto;
}
.grid {
width: 100%;
/* Eight columns of operational data do not compress: below this the card
scrolls sideways rather than squeezing every cell into two words a line. */
min-width: 1000px;
border-collapse: separate;
border-spacing: 0;
font-size: 0.86rem;
}
.grid th {
position: sticky;
top: 0;
z-index: 1;
text-align: left;
font-size: 0.65rem;
font-weight: 500;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--zk-muted);
padding: 12px 16px;
background: var(--zk-tint);
border-bottom: 1px solid var(--zk-line);
white-space: nowrap;
}
.grid td {
padding: 13px 16px;
border-bottom: 1px solid var(--zk-line-soft);
vertical-align: top;
}
.grid tbody tr {
transition: background var(--t-fast);
}
.grid tbody tr:last-child td {
border-bottom: none;
}
.grid tbody tr:hover {
background: var(--zk-tint);
}
/* An accent that arrives on hover, drawn inside the cell so it never disturbs
the table's own borders. */
.grid tbody tr:hover td:first-child {
box-shadow: inset 3px 0 0 var(--zk-blue);
}
.grid .num {
text-align: right;
font-variant-numeric: tabular-nums;
}
/* The lead reference is the thing an operator quotes on a call. */
.grid__ref {
font-variant-numeric: tabular-nums;
white-space: nowrap;
color: var(--zk-muted);
}
.grid__sub {
font-size: 0.76rem;
color: var(--zk-muted);
margin-top: 3px;
}
.grid__link {
color: var(--zk-blue);
text-decoration: none;
font-weight: 500;
border-bottom: 1px solid transparent;
transition: border-color var(--t-fast);
}
.grid__link:hover {
border-bottom-color: currentColor;
}
/* Row action. Renders as a button; stays an anchor so an operator can open a
lead in a new tab from a queue.
NOT `.act` — that class belongs to the Lead page's activity buttons and is
display:flex, which stretched this anchor to fill the cell. */
.grid__act {
text-align: right;
white-space: nowrap;
width: 1%;
}
.grid__btn {
display: inline-flex;
align-items: center;
gap: 6px;
text-decoration: none;
white-space: nowrap;
font-size: 0.78rem;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--r-pill);
background: var(--zk-white);
color: var(--zk-blue);
border: 1px solid var(--zk-line);
transition: background var(--t-fast), border-color var(--t-fast), box-shadow var(--t-fast);
}
.grid__btn::after {
content: '→';
font-size: 0.85em;
transition: transform var(--t-fast);
}
.grid__btn:hover {
background: var(--zk-tint-blue);
border-color: var(--zk-blue-light);
}
.grid__btn:hover::after {
transform: translateX(2px);
}
.grid__btn:focus-visible {
outline: none;
border-color: var(--zk-blue);
box-shadow: var(--ring);
}
/* ---- loading skeleton ---- */
.skel {
display: flex;
flex-direction: column;
gap: 1px;
padding: 14px 0;
background: var(--zk-white);
border: 1px solid var(--zk-line);
border-radius: var(--r-lg);
box-shadow: var(--sh-sm);
overflow: hidden;
}
.skel__row {
height: 18px;
margin: 9px 16px;
border-radius: var(--r-sm);
background: linear-gradient(90deg, var(--zk-line-soft) 0%, var(--zk-tint) 40%, var(--zk-line-soft) 80%);
background-size: 420px 100%;
animation: zk-shimmer 1.25s linear infinite;
}
.skel__row:nth-child(odd) { width: calc(100% - 32px); }
.skel__row:nth-child(3n) { width: 72%; }
.skel__row:nth-child(3n + 2) { width: 88%; }
/* ---- chips ---- */
.chip {
display: inline-flex;
align-items: center;
font-size: 0.72rem;
font-weight: 500;
padding: 3px 10px;
border-radius: var(--r-pill);
background: var(--zk-tint-blue);
color: var(--zk-blue-dark);
border: 1px solid var(--zk-blue-light);
}
.chip--warn {
background: var(--zk-amber-tint);
color: var(--zk-amber-ink);
border-color: var(--zk-amber-line);
}
/* ---- doors ---- */
.doors {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(268px, 1fr));
gap: 18px;
}
.door {
position: relative;
font: inherit;
text-align: left;
cursor: pointer;
background: var(--zk-white);
border: 1px solid var(--zk-line);
border-radius: var(--r-lg);
box-shadow: var(--sh-sm);
padding: 22px 22px 20px;
display: flex;
flex-direction: column;
gap: 10px;
overflow: hidden;
transition: box-shadow var(--t), transform var(--t-fast), border-color var(--t-fast);
}
/* The accent bar is the door's handle: 3px at rest, the full brand gradient
once the pointer is on it. */
.door::before {
content: '';
position: absolute;
inset: 0 0 auto;
height: 3px;
background: var(--grad-blue);
transform-origin: left;
transition: height var(--t);
}
.door:hover {
border-color: var(--zk-blue-light);
box-shadow: var(--sh-md);
transform: translateY(-2px);
}
.door:hover::before {
height: 5px;
}
.door:focus-visible {
border-color: var(--zk-blue);
box-shadow: var(--ring);
}
.door strong {
font-size: 1.02rem;
font-weight: 500;
letter-spacing: -0.01em;
color: var(--zk-ink);
}
.door p {
margin: 0;
font-size: 0.82rem;
color: var(--zk-muted);
line-height: 1.55;
}
.door .chip {
align-self: flex-start;
}
/* ---- panel ---- */
.panel {
background: var(--zk-white);
border: 1px solid var(--zk-line);
border-radius: var(--r-lg);
box-shadow: var(--sh-sm);
padding: 24px 26px;
margin-bottom: 22px;
}
.panel__head {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 20px;
margin-bottom: 18px;
}
.panel__title {
margin: 0;
font-size: 1.06rem;
font-weight: 500;
letter-spacing: -0.012em;
}
.panel__sub {
margin: 5px 0 0;
font-size: 0.82rem;
color: var(--zk-muted);
max-width: 62ch;
line-height: 1.55;
}
/* ---- actions ---- */
.acts {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.act {
font: inherit;
cursor: pointer;
text-align: left;
background: var(--zk-white);
border: 1px solid var(--zk-line);
border-radius: var(--r-md);
padding: 11px 16px;
display: flex;
flex-direction: column;
gap: 3px;
min-width: 196px;
transition: border-color var(--t-fast), background var(--t-fast), box-shadow var(--t-fast), transform var(--t-fast);
}
.act:hover {
border-color: var(--zk-blue-light);
background: var(--zk-tint);
box-shadow: var(--sh-sm);
transform: translateY(-1px);
}
.act.is-open {
border-color: var(--zk-blue);
background: var(--zk-tint-blue);
box-shadow: var(--ring);
transform: none;
}
.act strong {
font-size: 0.885rem;
font-weight: 500;
}
.act__by {
font-size: 0.72rem;
color: var(--zk-muted);
}
.acts__form {
margin-top: 22px;
padding-top: 22px;
border-top: 1px solid var(--zk-line-soft);
animation: zk-rise 0.24s var(--ease) both;
}
/* ---- what the machine is doing ----
Shown where an empty action bar used to be. Most stages are carried by an AI
employee that takes a minute or two, and a screen that says nothing for two
minutes reads as broken. */
.doing {
display: flex;
align-items: flex-start;
gap: 14px;
margin-bottom: 22px;
padding: 16px 20px;
border-radius: var(--r-lg);
border: 1px solid var(--zk-blue-light);
background: var(--zk-tint-blue);
}
.doing div {
display: flex;
flex-direction: column;
gap: 3px;
min-width: 0;
}
.doing strong {
font-size: 0.95rem;
font-weight: 500;
color: var(--zk-blue-dark);
}
.doing span {
font-size: 0.82rem;
line-height: 1.5;
color: var(--zk-muted);
}
.doing__pulse {
flex: none;
margin-top: 5px;
width: 10px;
height: 10px;
border-radius: 50%;
background: var(--zk-blue);
box-shadow: 0 0 0 0 rgba(33, 103, 174, 0.5);
animation: zk-pulse 1.9s var(--ease) infinite;
}
@keyframes zk-pulse {
70% { box-shadow: 0 0 0 9px rgba(33, 103, 174, 0); }
100% { box-shadow: 0 0 0 0 rgba(33, 103, 174, 0); }
}
/* ---- what the workflow said ----
The message the API returns per activity, shown verbatim: it is the workflow
telling the operator what it just set in motion. */
.said {
display: flex;
align-items: flex-start;
gap: 14px;
margin-bottom: 22px;
padding: 14px 16px 14px 20px;
border-radius: var(--r-lg);
border: 1px solid var(--zk-line);
border-left: 3px solid var(--zk-blue);
background: var(--zk-white);
box-shadow: var(--sh-sm);
animation: zk-rise 0.24s var(--ease) both;
}
.said p {
flex: 1;
margin: 0;
font-size: 0.88rem;
line-height: 1.5;
color: var(--zk-ink);
}
.said button {
flex: none;
font: inherit;
font-size: 1.1rem;
line-height: 1;
cursor: pointer;
padding: 2px 6px;
border: 0;
border-radius: var(--r-sm);
background: none;
color: var(--zk-grey);
transition: background var(--t-fast), color var(--t-fast);
}
.said button:hover {
background: var(--zk-tint);
color: var(--zk-ink);
}
/* The stage a queue named by need actually maps to. */
.page__stage {
display: block;
margin-top: 4px;
font-size: 0.72rem;
color: var(--zk-grey);
}
/* ---- back ----
An icon, not a sentence: the way out of a record is a known shape and does not
need naming twice on the page. It carries a title and an aria-label, so the
name is still there for a pointer that hovers and for a screen reader. */
.backbtn {
flex: none;
margin-top: 4px;
width: 34px;
height: 34px;
display: grid;
place-items: center;
cursor: pointer;
border-radius: var(--r-md);
border: 1px solid var(--zk-line);
background: var(--zk-white);
color: var(--zk-muted);
box-shadow: var(--sh-xs);
transition: border-color var(--t-fast), color var(--t-fast), background var(--t-fast), box-shadow var(--t-fast);
}
.backbtn svg {
width: 16px;
height: 16px;
transition: transform var(--t-fast);
}
.backbtn:hover {
border-color: var(--zk-blue-light);
background: var(--zk-tint-blue);
color: var(--zk-blue-dark);
box-shadow: var(--sh-sm);
}
.backbtn:hover svg {
transform: translateX(-2px);
}
.backbtn:focus-visible {
outline: none;
border-color: var(--zk-blue);
box-shadow: var(--ring);
}
.page__lead {
display: flex;
align-items: flex-start;
gap: 14px;
min-width: 0;
}
/* ---- lead: the file beside the story ---- */
.lead {
display: grid;
grid-template-columns: minmax(0, 1fr) 384px;
gap: 20px;
align-items: start;
}
.lead__main {
min-width: 0;
}
/* The trail stays in view while the file is read against it. */
.lead__side {
position: sticky;
top: 90px;
min-width: 0;
}
.panel--rail {
padding: 0;
margin-bottom: 0;
overflow: hidden;
}
.panel--rail .panel__head {
padding: 20px 22px 0;
margin-bottom: 14px;
}
.lead__feed {
max-height: calc(100vh - 210px);
overflow-y: auto;
overscroll-behavior: contain;
padding: 0 22px 20px;
}
/* One column below the width where a 384px rail stops paying for itself. */
@media (max-width: 1180px) {
.lead {
grid-template-columns: minmax(0, 1fr);
}
.lead__side {
position: static;
}
.lead__feed {
max-height: 560px;
}
}
/* ---- tabs ----
Underline rather than pills: these swap the whole panel below them, which is
what a tab is for; a pill segment reads as a filter on shared content. The
2px rule lives on the button, so a strip that wraps to two rows still marks
the active one correctly. */
.tabs {
display: flex;
flex-wrap: wrap;
gap: 2px;
margin-bottom: 20px;
border-bottom: 1px solid var(--zk-line);
}
.tab {
font: inherit;
font-size: 0.82rem;
white-space: nowrap;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 7px;
padding: 9px 13px;
background: none;
border: 0;
border-bottom: 2px solid transparent;
border-radius: var(--r-sm) var(--r-sm) 0 0;
color: var(--zk-muted);
transition: color var(--t-fast), background var(--t-fast), border-color var(--t-fast);
}
.tab:hover {
background: var(--zk-tint);
color: var(--zk-ink);
}
.tab.is-on {
color: var(--zk-blue-dark);
font-weight: 500;
border-bottom-color: var(--zk-blue);
}
.tab__n {
font-size: 0.66rem;
font-variant-numeric: tabular-nums;
min-width: 18px;
padding: 1px 6px;
border-radius: var(--r-pill);
background: var(--zk-line-soft);
color: var(--zk-muted);
text-align: center;
}
.tab.is-on .tab__n {
background: var(--zk-tint-blue);
color: var(--zk-blue);
}
/* ---- property rows ----
Facts read as label/value pairs on hairlines rather than as a wall of filled
boxes: the tint was carrying no information and made every field shout as
loudly as every other. */
.props {
margin: 0;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(330px, 1fr));
gap: 0 36px;
}
.prop {
display: grid;
grid-template-columns: minmax(96px, 33%) minmax(0, 1fr);
gap: 16px;
align-items: baseline;
padding: 11px 10px;
margin: 0 -10px;
border-radius: var(--r-md);
border-bottom: 1px solid var(--zk-line-soft);
transition: background var(--t-fast);
}
.prop:hover {
background: var(--zk-tint);
}
.prop dt {
font-size: 0.78rem;
color: var(--zk-muted);
line-height: 1.45;
}
.prop dd {
margin: 0;
font-size: 0.875rem;
color: var(--zk-ink);
line-height: 1.45;
overflow-wrap: anywhere;
}
.prop__num {
font-variant-numeric: tabular-nums;
font-weight: 500;
}
/* Prose is not a property. It takes the full width, is labelled above rather
than beside, and is folded by ClampText. */
.prop--note {
grid-column: 1 / -1;
display: block;
margin: 10px -10px;
padding: 14px 16px;
border-bottom: 0;
border: 1px solid var(--zk-line-soft);
border-left: 3px solid var(--zk-blue-light);
border-radius: 0 var(--r-md) var(--r-md) 0;
background: var(--zk-tint);
}
.prop--note:hover {
background: var(--zk-tint);
border-color: var(--zk-blue-light);
}
.prop--note dt {
margin-bottom: 7px;
font-size: 0.66rem;
font-weight: 500;
letter-spacing: 0.09em;
text-transform: uppercase;
color: var(--zk-blue-dark);
}
.prop--note dd {
margin: 0;
}
/* ---- lead file ---- */
.lead__stage {
flex: none;
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 5px;
text-align: right;
}
.lead__stagelabel {
display: block;
font-size: 0.6rem;
font-weight: 500;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--zk-grey);
}
.lead__closed {
font-size: 0.7rem;
color: var(--zk-grey);
}
.lead__stage strong {
font-size: 0.9rem;
font-weight: 500;
color: var(--zk-blue-dark);
padding: 6px 14px;
border-radius: var(--r-pill);
background: var(--zk-tint-blue);
border: 1px solid var(--zk-blue-light);
}
/* A closed lead is not a live stage; it should not wear the live stage's blue. */
.lead__stage strong.is-closed {
color: var(--zk-muted);
background: var(--zk-tint);
border-color: var(--zk-line);
}
/* ---- renewal countdown ---- */
.due {
display: inline-flex;
align-items: center;
font-size: 0.75rem;
font-weight: 500;
padding: 3px 10px;
border-radius: var(--r-pill);
white-space: nowrap;
}
.due--lapsed {
background: var(--zk-danger-tint);
color: var(--zk-danger-ink);
border: 1px solid var(--zk-danger-line);
}
.due--urgent {
background: var(--zk-amber-tint);
color: var(--zk-amber-ink);
border: 1px solid var(--zk-amber-line);
}
.due--soon {
background: var(--zk-tint-blue);
color: var(--zk-blue-dark);
border: 1px solid var(--zk-blue-light);
}
.due--later {
background: var(--zk-tint);
color: var(--zk-muted);
border: 1px solid var(--zk-line);
}
/* ---- lead header meta ---- */
.lead__meta {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin: 0 0 22px;
}
.lead__meta div {
display: flex;
flex-direction: column;
gap: 3px;
padding: 9px 16px;
border-radius: var(--r-md);
background: var(--zk-white);
border: 1px solid var(--zk-line);
box-shadow: var(--sh-xs);
}
.lead__meta dt {
font-size: 0.6rem;
font-weight: 500;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--zk-grey);
}
.lead__meta dd {
margin: 0;
font-size: 0.85rem;
color: var(--zk-ink);
}
.lead__meta--money {
border-color: var(--zk-blue-light) !important;
background: var(--zk-tint-blue) !important;
}
.lead__meta--money dd {
font-size: 1rem;
font-weight: 500;
color: var(--zk-blue-dark);
font-variant-numeric: tabular-nums;
}
/* ── Overview ────────────────────────────────────────────────────────────
The morning page. Three blocks, in the order a person cares: what is
waiting on me, what is running out of time, and how the book looks.
Nothing here is a chart — a demo book is small enough that a number and a
name beat any visualisation of them. */
.sec {
display: flex;
align-items: baseline;
gap: 10px;
margin: 28px 0 12px;
font-size: 13px;
font-weight: 500;
letter-spacing: .02em;
text-transform: uppercase;
color: var(--zk-muted);
}
.sec:first-of-type { margin-top: 8px; }
.sec__hint {
font-size: 12px;
font-weight: 400;
letter-spacing: 0;
text-transform: none;
color: var(--zk-grey);
}
/* Three cards, never more. These are the only queues a person acts in, and
keeping the row short is what makes it readable at a glance. */
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
gap: 12px;
}
.card {
display: block;
padding: 18px 18px 16px;
border: 1px solid var(--zk-line);
border-radius: var(--r-md);
background: var(--zk-white);
text-decoration: none;
color: inherit;
transition: border-color .12s, box-shadow .12s, transform .12s;
}
.card:hover { border-color: var(--zk-blue-light); box-shadow: 0 2px 10px rgba(35,54,111,.07); transform: translateY(-1px); }
.card__n { display: block; font-size: 34px; line-height: 1; font-weight: 300; color: var(--zk-grey); }
.card__t { display: block; margin-top: 10px; font-size: 15px; font-weight: 500; color: var(--zk-ink); }
.card__w { display: block; margin-top: 3px; font-size: 12.5px; color: var(--zk-muted); }
/* A queue with something in it earns colour. One with nothing stays quiet —
the point of the row is that the eye lands on the number that matters. */
.card.is-live { border-color: var(--zk-amber-line); background: var(--zk-amber-tint); }
.card.is-live .card__n { color: var(--zk-amber-ink); font-weight: 400; }
/* Every stage, small. Zeroes are shown rather than hidden: a stage that has
quietly stopped receiving leads is only visible if its zero is on screen. */
.tally {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(124px, 1fr));
gap: 8px;
}
.tally__i {
display: flex;
align-items: baseline;
gap: 8px;
padding: 10px 12px;
border: 1px solid var(--zk-line-soft);
border-radius: var(--r-sm);
background: var(--zk-white);
text-decoration: none;
color: inherit;
transition: border-color .12s, background .12s;
}
.tally__i:hover { border-color: var(--zk-blue-light); background: var(--zk-tint); }
.tally__n { font-size: 18px; font-weight: 500; color: var(--zk-ink); min-width: 1.2em; }
.tally__l { font-size: 12.5px; color: var(--zk-muted); line-height: 1.25; }
.tally__i.is-zero { background: transparent; }
.tally__i.is-zero .tally__n { color: var(--zk-grey); font-weight: 300; }
.tally__i.is-zero .tally__l { color: var(--zk-grey); }
@media (max-width: 720px) {
.cards { grid-template-columns: 1fr; }
}