/* ==========================================================================
   Theme Styles - Design System
   ==========================================================================
   Usage: Add data-preset="light|dark|midnight|warm|forest" to body
   Default preset is "light" when no attribute is set
   ========================================================================== */

/* ============================================================
   LIGHT PRESET (DEFAULT) - coss.com/ui monochrome
   Geist, neutral ramp, 10px radius, hairline borders, flat cards
   Ramp: 50 #fafafa · 100 #f5f5f5 · 200 #e5e5e5 · 300 #d4d4d4
         400 #a1a1a1 · 500 #737373 · 600 #525252 · 700 #404040
         800 #262626 · 900 #171717 · 950 #0a0a0a
   ============================================================ */
:root,
[data-preset="light"] {
  /* Typography - Geist */
  /* ONE SANS AND ONE MONO, IN ALL SIX PRESETS.

     Heading and body are the same family on purpose - there is no pairing in
     this system - and every preset now names it. Before this pass the dark and
     midnight presets shipped 'Inter' as their body face, warm shipped
     'Source Sans 3', forest shipped 'DM Sans', and three presets asked for
     'JetBrains Mono'. None of those faces is loaded by this theme, so what
     actually rendered was whatever the fallback chain reached first - which is
     the stray Inter measured on /contact and the stray Times on /services.
     A font a theme does not load is not a design decision, it is a lottery. */
  --font-family-heading: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-family-body: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-family-mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  /* The type SCALE is not declared per preset any more. It used to be, six
     times, with six different sets of numbers - h2 was 30px on light, 24px
     on dark and midnight, 27px on warm - so "one theme setting for h2" was
     never true and the same page measured two different h2 sizes depending
     on which preset it rendered under. A typeface is preset character; a
     size ladder is not. One fluid scale is declared once, after the preset
     blocks, under THE TYPE SCALE below. */
  --font-weight-light: 400;
  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  /* 700, not 600. The scale uses four weights and they are not
     interchangeable: 400 prose, 500 UI, 600 h2-h4, 700 h1 and display. With
     bold at 600 the h1 and the h2 were the same weight and the hierarchy
     between them was carried by size alone, which at 48 over 24 still reads
     but is a step of the system that was simply not there. */
  --font-weight-bold: 700;
  --line-height-none: 1;
  --line-height-tight: 1.15;
  --line-height-snug: 1.35;
  /* 1.625 gives a whole 26px at the 16px body step, and 1.55 gives a whole
     28px at the 18px lead step - the two ratios the scale actually has to
     land on. At 1.6 and 1.7 a paragraph measured 25.6px and a lede 30.6px,
     neither of which is on the 4px grid, and the lede was a full step looser
     than the body under it. */
  --line-height-normal: 1.625;
  --line-height-relaxed: 1.55;
  --line-height-loose: 1.8;
  /* TRACKING IS NORMAL. All five names resolve to the same value on purpose.

     Measured across the live pages, headings were rendering at -1.223px,
     -0.79px, -0.575px, -0.433px and -0.36px of tracking, and small uppercase
     labels at +0.26px. Negative tracking on a variable sans at display sizes
     is what makes type look squeezed rather than confident, and the reference
     system has letter-spacing: normal on every element without exception.

     The NAMES are kept rather than deleted because a dozen module rules and
     several theme-settings fields read them; deleting them would have failed
     those declarations open to the browser default, which is the same value
     but reached by accident. Keeping the names means one edit here changes
     every one of them, and a buyer who genuinely wants tracking has a token
     to move. */
  --letter-spacing-tighter: normal;
  --letter-spacing-tight: normal;
  --letter-spacing-normal: normal;
  --letter-spacing-wide: normal;
  --letter-spacing-wider: normal;

  /* Colors - neutral ramp, no coloured accents.

     A blue accent was tried here and rejected on sight. The identity is
     monochrome: colour is earned in the one or two places where it carries
     meaning - a rating, a warning - and is never rolled out as a site-wide
     accent. --color-rating below is the whole of the colour in this preset.
     Do not reintroduce a general accent without asking. */
  --color-primary: #171717;
  --color-secondary: #737373;
  --color-accent: #171717;
  --color-accent-hover: #262626;
  --color-background: #ffffff;
  --color-foreground: #262626;
  --color-error: #ef4444;
  --color-success: #262626;
  --color-warning: #525252;

  /* Status Colors - depth of grey instead of hue */
  --color-status-draft: #a1a1a1;
  --color-status-draft-bg: #fafafa;
  --color-status-draft-text: #737373;
  --color-status-generated: #737373;
  --color-status-generated-bg: #f5f5f5;
  --color-status-generated-text: #525252;
  --color-status-sent: #525252;
  --color-status-sent-bg: #f5f5f5;
  --color-status-sent-text: #404040;
  --color-status-accepted: #262626;
  --color-status-accepted-bg: #e5e5e5;
  --color-status-accepted-text: #171717;
  --color-status-declined: #a1a1a1;
  --color-status-declined-bg: #fafafa;
  --color-status-declined-text: #a1a1a1;
  --color-status-fulfilled: #404040;
  --color-status-fulfilled-bg: #f5f5f5;
  --color-status-fulfilled-text: #262626;
  --color-status-closed: #737373;
  --color-status-closed-bg: #f5f5f5;
  --color-status-closed-text: #525252;
  --color-status-inactive: #d4d4d4;
  --color-status-inactive-bg: #fafafa;
  --color-status-inactive-text: #a1a1a1;

  --color-on-accent: #fafafa;
  --color-body-bg: #ffffff;
  --color-cards-bg: #ffffff;
  /* coss draws its hairlines as translucent black rather than a solid grey,
     so a border stays crisp on any surface: --border is #000 at 8%, which
     flattens to #ebebeb over white, and --input is #000 at 10% -> #e5e5e5.
     This theme had one token doing both jobs at the input value, so every
     card hairline was a step heavier than the system draws it. Split. */
  --color-border: rgba(0, 0, 0, 0.08);
  --color-border-strong: rgba(0, 0, 0, 0.10);
  --color-border-hover: #d4d4d4;
  --color-muted: #737373;
  --color-overlay: rgba(10, 10, 10, 0.5);
  --color-text: #262626;
  /* #686868, not #737373. coss derives muted text as a 90% srgb mix of
     neutral-500 toward black; #737373 is neutral-500 raw and measures 4.74:1
     on white, which is under AA for the 14px it is used at. #686868 measures
     5.57:1 and is the value the live components render. */
  --color-text-muted: #686868;
  --color-heading: #171717;
  --color-link: #262626;
  --color-link-hover: #737373;
  --color-card-bg: #ffffff;
  --color-accent-light: rgba(38, 38, 38, 0.04);

  /* Rating marks. A star is not an accent - it is a rating, and a rating
     reads as warm. Its own token so colouring stars never means recolouring
     links, and so a buyer can set it without touching the accent. */
  --color-rating: #f59e0b;

  /* BADGES - the only other colour in the theme.

     Status chips (HIRING, NEW, FREE) carry the colour the site itself does
     not. They used to read off --color-accent and --color-success, which in
     a monochrome preset are both near-black, so on the black footer they
     were dark chips on a dark ground and effectively invisible.

     Each style is a pair - a solid fill and its own foreground - chosen so
     the chip passes on BOTH grounds: a saturated mid-tone with white text
     reads against white and against black without a second rule. Adding a
     style means adding a pair here, not writing new CSS. */
  /* BADGES ARE TINTED CHIPS, NOT SATURATED FILLS.

     What shipped was a solid saturated fill with white text, and two of the
     pairs failed WCAG AA outright: white on #059669 measures 3.77:1 and white
     on #d97706 measures 3.19:1, against the 4.5 a 12px label needs. Raising
     the fills would have fixed the numbers and kept a look the system does
     not have - five loud blocks of colour on a monochrome page.

     coss draws a semantic badge as the colour at 8% with the DARK end of the
     same hue as the label. Measured over white, every pair clears AA with
     room: info #eef5ff/#1447e6 6.23, success #ebfaf5/#007a55 4.99, warning
     #fff7eb/#bb4d00 4.73, error #ffeeef/#c10007 5.73. On the black footer the
     chips themselves read at 18.7-19.8:1, so the same tokens work on both
     grounds without a dark-footer variant.

     `new` has no counterpart in coss - there is no purple in the system - so
     it takes the secondary chip, #f5f5f5 on #262626 at 13.88:1. A "New" flag
     is emphasis, not a semantic state, and emphasis in a monochrome system is
     weight and ground, not hue.

     The one pair left alone is `default`, a near-black chip: it measures
     1.39:1 against the black footer and is invisible there, and that case is
     already handled inside the footer module, which swaps to its own inverted
     white-chip/black-label pair at 21:1. */
  --badge-default-bg: #262626;
  --badge-default-fg: #fafafa;
  --badge-info-bg: #eef5ff;
  --badge-info-fg: #1447e6;
  --badge-new-bg: #f5f5f5;
  --badge-new-fg: #262626;
  --badge-success-bg: #ebfaf5;
  --badge-success-fg: #007a55;
  --badge-warning-bg: #fff7eb;
  --badge-warning-fg: #bb4d00;
  --badge-error-bg: #ffeeef;
  --badge-error-fg: #c10007;
  --color-icon: #737373;

  /* Code Block - monochrome, weight of grey carries the syntax */
  --code-bg: #fafafa;
  --code-border: #e5e5e5;
  --code-header-bg: #f5f5f5;
  --code-text: #262626;
  --code-text-muted: #737373;
  --code-keyword: #0a0a0a;
  --code-string: #525252;
  --code-number: #404040;
  --code-comment: #a1a1a1;
  --code-function: #171717;
  --code-operator: #737373;
  --code-punctuation: #a1a1a1;
  --code-success: #262626;
  --code-scrollbar: rgba(10, 10, 10, 0.15);

  /* Spacing */

  /* Border Radius - the coss.com/ui ramp, measured off the live components.

     It used to be flat: sm 6 and everything from md up pinned to 10, on the
     reasoning that one surface radius stops two corner treatments appearing
     side by side. That reasoning was right about the DEFECT and wrong about
     the fix. coss does not use one radius; it uses one BASE (0.625rem = 10px)
     and derives a short ramp from it, and it assigns each component a fixed
     step so nothing is ever choosing. Measured on the live coss components:
     badge 6, tab trigger and inline code 8, button / input / tabs list /
     popover 10, table-in-card 14, card 16.

     So the ramp comes back, and the drift it used to cause is prevented the
     other way - by every component below naming its step explicitly rather
     than by flattening the scale until the choice cannot be got wrong. */
  --radius-none: 0;
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 10px;
  --radius-xl: 14px;
  --radius-2xl: 16px;
  --radius-full: 9999px;

  /* Shadows - flat surfaces; depth survives only on floating chrome */
  --shadow-none: none;
  --shadow-sm: 0 1px 2px 0 rgba(10, 10, 10, 0.04);
  --shadow-md: 0 2px 6px -1px rgba(10, 10, 10, 0.06);
  --shadow-lg: 0 8px 24px -6px rgba(10, 10, 10, 0.10);
  --shadow-xl: 0 16px 40px -12px rgba(10, 10, 10, 0.12);
  --shadow-2xl: 0 24px 56px -16px rgba(10, 10, 10, 0.16);
  --shadow-inner: none;

  /* Buttons */
  --btn-padding-x: 1rem;
  --btn-padding-y: 0.5rem;
  --btn-padding-x-sm: 0.75rem;
  --btn-padding-y-sm: 0.375rem;
  --btn-padding-x-lg: 1.25rem;
  --btn-padding-y-lg: 0.625rem;
  --btn-font-size: 0.875rem;
  --btn-font-weight: 500;
  --btn-border-radius: 10px;
  --btn-border-width: 1px;
  --btn-primary-border-width: 1px;
  --btn-primary-bg: #171717;
  --btn-primary-bg-size: 100% 100%;
  --btn-primary-bg-position: 0 0;
  --btn-primary-bg-position-hover: 0 0;
  --btn-primary-bg-hover: #404040;
  --btn-primary-color: #fafafa;
  --btn-primary-color-hover: #fafafa;
  --btn-primary-border: #171717;
  --btn-primary-border-hover: #404040;
  --btn-secondary-bg: #ffffff;
  --btn-secondary-color: #262626;
  --btn-secondary-border: #e5e5e5;
  --btn-secondary-bg-hover: #f5f5f5;
  --btn-secondary-color-hover: #171717;
  --btn-secondary-border-hover: #d4d4d4;
  --btn-ghost-bg: transparent;
  --btn-ghost-color: #262626;
  --btn-ghost-border: transparent;
  --btn-ghost-bg-hover: #f5f5f5;
  --btn-shadow: none;
  --btn-shadow-hover: none;

  /* CTA Banner Backgrounds - flat */
  --cta-dark-bg: #171717;
  --cta-light-bg: #fafafa;

  /* Forms/Inputs */
  --input-padding-x: 0.75rem;
  --input-padding-y: 0.5rem;
  --input-font-size: 0.875rem;
  --input-border-radius: 10px;
  --input-border-width: 1px;
  /* An input's border is the one hairline coss draws heavier than a card's:
     --input is #000 at 10% (#e5e5e5) against --border's 8%. The focus ring is
     --ring, neutral-400. */
  --input-border-color: var(--color-border-strong);
  --input-border-color-focus: #a1a1a1;
  --input-bg: #ffffff;
  --input-bg-focus: #ffffff;
  --input-color: #262626;
  --input-placeholder: #a1a1a1;
  --input-border: var(--color-border-strong);
  --input-border-focus: #a1a1a1;

  /* Cards - the coss card, measured: 24px padding, 16px radius, a 1px
     translucent hairline, and shadow-xs.

     NO SHADOW. I put --shadow-control on the card in an earlier pass, reading
     it off the coss cards, and that was wrong for this theme.
     DESIGN-DIRECTION 5 settles it in one line - "Cards carry no shadow. A
     card is background + 1px solid border + radius 16px. That is the whole
     card." - and 7.4 repeats `box-shadow none`. --shadow-control is reserved
     there for controls: inputs, select triggers and outline buttons. It was
     landing on roughly eighteen card types including blog and listing cards,
     so this is the single token that takes it off all of them. Depth in this
     system comes from surface and hairline, never from lift. */
  --card-padding: 1.5rem;
  --card-border-radius: var(--radius-2xl);
  --card-border-width: 1px;
  --card-border-color: var(--color-border);
  --card-bg: #ffffff;
  --card-shadow: none;
  --card-image-height: 12rem;
  --card-image-height-mobile: 10rem;

  /* Layout */
  --header-height: 56px;

  /* Transitions */
  --transition-fast: 120ms cubic-bezier(0.16, 1, 0.3, 1);
  --transition-base: 160ms cubic-bezier(0.16, 1, 0.3, 1);
  --transition-slow: 200ms cubic-bezier(0.16, 1, 0.3, 1);
  --transition-slower: 240ms cubic-bezier(0.16, 1, 0.3, 1);

  /* Z-Index */
  --z-dropdown: 1000;
  --z-sticky: 1020;
  --z-fixed: 1030;
  --z-modal-backdrop: 1040;
  --z-modal: 1050;
  --z-popover: 1060;
  --z-tooltip: 1070;

  /* Gradients */
  --gradient-1: linear-gradient(to bottom right, #262626, #171717);
  --gradient-2: linear-gradient(to bottom, #ffffff, #fafafa);
  --gradient-3: linear-gradient(to bottom, transparent, #ffffff);

  /* Color scheme helpers */
  --color-on-dark: #fafafa;
  --color-muted-on-dark: rgba(250, 250, 250, 0.72);
  --color-border-on-dark: rgba(250, 250, 250, 0.14);
  --color-on-light: #262626;

  /* SOLID, NOT FADED. This was rgba(38, 38, 38, 0.6), and the hero lede is the
     one place it lands at 18px on white: measured 4.06:1, under the 4.5 AA
     needs at that size, and read as washed-out grey rather than as text. coss
     has no translucent foreground anywhere - muted text is a solid colour, a
     90% mix of neutral-500 toward black. Same construction here, expressed
     against the preset's own two colours so it resolves correctly on all six
     instead of six hand-picked greys: 74% of the foreground over the body
     ground, which is 5.9:1 on the light preset. */
  --color-muted-on-light: color-mix(in srgb, var(--color-foreground) 74%, var(--color-body-bg));
  --color-border-on-light: rgba(38, 38, 38, 0.09);

  /* Icon styling */
  --icon-fill: 0;
  --icon-weight: 300;
  --icon-grade: 0;
  --icon-opsz: 24;

  /* Hero/Banner heights */
  --hero-height-short: 400px;
  --hero-height-regular: 600px;
  --hero-height-tall: 800px;
  --hero-height-short-mobile: 300px;
  --hero-height-regular-mobile: 400px;
  --hero-height-tall-mobile: 500px;

  /* Content max widths */
  --content-max-width-narrow: 580px;
  --content-max-width-medium: 640px;
  --content-max-width-wide: 800px;
  --modal-max-width-sm: 600px;
  --modal-max-width-md: 800px;
  --modal-max-width-lg: 1440px;

  /* Component sizes */
  --logo-max-height: 40px;
  --avatar-size-sm: 24px;
  --avatar-size-md: 200px;
  --avatar-size-lg: 240px;
  --textarea-min-height: 100px;
  --loader-size: 80px;
}

/* ============================================================
   DARK PRESET - Linear/Raycast Inspired
   Inter font, true black, subtle borders, refined minimal
   ============================================================ */
[data-preset="dark"] {
  /* Typography - Inter */
  --font-family-heading: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-family-body: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-family-mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-weight-light: 300;
  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
  --line-height-none: 1;
  --line-height-tight: 1.2;
  --line-height-snug: 1.375;
  --line-height-normal: 1.625;
  --line-height-relaxed: 1.55;
  --line-height-loose: 1.75;
  --letter-spacing-tighter: normal;
  --letter-spacing-tight: normal;
  --letter-spacing-normal: normal;
  --letter-spacing-wide: normal;
  --letter-spacing-wider: normal;

  /* Colors - True black with zinc accents */
  --color-primary: #fafafa;
  --color-secondary: #71717a;
  --color-accent: #fafafa;
  --color-accent-hover: #d4d4d8;
  --color-background: #000000;
  --color-foreground: #fafafa;
  --color-error: #ef4444;
  --color-success: #22c55e;
  --color-warning: #eab308;

  /* Status Colors */
  --color-status-draft: #52525b;
  --color-status-draft-bg: rgba(82, 82, 91, 0.15);
  --color-status-draft-text: #a1a1aa;
  --color-status-generated: #3b82f6;
  --color-status-generated-bg: rgba(59, 130, 246, 0.12);
  --color-status-generated-text: #60a5fa;
  --color-status-sent: #8b5cf6;
  --color-status-sent-bg: rgba(139, 92, 246, 0.12);
  --color-status-sent-text: #a78bfa;
  --color-status-accepted: #22c55e;
  --color-status-accepted-bg: rgba(34, 197, 94, 0.12);
  --color-status-accepted-text: #4ade80;
  --color-status-declined: #ef4444;
  --color-status-declined-bg: rgba(239, 68, 68, 0.12);
  --color-status-declined-text: #f87171;
  --color-status-fulfilled: #eab308;
  --color-status-fulfilled-bg: rgba(234, 179, 8, 0.12);
  --color-status-fulfilled-text: #facc15;
  --color-status-closed: #52525b;
  --color-status-closed-bg: rgba(82, 82, 91, 0.15);
  --color-status-closed-text: #a1a1aa;
  --color-status-inactive: #3f3f46;
  --color-status-inactive-bg: rgba(63, 63, 70, 0.15);
  --color-status-inactive-text: #71717a;

  --color-on-accent: #09090b;
  --color-body-bg: #000000;
  --color-cards-bg: #0a0a0a;
  --color-border: #1f1f23;
  --color-border-hover: #2e2e33;
  --color-muted: #71717a;
  --color-overlay: rgba(0, 0, 0, 0.85);
  --color-text: #a1a1aa;
  --color-text-muted: #71717a;
  --color-heading: #fafafa;
  --color-link: #fafafa;
  --color-link-hover: #d4d4d8;
  --color-card-bg: #0a0a0a;
  --color-accent-light: rgba(250, 250, 250, 0.04);
  --color-icon: #71717a;

  /* Code Block - Dark theme (One Dark inspired) */
  --code-bg: #0d0d0f;
  --code-border: #1f1f23;
  --code-header-bg: #0a0a0a;
  --code-text: #abb2bf;
  --code-text-muted: #5c6370;
  --code-keyword: #c678dd;
  --code-string: #98c379;
  --code-number: #d19a66;
  --code-comment: #5c6370;
  --code-function: #61afef;
  --code-operator: #56b6c2;
  --code-punctuation: #abb2bf;
  --code-success: #98c379;
  --code-scrollbar: rgba(255, 255, 255, 0.1);

  /* Spacing */

  /* Border Radius */
  --radius-none: 0;
  --radius-sm: 0.25rem;
  --radius-md: 0.375rem;
  --radius-lg: 0.5rem;
  --radius-xl: 0.625rem;
  --radius-2xl: 0.75rem;
  --radius-full: 9999px;

  /* Shadows */
  --shadow-none: none;
  --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.5);
  --shadow-md: 0 2px 4px 0 rgba(0, 0, 0, 0.5);
  --shadow-lg: 0 4px 8px 0 rgba(0, 0, 0, 0.5);
  --shadow-xl: 0 8px 16px 0 rgba(0, 0, 0, 0.5);
  --shadow-2xl: 0 16px 32px 0 rgba(0, 0, 0, 0.6);
  --shadow-inner: inset 0 1px 2px 0 rgba(0, 0, 0, 0.3);
  --shadow-glow: 0 0 0 1px rgba(250, 250, 250, 0.05);

  /* Buttons */
  --btn-padding-x: 1rem;
  --btn-padding-y: 0.5rem;
  --btn-padding-x-sm: 0.75rem;
  --btn-padding-y-sm: 0.375rem;
  --btn-padding-x-lg: 1.5rem;
  --btn-padding-y-lg: 0.625rem;
  --btn-font-size: 0.875rem;
  --btn-font-weight: 500;
  --btn-border-radius: 0.375rem;
  --btn-border-width: 1px;
  --btn-primary-border-width: 0;
  --btn-primary-bg: linear-gradient(to bottom, #27272a 0%, #18181b 50%, #09090b 100%);
  --btn-primary-bg-size: 100% 200%;
  --btn-primary-bg-position: 0 0;
  --btn-primary-bg-position-hover: 0 100%;
  --btn-primary-color: #fafafa;
  --btn-primary-border: transparent;
  --btn-primary-bg-hover: #27272a;
  --btn-primary-color-hover: #fafafa;
  --btn-primary-border-hover: transparent;
  --btn-secondary-bg: transparent;
  --btn-secondary-color: #a1a1aa;
  --btn-secondary-border: #27272a;
  --btn-secondary-bg-hover: #18181b;
  --btn-secondary-color-hover: #fafafa;
  --btn-secondary-border-hover: #3f3f46;
  --btn-ghost-bg: transparent;
  --btn-ghost-color: #71717a;
  --btn-ghost-border: transparent;
  --btn-ghost-bg-hover: rgba(255, 255, 255, 0.05);
  --btn-shadow: none;
  --btn-shadow-hover: none;

  /* CTA Banner Backgrounds */
  --cta-dark-bg: linear-gradient(180deg, #18181b 0%, #09090b 100%);
  --cta-light-bg: #0a0a0a;

  /* Forms/Inputs */
  --input-padding-x: 0.75rem;
  --input-padding-y: 0.5rem;
  --input-font-size: 0.875rem;
  --input-border-radius: 0.375rem;
  --input-border-width: 1px;
  --input-border-color: #27272a;
  --input-border-color-focus: #3f3f46;
  --input-bg: #0a0a0a;
  --input-bg-focus: #0a0a0a;
  --input-color: #fafafa;
  --input-placeholder: #52525b;
  --input-border: #27272a;
  --input-border-focus: #52525b;

  /* Cards */
  --card-padding: 1.5rem;
  --card-border-radius: 0.5rem;
  --card-border-width: 1px;
  --card-border-color: #1f1f23;
  --card-bg: #0a0a0a;
  --card-shadow: none;
  --card-image-height: 12rem;
  --card-image-height-mobile: 10rem;

  /* Layout */
  --header-height: 56px;

  /* Transitions */
  --transition-fast: 100ms ease;
  --transition-base: 150ms ease;
  --transition-slow: 200ms ease;
  --transition-slower: 300ms ease;

  /* Z-Index */
  --z-dropdown: 1000;
  --z-sticky: 1020;
  --z-fixed: 1030;
  --z-modal-backdrop: 1040;
  --z-modal: 1050;
  --z-popover: 1060;
  --z-tooltip: 1070;

  /* Gradients */
  --gradient-1: linear-gradient(to bottom, #18181b, #09090b);
  --gradient-2: linear-gradient(to bottom, #0a0a0a, #000000);
  --gradient-3: linear-gradient(to bottom, transparent, #000000);

  /* Color scheme helpers */
  --color-on-dark: #fafafa;
  --color-muted-on-dark: rgba(250, 250, 250, 0.6);
  --color-border-on-dark: rgba(250, 250, 250, 0.08);
  --color-on-light: #09090b;
  --color-muted-on-light: color-mix(in srgb, var(--color-foreground) 74%, var(--color-body-bg));
  --color-border-on-light: rgba(9, 9, 11, 0.08);

  /* Icon styling */
  --icon-fill: 0;
  --icon-weight: 300;
  --icon-grade: 0;
  --icon-opsz: 24;

  /* Hero/Banner heights */
  --hero-height-short: 400px;
  --hero-height-regular: 600px;
  --hero-height-tall: 800px;
  --hero-height-short-mobile: 300px;
  --hero-height-regular-mobile: 400px;
  --hero-height-tall-mobile: 500px;

  /* Content max widths */
  --content-max-width-narrow: 580px;
  --content-max-width-medium: 640px;
  --content-max-width-wide: 800px;
  --modal-max-width-sm: 600px;
  --modal-max-width-md: 800px;
  --modal-max-width-lg: 1440px;

  /* Component sizes */
  --logo-max-height: 40px;
  --avatar-size-sm: 24px;
  --avatar-size-md: 200px;
  --avatar-size-lg: 240px;
  --textarea-min-height: 100px;
  --loader-size: 80px;
}

/* ============================================================
   MIDNIGHT PRESET - Stripe/Linear Inspired
   Inter font, slate palette, indigo accent
   ============================================================ */
[data-preset="midnight"] {
  /* Typography - Inter */
  --font-family-heading: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-family-body: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-family-mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-weight-light: 300;
  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
  --line-height-none: 1;
  --line-height-tight: 1.2;
  --line-height-snug: 1.375;
  --line-height-normal: 1.625;
  --line-height-relaxed: 1.55;
  --line-height-loose: 1.75;
  --letter-spacing-tighter: normal;
  --letter-spacing-tight: normal;
  --letter-spacing-normal: normal;
  --letter-spacing-wide: normal;
  --letter-spacing-wider: normal;

  /* Colors - Slate with indigo accent */
  --color-primary: #0f172a;
  --color-secondary: #64748b;
  --color-accent: #0f172a;
  --color-accent-hover: #334155;
  --color-background: #ffffff;
  --color-foreground: #0f172a;
  --color-error: #dc2626;
  --color-success: #059669;
  --color-warning: #d97706;

  /* Status Colors */
  --color-status-draft: #64748b;
  --color-status-draft-bg: #f1f5f9;
  --color-status-draft-text: #475569;
  --color-status-generated: #334155;
  --color-status-generated-bg: #f1f5f9;
  --color-status-generated-text: #0f172a;
  --color-status-sent: #7c3aed;
  --color-status-sent-bg: #f5f3ff;
  --color-status-sent-text: #6d28d9;
  --color-status-accepted: #059669;
  --color-status-accepted-bg: #ecfdf5;
  --color-status-accepted-text: #047857;
  --color-status-declined: #dc2626;
  --color-status-declined-bg: #fef2f2;
  --color-status-declined-text: #b91c1c;
  --color-status-fulfilled: #d97706;
  --color-status-fulfilled-bg: #fffbeb;
  --color-status-fulfilled-text: #b45309;
  --color-status-closed: #64748b;
  --color-status-closed-bg: #f1f5f9;
  --color-status-closed-text: #475569;
  --color-status-inactive: #94a3b8;
  --color-status-inactive-bg: #f8fafc;
  --color-status-inactive-text: #64748b;

  --color-on-accent: #ffffff;
  --color-body-bg: #f8fafc;
  --color-cards-bg: #ffffff;
  --color-border: #e2e8f0;
  --color-border-hover: #cbd5e1;
  --color-muted: #64748b;
  --color-overlay: rgba(15, 23, 42, 0.6);
  --color-text: #475569;
  --color-text-muted: #64748b;
  --color-heading: #0f172a;
  --color-link: #0f172a;
  --color-link-hover: #475569;
  --color-card-bg: #ffffff;
  --color-accent-light: rgba(79, 70, 229, 0.06);
  --color-icon: #64748b;

  /* Code Block - Midnight theme (Night Owl inspired) */
  --code-bg: #011627;
  --code-border: #e2e8f0;
  --code-header-bg: #001122;
  --code-text: #d6deeb;
  --code-text-muted: #637777;
  --code-keyword: #c792ea;
  --code-string: #addb67;
  --code-number: #f78c6c;
  --code-comment: #637777;
  --code-function: #82aaff;
  --code-operator: #7fdbca;
  --code-punctuation: #d6deeb;
  --code-success: #addb67;
  --code-scrollbar: rgba(255, 255, 255, 0.12);

  /* Spacing */

  /* Border Radius */
  --radius-none: 0;
  --radius-sm: 0.25rem;
  --radius-md: 0.375rem;
  --radius-lg: 0.5rem;
  --radius-xl: 0.75rem;
  --radius-2xl: 1rem;
  --radius-full: 9999px;

  /* Shadows */
  --shadow-none: none;
  --shadow-sm: 0 1px 2px 0 rgba(15, 23, 42, 0.04);
  --shadow-md: 0 1px 3px 0 rgba(15, 23, 42, 0.06), 0 1px 2px -1px rgba(15, 23, 42, 0.06);
  --shadow-lg: 0 4px 6px -1px rgba(15, 23, 42, 0.07), 0 2px 4px -2px rgba(15, 23, 42, 0.05);
  --shadow-xl: 0 10px 15px -3px rgba(15, 23, 42, 0.08), 0 4px 6px -4px rgba(15, 23, 42, 0.04);
  --shadow-2xl: 0 20px 40px -8px rgba(15, 23, 42, 0.12);
  --shadow-inner: inset 0 2px 4px 0 rgba(15, 23, 42, 0.04);

  /* Buttons */
  --btn-padding-x: 1rem;
  --btn-padding-y: 0.5rem;
  --btn-padding-x-sm: 0.75rem;
  --btn-padding-y-sm: 0.375rem;
  --btn-padding-x-lg: 1.5rem;
  --btn-padding-y-lg: 0.625rem;
  --btn-font-size: 0.875rem;
  --btn-font-weight: 500;
  --btn-border-radius: 0.375rem;
  --btn-border-width: 1px;
  --btn-primary-border-width: 0;
  --btn-primary-bg: linear-gradient(to bottom, #334155 0%, #1e293b 50%, #0f172a 100%);
  --btn-primary-bg-size: 100% 200%;
  --btn-primary-bg-position: 0 100%;
  --btn-primary-bg-position-hover: 0 0;
  --btn-primary-color: #ffffff;
  --btn-primary-border: transparent;
  --btn-primary-bg-hover: #1e293b;
  --btn-primary-color-hover: #ffffff;
  --btn-primary-border-hover: transparent;
  --btn-secondary-bg: #ffffff;
  --btn-secondary-color: #0f172a;
  --btn-secondary-border: #e2e8f0;
  --btn-secondary-bg-hover: #f8fafc;
  --btn-secondary-color-hover: #0f172a;
  --btn-secondary-border-hover: #cbd5e1;
  --btn-ghost-bg: transparent;
  --btn-ghost-color: #64748b;
  --btn-ghost-border: transparent;
  --btn-ghost-bg-hover: #f1f5f9;
  --btn-shadow: 0 1px 2px 0 rgba(15, 23, 42, 0.04);
  --btn-shadow-hover: 0 4px 8px 0 rgba(79, 70, 229, 0.15);

  /* CTA Banner Backgrounds */
  --cta-dark-bg: linear-gradient(135deg, #0f172a 0%, #1e293b 50%, #334155 100%);
  --cta-light-bg: linear-gradient(180deg, #f8fafc 0%, #f1f5f9 100%);

  /* Forms/Inputs */
  --input-padding-x: 0.75rem;
  --input-padding-y: 0.5rem;
  --input-font-size: 0.875rem;
  --input-border-radius: 0.375rem;
  --input-border-width: 1px;
  --input-border-color: #e2e8f0;
  --input-border-color-focus: #0f172a;
  --input-bg: #ffffff;
  --input-bg-focus: #ffffff;
  --input-color: #0f172a;
  --input-placeholder: #94a3b8;
  --input-border: #e2e8f0;
  --input-border-focus: #0f172a;

  /* Cards */
  --card-padding: 1.5rem;
  --card-border-radius: 0.5rem;
  --card-border-width: 1px;
  --card-border-color: #e2e8f0;
  --card-bg: #ffffff;
  --card-shadow: none;
  --card-image-height: 12rem;
  --card-image-height-mobile: 10rem;

  /* Layout */
  --header-height: 56px;

  /* Transitions */
  --transition-fast: 100ms ease;
  --transition-base: 150ms ease;
  --transition-slow: 200ms ease;
  --transition-slower: 300ms ease;

  /* Z-Index */
  --z-dropdown: 1000;
  --z-sticky: 1020;
  --z-fixed: 1030;
  --z-modal-backdrop: 1040;
  --z-modal: 1050;
  --z-popover: 1060;
  --z-tooltip: 1070;

  /* Gradients */
  --gradient-1: linear-gradient(135deg, #334155 0%, #0f172a 100%);
  --gradient-2: linear-gradient(to bottom, #ffffff, #f8fafc);
  --gradient-3: linear-gradient(to bottom, transparent, #ffffff);

  /* Color scheme helpers */
  --color-on-dark: #ffffff;
  --color-muted-on-dark: rgba(255, 255, 255, 0.7);
  --color-border-on-dark: rgba(255, 255, 255, 0.12);
  --color-on-light: #0f172a;
  --color-muted-on-light: color-mix(in srgb, var(--color-foreground) 74%, var(--color-body-bg));
  --color-border-on-light: rgba(15, 23, 42, 0.08);

  /* Icon styling */
  --icon-fill: 0;
  --icon-weight: 300;
  --icon-grade: 0;
  --icon-opsz: 24;

  /* Hero/Banner heights */
  --hero-height-short: 400px;
  --hero-height-regular: 600px;
  --hero-height-tall: 800px;
  --hero-height-short-mobile: 300px;
  --hero-height-regular-mobile: 400px;
  --hero-height-tall-mobile: 500px;

  /* Content max widths */
  --content-max-width-narrow: 580px;
  --content-max-width-medium: 640px;
  --content-max-width-wide: 800px;
  --modal-max-width-sm: 600px;
  --modal-max-width-md: 800px;
  --modal-max-width-lg: 1440px;

  /* Component sizes */
  --logo-max-height: 40px;
  --avatar-size-sm: 24px;
  --avatar-size-md: 200px;
  --avatar-size-lg: 240px;
  --textarea-min-height: 100px;
  --loader-size: 80px;
}

/* ============================================================
   WARM PRESET - Aesop/Monocle Inspired
   Playfair Display + Source Sans, warm neutrals, terracotta
   ============================================================ */
[data-preset="warm"] {
  /* Typography - Playfair Display + Source Sans */
  --font-family-heading: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-family-body: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-family-mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-weight-light: 300;
  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
  --line-height-none: 1;
  --line-height-tight: 1.15;
  --line-height-snug: 1.35;
  --line-height-normal: 1.625;
  --line-height-relaxed: 1.55;
  --line-height-loose: 1.9;
  --letter-spacing-tighter: normal;
  --letter-spacing-tight: normal;
  --letter-spacing-normal: normal;
  --letter-spacing-wide: normal;
  --letter-spacing-wider: normal;

  /* Colors - Warm cream with terracotta accent */
  --color-primary: #c2410c;
  --color-secondary: #78716c;
  --color-accent: #ea580c;
  --color-accent-hover: #c2410c;
  --color-background: #fafaf9;
  --color-foreground: #1c1917;
  --color-error: #b91c1c;
  --color-success: #15803d;
  --color-warning: #a16207;

  /* Status Colors */
  --color-status-draft: #78716c;
  --color-status-draft-bg: #f5f5f4;
  --color-status-draft-text: #57534e;
  --color-status-generated: #57534e;
  --color-status-generated-bg: #f5f5f4;
  --color-status-generated-text: #44403c;
  --color-status-sent: #57534e;
  --color-status-sent-bg: #f5f5f4;
  --color-status-sent-text: #44403c;
  --color-status-accepted: #15803d;
  --color-status-accepted-bg: #f0fdf4;
  --color-status-accepted-text: #166534;
  --color-status-declined: #b91c1c;
  --color-status-declined-bg: #fef2f2;
  --color-status-declined-text: #991b1b;
  --color-status-fulfilled: #a16207;
  --color-status-fulfilled-bg: #fefce8;
  --color-status-fulfilled-text: #854d0e;
  --color-status-closed: #78716c;
  --color-status-closed-bg: #f5f5f4;
  --color-status-closed-text: #57534e;
  --color-status-inactive: #a8a29e;
  --color-status-inactive-bg: #fafaf9;
  --color-status-inactive-text: #78716c;

  --color-on-accent: #fafaf9;
  --color-body-bg: #fafaf9;
  --color-cards-bg: #ffffff;
  --color-border: #e7e5e4;
  --color-border-hover: #d6d3d1;
  --color-muted: #78716c;
  --color-overlay: rgba(28, 25, 23, 0.7);
  --color-text: #57534e;
  --color-text-muted: #78716c;
  --color-heading: #1c1917;
  --color-link: #c2410c;
  --color-link-hover: #9a3412;
  --color-card-bg: #ffffff;
  --color-accent-light: rgba(234, 88, 12, 0.08);
  --color-icon: #78716c;

  /* Code Block - Warm neutral theme */
  --code-bg: #f5f5f4;
  --code-border: #e7e5e4;
  --code-header-bg: #fafaf9;
  --code-text: #1c1917;
  --code-text-muted: #57534e;
  --code-keyword: #9f1239;
  --code-string: #166534;
  --code-number: #a16207;
  --code-comment: #a8a29e;
  --code-function: #6b21a8;
  --code-operator: #1c1917;
  --code-punctuation: #57534e;
  --code-success: #166534;
  --code-scrollbar: rgba(28, 25, 23, 0.08);

  /* Spacing */

  /* Border Radius */
  --radius-none: 0;
  --radius-sm: 0.125rem;
  --radius-md: 0.25rem;
  --radius-lg: 0.25rem;
  --radius-xl: 0.375rem;
  --radius-2xl: 0.5rem;
  --radius-full: 9999px;

  /* Shadows */
  --shadow-none: none;
  --shadow-sm: 0 1px 2px 0 rgba(28, 25, 23, 0.03);
  --shadow-md: 0 2px 4px 0 rgba(28, 25, 23, 0.04);
  --shadow-lg: 0 4px 8px 0 rgba(28, 25, 23, 0.05);
  --shadow-xl: 0 8px 16px 0 rgba(28, 25, 23, 0.06);
  --shadow-2xl: 0 16px 32px 0 rgba(28, 25, 23, 0.08);
  --shadow-inner: inset 0 1px 2px 0 rgba(28, 25, 23, 0.03);

  /* Buttons */
  --btn-padding-x: 1.25rem;
  --btn-padding-y: 0.625rem;
  --btn-padding-x-sm: 1rem;
  --btn-padding-y-sm: 0.5rem;
  --btn-padding-x-lg: 1.75rem;
  --btn-padding-y-lg: 0.75rem;
  --btn-font-size: 0.8125rem;
  --btn-font-weight: 500;
  --btn-border-radius: 0.125rem;
  --btn-border-width: 1px;
  --btn-primary-border-width: 1px;
  --btn-primary-bg: #ea580c;
  --btn-primary-bg-size: 100% 100%;
  --btn-primary-bg-position: 0 0;
  --btn-primary-bg-position-hover: 0 0;
  --btn-primary-color: #ffffff;
  --btn-primary-border: #ea580c;
  --btn-primary-bg-hover: #c2410c;
  --btn-primary-color-hover: #ffffff;
  --btn-primary-border-hover: #c2410c;
  --btn-secondary-bg: transparent;
  --btn-secondary-color: #c2410c;
  --btn-secondary-border: #c2410c;
  --btn-secondary-bg-hover: rgba(234, 88, 12, 0.08);
  --btn-secondary-color-hover: #9a3412;
  --btn-secondary-border-hover: #c2410c;
  --btn-ghost-bg: transparent;
  --btn-ghost-color: #78716c;
  --btn-ghost-border: transparent;
  --btn-ghost-bg-hover: #f5f5f4;
  --btn-shadow: none;
  --btn-shadow-hover: none;

  /* CTA Banner Backgrounds */
  --cta-dark-bg: #7c2d12;
  --cta-light-bg: #fff7ed;

  /* Forms/Inputs */
  --input-padding-x: 0.75rem;
  --input-padding-y: 0.625rem;
  --input-font-size: 1rem;
  --input-border-radius: 0.125rem;
  --input-border-width: 1px;
  --input-border-color: #e7e5e4;
  --input-border-color-focus: #ea580c;
  --input-bg: #ffffff;
  --input-bg-focus: #ffffff;
  --input-color: #1c1917;
  --input-placeholder: #a8a29e;
  --input-border: #e7e5e4;
  --input-border-focus: #ea580c;

  /* Cards */
  --card-padding: 1.5rem;
  --card-border-radius: 0.25rem;
  --card-border-width: 1px;
  --card-border-color: #e7e5e4;
  --card-bg: #ffffff;
  --card-shadow: none;
  --card-image-height: 14rem;
  --card-image-height-mobile: 11rem;

  /* Layout */

     56px, not 64. The navigation bar does not change height with the colour
     preset - it is the same module with the same padding in all six - and
     this was the only preset that said otherwise. It fed the page clearance
     calculation, so a site on the warm preset reserved 8px more room for the
     bar than the bar occupies. Measured on the live navigation: 56px at
     desktop in every preset. The two places the bar genuinely does change
     height are widths, not presets, and they are handled in
     theme-overrides.css. */
  --header-height: 56px;

  /* Transitions */
  --transition-fast: 100ms ease;
  --transition-base: 150ms ease;
  --transition-slow: 200ms ease;
  --transition-slower: 300ms ease;

  /* Z-Index */
  --z-dropdown: 1000;
  --z-sticky: 1020;
  --z-fixed: 1030;
  --z-modal-backdrop: 1040;
  --z-modal: 1050;
  --z-popover: 1060;
  --z-tooltip: 1070;

  /* Gradients */
  --gradient-1: linear-gradient(135deg, #ea580c, #c2410c);
  --gradient-2: linear-gradient(to bottom, #fff7ed, #fafaf9);
  --gradient-3: linear-gradient(to bottom, transparent, #fafaf9);

  /* Color scheme helpers */
  --color-on-dark: #fafaf9;
  --color-muted-on-dark: rgba(250, 250, 249, 0.7);
  --color-border-on-dark: rgba(250, 250, 249, 0.12);
  --color-on-light: #1c1917;
  --color-muted-on-light: color-mix(in srgb, var(--color-foreground) 74%, var(--color-body-bg));
  --color-border-on-light: rgba(28, 25, 23, 0.08);

  /* Icon styling */
  --icon-fill: 0;
  --icon-weight: 300;
  --icon-grade: 0;
  --icon-opsz: 24;

  /* Hero/Banner heights */
  --hero-height-short: 400px;
  --hero-height-regular: 600px;
  --hero-height-tall: 800px;
  --hero-height-short-mobile: 300px;
  --hero-height-regular-mobile: 400px;
  --hero-height-tall-mobile: 500px;

  /* Content max widths */
  --content-max-width-narrow: 580px;
  --content-max-width-medium: 640px;
  --content-max-width-wide: 800px;
  --modal-max-width-sm: 600px;
  --modal-max-width-md: 800px;
  --modal-max-width-lg: 1440px;

  /* Component sizes */
  --logo-max-height: 40px;
  --avatar-size-sm: 24px;
  --avatar-size-md: 200px;
  --avatar-size-lg: 240px;
  --textarea-min-height: 100px;
  --loader-size: 80px;
}

/* ============================================================
   FOREST PRESET - Notion/Figma Inspired
   DM Sans, clean white, emerald accent
   ============================================================ */
[data-preset="forest"] {
  /* Typography - DM Sans */
  --font-family-heading: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-family-body: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-family-mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-weight-light: 300;
  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
  --line-height-none: 1;
  --line-height-tight: 1.2;
  --line-height-snug: 1.375;
  --line-height-normal: 1.625;
  --line-height-relaxed: 1.55;
  --line-height-loose: 1.75;
  --letter-spacing-tighter: normal;
  --letter-spacing-tight: normal;
  --letter-spacing-normal: normal;
  --letter-spacing-wide: normal;
  --letter-spacing-wider: normal;

  /* Colors - Neutral with emerald accent */
  --color-primary: #18181b;
  --color-secondary: #71717a;
  --color-accent: #059669;
  --color-accent-hover: #047857;
  --color-background: #ffffff;
  --color-foreground: #18181b;
  --color-error: #dc2626;
  --color-success: #059669;
  --color-warning: #d97706;

  /* Status Colors */
  --color-status-draft: #71717a;
  --color-status-draft-bg: #f4f4f5;
  --color-status-draft-text: #52525b;
  --color-status-generated: #059669;
  --color-status-generated-bg: #ecfdf5;
  --color-status-generated-text: #047857;
  --color-status-sent: #475569;
  --color-status-sent-bg: #f1f5f9;
  --color-status-sent-text: #334155;
  --color-status-accepted: #059669;
  --color-status-accepted-bg: #ecfdf5;
  --color-status-accepted-text: #047857;
  --color-status-declined: #dc2626;
  --color-status-declined-bg: #fef2f2;
  --color-status-declined-text: #b91c1c;
  --color-status-fulfilled: #d97706;
  --color-status-fulfilled-bg: #fffbeb;
  --color-status-fulfilled-text: #b45309;
  --color-status-closed: #71717a;
  --color-status-closed-bg: #f4f4f5;
  --color-status-closed-text: #52525b;
  --color-status-inactive: #a1a1aa;
  --color-status-inactive-bg: #fafafa;
  --color-status-inactive-text: #71717a;

  --color-on-accent: #ffffff;
  --color-body-bg: #fafafa;
  --color-cards-bg: #ffffff;
  --color-border: #e4e4e7;
  --color-border-hover: #d4d4d8;
  --color-muted: #71717a;
  --color-overlay: rgba(24, 24, 27, 0.6);
  --color-text: #52525b;
  --color-text-muted: #71717a;
  --color-heading: #18181b;
  --color-link: #059669;
  --color-link-hover: #047857;
  --color-card-bg: #ffffff;
  --color-accent-light: rgba(5, 150, 105, 0.06);
  --color-icon: #71717a;

  /* Code Block - Clean neutral theme */
  --code-bg: #f4f4f5;
  --code-border: #e4e4e7;
  --code-header-bg: #fafafa;
  --code-text: #18181b;
  --code-text-muted: #52525b;
  --code-keyword: #059669;
  --code-string: #0369a1;
  --code-number: #c2410c;
  --code-comment: #a1a1aa;
  --code-function: #7c3aed;
  --code-operator: #18181b;
  --code-punctuation: #52525b;
  --code-success: #059669;
  --code-scrollbar: rgba(0, 0, 0, 0.08);

  /* Spacing */

  /* Border Radius */
  --radius-none: 0;
  --radius-sm: 0.25rem;
  --radius-md: 0.375rem;
  --radius-lg: 0.5rem;
  --radius-xl: 0.625rem;
  --radius-2xl: 0.75rem;
  --radius-full: 9999px;

  /* Shadows */
  --shadow-none: none;
  --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.04);
  --shadow-md: 0 1px 3px 0 rgba(0, 0, 0, 0.06), 0 1px 2px -1px rgba(0, 0, 0, 0.06);
  --shadow-lg: 0 4px 6px -1px rgba(0, 0, 0, 0.07), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
  --shadow-xl: 0 10px 15px -3px rgba(0, 0, 0, 0.08), 0 4px 6px -4px rgba(0, 0, 0, 0.04);
  --shadow-2xl: 0 20px 40px -8px rgba(0, 0, 0, 0.1);
  --shadow-inner: inset 0 2px 4px 0 rgba(0, 0, 0, 0.04);

  /* Buttons */
  --btn-padding-x: 1rem;
  --btn-padding-y: 0.5rem;
  --btn-padding-x-sm: 0.75rem;
  --btn-padding-y-sm: 0.375rem;
  --btn-padding-x-lg: 1.5rem;
  --btn-padding-y-lg: 0.625rem;
  --btn-font-size: 0.875rem;
  --btn-font-weight: 500;
  --btn-border-radius: 0.375rem;
  --btn-border-width: 1px;
  --btn-primary-border-width: 0;
  --btn-primary-bg: linear-gradient(to bottom, #10b981 0%, #059669 50%, #047857 100%);
  --btn-primary-bg-size: 100% 200%;
  --btn-primary-bg-position: 0 100%;
  --btn-primary-bg-position-hover: 0 0;
  --btn-primary-color: #ffffff;
  --btn-primary-border: transparent;
  --btn-primary-bg-hover: #047857;
  --btn-primary-color-hover: #ffffff;
  --btn-primary-border-hover: transparent;
  --btn-secondary-bg: #ffffff;
  --btn-secondary-color: #18181b;
  --btn-secondary-border: #e4e4e7;
  --btn-secondary-bg-hover: #f4f4f5;
  --btn-secondary-color-hover: #18181b;
  --btn-secondary-border-hover: #d4d4d8;
  --btn-ghost-bg: transparent;
  --btn-ghost-color: #71717a;
  --btn-ghost-border: transparent;
  --btn-ghost-bg-hover: #f4f4f5;
  --btn-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.04);
  --btn-shadow-hover: 0 4px 8px 0 rgba(5, 150, 105, 0.15);

  /* CTA Banner Backgrounds */
  --cta-dark-bg: linear-gradient(135deg, #065f46 0%, #047857 50%, #059669 100%);
  --cta-light-bg: linear-gradient(180deg, #fafafa 0%, #f4f4f5 100%);

  /* Forms/Inputs */
  --input-padding-x: 0.75rem;
  --input-padding-y: 0.5rem;
  --input-font-size: 0.875rem;
  --input-border-radius: 0.375rem;
  --input-border-width: 1px;
  --input-border-color: #e4e4e7;
  --input-border-color-focus: #059669;
  --input-bg: #ffffff;
  --input-bg-focus: #ffffff;
  --input-color: #18181b;
  --input-placeholder: #a1a1aa;
  --input-border: #e4e4e7;
  --input-border-focus: #059669;

  /* Cards */
  --card-padding: 1.5rem;
  --card-border-radius: 0.5rem;
  --card-border-width: 1px;
  --card-border-color: #e4e4e7;
  --card-bg: #ffffff;
  --card-shadow: none;
  --card-image-height: 12rem;
  --card-image-height-mobile: 10rem;

  /* Layout */
  --header-height: 56px;

  /* Transitions */
  --transition-fast: 100ms ease;
  --transition-base: 150ms ease;
  --transition-slow: 200ms ease;
  --transition-slower: 300ms ease;

  /* Z-Index */
  --z-dropdown: 1000;
  --z-sticky: 1020;
  --z-fixed: 1030;
  --z-modal-backdrop: 1040;
  --z-modal: 1050;
  --z-popover: 1060;
  --z-tooltip: 1070;

  /* Gradients */
  --gradient-1: linear-gradient(135deg, #059669 0%, #047857 100%);
  --gradient-2: linear-gradient(to bottom, #ffffff, #fafafa);
  --gradient-3: linear-gradient(to bottom, transparent, #ffffff);

  /* Color scheme helpers */
  --color-on-dark: #ffffff;
  --color-muted-on-dark: rgba(255, 255, 255, 0.7);
  --color-border-on-dark: rgba(255, 255, 255, 0.12);
  --color-on-light: #18181b;
  --color-muted-on-light: color-mix(in srgb, var(--color-foreground) 74%, var(--color-body-bg));
  --color-border-on-light: rgba(24, 24, 27, 0.08);

  /* Icon styling */
  --icon-fill: 0;
  --icon-weight: 300;
  --icon-grade: 0;
  --icon-opsz: 24;

  /* Hero/Banner heights */
  --hero-height-short: 400px;
  --hero-height-regular: 600px;
  --hero-height-tall: 800px;
  --hero-height-short-mobile: 300px;
  --hero-height-regular-mobile: 400px;
  --hero-height-tall-mobile: 500px;

  /* Content max widths */
  --content-max-width-narrow: 580px;
  --content-max-width-medium: 640px;
  --content-max-width-wide: 800px;
  --modal-max-width-sm: 600px;
  --modal-max-width-md: 800px;
  --modal-max-width-lg: 1440px;

  /* Component sizes */
  --logo-max-height: 40px;
  --avatar-size-sm: 24px;
  --avatar-size-md: 200px;
  --avatar-size-lg: 240px;
  --textarea-min-height: 100px;
  --loader-size: 80px;
}

/* ============================================================
   CUSTOM PRESET - Theme Settings Controlled
   Based on Light preset with user-configurable overrides
   Note: Actual values from theme settings are injected via
   theme_styles.html HubL rendering. These are fallback defaults.
   ============================================================ */
[data-preset="custom"] {
  /* Typography - Geist (default) with theme settings overrides */
  --font-family-heading: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-family-body: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-family-mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-weight-light: 300;
  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
  --line-height-none: 1;
  --line-height-tight: 1.2;
  --line-height-snug: 1.375;
  --line-height-normal: 1.625;
  --line-height-relaxed: 1.55;
  --line-height-loose: 1.75;
  --letter-spacing-tighter: normal;
  --letter-spacing-tight: normal;
  --letter-spacing-normal: normal;
  --letter-spacing-wide: normal;
  --letter-spacing-wider: normal;

  /* Colors - Zinc palette (shadcn defaults) */
  --color-primary: #09090b;
  --color-secondary: #71717a;
  --color-accent: #18181b;
  --color-accent-hover: #09090b;
  --color-background: #ffffff;
  --color-foreground: #09090b;
  --color-error: #ef4444;
  --color-success: #22c55e;
  --color-warning: #eab308;

  /* Status Colors - Muted, professional */
  --color-status-draft: #71717a;
  --color-status-draft-bg: #f4f4f5;
  --color-status-draft-text: #3f3f46;
  --color-status-generated: #3b82f6;
  --color-status-generated-bg: #eff6ff;
  --color-status-generated-text: #1d4ed8;
  --color-status-sent: #8b5cf6;
  --color-status-sent-bg: #f5f3ff;
  --color-status-sent-text: #6d28d9;
  --color-status-accepted: #22c55e;
  --color-status-accepted-bg: #f0fdf4;
  --color-status-accepted-text: #15803d;
  --color-status-declined: #ef4444;
  --color-status-declined-bg: #fef2f2;
  --color-status-declined-text: #b91c1c;
  --color-status-fulfilled: #f59e0b;
  --color-status-fulfilled-bg: #fffbeb;
  --color-status-fulfilled-text: #b45309;
  --color-status-closed: #71717a;
  --color-status-closed-bg: #f4f4f5;
  --color-status-closed-text: #3f3f46;
  --color-status-inactive: #a1a1aa;
  --color-status-inactive-bg: #fafafa;
  --color-status-inactive-text: #71717a;

  --color-on-accent: #fafafa;
  --color-body-bg: #fafafa;
  --color-cards-bg: #ffffff;
  --color-border: #e4e4e7;
  --color-border-hover: #a1a1aa;
  --color-muted: #71717a;
  --color-overlay: rgba(0, 0, 0, 0.5);
  --color-text: #3f3f46;
  --color-text-muted: #71717a;
  --color-heading: #09090b;
  --color-link: #18181b;
  --color-link-hover: #09090b;
  --color-card-bg: #ffffff;
  --color-accent-light: rgba(24, 24, 27, 0.04);
  --color-icon: #71717a;

  /* Code Block - Light theme (GitHub-inspired) */
  --code-bg: #f6f8fa;
  --code-border: #d0d7de;
  --code-header-bg: #f0f3f6;
  --code-text: #24292f;
  --code-text-muted: #656d76;
  --code-keyword: #cf222e;
  --code-string: #0a3069;
  --code-number: #0550ae;
  --code-comment: #6e7781;
  --code-function: #8250df;
  --code-operator: #24292f;
  --code-punctuation: #24292f;
  --code-success: #1a7f37;
  --code-scrollbar: rgba(0, 0, 0, 0.15);

  /* Spacing - Tight with theme settings overrides */

  /* Semantic spacing aliases */

  /* Border Radius - Sharp, minimal with theme settings overrides */
  --radius-none: 0;
  --radius-sm: 4px;
  --radius-md: 6px;
  --radius-lg: 8px;
  --radius-xl: 10px;
  --radius-2xl: 0.75rem;
  --radius-full: 9999px;

  /* Shadows - None or minimal */
  --shadow-none: none;
  --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
  --shadow-md: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1);
  --shadow-lg: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
  --shadow-xl: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
  --shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
  --shadow-inner: inset 0 2px 4px 0 rgba(0, 0, 0, 0.05);

  /* Buttons - Configurable via theme settings */
  --btn-padding-x: 20px;
  --btn-padding-y: 10px;
  --btn-padding-x-sm: 0.75rem;
  --btn-padding-y-sm: 0.375rem;
  --btn-padding-x-lg: 1.5rem;
  --btn-padding-y-lg: 0.625rem;
  --btn-font-size: 14px;
  --btn-font-weight: 500;
  --btn-border-radius: 6px;
  --btn-border-width: 1px;
  --btn-primary-border-width: 0px;

  /* Primary button - shadcn style */
  --btn-primary-bg: #18181b;
  --btn-primary-color: #fafafa;
  --btn-primary-border: transparent;
  --btn-primary-bg-hover: #3f3f46;
  --btn-primary-color-hover: #fafafa;
  --btn-primary-border-hover: transparent;

  /* Button shadows - minimal */
  --btn-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
  --btn-shadow-hover: 0 1px 3px 0 rgba(0, 0, 0, 0.1);

  /* CTA Banner Backgrounds */
  --cta-dark-bg: linear-gradient(135deg, #3f3f46 0%, #18181b 100%);
  --cta-light-bg: linear-gradient(0deg, rgba(0, 0, 0, 0.05) 0%, rgba(0, 0, 0, 0.02) 100%), var(--color-cards-bg);

  /* Secondary button - shadcn style */
  --btn-secondary-bg: #ffffff;
  --btn-secondary-color: #18181b;
  --btn-secondary-border: #e4e4e7;
  --btn-secondary-bg-hover: #f4f4f5;
  --btn-secondary-color-hover: #09090b;
  --btn-secondary-border-hover: #d4d4d8;

  /* Ghost button */
  --btn-ghost-bg: transparent;
  --btn-ghost-color: #71717a;
  --btn-ghost-border: transparent;
  --btn-ghost-bg-hover: #f4f4f5;
  --btn-ghost-color-hover: #18181b;

  /* Forms/Inputs - Clean, bordered */
  --input-padding-x: 0.75rem;
  --input-padding-y: 0.5rem;
  --input-font-size: 0.875rem;
  --input-border-radius: 6px;
  --input-border-width: 1px;
  --input-border-color: #e4e4e7;
  --input-border-color-focus: #a1a1aa;
  --input-bg: #ffffff;
  --input-bg-focus: #ffffff;
  --input-color: #09090b;
  --input-placeholder: #a1a1aa;
  --input-border: #e4e4e7;
  --input-border-focus: #18181b;

  /* Cards - Bordered, no shadow */
  --card-padding: 1.5rem;
  --card-border-radius: 8px;
  --card-border-width: 1px;
  --card-border-color: #e4e4e7;
  --card-bg: #ffffff;
  --card-shadow: none;
  --card-image-height: 12rem;
  --card-image-height-mobile: 10rem;

  /* Layout - Tight with theme settings overrides */
  --header-height: 56px;

  /* Transitions - Quick */
  --transition-fast: 100ms ease;
  --transition-base: 150ms ease;
  --transition-slow: 200ms ease;
  --transition-slower: 300ms ease;

  /* Z-Index */
  --z-dropdown: 1000;
  --z-sticky: 1020;
  --z-fixed: 1030;
  --z-modal-backdrop: 1040;
  --z-modal: 1050;
  --z-popover: 1060;
  --z-tooltip: 1070;

  /* Gradients */
  --gradient-1: linear-gradient(to bottom right, #18181b, #27272a);
  --gradient-2: linear-gradient(to bottom, #ffffff, #fafafa);
  --gradient-3: linear-gradient(to bottom, transparent, #ffffff);

  /* Color scheme helpers */
  --color-on-dark: #fafafa;
  --color-muted-on-dark: rgba(250, 250, 250, 0.7);
  --color-border-on-dark: rgba(250, 250, 250, 0.15);
  --color-on-light: #09090b;
  --color-muted-on-light: color-mix(in srgb, var(--color-foreground) 74%, var(--color-body-bg));
  --color-border-on-light: rgba(9, 9, 11, 0.08);

  /* Icon styling - Defaults */
  --icon-fill: 0;
  --icon-weight: 400;
  --icon-grade: 0;
  --icon-opsz: 24;

  /* Hero/Banner heights */
  --hero-height-short: 400px;
  --hero-height-regular: 600px;
  --hero-height-tall: 800px;
  --hero-height-short-mobile: 300px;
  --hero-height-regular-mobile: 400px;
  --hero-height-tall-mobile: 500px;

  /* Content max widths */
  --content-max-width-narrow: 580px;
  --content-max-width-medium: 640px;
  --content-max-width-wide: 800px;
  --modal-max-width-sm: 600px;
  --modal-max-width-md: 800px;
  --modal-max-width-lg: 1440px;

  /* Component sizes */
  --logo-max-height: 40px;
  --avatar-size-sm: 24px;
  --avatar-size-md: 200px;
  --avatar-size-lg: 240px;
  --textarea-min-height: 100px;
  --loader-size: 80px;
}

/* ============================================================
   SPACING SCALE - declared ONCE, for every preset
   Base unit 4px; every step a multiple of 4, so nothing lands on a half
   pixel at any device scale. It runs 2-4-8-12-16-24-32-48-64: doubling at
   the bottom where differences are hard to see, then 1.33-1.5x through the
   middle where most decisions live.
   24 is the anchor: body type is 15px at 1.6, so a line box is exactly 24px.
   A card gap of one line is what makes a grid read as a grid.

   This used to be declared six times, once per preset, and warm carried a
   different ramp - so --space-lg meant 16px on five presets and 24px on the
   sixth, and a shared module's "Medium" meant two different things. A
   typeface and an accent colour are preset character; a 4px grid is not.
   ============================================================ */
:root {
  --space-2xs: 2px;
  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 12px;
  --space-lg: 16px;
  --space-xl: 24px;
  --space-2xl: 32px;
  --space-3xl: 48px;
  --space-4xl: 64px;
  --space-5xl: 96px;

  /* Section seams. A seam is the total gap between two sections; each side
     contributes half, so a section reads correctly at either end of a page.
     bond   - two sections that are one editorial unit
     step   - the default; different kinds on the same ground
     chapter- a ground change, or the run-up to the closing ask */
  --seam-bond: 64px;
  --seam-step: 112px;
  --seam-chapter: 176px;
}

/* ============================================================
   SECTION GROUNDS
   Measured before this block shipped: all 38 pages, every section
   computed to rgba(0,0,0,0). In the flat monochrome system there is no
   colour and no shadow left to separate two sections, so the ground IS
   the section boundary - and with no ground, a text-and-image section and
   the icon cards under it read as one run of content.

   Two grounds only. --ground-base is the page itself. --ground-raised is
   the page tinted by its own foreground, which is how the /faqs hero band
   was already built, so a band is the same gesture on every preset instead
   of six hand-picked greys. Both inputs are preset tokens, so the pair
   resolves per preset with nothing scoped to [data-preset="light"]:
     light    #ffffff -> #f9f9f9      dark    #000000 -> #080808
     midnight #f8fafc -> #f1f3f6      warm    #fafaf9 -> #f3f2f1
     forest   #fafafa -> #f3f3f3      custom  #fafafa -> #f3f3f3
   Every preset separates by ~7 levels, dark included, which is the same
   step --color-cards-bg already uses against --color-body-bg.

   The selector must mirror the preset blocks. A :root-only block would
   mix the LIGHT foreground on html and let every other preset inherit it,
   because the preset blocks declare their colours on the body element.
   ============================================================ */
:root,
[data-preset] {
  --ground-base: var(--color-body-bg);
  --ground-raised: color-mix(in srgb, var(--color-foreground) 3%, var(--color-body-bg));
}

/* ============================================================
   SHELL WIDTH - one declaration, not six

   --container-max-width used to be declared inside every preset block, and
   they had drifted: five said 1180px and warm said 1160px, so the page
   silently got 20px narrower when a buyer switched preset. A container width
   is layout, not preset character - nothing about a serif or a dark palette
   wants a different measure - so it is declared once here, after the preset
   blocks, on the same selector shape they use so it lands on body and wins.

   NOTE FOR WHOEVER OWNS fields.json AND templates/partials/theme-styles.html:
   this token is NOT the value that reaches the page today. That partial emits
   `--container-max-width` at `body[data-preset]` whenever the field differs
   from the default transcribed in its own DEFAULTS table, and the two do not
   agree - fields.json ships 1180 and the partial's table says 1100 - so 1180
   is emitted on EVERY page load and beats whatever this file says. Both have
   to move to 1200 for this token to be the source of truth.
   ============================================================ */
:root,
[data-preset] {
  --container-max-width: 1200px;

  /* Same argument, same three tokens that had drifted with it. The gutter was
     1rem on five presets and 1.5rem on warm; the two hero measures were
     identical in all six blocks and only waiting to drift. */
  --container-padding: 1rem;
  --hero-desc-max-width: 640px;
  --hero-form-max-width: 480px;
}

/* ============================================================
   SURFACE, MOTION AND SCRIM TOKENS

   Everything a rule used to hardcode. A marketplace theme has no business
   shipping a raw `1px`, a raw `translateY(1px)` or a raw `rgba(0,0,0,.6)` -
   each one is a decision a buyer can never reach and a value that drifts the
   moment two files disagree about it.

   --hairline is the theme's one DIVIDER width - an hr, a menu separator,
   the rule under a price, the line between two comparison rows. Nine card
   modules read `var(--hairline, 1px)`, and that fallback was the last
   physical constant left in the card set; declaring it here retires it.

   IT MUST NEVER BE ALIASED TO --card-border-width. They look like the same
   number and are two different concepts. --card-border-width is the card's
   OWN outline and is a buyer setting that can legitimately go to zero - the
   elevated pricing style sets it to 0 deliberately, to drop the outline and
   let the shadow do the work. If the divider read that token, zeroing the
   outline would also delete the rule under the price. A divider inside a
   card has to keep drawing after the card's border is gone.

   The lift and press distances are the whole of the theme's micro-motion
   vocabulary: a card or a button rises by one on hover and sinks by one on
   press. One pair of numbers, so nothing invents its own.

   The scrims are the only place a fixed black is allowed, because a scrim is
   not a colour - it is an opacity over an image, and it has to stay dark on
   every preset or hero text stops being readable on a light photo.
   ============================================================ */
:root {
  --hairline: 1px;
  --lift-distance: 4px;
  --btn-lift-distance: 1px;
  --press-distance: 1px;
  --focus-outline-offset: 2px;
  --underline-offset: 3px;
  --btn-line-height: 1.5;

  --scrim-10: rgba(0, 0, 0, 0.1);
  --scrim-20: rgba(0, 0, 0, 0.2);
  --scrim-30: rgba(0, 0, 0, 0.3);
  --scrim-40: rgba(0, 0, 0, 0.4);
  --scrim-60: rgba(0, 0, 0, 0.6);
  --scrim-80: rgba(0, 0, 0, 0.8);
  --scrim-light-10: rgba(255, 255, 255, 0.1);
  --scrim-light-25: rgba(255, 255, 255, 0.25);

  /* Legacy .banner block padding. The .hero shell reads --hero-padding-block
     in theme-overrides.css; these three are what the older .banner markup
     still consumes, and they were inline fallbacks inside the var() calls
     until now, which put three lengths outside the token system. */
  --hero-padding-mobile: 60px;
  --hero-padding-tablet: 80px;
  --hero-padding-desktop: 100px;
}

/* ============================================================
   BLUE IS A BADGE COLOUR, AND ONLY A BADGE COLOUR

   Blue was rejected outright as a general accent. It is not banned from the
   theme - a "Hiring" chip in a menu, a "New" chip on a listing and a status
   pill all need to be picked out of a monochrome page, and grey cannot do
   that - but it is confined to that one job and given one name so it cannot
   leak back into --color-accent, --color-link or a button.

   THE RULE, for anyone adding CSS to this theme: if a value is blue and the
   selector is not a badge, chip, pill or status dot, it is wrong. Use
   --color-accent, which is the preset's own neutral.

   --badge-accent-bg is the single blue. --badge-info-bg is kept as an alias
   so the existing badge markup does not have to change, and every preset's
   --color-status-* pills point here too, which is what stops five presets
   each carrying their own blue.
   ============================================================ */
:root {
  --badge-accent-bg: #2563eb;
  --badge-accent-fg: #ffffff;
}

/* ============================================================
   COMPONENT METRICS - coss.com/ui, measured off the live components

   The colours above are half of a component; these are the other half, and
   they are declared once, outside the preset blocks, for the same reason the
   type scale is: a badge is 12px because that is what a badge is, not because
   of which palette a buyer picked. Every value here was measured on the
   rendered coss components at a desktop width, not read out of prose.

   WHY THESE EXIST AS TOKENS AT ALL. Measured on the live theme before this
   pass, the same component came out differently on every page: the footer
   badge was 13px/600 with 4px of padding on all four sides and stood 28.8px
   tall, and the pricing badge was 9px/600 with 1px 5px of padding and stood
   16.4px. Neither is a size in any scale. That is "look at the badges at the
   spacing" - not one bad number, two components answering the same question
   from nothing.

   BADGES. coss default: 18px tall, 12px/16px label at weight 500, 3px of
   horizontal padding and none vertical, 6px corner, 4px icon gap, and a
   min-width equal to the height so a single digit stays square rather than
   collapsing to a sliver. No letter-spacing - the theme was tracking badges
   at 0.26px, which is what makes small caps look stretched.

   TABS. coss's default tab set is a segmented control, and the whole of it is
   the TRACK: a --muted rail with 2px of padding, and the active tab is a
   white chip inside it. What shipped here had no track at all, so the active
   tab was a black lozenge sitting on the page with grey words beside it -
   which is "these don't look like tabs" exactly. The active chip is white on
   the rail, not black on the page.

   CARD TYPE. Title 18px at weight 600 on leading-none; description 14px/20px
   in muted; 6px between them. The measured theme had 20px/23 titles over a
   15px body at 24px leading and a 12px header gap - a size that is not on the
   ladder, leading of 1.7 on 14px description text, and twice the gap. That is
   "weird fonts, improper spacing, improper padding" in three numbers.
   ============================================================ */
:root,
[data-preset] {
  --badge-height: 20px;
  --badge-padding-x: 6px;
  --badge-font-size: 12px;
  --badge-line-height: 16px;
  --badge-font-weight: 500;
  --badge-letter-spacing: normal;
  --badge-radius: var(--radius-sm);
  --badge-gap: 4px;

  /* THE BORDER COLOUR IS A TOKEN BECAUSE AN OUTLINE CHIP IS A REAL VARIANT.
     The shared badge rule draws a 1px border on every chip so that filled and
     outlined chips sit at the same optical height. That border's colour was
     the literal `transparent`, which made coss's `outline` badge impossible
     to express: a module could move every other badge value through a custom
     property and still not produce an outlined chip. The changelog module's
     `fixed` and `deprecated` badges hit exactly that and had to be reworked
     onto surfaces instead. A module now sets --badge-border-color. */
  --badge-border-color: transparent;

  --badge-height-sm: 16px;
  --badge-padding-x-sm: 6px;
  --badge-font-size-sm: 10px;
  --badge-radius-sm: 4px;

  --badge-height-lg: 22px;
  --badge-padding-x-lg: 10px;
  --badge-font-size-lg: 14px;

  /* Translucent, like every other hairline and tint in this file, so the
     track is correct on the page ground and on the raised band without a
     second value. A BACKGROUND may use alpha; only text may not. */
  --tab-track-bg: rgba(0, 0, 0, 0.04);
  --tab-track-radius: var(--radius-lg);
  --tab-track-padding: 2px;
  --tab-gap: 2px;
  --tab-height: 30px;
  --tab-padding-x: 9px;
  --tab-radius: var(--radius-md);
  --tab-font-size: 0.875rem;
  --tab-line-height: 20px;
  --tab-font-weight: 500;
  /* AN INACTIVE TAB LABEL IS A SOLID COLOUR. It was
     `color-mix(in srgb, var(--color-text-muted) 72%, transparent)`, which is
     an alpha wearing a different hat: the declaration says 72% of a colour
     that passes, and what lands on the page is #909090 over the #f5f5f5
     track - 2.95:1, against the 4.5 a 14px label needs. This is the same
     defect as the `rgba(38, 38, 38, 0.6)` hero lede, and it is the reason a
     translucent value can never be checked by reading it: the real ratio
     depends on what it happens to land on, and a tab sits on the track, the
     page ground and the raised band on different pages.

     DESIGN-DIRECTION 7.6 specifies `rgba(82, 82, 82, 0.72)` here. Measured,
     that composites to #808080 and scores 3.65:1 - it fails too, so it is not
     transcribed. The muted token is solid and already the theme's answer for
     secondary text: 5.16:1 on the track, 5.57 on the page ground, 5.25 on the
     raised band. One value that passes on all three.

     Hover goes to the heading colour rather than part-way, so the three
     states are a real progression: muted, ink, then ink on a white chip. */
  --tab-color: var(--color-text-muted);
  --tab-color-hover: var(--color-heading);
  --tab-border-color: transparent;
  --tab-active-bg: var(--color-cards-bg);
  --tab-active-color: var(--color-heading);

  /* One of the three sanctioned shadows, not a fourth invented here.
     DESIGN-DIRECTION 5 names --shadow-control for a control-sized lift and
     7.6 gives it to the active tab chip by name. */
  --tab-active-shadow: var(--shadow-control);

  /* --card-title-size AND --card-title-weight ARE NOT DECLARED HERE.

     They were, at 1.125rem and 600, and both were dead the moment they were
     written: theme-overrides.css already declares them, it loads last, and
     its size is wired to a buyer field (design_tokens.rhythm.card_title_size,
     fields.json default 20). Measured on the deploy, every card title
     rendered 20px - this file said 18 and no one could see why.

     That is the exact defect this pass exists to remove - two declarations of
     one token name - and I introduced it by adding a component block without
     checking what the file that loads after this one already owned. The
     field-backed declaration is the correct owner, so the duplicates are
     deleted rather than reconciled. --card-title-line-height has no such
     collision and stays. */
  --card-title-line-height: 1.15;
  --card-desc-size: 0.875rem;
  --card-desc-line-height: 20px;
  --card-header-gap: 6px;

  /* THE THREE NAMED SHADOWS.

     "Flat" in this system means there is no elevation LADDER - nothing rises
     on hover, nothing carries a coloured glow - not that nothing has a
     shadow. The reference draws exactly three, each attached to one job, and
     they are named for the job rather than for a size so a rule cannot pick
     the wrong step of a ramp that no longer exists.

     --shadow-control is the hairline lift under a control or a card: one
     pixel at 5% black. --shadow-raise is the inset white highlight along the
     top edge of a filled button, which is what makes a solid dark button read
     as a physical key rather than a rectangle. --shadow-popup is the only one
     with any spread, and only a menu or popover uses it. */
  --shadow-control: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
  --shadow-raise: inset 0 1px 0 0 rgba(255, 255, 255, 0.16);
  --shadow-popup: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -2px rgba(0, 0, 0, 0.05);

  /* CONTROL GEOMETRY - one box, three sizes, and the same box for every
     control type.

     Measured before this pass, a text control was 40px tall on /contact,
     42px on /portfolio and 60px on /faqs, because each place that renders one
     set its own padding and let the height fall out of the line box. Height
     is now declared, padding-block is zero, and the line-height equals the UI
     step, so a select, an input and a textarea's first line all sit on the
     same baseline whatever font size a buyer picks. */
  --control-height: 32px;
  --control-height-sm: 28px;
  --control-height-lg: 36px;
  --control-padding-x: 11px;
  --control-padding-x-sm: 9px;

  /* The textarea floor moves with the control box: two lines of UI text plus
     the control's own padding. Six preset blocks each said 100px, which is
     the same kind of drift as the six type ladders. */
  --textarea-min-height: 64px;
}

/* ============================================================
   ICON SIZE RAMP
   Deliberately outside the type scale. An icon has a box, not a rank,
   so it never takes a --font-size-* token and its size must not follow a
   buyer's heading settings. No theme fields in this pass.
   ============================================================ */
:root {
  --icon-size-xs: 12px;
  --icon-size-sm: 16px;
  --icon-size-md: 20px;
  --icon-size-lg: 24px;
  --icon-size-xl: 32px;
  --icon-size-2xl: 48px;
}

/* ============================================================
   THE TYPE SCALE - one system, declared exactly once

   WHAT WAS WRONG. Heading sizes were declared in six places (one per preset
   block above) with six different sets of numbers, again in a mobile media
   query, and again as raw values inside module style blocks. Measured on a
   rendered page, h2 came back as 30px on some sections and 32px on others
   and h1 as 48.96px, because those are three different systems answering the
   same question. A marketplace theme has to be able to say "this is the h2
   size" and mean it.

   WHAT THIS IS. One fluid ladder, shared by every preset, with a real step
   between every level. Each step is a clamp of a floor (the phone size), a
   viewport term, and a ceiling (the size it stops growing at), so there is
   no breakpoint at which a heading jumps and no media query to keep in sync.
   At a 1440px window the ladder reads:

     display 68  h1 44  h2 32  h3 24  h4 20  h5 18  h6 14   body 16

   and on a 375px phone it reads 44 / 34 / 26 / 21 / 18 / 17 / 14 over the
   same 16px body. Every level stays at least a fifth larger than the one
   below it at both ends, which is the hierarchy the fixed ramps lost below
   h2. The hero opener is --font-size-display, and it is the SAME token the
   hero module reads (theme-overrides.css maps --hero-size-xl onto it), so a
   full-height banner can no longer render its headline at a body-scale 24px.

   SELECTOR. `:root, [data-preset]` mirrors the preset blocks deliberately.
   The presets declare their variables on body, and a custom property
   declared on body beats one inherited from html for every descendant
   whatever the specificity - so a `:root`-only block here would lose to all
   five non-light presets. `[data-preset]` lands on the same element and is
   later in source order, so it wins by the ordinary cascade with no
   importance flag. Buyer settings still win on top: theme-styles.html emits
   them at `body[data-preset]` (0,1,1).
   ============================================================ */
/* WHY THE CLAMPS ARE GONE.

   The ladder above was a clamp per level: a floor, a vw term and a ceiling.
   It was written to remove breakpoint jumps and it did, at a price that was
   only visible once the pages were measured.

   THE VW TERM PRODUCES FRACTIONAL TYPE. Measured on the live site, h1 came
   back at 67.968px and h2 at 43.92 / 31.968 / 24.048 / 20.016 on five
   different pages. Not one of those is a size; they are the same expression
   evaluated at five widths, and a theme that cannot say "the h2 is 24px" has
   no type scale, it has a curve. Every module that hardcodes a px size is
   then fighting a number that does not exist anywhere in the codebase, which
   is the "two type systems" finding: the modules are not wrong to want a
   whole pixel.

   THE CLAMP ALSO NEVER REACHED ITS FLOOR. `clamp(2.75rem, 4.72vw, 4.5rem)`
   hits 44px below 932px and stays there - so the headline measured 44px at
   768 AND at 375. The phone had no step at all. The one thing a fluid scale
   is for, it was not doing.

   WHAT REPLACES IT. Ten whole-pixel steps and three fixed breakpoints, with
   every line-height a whole pixel on the 4px grid. Three declarations of the
   same ladder is more lines than six clamps and is the correct trade: a
   reader of this file can now see what an h2 is at each width, and so can a
   module author.

   LINE-HEIGHTS ARE PX, NOT RATIOS. A ratio times a fractional size is a
   fractional leading - 78.163px was measured under the old ladder - and it
   also means the leading changes whenever a buyer nudges a size, which is how
   text ends up off the baseline grid. Whole px, declared next to the size
   they belong to.

   LETTER-SPACING IS NORMAL, EVERYWHERE. See the note on the tracking tokens
   at the top of this file. */
:root,
[data-preset] {
  --font-size-display: 48px;
  --font-size-h1:      36px;
  --font-size-h2:      24px;
  --font-size-h3:      18px;
  --font-size-h4:      16px;
  --font-size-h5:      14px;
  --font-size-h6:      12px;
  --font-size-body:    16px;
  --font-size-lead:    18px;
  --font-size-lg:      18px;
  --font-size-sm:      14px;
  --font-size-xs:      12px;
  --font-size-code:    13px;

  --line-height-display: 48px;
  --line-height-h1: 40px;
  --line-height-h2: 32px;
  --line-height-h3: 28px;
  --line-height-h4: 24px;
  --line-height-h5: 20px;
  --line-height-h6: 16px;
  --line-height-body: 26px;
  --line-height-lead: 28px;
  --line-height-ui: 20px;
}

/* Tablet. Only prose and headings step; a control is the same size on every
   device, so --font-size-sm, --font-size-xs and --font-size-code are absent
   from both of these blocks on purpose. */
@media (max-width: 1023px) {
  :root,
  [data-preset] {
    --font-size-display: 36px;
    --font-size-h1:      32px;
    --font-size-h2:      22px;
    --font-size-lead:    17px;
    --font-size-lg:      17px;

    --line-height-display: 40px;
    --line-height-h1: 38px;
    --line-height-h2: 30px;
    --line-height-lead: 27px;
  }
}

@media (max-width: 767px) {
  :root,
  [data-preset] {
    --font-size-display: 30px;
    --font-size-h1:      28px;
    --font-size-h2:      20px;
    --font-size-h3:      17px;
    --font-size-body:    15px;
    --font-size-lead:    16px;
    --font-size-lg:      16px;

    --line-height-display: 36px;
    --line-height-h1: 34px;
    --line-height-h2: 28px;
    --line-height-h3: 26px;
    --line-height-body: 24px;
    --line-height-lead: 26px;
  }
}

/* THE WARM PRESET NO LONGER CARRIES ITS OWN LADDER.

   It used to run a display serif one step taller than the sans presets, as a
   second set of clamps. There is no serif in this theme any more and there is
   one scale; a preset is a palette, not a type system. Deleted rather than
   converted, because converting it would have re-created the thing the ladder
   above exists to remove - two answers to "how big is the h1". */

/* Spacing and seams still step down on a phone: a gap is not fluid, it is a
   decision about how much of a small screen a boundary is allowed to eat.
   Only the four largest steps move - below 16px a gap is inside a control or
   inside one statement, and the control does not shrink. */
@media (max-width: 767px) {
  :root,
  [data-preset] {
    --space-xl: 20px;
    --space-2xl: 24px;
    --space-3xl: 32px;
    --space-4xl: 48px;

    /* The seams keep their 1 : 1.75 : 2.75 proportions. At the old 64/56 the
       two rhythms were 8px apart and the page had no rhythm on a phone. */
    --seam-bond: 40px;
    --seam-step: 72px;
    --seam-chapter: 104px;
  }
}

/* ============================================================
   BASE ELEMENT TYPOGRAPHY IS NOT DECLARED HERE.

   body, h1-h6, p, li, a and blockquote were styled in this file AND in
   _typography.css AND in theme-overrides.css. Three copies of one rule, each
   partially overriding the others: this file won font-size, line-height and
   letter-spacing because it loads after main.css, _typography.css won
   font-family, colour, weight and margin because this file did not restate
   them, and a fix to any of the three landed in whichever copy the author
   happened to open. _typography.css is the single home for element defaults
   now. This file declares the TOKENS those rules read, and nothing else.
   ============================================================ */

/* ============================================================
   BUTTONS
   ============================================================ */
.hs-button,
button[type="submit"],
input[type="submit"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--btn-padding-y) var(--btn-padding-x);
  font-size: var(--btn-font-size);
  font-weight: var(--btn-font-weight);
  font-family: var(--font-family-body);
  line-height: var(--btn-line-height);
  text-decoration: none;
  border-radius: var(--btn-border-radius);
  border: var(--btn-primary-border-width) solid var(--btn-primary-border);
  background: var(--btn-primary-bg);
  background-size: var(--btn-primary-bg-size, 100% 100%);
  background-position: var(--btn-primary-bg-position, 0 0);
  color: var(--btn-primary-color);
  box-shadow: var(--btn-shadow);
  cursor: pointer;
  transition: var(--btn-transition, all var(--transition-base));
}

.hs-button:hover,
button[type="submit"]:hover,
input[type="submit"]:hover {
  background-position: var(--btn-primary-bg-position-hover, 0 0);
  background-color: var(--btn-primary-bg-hover, var(--btn-primary-bg));
  border-color: var(--btn-primary-border-hover);
  color: var(--btn-primary-color-hover);
  box-shadow: var(--btn-shadow-hover);
}

.primary-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--btn-padding-y) var(--btn-padding-x);
  font-size: var(--btn-font-size);
  font-weight: var(--btn-font-weight);
  font-family: var(--font-family-body);
  line-height: var(--btn-line-height);
  text-decoration: none;
  border-radius: var(--btn-border-radius);
  border: var(--btn-primary-border-width) solid var(--btn-primary-border);
  background: var(--btn-primary-bg);
  background-size: var(--btn-primary-bg-size, 100% 100%);
  background-position: var(--btn-primary-bg-position, 0 0);
  color: var(--btn-primary-color);
  box-shadow: var(--btn-shadow);
  cursor: pointer;
  transition: var(--btn-transition, all var(--transition-base));
}

.primary-button:hover {
  background-position: var(--btn-primary-bg-position-hover, 0 0);
  background-color: var(--btn-primary-bg-hover, var(--btn-primary-bg));
  border-color: var(--btn-primary-border-hover);
  color: var(--btn-primary-color-hover);
  box-shadow: var(--btn-shadow-hover);
}

.secondary-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--btn-padding-y) var(--btn-padding-x);
  font-size: var(--btn-font-size);
  font-weight: var(--btn-font-weight);
  font-family: var(--font-family-body);
  line-height: var(--btn-line-height);
  text-decoration: none;
  border-radius: var(--btn-border-radius);
  border: var(--btn-border-width) solid var(--btn-secondary-border);
  background: var(--btn-secondary-bg);
  color: var(--btn-secondary-color);
  cursor: pointer;
  transition: all var(--transition-base);
}

.secondary-button:hover {
  background: var(--btn-secondary-bg-hover);
  border-color: var(--btn-secondary-border-hover);
  color: var(--btn-secondary-color-hover);
}

/* Tertiary button on dark sections */
[data-scheme="dark"] .tertiary-button,
[data-scheme="accent"] .tertiary-button,
[data-scheme="gradient"] .tertiary-button,
.dark-section .tertiary-button,
.banner .tertiary-button {
  border-color: var(--color-border-on-dark);
  color: var(--color-on-dark);
}

[data-scheme="dark"] .tertiary-button:hover,
[data-scheme="accent"] .tertiary-button:hover,
[data-scheme="gradient"] .tertiary-button:hover,
.dark-section .tertiary-button:hover,
.banner .tertiary-button:hover {
  background: var(--scrim-light-10);
  border-color: var(--color-on-dark);
  color: var(--color-on-dark);
}

.ghost-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--btn-padding-y) var(--btn-padding-x);
  font-size: var(--btn-font-size);
  font-weight: var(--btn-font-weight);
  font-family: var(--font-family-body);
  line-height: var(--btn-line-height);
  text-decoration: none;
  border-radius: var(--btn-border-radius);
  border: var(--btn-border-width) solid var(--btn-ghost-border);
  background: var(--btn-ghost-bg);
  color: var(--btn-ghost-color);
  cursor: pointer;
  transition: all var(--transition-base);
}

.ghost-button:hover {
  background: var(--btn-ghost-bg-hover);
  color: var(--color-foreground);
}

.button-sm {
  padding: var(--btn-padding-y-sm) var(--btn-padding-x-sm);
  font-size: var(--font-size-sm);
}

.button-lg {
  padding: var(--btn-padding-y-lg) var(--btn-padding-x-lg);
  font-size: var(--font-size-lg);
}

/* ------------------------------------------------------------
   LIGHT PRESET COMPONENT RULES (coss.com/ui)
   Values below are tokens only; every literal lives in the
   preset block at the top of this file.
   ------------------------------------------------------------ */

/* Tabular figures + the alternate single-storey shapes. Geist's
   default zero is fine, but tnum keeps figure columns aligned and
   stops "50 templates" / "20%" reading as letters. */
[data-preset="light"] {
  font-feature-settings: 'tnum' 1, 'cv05' 1;
}

/* Buttons are rectangles with a 10px radius, not pills, so the
   rotating circular chevron badge of the old pill design is retired.
   The icon is now a plain inline glyph that shifts on hover. */
[data-preset="light"] .primary-button,
[data-preset="light"] .secondary-button,
[data-preset="light"] .ghost-button {
  gap: var(--space-sm);
  height: auto;
}

[data-preset="light"] .primary-button .btn-icon,
[data-preset="light"] .secondary-button .btn-icon,
[data-preset="light"] .ghost-button .btn-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--icon-size-sm);
  height: var(--icon-size-sm);
  background: none;
  border-radius: 0;
  color: inherit;
  font-size: var(--icon-size-sm);
  transition: transform var(--transition-slow);
}

[data-preset="light"] .primary-button:hover .btn-icon,
[data-preset="light"] .secondary-button:hover .btn-icon,
[data-preset="light"] .ghost-button:hover .btn-icon {
  transform: translateX(var(--press-distance));
}

/* Section seams.

   This replaces a :nth-of-type(odd/even) pair that was scoped to
   [data-preset="light"], so five of six presets had no rhythm at all. The
   parity also counted DOM position and knew nothing about content: measured
   over 221 adjacent section pairs it produced 56px and 96px at almost exactly
   even odds whether the two sections were the same kind or not, and a single
   zero-height section desynchronised every seam below it.

   The seam is now chosen by what the sections ARE. Each section contributes
   half, so the pair sums correctly and a section works at either end of a
   page. No preset scoping: rhythm is not a colour concern. */
.dnd-section {
  padding-block: calc(var(--seam-step) / 2);
}

.dnd-section[data-seam="bond"]    { padding-block: calc(var(--seam-bond) / 2); }
.dnd-section[data-seam="step"]    { padding-block: calc(var(--seam-step) / 2); }
.dnd-section[data-seam="chapter"] { padding-block: calc(var(--seam-chapter) / 2); }
.dnd-section[data-seam="flush"]   { padding-block: 0; }

/* SECTION GROUNDS AND THE FIRST-SECTION SEAM ARE NOT DECLARED HERE.

   There used to be two ground systems. This file chose a section's ground
   from what it CONTAINED (`.dnd-section:has(.team-members__card)` -> raised);
   theme-overrides.css loads last and re-applied a strict odd/even alternation
   at `html body .dnd-section:nth-of-type(...)`. Those selectors weigh (0,2,2)
   against the (0,1,1) of the :has() rules, so the content-shape system never
   painted anything: it was dead code that still had to be read and maintained,
   and every "gray banner on a gray section" report was the alternation doing
   exactly what it says.

   Only one of the two can satisfy the standing rule that no two adjacent
   sections share a background, because only a positional rule can see a
   section's neighbours. Content shape cannot: two card sections in a row are
   both raised by definition. So the alternation is the system, the
   content-shape block is deleted rather than out-specified, and ALL ground
   painting now lives in one place - theme-overrides.css section 1, together
   with the [data-ground] escape hatch and the footer's place in the run.

   This file keeps the ground TOKENS (--ground-base / --ground-raised, above),
   which is the layer it owns. Tokens here, painting there.

   The old `.dnd-section:first-of-type { padding-top: 0 }` went with it: it
   made the opening section of every page unequal by construction, which is
   the sitewide top-heaviness. Every section now takes the same
   padding-block from the seam rule above, first one included. A section that
   must be flush uses data-seam="flush", which is zero on BOTH sides. */

/* Scroll reveal tokens only. --reveal-duration / --reveal-distance are
   declared in the preset block above so a reveal script has one place to
   read its timing from. No `opacity: 0` rule ships here on purpose: there
   is no IntersectionObserver in this theme yet, and a hide-by-default rule
   with nothing to un-hide it would blank any element that adopted the
   attribute. Wire the observer first, then add the rule. */

/* Link with icon */
.link-icon {
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  color: var(--color-heading);
  text-decoration: none;
  font-weight: var(--font-weight-medium);
  font-size: var(--font-size-body);
  font-family: var(--font-family-heading);
  transition: all var(--transition-base);
}

.link-icon .link-text {
  text-decoration: underline;
  text-underline-offset: var(--underline-offset);
}

.link-icon .btn-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--icon-size-md);
  height: var(--icon-size-md);
  background: var(--scrim-10);
  color: var(--color-heading);
  font-size: var(--font-size-sm);
  border-radius: var(--radius-full);
  transition: all var(--transition-base);
}

.link-icon:hover {
  opacity: 0.7;
}

.link-icon:hover .btn-icon {
  transform: rotate(45deg);
}

.link-icon-light {
  color: var(--color-on-dark);
}

.link-icon-light .btn-icon {
  background: var(--scrim-light-25);
  color: var(--color-on-dark);
}

/* ============================================================
   FORMS
   ============================================================ */
.hs-input,
input[type="text"],
input[type="email"],
input[type="tel"],
input[type="number"],
input[type="password"],
input[type="search"],
input[type="url"],
textarea,
select {
  width: 100%;
  padding: var(--input-padding-y) var(--input-padding-x);
  font-size: var(--input-font-size);
  font-family: var(--font-family-body);
  line-height: var(--line-height-normal);
  color: var(--input-color);
  background-color: var(--input-bg);
  border: var(--input-border-width) solid var(--input-border-color);
  border-radius: var(--input-border-radius);
  transition: border-color var(--transition-fast), background-color var(--transition-fast);
}

.hs-input:focus,
input:focus,
textarea:focus,
select:focus {
  outline: none;
  border-color: var(--input-border-focus);
  background-color: var(--input-bg-focus);
}

.hs-input::placeholder,
input::placeholder,
textarea::placeholder {
  color: var(--input-placeholder);
}

/* ============================================================
   CARDS
   ============================================================ */
.card {
  background: var(--card-bg);
  border-radius: var(--card-border-radius);
  border: var(--card-border-width) solid var(--card-border-color);
  box-shadow: var(--card-shadow);
  transition: box-shadow var(--transition-base), transform var(--transition-base);
}

.card-hover:hover {
  box-shadow: var(--shadow-lg);
  transform: translateY(calc(var(--lift-distance) / 2 * -1));
}

/* ============================================================
   UTILITY CLASSES
   ============================================================ */
.title-label {
  display: inline-block;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-wider);
  color: var(--color-accent);
}

.text-muted {
  color: var(--color-text-muted);
}

.text-accent {
  color: var(--color-accent);
}

.bg-accent-light {
  background-color: var(--color-accent-light);
}

.hover-lift {
  transition: transform var(--transition-base), box-shadow var(--transition-base);
}

.hover-lift:hover {
  transform: translateY(calc(var(--lift-distance) * -1));
  box-shadow: var(--shadow-xl);
}