Browse all of Kata

Dashboards and snapshot cards

Source docs/design/studio/dashboard.mdMarkdown

On this page

Studio's landing shape. A grid of cards that answer one question — what needs me today? — and hand off to the section that can do something about it.

Part of the Konjo design language. The laws in the spine apply here unless this chapter contradicts them. Studio-specific — see the dialect and Studio metrics.

This chapter exists because a completeness test specified Studio's Home screen and found the whole shape described in twenty words — "snapshot cards with a title, a few key numbers/rows, and a '→' link to the full section" — next to a table chapter of 158 lines and a form chapter of 323. The agent invented a grid, a gutter, a span rule, a panel radius, a card-row anatomy, an internal spacing scale, a card-height rule, an ordering rule and a state model, and every one of those inventions was a place two engineers would have chosen differently.

When a dashboard

  • The person is triaging, not browsing — they came to find out what changed, not to look something up.
  • The answer is spread across unrelated domains (money, attendance, testing, people) and no single list holds it.
  • Every region has a real home elsewhere, and this screen is the doorway, not the desk.

If one domain dominates, that is a table or an index with filters, not a dashboard. A dashboard whose cards are all attendance is the attendance screen, wearing six boxes.

Anatomy

HOME                             eyebrow, text.secondary
Blue Heron Martial Arts          display 34/800 — the DOJO, not the screen name
Saturday, Aug 23                 body 15/400, text.secondary
( Blue Heron ) ( Riverside )     dojo chips, only when there is more than one
                            ↕24
┌── the alert slot — at most one, and usually empty ──────────────────────┐
│ Adult Intermediate at 7:15pm has no instructor.       Assign a sub →    │
└─────────────────────────────────────────────────────────────────────────┘
                            ↕24
┌ Today ─────────────── span 2 ─┐ ┌ Needs attention ─────┐
│ Today                4 classes│ │ Needs attention     7 │  title 22/700 ⟷ caption
│                          ↕12  │ │                       │
│ Kids Beginner                 │ │ Ana Torres            │  rowTitle 16/600
│ 6:00pm · Marcus Webb          │ │ ( Waiver missing )    │  caption / pills
│ · 8 booked                    │ │                       │
│                          ↕12  │ │                       │
│ Adult Intermediate  ( No sub )│ │ …                     │
│ 7:15pm · Unassigned           │ │                       │
│ · 12 booked                   │ │                       │
│                          ↕16  │ │                  ↕16  │
│ Open the schedule →           │ │ Open the risk queue → │  label 13/700, pinned to the floor
└───────────────────────────────┘ └───────────────────────┘
                            ↕24
┌ Growth ──────┐ ┌ Testing ─────┐ ┌ Birthdays ───┐
└──────────────┘ └──────────────┘ └──────────────┘
                            ↕24
┌ Money ─────────────── span 2 ─┐
└───────────────────────────────┘

The screen inventory puts six cards on Home — Money, Today, Needs attention, Growth, Testing, Birthdays — and Money is the one blocked on a product fact (refund and revoke semantics), not on a design one. The sketch shows six so nobody builds five and calls it done.

The grid

Value
Columns 3 at ≥1280. Not 4 — a 4-column card at Studio's widths holds a title and two rows before it lies about how much fits
Gutter spacing.s24, both axes — the same value as panel→panel in metrics, because that is what it is
Column width equal, minmax(0, 1fr). Never content-driven: a grid whose columns resize as the data changes cannot be learned
Span a card may span 2; never 3, which is a section, not a card
Row alignment align-items: stretch — cards in a row are the same height, and the footer link pins to the floor with margin-top: auto
Card count 3 to 6. Fewer is a detail screen; more is a screen with no opinion

One card may span 2, and it is the one with the most fields per row. A row carrying four facts (name, time, person, count) needs the width; a row carrying two does not. If two cards both want the span, one of them has too many columns and belongs in a table.

Card order is fixed and never reorders by urgency

The card an owner needs is in the same place every morning. This is the same law as stable column widths and for the same reason: a layout that changes shape with its data cannot be learned, and a dashboard is looked at every day by the same person.

Urgency is expressed by the alert slot and by pill tone inside a card — never by moving a card, resizing one, or colouring its whole surface.

The alert slot — how a dashboard spends its budgets

This is the part of the shape that no other pattern has, and the part most likely to be got wrong.

Every other screen in Konjo has a fixed subject, so the four budgets can be spent at design time: the designer decides which thing is loud, and it is the same thing on every render. A dashboard's most important fact changes daily — on Tuesday an uncovered class, on Wednesday three unsigned waivers, on Thursday nothing at all — and loudness in this system is a property of a component, not of a fact.

So the emphasis is allocated to a slot, not to a card:

  • One alert slot, directly under the page header, above the grid, full content width, in flow — never floating, never a toast. See notifications.
  • At most one alert renders, ever. Two urgent things is one alert plus a pill.
  • It renders only when a stated bar is met. What clears the bar is a product fact, not a design judgement — "which costs the dojo more, an uncovered class or an unsigned waiver" is a business answer. If the bar for a surface is not written down, the slot renders only for facts whose urgency is unambiguous, and you name the missing bar rather than inventing a ranking.
  • On a quiet morning the slot is empty and the page has no loud element. That is correct. The skill's closing bar — if you cannot point at the one loud thing within a second, it isn't finished — is asked of a screen with a fixed subject. Here, the absence of an alert is the answer to the screen's question, and it is a good answer. Never manufacture urgency to fill the slot: no "all clear" banner, no green celebration, no card promoted to loud because nothing else was.
Fill feedback.errorFill, or feedback.warningFill if the bar it cleared is a warning-tone fact
Border 1px matching feedback.*Border — a fill alone is ~1.02:1 on the page and reads as a different background
Text caption 13/400 in the matching feedback.*Text
Radius radius.card 12
Padding spacing.s16
Action exactly one, a text link — label 13/700 in text.primary, min-height controlHeight.chip 32

The alert does not spend the red role. feedback.errorText reports a fact; brand.red invites an action. See what a status means. A dashboard normally spends zero of the red role, zero loud blocks and zero filled primaries, and one uppercase register on the eyebrow. Zero is not a failure on this shape.

The card

Token
Surface surface.card on surface.page. Tone separates it; see tables
Radius radius.card 12 — a Studio panel is a card, not a radius.large feature block
Border none required. A hairline is an optical edge, never the separator
Shadow, gradient never
Padding spacing.s16
Title typography.title 22/700, text.primary
Status line, beside the title caption 13/400, text.secondary, right-aligned. Usually a count — "4 classes", both plural forms written out, the unit on every row that carries one. It may instead be the card's one framing fact where a count is not the answer: "Next test Sep 14". One or the other, never both
Title → first row spacing.s12
Row → row spacing.s12
Last row → footer link spacing.s16
Footer link label 13/700, text.primary, min-height controlHeight.chip 32, pinned with margin-top: auto
Arrow → typed, or iconSize.inline 16 — one or the other on a screen, not both

The card is not a link. Its rows and its footer link navigate; the card body does not. Otherwise the same destination is reachable twice in one viewport and a keyboard user tabs through a card-sized target with no name.

Three cards, three shapes, and no fourth:

A row card

Rows of records. Subject rowTitle 16/600 text.primary; supporting line caption 13/400 text.secondary; min-height controlHeight.chip 32.

  • Five rows maximum, then the footer link. A card is a sample, not a list.
  • At five or fewer, no hairlines — 12pt of space groups them, per L3. Above five you are building a table in a box; move it.
  • The subject leads. Never invert to put a time or a date first — an inverted row is anti-pattern #12.
  • One status pill per row, right-aligned. More than one and the row has become a table row. Where a record genuinely has several reasons, show the highest tone and enumerate all of them in the accessible name.
  • Row actions are text links, label 13/700, never buttons. Five bordered buttons down a card is five controls of equal weight competing with the footer link.

A stat card

Label, value, hint. See charts for when a number should be a chart instead.

  • Label: eyebrow, text.secondary.
  • Value: typography.metric 28/800, text.primary. Never hero — that is a loud block, counted per instance.
  • Hint: caption 13/400. The comparison lives here ("+12 vs last month"), and its sign is the only place a feedback.* tone is legal on a stat card.
  • At most three stats in one card. Four is a table.

A mixed card

One stat on top, up to three rows under it. Used when the number needs naming — "6 test-ready" over the three students closest to it. The stat and the rows must be the same fact; a number over unrelated rows is two cards pretending to be one.

States

Each card loads, empties, and fails independently. A dashboard assembles from unrelated queries, and one slow endpoint must not hold the other five.

Loading

  • Under 1s, nothing. See states.
  • Then, per card: the frame renders immediately — title and footer link — and the body is Skeleton.Text at the line height of the token it stands in for. No pulse, no shimmer. This is the same rule as a table's header rendering before its rows.
  • A dashboard is the daily landing screen, so it always qualifies for skeletons: the person has seen this layout before by definition.
  • Skeletons are hidden from assistive tech; completion is announced once, politely, for the page — not six times, once per card.

Empty — nothing today

One line of body 15/400 in text.secondary, left-aligned, in flow. No action, no illustration, never centred in a void.

No classes today. · Nobody needs attention today. · No birthdays in the next 30 days.

The card still renders. (Shape-local. It overrides the detail-screen rule deliberately.) states says a section with nothing to say does not render, and that rule is written for a detail screen, whose sections vary by record. A dashboard's grid is fixed, and a card that disappears on a quiet day changes the page's shape every morning — which is the thing card order is fixed exists to prevent. On this shape, "nothing today" is an answer worth printing.

Not yet set up — the third state

Empty means nothing happened. Not-yet-set-up means this was never switched on, and reporting the first when the second is true is the design lying to the owner. A dashboard is where the difference shows, because a new dojo's Home is mostly unconfigured.

One line of body 15/400, plus one text link — this is the actionable-emptiness exception:

Lead capture isn't turned on. · Set up your public page →

Tell them what is off and where the switch is. Never dress it as data ("0 leads"), and never as an error.

Error — one card fails

The card keeps its title and footer link and replaces its body:

  • feedback.errorFill, 1px feedback.errorBorder, radius.card 12, spacing.s16 padding.
  • One line of caption in feedback.errorText. No codes, no raw messages.
  • Retry is a bordered secondary, controlHeight.dense 36 — a state's action inherits the weight of what it replaced, and what it replaced was a list, not a primary action.
  • Every other card keeps rendering.

Error — the page fails

Nothing else is on screen, so the retry is the filled primary: eyebrow, title 22/700, one body line, one filled button at controlHeight.primary 48.

Responsive

Studio's stated range is 1280–1440, and a laptop outside it is not a reason to invent a phone layout.

Viewport Behaviour
≥ 1440 3 columns; they grow, there is no max width
1280–1439 3 columns
1024–1279 2 columns; the spanning card spans both
< 1024 1 column; the rail collapses to icons with aria-labels and the cards keep their order

The page never scrolls horizontally. A card that cannot fit its content at 1024 has too many columns in its rows.

Accessibility

The web contract in accessibility covers the general rules; these are the ones this shape needs.

  • Each card is a <section> with an aria-labelledby pointing at its <h2>, so a screen reader can list the regions and jump between them. The count line is the section's aria-describedby.
  • <h1> is the page title, <h2> is every card title. Do not skip to <h3> because a card looks smaller than a page.
  • The alert slot is not role="alert". It is present at page load, so nothing changed — role="alert" would interrupt the screen reader every single morning. It is a labelled <section> like the cards. role="alert" is for something that appears after an action.
  • A row action names its row: aria-label="Assign a sub for Adult Intermediate at 7:15pm", never bare "Assign".
  • A row with several status reasons enumerates all of them in its accessible name, even when only the highest tone is drawn.
  • Rows are separate tab stops on the web. Mobile's "group a row into one stop" is a VoiceOver rotor idiom; on the web a row with a link, a pill and a second link is correctly two stops, and collapsing it into one hides the second action from a keyboard.
  • A skip link is mandatory on every Studio screen: the rail is ~25 links and comes before the content in DOM order on every page.
  • Every pill carries its word — status is never colour alone.

The self-check

  • Can the owner name the one thing that needs them, in under a second, on a busy morning?
  • On a quiet morning, does the page say so plainly rather than performing calm?
  • Is every card in the same place it was yesterday?
  • Does every card end in a doorway — a link to the place the work actually happens?
  • Is any card doing a table's job? Move it.