/* 2026 Portfolio — generated from tokens.json */
:root, [data-theme="light"] {
  --surface-canvas: #f4f7fc; /* Level 1: page background, the primary canvas. Pale periwinkle in light, cool charcoal in dark. Never pure #ffffff or #000000. */
  --surface-card: #eaf0f9; /* Level 2: card surfaces and product mockup backgrounds, one step off the canvas for paper-on-paper layering. */
  --surface-elevated: #dce6f4; /* Level 3: secondary buttons, logo tiles and higher-elevation cards. */
  --surface-outline: #c5d7eb; /* Level 4: hairline borders, dividers and separators on elevated surfaces, and the window-frame dots. A 1px rule only; at 1.4:1 (light) and 1.8:1 (dark) on surface-canvas it is decorative and must not be the only edge of a control. */
  --text-primary: #021b43; /* Primary text, navigation and headings on every surface level: navy in light, cool white in dark (15.3:1 or better on surface-canvas in both themes). */
  --text-subdued: #3e4c6c; /* Icon fills, subdued UI labels, footer links, mono metadata and the terminal prompt glyph, on surface-canvas, surface-card and surface-elevated (6.7:1 or better in both themes). */
  --text-secondary: #4a5878; /* Secondary body text, table content, ghost buttons and logo-tile marks, on surface-canvas, surface-card and surface-elevated (5.6:1 or better in both themes). */
  --text-helper: #566485; /* Tertiary helper text and captions, on surface-canvas, surface-card and surface-elevated (4.6:1 or better in both themes). */
  --border-subtle: #021b430d; /* text-primary at low alpha (5% in light, 8% in dark): the 1px border of cards and window frames. Update it when text-primary changes. Decorative. */
  --border-strong: #021b431a; /* text-primary at low alpha (10% in light, 14% in dark): the 1px border of the terminal input and window chrome. Update it when text-primary changes. Below the 3:1 a control border should have, so pair it with a surface-card fill. */
  --accent-1: #4758c0; /* The one accent: inline text links, tags and short emphasized phrases. Indigo in light, periwinkle in dark, on surface-canvas, surface-card and surface-elevated (4.8:1 or better in both themes). Text only; never a button background, large fill or icon fill. */
  --accent-2: #c8331f; /* Supporting text accent for links, tags and short emphasis: deep coral in light, peach in dark. On surface-canvas and surface-card (4.6:1 or better in both themes); in dark it also passes on surface-elevated. Not a status color. */
  --accent-3: #c90b62; /* Second supporting text accent: magenta in light, neon pink in dark. On surface-canvas and surface-card (4.9:1 or better in both themes); in dark it also passes on surface-elevated. Not a status color. */
  --action-primary: var(--text-primary); /* Fill of the primary filled button, the highest-contrast action on a page. An alias of text-primary: a navy button in light, a cool white one in dark. */
  --on-action-primary: var(--surface-canvas); /* Label on an action-primary fill. An alias of surface-canvas. */
  --action-secondary: var(--surface-elevated); /* Fill of the secondary filled button, paired beside the primary. An alias of surface-elevated. */
  --on-action-secondary: var(--text-primary); /* Label and arrow glyph on an action-secondary fill. An alias of text-primary. */
  --action-build: #cf372b; /* Fill of the compact in-product action button (Build, Continue, Publish) and accent icon strokes inside product mockups: deep coral in light, peach in dark. Product chrome only, never a page-level CTA. */
  --on-action-build: var(--surface-canvas); /* Label on an action-build fill. An alias of surface-canvas in both themes: light on deep coral (4.6:1), charcoal on peach (7.7:1). */
  --action-confirm: #552580; /* Fill and 1px border of the confirm action button (View PR, View page) inside product mockups, and selected navigation states: deep purple in light, lavender in dark. A supporting accent, not a status color. */
  --on-action-confirm: var(--surface-canvas); /* Label on an action-confirm fill. An alias of surface-canvas in both themes: light on deep purple (9.9:1), charcoal on lavender (6.4:1). */
  --selection: #f5dfba; /* Background of browser text selection, with text-primary on it: pale sand in light (13.0:1), slate blue in dark (8.8:1). Reserved for selection only. */
  --art-coral: #f3584e; /* Coral. A GradientArt layer color, the same in both themes. Artwork only: never text, a button fill, a border or a flat surface. */
  --art-amber: #fea756; /* Amber. A GradientArt layer color, the same in both themes. Artwork only: never text, a button fill, a border or a flat surface. */
  --art-pink: #f57ecb; /* Pink. A GradientArt layer color, the same in both themes. Artwork only: never text, a button fill, a border or a flat surface. */
  --art-violet: #ab73fa; /* Violet. A GradientArt layer color, the same in both themes. Artwork only: never text, a button fill, a border or a flat surface. */
  --art-blue: #6593f0; /* Blue. A GradientArt layer color, the same in both themes. Artwork only: never text, a button fill, a border or a flat surface. */
  --art-cyan: #67cbed; /* Cyan. A GradientArt layer color, the same in both themes. Artwork only: never text, a button fill, a border or a flat surface. */
  --art-mint: #8fe6cb; /* Mint. A GradientArt layer color, the same in both themes. Artwork only: never text, a button fill, a border or a flat surface. */
  --art-light: #fbfcff; /* Near white, the same in both themes. The pale core of a bloom in GradientArt. Artwork only. */
  --glass-fill: #dce6f4cc; /* Fill of a glass panel: the surface-elevated tone at 80% in each theme, with a backdrop blur behind it, so a pattern shows through as a soft tint. Opaque enough that text-primary and text-subdued keep 4.5:1 even with the brightest art color directly underneath. accent-1 passes over plain glass but not over a bright pattern core, so use it only for the current page in SideNav. */
  --glass-border: #fbfcff99; /* The 1px edge of a glass panel: a light rim that catches the pattern behind it. Decorative. */
  --shadow-xl: rgba(0, 0, 0, 0.14) 0px 28px 70px 0px, rgba(0, 0, 0, 0.1) 0px 14px 32px 0px, #021b431a 0px 0px 0px 1px; /* Product mockup card: the soft double-layer elevation with a 1px ring. */
  --shadow-xl-2: rgba(0, 0, 0, 0.25) 0px 25px 50px -12px, rgba(0, 0, 0, 0.15) 0px 12px 24px -8px, #021b431a 0px 0px 0px 0.5px; /* Heavier floating elevation for windows lifted off a card. */
  --shadow-subtle: #e3ebf7 0px 0px 0px 2px; /* A 2px ring in a tone between surface-card and surface-elevated, for quiet grouping. */
  --shadow-subtle-2: #021b431a 0px 0px 0px 1px, rgba(0, 0, 0, 0.28) 0px 18px 36px -18px; /* A 1px ring with a tight under-shadow, for small raised panels. */
  --shadow-flyout: 0 0 1rem #00000005, 0 0 0.5rem #00000002; /* Flyouts and popovers. */
  --focus-ring: 0 0 0 2px #f4f7fc, 0 0 0 4px #021b43; /* Keyboard focus: a 2px surface-canvas gap, then 2px of solid text-primary. Update both values when those tokens change. */
}
[data-theme="dark"] {
  --surface-canvas: #161b20;
  --surface-card: #1d242b;
  --surface-elevated: #262e37;
  --surface-outline: #3a4558;
  --text-primary: #eef1f8;
  --text-subdued: #b9c3d6;
  --text-secondary: #a9b4c9;
  --text-helper: #99a5bc;
  --border-subtle: #eef1f814;
  --border-strong: #eef1f824;
  --accent-1: #8ba2f0;
  --accent-2: #fb9173;
  --accent-3: #f57ecb;
  --action-primary: var(--text-primary);
  --on-action-primary: var(--surface-canvas);
  --action-secondary: var(--surface-elevated);
  --on-action-secondary: var(--text-primary);
  --action-build: #fb9173;
  --on-action-build: var(--surface-canvas);
  --action-confirm: #af8deb;
  --on-action-confirm: var(--surface-canvas);
  --selection: #354163;
  --art-coral: #f3584e;
  --art-amber: #fea756;
  --art-pink: #f57ecb;
  --art-violet: #ab73fa;
  --art-blue: #6593f0;
  --art-cyan: #67cbed;
  --art-mint: #8fe6cb;
  --art-light: #fbfcff;
  --glass-fill: #262e37cc;
  --glass-border: #eef1f81f;
  --shadow-xl: rgba(0, 0, 0, 0.5) 0px 28px 70px 0px, rgba(0, 0, 0, 0.4) 0px 14px 32px 0px, #eef1f824 0px 0px 0px 1px;
  --shadow-xl-2: rgba(0, 0, 0, 0.6) 0px 25px 50px -12px, rgba(0, 0, 0, 0.45) 0px 12px 24px -8px, #eef1f824 0px 0px 0px 0.5px;
  --shadow-subtle: #262e37 0px 0px 0px 2px;
  --shadow-subtle-2: #eef1f824 0px 0px 0px 1px, rgba(0, 0, 0, 0.6) 0px 18px 36px -18px;
  --shadow-flyout: 0 0 1rem #00000040, 0 0 0.5rem #00000026;
  --focus-ring: 0 0 0 2px #161b20, 0 0 0 4px #eef1f8;
}
:root {
  --spacing-4: 4px; /* Base unit: icon-to-label gaps and the tightest insets. */
  --spacing-8: 8px; /* Default gap between sibling elements, rows in a footer column, prompt-to-command gap. */
  --spacing-12: 12px; /* Horizontal padding of compact product buttons and inputs; gap inside button groups. */
  --spacing-16: 16px; /* Logo tile padding; gaps between navigation actions. */
  --spacing-20: 20px; /* Between a heading and its body copy. */
  --spacing-24: 24px; /* Card padding, page side gutter, navigation bar side padding. */
  --spacing-32: 32px; /* Between blocks inside a section. */
  --spacing-48: 48px; /* Between a section heading and its content grid. */
  --spacing-56: 56px; /* Large gaps inside a hero. */
  --spacing-64: 64px; /* Smallest gap between page sections. */
  --radius-sm: 2px; /* Smallest details inside product mockups. */
  --radius-md: 4px; /* The workhorse corner for surfaces: cards, inputs, tiles. */
  --radius-lg: 8px; /* Modals. */
  --radius-xl: 12px; /* Top of the scale; reserve for large overlays. */
  --radius-buttons: 9999px; /* Every action button: a full pill. Buttons are the only pill shape in the system. */
  --radius-cards: 4px; /* Cards and window frames. */
  --radius-tiles: 4px; /* Logo tiles. */
  --radius-inputs: 4px; /* Inputs and the terminal field. */
  --radius-modals: 8px; /* Modal dialogs. */
  --radius-panels: 20px; /* Glass panels such as SideNav. */
  --page-max-width: 1300px; /* Maximum content width, centered. */
  --page-gutter: 24px; /* Outer page padding at every width. */
  --nav-height: 52px; /* Height of the top navigation bar. */
  --section-gap-min: 64px; /* Smallest vertical gap between page sections. */
  --section-gap-max: 96px; /* Largest vertical gap between page sections. */
  --card-padding: 24px; /* Internal padding of cards. */
  --element-gap: 12px; /* Default gap between sibling elements. */
  --font-sans: Geist, ui-sans-serif, system-ui, "Helvetica Neue", sans-serif;
  --font-serif: "EB Garamond", "Iowan Old Style", "Palatino Linotype", ui-serif, Georgia, serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  --font-system: system-ui, -apple-system, "Helvetica Neue", sans-serif;
  --text-display: 400 72px/1.1 var(--font-sans); /* Hero headline, once per page. */
  --text-heading-lg: 400 36px/1.2 var(--font-sans); /* Section headlines. */
  --text-heading: 400 26px/1.25 var(--font-sans); /* Card and feature headings. */
  --text-heading-sm: 400 22px/1.3 var(--font-sans); /* Feature-section headings beside a screenshot. */
  --text-body: 400 16px/1.5 var(--font-sans); /* Default body copy. */
  --text-body-sm: 400 14px/1.5 var(--font-sans); /* Buttons, navigation links and compact UI text. Weight 500 for the wordmark and footer column headings. */
  --text-body-xs: 400 13px/1.5 var(--font-sans); /* Footer links and small ghost buttons. */
  --text-eyebrow: 400 12px/1.63 var(--font-sans); /* Small label above a heading. */
  --text-editorial-lg: 400 19px/1.35 var(--font-serif); /* Editorial subheadings and pull lines. */
  --text-editorial: 400 17px/1.5 var(--font-serif); /* Prose body in long-form pages. */
  --text-editorial-sm: 400 16px/1.5 var(--font-serif); /* Table data and short editorial notes. */
  --text-code: 400 12px/1.67 var(--font-mono); /* Code, file paths, CLI commands, metadata tags and file tabs. */
  --text-code-lg: 400 13px/1.43 var(--font-mono); /* Larger code blocks. */
  --text-meta-title: 400 13px/1.25 var(--font-system); /* Window-frame titles. */
  --text-meta: 400 12px/1.55 var(--font-system); /* Small meta labels and supplementary UI. */
  --text-meta-sm: 400 11px/1.55 var(--font-system); /* The smallest meta labels. */
}
.display {
  font-family: var(--font-sans);
  font-size: 72px;
  line-height: 1.1;
  font-weight: 400;
  letter-spacing: -2.16px;
}
.heading-lg {
  font-family: var(--font-sans);
  font-size: 36px;
  line-height: 1.2;
  font-weight: 400;
  letter-spacing: -0.72px;
}
.heading {
  font-family: var(--font-sans);
  font-size: 26px;
  line-height: 1.25;
  font-weight: 400;
  letter-spacing: -0.312px;
}
.heading-sm {
  font-family: var(--font-sans);
  font-size: 22px;
  line-height: 1.3;
  font-weight: 400;
  letter-spacing: -0.11px;
}
.body {
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.5;
  font-weight: 400;
  letter-spacing: 0;
}
.body-sm {
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.5;
  font-weight: 400;
  letter-spacing: 0.14px;
}
.body-xs {
  font-family: var(--font-sans);
  font-size: 13px;
  line-height: 1.5;
  font-weight: 400;
  letter-spacing: 0;
}
.eyebrow {
  font-family: var(--font-sans);
  font-size: 12px;
  line-height: 1.63;
  font-weight: 400;
  letter-spacing: 0;
}
.editorial-lg {
  font-family: var(--font-serif);
  font-size: 19px;
  line-height: 1.35;
  font-weight: 400;
  letter-spacing: 0;
}
.editorial {
  font-family: var(--font-serif);
  font-size: 17px;
  line-height: 1.5;
  font-weight: 400;
  letter-spacing: 0;
}
.editorial-sm {
  font-family: var(--font-serif);
  font-size: 16px;
  line-height: 1.5;
  font-weight: 400;
  letter-spacing: 0;
}
.code {
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.67;
  font-weight: 400;
  letter-spacing: 0;
}
.code-lg {
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.43;
  font-weight: 400;
  letter-spacing: 0;
}
.meta-title {
  font-family: var(--font-system);
  font-size: 13px;
  line-height: 1.25;
  font-weight: 400;
  letter-spacing: 0.004em;
}
.meta {
  font-family: var(--font-system);
  font-size: 12px;
  line-height: 1.55;
  font-weight: 400;
  letter-spacing: 0.004em;
}
.meta-sm {
  font-family: var(--font-system);
  font-size: 11px;
  line-height: 1.55;
  font-weight: 400;
  letter-spacing: 0.004em;
}
