Sagix · brand & platform foundations DS v1.5 · brand-level extract · not product-specific Sagix design system brand layer · v1.5 · August 2026 The Sagix layer every Sagix product inherits Everything below is brand and platform level: the identity, the colour and type systems, the foundations, the icon rules, the voice and the product-UI conventions that hold across any Sagix interface. Nothing here belongs to one application. In scope — reuse verbatim Logo and lockups · colour ramps and semantic families · type scale · spacing, radii, motion, grid · theme and density axes · icon system · voice · chip, control, table, overlay and accessibility conventions · adoption rules. Out of scope — per application Screen layouts and page compositions · domain vocabularies and state registers · screen inventories and navigation trees · app chrome and data adapters · anything whose meaning is owned by one product's engine. Those live in the product that owns them. 01 Brand — what the system is for, and the four principles that settle arguments 02 Identity — mark, wordmark, lockups, clear space, minimums, misuse 03 Colour — ramps, surfaces, text ladder, semantic families, both themes 04 Typography — two families, the scale, numerals, dates and money 05 Foundations — space, radius, motion, grid, and the two axes 06 Iconography — grid, stroke, sprite, inventory, how to add one 07 Voice — how the product speaks, including when it refuses 08 Product UI — chips, controls, tables, nav, overlays, layering, a11y 09 Adoption — the carry-over kit, the API contract, versioning Section 01 Brand Sagix builds instruments for people who are accountable for a record — auditors, controllers, risk owners, regulators. The brand's job is to look like something you could defend in a committee room: exact, quiet, and unmistakably the same product from screen to certificate to PDF. Principle 01 An instrument, not a brochure Someone scans 248 rows before their second coffee. Density is the feature: compact is the default for anything tabular, and decoration that costs a row is decoration we cut. Comfortable exists for tablets and for people who ask — never as the design target. Principle 02 Scarcity is what makes saffron mean something Saffron marks exactly four things: the one primary action in view, the active location, the focus ring, and a citation. A screen with six saffron elements has none. Do primary button · active nav · focus ring · citation · one KPI Don't body text on light · every chip · zebra rows · icons · hover fills · warnings Principle 03 The record is the product Every state change is attributable, timestamped, and reversible only by a new event. The UI never implies deletion; it shows supersession. Machine-assisted actions carry a human actor. When the system does not know, it says so rather than rounding to a confident number. Principle 04 Elegance is legibility at density Air belongs where people orient — page headers, KPI bands, empty states — and nowhere else. Structure is carried by whitespace and hairlines first; cards only when containment is real. The test: cover the data, and the page should still explain itself. What the brand never does. No gradients as decoration. No illustration in an empty state. No emoji. No celebration copy. No third brand colour. No second typeface family. No rounded-friendly softening of a consequence — a destructive act is stated in the words of the act. Section 02 Identity sagix sagix sagix sagix The mark is five bars — 9-unit bar height on a 100-unit grid, alternating full and half widths, the third bar saffron. It reads as a ledger, a rule set, a stack of statements. The geometry is locked: it is artwork, not a layout to be re-drawn. Typeface Public Sans SemiBold (600), lowercase, +1% tracking (0.01em). No bolding, stretching or redrawn glyphs. Colour Ink #161616 · saffron #E89B22 . Two colours only. Reversed lockups use #FFFFFF for the ink parts; saffron holds on both polarities (7.9:1 on ink). Tittle rule The dot on the i is the native glyph, recoloured — identical shape, size, height, x-position. Saffron at ≥ 24px ; ink below 24px and in every single-colour, embossed, engraved or one-colour print use. Proportion Mark height = wordmark baseline → tittle top, optically set to 98% of that measure; mark sits on the wordmark baseline and the g descender hangs below it. Gap mark→wordmark = one bar height = 0.09 × mark height. Clear space One bar height on all four sides of the lockup bounding box. Nothing enters it — no rules, no type, no image edges. Minimum sizes Lockup 96px digital / 24mm print · wordmark alone 12px · mark alone 16px. Below 16px, set the mark on a solid tile rather than bare. Variants Full colour · reversed · one-colour ink · one-colour reversed. The one-colour variants carry no accent at any size. Don't No gradients, outlines, shadows or third colours. Don't recolour individual bars, rotate the mark, set the wordmark in another face, or use the saffron tittle under 24px. Files sagix-lockup.svg and sagix-lockup-reversed.svg — mark as rects, wordmark as live text, tittle isolated as node #tittle for recolouring. Convert text to outlines before handing files to a vendor without the font. Never hand-author a wordmark. Naming a Sagix product. The lockup never changes for a product; the product name sits beside it, separated by a mid-dot or a hairline, set in Public Sans Medium at the wordmark's cap height, in ink or #4A4D55 — never in saffron, never in a second face, never as a second mark. A product does not get its own accent colour, its own icon or its own logotype: it is a posture on one identity, not a sibling brand. Section 03 Colour Two brand colours, one cool neutral ramp, one warm ecru register for reading surfaces, four semantic families, and a heat sequence. Both themes are authored independently — dark is never derived from light by inversion, and every figure below was measured, not assumed. #161616 Ink · brand, primary text, closed states, document ink. Theme-invariant identity. #E89B22 Saffron · one primary action, active location, focus ring, citation. Never text on light. 3.1 Neutral ramp · light · thirteen steps n-0 #FFFFFF n-25 #FCFCFD n-50 #F8F8FA n-100 #F1F2F4 n-150 #E9EAEE n-200 #DFE1E6 n-300 #C9CCD4 n-400 #A8ACB6 n-500 #878B96 n-600 #62666F n-700 #4A4D55 n-800 #33353B n-950 #161616 3.2 Warm wells · the ecru register — reading surfaces, never a page canvas w-25 #FDFBF7 w-50 #FBF7EF w-100 #F5EFE1 w-200 #EFE7D6 Ecru is the vocabulary for something authoritative rather than active : a quotation, a document well, a read-only microsite, a settled baseline. Wells, never canvases. 3.3 Surface and text roles · light bg-canvas n-50 · the page bg-surface n-0 · cards, rows, panels bg-sunken n-100 · inset areas, table heads bg-well w-50 · reading wells bg-hover n-50 bg-selected #FDF3E4 hairline n-150 · structure inside a card border n-200 · a real edge border-strong n-300 · controls, dividers that must be seen text-primary n-950 · 16.9:1 text-secondary n-700 · 8.5:1 text-tertiary n-600 · 5.8:1 text-muted #6D717C · 4.88:1 on surface …on sunken n-600 · muted's pair token, mandatory there text-inverse n-25 paper / ink #FFFFFF / #161616 · both themes, never inverts scrim rgba(18,22,31,.38) focus ring 2px surface + 2px saffron, two-ring Four text steps, in that order, never skipped. Muted is never body text — it is for a stamp, an attribution, a count. A text step that fails its floor on the commonest surface in the product is not a text step: move the floor, do not add a second token. 3.4 Accent and semantic families · light · bg / border / text / emph Accent #FDF3E4 #F3D2A0 #8F4E04 · 6.6:1 #E89B22 Success #E9F6EF #B9E2CB #0E6B41 · 6.6:1 #12885A Warning #FCF6E4 #E7D49A #7A5B02 · 6.4:1 #C99A0B Danger #FDECEA #F5C4BE #A32B22 · 6.2:1 #C43B30 Info #ECF3FA #BCD7EE #15537F · 7.3:1 #1F6FB2 Warning is amber and deliberately separable from brand saffron — a status must never read as an action. Info carries two extra plates: #DCEAF7 strong (handed over) and #F5F8FC in-flight with a inset 2px 0 0 leading bar (actively being worked). Aging uses one warm five-step heat sequence — #F1F2F4 · #FDF3E4 · #FBE7C8 · #F6D3AB · #EDBE85 · #C43B30 — never a rainbow. 3.5 Elevation · light raises with shadow, dark raises with surface elev-1 · rows, quiet cards elev-2 · popovers, menus elev-3 · panels, modals Elevation ink is a cool blue-black at low opacity, and never combined with a border — a raised thing has one edge treatment, not two. In dark, all three shadow tokens resolve to none and separation is carried by two surface steps, so the scrim goes heavier there ( rgba(0,0,0,.58) ). Adding a colour family. A new vocabulary gets its own trio, never a borrowed one: two families that paint the same pixels are two vocabularies a reader cannot tell apart, and a border alone is the weakest separation this system permits. Separate on plate and ink — a visible step is ≥ 1.20:1 between plates and a readable one is ≥ 4.5:1 for text — and state the measured figure beside the value. Floors: text ≥ 4.5:1, UI borders ≥ 3:1 against their surface, in both themes. 3.6 Dark theme · authored, not derived canvas #0D0E10 d-50 #121417 d-100 #16181B d-150 #1D2024 d-200 #24272C d-300 #2E3238 d-400 #3D424A d-500 #565C66 d-600 #767C87 d-650 #8B919B d-700 #A2A8B2 d-800 #CBD0D7 d-900 #EEF0F3 Accent #2A1F0A / #4D3A11 #F2AE45 Success #0F2419 / #1F4433 #6FD39B · 9.0:1 Warning #241E08 / #4A3F12 #E3C55F · 9.1:1 Danger #2A1513 / #55231F #F19B92 · 8.1:1 Info #0F2130 / #1E3D53 #8CC0E6 · 8.6:1 Dark keeps the same brand saffron for fills and lifts the accent text to #F2AE45 . Its text ladder is #EEF0F3 · #A2A8B2 · #8B919B · #7E848F — four steps that stay four steps: a ladder that collapses to three in one theme is a light-only ladder with a dark alias. Muted is barred from wells in dark (4.35:1); use tertiary there. Section 04 Typography Public Sans 300 · 400 · 500 · 600 · 700 Open-licensed, drawn for public records and screens. Institutional without being cold, and it carries a 12px table cell as well as a 48px display line. Everything that is not a code, an identifier or an eyebrow is set in it. IBM Plex Mono 400 · 500 The machine register: identifiers, hashes, timestamps, engine lines, refusal codes, section eyebrows and every value a person may need to read back character by character. It is never body copy and never a heading. Token Size / line Wt Tracking Where it is used display-lg 48 / 52 600 −0.028em covers, marketing, section openers display 34 / 40 600 −0.022em page title on a landing surface h1 24 / 32 600 −0.012em screen title h2 19 / 26 600 — card and section heading h3 16 / 22 600 — sub-heading, panel band body-lead 16 / 27 400 — the one paragraph that orients a screen body 14 / 22 400 / 500 — prose, form values; 500 for emphasis body-sm 13 / 20 400 — secondary prose, help text, empty states table 13 / 18 400 — comfortable density rows table-dense 12 / 16 400 — compact density rows — the default label 12 / 16 500 — field labels, chips, column heads caption 11 / 15 400 — stamps, attribution, footnotes overline 11 500 0.12em mono eyebrows, uppercase mono 11 / 15 400 — ids, digests, engine lines kpi 52 / 52 600 −0.03em one figure per band; unit at 24px Numerals Tabular figures everywhere a number can be compared or stacked — tables, KPIs, currency, dates, aging, countdowns, identifiers. A number that moves as it updates is a number nobody can scan. 1,240,000 0.0125 −11 days Dates and money Render in the viewer's locale; store and export as ISO 8601. Any cross-entity export states its locale in the header. Currency always shows its symbol, and the grouping follows the locale (lakh/crore where that is the locale). Ambiguous month/day order is never used in email or print — those render 18 Jun 2026 . Emphasis is weight 500 and ink , never italics, never colour alone, never uppercase. Two families, and no third: a product that needs a display face has a layout problem, not a type problem. Section 05 Foundations 5.1 Spacing · 4px base, eleven steps 4 8 12 16 20 24 32 40 48 56 64 5.2 Radii xs 3 · sm 4 · md 6 · lg 8 · xl 12 · pill 999 Controls and inputs take sm; cards take lg; panels and modals take lg; a chip is a pill or a 3px box, and which of the two it is carries meaning (§8.1). 5.3 Motion fast 100ms · base 150ms · slow 200ms ease cubic-bezier(.2, 0, .2, 1) Motion confirms a state change; it never introduces one. All three durations resolve to 0ms under prefers-reduced-motion , and anything streamed renders as a complete block instead. No parallax, no entrance animation on data, no spinner where a skeleton row will do. 5.4 Grid and breakpoints 12 columns · content max 1600px · gutters follow density (16px compact, 24px comfortable) · breakpoints sm 768 · md 1024 · lg 1280 · xl 1600 . The 1280px boundary is where a docked side panel stops being an overlay and becomes part of the layout. 5.5 Two axes · theme × density Both are attribute scopes on the root — [data-theme] and [data-density] — and never component props. A component that takes a dense prop lets two rows of one table disagree. Token Compact — the default Comfortable row-height 32px 44px cell-pad-y / x 6 / 8 12 / 12 control-height 28px 36px control-pad-x 10px 14px card-pad 16px 24px stack-gap 8px 16px table font 12 / 16 13 / 18 hit-target-min 28px 36px Compact is not available below 1024px — the media query forces comfortable values there regardless of the attribute. On touch, an extended invisible hit area keeps every target at 44px even when the row is 32px. Section 06 Iconography The drawing spec 20 × 20 grid · 1.5px stroke round caps and joins · fill: none stroke: currentColor One weight, one grid, no filled variants and no duotone. A dot inside a glyph is the one licensed fill. Colour comes from the text colour of the control the icon sits in — an icon is never coloured on its own. Delivery One hidden SVG sprite of , injected synchronously by sagix-icons.js ; consumers reference . The injection must target document.documentElement when there is no body yet: a sprite that arrives after its references is a sprite that arrives too late , and does not reliably re-resolve later. 6.1 Size ladder and accessibility 12px disclosure chevrons 14 – 16px inside buttons, menu items, chips 18px navigation destinations, in both the wide column and the icon-only rail aria Every icon is aria-hidden , without exception. The accessible name lives on the surrounding control — never on the glyph. distinctness A new glyph must be tellable apart from its neighbours at 16px , because an icon-only rail is the hardest case. Two destinations that share a glyph make the rail lie about identity. one meaning One glyph, one meaning, one owner. If a second concept wants an existing glyph, draw a new one — and record what it had to stay distinct from. 6.2 The set · 46 glyphs dashboard requests evidence trail entities chart admin shield search filter plus minus check close chevron-down chevron-right alert info inflight upload download lock eye user more external flag link bell mail calendar clip refresh grid-rows table door observation cluster matrix horizon batch queue agent annotate baseline sagi Roughly two thirds are universal platform glyphs; the remainder are domain marks a product may not need. Take the whole sprite anyway — it is one file, and a partial copy is the start of two sprites. A missing glyph is a change to the system, not a local drawing. Section 07 Voice Calm, precise, specific. Present tense. No exclamation marks, no emoji, no oops , no congratulation. State the fact, then the consequence, then the option. Numbers over adjectives. Never blame the reader, and never dress a machine action as a personality. Write “Nine items are overdue in the western region. The oldest has been unassigned for 11 days.” “Returned to the preparer. A reason is required before the item leaves review.” “12 records exist here; your grant covers one entity only.” Not “Uh oh! Looks like some items need attention!” “Great job — you're almost there!” “Something went wrong. Please try again later.” “Thinking really hard about this…” Empty states A sentence, not a graphic — no illustration, no icon, no “get started” button. Three facts: what happened (nothing matched), why (which filter is doing the work, and the count it would return), what to do (one escape, one reset). It sits exactly where the rows would have been, and the section is rendered rather than hidden: a section that disappears when empty teaches the reader it does not exist. Withheld ≠ empty If the emptiness is a permission boundary, say so instead of implying the data is absent, and always state the count of withheld items. A reassurance where a refusal belongs is the most expensive sentence in the product. Refusals A refusal is content, not an error state. Render it where the press was, carrying the code and the system's own sentence verbatim — never re-worded, never softened, never swallowed into a toast that fires while the surface is still loading. Failures A load failure is a banner in the refusal treatment with role="alert" and the message verbatim; a runtime failure is a toast, because it has a rendered page to appear on. “Not ready” always says which not-ready it is — connecting, or failed. Destructive acts Two stated verbs, never Cancel / OK : a stated keep and a stated act — “Keep it” / “Deactivate”. A confirm never dismisses by doing the thing. Counts The count comes from the selection, never from a typed number, and the label carries it: “Approve 4”, “Share 12 documents”. Pluralisation is a formatter's job so the noun agrees at one and at many. Machine actors An assistant has a short product name and nothing more. Never anthropomorphise it beyond that name — no thinking, no feeling, no first-person enthusiasm — and its trail entries always name the human who acted through it. Section 08 Product UI These are conventions, not layouts. Nothing here prescribes how a screen is composed — no page templates, no mandated column split, no fixed placement of headers, panels or tables. Each product designs its own screens; what must be identical across Sagix is how a state is painted, how a control behaves, how layers stack and how a failure speaks. Where a dimension appears below, it is the default of a shared component (the nav shell's own two widths) or a shared grid ceiling — not a rule about where anything sits on a page. 8.1 Chips · shape is read before colour Neutral state Info state In flight Settled Returned Closed Severity · boxed Classification · tag v1.4 · version Required · marker unrecognised · raw.code Pill A state — something a person owes a person. Semantic family, optional icon, and an in-flight state carries a 2px leading inset bar. Box (3px) A grade or a fact about the thing — severity, tier, lifecycle. Boxed so it can never be mistaken for a state at a glance. Tag A classification — framework, applicability, version. Facts of one class share one plate and are told apart by their word, not by a colour each. Marker Ink only, no plate. For a flag that qualifies a row rather than describing it. Derived markers (overdue, escalation tier) layer onto a state — they are never an extra state. The label Comes from the register that owns the vocabulary, never from a map held beside it. A map keyed by a register's codes is a second copy of that register , and it breaks when the register grows and when it shrinks. Unknown key An unmapped value takes the dashed unrecognised treatment and prints the raw code un-prettified. It never takes a sibling's paint — a value dressed as its neighbour is a defect the paint is hiding. 8.2 Controls Primary act Secondary Ghost Deactivate Not ready ⌘K Geometry Height and horizontal padding are density tokens (28/10 compact, 36/14 comfortable); radius sm; label at 12.5–13px weight 500; icon 14–16px. One primary Exactly one saffron action in view, and its ink is #161616 — 7.9:1 on the accent. Destructive actions are the danger emphasis with white ink, and are never the primary style. Disabled A control that cannot act is genuinely disabled — the DOM property, not an aria attribute alone, and never a handler wired to a no-op. A disabled control tells the truth about its state; a supplied no-op lies quietly. Absent vs disabled Where a capability does not exist for this reader at all, the control is absent , not disabled. Disabled means “not now”; absent means “not yours”. Focus One ring everywhere, declared once at the root and never per component: outline: none; box-shadow: 0 0 0 2px surface, 0 0 0 4px accent on :focus-visible . Two rings so it survives overflow: hidden . Never removed, never replaced by a colour change alone. 8.3 Tables, rows and navigation Rows Hairlines between rows, no zebra. Hover is a surface change, never a saffron fill. A selectable row is keyboard-reachable and marks the current one with aria-current ; the detail it drives is a rail beside the table, not a navigation. Headers Sticky in the in-flow band (z 0–9) on the sunken plate. Sortable columns are buttons in the header cell and the sort state is in the button's accessible name, not in a glyph alone. A long table repeats its in print. Filters Every filter set carries a Clear — per-filter where there are several, plus one “clear every filter” — and the empty state names how many filters are active. Nav shell Where a product uses the shared nav component, its own defaults are a 216px labelled column collapsing to a 48px icon-only rail; a product free-composes its shell if it needs to. Group headings are