Brand
GLAC’s design system at work. Every value here is read from tokens.css when the site is built, every component is the site’s own, and every contrast figure is measured from those values, in both themes.
Brand
An ice cube beside the word: the files to use, the names we write, and how we write. From components/brand-guide.md and brand/logo/glac/.
The logo
An isometric cube with rounded corners, in three blues, beside Glac in Outfit SemiBold. One cube is one sandbox; the ice nods to the glacier in the name.
On light · logo.svg, mark.svg, wordmark.svg
On dark · logo-dark.svg, wordmark-white.svg
Using it
The header shows the logo 24 px tall, the footer 26 px. On photographs or busy colour, use a one-colour file.
Clear space and the least size
At least half the cube’s height on every side.
The logo is 80 px wide at the least; below that the cube alone, which holds at 16 px.
One colour
logo-white.svg, and logo-mono.svg in the current colour (here the dark theme’s text). The faces are parted by seams 4 units wide.
- Never recolour the cube or reorder its faces: the darkest face stays on the right.
- Never sharpen the corners, add a face or stretch the cube.
- Never set the word in another font.
Construction
The drawing is measured from build.py’s own numbers, so it follows the files if they change.
- Grid
- The cube on a 100 grid, about (50, 50), on a lattice at 30°, its edge e = 42, the hexagon’s side and circumradius: √3 e = 72.75 wide, 2e = 84 tall before rounding.
- Corners
- Each outer corner a quadratic curve k = 9 long on each side.
- Seams
- One-colour versions part the faces with seams 4 wide.
- Word
- Outfit at weight 600, tracked −25 units, as outlines.
- Together
- The cube 1.25 times the capitals’ height, centred on them, 0.32 cube heights before the word; stacked, the cube two capitals tall, 0.55 above the word.
- Colour
- Ice on top, glacier light on the left, glacier on the right: the darkest face on the right.
Files
As they are in brand/logo/glac/: the SVGs come from build.py, the PNGs from its export page.
| Use | SVG | PNG, by width in px |
|---|---|---|
| The default: the cube in colour, ink letters, on light grounds | logo.svg | 600, 1200, 2400 |
| The cube in colour, white letters, on dark grounds | logo-dark.svg | 1200, 2400 |
| The cube over the word, for square spaces | logo-stacked.svg, logo-stacked-dark.svg | logo-stacked-1200, logo-stacked-dark-1200 |
| One colour, the faces parted by seams: blue with ink letters, all ink, all white, or the current colour | logo-blue.svg, logo-ink.svg, logo-white.svg, logo-mono.svg | logo-blue-1200, logo-ink-1200, logo-white-1200 |
| The cube alone, in colour | mark.svg | 64, 128, 256, 512, 1024 |
| The cube alone, in one colour | mark-blue.svg, mark-ink.svg, mark-white.svg, mark-mono.svg | mark-blue-1024, mark-ink-1024, mark-white-1024 |
| The word alone | wordmark.svg, wordmark-white.svg | — |
| Full-bleed tiles, the cube on ink or on white; app stores add their own corners (180 is the Apple touch icon) | app-icon.svg, app-icon-light.svg | app-icon-1024, app-icon-512, app-icon-192, app-icon-180, app-icon-light-1024 |
| The browser tab: the cube alone; the ICO holds 16, 32 and 48 px | favicon.svg, favicon.ico | favicon-16, favicon-32, favicon-48 |
Names
Each product has a singular name and an address of its own. What is not there yet is marked Soon.
| Group | Product | Address |
|---|---|---|
| Cube | Cube | /cube/ |
| Cube | Volume | /volume/ |
| Managed Applications | Sandbox | /sandbox/ |
| Managed Applications | Browser Soon | /browser/ |
| Managed Applications | Serverless Postgres Soon | /database/ |
| Managed Applications | Third-party apps Soon | |
| Thing | Name |
|---|---|
| Company | GLAC PTY LTD |
| Command line | glac (curl -fsSL https://glac.ai/install.sh | sh) |
| API | https://api.glac.ai, the key in GLAC_API_KEY, the address in GLAC_API_URL |
| Console | https://console.glac.ai |
| SSH | ssh.glac.ai |
| Packages | PyPI glac; npm glac and glac-mcp; crates.io glac; Maven ai.glac:glac; Go github.com/GlacAI/glac-go |
| Preview links | https://3000-‹sandbox›-‹signature›.glac.run/ |
Voice
Plain, measured and true.
- Plain and short. Say what it does in the reader’s words, one idea a sentence.
- Measured, not loud. Every number has a source and a footnote that says how it was measured. Never “as little as”, “blazing” or “best”.
- Say what exists. A feature that is not there yet is marked Soon, or left out.
- Rivals only on Pricing, each figure with its source and the day it was checked.
- Actions say what they do: Get started, Talk to us →, In the docs →.
- Prices in US dollars, read from the billing code, never typed by hand.
Colour
One accent, the glacier’s blue, on twelve neutrals tinted toward the ink, in a light theme and a dark one; and the night that drawings stand on. From colors.md.
The logo’s colours
The same in both themes.
- Ice--ice #e3ecffThe cube’s top face
- Glacier light--glacier-light #6e9bffThe cube’s left face; the accent in the dark theme
- Glacier--glacier #2f6bffThe cube’s right face; fills, lines, the live dot
- Ink--ink #12161cThe logo’s letters on light; words on light buttons
- White--white #ffffffThe logo’s letters on dark
Neutrals
Twelve steps tinted toward the ink’s hue, which the roles read by name. Each ratio is against the page; AA is enough for words, 3:1 for a control’s edge.
Light
- --n1 #fcfdfe--bg · The page1.00
- --n2 #f7f9fb--surface · Cards, code, inline code1.04
- --n3 #f0f3f7--surface-2 · A second surface1.09
- --n4 #e8ecf1--hover · Hover1.17
- --n5 #e0e5ec1.24
- --n6 #d6dce4--line · Every rule and card edge1.36
- --n7 #c5cdd8--line-strong · Line buttons, Soon pills1.57
- --n8 #a9b3c12.08
- --n9 #7c8696--mark · Ticks, marks and a field’s edge; never words3.613:1
- --n10 #646d7a--faint · Notes, group labels, table heads5.14AA
- --n11 #545d6b--muted · Support text, navigation6.54AA
- --n12 #12161c--text · Text17.82AA
Dark
- --n1 #0b0d11--bg · The page1.00
- --n2 #101318--surface · Cards, code, inline code1.04
- --n3 #15191f--surface-2 · A second surface1.10
- --n4 #1a1f26--hover · Hover1.17
- --n5 #20262e1.28
- --n6 #262d36--line · Every rule and card edge1.40
- --n7 #2f3742--line-strong · Line buttons, Soon pills1.62
- --n8 #3d46532.04
- --n9 #5d6574--mark · Ticks, marks and a field’s edge; never words3.313:1
- --n10 #7a8393--faint · Notes, group labels, table heads5.09AA
- --n11 #9aa3b2--muted · Support text, navigation7.64AA
- --n12 #e9edf3--text · Text16.55AA
Accent
The glacier’s blue, the one accent: the cube, live numbers, links, focus, the first action, what is ours in a comparison.
Light
- --accent #2f6bff var(--glacier)Fills and strokes in the accent
- Aa--accent-text #2257e0 Blue words: links, footnote marks, a product group’s label5.88AA
- --accent-tint #eef3ff A pale ground for notes and tags
- --accent-line #c9d8ff The edge of the paid plan’s card and of tags
- --focus #2f6bff var(--glacier)Focus rings4.423:1
- --ours #2f6bff at 6% color-mix(in srgb, var(--glacier) 6%, transparent)Our column or row in a comparison
- --row-hover #2f6bff at 3.5% color-mix(in srgb, var(--glacier) 3.5%, transparent)A price row under the pointer
Dark
- --accent #6e9bff var(--glacier-light)Fills and strokes in the accent
- Aa--accent-text #6e9bff var(--glacier-light)Blue words: links, footnote marks, a product group’s label7.22AA
- --accent-tint #131b2b A pale ground for notes and tags
- --accent-line #24365e The edge of the paid plan’s card and of tags
- --focus #6e9bff var(--glacier-light)Focus rings7.223:1
- --ours #2f6bff at 6% color-mix(in srgb, var(--glacier) 6%, transparent)Our column or row in a comparison
- --row-hover #2f6bff at 3.5% color-mix(in srgb, var(--glacier) 3.5%, transparent)A price row under the pointer
Actions
The first action of a screen and its states, a step deeper in light and brighter in dark; and the switch, its knob on its track.
Light
- Aa--action #2257e0 The first action of a screen, everywhere, --action-ink on it5.99AA
- Aa--action-hover #1b4bc8 Its hover: a step deeper (light) or brighter (dark), --action-ink on it7.27AA
- Aa--action-press #173fa8 Its press, --action-ink on it9.08AA
- --knob #ffffff A switch’s knob, on its track
- --knob-edge #7c8696 var(--mark)The knob’s edge: the switch’s state, 3:1 on the track3.203:1
- --track #12161c at 6% color-mix(in srgb, var(--text) 6%, transparent)A switch’s track
Dark
- Aa--action #6e9bff var(--night-action)The first action of a screen, everywhere, --action-ink on it6.74AA
- Aa--action-hover #8db1ff var(--night-action-hover)Its hover: a step deeper (light) or brighter (dark), --action-ink on it8.52AA
- Aa--action-press #a9c4ff var(--night-action-press)Its press, --action-ink on it10.39AA
- --knob #2a313b A switch’s knob, on its track
- --knob-edge #7a8393 var(--n10)The knob’s edge: the switch’s state, 3:1 on the track4.323:1
- --track #e9edf3 at 8% color-mix(in srgb, var(--text) 8%, transparent)A switch’s track
States and notes
Each only for what it means, and always with a word beside it.
Light
- Aa--ok #1a7f37 Success; GET in the API reference4.99AA
- Aa--warn #9a6700 Warning; PATCH4.78AA
- Aa--bad #cf222e Error; DELETE5.26AA
- Aa--info #2257e0 Info; POST5.88AA
- Aa--todo-bg #fff3c4 A fact still to be supplied (mark.todo), --todo-text on it8.27AA
- Aa--draft-bg #fdecea The “Draft — not yet reviewed” banner, --draft-text on it9.17AA
Dark
- Aa--ok #3fb950 Success; GET in the API reference7.66AA
- Aa--warn #d29922 Warning; PATCH7.70AA
- Aa--bad #f85149 Error; DELETE5.80AA
- Aa--info #6e9bff var(--glacier-light)Info; POST7.22AA
- Aa--todo-bg #4a3b06 A fact still to be supplied (mark.todo), --todo-text on it8.60AA
- Aa--draft-bg #4a1a14 The “Draft — not yet reviewed” banner, --draft-text on it9.92AA
The night
The ground of drawings, tiles, product figures and the closing card: the same in both themes, with white words and ice-blue light. Each ratio is on --night-1, the night’s lighter end.
Grounds
- --nightlinear-gradient(180deg, var(--night-1) 0%, var(--night-2) 100%)Tiles, product figures: the night itself
- --night-1#131f4aIts top
- --night-2#0b1331Its foot
- --night-deeplinear-gradient(180deg, #050a1e 0%, #0a1846 60%, #10266c 100%)The closing card
- --night-glowradial-gradient(90% 70% at 50% 108%, rgb(47 107 255 / 0.42), transparent 62%)The light from below a product figure
- --dawn-core#2c5fe6The dawn’s core, low in the hero’s and the closing card’s sky
- --dawn-mid#163a9eAround it
Words and lamps
- Aa--on-night #ffffffWords on the night15.88AA
- Aa--on-night-strong #ffffff at 90%Words that lead: a terminal’s line, a tile’s sentence13.04AA
- Aa--on-night-muted #ffffff at 78%Support text on the night10.08AA
- Aa--on-night-faint #ffffff at 60%The faintest words allowed6.50AA
- Aa--night-ice #9db9ffLive words, lamps and marks8.18AA
- Aa--frost #c9d8ffWhat is asleep; words in frost11.15AA
- Aa--frost-muted #c9d8ff at 72%Labels in frost6.42AA
- Aa--lamp-ok #6fdc9bA drive’s lamp; a GET in a route list9.37AA
- Aa--lamp-busy #e8b75aA PATCH in a route list; a change on its way8.58AA
Actions
- Aa--night-action #6e9bffThe first action on the night (and the dark theme’s), --ink on it6.74AA
- Aa--night-action-hover #8db1ffHovered, --ink on it8.52AA
- Aa--night-action-press #a9c4ffPressed, --ink on it10.39AA
- --night-action-edgeThe second action’s edge: inset 0 0 0 1px rgb(var(--c-frost) / 0.5)3.833:1
- --focusThe focus ring on the night, in the light theme3.533:1
- --focusThe focus ring on the night, in the dark theme5.893:1
The night’s drawings
A drawing on the night reads these and no other colour. The logo’s blues are kept as channels, so a part can take its own strength; the named strengths are the ones drawings share.
Channels
- --c-glacier47 107 255--glacier: the cube’s right face, what is awake
- --c-glacier-light110 155 255--glacier-light: the cube’s left face, lamps, routes
- --c-glacier-deep31 79 208The cube’s right face in shade
- --c-glass140 180 255The body of glass
- --c-edge170 200 255The edge of glass; the night’s drawn lines
- --c-line160 195 255Rules, hairlines, panel edges
- --c-frost201 216 255What is asleep; words in frost
- --c-glint220 230 255The brightest light on a part
- --c-abyss4 9 28The ground of a panel
Named strengths
- --glacier-deep#2349b8A blue part’s left face
- --glacier-deeper#18348aA blue part’s right face
- --night-face-top#1c2b62A dark part on the night: its top
- --night-face-left#121d47Its left face
- --night-face-right#0c1538Its right face
- --night-hair#a0c3ff at 14% · rgb(var(--c-line) / 0.14)The faintest line: a grid, a seam
- --night-rule#a0c3ff at 20% · rgb(var(--c-line) / 0.2)A rule between parts
- --night-line#a0c3ff at 35% · rgb(var(--c-line) / 0.35)A drawn line
- --night-line-strong#a0c3ff at 50% · rgb(var(--c-line) / 0.5)A line that leads: a route, a dashed blueprint
- --night-panel#04091c at 55% · rgb(var(--c-abyss) / 0.55)A terminal or a file (with --night-panel-edge)
- --night-glass#8cb4ff at 20% · rgb(var(--c-glass) / 0.2)Glass on the night (with --night-glass-edge)
- --night-glow-soft#6e9bff at 28% · rgb(var(--c-glacier-light) / 0.28)The ring of light around an awake lamp
Measured contrast
Worked out from tokens.css when the site is built (WCAG 2.x): words need 4.5:1, what identifies a control 3:1, a rule nothing. A translucent colour is laid over its ground first.
| Pair | Tokens | Light | Dark |
|---|---|---|---|
| Text on the page | --text on --bg | 17.82AA | 16.55AA |
| Text on a card | --text on --surface | 17.19AA | 15.84AA |
| Support text on the page | --muted on --bg | 6.54AA | 7.64AA |
| Support text on a card | --muted on --surface | 6.31AA | 7.32AA |
| A note on the page | --faint on --bg | 5.14AA | 5.09AA |
| A note on a card | --faint on --surface | 4.96AA | 4.87AA |
| A link on the page | --accent-text on --bg | 5.88AA | 7.22AA |
| A tag’s words on its tint | --accent-text on --accent-tint | 5.39AA | 6.39AA |
| The first action’s label | --action-ink on --action | 5.99AA | 6.74AA |
| … hovered | --action-ink on --action-hover | 7.27AA | 8.52AA |
| … pressed | --action-ink on --action-press | 9.08AA | 10.39AA |
| Success, on the page | --ok on --bg | 4.99AA | 7.66AA |
| Warning, on the page | --warn on --bg | 4.78AA | 7.70AA |
| Error, on the page | --bad on --bg | 5.26AA | 5.80AA |
| A TODO mark | --todo-text on --todo-bg | 8.27AA | 8.60AA |
| The draft banner | --draft-text on --draft-bg | 9.17AA | 9.92AA |
| The focus ring | --focus on --bg | 4.423:1 | 7.223:1 |
| A field’s edge | --mark on --bg | 3.613:1 | 3.313:1 |
| A switch’s knob: its edge on the track | --knob-edge on --track | 3.203:1 | 4.323:1 |
| A link beside text, by colour alone (links in text are underlined) | --accent-text on --text | 3.033:1 | 2.29under 3:1 |
| A rule | --line on --bg | 1.36decorative | 1.40decorative |
| A line button’s edge, a Soon pill’s | --line-strong on --bg | 1.57decorative | 1.62decorative |
Type
Three families on one scale, the cube’s height over its width. Each text takes the role of what it does, not of its tag. From typography.md.
Families
Self-hosted variable fonts, each under the SIL Open Font License.
Outfit
--font-displayAa Gg 3.5 ms
Headlines, titles and measured figures, at weight 500. The logo’s word is the same family at 600, as outlines.
Inter
--font-textAa Gg 3.5 ms
Everything that is read: body, tables, buttons, navigation, card titles.
JetBrains Mono
--font-monoAa Gg 3.5 ms
Code, and the label role: small capitals that name a group or a column.
Weights: --weight-text 400, --weight-medium 500, --weight-strong 600. Text 400, headings and names 500, actions and the key words of a fact 600; never 700.
The scale
Step n is 16 px × (2/√3)ⁿ: the cube’s height over its width, 1.1547, so two steps make 1.3333, 4/3. Step −1 is 14 px, 13.9 rounded up to TypeUI’s floor for support text, so the steps either side of it differ.
- --step--212 px0.75rem
- --step--114 px×1.1667
- --step-016 px×1.1429
- --step-118.5 px×1.1547
- --step-221.3 px×1.1547
- --step-324.6 px×1.1547
- --step-428.4 px×1.1547
- --step-532.8 px×1.1547
- --step-637.9 px×1.1547
- --step-743.8 px×1.1547
- --step-850.6 px×1.1547
- --step-958.4 px×1.1547
- --step-1067.4 px×1.1547
- --step-1177.9 px×1.1547
The steps each role takes, at 390 and at 1440: Display ? → 10; Title ? → 7; Subtitle ? → 4; Figure ? → 8; Heading 1; Lead 1; Body 0; Note −1; Label −2; Code −1.
Roles
Each set in itself by its own class; the measures are what that rule gives, at a 390 px window and a 1440 px one. Display is used once a page.
Next-generation computing for AI agents
Display --text-display
- Font
- Outfit 500
- Size
- 57.6 → 67.4 px
- Line
- 1
- Tracking
- -0.04em
The one hero headline of a page: the home page’s, a product’s name, a solution’s promise
How billing works
Title --text-title
- Font
- Outfit 500
- Size
- 37.4 → 43.8 px
- Line
- 1
- Tracking
- -0.03em
A section’s heading (h2); the h1 of a page of text
A computer of its own for every agent
Subtitle --text-subtitle
- Font
- Outfit 500
- Size
- 24.3 → 28.4 px
- Line
- 1.15
- Tracking
- -0.02em
A sub-section (h3); a product’s headline; h2 in long text
3.5 ms1
Figure --text-figure
- Font
- Outfit 500
- Size
- 43.3 → 50.6 px
- Line
- 1
- Tracking
- -0.04em
A measured number shown large, in tabular figures
What counts as usage?
Heading --text-heading
- Font
- Inter 500
- Size
- 18.5 px
- Line
- 1.35
- Tracking
- 0
A card’s or a list’s title, a plan’s name, a question
A sandbox is a microVM your code or your agent drives through the API: run commands, read and write files, open a terminal or a link to a port, save it whole and fork it.
Lead --text-lead
- Font
- Inter 400
- Size
- 18.5 px
- Line
- 1.55
- Tracking
- 0
- Colour
- --muted
The sentence under a hero or a section title, at most 36rem wide
One platform: Compute, where any container image runs as instances of its own, keeping their state or not, and the storage beside it. Every product is built on the two.
Body --text-body
- Font
- Inter 400
- Size
- 16 px
- Line
- 1.6
- Tracking
- 0
- Colour
- --text
Running text and table rows; support text in --muted
Medians measured on bare metal (AMD Ryzen 9 9950X, 3 October 2026), on a machine with nothing else running.
Note --text-note
- Font
- Inter 400
- Size
- 14 px
- Line
- 1.5
- Tracking
- 0
- Colour
- --faint
Footnotes, a table’s note, a code sample’s note, a field’s label
Included each month
Label --text-label
- Font
- JetBrains Mono 500, capitals
- Size
- 12 px
- Line
- 1.2
- Tracking
- 0.1em
- Colour
- --faint
The names of groups and columns; never a sentence, never wraps
glac sandboxes create --name web --image python:3.12Code --text-code
- Font
- JetBrains Mono 400
- Size
- 14 px
- Line
- 1.7
- Tracking
- 0
Code blocks and windows
Space and layout
The 4-point grid with the cube’s 24 px edge as its module, a rhythm that grows with the window, and one column for every page. From spacing.md and layout.md.
The scale
Every margin, padding and gap is one of these. Space grows with what it separates: label, item, block, part.
| Token | px | Drawn | Tier | Typical use |
|---|---|---|---|---|
| --sp-4 | 4 | Micro | Icon to label; a nudge | |
| --sp-8 | 8 | Micro, tight | Label to field; between pills; a list’s rows | |
| --sp-12 | 12 | Tight | Inside cards and lists; between buttons | |
| --sp-16 | 16 | Default | Paragraph to paragraph; a rule to its content; table cells | |
| --sp-24 | 24 | Medium | The column gutter; between a card’s parts | |
| --sp-32 | 32 | Medium | A display or title heading to its content | |
| --sp-48 | 48 | Loose | Between blocks within a part | |
| --sp-64 | 64 | Loose | Between groups of a page | |
| --sp-96 | 96 | Section | A section’s padding on wide windows | |
| --sp-128 | 128 | Section | The largest pause |
--e is the cube’s edge, 24 px: the gutter, and the module the larger steps are made of.
Rhythm
Fluid in a straight line between a 390 px window and a 1440 px one. The pale bar is the value in this window: resize it to see it move.
| Token | 390 | 1440 | Here | Between |
|---|---|---|---|---|
| --section-gap | 72 | 128 | A page’s parts | |
| --section-pad | 24 | 32 | A part’s rule and its title | |
| --head-gap | 24 | 32 | A display or title heading and what follows it | |
| --card-pad | 20 | 32 | A card’s edge and its content | |
| --card-gap | 16 | 24 | Cards in a row or a column | |
| --page-top | 40 | 72 | The header and a page’s first content | |
| --page-bottom | 64 | 96 | A page’s last content and the footer |
Layout
One column for every page: the header, each section and the footer start and end on its two edges.
| Token | Written | Comes to | For |
|---|---|---|---|
| --page | clamp(1280px, 66.67vw, 1760px) | 1280 px at 1440, 1706.8 px at 2560 | The one column every page shares |
| --margin | clamp(20px, 5vw, 64px) | 20 px at 390, 64 px at 1440 | The window’s edge to the column |
| --gutter | 24px | 24 px | Between columns: one cube edge |
| --col | calc((var(--container) - 11 * var(--gutter)) / 12) | 84.7 px | One of twelve columns |
| --header-h | 64px | 64 px | The header |
| --measure-lead | 36rem | 576 px | A lead’s width |
| --measure | 65ch | 65 characters | Running text, answers, notes |
Twelve columns
At the column’s own width, one gutter between them. Grid and flex children that hold code or long words get min-width: 0, so nothing pushes the page wider than the window.
Radius
Actions have the cube’s corner, choices and statuses are round, containers grow with their size, and a corner inside another is concentric. From radius.md.
Corners
Six, each for one reason. Never only some corners of a box.
- --radius-xs4 pxInline code, TODO marks, a focus ring’s corner on a link
- --radius-control6 pxButtons of every size, fields: the cube’s corner
- --radius-md12 pxA tile or code inside a card, at its 12 px tray
- --radius-lg16 pxCode blocks and windows; the menus’ ground; a link card
- --radius-xl24 pxCards, figures, night tiles, the closing card
- --radius-pill999 pxSwitches and their knob; Soon and region pills; the status
Concentric
An inner corner is its outer corner less the space between them, so the two curves run side by side.
Lines and shadows
Flat: one step of surface and a 1 px line. Only what floats casts a shadow. Edges are inset, so they never change a box’s size. From shadow.md.
Edges and shadows
Each on what wears it, in both themes. The float’s shadow is the same dark blue in both; on the dark ground its line does the work.
Light
- --edgeinset 0 0 0 1px var(--line)Cards, code blocks, the status pill
- --edge-stronginset 0 0 0 1px var(--line-strong)Line buttons, Soon pills
- --edge-accentinset 0 0 0 1px var(--accent-line)The paid plan’s card, accent pills, step numbers
- --shadow-float0 0 0 1px var(--line), 0 18px 48px -12px rgb(10 20 50 / 0.28), 0 4px 12px -4px rgb(10 20 50 / 0.12)What floats: the menu panel
- --shadow-knob0 1px 2px rgb(10 20 50 / 0.14), 0 0 0 0.5px rgb(10 20 50 / 0.1)A switch’s knob
- --halo0 0 0 3px color-mix(in srgb, var(--focus) 24%, transparent)A field with focus
- Focus--ring-width, --ring-offset2px solid var(--focus), 3px offFocus on everything, keyboard only; it follows the element’s corner
Dark
- --edgeinset 0 0 0 1px var(--line)Cards, code blocks, the status pill
- --edge-stronginset 0 0 0 1px var(--line-strong)Line buttons, Soon pills
- --edge-accentinset 0 0 0 1px var(--accent-line)The paid plan’s card, accent pills, step numbers
- --shadow-float0 0 0 1px var(--line), 0 18px 48px -12px rgb(10 20 50 / 0.28), 0 4px 12px -4px rgb(10 20 50 / 0.12)What floats: the menu panel
- --shadow-knob0 1px 2px rgb(10 20 50 / 0.14), 0 0 0 0.5px rgb(10 20 50 / 0.1)A switch’s knob
- --halo0 0 0 3px color-mix(in srgb, var(--focus) 24%, transparent)A field with focus
- Focus--ring-width, --ring-offset2px solid var(--focus), 3px offFocus on everything, keyboard only; it follows the element’s corner
Night
- --night-edgeinset 0 1px 0 rgb(255 255 255 / 0.08), inset 0 0 0 1px rgb(255 255 255 / 0.06)Night tiles and figures: a lit top edge, not a shadow
- --night-panel-edgeA terminal or a file on the night
Motion
One ease for what travels, durations by what moves. Motion explains a state or points at one thing; reduced motion stops every travel and keeps every word. From motion.md.
Eases
Drawn from their own numbers: time across, progress up.
Durations
By what moves, all on --ease. Play runs them together, so each can be seen against the others.
Reduced motion is on: each dot goes straight to its end, as every transition on the site does.
- --dur-press 100msA press
- --dur-hover 150msHover, colour, an underline
- --dur-state 240msA switch’s knob, a chevron, the accordion’s sign
- --dur-panel 320msLarger changes
- --dur-fade 500msWords fading in on a story screen
- --dur-reveal 700msA part rising into view
- --dur-travel 900msA long move: a figure sliding into place
Rising into view
A part rises 24px and fades in over --dur-reveal, the opacity in 85% of it; the parts of a group are 60ms apart; the second of a pair follows 120ms after the first. Once only, and without script a part is simply there.
A title
And its sentence, 120ms after it.
Loops
Only in drawings, never in text; a figure pauses off screen. Here they run only while asked to.
Reduced motion is on: the loops stand still.
- --loop-pulse2.4sA lamp’s or a glow’s breath
- --loop-flow1.2sDashes running along a line
- --loop-caret1.1sA terminal’s caret
- --loop-orbit40sA ring turning around a globe
Components
The shared components, live: hover, press and Tab through them. Beside each, its states held still, drawn by the same rules. From button.md, link.md, switch.md, form.md, card.md, code.md, badge.md, accordion.md and table.md.
Buttons
Actions are rectangles with the cube’s corner, 6 px; one fill, flat. One first action a screen; the rest are line buttons or text actions.
Disabled, and saying why beside it: here, there is nothing to send.
Light
Dark
On the night
Links
A link in running text is underlined, so it is a link by more than its colour; a link on a line of its own goes without.
The rules for each part are in the design system’s files, and the platform itself is in the docs: the underline stays quiet until the pointer is on it.
A footnote’s mark says where a figure comes from: a sandbox wakes in 3.5 ms1.
The header’s and the footer’s links are the navigation links: muted, no underline, the ink on hover and where you are.
Switch
Words in a pill and one knob that slides under the chosen word. Radio buttons, so the arrow keys move it and it needs no script; it changes what is shown and never navigates.
It switches the table below; the theme switch at the top of the page is the same component with three words.
Table
No frame: rules between the rows, the head in the label role, one size across a row, numbers to the right. A row takes a tint under the pointer.
| Meter | What is counted | Unit price |
|---|---|---|
| Cube resources | ||
| CPU | Busy CPU time, by the millisecond | $0.01 / million CPU-ms$0.00001 / CPU-second$0.036 / CPU-hour$26.28 / CPU-month |
| Memory | Held, by the millisecond, in 128 MiB steps | $0.00222 / million GiB-ms$0.00000222 / GiB-second$0.008 / GiB-hour$5.84 / GiB-month |
| Requests | Per request into a Cube or through a sandbox link | $0.30 / million |
| Traffic outNA · EU | Per GB leaving North America and Europe | $0.004 / GB |
| Traffic outAPAC | Per GB leaving Asia-Pacific | $0.01 / GB |
| Kept asleep2 | What sleeping instances keep, and snapshots | $0.00000761 / million GB-ms$0.00000000761 / GB-second$0.0000274 / GB-hour$0.02 / GB-month |
Field
A visible label above the input, 8 px apart; a hint or an error in words under it, tied to it by aria-describedby. 16 px type, so a phone does not zoom.
An instance wakes for a request and sleeps 100 ms after the last one, so its memory counts only while it answers.
Memory is at most 16,384 MiB.
Disabled: the second surface, faint words, and the reason here.
Cards
Flat: the surface on the page, a line for an edge, no shadow. A card that goes somewhere is one link, the whole card.
A card
Its title in the heading role and its words in the body, on the surface with a line for its edge; its corner the largest there is.
A surface inside it goes back to the page’s ground: an inset tile.
Code
JetBrains Mono 14 px, highlighted at build time in GitHub’s two themes, four of their colours corrected to 4.5:1. Every sample runs as written.
# 1. Make one (it prints its id)
glac sandboxes create --name web --image python:3.12
# 2. Run in it (the exit code is the command's)
glac sandboxes exec web -- pip install pandas
# 3. Save it whole, then fork it
glac sandboxes snapshots create web --name ready
glac sandboxes fork web --count 16The Sandbox page’s three steps on the command line, as the docs give them.
Inline code sits in a sentence: the command line is glac, its key in GLAC_API_KEY.
Pills and notes
A pill is words, not colour, and says what it means; one a name at most. Notes in text mark what is not done.
A fact not yet given is marked like this, and must be gone before the launch.
The footer’s status pill, below, reads the live status.
Accordion
Native details and summary: it works without a script and find-in-page opens it. Several may be open at once.
Where does a value come from?
From tokens.css. The pages and the shared components read its names and set no colour, size, radius, shadow or duration of their own.
Why are buttons not round?
Actions have the cube’s corner, 6 px. Switches and pills are round, because they are choices and statuses.
Figures
GLAC draws its product as real hardware and as the logo’s cube. On the night, a drawing reads the palette by name and no other colour. From figure.md.
The palette in use
A dark part in the night’s three faces; the cube on it awake, its lamp in ice; a cube asleep in frost, a request on its way to it; a pane of glass; a terminal.
# 1. Make one (it prints its id)
$ glac sandboxes create --name web \
--image python:3.12
# 2. Run in it
$ glac sandboxes exec web -- pip install pandasA terminal panel: the night’s strong words, the prompt in ice, comments faint. The commands are the Sandbox page’s, from the docs.
Rules
The anatomy skill draws GLAC’s figures to these; its own craft rules still hold: real parts, painter’s order, no loose ends.
| Language | The machine, isometric hardware on the page’s own ground; or the night, drawings in white and ice on --night. A figure uses one, never both. |
|---|---|
| Diagonals | The cube’s 30°, true isometric. |
| Lines | 1–1.2 units, white or --night-glass-edge, round joins; quieter lines --night-line, --night-rule or --night-hair. |
| Ends | Every line ends on a part, a dot or an outline. |
| Dashes | Only for what is not there yet, or a boundary that is crossed. |
| Labels | Inter or JetBrains Mono, 12 units, white at 60% or more on the night. |
| Glass | --night-glass with a --night-glass-edge edge, and two straight streaks. |
| Panels | A terminal or a file: --night-panel with --night-panel-edge. |
| Colour | Blue is awake, live or in flight; frost and grey are asleep; green only for a drive’s lamp, amber for a change on its way. |
| The cube | Ice on top, glacier light on the left, glacier on the right, the darkest. |
| Glow | Only on the night, only around what is awake: a soft radial gradient, never a blur filter. |
| Motion | Only while on screen; under reduced motion it stands still, in a pose that still explains it. |
| Truth | Every number a figure shows is real: from src/data/measured.ts or the docs. |
Accessibility
WCAG 2.2 AA is the floor under everything, in both themes, from 320 px up. Where a style and accessibility disagree, accessibility wins. From accessibility.md.
The floor
Each standard, what GLAC holds to, and how it is checked.
- 1.4.3 Contrast
- Words 4.5:1, or 3:1 at 24 px and larger. --text, --muted, --faint and --accent-text pass on --bg and --surface in both themes; on the night, words are white at 60% or more.
- Checked Worked out from tokens.css when this page is built (Colour, above); measured on every rendered page by the design system’s audit in headless Chrome, each text against its own ground, at 1280 and 390 px, in both themes.
- 1.4.11 Non-text contrast
- What identifies a control or its state 3:1: focus rings, a field’s edge, the edge of a switch’s knob against its track.
- Checked Worked out here (Measured contrast).
- 1.4.1 Use of colour
- A link in running text is underlined; a status has a word; a switch’s choice has a knob as well as a colour.
- Checked The audit looks for links in text told apart by their colour alone.
- 2.4.7, 2.4.11 Focus
- One ring on everything, 2 px in the accent and 3 px off, on keyboard focus; a field shows an accent edge and a halo instead.
- Checked The audit tabs through the first 30 stops of each page and checks each one shows its ring.
- 2.1.1 Keyboard
- Menus open with Enter or Space and close with Esc; switches are radio groups, moved with the arrow keys; focus follows reading order.
- Checked By keyboard: Tab, Space, Enter and the arrows through this page’s components.
- 2.4.1 Bypass blocks
- “Skip to content” is the first stop on every page and takes focus to the main content.
- Checked The audit checks the first stop.
- 1.3.1, 2.4.6 Structure
- One h1 a page, no skipped level; landmarks named apart; tables with their heads.
- Checked The audit reads each page’s headings and landmarks.
- 1.4.10 Reflow
- No sideways scroll at 320 px; a wide table scrolls inside its own wrapper.
- Checked The audit opens each page at 320 px, and at 640 px for 200% zoom, and looks for anything wider.
- 1.4.12 Text spacing
- Nothing is clipped or overlaps under WCAG’s spacing override.
- Checked The audit applies the override and looks for clipped text.
- 2.5.8 Target size
- 24 by 24 px at least (WCAG); 44 by 44 on touch (TypeUI): buttons 44 and 48 px, the header’s 40; 8 px between targets.
- Checked The audit lists targets under 24 px.
- 2.3.3, 2.2.2 Motion
- Reduced motion stops every travel, with a 1 ms floor in ui.css, and content never waits on an animation; nothing flashes.
- Checked The audit runs with reduced motion and looks for loops still running.
- Without script
- Every page reads whole; switches, tabs, menus and accordions are CSS and native elements.
- Checked By loading a page with script turned off; the audit does not.