5317b8f142
Co-authored-by: Zachary Levy <zachary@sunforge.is> Reviewed-on: #23
757 lines
27 KiB
Odin
757 lines
27 KiB
Odin
// CYBERSTEEL DESIGN SYSTEM — Odin theme constants
|
||
//
|
||
// Retrofuturist. Technical. Direct. Gruvbox-derived palette
|
||
// with Art Deco type system. Every visual token from the
|
||
// Cybersteel design system, transferred 1:1 to Odin constants.
|
||
//
|
||
// Conventions:
|
||
// - Colors are [4]u8 RGBA. Alpha 255 = fully opaque.
|
||
// Translucent tints carry their alpha in the 4th channel.
|
||
// - Times are time.Duration via core:time.
|
||
// - Pixel sizes, weights, line-heights, letter-spacings, and
|
||
// ratio-like values are plain (untyped) numeric literals so
|
||
// callers can use them with whatever numeric type they need.
|
||
// - Letter-spacing values are expressed in EMs (multiply by
|
||
// the resolved font size to get pixels).
|
||
// - Line-heights are unitless multipliers of the font size.
|
||
|
||
package cybersteel
|
||
|
||
import "core:time"
|
||
|
||
import draw ".."
|
||
|
||
|
||
// ============================================================
|
||
// BASE BACKGROUNDS — warm dark, Gruvbox-derived
|
||
// Never pure black. The warmth is intentional: aged metal,
|
||
// amber phosphor, old paper. Order is: deepest chrome first
|
||
// (shell), then page, then progressively lighter surfaces.
|
||
// ============================================================
|
||
|
||
// Topbar, sidebar, nav chrome, modal backdrops. Deepest base.
|
||
BG_SHELL :: draw.Color{0x1d, 0x20, 0x21, 0xff}
|
||
|
||
// Default page canvas / main content area. One step up from shell.
|
||
BG_PAGE :: draw.Color{0x31, 0x31, 0x31, 0xff}
|
||
|
||
// Cards, panels, drawers, input fields, code blocks, table rows.
|
||
// Slightly lighter than the page so raised surfaces read clearly
|
||
// without shadows.
|
||
BG_SURFACE :: draw.Color{0x3c, 0x38, 0x36, 0xff}
|
||
|
||
// Selected rows, active nav items, hover states. One step lighter
|
||
// than BG_SURFACE.
|
||
BG_ACTIVE :: draw.Color{0x50, 0x49, 0x45, 0xff}
|
||
|
||
// Disabled buttons / inputs background. Pairs with FG_MUTED text
|
||
// only — the contrast is intentionally low.
|
||
BG_DISABLED :: draw.Color{0x66, 0x5c, 0x54, 0xff}
|
||
|
||
// Borders, dividers, rules, input outlines. Never use as a text
|
||
// surface — it has no fg-pair guarantee.
|
||
BG_BORDER :: draw.Color{0x7c, 0x6f, 0x64, 0xff}
|
||
|
||
|
||
// ============================================================
|
||
// BASE FOREGROUNDS — warm cream / ivory, never pure white
|
||
// Five-step ramp from brightest (heading) to most muted.
|
||
// ============================================================
|
||
|
||
// Hero text, page headings, display titles. Brightest fg.
|
||
FG_HEADING :: draw.Color{0xfb, 0xf1, 0xc7, 0xff}
|
||
|
||
// Primary body text, default readable content.
|
||
FG_BODY :: draw.Color{0xf2, 0xe2, 0xba, 0xff}
|
||
|
||
// Labels, secondary descriptions, table data.
|
||
FG_SECONDARY :: draw.Color{0xe0, 0xd0, 0xa8, 0xff}
|
||
|
||
// Captions, metadata, timestamps, placeholders.
|
||
FG_CAPTION :: draw.Color{0xce, 0xbd, 0x9e, 0xff}
|
||
|
||
// Disabled text, token labels, subtle UI annotations.
|
||
FG_MUTED :: draw.Color{0xb8, 0xa9, 0x8e, 0xff}
|
||
|
||
|
||
// ============================================================
|
||
// ACCENT — GOLD (signature color, Art Deco)
|
||
// The defining accent of the system. Use sparingly: borders,
|
||
// highlights, focus rings, primary interactive states.
|
||
// ============================================================
|
||
|
||
// Primary interactive, focus rings, headline interactive accent.
|
||
GOLD_BRIGHT :: draw.Color{0xfa, 0xbd, 0x2f, 0xff}
|
||
|
||
// Borders, decorative rules, default Art Deco ornament color.
|
||
GOLD_DIM :: draw.Color{0xd7, 0x99, 0x21, 0xff}
|
||
|
||
// Hover states, pressed accents, dimmer gold contexts.
|
||
GOLD_MUTED :: draw.Color{0xb5, 0x76, 0x14, 0xff}
|
||
|
||
// Pure CRT amber. Reserved for terminal-style glow / phosphor
|
||
// references — distinct from gold ramp.
|
||
AMBER :: draw.Color{0xff, 0xb0, 0x00, 0xff}
|
||
|
||
|
||
// ============================================================
|
||
// ACCENT — RED (danger, errors, critical alerts)
|
||
// ============================================================
|
||
|
||
RED_BRIGHT :: draw.Color{0xfb, 0x49, 0x34, 0xff}
|
||
RED_DIM :: draw.Color{0xcc, 0x24, 0x1d, 0xff}
|
||
RED_MUTED :: draw.Color{0x9d, 0x00, 0x06, 0xff}
|
||
|
||
|
||
// ============================================================
|
||
// ACCENT — GREEN (success, safe, complete)
|
||
// ============================================================
|
||
|
||
GREEN_BRIGHT :: draw.Color{0xb8, 0xbb, 0x26, 0xff}
|
||
GREEN_DIM :: draw.Color{0x98, 0x97, 0x1a, 0xff}
|
||
GREEN_MUTED :: draw.Color{0x79, 0x74, 0x0e, 0xff}
|
||
|
||
|
||
// ============================================================
|
||
// ACCENT — BLUE / TEAL (info, links, cool technical elements)
|
||
// ============================================================
|
||
|
||
BLUE_BRIGHT :: draw.Color{0x83, 0xa5, 0x98, 0xff}
|
||
BLUE_DIM :: draw.Color{0x45, 0x85, 0x88, 0xff}
|
||
BLUE_MUTED :: draw.Color{0x07, 0x66, 0x78, 0xff}
|
||
|
||
|
||
// ============================================================
|
||
// ACCENT — ORANGE (warnings, in-progress, hot paths)
|
||
// ============================================================
|
||
|
||
ORANGE_BRIGHT :: draw.Color{0xfe, 0x80, 0x19, 0xff}
|
||
ORANGE_DIM :: draw.Color{0xd6, 0x5d, 0x0e, 0xff}
|
||
ORANGE_MUTED :: draw.Color{0xaf, 0x3a, 0x03, 0xff}
|
||
|
||
|
||
// ============================================================
|
||
// ACCENT — AQUA (cool secondary accent, fresh/active states)
|
||
// ============================================================
|
||
|
||
AQUA_BRIGHT :: draw.Color{0x8e, 0xc0, 0x7c, 0xff}
|
||
AQUA_DIM :: draw.Color{0x68, 0x9d, 0x6a, 0xff}
|
||
AQUA_MUTED :: draw.Color{0x42, 0x7b, 0x58, 0xff}
|
||
|
||
|
||
// ============================================================
|
||
// ACCENT — PURPLE (rare, for categorical / data-vis variety)
|
||
// ============================================================
|
||
|
||
PURPLE_BRIGHT :: draw.Color{0xd3, 0x86, 0x9b, 0xff}
|
||
PURPLE_DIM :: draw.Color{0xb1, 0x62, 0x86, 0xff}
|
||
PURPLE_MUTED :: draw.Color{0x8f, 0x3f, 0x71, 0xff}
|
||
|
||
|
||
// ============================================================
|
||
// SEMANTIC COLOR ROLES
|
||
// Aliases to accent ramps, named by intent. Prefer these in
|
||
// product code so meaning travels with the value.
|
||
// ============================================================
|
||
|
||
// Primary brand interactive — buttons, key links, focus ring.
|
||
COLOR_PRIMARY :: GOLD_BRIGHT
|
||
COLOR_PRIMARY_DIM :: GOLD_DIM
|
||
|
||
// Destructive / error / critical states.
|
||
COLOR_DANGER :: RED_BRIGHT
|
||
COLOR_DANGER_DIM :: RED_DIM
|
||
|
||
// Successful operation / safe state / completion.
|
||
COLOR_SUCCESS :: GREEN_BRIGHT
|
||
COLOR_SUCCESS_DIM :: GREEN_DIM
|
||
|
||
// Caution / in-progress / non-fatal anomaly.
|
||
COLOR_WARNING :: ORANGE_BRIGHT
|
||
COLOR_WARNING_DIM :: ORANGE_DIM
|
||
|
||
// Informational / neutral status / passive notice.
|
||
COLOR_INFO :: BLUE_BRIGHT
|
||
COLOR_INFO_DIM :: BLUE_DIM
|
||
|
||
// Hyperlinks at rest and on hover (links flip to gold on hover).
|
||
COLOR_LINK :: BLUE_BRIGHT
|
||
COLOR_LINK_HOVER :: GOLD_BRIGHT
|
||
|
||
// Keyboard / programmatic focus ring color.
|
||
COLOR_FOCUS :: GOLD_BRIGHT
|
||
|
||
|
||
// ============================================================
|
||
// SURFACE ROLES
|
||
// Semantic aliases for the bg ramp by usage role.
|
||
// ============================================================
|
||
|
||
SURFACE_PAGE :: BG_PAGE // root canvas
|
||
SURFACE_RAISED :: BG_SURFACE // cards, panels, inputs
|
||
SURFACE_OVERLAY :: BG_SHELL // modals, popovers, deep chrome
|
||
SURFACE_HOVER :: BG_ACTIVE // hovered raised surfaces
|
||
SURFACE_ACTIVE :: BG_SURFACE // pressed/active raised surfaces
|
||
|
||
|
||
// ============================================================
|
||
// BORDER ROLES
|
||
// Cybersteel borders are 1px solid, always crisp, always visible.
|
||
// Color carries the meaning; weight rarely changes.
|
||
// ============================================================
|
||
|
||
BORDER :: BG_BORDER // structural borders, default
|
||
BORDER_SUBTLE :: BG_DISABLED // very faint separators
|
||
BORDER_ACCENT :: GOLD_DIM // decorative / active edge
|
||
BORDER_FOCUS :: GOLD_BRIGHT // focus rings
|
||
BORDER_DANGER :: RED_DIM // destructive states
|
||
BORDER_SUCCESS :: GREEN_DIM // success states
|
||
|
||
|
||
// ============================================================
|
||
// TRANSLUCENT ACCENT TINTS
|
||
// Used for hover fills behind ghost buttons and for warm
|
||
// gradient overlays. Alpha encodes the tint strength.
|
||
// ============================================================
|
||
|
||
// 20% gold tint behind a hovered secondary button.
|
||
TINT_GOLD_HOVER :: draw.Color{0xd7, 0x99, 0x21, 0x33} // ~20% alpha
|
||
|
||
// 20% red tint behind a hovered danger ghost button.
|
||
TINT_DANGER_HOVER :: draw.Color{0xcc, 0x24, 0x1d, 0x33}
|
||
|
||
// 20% green tint behind a hovered success ghost button.
|
||
TINT_SUCCESS_HOVER :: draw.Color{0x98, 0x97, 0x1a, 0x33}
|
||
|
||
// 8% gold tint — top of the diagonal "gold fade" feature
|
||
// section overlay.
|
||
TINT_GOLD_FADE :: draw.Color{0xfa, 0xbd, 0x2f, 0x14} // ~8% alpha
|
||
|
||
// 6% amber tint — top of the vertical "amber fade" overlay.
|
||
TINT_AMBER_FADE :: draw.Color{0xff, 0xb0, 0x00, 0x0f} // ~6% alpha
|
||
|
||
// 4% gold tint — corner of card gradient.
|
||
TINT_GOLD_CARD :: draw.Color{0xfa, 0xbd, 0x2f, 0x0a} // ~4% alpha
|
||
|
||
// 3% black tint — scanline overlay stripe color.
|
||
TINT_SCANLINE :: draw.Color{0x00, 0x00, 0x00, 0x08} // ~3% alpha
|
||
|
||
|
||
// ============================================================
|
||
// SHADOWS
|
||
// Cybersteel is FLAT — no drop shadows. Elevation is expressed
|
||
// through bg + border only. The single permitted shadow use is
|
||
// a 1px gold ring as a focus / active indicator. Constants are
|
||
// kept here so callers don't reach for ad-hoc shadow values.
|
||
// ============================================================
|
||
|
||
// 1px inset gold ring — only permitted shadow, used as focus
|
||
// or selected-state outline. Width is 1px; color follows.
|
||
SHADOW_GOLD_RING_WIDTH :: 1
|
||
SHADOW_GOLD_RING_COLOR :: GOLD_DIM
|
||
|
||
|
||
// ============================================================
|
||
// SPACING SCALE (8px base grid)
|
||
// All spacing values are multiples of 4px, with the main scale
|
||
// in multiples of 8px. Names describe the scope of the gap, not
|
||
// the raw size — pick by intent, not by pixel count.
|
||
// ============================================================
|
||
|
||
// Badge/tag inner padding, icon-label gap, border offsets, micro nudges.
|
||
SPACE_CHIP :: 4
|
||
|
||
// Inline element gaps, chip/pill padding, icon inset, tight row spacing.
|
||
SPACE_ELEMENT :: 8
|
||
|
||
// Button vertical padding, input inset, list row gap, label-to-field gap.
|
||
SPACE_COMPONENT :: 12
|
||
|
||
// Card inset, input horizontal padding, form field gap, default gap.
|
||
SPACE_GROUP :: 16
|
||
|
||
// Grouped nav items, related form section spacing, compact panel inset.
|
||
SPACE_CLUSTER :: 20
|
||
|
||
// Sidebar / panel inset, modal body padding, drawer inset, section
|
||
// subheader gap.
|
||
SPACE_PANEL :: 24
|
||
|
||
// Between distinct content blocks, card grid gutter, toolbar height.
|
||
SPACE_BLOCK :: 32
|
||
|
||
// Major content group spacing, dialog padding, page sub-section gap.
|
||
SPACE_CONTENT :: 40
|
||
|
||
// Page section breaks, feature group dividers, hero subheading gap.
|
||
SPACE_SECTION :: 48
|
||
|
||
// Hero vertical padding, layout area spacing, large feature gaps.
|
||
SPACE_REGION :: 64
|
||
|
||
// Page-scale layout spacing, full-width section vertical rhythm.
|
||
SPACE_ZONE :: 80
|
||
|
||
// Page margins, full-bleed hero top padding, maximum layout gutter.
|
||
SPACE_CANVAS :: 96
|
||
|
||
|
||
// ============================================================
|
||
// CORNER RADIUS
|
||
// Cybersteel does not round its corners like a toy. 0–4px is the
|
||
// preferred range; larger radii exist only for chips/pills.
|
||
// ============================================================
|
||
|
||
RADIUS_NONE :: 0 // sharp corners — preferred default for chrome
|
||
RADIUS_SM :: 4 // micro-rounding for inline code, small badges
|
||
RADIUS_MD :: 6 // default for cards, buttons, inputs
|
||
RADIUS_LG :: 10 // rare — used only for prominent containers
|
||
RADIUS_PILL :: 999 // fully-rounded chips, status pills, tags
|
||
|
||
|
||
// ============================================================
|
||
// BORDER WIDTH
|
||
// 1px solid is the standard. Heavier weights are only used for
|
||
// the Art Deco hairline accent on pre/code blocks.
|
||
// ============================================================
|
||
|
||
// Standard border weight everywhere — always crisp, always visible.
|
||
BORDER_WIDTH_DEFAULT :: 1
|
||
|
||
// Accent edge on <pre> blocks (left side, gold) and similar
|
||
// emphasized rule treatments.
|
||
BORDER_WIDTH_ACCENT :: 2
|
||
|
||
|
||
// ============================================================
|
||
// MOTION — TRANSITION DURATIONS
|
||
// Fast and purposeful. No bounce, no spring, no elastic. UI
|
||
// state changes in well under a quarter-second. Animations
|
||
// must explain causality; nothing is decorative.
|
||
// ============================================================
|
||
|
||
// Entering active/pressed state. Snap-down feel — must feel
|
||
// instant under the finger.
|
||
TRANSITION_PRESS :: 55 * time.Millisecond
|
||
|
||
// Releasing from a pressed state, and slower hover-out cases.
|
||
TRANSITION_UI :: 180 * time.Millisecond
|
||
|
||
// Hover enter / exit color shift on buttons, cards, links.
|
||
TRANSITION_HOVER :: 150 * time.Millisecond
|
||
|
||
// Overlay / modal / popover fade-in. Slightly longer to
|
||
// signal "a layer changed", not "a control changed".
|
||
TRANSITION_MODAL :: 200 * time.Millisecond
|
||
|
||
// Cursor / immediate-feedback transitions (caret moves,
|
||
// terminal output ticks).
|
||
TRANSITION_CURSOR :: 80 * time.Millisecond
|
||
|
||
|
||
// ============================================================
|
||
// MOTION — COMPONENT-LEVEL TIMINGS
|
||
// Specific named durations for known interactions. Prefer these
|
||
// over picking a raw transition for a given component.
|
||
// ============================================================
|
||
|
||
// Button press fade — primary/secondary/danger/success share this.
|
||
BUTTON_PRESS_FADE_DUR :: 55 * time.Millisecond
|
||
|
||
// Button release / hover-out fade.
|
||
BUTTON_RELEASE_FADE_DUR :: 180 * time.Millisecond
|
||
|
||
// Card hover (border + bg crossfade).
|
||
CARD_HOVER_FADE_DUR :: 150 * time.Millisecond
|
||
|
||
// Card press (border + bg snap to active).
|
||
CARD_PRESS_FADE_DUR :: 55 * time.Millisecond
|
||
|
||
// Modal / overlay enter.
|
||
MODAL_ENTER_DUR :: 200 * time.Millisecond
|
||
|
||
// Modal / overlay exit (mirror of enter for symmetry).
|
||
MODAL_EXIT_DUR :: 200 * time.Millisecond
|
||
|
||
// Link color crossfade on hover.
|
||
LINK_HOVER_FADE_DUR :: 180 * time.Millisecond
|
||
|
||
// Terminal scanline flicker tick — single frame of the loop.
|
||
SCANLINE_FLICKER_TICK :: 80 * time.Millisecond
|
||
|
||
|
||
// ============================================================
|
||
// TYPOGRAPHY — FONT FAMILY NAMES
|
||
// Sans: IBM Plex Sans
|
||
// Mono: Lilex — IBM Plex Mono with programming ligatures.
|
||
// Drop-in Plex Mono replacement; same skeleton, same
|
||
// proportions, plus =>, !=, >=, <=, etc. ligatures.
|
||
// Plex Sans covers display, body, and condensed roles by
|
||
// default. Lilex is for code, terminal output, data values,
|
||
// and full mono-mode surfaces.
|
||
// ============================================================
|
||
|
||
// Plain family names
|
||
FONT_FAMILY_SANS :: "IBM Plex Sans"
|
||
FONT_FAMILY_MONO :: "Lilex"
|
||
|
||
// IBM Plex Sans raw font data
|
||
SANS_THIN_RAW :: #load("fonts/IBMPlexSans-Thin.ttf") // IBM Plex Sans
|
||
SANS_THIN_ITALIC_RAW :: #load("fonts/IBMPlexSans-ThinItalic.ttf") // IBM Plex Sans
|
||
SANS_EXTRALIGHT_RAW :: #load("fonts/IBMPlexSans-ExtraLight.ttf") // IBM Plex Sans
|
||
SANS_EXTRALIGHT_ITALIC_RAW :: #load("fonts/IBMPlexSans-ExtraLightItalic.ttf") // IBM Plex Sans
|
||
SANS_LIGHT_RAW :: #load("fonts/IBMPlexSans-Light.ttf") // IBM Plex Sans
|
||
SANS_LIGHT_ITALIC_RAW :: #load("fonts/IBMPlexSans-LightItalic.ttf") // IBM Plex Sans
|
||
SANS_REGULAR_RAW :: #load("fonts/IBMPlexSans-Regular.ttf") // IBM Plex Sans
|
||
SANS_ITALIC_RAW :: #load("fonts/IBMPlexSans-Italic.ttf") // IBM Plex Sans
|
||
SANS_MEDIUM_RAW :: #load("fonts/IBMPlexSans-Medium.ttf") // IBM Plex Sans
|
||
SANS_MEDIUM_ITALIC_RAW :: #load("fonts/IBMPlexSans-MediumItalic.ttf") // IBM Plex Sans
|
||
SANS_SEMIBOLD_RAW :: #load("fonts/IBMPlexSans-SemiBold.ttf") // IBM Plex Sans
|
||
SANS_SEMIBOLD_ITALIC_RAW :: #load("fonts/IBMPlexSans-SemiBoldItalic.ttf") // IBM Plex Sans
|
||
SANS_BOLD_RAW :: #load("fonts/IBMPlexSans-Bold.ttf") // IBM Plex Sans
|
||
SANS_BOLD_ITALIC_RAW :: #load("fonts/IBMPlexSans-BoldItalic.ttf") // IBM Plex Sans
|
||
|
||
// Lilex raw font data
|
||
MONO_THIN_RAW :: #load("fonts/Lilex-Thin.ttf") // Lilex
|
||
MONO_THIN_ITALIC_RAW :: #load("fonts/Lilex-ThinItalic.ttf") // Lilex
|
||
MONO_EXTRALIGHT_RAW :: #load("fonts/Lilex-ExtraLight.ttf") // Lilex
|
||
MONO_EXTRALIGHT_ITALIC_RAW :: #load("fonts/Lilex-ExtraLightItalic.ttf") // Lilex
|
||
MONO_LIGHT_RAW :: #load("fonts/Lilex-Light.ttf") // Lilex
|
||
MONO_LIGHT_ITALIC_RAW :: #load("fonts/Lilex-LightItalic.ttf") // Lilex
|
||
MONO_REGULAR_RAW :: #load("fonts/Lilex-Regular.ttf") // Lilex
|
||
MONO_ITALIC_RAW :: #load("fonts/Lilex-Italic.ttf") // Lilex
|
||
MONO_MEDIUM_RAW :: #load("fonts/Lilex-Medium.ttf") // Lilex
|
||
MONO_MEDIUM_ITALIC_RAW :: #load("fonts/Lilex-MediumItalic.ttf") // Lilex
|
||
MONO_SEMIBOLD_RAW :: #load("fonts/Lilex-SemiBold.ttf") // Lilex
|
||
MONO_SEMIBOLD_ITALIC_RAW :: #load("fonts/Lilex-SemiBoldItalic.ttf") // Lilex
|
||
MONO_BOLD_RAW :: #load("fonts/Lilex-Bold.ttf") // Lilex
|
||
MONO_BOLD_ITALIC_RAW :: #load("fonts/Lilex-BoldItalic.ttf") // Lilex
|
||
|
||
|
||
// ============================================================
|
||
// TYPOGRAPHY — TYPE SCALE (1.25 modular ratio, base 16px)
|
||
// Minimum body size on web is 14px; print is 12pt.
|
||
// ============================================================
|
||
|
||
TEXT_XS :: 11 // status badges, fine print
|
||
TEXT_SM :: 13 // secondary labels, captions
|
||
TEXT_BASE :: 15 // default body text
|
||
TEXT_MD :: 16 // slightly prominent body
|
||
TEXT_LG :: 18 // subheadings, emphasized labels
|
||
TEXT_XL :: 22 // H3 level
|
||
TEXT_2XL :: 28 // H2 level
|
||
TEXT_3XL :: 36 // H1 level
|
||
TEXT_4XL :: 48 // display / hero
|
||
TEXT_5XL :: 64 // hero display
|
||
TEXT_6XL :: 96 // max scale; masthead only
|
||
|
||
|
||
// ============================================================
|
||
// TYPOGRAPHY — FONT WEIGHTS
|
||
// Constrained to the STATIC weights that BOTH faces actually
|
||
// ship from Google Fonts — IBM Plex Sans and Lilex share the
|
||
// same seven static instances:
|
||
// 100 Thin · 200 ExtraLight · 300 Light · 400 Regular ·
|
||
// 500 Medium · 600 SemiBold · 700 Bold
|
||
// There is no 800 ExtraBold and no 900 Black for either face.
|
||
// Do not request a weight outside this set — Google's API
|
||
// will fail or substitute, and the design will drift.
|
||
// ============================================================
|
||
|
||
WEIGHT_THIN :: 100
|
||
WEIGHT_EXTRALIGHT :: 200
|
||
WEIGHT_LIGHT :: 300
|
||
WEIGHT_REGULAR :: 400
|
||
WEIGHT_MEDIUM :: 500
|
||
WEIGHT_SEMIBOLD :: 600
|
||
WEIGHT_BOLD :: 700
|
||
|
||
|
||
// ============================================================
|
||
// TYPOGRAPHY — LINE HEIGHTS (unitless multipliers)
|
||
// Multiply by font size to derive a leading in pixels.
|
||
// ============================================================
|
||
|
||
LEADING_TIGHT :: 1.15 // display headings
|
||
LEADING_SNUG :: 1.30 // subheadings
|
||
LEADING_NORMAL :: 1.50 // default body prose
|
||
LEADING_LOOSE :: 1.70 // long-form reading, sparse density
|
||
LEADING_MONO :: 1.40 // code / terminal output
|
||
|
||
|
||
// ============================================================
|
||
// TYPOGRAPHY — LETTER SPACING (in EM units)
|
||
// Multiply by the resolved font size to get pixel spacing.
|
||
// ============================================================
|
||
|
||
TRACKING_TIGHT :: -0.02 // large headings, tightened display
|
||
TRACKING_NORMAL :: 0.00 // body default
|
||
TRACKING_WIDE :: 0.05 // H1/H2 ALL CAPS, button labels
|
||
TRACKING_WIDER :: 0.10 // H5 caps, section headers
|
||
TRACKING_WIDEST :: 0.20 // .label / .label-mono — ALL CAPS chip text
|
||
|
||
|
||
// ============================================================
|
||
// HEADING ROLES — paired size + tracking + casing intent
|
||
// Casing is documentation only; these are the numbers a
|
||
// renderer actually consumes.
|
||
// ============================================================
|
||
|
||
// H1 — page title, masthead. Title Case, ALL CAPS at display.
|
||
H1_SIZE :: TEXT_3XL
|
||
H1_WEIGHT :: WEIGHT_BOLD
|
||
H1_TRACKING :: TRACKING_WIDE
|
||
H1_LEADING :: LEADING_TIGHT
|
||
|
||
// H2 — major section. ALL CAPS.
|
||
H2_SIZE :: TEXT_2XL
|
||
H2_WEIGHT :: WEIGHT_BOLD
|
||
H2_TRACKING :: TRACKING_WIDE
|
||
H2_LEADING :: LEADING_TIGHT
|
||
|
||
// H3 — subsection. Sentence case, condensed semibold.
|
||
H3_SIZE :: TEXT_XL
|
||
H3_WEIGHT :: WEIGHT_SEMIBOLD
|
||
H3_TRACKING :: TRACKING_NORMAL
|
||
H3_LEADING :: LEADING_TIGHT
|
||
|
||
// H4 — minor subsection.
|
||
H4_SIZE :: TEXT_LG
|
||
H4_WEIGHT :: WEIGHT_SEMIBOLD
|
||
H4_TRACKING :: TRACKING_NORMAL
|
||
H4_LEADING :: LEADING_SNUG
|
||
|
||
// H5 — small caps section header (uses FG_SECONDARY).
|
||
H5_SIZE :: TEXT_BASE
|
||
H5_WEIGHT :: WEIGHT_SEMIBOLD
|
||
H5_TRACKING :: TRACKING_WIDER
|
||
H5_LEADING :: LEADING_SNUG
|
||
|
||
// H6 — mono caps eyebrow / overline (uses FG_CAPTION).
|
||
H6_SIZE :: TEXT_SM
|
||
H6_WEIGHT :: WEIGHT_REGULAR
|
||
H6_TRACKING :: TRACKING_WIDEST
|
||
H6_LEADING :: LEADING_SNUG
|
||
|
||
|
||
// ============================================================
|
||
// LABEL ROLES — small caps annotation chips
|
||
// ============================================================
|
||
|
||
// .label — sans condensed, ALL CAPS, FG_CAPTION.
|
||
LABEL_SIZE :: TEXT_XS
|
||
LABEL_WEIGHT :: WEIGHT_SEMIBOLD
|
||
LABEL_TRACKING :: TRACKING_WIDEST
|
||
|
||
// .label-mono — mono ALL CAPS, FG_MUTED.
|
||
LABEL_MONO_SIZE :: TEXT_XS
|
||
LABEL_MONO_WEIGHT :: WEIGHT_REGULAR
|
||
LABEL_MONO_TRACKING :: TRACKING_WIDEST
|
||
|
||
|
||
// ============================================================
|
||
// FOCUS RING
|
||
// 1px solid gold outline at 2px offset. Crisp, never blurry.
|
||
// No glow, no box-shadow halo.
|
||
// ============================================================
|
||
|
||
FOCUS_RING_WIDTH :: 1
|
||
FOCUS_RING_OFFSET :: 2
|
||
FOCUS_RING_COLOR :: BORDER_FOCUS // GOLD_BRIGHT
|
||
|
||
|
||
// ============================================================
|
||
// COMPONENT — BUTTONS
|
||
// Cybersteel buttons are uppercase, semibold→bold, with wide
|
||
// tracking. Default size is "md"; sm/lg shift padding + size.
|
||
// ============================================================
|
||
|
||
// Default (md) padding: vertical / horizontal
|
||
BUTTON_PAD_Y :: 8
|
||
BUTTON_PAD_X :: 18
|
||
BUTTON_FONT_SIZE :: 12
|
||
BUTTON_FONT_WEIGHT :: WEIGHT_BOLD
|
||
BUTTON_TRACKING :: 0.07 // EM — ALL CAPS button label
|
||
BUTTON_RADIUS :: RADIUS_MD
|
||
BUTTON_BORDER :: BORDER_WIDTH_DEFAULT
|
||
|
||
// Small button
|
||
BUTTON_SM_PAD_Y :: 5
|
||
BUTTON_SM_PAD_X :: 12
|
||
BUTTON_SM_FONT_SIZE :: 10
|
||
|
||
// Large button
|
||
BUTTON_LG_PAD_Y :: 11
|
||
BUTTON_LG_PAD_X :: 24
|
||
BUTTON_LG_FONT_SIZE :: 14
|
||
|
||
// Primary — solid gold fill, dark text. Hover brightens, press
|
||
// flips to fg-heading (cream) fill.
|
||
BUTTON_PRIMARY_BG :: GOLD_DIM
|
||
BUTTON_PRIMARY_FG :: BG_SHELL
|
||
BUTTON_PRIMARY_BORDER :: GOLD_DIM
|
||
BUTTON_PRIMARY_BG_HOVER :: GOLD_BRIGHT
|
||
BUTTON_PRIMARY_BORDER_HOVER :: GOLD_BRIGHT
|
||
BUTTON_PRIMARY_BG_PRESS :: FG_HEADING
|
||
BUTTON_PRIMARY_FG_PRESS :: BG_SHELL
|
||
BUTTON_PRIMARY_BORDER_PRESS :: FG_HEADING
|
||
|
||
// Secondary — transparent bg, structural border, hover gains
|
||
// gold tint + gold-dim border, press fills with gold-bright.
|
||
BUTTON_SECONDARY_BG :: [4]u8{0, 0, 0, 0} // transparent
|
||
BUTTON_SECONDARY_FG :: FG_SECONDARY
|
||
BUTTON_SECONDARY_BORDER :: BG_BORDER
|
||
BUTTON_SECONDARY_BG_HOVER :: TINT_GOLD_HOVER
|
||
BUTTON_SECONDARY_BORDER_HOVER :: GOLD_DIM
|
||
BUTTON_SECONDARY_FG_HOVER :: FG_BODY
|
||
BUTTON_SECONDARY_BG_PRESS :: GOLD_BRIGHT
|
||
BUTTON_SECONDARY_FG_PRESS :: [4]u8{0xff, 0xff, 0xff, 0xff}
|
||
BUTTON_SECONDARY_BORDER_PRESS :: GOLD_BRIGHT
|
||
|
||
// Ghost — fully transparent, no border. Hover lifts to BG_ACTIVE.
|
||
BUTTON_GHOST_BG :: [4]u8{0, 0, 0, 0}
|
||
BUTTON_GHOST_FG :: FG_CAPTION
|
||
BUTTON_GHOST_BORDER :: [4]u8{0, 0, 0, 0}
|
||
BUTTON_GHOST_BG_HOVER :: BG_ACTIVE
|
||
BUTTON_GHOST_FG_HOVER :: FG_BODY
|
||
BUTTON_GHOST_BG_PRESS :: GOLD_DIM
|
||
BUTTON_GHOST_FG_PRESS :: [4]u8{0xff, 0xff, 0xff, 0xff}
|
||
|
||
// Danger — destructive ghost button.
|
||
BUTTON_DANGER_BG :: [4]u8{0, 0, 0, 0}
|
||
BUTTON_DANGER_FG :: RED_BRIGHT
|
||
BUTTON_DANGER_BORDER :: RED_DIM
|
||
BUTTON_DANGER_BG_HOVER :: TINT_DANGER_HOVER
|
||
BUTTON_DANGER_BORDER_HOVER :: RED_BRIGHT
|
||
BUTTON_DANGER_FG_HOVER :: FG_BODY
|
||
BUTTON_DANGER_BG_PRESS :: RED_BRIGHT
|
||
BUTTON_DANGER_FG_PRESS :: [4]u8{0xff, 0xff, 0xff, 0xff}
|
||
BUTTON_DANGER_BORDER_PRESS :: RED_BRIGHT
|
||
|
||
// Success — confirming ghost button.
|
||
BUTTON_SUCCESS_BG :: [4]u8{0, 0, 0, 0}
|
||
BUTTON_SUCCESS_FG :: GREEN_BRIGHT
|
||
BUTTON_SUCCESS_BORDER :: GREEN_DIM
|
||
BUTTON_SUCCESS_BG_HOVER :: TINT_SUCCESS_HOVER
|
||
BUTTON_SUCCESS_BORDER_HOVER :: GREEN_BRIGHT
|
||
BUTTON_SUCCESS_FG_HOVER :: FG_BODY
|
||
BUTTON_SUCCESS_BG_PRESS :: GREEN_BRIGHT
|
||
BUTTON_SUCCESS_FG_PRESS :: [4]u8{0xff, 0xff, 0xff, 0xff}
|
||
BUTTON_SUCCESS_BORDER_PRESS :: GREEN_BRIGHT
|
||
|
||
// Disabled — flat low-contrast surface, opacity-dimmed.
|
||
BUTTON_DISABLED_BG :: BG_ACTIVE
|
||
BUTTON_DISABLED_FG :: FG_MUTED
|
||
BUTTON_DISABLED_BORDER :: BG_BORDER
|
||
BUTTON_DISABLED_OPACITY :: 0.5
|
||
|
||
|
||
// ============================================================
|
||
// COMPONENT — CARDS
|
||
// Flat, structural, mechanical. Background sits one step above
|
||
// page; border is structural by default and shifts to gold-dim
|
||
// on hover/press. Corner radius is the default 6px (RADIUS_MD).
|
||
// ============================================================
|
||
|
||
CARD_BG :: BG_SURFACE
|
||
CARD_BORDER :: BG_BORDER
|
||
CARD_BORDER_HOVER :: GOLD_DIM
|
||
CARD_BG_PRESS :: BG_ACTIVE
|
||
CARD_BORDER_PRESS :: GOLD_DIM
|
||
CARD_RADIUS :: RADIUS_MD
|
||
CARD_BORDER_WIDTH :: BORDER_WIDTH_DEFAULT
|
||
CARD_PADDING :: SPACE_GROUP // 16px default inset
|
||
|
||
|
||
// ============================================================
|
||
// COMPONENT — INPUTS
|
||
// Inputs sit on BG_SURFACE with structural borders. Focus
|
||
// promotes the border to gold-bright; the focus ring follows.
|
||
// ============================================================
|
||
|
||
INPUT_BG :: BG_SURFACE
|
||
INPUT_FG :: FG_BODY
|
||
INPUT_PLACEHOLDER :: FG_CAPTION
|
||
INPUT_BORDER :: BG_BORDER
|
||
INPUT_BORDER_HOVER :: GOLD_DIM
|
||
INPUT_BORDER_FOCUS :: GOLD_BRIGHT
|
||
INPUT_BORDER_DANGER :: RED_DIM
|
||
INPUT_RADIUS :: RADIUS_MD
|
||
INPUT_PAD_Y :: SPACE_COMPONENT // 12
|
||
INPUT_PAD_X :: SPACE_GROUP // 16
|
||
|
||
|
||
// ============================================================
|
||
// COMPONENT — BADGES / STATUS PILLS
|
||
// ============================================================
|
||
|
||
BADGE_FONT_SIZE :: TEXT_XS
|
||
BADGE_WEIGHT :: WEIGHT_SEMIBOLD
|
||
BADGE_TRACKING :: TRACKING_WIDEST
|
||
BADGE_PAD_Y :: SPACE_CHIP // 4
|
||
BADGE_PAD_X :: SPACE_ELEMENT // 8
|
||
BADGE_RADIUS :: RADIUS_SM
|
||
|
||
|
||
// ============================================================
|
||
// COMPONENT — DECO RULE
|
||
// Hairline Art Deco horizontal rule: 1px gold-dim top + 1px
|
||
// structural drop, with panel-sized vertical margins.
|
||
// ============================================================
|
||
|
||
DECO_RULE_TOP_WIDTH :: 1
|
||
DECO_RULE_TOP_COLOR :: GOLD_DIM
|
||
DECO_RULE_DROP_WIDTH :: 1
|
||
DECO_RULE_DROP_COLOR :: BG_BORDER
|
||
DECO_RULE_MARGIN_Y :: SPACE_PANEL // 24
|
||
|
||
|
||
// ============================================================
|
||
// LAYOUT — FIXED CHROME WIDTHS
|
||
// Sidebar widths are fixed; content lives in 8 or 12 column
|
||
// grids. No responsive collapsing for chrome — Cybersteel UIs
|
||
// run on real workstations.
|
||
// ============================================================
|
||
|
||
SIDEBAR_WIDTH_NARROW :: 240
|
||
SIDEBAR_WIDTH_WIDE :: 280
|
||
|
||
GRID_COLUMNS_NARROW :: 8
|
||
GRID_COLUMNS_WIDE :: 12
|
||
|
||
// Toolbar height matches SPACE_BLOCK so vertical rhythm aligns.
|
||
TOOLBAR_HEIGHT :: SPACE_BLOCK // 32
|
||
|
||
|
||
// ============================================================
|
||
// CODE BLOCKS — <pre>
|
||
// Mono, BG_SHELL surface with a 1px structural border and a
|
||
// 2px gold-dim accent on the left edge.
|
||
// ============================================================
|
||
|
||
CODE_INLINE_BG :: BG_SURFACE
|
||
CODE_INLINE_FG :: GOLD_BRIGHT
|
||
CODE_INLINE_BORDER :: BG_BORDER
|
||
CODE_INLINE_PAD_Y :: 2
|
||
CODE_INLINE_PAD_X :: 6
|
||
CODE_INLINE_RADIUS :: RADIUS_SM
|
||
|
||
PRE_BG :: BG_SHELL
|
||
PRE_FG :: FG_BODY
|
||
PRE_BORDER :: BG_BORDER
|
||
PRE_BORDER_LEFT_COLOR :: GOLD_DIM
|
||
PRE_BORDER_LEFT_WIDTH :: BORDER_WIDTH_ACCENT // 2
|
||
PRE_PAD_Y :: SPACE_GROUP // 16
|
||
PRE_PAD_X :: SPACE_PANEL // 24
|
||
|
||
|
||
// ============================================================
|
||
// SCANLINE OVERLAY (opt-in, terminal surfaces only)
|
||
// Repeating-stripe pattern at very low opacity. Stripe is 2px
|
||
// transparent + 2px black-at-3% (TINT_SCANLINE).
|
||
// ============================================================
|
||
|
||
SCANLINE_STRIPE_PX :: 2
|
||
SCANLINE_GAP_PX :: 2
|
||
SCANLINE_COLOR :: TINT_SCANLINE
|