Skip to main content
PULSE Lab logo
PULSE Lab

Branding

The lab's visual system.

Colour, type, and shape tokens with the rules that govern them. Anything made for the lab — a page, a poster, a slide — should be able to point at this page for every value it uses.

Download brand kit (.zip) Skill document

The skill document plus every SVG, at the paths the document names them by.

PULSE Lab logo — Full colour

Full colour

assets/pulse-logo-colour.svg

The primary mark. Use on white or a very light neutral, in print, on posters, and on slide title cards. Also serves as the favicon.

Download SVG
PULSE Lab logo — Monochrome, knocked out

Monochrome, knocked out

assets/pulse-logo-mono.svg

The mark used in the site header and footer. Same file as the positive mono mark, rendered white via `filter: brightness(0) invert(1)` so it never competes with the navigation.

Download SVG
PULSE Lab logo — Monochrome, positive

Monochrome, positive

assets/pulse-logo-mono.svg

For single-colour reproduction: fax-grade printing, embroidery, engraving, and any context where colour cannot be trusted.

Download SVG

Clear space

Keep free space around the mark equal to half its height on every side. In the site header the mark is 36 px, so nothing sits closer than 18 px to it.

Minimum size

24 px on screen, 8 mm in print. Below that, use the favicon crop rather than shrinking the full mark further.

Lock-up

The mark pairs with PULSE LAB set in bold uppercase at 0.2em tracking, above AI for Oceanography & Health at 0.14em. Never re-typeset the wordmark in another face.

Do

  • Use the knocked-out mono mark on any `ink-*` surface.
  • Use the full-colour mark on white or near-white.
  • Scale the SVG — it is resolution independent.

Don't

  • Recolour the mark to an accent, or add a gradient to it.
  • Place the full-colour mark on a photograph or a mid-tone.
  • Stretch, rotate, outline, or add a drop shadow.

Colour

A dark navy substrate, and four accents that mean something.

The site is dark-theme only. There is no light variant, so these values are the theme rather than one half of it. Click any hex value to copy it.

Surfaces

Seven steps of deep navy. Depth is expressed by stepping up this scale, not by adding a shadow. Sections alternate ink-900 and ink-850 with a hairline between them.

  • ink-950 Page chrome. The header, the footer, and the header band at the top of every page.
  • ink-900 The default page background. Most content sits directly on this.
  • ink-850 Alternating section band, and sub-panels nested inside a card.
  • ink-800 Card and panel surface. Anything that reads as a discrete object.
  • ink-750 Raised surface: secondary buttons, hover states, panel headers.
  • ink-700 Inset dividers and table rules where a hairline is not enough.
  • ink-600 The strongest structural line. Use sparingly.

Accents

Four accents, each attached to a part of the site. An accent identifies what the reader is looking at — it is never applied for variety alone. Use the 300 shade for text on dark, 500 for solid fills and rails, and an 8–12% alpha of 500 for tinted backgrounds.

Azure

azure-500 · #0EA5E9

Azure

Oceanography, and the lab itself.

The primary interactive colour: links, primary buttons, focus rings, the active nav item. Also marks the Team page and journal publications.

Emerald

emerald-500 · #10B981

Emerald

Health sciences, and research programs.

The second domain colour. Marks the Health discipline, the Projects page, alumni, completed states, and code repository links.

Amber

amber-500 · #F59E0B

Amber

The publication archive.

The Publications page header, featured publications, and references to published work from elsewhere in the site.

Iris

iris-500 · #6366F1

Iris

The blog, and editorial writing.

Everything under /blog/ — the masthead rule, post titles on hover, category chips for announcements, and links inside post bodies.

Text

Five steps of contrast. Never go below slate-500 on a dark surface.

  • Aa white Headings and the highest-priority text.
  • Aa slate-200 Emphasised body text, control labels.
  • Aa slate-300 Default body text (`body-text`, `body-lead`).
  • Aa slate-400 Secondary text, metadata, captions, placeholders, footer labels. The floor for text.
  • Aa slate-500 Non-text only — decorative glyphs and disabled marks. Fails 4.5:1 as text on every surface.

Hairlines

Borders carry the structural load. All three are translucent slate, so they work on any surface step without being re-specified.

  • border-line-soft

    Dividers inside a card, between rows of the same object.

  • border-line

    The default border. Card edges, section boundaries, table rules.

  • border-line-strong

    Interactive edges: inputs, buttons, avatar rings.

Typography

Three families, one scale.

All three are system stacks: they render instantly, need no network request, and stay legible on every platform the lab's readers use.

Sans — interface & body

Aa Bb Cc

Scientific machine learning for oceanography and health. 0123456789

Inter, SF Pro Text, -apple-system, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif

Everything except the blog and tabular figures. Headings run at semibold with tight tracking; body copy at regular.

Serif — editorial

Aa Bb Cc

What's happening in the lab — and beyond. 0123456789

Iowan Old Style, Source Serif 4, Palatino Linotype, Palatino, Georgia, serif

Reserved for the blog: the masthead, post titles, article headings, and pull quotes. It is what makes the blog read as its own publication. Do not use it elsewhere.

Mono — data

2026

10.1029/2024MS004405

JetBrains Mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace

Years, counts, dates, DOIs, hex values, and code. Pair with tabular-nums wherever numbers stack vertically.

Scale

Every heading and paragraph on the site uses one of these seven shortcuts. If a size is not listed here, it should not be used.

  • h-page

    Page title

    One per page, in the header band. Caps at 2.75rem.

  • h-section

    Section heading

    Introduces a band of content.

  • h-card

    Card heading

    The title of a discrete object.

  • body-lead

    The standfirst that follows a page title, one or two sentences long.

    Directly under a page title only.

  • body-text

    Default running text, used for descriptions, summaries, and long-form prose blocks.

    Everything else. Cap at `measure` (68ch).

  • eyebrow

    Eyebrow label

    Sits above a heading. Always takes an accent colour.

  • label-meta

    Metadata label

    Terms in a stat strip, field labels, table headers.

Shape & elevation

Tight corners, hairline edges, almost no shadow.

A research lab should read as precise. The whole radius scale is compressed to 2–8px, and elevation is expressed with a border and a surface step rather than a glow.

Radius

rounded-xs

2px

rounded-sm

2px

rounded-md

3px

rounded-lg

4px

rounded-2xl

6px

rounded-3xl

8px

rounded-full

9999px

rounded-sm is the default. rounded-full is reserved for avatars, status dots, and count badges — never for buttons, cards, inputs, or tags.

Elevation

shadow-sm

shadow

shadow-md

shadow-lg

Shadows are neutral and near-black — never tinted with an accent. In practice only floating layers (dropdown menus, the account menu) use one at all.

Layout rhythm

shell
Max width 80rem, gutter 1.25→3rem. Every full-width section uses it.
section-y
3.5rem of vertical padding, 4.5rem from `lg` up.
measure
68 characters. Any run of prose longer than two lines gets it.
band / band-alt
Alternating section surfaces, separated by `border-t border-line`.

Components

The parts, as they actually render.

Everything below is live markup using the shortcuts named beside it, not a screenshot.

Buttons

One primary button per view. Secondary for the alternative path, ghost for anything tertiary. All three share the same 2px radius and azure focus ring.

Chips & status

Neutral chip Current Completed Featured

Chips are rectangular, uppercase, and 0.1em tracked. A leading dot means the chip reports a state; no dot means it reports a category.

Form field

Inputs sit on ink-900 — darker than the panel around them — so a field always reads as somewhere you can type.

Stat strip

Total
27
Ocean
14
Health
13

Counts go in one bordered strip divided by hairlines — never in a row of separate floating cards.

Accent rails

rail-azure

Lab, people, ocean work, journal articles.

rail-emerald

Health work, research programs, alumni.

rail-amber

Publications, findings, featured items.

rail-iris

Blog posts and editorial writing.

Worked examples

The tokens, assembled.

Three compositions built only from the values above, showing how surface, accent, type, and shape combine.

Principal Investigator

2019–Present

PL

A Full Name That Wraps Instead Of Truncating

Identity band: avatar, wrapping name, links. Nothing here is allowed to clip.

View profile →
Journal Ocean Modelling
2026

Venue type sets the rail colour, so an archive reads as more than one long grey list.

A. Researcher · B. Collaborator · C. Student

Ocean DOI 10.1016/j.ocemod.2025.102550
Announcements

The blog is the only place the serif face appears

Serif headlines, an iris accent, and an index-style row rather than a card. That combination is what makes the blog read as its own publication while still sitting on the same surfaces and hairlines as the rest of the site.

Rules worth repeating

  • An accent must mean something. If it does not identify a domain, a status, or a content type, leave it off.
  • Never truncate a person's name, a project title, or a publication title.
  • No blur blobs, no stacked radial gradients, no coloured drop shadows.
  • Prose gets a labelled container and a 68-character measure. Never a bare wall of text.
  • Two links on the same object must not go to the same place, and each label must name its destination.
  • Tokens live in labsite/web/uno.config.ts. Change them there, then update this page.

Skill document

The whole system, as one pasteable file.

Everything above, written out as structured Markdown. Paste it into an assistant as a reference so anything it produces for the lab uses the right colours, type, and assets — or read it as a plain checklist.

PULSE-BRAND-SKILL.md

---
name: pulse-lab-brand
description: The PULSE Lab visual system — colour tokens and their meaning, logo assets and usage rules, typography, shape, and component recipes. Use when producing any artefact for the PULSE Lab: a web page, a poster, a slide deck, a diagram, or a figure.
---

# PULSE Lab Brand System

PULSE is a research lab at Florida State University working on scientific
machine learning for oceanography and health sciences. Its visual system is
dark-theme only: a deep navy substrate with four accents, hairline borders,
tight corners, and almost no shadow. The intent is that the output reads as
precise and instrument-like rather than decorative.

## How to use this document

1. Every colour, size, and radius you use must appear somewhere below. If a
   value is not listed, it is not part of the system.
2. Accents carry meaning. Never pick one for variety — pick the one that
   matches what the reader is looking at.
3. There is no light theme. Do not invent one.

## Colour

### Surfaces

Seven steps of deep navy. Depth is expressed by stepping up this scale, not by
adding a shadow. Sections alternate `ink-900` and `ink-850` with a hairline
between them.

| Token | Hex | Use for |
| --- | --- | --- |
| `ink-950` | #04070E | Page chrome. The header, the footer, and the header band at the top of every page. |
| `ink-900` | #070C17 | The default page background. Most content sits directly on this. |
| `ink-850` | #0B1220 | Alternating section band, and sub-panels nested inside a card. |
| `ink-800` | #0F1828 | Card and panel surface. Anything that reads as a discrete object. |
| `ink-750` | #152036 | Raised surface: secondary buttons, hover states, panel headers. |
| `ink-700` | #1C2A42 | Inset dividers and table rules where a hairline is not enough. |
| `ink-600` | #2A3B57 | The strongest structural line. Use sparingly. |

### Accents

Four accents, each attached to a part of the site. Use the 300 shade for text
on dark, 500 for solid fills and rails, and an 8–12% alpha of 500 for tinted
backgrounds.

| Accent | Base | Means | Applied to |
| --- | --- | --- | --- |
| Azure | `azure-500` #0EA5E9 | Oceanography, and the lab itself. | The primary interactive colour: links, primary buttons, focus rings, the active nav item. Also marks the Team page and journal publications. |
| Emerald | `emerald-500` #10B981 | Health sciences, and research programs. | The second domain colour. Marks the Health discipline, the Projects page, alumni, completed states, and code repository links. |
| Amber | `amber-500` #F59E0B | The publication archive. | The Publications page header, featured publications, and references to published work from elsewhere in the site. |
| Iris | `iris-500` #6366F1 | The blog, and editorial writing. | Everything under /blog/ — the masthead rule, post titles on hover, category chips for announcements, and links inside post bodies. |

Full ramps:

- **Azure** — 200 `#BAE6FD`, 300 `#7DD3FC`, 400 `#38BDF8`, 500 `#0EA5E9`, 600 `#0284C7`, 700 `#0369A1`
- **Emerald** — 200 `#A7F3D0`, 300 `#6EE7B7`, 400 `#34D399`, 500 `#10B981`, 600 `#059669`, 700 `#047857`
- **Amber** — 200 `#FDE68A`, 300 `#FCD34D`, 400 `#FBBF24`, 500 `#F59E0B`, 600 `#D97706`, 700 `#B45309`
- **Iris** — 200 `#C7D2FE`, 300 `#A5B4FC`, 400 `#818CF8`, 500 `#6366F1`, 600 `#4F46E5`, 700 `#4338CA`

### Text

Five steps of contrast. `slate-400` is the floor **for text** — it clears 4.5:1 on
every surface in the palette (6.3:1 on `ink-750`, 7.9:1 on `ink-950`). `slate-500`
measures 3.4–4.2:1 and fails WCAG 1.4.3 as text anywhere; it is kept only for
decorative, non-text marks, where the 3:1 threshold applies instead.

| Token | Hex | Use for |
| --- | --- | --- |
| `text-white` | #FFFFFF | Headings and the highest-priority text. |
| `text-slate-200` | #E2E8F0 | Emphasised body text, control labels. |
| `text-slate-300` | #CBD5E1 | Default body text (`body-text`, `body-lead`). |
| `text-slate-400` | #94A3B8 | Secondary text, metadata, captions, placeholders, footer labels. The floor for text. |
| `text-slate-500` | #64748B | Non-text only — decorative glyphs and disabled marks. Fails 4.5:1 as text on every surface. |

Solid accent fills carry `ink-950` text, not white: white on `azure-500` measures
2.8:1 and fails, while `ink-950` on the same fill measures 7.3:1 and keeps the
accent at full strength. Tag and chip labels on tinted (low-alpha) backgrounds are
still `#FFFFFF`. The tag's own colour is carried by
its dot, its border, and a low-alpha tint of its background — never by the
label text.

### Hairlines

Borders carry the structural load. All three are translucent slate, so they
work on any surface step without being re-specified.

| Token | Value | Use for |
| --- | --- | --- |
| `border-line-soft` | `rgba(148, 163, 184, 0.08)` | Dividers inside a card, between rows of the same object. |
| `border-line` | `rgba(148, 163, 184, 0.14)` | The default border. Card edges, section boundaries, table rules. |
| `border-line-strong` | `rgba(148, 163, 184, 0.26)` | Interactive edges: inputs, buttons, avatar rings. |

## Typography

| Role | Token | Stack |
| --- | --- | --- |
| Everything except the blog and tabular figures. | `font-sans` | Inter, SF Pro Text, -apple-system, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif |
| The blog only: masthead, post titles, article headings, pull quotes. | `font-serif` | Iowan Old Style, Source Serif 4, Palatino Linotype, Palatino, Georgia, serif |
| Years, counts, dates, DOIs, hex values, code. Pair with tabular-nums. | `font-mono` | JetBrains Mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace |

All three are system stacks: they render instantly and need no network
request. The serif face is reserved for the blog and must not appear elsewhere.

### Scale

Every heading and paragraph uses one of these seven shortcuts.

| Shortcut | Rule |
| --- | --- |
| `h-page` | One per page, in the header band. Caps at 2.75rem. |
| `h-section` | Introduces a band of content. |
| `h-card` | The title of a discrete object. |
| `body-lead` | Directly under a page title only. |
| `body-text` | Everything else. Cap at `measure` (68ch). |
| `eyebrow` | Sits above a heading. Always takes an accent colour. |
| `label-meta` | Terms in a stat strip, field labels, table headers. |

## Shape and elevation

| Token | Value |
| --- | --- |
| `rounded-xs` | 2px |
| `rounded-sm` | 2px |
| `rounded-md` | 3px |
| `rounded-lg` | 4px |
| `rounded-2xl` | 6px |
| `rounded-3xl` | 8px |
| `rounded-full` | 9999px |

`rounded-sm` (2px) is the default. `rounded-full` is reserved for avatars,
status dots, and count badges — never for buttons, cards, inputs, or tags.

Shadows are neutral and near-black, never tinted with an accent. In practice
only floating layers (dropdown menus) use one at all.

## Layout rhythm

- `shell` — max width 80rem, gutter 1.25→3rem. Every full-width section uses it.
- `section-y` — 3.5rem of vertical padding, 4.5rem from `lg` up.
- `measure` — 68 characters. Any run of prose longer than two lines gets it.
- `band` / `band-alt` — alternating section surfaces, separated by a hairline.

## Component recipes

- **Primary button** — `azure-500` fill, white label, 2px radius, azure focus ring. One per view.
- **Secondary button** — `ink-750` fill with a `line-strong` border.
- **Ghost button** — transparent with a `line` border.
- **Chip** — rectangular, uppercase, 0.1em tracking. A leading dot means the chip reports a state; no dot means it reports a category.
- **Input** — sits on `ink-900`, darker than the panel around it, so a field always reads as somewhere you can type.
- **Stat strip** — counts go in one bordered strip divided by hairlines, never a row of separate floating cards.
- **Accent rail** — a 2px left border in an accent, marking a block as belonging to that domain.

## Assets

The kit that accompanies this document contains the following files. Reference
them by these exact paths.

| File | Variant | When to use it |
| --- | --- | --- |
| `assets/pulse-logo-colour.svg` | Full colour | The primary mark. Use on white or a very light neutral, in print, on posters, and on slide title cards. Also serves as the favicon. |
| `assets/pulse-logo-mono.svg` | Monochrome, knocked out | The mark used in the site header and footer. Same file as the positive mono mark, rendered white via `filter: brightness(0) invert(1)` so it never competes with the navigation. |
| `assets/pulse-logo-mono.svg` | Monochrome, positive | For single-colour reproduction: fax-grade printing, embroidery, engraving, and any context where colour cannot be trusted. |

Rules for the mark:

- **Clear space** — keep free space around the mark equal to half its height on every side.
- **Minimum size** — 24px on screen, 8mm in print. Below that, crop to the favicon rather than shrinking further.
- **Lock-up** — the mark pairs with `PULSE LAB` in bold uppercase at 0.2em tracking, above `AI for Oceanography & Health` at 0.14em. Never re-typeset the wordmark in another face.
- **Never** recolour the mark to an accent, add a gradient, place the full-colour mark on a photograph or mid-tone, or stretch, rotate, outline, or shadow it.

Both marks are SVG and resolution independent — scale them rather than
exporting a raster.

## Rules worth repeating

- An accent must mean something. If it does not identify a domain, a status, or a content type, leave it off.
- Never truncate a person's name, a project title, or a publication title.
- No blur blobs, no stacked radial gradients, no coloured drop shadows.
- Prose gets a labelled container and a 68-character measure. Never a bare wall of text.
- Two links on the same object must not go to the same place, and each label must name its destination.

Download

The kit contains the document and the SVGs together. The document refers to each asset by its path inside the kit, so a model reading it can name the right file.

What's inside

  • PULSE-BRAND-SKILL.md
  • README.md
  • assets/pulse-logo-colour.svg
  • assets/pulse-logo-mono.svg

Keeping it true

This page, the document, and the kit are all generated from src/lib/brand.ts. Change a token in uno.config.ts, mirror it there, and all three follow.