Documentation
Arivin design system
The single source of truth for the Arivin digital identity: colour, type, layout, components, motion and the rules that hold them together. This document loads the same stylesheets as the website, so every component below is the production component with live states – not a screenshot of one. It also carries a machine-readable copy of itself, so a language model can design with this system without guessing.
Four principles
Everything below follows from these. When a new page is designed and a rule is missing, these decide.
Code is the source of truth
Every colour, size and easing on the site comes from tokens.css. If a design file and the code disagree, the code is right and the documentation is corrected the same day.
Two surfaces, one system
Every component is defined on the dark ink and on the light sheet. The class .on-sheet is the only switch. There is no second colour theme and no inversion inside a section.
One accent
Arivin Blue carries every action across the site. The secondary palette appears only where a colour carries meaning, such as a figure that signals risk. Never as decoration.
Motion explains or it goes
Every animation is a named preset from the registry. One loud moment per page, the rest quiet. Anything not in the registry does not exist.
Colour
The accent scale is not a decision made for the website. It is the Arivin mark: the five hexagons of the logo are the 100/80/60/40/20 % tints of Arivin Blue from the identity manual.
Contrast, measured
WCAG 2.1 ratios computed from the actual token values, alpha included. One pair is below the threshold and is marked: a system that names its own gaps is more useful than one that hides them.
| Foreground | Background | Ratio | Where it is used |
|---|---|---|---|
| --color-fg | --color-ink | 19.79 | Headlines and primary text on dark. |
| --color-fg-muted | --color-ink | 10.76 | Running text on dark. |
| --color-fg-dim | --color-ink | 5.29 | Captions and dates. Never below 15 px. |
| --color-accent-40 | --color-ink | 9.96 | The accent word inside a dark headline. |
| --color-accent-20 | --color-ink | 14.36 | Hairlines and quiet marks on dark. |
| --color-alarm-soft | --color-ink | 10.14 | A figure that signals risk, dark only. |
| --color-ink-on-sheet | --color-sheet | 17.52 | Headlines and primary text on light. |
| --color-ink-on-sheet-muted | --color-sheet | 5.98 | Running text on light. |
| --color-ink-on-sheet-dim | --color-sheet | 2.91 | Below AA. Non-essential labels only, or raise the alpha to 0.56. |
| --color-accent | --color-sheet | 6.63 | Links and the accent word on light. |
| --color-alarm | --color-sheet | 9.41 | A figure that signals risk on light. |
| --color-fg | --color-accent | 7.17 | Label inside a filled button. |
Type
Archivo for display, Lato for running text. Lato is the brand typeface from the identity manual and carries everything a reader reads; Archivo gives headlines the width and weight that Lato cannot. There is no monospace and no all-caps anywhere in the system.
Future-Proof antimicrobial therapies
Resistance develops faster than we can develop treatments
A unique and novel dual target
8.22M
4.7M
Bacterial biofilms
Platform technology
Scientific validation
Arivin targets bacterial virulence, not bacterial survival.
The therapies bind and neutralize bacterial toxins while interacting with the extracellular polymeric substance of the biofilm.
Nature Communications, 14, 2141, 13 April 2023
Aalto University, photo Mikko Raskinen
Science & Technology
Layout
Twelve columns at 1440, four at 390. Nothing is positioned by hand: every width is a column span, every gap is a token.
| Token | Value | What it controls |
|---|---|---|
| --page-pad | 56px | Page margin left and right. 20 px below 768 px. |
| --gutter | 24px | Gap between grid columns. 16 px below 768 px. |
| --section-pad | var(--space-160) | Vertical rhythm between sections. 80 px below 768 px. |
| --head-h | 88px | Height of the site header. 68 px below 768 px. |
| --measure-hero | 900px | The widest a headline is allowed to run. |
| --measure | 46ch | Reading measure for running text. |
| --person-w | 340px | Width of a person card. |
| --modal-w | 860px | Width of the profile modal. |
| --tap | 46px | Minimum tap target, above the 44 px accessibility minimum. |
| --logo-h | 48px | Logo height in the header. 38 px below 768 px. |
Spacing scale
A value outside the scale is a mistake, not a decision. Distance always comes from gap, padding or margin.
Components
Twelve components, all of them live. Each one carries its anatomy, its states, its responsive behaviour and the rule that governs it. The header, the menu and the modal sit inside a frame so they stay in their own context without taking over this document.
.site-head__logoVariantsLockup: Full, Short, Mark / Colour: Brand, On dark, WhiteAnatomyFive hexagons from the identity manual plus the lowercase wordmark set in two lines. Height is set by --logo-h: 48 px on desktop, 38 px on mobile; width follows.StatesNo interactive states. In the header it is a link to the top of the page.ResponsiveBelow 768 px the height drops to 38 px. Under 120 px of available width, switch to the Mark lockup.RulesNever redrawn, recoloured, stretched or placed on a photograph without a scrim. Keep at least one hexagon of clear space on every side. The White lockup is only ever used on an Arivin Blue field..site-head, .site-navVariantsSurface: Dark, Sheet / State: transparent, .is-scrolledAnatomyFixed, --head-h tall, page padding --page-pad. Logo left, navigation right with four dropdown groups and one button.StatesTransparent until the page scrolls. After 8 px it gains .is-scrolled and a blurred backdrop. Over a light section it gains .is-on-sheet, which swaps the logo file and flips the links to --color-ink-on-sheet. Dropdowns open on hover and on focus-within, so they are reachable by keyboard.ResponsiveBelow 768 px the groups are hidden and the burger appears.RulesThe four groups mirror the information architecture and are not reordered per page. The dropdown is shown open in this document because a static page cannot hover..burger, .sheet-menuVariantsState: closed, openAnatomyBurger 46 px square from --tap, two lines of unequal width. The sheet covers everything below the header and is filled --color-ink-deep. Groups keep their children indented by --space-16.StatesOpening adds .is-menu-open to the body, which also locks page scrolling.ResponsiveExists only below 768 px.RulesThe sheet is a full surface, not a dropdown: the whole architecture is visible at once..btnVariantsStyle: Primary, Ghost (.btn--ghost), Ink (.btn--ink) / Size: Default, Large (.btn--l)AnatomyLabel in the nav text style, gap --space-12, icon --icon, radius --radius-pill. Default padding --space-12 / --space-24; Large padding --space-16 / --space-32.StatesOn hover the fill wipes in from the left over --dur-m, the label flips to ink, and the arrow slides out while a second arrow slides in behind it. Active resets the lift. Focus shows the standard 1 px --color-accent-40 outline.ResponsiveUnchanged. Minimum height already exceeds --tap.RulesThere is no secondary button component: use Ghost. Ink exists because Primary would vibrate against the light sheet..personVariantsSurface: Dark, SheetAnatomyWidth --person-w, gap --space-12. Square portrait on --color-ink-soft, name in .title-s, role in .body-s. The whole card is a button.StatesOn hover the card lifts --space-8, the portrait scales to 1.05 over --dur-l and the name turns --color-accent-40.ResponsiveWidth is fixed; the band scrolls horizontally below 768 px.RulesPortraits are square, shoulders up, on a neutral background. Clicking opens the Modal with the full profile..modalVariantsState: closed, .is-openAnatomyVeil --veil-82 with a --blur-veil blur. White card at --modal-w, radius --radius-s, padding --space-40, portrait and text in a 1:2 grid. Close target 46 px from --tap, pinned to the top right of the card.StatesOpening adds .is-open and locks body scrolling. Closing works from the close target, from the veil and from Escape.ResponsiveBelow 768 px the grid collapses to one column and the portrait is capped at --shape.RulesThe card always sits on .on-sheet, whatever surface opened it. Role, name, education and motivation are all required: none is optional.Peer-reviewed in Nature Communications2023
.proofVariantsSurface: Dark, SheetAnatomyVertical, gap --space-2, padding-left --space-24, 1 px left border in the surface line colour. Claim in bold .body-s, date below in the muted foreground.StatesNone. It is not interactive.ResponsiveUnchanged.RulesOnly for something a reader could verify: a journal, a funding round, a coordinator role. Not for marketing claims..figureVariantsTone: Default, Alarm (.figure--alarm) / Surface: Dark, SheetAnatomyVertical, gap --space-8. Number in .display-num or .display-num-s with tabular numerals so digits do not dance between rows; caption in .body-s.StatesNone, but it is normally paired with data-reveal="count" so the number counts up on entry.ResponsiveThe clamp on the number handles the scale; no separate mobile rule.RulesAlarm is the only place the secondary palette appears anywhere in the system, and only for a value that signals risk..rule-itemVariantsSurface: Dark, SheetAnatomyVertical, gap --space-12, padding-top --space-20, 1 px top border. Title in .title, body in .body-s.StatesNone.ResponsiveStacks into a single column below 768 px.RulesThe default way to list anything that is not a card. The system separates with lines, not containers..fieldVariantsSurface: Dark, Sheet / Type: input, textareaAnatomyLabel in .body-s, input --field-h tall, padding --space-12 / --space-16, radius --radius-s, 1 px border. Fill --color-ink-soft on dark, --color-sheet-pure on light.StatesFocus moves the border to --color-accent. The placeholder uses the dim foreground of the surface and never replaces the label.ResponsiveFull width of its column.RulesA textarea is the same component with min-height twice --field-h and vertical resize only..checkVariantsSurface: Dark, Sheet / State: Off, OnAnatomyHorizontal, gap --space-12, aligned to the top so a two-line label stays tidy. Box --space-20 square, radius --radius-s.StatesOff shows a 1 px border in the surface line colour. On fills --color-accent with a white tick, matching the native accent-color.ResponsiveUnchanged.RulesThe tap target is the whole row, not the box..gridVariantsBreakpoint: Desktop 12, Mobile 4AnatomyCSS grid of --grid-cols columns with a --gutter gap, inside page padding --page-pad.StatesNone.ResponsiveTwelve columns at 1440, four below 768 px with a 16 px gutter.RulesEvery section lays out on this grid. Column spans never overlap: two elements claiming the same column silently push each other onto a new row.Motion
Nine presets, assigned in the markup as data-reveal. A developer never writes an animation: they choose a name from this table.
| Name | What it does | Parameters | Where it is used |
|---|---|---|---|
| fade | Fades up by --reveal-y. | 0.9 s, expo.out | Captions, small items, third-level headings. |
| lines | Lines of text rise out of a mask; the mask is removed afterwards. | 1.1 s, step 0.1 | Headings and paragraphs. |
| chars | Letters rise out of the line mask. | 1.1 s, step 0.018 | One H1 per page. |
| clip | A window opens with clip-path from the bottom up. | 1.2 s, power2.inOut | Photographs, windows, diagrams. |
| card | A panel rises with a slight scale. | 1 s, expo.out | Cards and panels. |
| stagger | Children of a container appear in sequence. | step 0.09 | Lists, rows, bands. |
| rule | A line draws from left to right. | 1.2 s, power2.inOut | Dividers and connectors. |
| count | A number counts up on entry. | 1.8 s, power2.out | Large figures. |
| bar | A bar fills to the share in data-bar. | 1.4 s, expo.out | Progress bars and scales. |
One loud moment
Per page, exactly one element may be dramatic. Everything else enters quietly. A page where everything animates reads as noise.
Once, at 85 %
Reveals fire when an element reaches 85 % of the viewport height and never repeat on the way back up.
The page works without it
Under prefers-reduced-motion or the ?static switch, every element is simply visible and the layout is identical. Motion is never load-bearing.
Accessibility
Not a checklist bolted on at the end. These are properties of the tokens themselves, so a new page inherits them.
Focus is visible
Every interactive element gets a 1 px --color-accent-40 outline offset by --space-4, set once on :focus-visible in base.css. It is never removed.
Targets are 46 px
The --tap token sets the burger, the modal close and every icon-only control to 46 px square, above the 44 px minimum.
Contrast is a number
Every text-on-surface pair is measured, listed, and re-checked when a token changes. One pair currently falls short and is marked.
Reduced motion is respected
The reveal engine checks prefers-reduced-motion before it runs and shows the final state instead. Transitions fall back to --dur-s.
What the system does not allow
A system is defined as much by what it refuses. Every rule here is enforced by a linter that runs before each release, so none of it is advice.
No raw values
A hex colour or a pixel gap written anywhere other than tokens.css fails the build. Need a new value? Add the token first.
No all-caps, no monospace
The small label above a heading is sentence case in the text face. Letter-spaced caps in a technical font are the fastest way to make a biotech site look like every other one.
No spacer elements
Distance comes from gap, margin and padding. An empty div used as a strut fails the build.
No font sizes by hand
Text size is set only by a class from the scale. A font-size inside a section rule fails the build.
No unnamed motion
A data-reveal value outside the registry fails the build. New behaviour is documented first, then implemented.
No second accent
The secondary palette may colour a figure that carries risk. It may not colour a button, a link, a heading or a background.
For AI and tooling
This page carries a complete machine-readable copy of itself: every token with its value and purpose, the whole type scale, the measured contrast pairs, all twelve component specs, the motion registry and the rules. Hand this file to a language model and it can design inside the system instead of guessing at it.
Where the data is
Inside this page as <script type="application/json" id="arivin-spec">, and alongside it as design-tokens.json. Both are generated from styles/tokens.css in the same build, so neither can drift from the site.
What is inside
122 tokens grouped by role, 14 text styles with font, size, leading and tracking, 12 measured contrast pairs, 12 component specs with anatomy and states, 9 motion presets, the accessibility rules and the list of what the system forbids.
How to use it
Attach this HTML file, or just design-tokens.json, and ask for the artefact you need: a deck, a one-pager, a social template, a new page. The model has the values, the names and the rules, so what it produces can be checked against the same system.
A prompt that works
“Read the JSON in #arivin-spec. Build a 10-slide investor deck for Arivin Therapeutics using only the tokens, type scale and components it defines. Dark sections use --color-ink with --color-fg; light sections use --color-sheet with --color-ink-on-sheet. One accent only. No all-caps, no monospace, no second accent colour.”
Where it lives
Four stylesheets, one motion module and two generated documents. A developer joining the project needs nothing else to stay inside the system.
| File | What is in it | May I edit it? |
|---|---|---|
| styles/tokens.css | Every colour, size, easing and duration. The only file where raw values are allowed. | Yes – and update this document in the same commit. |
| styles/base.css | Reset and the fourteen text scale classes. | Rarely. Adding a scale step is a system decision. |
| styles/components.css | The twelve components documented here. | Yes, for a new component. |
| styles/sections.css | Layout of individual sections. Composition only, no new values. | Yes. |
| js/motion.js | The nine reveal presets and the ?static switch. | Only together with the motion registry. |
| design-system.html | This document. Loads the same stylesheets as the site, so it cannot drift. | Yes, through scripts/build_system.py. |
| design-tokens.json | Machine-readable export of every token and every component spec. | Generated. Do not hand-edit. |