/* Theme base styles */

/* Tools */

/* Generic */

*, *:before, *:after {
  box-sizing: border-box;
}
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */

/* Document
   ========================================================================== */

/**
 * 1. Correct the line height in all browsers.
 * 2. Prevent adjustments of font size after orientation changes in iOS.
 */

html {
  line-height: 1.15; /* 1 */
  -webkit-text-size-adjust: 100%; /* 2 */
}

/* Sections
   ========================================================================== */

/**
 * Remove the margin in all browsers.
 */

body {
  margin: 0;
}

/**
 * Correct the font size and margin on `h1` elements within `section` and
 * `article` contexts in Chrome, Firefox, and Safari.
 */

h1 {
  font-size: 2em;
  margin: 0.67em 0;
}

/* Grouping content
   ========================================================================== */

/**
 * Add the correct box sizing in Firefox.
 */

hr {
  box-sizing: content-box;
  height: 0;
}

/**
 * 1. Correct the inheritance and scaling of font size in all browsers.
 * 2. Correct the odd `em` font sizing in all browsers.
 */

pre {
  font-family: monospace, monospace; /* 1 */
  font-size: 1em; /* 2 */
}

/* Text-level semantics
   ========================================================================== */

/**
 * 1. Remove the bottom border in Chrome 57-
 * 2. Add the correct text decoration in Chrome, Edge, Opera, and Safari.
 */

abbr[title] {
  border-bottom: none; /* 1 */
  text-decoration: underline; /* 2 */
  text-decoration: underline dotted; /* 2 */
}

/**
 * Add the correct font weight in Chrome, Edge, and Safari.
 */

b,
strong {
  font-weight: bolder;
}

/**
 * 1. Correct the inheritance and scaling of font size in all browsers.
 * 2. Correct the odd `em` font sizing in all browsers.
 */

code,
kbd,
samp {
  font-family: monospace, monospace; /* 1 */
  font-size: 1em; /* 2 */
}

/**
 * Add the correct font size in all browsers.
 */

small {
  font-size: 80%;
}

/**
 * Prevent `sub` and `sup` elements from affecting the line height in
 * all browsers.
 */

sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}

sub {
  bottom: -0.25em;
}

sup {
  top: -0.5em;
}

/* Forms
   ========================================================================== */

/**
 * 1. Change the font styles in all browsers.
 * 2. Remove the margin in Firefox and Safari.
 */

button,
input,
optgroup,
select,
textarea {
  font-family: inherit; /* 1 */
  font-size: 100%; /* 1 */
  line-height: 1.15; /* 1 */
  margin: 0; /* 2 */
}

/**
 * Remove the inheritance of text transform in Edge and Firefox.
 * 1. Remove the inheritance of text transform in Firefox.
 */

button,
select { /* 1 */
  text-transform: none;
}

/**
 * Correct the inability to style clickable types in iOS and Safari.
 */

button,
[type="button"],
[type="reset"],
[type="submit"] {
  -webkit-appearance: button;
}

/**
 * Remove the inner border and padding in Firefox.
 */

button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
  border-style: none;
  padding: 0;
}

/**
 * Restore the focus styles unset by the previous rule.
 */

button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
  outline: 1px dotted ButtonText;
}

/**
 * Correct the padding in Firefox.
 */

fieldset {
  padding: 0.35em 0.75em 0.625em;
}

/**
 * Remove the padding so developers are not caught out when they zero out `fieldset` elements in all browsers.
 */

legend {
  padding: 0;
}

/**
 * Add the correct vertical alignment in Chrome, Firefox, and Opera.
 */

progress {
  vertical-align: baseline;
}

/**
 * Correct the cursor style of increment and decrement buttons in Chrome.
 */

[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
  height: auto;
}

/**
 * 1. Correct the odd appearance in Chrome and Safari.
 * 2. Correct the outline style in Safari.
 */

[type="search"] {
  -webkit-appearance: textfield; /* 1 */
  outline-offset: -2px; /* 2 */
}

/**
 * Remove the inner padding in Chrome and Safari on macOS.
 */

[type="search"]::-webkit-search-decoration {
  -webkit-appearance: none;
}

/**
 * 1. Correct the inability to style clickable types in iOS and Safari.
 * 2. Change font properties to `inherit` in Safari.
 */

::-webkit-file-upload-button {
  -webkit-appearance: button; /* 1 */
  font: inherit; /* 2 */
}

/* Interactive
   ========================================================================== */

/*
 * Add the correct display in Edge and Firefox.
 */

details {
  display: block;
}

/*
 * Add the correct display in all browsers.
 */

summary {
  display: list-item;
}

/* Design Tokens */

:root {
  --font-primary: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --container-max: 1280px;

  /* Section vertical padding — one fluid scale, six steps. Drives the
   * .section / .section--sm base classes AND the editor section-padding
   * preset dropdown (resolved in the render_section macro). Every step is
   * clamp(mobile, rem + vw, desktop) so the between-module rhythm scales
   * continuously — desktop's generous padding eases to a mobile-right
   * proportion instead of sitting desktop-sized on a phone. */
  --section-pad-none: 0px;
  --section-pad-xs: clamp(20px, 0.94rem + 1.33vw, 32px);
  --section-pad-sm: clamp(40px, 1.88rem + 2.65vw, 64px);
  --section-pad-md: clamp(56px, 2.46rem + 4.42vw, 96px);
  --section-pad-lg: clamp(72px, 3.05rem + 6.19vw, 128px);
  --section-pad-xl: clamp(104px, 4.22rem + 9.72vw, 192px);

  /* Legacy aliases — existing references (_section.css, theme-overrides.css)
   * keep working; new code uses --section-pad-* directly. */
  --section-py: var(--section-pad-lg);
  --section-py-sm: var(--section-pad-md);

  /* Section header → content gap (the space below a .section__header).
   * Single source of truth — modules must NOT add their own margin-top
   * between the header and the section content; that double-stacks the
   * gap. 32px floor on mobile, 64px ceiling on desktop. */
  --section-header-gap: clamp(32px, 1.17rem + 3.54vw, 64px);

  /* Card inner padding + grid/card gap — fluid so dense desktop spacing
   * eases on mobile (a 40px-padded card on a 375px screen eats 80px of
   * width; a 32px grid gap is a lot between narrow phone cards). */
  --glass-padding: clamp(24px, 1.09rem + 1.77vw, 40px);
  --bento-gap: clamp(16px, 0.59rem + 1.77vw, 32px);

  /* Fluid text-spacing scale — the DESIGN.md "Stack rhythm" tiers made
   * fluid. Modules use these for text-element margins (eyebrow→heading,
   * heading→body, copy→features, etc.) instead of raw px, so the whole
   * page's vertical rhythm scales on one shared curve.
   *   xs  paired-tight        sm  paired (eyebrow→heading / heading→lead)
   *   md  group (items)       lg  section break (copy→features, →CTA)
   *   xl  biggest break (different content type) */
  --text-gap-xs: clamp(8px,  0.4rem  + 0.44vw, 12px);
  --text-gap-sm: clamp(12px, 0.65rem + 0.44vw, 16px);
  --text-gap-md: clamp(20px, 1.15rem + 0.44vw, 24px);
  --text-gap-lg: clamp(28px, 1.44rem + 1.33vw, 40px);
  --text-gap-xl: clamp(44px, 2.23rem + 2.2vw,  64px);

  --radius-sm: 12px;
  --radius-md: 12px;
  --radius-lg: 12px;
  --radius-xl: 12px;
  --radius-2xl: 12px;
  --radius-card: 12px;
  --radius-full: 9999px;

  --transition-theme: background-color 0.5s ease, color 0.5s ease, border-color 0.5s ease;
  --transition-hover: all 0.3s ease;

  /* Color tokens — text */
  --color-text-primary-dark: #ffffff;
  --color-text-secondary-dark: #a1a1aa;
  --color-text-muted-dark: rgba(255, 255, 255, 0.7);
  --color-text-primary-light: #1d1d1f;
  --color-text-secondary-light: #52525b;
  --color-text-muted-light: #86868b;

  /* Color tokens — accents */
  --color-accent-dark: #3b82f6;
  --color-accent-dark-hover: #60a5fa;
  --color-accent-light: #007aff;
  --color-accent-light-hover: #0066cc;

  /* Color tokens — rating / status */
  --color-rating-star: #f59e0b;

  /* Color tokens — surfaces */
  --color-bg-dark: #1d1d1f;
  --color-bg-dark-well: #1c1c1e;
  --color-bg-light: #f1f3f6;
  --color-bg-alt-light: #fafafa;

  --color-surface-dark: rgba(255, 255, 255, 0.05);
  --color-surface-dark-elevated: rgba(255, 255, 255, 0.1);
  --color-surface-light: #ffffff;

  /* Color tokens — borders */
  --color-border-dark: rgba(255, 255, 255, 0.1);
  --color-border-dark-strong: rgba(255, 255, 255, 0.2);
  --color-border-light: rgba(0, 0, 0, 0.1);
  --color-border-solid: #e4e4e7;

  /* Color tokens — accent washes */
  --color-accent-wash-dark: rgba(59, 130, 246, 0.2);
  --color-accent-wash-dark-border: rgba(59, 130, 246, 0.3);
  --color-accent-wash-light: rgba(0, 122, 255, 0.08);
  --color-accent-wash-light-border: rgba(0, 122, 255, 0.2);

  /* Color tokens — semantic (success / disabled) */
  --color-success-dark: #4ade80;
  --color-success-light: #16a34a;
  --color-muted-icon-dark: var(--color-text-secondary-dark);
  --color-muted-icon-light: #d4d4d8;

  /* Color tokens — dividers (accordion item borders, hr-style splits) */
  --color-divider-dark: rgba(255, 255, 255, 0.08);
  --color-divider-light: rgba(0, 0, 0, 0.08);

  /* Color tokens — table */
  --color-table-row-alt-dark: rgba(255, 255, 255, 0.02);
  --color-table-row-alt-light: rgba(0, 0, 0, 0.02);
  --color-table-row-border-dark: rgba(255, 255, 255, 0.05);
  --color-table-row-border-light: rgba(0, 0, 0, 0.05);
  --color-table-head-border-dark: rgba(255, 255, 255, 0.1);
  --color-table-head-border-light: rgba(0, 0, 0, 0.08);
}

/* Objects */



/* CSS variables */

:root {
  --column-gap: 2.13%;
  --column-width-multiplier: 8.333;
}

/* Mobile layout */

.row-fluid {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
}


  .row-fluid .span1,
  .row-fluid .span2,
  .row-fluid .span3,
  .row-fluid .span4,
  .row-fluid .span5,
  .row-fluid .span6,
  .row-fluid .span7,
  .row-fluid .span8,
  .row-fluid .span9,
  .row-fluid .span10,
  .row-fluid .span11,
  .row-fluid .span12{
  min-height: 1px;
  width: 100%;
}

/* Desktop layout */

@media (min-width: 768px) {
  .row-fluid {
    flex-wrap: nowrap;
    justify-content: space-between;
  }

  
    .row-fluid .span1 {
      width: calc(var(--column-width-multiplier) * 1% * 1 - var(--column-gap) * (11 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span2 {
      width: calc(var(--column-width-multiplier) * 1% * 2 - var(--column-gap) * (10 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span3 {
      width: calc(var(--column-width-multiplier) * 1% * 3 - var(--column-gap) * (9 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span4 {
      width: calc(var(--column-width-multiplier) * 1% * 4 - var(--column-gap) * (8 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span5 {
      width: calc(var(--column-width-multiplier) * 1% * 5 - var(--column-gap) * (7 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span6 {
      width: calc(var(--column-width-multiplier) * 1% * 6 - var(--column-gap) * (6 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span7 {
      width: calc(var(--column-width-multiplier) * 1% * 7 - var(--column-gap) * (5 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span8 {
      width: calc(var(--column-width-multiplier) * 1% * 8 - var(--column-gap) * (4 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span9 {
      width: calc(var(--column-width-multiplier) * 1% * 9 - var(--column-gap) * (3 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span10 {
      width: calc(var(--column-width-multiplier) * 1% * 10 - var(--column-gap) * (2 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span11 {
      width: calc(var(--column-width-multiplier) * 1% * 11 - var(--column-gap) * (1 * var(--column-width-multiplier) / 100));
    }
  
}
/* DnD wrappers are zero-padding passthroughs — modules handle their own container/spacing */

.dnd-section {
  padding-top: 0 !important;
  padding-bottom: 0 !important;
  padding-left: 0 !important;
  padding-right: 0 !important;
  max-width: 100% !important;
}

.dnd-section > .row-fluid {
  margin: 0 !important;
  max-width: 100% !important;
  width: 100% !important;
}

.dnd-section .dnd-column {
  padding: 0 !important;
}

/* Elements */

body {
  font-family: var(--font-primary);
  line-height: 1.4;
  overflow-wrap: break-word;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: var(--color-text-primary-light);
}

.section--dark { color: var(--color-text-primary-dark); }

/* Handles word breaking for a few specific languages which handle breaks in words differently. If your content is not translated into these languages, you can safely remove this.  */

html[lang^="ja"] body,
html[lang^="zh"] body,
html[lang^="ko"] body {
  line-break: strict;
  overflow-wrap: normal;
  word-break: break-all;
}

/* Paragraphs */

p {
  font-size: 1rem;
  margin: 0 0 1.4rem;
}

/* Anchors — design-system colors, theme-aware. */

a {
  cursor: pointer;
  color: var(--color-accent-light);
  text-decoration: none;
}

a:hover, a:focus { color: var(--color-accent-light-hover); }

/* On dark sections, inline text links rest at the lighter blue (#60a5fa)
 * — the mid-blue --color-accent-dark is too dim for body-text link
 * legibility on black. Hover shifts to that mid-blue (the same inverted
 * pairing as accent glyphs).
 *
 * The hover rule is scoped with :not(.btn):not(.cta_button) so it never
 * reaches button anchors — render_button emits <a class="btn"> and CTAs
 * emit <a class="cta_button">; buttons own their colour via the
 * .section--dark .btn--* rules in _buttons.css. An earlier version of
 * this rule added a hover `text-decoration: underline`, which leaked
 * onto every .btn anchor on dark sections (specificity 0,2,1 beat
 * .btn's 0,1,0) — hence no underline here, and the :not() scoping. The
 * rest rule needs no :not(): buttons' .section--dark .btn--* colour
 * rules (0,2,0) already outrank `.section--dark a` (0,1,1). */
.section--dark a { color: var(--color-accent-dark-hover); }
.section--dark a:not(.btn):not(.cta_button):hover,
.section--dark a:not(.btn):not(.cta_button):focus { color: var(--color-accent-dark); }

/* Headings — bare h1-h6 defaults (Inter, weight 600, theme-aware color, sensible sizes).
 * Modules wanting the canonical TMM scale should add the .t-h1 / .t-h2 / .t-h3
 * utility classes (defined later in this file). Bare-element defaults below are
 * MODEST so any module class override (e.g. .dep-steps__title { font-size: 20px })
 * wins via specificity without needing !important. */

h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6 {
  font-family: var(--font-primary);
  font-weight: 600;
  color: var(--color-text-primary-light);
}

h1, .h1 { font-size: 40px; line-height: 1.1; letter-spacing: -0.03em; }
h2, .h2 { font-size: 32px; line-height: 1.15; letter-spacing: -0.02em; }
h3, .h3 { font-size: 24px; line-height: 1.2; letter-spacing: -0.01em; }
h4, .h4 { font-size: 20px; line-height: 1.3; }
h5, .h5 { font-size: 18px; line-height: 1.3; }
h6, .h6 { font-size: 16px; line-height: 1.3; }

.section--dark h1, .section--dark .h1,
.section--dark h2, .section--dark .h2,
.section--dark h3, .section--dark .h3,
.section--dark h4, .section--dark .h4,
.section--dark h5, .section--dark .h5,
.section--dark h6, .section--dark .h6 {
  color: var(--color-text-primary-dark);
}

h1, h2, h3, h4, h5, h6 {
  margin: 0 0 1.4rem;
}

/* Lists */

ul,
ol {
  margin: 0 0 1.4rem;
}

ul ul,
ol ul,
ul ol,
ol ol {
  margin: 0;
}

ul.no-list {
  list-style: none;
  margin: 0;
  padding-left: 0;
}

/* Code blocks */

pre {
  overflow: auto;
}

code {
  vertical-align: bottom;
}

/* Highlight + selection — brand-blue background with white text.
 * <mark> is the semantic highlight element editors get from
 * rich-text editors (e.g. HubSpot's "highlight" toolbar button)
 * and accessible content tools. ::selection is the user-driven
 * selection-on-drag pattern. Both unified to brand chrome so
 * highlighted text and selected text feel like one system. */
mark {
  background-color: var(--color-accent-light);
  color: var(--color-text-primary-dark);
  padding: 0.1em 0.3em;
  border-radius: 4px;
}

::selection {
  background-color: var(--color-accent-light);
  color: var(--color-text-primary-dark);
}

::-moz-selection {
  background-color: var(--color-accent-light);
  color: var(--color-text-primary-dark);
}

/* Blockquotes */

blockquote {
  border-left: 2px solid var(--color-border-solid);
  margin: 0 0 1.4rem;
  padding-left: 0.7rem;
}

/* Horizontal rules */

hr {
  border: none;
  border-bottom: 1px solid #CCC;
}

/* Image alt text */

img {
  font-size: 0.583rem;
  word-break: normal;
}

/* TMM Type Scale
 * Sizing/weight/spacing only. Colors are applied by theme via .section--{theme}.
 * Modules MUST NOT redefine these or override their colors per-theme.
 */

.t-display,
.t-h1,
.t-h2,
.t-h3,
.t-card-title {
  font-family: var(--font-primary);
  font-weight: 600;
  margin: 0;
}

/* Fluid type scale — every heading size is clamp(mobile, rem + vw, desktop).
 * The `rem` base keeps the value scaling on phones (a bare `vw` term is
 * near-zero at phone widths and just pins at the floor); the `vw` does the
 * scaling; min/max are deliberate design targets (~375px mobile / ~1280px
 * desktop). Desktop ceilings are unchanged from the previous scale — this
 * pass fixes the broken mobile floors and the flow between them. */

/* Display — one tier larger than .t-h1, for hero-CTA-style dramatic
 * display headlines. Picked via the editor "Headline Size → Large" toggle
 * on hero / cta-banner modules. */
.t-display {
  font-size: clamp(44px, 1.4rem + 5.75vw, 96px);
  line-height: 1;
  letter-spacing: -0.03em;
}

.t-h1 {
  font-size: clamp(36px, 1.32rem + 4vw, 72px);
  line-height: 1.1;
  letter-spacing: -0.04em;
}

.t-h2 {
  font-size: clamp(30px, 1.1rem + 3.3vw, 60px);
  line-height: 1.15;
  letter-spacing: -0.02em;
}

.t-h3 {
  font-size: clamp(24px, 1.19rem + 1.33vw, 36px);
  line-height: 1.2;
  letter-spacing: -0.01em;
}

/* Card title — the single canonical card-heading role. Consolidates the
 * ~16-24px bespoke card titles that drifted across ~8 modules into one
 * fluid size. A card title is a ROLE, not a pixel count — every card
 * surface uses this so the eye never has to recalibrate scanning a page.
 * (Genuinely larger "card" headings — e.g. blog-featured — are a different
 * role and use .t-h3 instead.) */
.t-card-title {
  font-size: clamp(19px, 1.11rem + 0.33vw, 22px);
  line-height: 1.3;
  letter-spacing: -0.01em;
}

/* Mobile line-height loosening. Unitless line-height scales the NUMBER
 * proportionally with font-size, but typographically small/wrapping type
 * wants LOOSER leading than large display type — the relationship is
 * inverse, not proportional. On phones the headings clamp down and wrap
 * to more lines, so loosen the leading for small viewports. Mirrors the
 * pattern already shipped in _prose.css. */
@media (max-width: 767px) {
  .t-display { line-height: 1.08; }
  .t-h1 { line-height: 1.15; }
  .t-h2 { line-height: 1.22; }
  .t-h3 { line-height: 1.3; }
}

/* Micro-labels (.t-subheader, .t-label-sm, .t-eyebrow) stay fixed-size —
 * 11/12px uppercase overlines don't benefit from scaling, and shrinking
 * them further on mobile just makes them hard to read. Their line-heights
 * are unitless (not the old fixed 16px) purely for consistency with the
 * rest of the scale. */
.t-subheader {
  font-family: var(--font-primary);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin: 0;
}

/* Body roles — fluid where it earns it. .t-body-lg is the site's default
 * reading voice; .t-body-xl is the lead/large body. Both clamp on the
 * rem + vw curve so body copy reads with one consistent voice whatever
 * the viewport. .t-body-md (small/meta) stays fixed — 14px is already
 * mobile-appropriate. Line-heights are unitless so they scale with the
 * now-fluid font-size. */
.t-body-lg {
  font-family: var(--font-primary);
  font-size: clamp(16px, 0.95rem + 0.22vw, 18px);
  font-weight: 500;
  line-height: 1.55;
  margin: 0;
}

.t-body-xl {
  font-family: var(--font-primary);
  font-size: clamp(20px, 1.15rem + 0.44vw, 24px);
  font-weight: 500;
  line-height: 1.5;
  margin: 0;
}

.t-body-md {
  font-family: var(--font-primary);
  font-size: 14px;
  font-weight: 400;
  line-height: 1.45;
  margin: 0;
}

.t-label-sm {
  font-family: var(--font-primary);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin: 0;
}

/* Theme-aware coloring for body/secondary copy.
 * Headings inherit section text color (white/black). Secondary text and
 * subheaders pick up the muted tone for the active theme automatically.
 */

/* Body copy on dark sections. Lifted from --color-text-secondary-dark (#a1a1aa, ~6.5:1)
 * to #e4e4e7 (~13:1, comfortably AAA) so the main reading text is brighter than the
 * subheader/label eyebrows above it. Subheader and label-sm keep the quieter secondary
 * token to preserve hierarchy. */
.section--dark .t-body-lg,
.section--dark .t-body-md,
.section--dark .t-body-xl { color: #e4e4e7; }

.section--dark .t-subheader,
.section--dark .t-label-sm { color: var(--color-text-secondary-dark); }

.section--light .t-body-lg,
.section--light .t-body-md,
.section--light .t-body-xl,
.section--light .t-subheader,
.section--light .t-label-sm { color: var(--color-text-secondary-light); }

/* Accent variant — for subheaders rendered in the section accent color */
.t-subheader--accent { color: var(--color-accent-light); }
.section--dark .t-subheader--accent { color: var(--color-accent-dark); }

/* Muted variant — for extra-quiet captions above logo clouds, metric rows, etc.
 * Lighter than the default secondary color: #a1a1aa on light, white@40% on dark. */
.t-subheader--muted { color: #a1a1aa; }
.section--dark .t-subheader--muted { color: rgba(255, 255, 255, 0.4); }

/* ── Section eyebrow ─────────────────────────────────────────────────
 * Accent-dot + uppercase tracking-widest label. The standard section eyebrow
 * across the site — replaces the old pill-badge pattern in places that wanted
 * a quieter visual.
 *
 * Markup:  <p class="t-eyebrow"><span class="t-eyebrow__dot"></span>SECTION LABEL</p>
 * Macro:   render_eyebrow(label, style)    (see templates/macros/section.html)
 *
 * Variants:
 *   .t-eyebrow         — solid dot, accent-coloured label (default)
 *   .t-eyebrow--live   — adds a 2s pulse on the dot (for "live" / monitoring contexts)
 *   .t-eyebrow--muted  — keeps the accent dot but quiets the label colour
 *
 * Theme: label and dot follow the accent-glyph contrast rule from DESIGN.md
 *   (light section → --color-accent-light; dark section → --color-accent-dark-hover).
 */
.t-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-primary);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-accent-light);
  margin: 0;
}
.section--dark .t-eyebrow { color: var(--color-accent-dark-hover); }

.t-eyebrow__dot {
  flex-shrink: 0;
  width: 8px;
  height: 8px;
  border-radius: var(--radius-full);
  background: currentColor;
}

/* Live variant — dot pulses (factory monitoring vibe) */
.t-eyebrow--live .t-eyebrow__dot {
  animation: t-eyebrow-live-pulse 2s ease-in-out infinite;
}
body.is-editor .t-eyebrow--live .t-eyebrow__dot { animation: none; }

/* Muted variant — accent dot stays, label drops to secondary text colour */
.t-eyebrow--muted { color: var(--color-text-secondary-light); }
.section--dark .t-eyebrow--muted { color: var(--color-text-secondary-dark); }
.t-eyebrow--muted .t-eyebrow__dot { background: var(--color-accent-light); }
.section--dark .t-eyebrow--muted .t-eyebrow__dot { background: var(--color-accent-dark-hover); }

/* ── Legacy live indicator (kept for hero module backwards-compat) ───
 * Prefer .t-eyebrow / .t-eyebrow--live for new code. */
.t-eyebrow-live {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-primary);
  font-size: 12px;
  font-weight: 600;
  line-height: 16px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-accent-dark);
  transition: color 0.5s ease;
}

.t-eyebrow-live__dot {
  width: 8px;
  height: 8px;
  border-radius: var(--radius-full);
  background: var(--color-accent-dark);
  animation: t-eyebrow-live-pulse 2s ease-in-out infinite;
}

@keyframes t-eyebrow-live-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

body.is-editor .t-eyebrow-live__dot { animation: none; }

/* Gradient-text headline modifier — apply to a <span> inside .t-h1 / .t-h2
 * to render the text with a vertical-fade gradient (primary → secondary).
 * Theme-aware via .section--{theme}.
 */
.t-text-gradient {
  background: linear-gradient(to right, var(--color-text-primary-light), var(--color-text-secondary-light));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}
.section--dark .t-text-gradient {
  background: linear-gradient(to right, var(--color-text-primary-dark), var(--color-text-secondary-dark));
  -webkit-background-clip: text;
  background-clip: text;
}

/* Accent-gradient modifier — brand-blue gradient for hero-CTA emphasis phrases.
 * Use as <span class="t-text-gradient t-text-gradient--accent">closing phrase</span>
 * inside a .t-h1 / .t-h2. Sparingly — reserve for hero-CTA sections (demo form,
 * brochure, etc.) where the gradient is part of the call-to-action emphasis.
 *
 * Theme: light gradient runs accent → darker-blue (#2563eb); dark gradient runs
 * lighter-blue (#60a5fa) → accent for legibility against the dark surface. */
.t-text-gradient--accent {
  background: linear-gradient(90deg, var(--color-accent-light), #2563eb);
}
.section--dark .t-text-gradient--accent {
  background: linear-gradient(90deg, var(--color-accent-dark-hover), var(--color-accent-dark));
}
/* HubSpot-system buttons (blog list "Read more", form submits, system pages) —
 * TMM-themed defaults via NAMED CLASSES only. The bare `button` element
 * selector was deliberately removed: it was force-painting every <button>
 * on the site brand-blue (tab triggers, accordion toggles, share buttons,
 * header toggles, etc.), creating a specificity trap that required every
 * non-CTA <button> to ship its own four-state reset. Named classes are an
 * explicit opt-in to the primary-CTA chrome; bare <button> is left alone
 * so per-component module CSS can style it freely. */

.button,
.hs-button,
.hs-blog-post-listing__post-button {
  cursor: pointer;
  display: inline-block;
  text-align: center;
  font-family: var(--font-primary);
  font-weight: 600;
  background-color: var(--color-accent-light);
  border: 1px solid var(--color-accent-light);
  border-radius: var(--radius-xl);
  color: #ffffff;
  font-size: 14px;
  padding: 14px 24px;
  text-transform: none;
  transition: all 0.15s linear;
  white-space: normal;
}

.button:hover, .button:focus,
.hs-button:hover, .hs-button:focus,
.hs-blog-post-listing__post-button:hover,
.hs-blog-post-listing__post-button:focus {
  background-color: var(--color-accent-light-hover);
  border-color: var(--color-accent-light-hover);
  color: #ffffff;
}

.button:active,
.hs-button:active { transform: scale(0.98); }

.section--dark .button,
.section--dark .hs-button {
  background-color: var(--color-accent-dark);
  border-color: var(--color-accent-dark);
}

.section--dark .button:hover,
.section--dark .hs-button:hover {
  background-color: var(--color-accent-dark-hover);
  border-color: var(--color-accent-dark-hover);
}

.button:disabled,
.hs-button:disabled {
  background-color: #D0D0D0;
  border-color: #D0D0D0;
  color: #E6E6E6;
}

/* No button */

.no-button,
.no-button:hover,
.no-button:focus,
.no-button:active {
  background: none;
  border: none;
  border-radius: 0;
  color: initial;
  font-family: inherit;
  font-size: inherit;
  font-style: inherit;
  font-weight: inherit;
  letter-spacing: inherit;
  line-height: inherit;
  margin-bottom: 0;
  padding: 0;
  text-align: left;
  text-decoration: none;
  transition: none;
}

/* TMM Button System */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-primary);
  font-weight: 600;
  border-radius: var(--radius-xl);
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: var(--transition-hover);
  -webkit-font-smoothing: antialiased;
}

.btn:active { transform: scale(0.98); }

/* A11y — users with prefers-reduced-motion get no scale-on-active animation.
 * Applied to every button/CTA path so motion preference is respected uniformly. */
@media (prefers-reduced-motion: reduce) {
  button:active,
  .button:active,
  .hs-button:active,
  .btn:active,
  form input[type=submit]:active,
  form button[type=submit]:active {
    transform: none;
  }
}

/* Pre-label icon (e.g. calendar SVG for "Book a meeting"). Sized to current font size
 * so it optically matches text cap-height; inherits color via currentColor. Non-ghost only. */
.btn__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 1em;
  height: 1em;
}
.btn__icon svg {
  width: 100%;
  height: 100%;
  display: block;
}

/* Chevron icon inside buttons — animates on hover for ghost variant. */
.btn__chevron {
  flex-shrink: 0;
  transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

.btn--ghost.btn--with-arrow:hover .btn__chevron,
.btn--ghost.btn--with-arrow:focus .btn__chevron { transform: translateX(4px); }

.tmm-cta--ghost.tmm-cta--with-arrow:hover .btn__chevron,
.tmm-cta--ghost.tmm-cta--with-arrow:focus .btn__chevron { transform: translateX(4px); }

/* Ghost-with-arrow strips padding — matches React's "text + chevron" pattern */
.btn--ghost.btn--with-arrow {
  padding: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
}
.btn--ghost.btn--with-arrow:hover,
.btn--ghost.btn--with-arrow:focus {
  background: transparent !important;
  box-shadow: none !important;
}


/* Sizes. sm / md stay fixed — 13/14px text with compact padding is
 * already mobile-appropriate, and a button is a constant the eye anchors
 * on while scrolling, so the small/medium sizes shouldn't drift. lg / xl
 * get fluid padding (and xl a gentle font clamp) so they ease toward md
 * proportions on phones instead of sitting desktop-oversized — xl at
 * 18px/24-40 was a slab on a 375px screen. */
.btn--sm { font-size: 13px; padding: 8px 16px; }
.btn--md { font-size: 14px; padding: 14px 24px; }
.btn--lg {
  font-size: 16px;
  padding: clamp(13px, 0.5rem + 0.55vw, 16px) clamp(22px, 0.9rem + 1.1vw, 32px);
}
.btn--xl {
  font-size: clamp(16px, 0.9rem + 0.22vw, 18px);
  padding: clamp(16px, 0.6rem + 1vw, 24px) clamp(28px, 1.1rem + 1.3vw, 40px);
}
.btn--full { width: 100%; }

/* Primary — no drop-shadow / glow. Buttons across the system render flat
 * (depth comes from the surrounding card / section, not from a haloed
 * shadow under the button itself). */
.btn--primary {
  background-color: var(--color-accent-light);
  color: #ffffff;
  border-color: var(--color-accent-light);
}
.btn--primary:hover, .btn--primary:focus {
  background-color: var(--color-accent-light-hover);
  border-color: var(--color-accent-light-hover);
  color: #ffffff;
}

/* Primary on dark sections.
 * `color: #fff` is restated here because `.section--dark a` (in _typography.css)
 * has specificity (0,1,1) and would otherwise repaint the link text in accent-blue,
 * making the label invisible against the blue button background. */
.section--dark .btn--primary {
  background-color: var(--color-accent-dark);
  border-color: var(--color-accent-dark);
  color: #ffffff;
}
.section--dark .btn--primary:hover {
  background-color: var(--color-accent-dark-hover);
  border-color: var(--color-accent-dark-hover);
  color: #ffffff;
}

/* Secondary */
.btn--secondary {
  background-color: transparent;
  color: var(--color-text-primary-light);
  border-color: var(--color-border-solid);
}
.btn--secondary:hover, .btn--secondary:focus {
  background-color: rgba(0, 0, 0, 0.03);
  color: var(--color-text-primary-light);
}
.section--dark .btn--secondary {
  color: var(--color-text-primary-dark);
  border-color: var(--color-border-dark-strong);
}
.section--dark .btn--secondary:hover {
  background-color: rgba(255, 255, 255, 0.08);
  color: var(--color-text-primary-dark);
}

/* Inverse — solid pill that inverts the section theme.
 * Light sections → dark fill, white text.
 * Dark sections → white fill, dark text.
 * Used for primary heroes in dashboard/minimal/gradient-image layouts. */
.btn--inverse {
  background-color: var(--color-text-primary-light);
  color: var(--color-text-primary-dark);
  border-color: transparent;
}
.btn--inverse:hover, .btn--inverse:focus {
  background-color: var(--color-text-primary-light);
  color: var(--color-text-primary-dark);
}
.section--dark .btn--inverse {
  background-color: var(--color-text-primary-dark);
  color: var(--color-text-primary-light);
}
.section--dark .btn--inverse:hover {
  background-color: var(--color-border-solid);
  color: var(--color-text-primary-light);
}

/* CTA group row — wrapper for 1 or 2 buttons (output of render_cta_group). */
.tmm-cta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
  margin-top: 8px;
}

@media (max-width: 640px) {
  .tmm-cta-row { flex-direction: column; align-items: stretch; }
  .tmm-cta-row > * { width: 100%; }
  .tmm-cta-row .btn { justify-content: center; }
  /* HubSpot CTA wrappers are inline-block, not inline-flex like .btn — so
   * justify-content can't centre their inner .cta_button once the row
   * stretches them to full width. text-align centres the inline-level
   * .cta_button instead, so HubSpot-CTA variants stay visually consistent
   * with custom-button variants on mobile. */
  .tmm-cta-row .tmm-cta { text-align: center; }
}

/* HubSpot CTA wrapper — overrides HubSpot's default .cta_button styling so a
 * CTA picked from the CMS renders with TMM button look. The inner element is
 * an a.cta_button emitted by HubSpot's native CTA renderer. */
.tmm-cta {
  display: inline-block;
  line-height: 0;
}

.tmm-cta .cta_button,
.tmm-cta a.cta_button {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 8px !important;
  font-family: var(--font-primary) !important;
  font-weight: 600 !important;
  border-radius: var(--radius-xl) !important;
  border: 1px solid transparent !important;
  text-decoration: none !important;
  white-space: nowrap !important;
  cursor: pointer;
  transition: var(--transition-hover) !important;
  -webkit-font-smoothing: antialiased !important;
  line-height: 1.2 !important;
}

.tmm-cta--sm .cta_button { font-size: 13px !important; padding: 8px 16px !important; }
.tmm-cta--md .cta_button { font-size: 14px !important; padding: 14px 24px !important; }
/* lg / xl mirror the fluid scaling of .btn--lg / .btn--xl above. */
.tmm-cta--lg .cta_button {
  font-size: 16px !important;
  padding: clamp(13px, 0.5rem + 0.55vw, 16px) clamp(22px, 0.9rem + 1.1vw, 32px) !important;
}
.tmm-cta--xl .cta_button {
  font-size: clamp(16px, 0.9rem + 0.22vw, 18px) !important;
  padding: clamp(16px, 0.6rem + 1vw, 24px) clamp(28px, 1.1rem + 1.3vw, 40px) !important;
}

/* Style variants on CTAs */
.tmm-cta--primary .cta_button {
  background-color: var(--color-accent-light) !important;
  color: #ffffff !important;
  border-color: var(--color-accent-light) !important;
}
.tmm-cta--primary .cta_button:hover {
  background-color: var(--color-accent-light-hover) !important;
  border-color: var(--color-accent-light-hover) !important;
}
.section--dark .tmm-cta--primary .cta_button {
  background-color: var(--color-accent-dark) !important;
  border-color: var(--color-accent-dark) !important;
}

.tmm-cta--secondary .cta_button {
  background-color: transparent !important;
  color: var(--color-text-primary-light) !important;
  border-color: var(--color-border-solid) !important;
}
.section--dark .tmm-cta--secondary .cta_button {
  color: var(--color-text-primary-dark) !important;
  border-color: var(--color-border-dark-strong) !important;
}

.tmm-cta--inverse .cta_button {
  background-color: var(--color-text-primary-light) !important;
  color: var(--color-text-primary-dark) !important;
}
.section--dark .tmm-cta--inverse .cta_button {
  background-color: var(--color-text-primary-dark) !important;
  color: var(--color-text-primary-light) !important;
}

.tmm-cta--ghost .cta_button {
  background-color: transparent !important;
  color: var(--color-text-primary-light) !important;
  border-color: transparent !important;
}
.section--dark .tmm-cta--ghost .cta_button {
  color: var(--color-text-primary-dark) !important;
}

/* Ghost */
.btn--ghost {
  background-color: transparent;
  color: var(--color-text-primary-light);
  border-color: transparent;
}
.btn--ghost:hover, .btn--ghost:focus {
  background-color: rgba(0, 0, 0, 0.05);
  color: var(--color-text-primary-light);
}
.section--dark .btn--ghost {
  color: var(--color-text-primary-dark);
}
.section--dark .btn--ghost:hover {
  background-color: rgba(255, 255, 255, 0.08);
  color: var(--color-text-primary-dark);
}

/* Accent — text + chevron in the brand accent colour. Same shape as Ghost
 * (always-chevron, no icon, padding-stripped via .btn--with-arrow), but theme-aware
 * accent colour instead of neutral text. Used for "Learn more" / inline CTAs that
 * should pop in brand blue rather than recede. */
.btn--accent {
  background-color: transparent;
  color: var(--color-accent-light);
  border-color: transparent;
}
.btn--accent:hover, .btn--accent:focus {
  background-color: transparent;
  color: var(--color-accent-light-hover);
}
/* On dark, the lighter blue is the resting state (better contrast against #1d1d1f),
 * and the darker blue becomes the hover. This inverts the light-mode pairing. */
.section--dark .btn--accent {
  color: var(--color-accent-dark-hover);
}
.section--dark .btn--accent:hover, .section--dark .btn--accent:focus {
  color: var(--color-accent-dark);
}
/* Accent reuses the ghost-with-arrow padding strip + chevron animation. */
.btn--accent.btn--with-arrow {
  padding: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
}
.btn--accent.btn--with-arrow:hover,
.btn--accent.btn--with-arrow:focus {
  background: transparent !important;
  box-shadow: none !important;
}
.btn--accent.btn--with-arrow:hover .btn__chevron,
.btn--accent.btn--with-arrow:focus .btn__chevron { transform: translateX(4px); }

/* Link — text + optional chevron + intrinsic 1px border-bottom underline.
 * Same family as ghost (text-link, padding-stripped) but with the underline
 * baked in as part of the style (NOT a modifier on top of ghost/accent —
 * those stay decoration-free). The 4px padding-bottom gives the line
 * breathing room from the text baseline; React-style "Explore integrations →"
 * with deliberate underline. */
.btn--link {
  padding: 0 0 4px 0;
  background-color: transparent;
  border-color: transparent;
  border-bottom: 1px solid currentColor;
  border-radius: 0;
  color: var(--color-text-primary-light);
}
.btn--link:hover, .btn--link:focus {
  background-color: transparent;
  color: var(--color-text-primary-light);
}
.section--dark .btn--link {
  color: var(--color-text-primary-dark);
}
.section--dark .btn--link:hover, .section--dark .btn--link:focus {
  color: var(--color-text-primary-dark);
}
/* Chevron animates on hover, same as ghost/accent text-link family. */
.btn--link.btn--with-arrow:hover .btn__chevron,
.btn--link.btn--with-arrow:focus .btn__chevron { transform: translateX(4px); }

/* HubSpot CTA wrapper version of .btn--link. */
.tmm-cta--link .cta_button {
  padding: 0 0 4px 0 !important;
  background-color: transparent !important;
  border-color: transparent !important;
  border-bottom: 1px solid currentColor !important;
  border-radius: 0 !important;
  color: var(--color-text-primary-light) !important;
  box-shadow: none !important;
}
.section--dark .tmm-cta--link .cta_button {
  color: var(--color-text-primary-dark) !important;
}
.tmm-cta--link.tmm-cta--with-arrow:hover .btn__chevron,
.tmm-cta--link.tmm-cta--with-arrow:focus .btn__chevron { transform: translateX(4px); }

/* Same set, applied to HubSpot CTA wrappers when style=accent. */
.tmm-cta--accent .cta_button {
  background-color: transparent !important;
  color: var(--color-accent-light) !important;
  border-color: transparent !important;
  box-shadow: none !important;
}
.tmm-cta--accent .cta_button:hover {
  color: var(--color-accent-light-hover) !important;
}
.section--dark .tmm-cta--accent .cta_button {
  color: var(--color-accent-dark-hover) !important;
}
.section--dark .tmm-cta--accent .cta_button:hover {
  color: var(--color-accent-dark) !important;
}
.tmm-cta--accent.tmm-cta--with-arrow:hover .btn__chevron,
.tmm-cta--accent.tmm-cta--with-arrow:focus .btn__chevron { transform: translateX(4px); }
/* Badge — accent pill in the same glass material the cards use. Depth comes
 * from refraction (backdrop-blur) + a 1px inner hairline highlight that
 * matches the .card--{theme} spec, NOT from coloured drop shadows. Per
 * DESIGN.md → Elevation & Depth: "true shadows are non-existent or extremely
 * subtle"; coloured glow is not part of the design language.
 *
 * Typography is owned by .t-subheader (12px / 600 / 0.1em uppercase Inter).
 * Markup must include both classes: `class="badge badge--{theme} t-subheader"`.
 * The macro render_badge does this automatically.
 *
 * Use for section eyebrows that need visual weight. For a quieter alternative,
 * use .t-eyebrow (accent dot + label, no chrome). */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 18px;
  border-radius: var(--radius-full);
  border: 1px solid;
  /* Override .t-subheader's 16px line-height — pills want tight chrome with
   * padding-driven vertical breathing room, not extra leading inside. */
  line-height: 1;
  white-space: nowrap;
  -webkit-backdrop-filter: blur(20px);
          backdrop-filter: blur(20px);
  transition: var(--transition-hover);
}

/* Colour rules use combined-class specificity (.badge.badge--{theme}) so they
 * win the cascade against .section--dark .t-subheader (specificity 0,2,0)
 * which would otherwise paint muted secondary text on the pill. */
.badge.badge--dark {
  background-color: var(--color-accent-wash-dark);
  border-color: var(--color-accent-wash-dark-border);
  color: var(--color-accent-dark-hover);
  /* Subtle inner edge highlight — same family of inset hairline the cards use,
   * just dimmer to match the dark-section material. */
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.06);
}

.badge.badge--light {
  background-color: var(--color-accent-wash-light);
  border-color: var(--color-accent-wash-light-border);
  color: var(--color-accent-light);
  /* Same inset hairline as .card--light's `inset 0 0 0 1px rgba(255,255,255,0.4)`
   * — keeps the pill in the same material family as the cards. */
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4);
}

/* Tag — smaller pill, theme-aware muted bg/text. Pair with .t-label-sm on the element. */

.tag {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: var(--radius-full);
}

.section--dark .tag {
  background: rgba(255, 255, 255, 0.08);
  color: var(--color-text-secondary-dark);
}

.section--light .tag {
  background: rgba(0, 0, 0, 0.05);
  color: var(--color-text-secondary-light);
}
/* TMM Form System
 *
 * Spacing model — built around HubSpot's actual form HTML:
 *
 *   <form>
 *     <fieldset class="form-columns-{1,2,3}">    ← a row, with N columns
 *       <div class="hs-form-field">...</div>     ← a field
 *       ...
 *     </fieldset>
 *     <fieldset class="form-columns-1">...</fieldset>
 *     ...
 *     <div class="hs_submit">submit</div>
 *   </form>
 *
 * Each <fieldset> is treated as a CSS-grid row; the .form-columns-N class sets
 * the column template. This produces deterministic spacing regardless of how
 * an editor configures the form layout in HubSpot's form builder, and keeps
 * mobile predictable (everything collapses to 1-col below 600px).
 *
 * Visual primitives:
 *   - --form-row-gap     vertical gap between fieldset rows
 *   - --form-col-gap     horizontal gap between columns inside a multi-col row
 *   - --form-submit-gap  gap between the last fieldset and the submit button
 *
 * Inputs: rounded-xl, theme-aware bg/border/text. Inset shadow suggests recessed well.
 * Focus: border-color change + 3px ring + bg "lift to white".
 * Error: subtle red wash + border + ring.
 * Disabled: opacity 0.6, not-allowed.
 */

:root {
  --form-row-gap:    20px;
  --form-col-gap:    16px;
  --form-submit-gap: 24px;
}

/* Row-level container — applies to whatever wrapper HubSpot uses for a row.
 * Legacy portals emit <fieldset class="form-columns-N">; newer portals
 * sometimes emit <div class="form-columns-N">. Belt-and-braces target both.
 *
 * `!important` is used liberally throughout the form spacing system because
 * HubSpot injects inline styles directly onto form elements (inline `style="..."`
 * has higher specificity than any class rule), and class-based rules without
 * `!important` lose. The form layout is fully HubSpot-managed at the markup
 * level, so external overrides from outside this file are rare. */
form fieldset,
form .form-columns-1,
form .form-columns-2,
form .form-columns-3 {
  border: 0 !important;
  padding: 0 !important;
  margin: 0 0 var(--form-row-gap) 0 !important;
  min-width: 0;
  max-width: 100% !important;
  display: grid !important;
  grid-template-columns: 1fr;
  gap: var(--form-col-gap);
}

/* Last row — submit area takes over. */
form fieldset:last-of-type,
form .form-columns-1:last-of-type,
form .form-columns-2:last-of-type,
form .form-columns-3:last-of-type {
  margin-bottom: 0 !important;
}

/* Column variants. HubSpot's form builder writes these classes directly. */
form .form-columns-2 { grid-template-columns: 1fr 1fr !important; }
form .form-columns-3 { grid-template-columns: 1fr 1fr 1fr !important; }

/* Mobile collapse — every multi-col row becomes 1-col below 600px so 2-up
 * fields don't get crushed at narrow viewports. */
@media (max-width: 599px) {
  form .form-columns-2,
  form .form-columns-3 {
    grid-template-columns: 1fr !important;
  }
}

/* Field reset. The grid handles placement; HubSpot ships inline
 * `style="float:left; width:50%; margin-right:5%"` on .hs-form-field which
 * fights the grid — neutralize all three. */
.hs-form-field {
  margin: 0 !important;
  width: 100% !important;
  float: none !important;
}

/* Submit area gap. */
form .hs_submit,
form .hs-submit {
  margin-top: var(--form-submit-gap);
}
form .hs_submit .actions,
form .hs-submit .actions {
  margin: 0;
  padding: 0;
}

/* Labels — quiet, sentence case, like Apple's web form labels. Uppercase
 * letterspaced caps belong on section eyebrows, not on every form field;
 * applied to every label they read as visual shouting. */
form label,
.hs-form-field > label {
  display: block;
  font-family: var(--font-primary);
  font-size: 14px;
  font-weight: 500;
  line-height: 20px;
  color: var(--color-text-secondary-light);
  margin-bottom: 6px;
}

.section--dark form label,
.section--dark .hs-form-field > label,
.tmm-form-wrap--dark form label,
.tmm-form-wrap--dark .hs-form-field > label {
  color: var(--color-text-secondary-dark);
}

/* Help / legend text — sits between label and input. Label already has a 6px
 * margin-bottom, so the gap above the help text is 6px (margins collapse to
 * the larger of the two). The 8px margin-bottom puts a slightly larger gap
 * below the help text before the input. */
form legend,
.hs-form-field .hs-field-desc {
  font-family: var(--font-primary);
  font-size: 12px;
  font-weight: 400;
  line-height: 16px;
  color: #86868b;
  margin: 0 0 8px;
}

/* Inputs, selects, textareas — light section default.
 * The input is a recessed well in the form card. Subtle off-white bg + a
 * faint inset shadow on the top edge to suggest the surface receding into
 * the card. Focus brings the bg up to white as a "lift to attention" cue.
 * 14px vertical padding (up from 12px) gives the input proper breathing room
 * — short fields look cramped at the lower padding. */
form input[type=text],
form input[type=search],
form input[type=email],
form input[type=password],
form input[type=tel],
form input[type=number],
form input[type=url],
form input[type=date],
form input[type=file],
form select,
form textarea,
.hs-input {
  display: block;
  /* `!important` defeats HubSpot's inline `style="width: 95%"` which leaves a
   * useless 5% right gap inside our grid-managed columns. */
  width: 100% !important;
  font-family: var(--font-primary);
  font-size: 15px;
  font-weight: 400;
  line-height: 20px;
  color: #1d1d1f;
  background-color: #fafafa;
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: var(--radius-xl);
  padding: 14px 16px;
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.02);
  transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
  -webkit-appearance: none;
  appearance: none;
}

form textarea {
  resize: vertical;
  min-height: 120px;
  line-height: 22px;
}

/* Placeholders */
form input::placeholder,
form textarea::placeholder,
.hs-input::placeholder {
  color: #a1a1aa;
  opacity: 1;
}

/* Focus — both border-color change AND ring (per spec rule 10). Bg shifts
 * to pure white and the resting inset shadow is dropped — the field is
 * "lifted out of the well" while focused.
 *
 * :focus-visible (modern, well supported) shows the ring on keyboard focus
 * AND text-input focus (browsers always treat text-input focus as visible).
 * Mouse users clicking a button-like input don't get a stray ring. The :focus
 * fallback below covers ancient browsers without :focus-visible support. */
form input:focus,
form select:focus,
form textarea:focus,
.hs-input:focus {
  outline: none;
}
form input:focus-visible,
form select:focus-visible,
form textarea:focus-visible,
.hs-input:focus-visible {
  outline: none;
  background-color: #ffffff;
  border-color: var(--color-accent-light);
  box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.2);
}

/* Disabled */
form input:disabled,
form select:disabled,
form textarea:disabled,
.hs-input:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  background-color: #fafafa;
}

/* Error states — input goes a quiet red, not a screaming one. The bg tint
 * is barely there, the border is subtle, the text shifts back to the
 * normal foreground (the bg + border + ring carry the error signal). */
form input.invalid,
form input.error,
form select.invalid,
form textarea.invalid,
.hs-input.invalid.error,
.hs-input.error {
  border-color: rgba(255, 59, 48, 0.4);
  background-color: rgba(255, 59, 48, 0.03);
}

form input.invalid:focus-visible,
form input.error:focus-visible,
.hs-input.invalid.error:focus-visible,
.hs-input.error:focus-visible {
  background-color: #ffffff;
  border-color: rgba(255, 59, 48, 0.7);
  box-shadow: 0 0 0 3px rgba(255, 59, 48, 0.15);
}

/* Error message list — HubSpot wraps each error in <ul.hs-error-msgs><li><label.hs-error-msg>.
 * Strip the list chrome and align messages directly under the field. */
.hs-error-msgs.inputs-list {
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
}
.hs-error-msgs.inputs-list > li { margin: 0; }

.hs-error-msg,
.hs-error-msgs label {
  display: flex;
  /* flex-start, not center — when the message wraps to two lines, `center`
   * parks the icon between the lines instead of next to the first one. */
  align-items: flex-start;
  gap: 6px;
  font-family: var(--font-primary);
  font-size: 13px;
  font-weight: 400;
  line-height: 18px;
  color: rgba(255, 59, 48, 0.85);
  margin: 0;
}

/* Alert-circle icon prefix — matches the message colour via mask-image +
 * background-color: currentColor. Improves a11y by giving error messages a
 * visual cue beyond colour alone (helpful for colour-blind users).
 * margin-top: 2px optical-aligns the icon's centre with the first text line's
 * cap-height (text starts ~2.5px below the line-box top at 13/18 sizing). */
.hs-error-msg::before,
.hs-error-msgs label::before {
  content: '';
  flex-shrink: 0;
  width: 14px;
  height: 14px;
  margin-top: 2px;
  background-color: currentColor;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='12' y1='8' x2='12' y2='12'/%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='12' y1='8' x2='12' y2='12'/%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'/%3E%3C/svg%3E");
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-size: contain;
          mask-size: contain;
}

/* Required-field asterisk — quieter than the error red. */
.hs-form-required {
  color: rgba(255, 59, 48, 0.7);
  margin-left: 2px;
  font-weight: 400;
}

/* File picker */
form input[type=file] {
  background-color: transparent;
  border: 1px dashed #d2d2d7;
  padding: 12px 16px;
  cursor: pointer;
}

/* Checkboxes & radios — within a multi-option field, options stack vertically
 * with a consistent 10px gap.
 *
 * The :not(.hs-error-msgs) selector is critical: HubSpot uses .inputs-list on
 * BOTH checkbox/radio groups AND error message lists. Without :not(), these
 * rules hijack error message styling (which we want to stay small + red, not
 * 14px primary-text-colour). Each rule below is explicitly scoped. */
form .inputs-list:not(.hs-error-msgs) {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

form .inputs-list:not(.hs-error-msgs) > li {
  margin: 0;
}

form .inputs-list:not(.hs-error-msgs) label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 400;
  color: var(--color-text-primary-light);
  cursor: pointer;
  margin-bottom: 0;
  /* Override the muted secondary colour the global form-label rule applies. */
  text-transform: none;
  letter-spacing: 0;
}

.section--dark form .inputs-list:not(.hs-error-msgs) label,
.tmm-form-wrap--dark form .inputs-list:not(.hs-error-msgs) label {
  color: var(--color-text-primary-dark);
}

form input[type=checkbox],
form input[type=radio] {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--color-accent-light);
  cursor: pointer;
}

.section--dark form input[type=checkbox],
.section--dark form input[type=radio] {
  accent-color: var(--color-accent-dark);
}

/* Select chevron */
form select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%2386868b' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 16px center;
  padding-right: 40px;
  cursor: pointer;
}

/* Rich text inside form */
form .hs-richtext,
form .hs-richtext p {
  font-family: var(--font-primary);
  font-size: 13px;
  font-weight: 400;
  line-height: 18px;
  color: #52525b;
  margin: 0 0 12px;
}

form .hs-richtext img {
  max-width: 100%;
}

/* GDPR / legal consent — sits between the last fieldset and the submit button
 * (NOT inside a fieldset). Inherits the row gap so it lines up with the
 * fieldset rhythm above. */
form .legal-consent-container {
  margin: 0 0 var(--form-row-gap);
}
form .legal-consent-container .hs-richtext {
  margin: 0 0 12px;
  font-size: 13px;
  line-height: 18px;
  color: var(--color-text-secondary-light);
}
.section--dark form .legal-consent-container .hs-richtext {
  color: var(--color-text-secondary-dark);
}

.legal-consent-container .hs-form-booleancheckbox-display > span,
.legal-consent-container .hs-form-booleancheckbox-display > span p {
  margin-left: 8px;
  font-size: 13px;
}

/* Submit button — conversion CTA. Sized to match .btn--xl (the canonical
 * extra-large variant in _buttons.css): 18px / 600 / 24×40 padding. Always
 * full-width inside the form card. This is the right visual weight for a
 * hero form submit — the climax of the form's vertical rhythm.
 *
 * The bare .hs-button rule in _buttons.css supplies the brand-blue fill,
 * white text, --radius-xl, and active:scale. We override sizing here and
 * add the arrow + box-shadow to match .btn--primary's CTA weight.
 *
 * Two variants:
 *   <input type="submit">  — HubSpot's default render. Arrow via background-
 *                            image at the right edge (only place CSS can put
 *                            an icon on a single-text-content element).
 *   <button type="submit"> — module.js may replace the input with a button
 *                            so text + arrow can sit as flex siblings,
 *                            centered together. The replacement is opt-in
 *                            per module (see gated-form/module.js). */

/* Base — applies to both input and button variants. No glow shadow; the
 * site-wide button policy is flat (matches .btn--primary in _buttons.css).
 * Font-size mirrors .btn--xl's fluid clamp — the submit is the xl-tier
 * button, so it eases toward 16px on phones instead of sitting at 18px. */
form input[type=submit],
form button[type=submit],
form .hs-form-submit input,
form .hs-button {
  width: 100%;
  margin-top: 8px;
  font-size: clamp(16px, 0.9rem + 0.22vw, 18px);
  font-weight: 600;
}

/* Input variant — arrow via background-image at the right edge (fallback
 * when JS hasn't enhanced the submit, or for forms outside enhancement
 * scope). Right padding keeps the centred label clear of the arrow.
 * Vertical padding clamps with the xl-tier curve; the asymmetric
 * horizontal padding stays fixed (it's tied to the arrow's position). */
form input[type=submit],
form .hs-form-submit input {
  padding: clamp(16px, 0.6rem + 1vw, 20px) 56px clamp(16px, 0.6rem + 1vw, 20px) 40px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'/%3E%3Cpolyline points='12 5 19 12 12 19'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 28px center;
}

/* Button variant — inline-flex container with text + arrow as flex children,
 * both centered together with a 12px gap. This is what JS-enhanced submits
 * (and HubSpot configurations that render <button> directly) get. Fluid
 * padding mirrors .btn--xl. */
form button[type=submit],
form button.hs-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: clamp(16px, 0.6rem + 1vw, 20px) clamp(28px, 1.1rem + 1.3vw, 40px);
}

/* Arrow SVG inside the enhanced button. Inherits the button's white text
 * colour via stroke="currentColor" set in the JS-injected SVG. */
.gated-form__btn-arrow {
  flex-shrink: 0;
}

/* Submit hover — no glow shadow; flat hover state matches .btn--primary. */

/* Captcha */
.grecaptcha-badge {
  margin: 0 auto;
}

/* ── TMM form wrapper (macro output) ──────────────────────────── */

.tmm-form-wrap {
  border-radius: var(--radius-card);
  padding: var(--glass-padding);
  transition: var(--transition-hover);
}

.tmm-form-wrap--default,
.tmm-form-wrap--flat {
  background: #ffffff;
  border: 1px solid #e4e4e7;
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.08);
}

.tmm-form-wrap--glass {
  background: rgba(255, 255, 255, 0.6);
  border: 1px solid rgba(255, 255, 255, 0.5);
  -webkit-backdrop-filter: blur(40px);
  backdrop-filter: blur(40px);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.06);
}

/* Dark theme form wrap */
.tmm-form-wrap--dark.tmm-form-wrap--default,
.tmm-form-wrap--dark.tmm-form-wrap--flat,
.tmm-form-wrap--dark.tmm-form-wrap--glass {
  background: rgba(255, 255, 255, 0.05);
  border-color: rgba(255, 255, 255, 0.1);
  -webkit-backdrop-filter: blur(24px);
  backdrop-filter: blur(24px);
  box-shadow: none;
}

/* Dark theme inputs — sunken material.
 * Resting bg is slightly DARKER than the section background (#1c1c1e vs the
 * #1d1d1f section), so the input reads as a recessed well. Translucent
 * white overlays (which we used previously) made inputs feel like raised
 * cards floating above the surface — wrong direction for a form input. */
.section--dark form input[type=text],
.section--dark form input[type=search],
.section--dark form input[type=email],
.section--dark form input[type=password],
.section--dark form input[type=tel],
.section--dark form input[type=number],
.section--dark form input[type=url],
.section--dark form select,
.section--dark form textarea,
.section--dark .hs-input,
.tmm-form-wrap--dark form input[type=text],
.tmm-form-wrap--dark form input[type=search],
.tmm-form-wrap--dark form input[type=email],
.tmm-form-wrap--dark form input[type=password],
.tmm-form-wrap--dark form input[type=tel],
.tmm-form-wrap--dark form input[type=number],
.tmm-form-wrap--dark form input[type=url],
.tmm-form-wrap--dark form select,
.tmm-form-wrap--dark form textarea,
.tmm-form-wrap--dark .hs-input {
  background-color: #1c1c1e;
  border-color: rgba(255, 255, 255, 0.08);
  color: #ffffff;
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.4);
}

.section--dark form input::placeholder,
.section--dark form textarea::placeholder,
.tmm-form-wrap--dark form input::placeholder,
.tmm-form-wrap--dark form textarea::placeholder {
  color: rgba(255, 255, 255, 0.3);
}

/* Dark focus — keep the sunken bg (no white "wake up" — would be too jarring
 * against a dark section). Border + ring do the work. Uses :focus-visible
 * to match the light-section behaviour. */
.section--dark form input:focus-visible,
.section--dark form select:focus-visible,
.section--dark form textarea:focus-visible,
.section--dark .hs-input:focus-visible,
.tmm-form-wrap--dark form input:focus-visible,
.tmm-form-wrap--dark form select:focus-visible,
.tmm-form-wrap--dark form textarea:focus-visible,
.tmm-form-wrap--dark .hs-input:focus-visible {
  background-color: #1c1c1e;
  border-color: var(--color-accent-dark);
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
}

/* Search field (theme module) */

  .body-container-wrapper .hs-search-field__button {
    padding: 12px 16px;
    border-radius: var(--radius-xl);
  }
  .body-container-wrapper .hs-search-field__bar--button-inline .hs-search-field__button {
    margin-left: 8px;
    margin-bottom: 0;
  }
  .body-container-wrapper .hs-search-field__button svg {
    height: 16px;
    fill: #ffffff;
  }
  .body-container-wrapper .hs-search-field__bar > form > .hs-search-field__input {
    padding: 12px 16px;
  }
  .body-container-wrapper .hs-search-field__suggestions li a {
    color: #1d1d1f;
    padding: 8px 16px;
    text-decoration: none;
    transition: background-color 0.2s ease;
  }
  .body-container-wrapper .hs-search-field__suggestions li a:hover {
    background-color: #f4f4f5;
  }

/* TMM Table System
 * Horizontal-only borders, no vertical rules.
 * <th> uses subheader typography (uppercase, tracking-widest).
 * Hosted in rounded container with overflow hidden.
 * Theme-aware row striping via tokens.
 */

/* Default table reset — overrides theme-overrides.css (which would otherwise
 * apply border: 1px solid <portal-brand-primary> to all <table>/<th>/<td>).
 * .container scoping bumps specificity above the bare `table {}` rule. */
table,
.container table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 1.4rem;
  overflow-wrap: break-word;
  font-family: var(--font-primary);
  border: none;
  background: transparent;
}

td,
th,
.container td,
.container th {
  vertical-align: top;
  text-align: left;
  border: none;
  border-bottom: 1px solid var(--color-border-solid);
  padding: 18px;
  color: var(--color-text-primary-light);
  background: transparent;
}

thead th {
  vertical-align: bottom;
  background-color: var(--color-bg-light);
  color: var(--color-text-primary-light);
}

tfoot td {
  background-color: var(--color-bg-light);
  color: var(--color-text-primary-light);
}

/* Dark-section theming for NAKED tables (e.g. blog post tables on dark sections).
 * Designed table surfaces (.tmm-comp-table, .tmm-table-wrap) own their own theming
 * later in this file, so these rules never reach them — selectors are written to
 * target only direct children of bare <table> elements. */
.section--dark table:not(.tmm-comp-table):not(.tmm-table-wrap) > tbody > tr > td,
.section--dark table:not(.tmm-comp-table):not(.tmm-table-wrap) > tbody > tr > th,
.section--dark table:not(.tmm-comp-table):not(.tmm-table-wrap) > thead > tr > th,
.section--dark table:not(.tmm-comp-table):not(.tmm-table-wrap) > tfoot > tr > td {
  color: var(--color-text-primary-dark);
  border-bottom-color: var(--color-border-dark);
}

.section--dark table:not(.tmm-comp-table):not(.tmm-table-wrap) > thead > tr > th,
.section--dark table:not(.tmm-comp-table):not(.tmm-table-wrap) > tfoot > tr > td {
  background-color: var(--color-surface-dark);
}

/* ── TMM table wrapper ───────────────────────────────────────────────── */

.tmm-table-wrap {
  border-radius: var(--radius-xl);
  border: 1px solid var(--color-border-solid);
  overflow: hidden;
  background: #ffffff;
}

.tmm-table-wrap table {
  margin: 0;
  border: none;
}

.tmm-table-wrap th {
  padding: 16px 24px;
  background: #fafafa;
  border: none;
  border-bottom: 1px solid var(--color-border-solid);
  font-family: var(--font-primary);
  font-size: 11px;
  font-weight: 600;
  line-height: 16px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--color-text-secondary-light);
}

.tmm-table-wrap td {
  padding: 16px 24px;
  border: none;
  border-bottom: 1px solid var(--color-border-solid);
  font-family: var(--font-primary);
  font-size: 14px;
  font-weight: 400;
  line-height: 20px;
  color: var(--color-text-primary-light);
}

.tmm-table-wrap tr:last-child td { border-bottom: none; }

.tmm-table-wrap tbody tr:nth-child(even) td {
  background: #fafafa;
}

/* Dark theme tables */
.section--dark .tmm-table-wrap {
  background: rgba(255, 255, 255, 0.03);
  border-color: var(--color-border-dark);
}

.section--dark .tmm-table-wrap th {
  background: var(--color-surface-dark);
  border-bottom-color: var(--color-border-dark);
  color: var(--color-text-secondary-dark);
}

.section--dark .tmm-table-wrap td {
  border-bottom-color: rgba(255, 255, 255, 0.08);
  color: var(--color-text-primary-dark);
}

.section--dark .tmm-table-wrap tbody tr:nth-child(even) td {
  background: rgba(255, 255, 255, 0.03);
}

/* Light/glass-card variant — keeps existing translucent look */
.section--light .tmm-table-wrap {
  background: rgba(255, 255, 255, 0.6);
  border-color: rgba(255, 255, 255, 0.5);
  -webkit-backdrop-filter: blur(40px);
  backdrop-filter: blur(40px);
}

.section--light .tmm-table-wrap th {
  background: rgba(255, 255, 255, 0.4);
}

/* ── Comparison table — theme-aware glass card surface ── */

/* border-collapse: separate (NOT collapse) — `collapse` breaks `position:
 * sticky` on <th> cells in every webkit-based browser (long-standing
 * bug). With separate + spacing:0 the table renders identically to
 * collapsed since only bottom borders are used, but sticky thead works
 * correctly on iOS Safari / mobile webkit. */
.tmm-comp-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-family: var(--font-primary);
  text-align: left;
  background: transparent;
  border: none;
}

/* Header row — subtle wash. Bottom border lives on the .th cells (not
 * the tr) because border-collapse: separate doesn't render tr borders. */
.tmm-comp-table thead tr {
  background: rgba(0, 0, 0, 0.02);
}

.section--dark .tmm-comp-table thead tr {
  background: rgba(255, 255, 255, 0.02);
}

.tmm-comp-table__th {
  padding: 24px;
  font-family: var(--font-primary);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-align: center;
  color: var(--color-text-primary-light);
  width: 20%;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--color-divider-light);
}

.section--dark .tmm-comp-table__th {
  border-bottom-color: rgba(255, 255, 255, 0.05);
}

.section--dark .tmm-comp-table__th {
  color: var(--color-text-primary-dark);
}

.tmm-comp-table__th--feature {
  text-align: left;
  width: 40%;
}

/* Body rows — neutral dividers */
.tmm-comp-table__row {
  transition: background-color 0.2s ease;
}

.tmm-comp-table tbody tr:last-child { border-bottom: none; }

/* Action row (Pricing Buttons) */
.tmm-comp-table__row--actions .tmm-comp-table__cell {
  padding: 32px 24px;
}

.tmm-comp-table__row--actions .btn,
.tmm-comp-table__row--actions .tmm-cta,
.tmm-comp-table__row--actions .tmm-cta .hs-cta-wrapper,
.tmm-comp-table__row--actions .tmm-cta .cta_button {
  width: 100%;
  justify-content: center;
}

/* Cells */
.tmm-comp-table__feature,
.tmm-comp-table__cell {
  padding: 24px;
  vertical-align: middle;
  font-size: 14px;
  background: transparent;
  border-bottom: 1px solid var(--color-divider-light);
}

.section--dark .tmm-comp-table__feature,
.section--dark .tmm-comp-table__cell {
  border-bottom-color: rgba(255, 255, 255, 0.03);
}

.tmm-comp-table tbody tr:last-child td { border-bottom: none; }

.tmm-comp-table__feature {
  text-align: left;
  font-weight: 500;
  color: var(--color-text-secondary-light);
}

.section--dark .tmm-comp-table__feature {
  color: #e4e4e7;
}

.tmm-comp-table__cell {
  text-align: center;
}

.tmm-comp-table__value {
  font-family: var(--font-primary);
  font-size: 14px;
  font-weight: 500;
  color: var(--color-text-secondary-light);
}

.section--dark .tmm-comp-table__value {
  color: var(--color-text-secondary-dark);
}

/* Check / minus icons — accent / muted */
.tmm-comp-table__check {
  display: inline-block;
  color: var(--color-accent-light);
  vertical-align: middle;
}

.section--dark .tmm-comp-table__check {
  color: var(--color-accent-dark-hover);
}

.tmm-comp-table__minus {
  display: inline-block;
  color: var(--color-muted-icon-light);
  vertical-align: middle;
}

.section--dark .tmm-comp-table__minus {
  color: var(--color-text-muted-dark);
}

/* Responsive */
@media (max-width: 767px) {
  .tmm-comp-table__th { padding: 16px 12px; font-size: 11px; }
  .tmm-comp-table__feature,
  .tmm-comp-table__cell { padding: 16px 12px; font-size: 13px; }
}
: 13px; }
}

/* Components */

/* TMM Navigation */

/* Skip link — canonical visually-hidden pattern. Width/height 1px + clip
 * keep it accessible to screen readers and keyboard focus while never
 * occupying any visible space. The old `left: -9999px` approach was
 * vulnerable to CSS-load ordering and stacking-context bugs that could
 * leave the text briefly visible during page load. */
.tmm-nav__skip {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
/* :focus-visible (NOT :focus) — only reveals the skip link when the
 * user is keyboard-navigating. Plain :focus also matched on
 * programmatic focus from scripts, browser autofocus, and (on some
 * browsers) mouse-clicks-elsewhere bouncing focus to the first
 * focusable element. That manifested as the link visually appearing
 * under the nav bar at random times. :focus-visible is the modern
 * canonical pattern for this exact accessibility-vs-visual-noise
 * tradeoff: keyboard users still get the link, mouse users don't. */
.tmm-nav__skip:focus-visible {
  width: auto;
  height: auto;
  clip: auto;
  overflow: visible;
  position: fixed;
  top: 0;
  left: 0;
  padding: 8px 16px;
  margin: 0;
  background: #1d1d1f;
  color: #fff;
  text-decoration: none;
  border-radius: 0 0 8px 0;
  z-index: 9999;
}

/* ── Nav surface state machine ─────────────────────────────────────
 * Two orthogonal axes editor-controllable:
 *   theme:        light (dark text)   |  dark (white text)
 *   start state:  solid (bg always)   |  transparent (over hero)
 *
 * Defaults come from navigation.module's STYLE-tab fields. Per-page
 * override comes from the Header Override module placed on a page;
 * main.js → initNavOverride() reads either source and adds body
 * classes (nav-theme-{light|dark}, nav-start-{solid|transparent}) that
 * the rules below switch on. Scrolled state (.nav--scrolled, also from
 * main.js) layers on top regardless of start state.
 */

.tmm-nav {
  /* Fixed — nav stays pinned to the viewport top across every template
   * (homepage, blog post, blog index, about, pricing, etc.). The
   * transparency-over-hero effect is purely a function of the start_state
   * axis (transparent vs solid) — orthogonal to position. Pages that want
   * a hero floating under the nav set start_state=transparent (typically
   * via the Header Override module placed in the page editor); pages
   * without a top hero use the default start_state=solid and pair with
   * the body.nav-start-solid main padding rule below to push content
   * clear of the fixed bar. */
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  height: var(--nav-height);
  background-color: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color 0.3s, border-color 0.3s, box-shadow 0.3s, color 0.3s;
}

/* Content offset — only for solid-start pages. Pushes the main element
 * down by the nav's rendered height (logo 32 + padding 16*2) so the
 * page's first content sits clear of the fixed bar. Transparent-start
 * pages skip the offset on purpose: the hero is designed to span the
 * top of the viewport with the nav floating over it. scroll-padding-top
 * on the root applies regardless so on-page anchor jumps (e.g. the
 * homepage's #pricing, #demo-form) land below the nav, not under it. */
:root { --nav-height: 72px; }
/* scrollbar-gutter: stable permanently reserves the scrollbar's track
 * width. Without it, opening the mobile drawer (which sets
 * body { overflow: hidden } to lock scroll) removes the scrollbar, the
 * viewport widens by its width, and the fixed nav re-centres — visibly
 * shifting the right-aligned burger sideways. Reserving the gutter keeps
 * layout width constant whether the page scrolls or not. */
html {
  scroll-padding-top: var(--nav-height);
  scrollbar-gutter: stable;
}
body.nav-start-solid main { padding-top: var(--nav-height); }

/* Theme — text + control colours (independent of bg state) */
body.nav-theme-light .tmm-nav__link              { color: #52525b; }
body.nav-theme-light .tmm-nav__link:hover,
body.nav-theme-light .tmm-nav__link.is-active    { color: #1d1d1f; }
body.nav-theme-light .tmm-nav__burger            { color: #1d1d1f; }
body.nav-theme-light .tmm-nav__burger:hover      { background-color: rgba(0, 0, 0, 0.05); }

body.nav-theme-dark  .tmm-nav__link              { color: rgba(255, 255, 255, 0.75); }
body.nav-theme-dark  .tmm-nav__link:hover,
body.nav-theme-dark  .tmm-nav__link.is-active    { color: #fff; }
body.nav-theme-dark  .tmm-nav__burger            { color: #fff; }
body.nav-theme-dark  .tmm-nav__burger:hover      { background-color: rgba(255, 255, 255, 0.1); }

/* Logo SVG fill follows theme via CSS (overrides any inline fill on
   individual paths, e.g. the #4d4d4d on the secondary glyphs). The
   default colour is set on .tmm-nav__logo-link itself so the logo
   renders dark from the very first paint — without it, the wrapper
   has no explicit colour, currentColor falls through to the browser's
   default <a> blue, and the SVG flashes blue for ~50ms before JS adds
   the nav-theme-light body class. The body-class rules below still
   win when they apply (dark theme keeps overriding to white). */
.tmm-nav__logo-link                              { color: #1d1d1f; }
body.nav-theme-light .tmm-nav__logo-link         { color: #1d1d1f; }
body.nav-theme-dark  .tmm-nav__logo-link         { color: #ffffff; }
.tmm-nav__logo-link svg path,
.tmm-nav__logo-link svg polygon,
.tmm-nav__logo-link svg rect {
  fill: currentColor;
}

/* Start state: solid → nav has its scrolled-state bg from page load.
   Same rules also apply when the user scrolls past 20px (.nav--scrolled)
   OR when any dropdown is open (.is-dropdown-open) — the bar reads as
   solid so dropdown content has a calm anchor at scroll position 0. */
body.nav-start-solid.nav-theme-light .tmm-nav,
body.nav-theme-light .tmm-nav.nav--scrolled,
body.nav-theme-light .tmm-nav.is-dropdown-open {
  background-color: rgba(255, 255, 255, 0.85);
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  border-bottom-color: rgba(0, 0, 0, 0.06);
  box-shadow: 0 1px 20px rgba(0, 0, 0, 0.05);
}

body.nav-start-solid.nav-theme-dark  .tmm-nav,
body.nav-theme-dark  .tmm-nav.nav--scrolled,
body.nav-theme-dark  .tmm-nav.is-dropdown-open {
  background-color: rgba(29, 29, 31, 0.85);
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  border-bottom-color: rgba(255, 255, 255, 0.08);
  box-shadow: 0 1px 20px rgba(0, 0, 0, 0.3);
}

.tmm-nav__inner {
  max-width: 1280px;
  margin-inline: auto;
  padding-inline: 80px;
  display: flex;
  align-items: stretch;
  justify-content: space-between;
  gap: 48px;
  height: 100%;
}
/* Logo + right actions vertically centred via align-self so they don't
   stretch the way nav links do — links need to span full bar height so
   the dropdown can anchor to the bar's bottom edge via top: 100%. */
.tmm-nav__inner > .tmm-nav__logo-link,
.tmm-nav__inner > .tmm-nav__right {
  align-self: center;
}

.tmm-nav__logo-link {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  text-decoration: none;
}
.tmm-nav__logo-link svg { height: 30px; width: auto; }

/* Desktop nav links container — flex row of .tmm-nav__item children.
   align-items: stretch (cascading down from .tmm-nav { height: var(--nav-height) })
   so each item is full bar height; the dropdown then positions cleanly
   at top: 100% of the item = the bar's bottom edge. */
.tmm-nav__links {
  display: flex;
  align-items: stretch;
  gap: 4px;
  flex: 1;
  justify-content: center;
}

.tmm-nav__item {
  position: relative;
  display: flex;
  align-items: center;
}

.tmm-nav__link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  font-size: 14px;
  font-weight: 500;
  color: var(--color-text-secondary-light);
  text-decoration: none;
  background: none;
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  font-family: inherit;
  transition: color 0.2s;
}
.tmm-nav__link:hover,
.tmm-nav__link.is-active,
.tmm-nav__item.is-active-branch > .tmm-nav__link,
.tmm-nav__item[data-has-dropdown="true"] > .tmm-nav__link[aria-expanded="true"] {
  color: var(--color-text-primary-light);
}
.tmm-nav__link--readonly { cursor: default; }

.tmm-nav__chevron {
  display: inline-flex;
  align-items: center;
  transition: transform 0.2s ease;
}
.tmm-nav__link[aria-expanded="true"] .tmm-nav__chevron {
  transform: rotate(180deg);
}

/* Active-branch underline cue — subtle line under the parent of the
   current page. Only shown when no dropdown is currently open (so the
   visual focus moves to the open item, not the active one). */
.tmm-nav__item.is-active-branch > .tmm-nav__link::after {
  content: '';
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: -2px;
  height: 2px;
  background: var(--color-accent-light);
  border-radius: 1px;
  opacity: 0.85;
  transition: opacity 0.2s ease;
}
.tmm-nav.is-dropdown-open .tmm-nav__item.is-active-branch > .tmm-nav__link::after {
  opacity: 0;
}

.tmm-nav__right {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-shrink: 0;
}

/* ── Desktop dropdown panel ─────────────────────────────────────────
 * Glass-card chrome per DESIGN.md → Light Glassmorphic. Two width
 * variants:
 *   --simple : 280px single column (e.g. Resources)
 *   --mega   : up to 880px multi-column grid (e.g. Platform)
 * Centered under the trigger via left: 50% + translateX(-50%); clamped
 * with max-width: 90vw so wide mega menus don't overflow on tablets.
 * Reveal: opacity + translateY transition on the [hidden] toggle. */

/* Solid surface — no backdrop blur. The dropdown layers content over
   the page beneath, and any transparency makes the leaf links difficult
   to read once they overlap a hero photograph or a busy section. The
   bar above retains its glass surface; the panel anchors visually to
   it via the slightly darker shadow + matched border. */
.tmm-nav__dropdown {
  position: absolute;
  top: 100%;
  left: 50%;
  z-index: 50;
  margin-top: 8px;
  padding: 16px;
  background-color: var(--color-surface-light);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-2xl);
  box-shadow: 0 32px 64px -16px rgba(0, 0, 0, 0.1);
  opacity: 0;
  transform: translateX(-50%) translateY(8px);
  pointer-events: none;
  transition: opacity 0.2s ease-out, transform 0.2s ease-out;
}
.tmm-nav__dropdown[hidden] {
  display: block;       /* override [hidden] so we can transition */
}
.tmm-nav__item.is-open > .tmm-nav__dropdown {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  pointer-events: auto;
}
/* Hover bridge — invisible wedge above the panel so the cursor doesn't
   close the dropdown while moving from trigger to panel content. */
.tmm-nav__dropdown::before {
  content: '';
  position: absolute;
  top: -8px;
  left: 0;
  right: 0;
  height: 8px;
}

.tmm-nav__dropdown--simple {
  width: 280px;
  padding: 8px;
}
.tmm-nav__dropdown--mega {
  width: 880px;
  max-width: 90vw;
  padding: 24px;
}

.tmm-nav__dropdown-grid {
  display: flex;
  gap: var(--bento-gap);
}
.tmm-nav__dropdown-section {
  flex: 1;
  min-width: 0;
  position: relative;
}
/* Hairline divider between adjacent columns — sits centred inside the
   bento gap (calc(--bento-gap / -2 + 0.5px) puts it 0.5px left of the
   column's left edge, which equals the gap's centre line). */
.tmm-nav__dropdown-section + .tmm-nav__dropdown-section::before {
  content: '';
  position: absolute;
  left: calc((var(--bento-gap) / -2) - 0.5px);
  top: 4px;
  bottom: 4px;
  width: 1px;
  background: var(--color-border-light);
}
/* Section title — uses the eyebrow font (.t-subheader = same uppercase
   tracking-widest 12px as .t-eyebrow) with a soft gray that's a hair
   lighter than the homepage section eyebrow's #a1a1aa. Reads as a quiet
   category label, doesn't compete with the leaf-link titles below.
   Hover (only when wrapped in <a>): drops to the homepage eyebrow's
   #a1a1aa for interactive feedback without going brand-blue loud. */
.tmm-nav__dropdown-section-title {
  display: block;
  margin: 0 0 16px;
  padding: 0 12px;
  color: rgba(0, 0, 0, 0.4);
  text-decoration: none;
  transition: color 0.2s ease;
}
a.tmm-nav__dropdown-section-title:hover,
a.tmm-nav__dropdown-section-title:focus-visible {
  color: rgba(0, 0, 0, 0.6);
}

.tmm-nav__dropdown-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.tmm-nav__dropdown-link {
  display: block;
  padding: 8px 12px;
  border-radius: var(--radius-lg);
  text-decoration: none;
  transition: background-color 0.2s ease;
}
.tmm-nav__dropdown-link:hover,
.tmm-nav__dropdown-link:focus-visible {
  background-color: var(--color-bg-alt-light);
}
.tmm-nav__dropdown-link.is-active {
  background-color: var(--color-bg-alt-light);
}
.tmm-nav__dropdown-link-title {
  display: block;
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text-primary-light);
  letter-spacing: -0.01em;
  transition: color 0.2s ease;
}
.tmm-nav__dropdown-link:hover .tmm-nav__dropdown-link-title,
.tmm-nav__dropdown-link:focus-visible .tmm-nav__dropdown-link-title {
  color: var(--color-accent-light);
}
.tmm-nav__dropdown-link.is-active .tmm-nav__dropdown-link-title {
  color: var(--color-accent-light);
}
.tmm-nav__dropdown-link-desc {
  display: block;
  margin-top: 2px;
  font-size: 13px;
  font-weight: 400;
  color: var(--color-text-muted-light);
  line-height: 1.35;
}

@media (prefers-reduced-motion: reduce) {
  .tmm-nav__dropdown,
  .tmm-nav__chevron,
  .tmm-nav__dropdown-link,
  .tmm-nav__dropdown-link-title { transition: none; }
}

/* Desktop bar CTA — dark pill, TMM's industrial-precision signature.
   The brand colour stays reserved for accents (eyebrows, links, focus
   rings); the conversion CTA reads via the dark/light contrast against
   the bar's surface, not via saturation. Pill shape per DESIGN.md
   "rounded-full where pill shape is explicitly required" — the natural
   geometry for a small horizontal nav button.

   Quality-of-execution details:
   - hover lift via shadow GROWING + softening (0 1px 2px → 0 4px 12px)
     plus bg going subtly LIGHTER (#1d1d1f → #2a2a2c). Lazy hovers go
     darker; the lifted feel comes from going lighter as the button
     "rises" toward the cursor.
   - separate transition durations: bg + shadow at 200ms (breathing),
     transform at 100ms (snap). Acts as one motion, reads as two.
   - brand-blue focus ring appears only on keyboard focus — a delicate
     signal of brand colour without making it a permanent fixture. */
.tmm-nav__cta {
  font-size: 13px !important;
  font-weight: 600 !important;
  letter-spacing: -0.01em !important;
  padding: 8px 18px !important;
  border-radius: var(--radius-full) !important;
  background-color: var(--color-bg-dark) !important;
  color: #fff !important;
  border-color: transparent !important;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06) !important;
  transition: background-color 0.2s ease, box-shadow 0.2s ease, transform 0.1s ease;
}
.tmm-nav__cta:hover {
  background-color: #2a2a2c !important;
  border-color: transparent !important;
  color: #fff !important;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12) !important;
}
.tmm-nav__cta:active {
  transform: scale(0.98);
}
.tmm-nav__cta:focus-visible {
  outline: 2px solid var(--color-accent-light);
  outline-offset: 2px;
}

/* Dark-theme inversion — when the nav is dark over a dark hero, the
   dark pill would disappear into the bar. Flip to a white pill with
   dark text; same lift behaviour, just inverted shadows. */
body.nav-theme-dark .tmm-nav__cta {
  background-color: #ffffff !important;
  color: var(--color-bg-dark) !important;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2) !important;
}
body.nav-theme-dark .tmm-nav__cta:hover {
  background-color: rgba(255, 255, 255, 0.92) !important;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3) !important;
  color: var(--color-bg-dark) !important;
}

.tmm-nav__burger {
  display: none;
  position: relative;
  width: 40px;
  height: 40px;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: var(--color-text-primary-light);
  border-radius: var(--radius-md);
  transition: background-color 0.2s;
}
.tmm-nav__burger:hover { background-color: rgba(0,0,0,0.05); }
.tmm-nav__burger-icon {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.tmm-nav__burger-icon--close { opacity: 0; transform: rotate(-90deg); }
.tmm-nav__burger[aria-expanded="true"] .tmm-nav__burger-icon--menu { opacity: 0; transform: rotate(90deg); }
.tmm-nav__burger[aria-expanded="true"] .tmm-nav__burger-icon--close { opacity: 1; transform: rotate(0); }

/* ── Mobile drawer ───────────────────────────────────────────────────
 * Full-viewport overlay below the bar (top: var(--nav-height)). Hidden
 * by default; .is-open on the drawer reveals it via opacity + translate.
 * Accordion sections animate via max-height transition on the panel.
 *
 * Rendered as a SIBLING of .tmm-nav, never a child: .tmm-nav carries a
 * backdrop-filter glass surface, and any backdrop-filter ancestor
 * becomes the containing block for position:fixed descendants — which
 * would resolve this drawer's top/bottom against the 72px nav box
 * instead of the viewport, collapsing it to zero usable height. */

.tmm-nav__drawer {
  position: fixed;
  top: var(--nav-height);
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 90;
  display: flex;
  flex-direction: column;
  background-color: #ffffff;
  overflow-y: auto;
  /* contain scroll chaining so flicking a long menu doesn't scroll the
     (locked) page behind it. */
  overscroll-behavior: contain;
  /* visibility (not display) drives hide/show so the fade+slide runs
     both ways; visibility:hidden also drops the drawer from the a11y
     tree + tab order at rest. The delayed visibility transition keeps
     the element rendered through the fade-out, then hides it. */
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  transform: translateY(-10px);
  transition: opacity 0.3s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.3s cubic-bezier(0.16, 1, 0.3, 1),
              visibility 0s linear 0.3s;
}
.tmm-nav__drawer[hidden] { display: none; }
.tmm-nav__drawer.is-open {
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
  transition: opacity 0.3s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.3s cubic-bezier(0.16, 1, 0.3, 1),
              visibility 0s linear 0s;
}

.tmm-nav__drawer-body {
  flex: 1;
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.tmm-nav__drawer-item {
  display: flex;
  flex-direction: column;
}

.tmm-nav__drawer-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 8px 0;
  background: none;
  border: none;
  text-align: left;
  font-family: inherit;
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -0.025em;
  color: rgba(0, 0, 0, 0.8);
  text-decoration: none;
  cursor: pointer;
  transition: color 0.2s ease;
}
.tmm-nav__drawer-trigger:hover,
.tmm-nav__drawer-trigger[aria-expanded="true"] {
  color: var(--color-text-primary-light);
}
.tmm-nav__drawer-chevron {
  display: inline-flex;
  align-items: center;
  color: rgba(0, 0, 0, 0.4);
  transition: transform 0.2s ease;
}
.tmm-nav__drawer-trigger[aria-expanded="true"] .tmm-nav__drawer-chevron {
  transform: rotate(180deg);
}

.tmm-nav__drawer-panel {
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-height 0.3s cubic-bezier(0.16, 1, 0.3, 1),
              opacity 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
.tmm-nav__drawer-trigger[aria-expanded="true"] + .tmm-nav__drawer-panel {
  max-height: 1200px;
  opacity: 1;
}

.tmm-nav__drawer-panel-inner {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding: 16px 0 8px;
}

.tmm-nav__drawer-section {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.tmm-nav__drawer-section-title {
  display: block;
  margin: 0 0 8px;
  padding: 0 12px;
  color: rgba(0, 0, 0, 0.4);
  text-decoration: none;
  transition: color 0.2s ease;
}
a.tmm-nav__drawer-section-title:hover,
a.tmm-nav__drawer-section-title:focus-visible {
  color: rgba(0, 0, 0, 0.6);
}

.tmm-nav__drawer-leaf {
  display: block;
  padding: 12px;
  border-radius: var(--radius-2xl);
  text-decoration: none;
  transition: background-color 0.2s ease;
}
.tmm-nav__drawer-leaf:hover,
.tmm-nav__drawer-leaf:active,
.tmm-nav__drawer-leaf:focus-visible {
  background-color: var(--color-bg-alt-light);
}
.tmm-nav__drawer-leaf-title {
  display: block;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--color-text-primary-light);
  transition: color 0.2s ease;
}
.tmm-nav__drawer-leaf:hover .tmm-nav__drawer-leaf-title,
.tmm-nav__drawer-leaf:active .tmm-nav__drawer-leaf-title,
.tmm-nav__drawer-leaf:focus-visible .tmm-nav__drawer-leaf-title {
  color: var(--color-accent-light);
}
.tmm-nav__drawer-leaf-desc {
  display: block;
  margin-top: 2px;
  font-size: 14px;
  font-weight: 400;
  color: var(--color-text-muted-light);
  line-height: 1.35;
}

.tmm-nav__drawer-footer {
  padding: 24px;
  border-top: 1px solid var(--color-divider-light);
  background-color: var(--color-bg-alt-light);
}
.tmm-nav__drawer-cta {
  display: flex !important;
  width: 100%;
  align-items: center;
  justify-content: center;
  padding: 16px 24px !important;
  font-size: 17px !important;
  font-weight: 700 !important;
  border-radius: var(--radius-2xl) !important;
  background-color: var(--color-accent-light) !important;
  color: #ffffff !important;
  border-color: var(--color-accent-light) !important;
  text-decoration: none;
}
.tmm-nav__drawer-cta:hover {
  background-color: var(--color-accent-light-hover) !important;
  border-color: var(--color-accent-light-hover) !important;
}

/* Body lock while drawer is open — JS adds .is-mobile-nav-open. */
body.is-mobile-nav-open { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .tmm-nav__drawer,
  .tmm-nav__drawer-panel,
  .tmm-nav__drawer-trigger,
  .tmm-nav__drawer-chevron,
  .tmm-nav__drawer-leaf,
  .tmm-nav__burger-icon { transition: none; }
}

/* Tablet */
@media (max-width: 1024px) {
  .tmm-nav__inner { padding-inline: 40px; gap: 24px; }
  .tmm-nav__links { gap: 0; }
}

/* Mobile breakpoint — hide desktop nav, show burger + drawer.
   Breakpoint matches the React reference (lg = 1024px). */
@media (max-width: 1023px) {
  .tmm-nav__inner { padding-inline: 24px; gap: 0; }
  .tmm-nav__burger { display: block; }
  .tmm-nav__cta { display: none !important; }
  .tmm-nav__links { display: none; }
}

/* TMM Footer */

.tmm-footer {
  background-color: #ffffff;
  border-top: 1px solid rgba(0, 0, 0, 0.1);
  padding-top: 80px;
  padding-bottom: 40px;
}

/* Two-column outer layout — brand block on the left (logo + tagline),
   menu block on the right. The menu block has its own internal grid for
   the per-section columns so the brand block stays as a single full-
   height unit instead of competing as one of N equal columns. */
.tmm-footer__grid {
  display: grid;
  grid-template-columns: minmax(240px, 1fr) 2fr;
  gap: 80px;
  margin-bottom: 64px;
  align-items: start;
}

/* Menu block — internal grid for the per-section columns. auto-fit means
   1–4 menu items render cleanly without manual breakpoint math; minmax
   prevents columns from squashing too narrow on tablets. */
.tmm-footer__nav {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 40px;
}

.tmm-footer__logo-link {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  margin-bottom: 20px;
}
.tmm-footer__logo-link svg { height: 28px; width: auto; }

.tmm-footer__tagline {
  font-size: 14px;
  color: #a1a1aa;
  font-weight: 500;
  margin: 0;
  line-height: 1.5;
}

/* Social icons row — sits beneath the tagline. Same hover-lift language
 * as the blog-share buttons. Each anchor is a 36px circle that rests at
 * the muted-secondary text colour and shifts to brand accent on hover. */
.tmm-footer__socials {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  list-style: none;
  padding: 0;
  margin: 24px 0 0;
}

.tmm-footer__socials a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-full);
  background: rgba(0, 0, 0, 0.04);
  color: var(--color-text-secondary-light);
  transition: background-color 0.2s ease, color 0.2s ease;
}

.tmm-footer__socials a:hover {
  background: var(--color-accent-wash-light);
  color: var(--color-accent-light);
}

/* Dark-footer variant — applied via .is-footer-dark wrapper on
 * blog-post pages. Same shape, theme-aware tones. */
.is-footer-dark .tmm-footer__socials a {
  background: rgba(255, 255, 255, 0.06);
  color: var(--color-text-secondary-dark);
}

.is-footer-dark .tmm-footer__socials a:hover {
  background: var(--color-accent-wash-dark);
  color: var(--color-accent-dark-hover);
}

.tmm-footer__col-heading {
  font-size: 13px;
  font-weight: 600;
  color: #1d1d1f;
  margin: 0 0 16px;
  font-family: var(--font-primary);
}

.tmm-footer__links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.tmm-footer__links a {
  font-size: 14px;
  font-weight: 500;
  color: #a1a1aa;
  text-decoration: none;
  transition: color 0.2s;
}
.tmm-footer__links a:hover { color: #1d1d1f; }

.tmm-footer__bottom {
  border-top: 1px solid rgba(0, 0, 0, 0.08);
  padding-top: 32px;
  text-align: center;
  font-size: 13px;
  font-weight: 500;
  color: #a1a1aa;
}

/* Tablet — stack: brand on top, menu block below. Menu's internal grid
   keeps its auto-fit columns. */
@media (max-width: 1024px) {
  .tmm-footer__grid {
    grid-template-columns: 1fr;
    gap: 48px;
  }
}

/* Mobile — same vertical stack, tighter spacing. The menu block's
   auto-fit handles per-column wrapping naturally. */
@media (max-width: 767px) {
  .tmm-footer { padding-top: 48px; }
  .tmm-footer__grid {
    grid-template-columns: 1fr;
    gap: 40px;
    margin-bottom: 40px;
  }
  .tmm-footer__nav { gap: 32px; }
}

/* Footer dark mode — applied via .is-footer-dark wrapper from
 * blog-post.html (and any other template that overrides the footer
 * block to wrap the global partial in this class). Surface flips to
 * canonical dark-section material; logo SVG fills currentColor so it
 * picks up white text colour; link/heading/border tokens swap to
 * dark-section equivalents per DESIGN.md → Section themes.
 * NOTE: HubL is parsed in CSS files including comments — never write
 * HubL tag/expression delimiters here, even as documentation. */

.is-footer-dark .tmm-footer {
  background-color: var(--color-bg-dark);
  border-top-color: rgba(255, 255, 255, 0.08);
  color: var(--color-text-primary-dark);
}

.is-footer-dark .tmm-footer__logo-link {
  color: var(--color-text-primary-dark);
}
.is-footer-dark .tmm-footer__logo-link svg path,
.is-footer-dark .tmm-footer__logo-link svg polygon,
.is-footer-dark .tmm-footer__logo-link svg rect {
  fill: currentColor;
}

.is-footer-dark .tmm-footer__tagline {
  color: var(--color-text-secondary-dark);
}

.is-footer-dark .tmm-footer__col-heading {
  color: var(--color-text-primary-dark);
}

.is-footer-dark .tmm-footer__links a {
  color: var(--color-text-secondary-dark);
}
.is-footer-dark .tmm-footer__links a:hover {
  color: var(--color-text-primary-dark);
}

.is-footer-dark .tmm-footer__bottom {
  border-top-color: rgba(255, 255, 255, 0.08);
  color: var(--color-text-secondary-dark);
}

/* Boilerplate header (kept for HubSpot system pages) */

/* Header DND sections */

.header .dnd-section {
  padding: 0;
}

/* Header container */

.header__container {
  display: flex;
  justify-content: space-between;
}

.header__row-1 {
  padding-top: 1rem;
}

.header__row-1,
.header__row-2 {
  align-items: center;
  display: flex;
  justify-content: flex-end;
  width: 100%;
}

@media (max-width: 1150px) and (min-width: 767px) {
  .header__column {
    width: 100%;
  }
}

@media (max-width: 767px) {
  .header__container {
    flex-direction: column;
    padding: 1rem 0 0;
  }

  .header__column {
    position: relative;
  }

  .header__row-1 {
    padding-top: 0;
  }

  .header__row-2 {
    justify-content: center;
    padding: 1.05rem;
  }
}

/* Navigation skipper */

.header__skip {
  height: 1px;
  left: -1000px;
  overflow: hidden;
  position: absolute;
  text-align: left;
  top: -1000px;
  width: 1px;
}

.header__skip:hover,
.header__skip:focus,
.header__skip:active {
  height: auto;
  left: 0;
  overflow: visible;
  top: 0;
  width: auto;
}

/* Logo */

.header__logo {
  align-items: center;
  display: flex;
  height: auto;
  margin-right: auto;
  max-width: 200px;
  overflow: hidden;
}

@media (max-width: 767px) {
  .header__logo {
    margin: 0 auto;
    width: 100%;
  }
}

.header__logo img {
  max-width: 100%;
}

.header__logo .logo-company-name {
  font-size: 1.167rem;
  margin-top: 0.7rem;
}

.header__logo--main {
  padding-top: 1rem;
}

/* Search bar */

.header__search {
  padding: 0 1rem;
  width: auto;
}



  .hs-search-field__form {
    position: relative;
  }

  .header__search .hs-search-field__label {
    flex-basis: auto;
  }



.header__search .hs-search-field__input {
  
  height: 45px;
  padding: 0 0.7rem;
}



  .header__search .hs-search-field__button {
    padding: 0;
    fill: #000;
    background-color: transparent;
    border: none;
    padding: 10px;
    position: absolute;
    top: 0;
    right: 0;
  }

  .header__search .hs-search-field__button svg {
    height: 25px;
  }


.header__search .hs-search-field--open .hs-search-field__input {
  border-bottom: none;
  border-radius: 6px 6px 0 0;
  max-width: 100%;
}

.header__search .hs-search-field--open .hs-search-field__suggestions {
  background-color: #FFF;
  border: 2px solid #D1D6DC;
  border-radius: 0 0 6px 6px;
  border-top-width: 1px;
  position: absolute;
  width: 100%;
  z-index: 10;
}

.header__search .hs-search-field__suggestions li {
  border-top: 1px solid #D1D6DC;
  font-size: 0.875rem;
}

.header__search .hs-search-field__suggestions li a {
  color: #494A52;
  padding: 0.35rem 0.7rem;
  text-decoration: none;
  transition: background-color 0.3s;
}

.header__search .hs-search-field__suggestions #results-for {
  display: none;
}

@media (min-width: 767px) {
  .header__search form {
    align-items: center;
    display: flex;
    flex-direction: row;
  }

  .header__search label {
    margin: 0 1rem 0 0;
  }

  .header__search .hs-search-field__input {
    width: auto;
  }
}

@media (max-width: 767px) {
  .header__search {
    border-top: 2px solid #CED4DB;
    order: 1;
    padding: 1.05rem;
  }
}

/* Language switcher */

.header__language-switcher {
  cursor: pointer;
  padding-right: 1.4rem;
}

.header__language-switcher .lang_switcher_class {
  position: static;
}

.header__language-switcher .lang_list_class {
  border: 2px solid;
  border-radius: 3px;
  box-shadow: 0 2px 9px 0 rgba(0, 0, 0, 0.2);
  display: block;
  left: calc(100% - 24px);
  opacity: 0;
  min-width: 100px;
  padding-top: 0;
  text-align: left;
  top: 100%;
  transition: opacity 0.3s;
  visibility: hidden;
}

.header__language-switcher:hover .lang_list_class,
.header__language-switcher:focus .lang_list_class {
  opacity: 1;
  transition: opacity 0.3s;
  visibility: visible;
}

.header__language-switcher .lang_list_class:before {
  left: 70%;
  top: -25px;
}

.header__language-switcher .lang_list_class:after {
  left: 70%;
  top: -22px;
}

.header__language-switcher .lang_list_class.first-active::after {
  top: -22px;
  transition: 0.3s;
}

.header__language-switcher .lang_list_class li {
  border: none;
  font-size: 18px;
  padding: 0.35rem 0.7rem;
}

.header__language-switcher .lang_list_class li:first-child {
  border-radius: 6px 6px 0 0;
  border-top: none;
}

.header__language-switcher .lang_list_class li:last-child {
  border-bottom: none;
  border-radius: 0 0 6px 6px;
}

.header__language-switcher .lang_list_class li:hover {
  transition: background-color 0.3s;
}

.header__language-switcher--label {
  display: flex;
  position: relative;
}

.header__language-switcher--label-current {
  align-items: center;
  display: flex;
  font-size: 0.75rem;
  margin-bottom: 0.175rem;
  margin-left: 0.7rem;
}

.header__language-switcher--label-current:after {
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 6px solid #494A52;
  content: "";
  display: block;
  height: 0px;
  margin-left: 0.7rem;
  margin-top: 0.175rem;
  width: 0px;
}

@media (max-width: 767px) {
  .header__language-switcher {
    border-top: 2px solid #CED4DB;
    padding-left: 1.05rem;
    padding-right: 0;
  }

  .header__language-switcher .lang_list_class {
    border: none;
    box-shadow: unset;
    display: block;
    left: 30px;
    opacity: 1;
    padding: 0 1.05rem;
    top: 0;
    visibility: visible;
  }

  .header__language-switcher .lang_list_class li {
    background-color: inherit;
    font-size: 0.917rem;
  }

  .header__language-switcher--label-current {
    display: none;
  }

  .header__language-switcher .globe_class {
    background-image: none;
  }

  .header__language-switcher .lang_list_class li:hover{
    background-color: inherit;
  }

  .header__language-switcher .lang_list_class:before,
  .header__language-switcher .lang_list_class:after {
    content: none;
  }
    /* V1 lang switcher updates to keep "in line" w/ v0 mobile styles */
    .header__language-switcher .hs-language-switcher__menu {
        display: block;
        box-shadow:none!important;
        background: transparent;
    }
    .header__language-switcher .hs-language-switcher__menu a {
        font-size: 20px!important;
    }
    .header__language-switcher .hs-language-switcher__button {
        display: none;
    }
  }

/* Navigation */

#nav-toggle {
  display: none;
}

/* Mobile toggles */

@media (max-width: 767px) {
  .header__navigation,
  .header__search,
  .header__language-switcher {
    display: none;
    width: 100%;
  }

  .header__navigation.open,
  .header__search.open,
  .header__language-switcher.open {
    background-color: #F8FAFC;
    display: block;
    left: 0;
    min-height: calc(100vh - 115px);
    position: absolute;
    right: 0;
    top: 75px;
    z-index: 2;
  }

  .header__navigation--toggle,
  .header__search--toggle,
  .header__language-switcher--toggle,
  .header__close--toggle {
    cursor: pointer;
    margin: 0 5vw;
    position: relative;
  }

  .header__navigation--toggle.hide,
  .header__search--toggle.hide,
  .header__language-switcher--toggle.hide {
    display: none;
  }

  .header__navigation--toggle.open,
  .header__search--toggle.open,
  .header__language-switcher--toggle.open {
    display: block;
    margin-left: 0;
    margin-right: auto;
  }

  .header__navigation--toggle:after,
  .header__search--toggle:after,
  .header__language-switcher--toggle:after {
    display: none;
    font-size: 1.083rem;
    font-weight: 600;
    position: absolute;
    left: 40px;
    text-transform: uppercase;
    top: -10px;
  }

  .header__navigation--toggle.open:after,
  .header__search--toggle.open:after,
  .header__language-switcher--toggle.open:after {
    display: block;
    word-break: normal;
  }

  .header__navigation--toggle {
    background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIyNHB4IiBoZWlnaHQ9IjI0cHgiIHZpZXdCb3g9IjAgMCAyNCAxOSIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4gICAgICAgIDx0aXRsZT5oYW1idXJnZXI8L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGcgaWQ9ImhhbWJ1cmdlciIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+ICAgICAgICA8ZyBpZD0iR3JvdXAiIHN0cm9rZT0iIzQ5NEE1MiIgc3Ryb2tlLXdpZHRoPSIzIj4gICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlIiB4PSIxLjUiIHk9IjEuNSIgd2lkdGg9IjIxIiBoZWlnaHQ9IjEiIHJ4PSIwLjUiPjwvcmVjdD4gICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlLUNvcHktNCIgeD0iMS41IiB5PSI5LjUiIHdpZHRoPSIyMSIgaGVpZ2h0PSIxIiByeD0iMC41Ij48L3JlY3Q+ICAgICAgICAgICAgPHJlY3QgaWQ9IlJlY3RhbmdsZS1Db3B5LTUiIHg9IjEuNSIgeT0iMTcuNSIgd2lkdGg9IjIxIiBoZWlnaHQ9IjEiIHJ4PSIwLjUiPjwvcmVjdD4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg==);
    background-size: cover;
    height: 25px;
    width: 25px;
  }

  .header__navigation--toggle:after {
    content: "Menu";
  }

  .header__language-switcher--toggle {
    background-image: url(//static.hsappstatic.net/cos-LanguageSwitcher/static-1.1/img/globe.png);
    background-size: cover;
    height: 25px;
    width: 25px;
  }

  .header__language-switcher--toggle:after {
    content: "Language";
  }

  .header__search--toggle {
    background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIyNHB4IiBoZWlnaHQ9IjI0cHgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4gICAgICAgIDx0aXRsZT5TZWFyY2g8L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+ICAgICAgICA8cGF0aCBkPSJNOS4xMzg2MTUzNCwxNS44OTI1Njg1IEM1LjQxMzk1NzQyLDE1Ljg5MjU2ODUgMi4zODM4ODUyNywxMi44NjM0NDc1IDIuMzgzODg1MjcsOS4xMzkwMDM3NiBDMi4zODM4ODUyNyw1LjQxNDU2MDA1IDUuNDEzOTU3NDIsMi4zODM4ODUyNyA5LjEzODYxNTM0LDIuMzgzODg1MjcgQzEyLjg2MzI3MzMsMi4zODM4ODUyNyAxNS44OTI1Njg1LDUuNDE0NTYwMDUgMTUuODkyNTY4NSw5LjEzOTAwMzc2IEMxNS44OTI1Njg1LDEyLjg2MzQ0NzUgMTIuODYzMjczMywxNS44OTI1Njg1IDkuMTM4NjE1MzQsMTUuODkyNTY4NSBNOS4xMzg3NTI0NSwyLjQzMzYwODg3ZS0xMyBDMTQuMTc3OTk1NSwyLjQzMzYwODg3ZS0xMyAxOC4yNzY0NTM3LDQuMTAwMzI0NzEgMTguMjc2NDUzNyw5LjEzOTI3Nzk2IEMxOC4yNzY0NTM3LDExLjIyOTgyMTEgMTcuNTcxMDE2OSwxMy4xNTg0NDM0IDE2LjM4NTYzMTMsMTQuNjk5NjY5NiBMMjMuNjUwODg4MSwyMS45NjUyMjY2IEMyNC4xMTYzNzA2LDIyLjQzMDcwOTIgMjQuMTE2MzcwNiwyMy4xODU0MDU1IDIzLjY1MDg4ODEsMjMuNjUwODg4MSBDMjMuMTg1NDA1NSwyNC4xMTYzNzA2IDIyLjQzMDcwOTIsMjQuMTE2MzcwNiAyMS45NjUyMjY2LDIzLjY1MDg4ODEgTDE0LjY5OTgxMzMsMTYuMzg1NDcxMyBDMTMuMTU4NDQwNSwxNy41NzA5NTA5IDExLjIyOTU3MzgsMTguMjc2NDUzNyA5LjEzODc1MjQ1LDE4LjI3NjQ1MzcgQzQuMDk5NTA5MzgsMTguMjc2NDUzNyAtMy43MzAzNDkzNmUtMTQsMTQuMTc4MjMxMiAtMy43MzAzNDkzNmUtMTQsOS4xMzkyNzc5NiBDLTMuNzMwMzQ5MzZlLTE0LDQuMTAwMzI0NzEgNC4wOTk1MDkzOCwyLjQzMzYwODg3ZS0xMyA5LjEzODc1MjQ1LDIuNDMzNjA4ODdlLTEzIFoiIGlkPSJwYXRoLTEiPjwvcGF0aD4gICAgPC9kZWZzPiAgICA8ZyBpZD0iU2VhcmNoIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4gICAgICAgIDxtYXNrIGlkPSJtYXNrLTIiIGZpbGw9IndoaXRlIj4gICAgICAgICAgICA8dXNlIHhsaW5rOmhyZWY9IiNwYXRoLTEiPjwvdXNlPiAgICAgICAgPC9tYXNrPiAgICAgICAgPHVzZSBpZD0iSWNvbnMvQWN0aW9ucy9TZWFyY2giIGZpbGw9IiM0OTRBNTIiIHhsaW5rOmhyZWY9IiNwYXRoLTEiPjwvdXNlPiAgICA8L2c+PC9zdmc+);
    background-size: cover;
    height: 25px;
    width: 25px;
  }

  .header__search--toggle:after {
    content: "Search";
  }

  .header__close--toggle {
    background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIyNHB4IiBoZWlnaHQ9IjE5cHgiIHZpZXdCb3g9IjAgMCAyNCAxOSIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4gICAgICAgIDx0aXRsZT5jbG9zZTwvdGl0bGU+ICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPiAgICA8ZyBpZD0iY2xvc2UiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPiAgICAgICAgPGcgaWQ9Ikdyb3VwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyLjAwMDAwMCwgLTEuMDAwMDAwKSIgc3Ryb2tlPSIjNDk0QTUyIiBzdHJva2Utd2lkdGg9IjMiPiAgICAgICAgICAgIDxyZWN0IGlkPSJSZWN0YW5nbGUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEwLjAwMDAwMCwgMTAuNTAwMDAwKSByb3RhdGUoLTQ1LjAwMDAwMCkgdHJhbnNsYXRlKC0xMC4wMDAwMDAsIC0xMC41MDAwMDApICIgeD0iLTAuNSIgeT0iMTAuNSIgd2lkdGg9IjIxIiBoZWlnaHQ9IjEiIHJ4PSIwLjUiPjwvcmVjdD4gICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlLUNvcHktNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTAuMDAwMDAwLCAxMC41MDAwMDApIHJvdGF0ZSg0NS4wMDAwMDApIHRyYW5zbGF0ZSgtMTAuMDAwMDAwLCAtMTAuNTAwMDAwKSAiIHg9Ii0wLjUiIHk9IjEwLjUiIHdpZHRoPSIyMSIgaGVpZ2h0PSIxIiByeD0iMC41Ij48L3JlY3Q+ICAgICAgICA8L2c+ICAgIDwvZz48L3N2Zz4=);
    background-repeat: no-repeat;
    background-size: 110%;
    display: none;
    height: 25px;
    margin-right: 0;
    width: 25px;
  }

  .header__close--toggle.show {
    display: block;
  }
}

/* Blog nav mode — distinct VISUAL + POSITION treatment for blog post
 * and blog index pages.
 *
 * Position: absolute (overrides the global .tmm-nav { position: fixed }
 * default). The nav sits at the top of the page document, NOT pinned to
 * the viewport — so it scrolls AWAY with the page as the reader moves
 * through the article. On blog posts the bottom pager (rendered by
 * blog-post.html as a sibling of main.blog-article) is the always-
 * visible navigation affordance during long reads; on the blog index
 * the listing itself is the surface, and a top nav that follows the
 * scroll would sit on top of grid cards reading as visual noise.
 *
 * Surface: filled with --color-bg-alt-light, the same token blog and
 * blog-index use as their page background. The strip blends seamlessly
 * into the page and the hairline border underneath is what delineates
 * it. No glass blur, no shadow — reads as a clean editorial nav strip
 * rather than the home page's blurred-glass surface. Border colour
 * follows the nav-theme axis: --color-divider-light on light pages,
 * --color-divider-dark on dark.
 *
 * Content offset: cancelled. The global content-offset rule
 * (body.nav-start-solid main { padding-top: var(--nav-height) }) only
 * makes sense when the nav is fixed and taken out of flow. With
 * position: absolute the nav layers over the top of the page anyway,
 * so an additional 64px of main padding would just leave dead space
 * between the strip and the article header.
 *
 * Scope: HubSpot's auto-applied body classes hs-blog-post (single
 * article + case study) and hs-blog-listing (resources index, tag
 * pages). Both match the body-wrapper class set in base.html via
 * builtin_body_classes — no template change needed; every blog post
 * and listing picks this up automatically.
 *
 * !important: the existing nav rules chain multiple body classes
 * (body.nav-start-solid.nav-theme-light .tmm-nav, specificity 0,3,1)
 * and a single-scope override can't beat that without long selector
 * chains. !important here is contained to one block + one scope,
 * doesn't leak. */

.body-wrapper.hs-blog-post .tmm-nav,
.body-wrapper.hs-blog-post .tmm-nav.nav--scrolled,
.body-wrapper.hs-blog-listing .tmm-nav,
.body-wrapper.hs-blog-listing .tmm-nav.nav--scrolled {
  position: absolute !important;
  background-color: var(--color-bg-alt-light) !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  box-shadow: none !important;
  border-bottom: 1px solid var(--color-divider-light) !important;
}

body.nav-theme-dark .body-wrapper.hs-blog-post .tmm-nav,
body.nav-theme-dark .body-wrapper.hs-blog-post .tmm-nav.nav--scrolled,
body.nav-theme-dark .body-wrapper.hs-blog-listing .tmm-nav,
body.nav-theme-dark .body-wrapper.hs-blog-listing .tmm-nav.nav--scrolled {
  border-bottom-color: var(--color-divider-dark) !important;
}

/* Cancel the global content offset on blog templates — see comment
 * block above. The strip is absolute, so main does not need padding to
 * clear it. */
body.hs-blog-post main,
body.hs-blog-listing main {
  padding-top: 0 !important;
}
/* Section themes */

.section {
  position: relative;
  padding-block: var(--section-pad-lg);
  transition: var(--transition-theme);
  overflow: hidden;
}

.section--sm {
  padding-block: var(--section-pad-md);
}

.section--dark  { background-color: var(--color-bg-dark);  color: var(--color-text-primary-dark); }
.section--light { background-color: var(--color-bg-light); color: var(--color-text-primary-light); }

.section--border-top    { border-top:    1px solid var(--color-border-light); }
.section--border-bottom { border-bottom: 1px solid var(--color-border-light); }
.section--dark.section--border-top    { border-top-color:    var(--color-border-dark); }
.section--dark.section--border-bottom { border-bottom-color: var(--color-border-dark); }

/* Container */

.container {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: 80px;
}

@media (max-width: 1024px) {
  .container { padding-inline: 40px; }
}

@media (max-width: 767px) {
  .container { padding-inline: 32px; }
  /* .section / .section--sm padding-block is NOT stepped down here any
   * more — --section-pad-lg / --section-pad-md are fluid clamp() tokens
   * (see main.css :root) that scale continuously. A hard step here would
   * override the fluid token and re-introduce the snap. */
}

/* Section header anatomy — every gap is a fluid token so the header
 * rhythm scales with the type and the section padding. --section-header-gap
 * is the space below the whole header block; the internal badge/eyebrow/
 * heading rhythm uses the shared --text-gap-* stack-rhythm scale. */

.section__header {
  text-align: center;
  margin-bottom: var(--section-header-gap);
}

.section__header--left {
  text-align: left;
}

.section__badge {
  margin-bottom: var(--text-gap-md);
}

.section__subheader {
  margin: 0 0 var(--text-gap-sm);
}

.section__heading {
  margin: 0 0 var(--text-gap-md);
  max-width: 800px;
  margin-inline: auto;
}

.section__header--left .section__heading {
  margin-inline: 0;
}

.section__description {
  margin: 0;
  max-width: 640px;
  margin-inline: auto;
}

/* color comes via .t-body-lg + .section--{theme} rules in elements/_typography.css */

.section__header--left .section__description {
  margin-inline: 0;
}

/* Split layout — eyebrow + heading on the left, richtext + optional button on
 * the right. Two-column grid on desktop; collapses to single-column stack
 * on tablet/mobile for natural reading order.
 *
 * Right-column alignment: the whole content stack (text + optional button)
 * bottom-aligns with the bottom of the left-column heading. Text and button
 * sit together — 24px between them — and the group hugs the bottom edge.
 * On mobile the column collapses, so we reset to top-aligned for natural
 * top-down reading order. */
.section__header--split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  /* Fluid column gap — eases on smaller viewports before the grid
   * collapses to one column at 1023px. */
  gap: clamp(32px, 1.65rem + 3.1vw, 64px);
  text-align: left;
  margin-bottom: var(--section-header-gap);
}

.section__header--split .section__heading,
.section__header--split .section__description {
  margin-inline: 0;
  max-width: none;
}

/* In split layout, zero the bottom margin of whichever element is LAST
 * in the left column. That element's visible baseline becomes the grid
 * row's bottom edge, so the right column's flex-end-aligned button
 * lines up with it pixel-perfect.
 *
 *   description_left=false → heading is :last-child  → its margin zeroes.
 *   description_left=true  → description is :last-child → its margin
 *                            zeroes (already 0 by default). Heading
 *                            keeps its 20px gap to the description below.
 *
 * `:last-child` handles both cases without the macro having to emit a
 * modifier class. */
.section__header--split .section__header-left > :last-child {
  margin-bottom: 0;
}

.section__header--split .section__header-left {
  align-self: start;
  min-width: 0;
}

.section__header--split .section__header-right {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-width: 0;
  /* description → CTA grouping. A flex `gap` only applies BETWEEN items,
   * so a lone CTA (no description) gets no extra space here — the column
   * gap (desktop) / stack gap (mobile) already separates it from the
   * heading. This replaces the old `.section__header-cta { margin-top }`,
   * which double-stacked with the grid gap once the header collapsed on
   * mobile, and which didn't adapt when the button size changed. */
  gap: var(--text-gap-sm);
}

/* Right-column alignment — modifier on .section__header-right drives
 * BOTH the description text alignment and the CTA button's flex-self
 * position. Editor sees the description + button move together as a
 * group, which is what they expect in a split section header. The
 * old .section__header-cta--right modifier (button-only alignment) is
 * removed — alignment is column-level now.
 *
 * NOTE: this is a DESKTOP two-column concern only. Below 1023px the
 * grid collapses to a single column and the media block below forces
 * everything left-aligned regardless of this modifier. */
.section__header-right--right .section__description { text-align: right; }
.section__header-right--right .section__header-cta   { align-self: flex-end; }

.section__header-right--left .section__description { text-align: left; }
.section__header-right--left .section__header-cta   { align-self: flex-start; }

@media (max-width: 1023px) {
  .section__header--split {
    grid-template-columns: 1fr;
    /* Single column now — the gap is the vertical stack gap between the
     * left (heading) block and the right (description/CTA) block. Matches
     * the stack-layout heading→description rhythm (--text-gap-md) so a
     * collapsed split header reads identically to a stack header; the
     * wider --text-gap-lg looked too loose once stacked on mobile. */
    gap: var(--text-gap-md);
  }
  .section__header--split .section__header-right {
    justify-content: flex-start;
  }
  /* Lone-CTA right column (no description) — tighten the heading→button
   * gap. A "View all" button trailing a heading reads as part of the
   * header, not a separate content block, so it wants the tighter
   * text-rhythm gap rather than the full heading→content gap. Content-
   * aware via :has(), so it adapts regardless of the button's size. */
  .section__header--split:has(.section__header-right > .section__header-cta:only-child) {
    gap: var(--text-gap-sm);
  }
  /* Stacked single column: text + CTA always read left-aligned, ignoring
   * the right_col_align setting. Right-aligned copy/button under a
   * left-aligned heading looks broken in a narrow column. */
  .section__header-right--right .section__description { text-align: left; }
  .section__header-right--right .section__header-cta   { align-self: flex-start; }
}

/* Section grid */

.section__grid {
  display: grid;
  gap: var(--bento-gap);
}

.section__grid--2 { grid-template-columns: repeat(2, 1fr); }
.section__grid--3 { grid-template-columns: repeat(3, 1fr); }
.section__grid--4 { grid-template-columns: repeat(4, 1fr); }

@media (max-width: 1024px) {
  .section__grid--3,
  .section__grid--4 { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 767px) {
  .section__grid--2,
  .section__grid--3,
  .section__grid--4 { grid-template-columns: 1fr; }
}

/* Cards */

.card {
  border-radius: var(--radius-card);
  padding: var(--glass-padding);
  transition: var(--transition-hover);
}

/* Dark cards — two surface shades, one shared border. The standard peer
 * shade (.card--dark) uses --color-surface-dark (5% white). The featured
 * shade is module-overridden to --color-surface-dark-elevated (10% white)
 * — see DESIGN.md → Cards → Dark card shades. Both shades share the
 * --color-border-dark-strong border token; hover never switches to an
 * accent-blue border (that's reserved for active selection states, not
 * hover affordance). */
.card--dark {
  background: var(--color-surface-dark);
  border: 1px solid var(--color-border-dark-strong);
  -webkit-backdrop-filter: blur(24px);
  backdrop-filter: blur(24px);
}

.card--dark:hover {
  background: var(--color-surface-dark-elevated);
}

/* Light card — gold standard per DESIGN.md → "Cards — the canonical surface".
 * Solid white body, hairline border, restrained shadow. NO backdrop-filter,
 * NO translucency, NO inset white-bevel. Glass was the original light treatment;
 * it competed with the section background and read as muddy. The dark theme
 * keeps glass (next rule); the light theme does not. */
.card--light {
  background: var(--color-surface-light);
  border: 1px solid var(--color-border-solid);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.04);
}

.card--light:hover {
  /* Hover lifts via shadow only — never a coloured-border shift.
   * Accent-blue on hover-borders is reserved for active/selected states
   * (e.g. tab triggers), not hover affordance. Same rule applies to
   * dark cards (see .card--dark:hover above). */
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
}

/* Card variants */

/* .card--static: A version of the card with zero hover interactivity.
 * Use this for outer wrappers or informational cards that shouldn't react
 * to mouse. The variant-specific :hover rules below restore the resting
 * bg/border/shadow so nothing changes on hover.
 *
 * Note: do NOT add `box-shadow: none` here — that strips the variant's
 * resting shadow at rest, then the :hover rules below restore it,
 * inverting the effect into "flat at rest, shadow on hover". The whole
 * point of card--static is "no change between rest and hover", so the
 * resting shadow stays in place. */
.card.card--static,
.card.card--static:hover {
  transition: none;
  transform: none;
}
/* Revert background/border to resting state even on hover */
.card--dark.card--static:hover  { background: var(--color-surface-dark); border-color: var(--color-border-dark-strong); }
.card--light.card--static:hover {
  background: var(--color-surface-light);
  border-color: var(--color-border-solid);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.04);
}
.card.card--static::before { display: none !important; }

/* Card hover variants — combine with .card--{theme} */

.card--hover-lift:hover { transform: translateY(-4px); box-shadow: 0 12px 40px rgba(0,0,0,0.12); }
.card--hover-border:hover { border-color: rgba(59, 130, 246, 0.4); }
.card--hover-none:hover { transform: none; box-shadow: none; }

/* Compact card padding variant — for tile/integration grids */
.card--compact { padding: 24px; border-radius: var(--radius-xl); }

/* Card internal spacing — replaces inline styles in render_card */
.card__title { margin: 0 0 12px; }
.card__title--with-icon { margin-top: 16px; }
.card__body { opacity: 0.7; }

/* Glass-card modifier — adds the canonical brand-blue hover glow.
 * Combine with .card--{theme} (.card--compact for tiles) and a hover variant.
 * The glow is intentionally identical across every module that opts in, so
 * tile grids feel consistent regardless of which module renders them. */
.card--glass { position: relative; overflow: hidden; }

.card--glass::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  /* dark sections: 16% accent on the top-left corner, fading to clear */
  background: linear-gradient(135deg, rgba(59, 130, 246, 0.16) 0%, rgba(255, 255, 255, 0) 100%);
  opacity: 0;
  transition: opacity 0.5s ease;
  pointer-events: none;
  z-index: 0;
}

/* Light sections: 8% brand-blue accent wash on top-left, fading to clear.
 * The old white "specular glint" was tuned for the translucent glass surface
 * — invisible against the new solid-white gold-standard card. Brand-blue at
 * 8% (vs 16% on dark) is the equivalent subtle hover signal. Matches DESIGN.md
 * → Cards → Variants → `.card--glass`. */
.section--light .card--glass::before {
  background: linear-gradient(135deg, rgba(0, 122, 255, 0.08) 0%, rgba(255, 255, 255, 0) 100%);
}

/* keep card content above the glow layer */
.card--glass > * { position: relative; z-index: 1; }

/* glow appears on hover unless hover is suppressed */
.card--glass:not(.card--hover-none):hover::before { opacity: 1; }

/* paired icon-box scale-on-hover — chrome-level hover behaviour, applies to any
 * icon-box inside a glass card so the hover effect feels consistent across
 * modules. Content sizing/positioning of the icon-box is module-owned. */
.card--glass .icon-box { transition: var(--transition-hover); }
.card--glass:not(.card--hover-none):hover .icon-box { transform: scale(1.1); }

/* Ambient orbs — single positioned blue orb behind section content.
 * Position class on .orb sets the base anchor; CSS custom properties
 * --orb-offset-x / --orb-offset-y (set inline by render_ambient_orbs) translate
 * the orb relative to that anchor. Intensity tier on .section__orbs sets opacity. */

.section__orbs {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}

.orb {
  position: absolute;
  /* Responsive size: tracks the viewport so the orb's relative footprint stays
   * consistent across phone → ultrawide. Lower bound prevents the blur from
   * looking weak on small screens; upper bound stops it dominating wide ones. */
  width: clamp(280px, 35vw, 500px);
  aspect-ratio: 1;
  border-radius: var(--radius-full);
  filter: blur(120px);
  pointer-events: none;
  background: var(--color-accent-light);
}

.section--dark .orb { background: var(--color-accent-dark); }

/* Position anchors — the orb's CENTRE sits 25% past the section corner so
 * ~75% of it bleeds inside the section and ~25% spills outside. Translate
 * percentages are relative to the orb's own size, so as the orb scales via
 * clamp() above, its position scales with it — visually consistent across
 * any section width or screen resolution. Editor offset CSS vars layer on top. */
.orb--top-right    { top: 0;    right: 0; transform: translate(calc( 25% + var(--orb-offset-x, 0)), calc(-25% + var(--orb-offset-y, 0))); }
.orb--top-left     { top: 0;    left: 0;  transform: translate(calc(-25% + var(--orb-offset-x, 0)), calc(-25% + var(--orb-offset-y, 0))); }
.orb--bottom-right { bottom: 0; right: 0; transform: translate(calc( 25% + var(--orb-offset-x, 0)), calc( 25% + var(--orb-offset-y, 0))); }
.orb--bottom-left  { bottom: 0; left: 0;  transform: translate(calc(-25% + var(--orb-offset-x, 0)), calc( 25% + var(--orb-offset-y, 0))); }
.orb--center       { top: 50%; left: 50%; transform: translate(calc(-50% + var(--orb-offset-x, 0)), calc(-50% + var(--orb-offset-y, 0))); }

/* Intensity tiers — opacity per theme */
.section--dark .section__orbs--subtle .orb  { opacity: 0.10; }
.section--dark .section__orbs--medium .orb  { opacity: 0.18; }
.section--dark .section__orbs--strong .orb  { opacity: 0.28; }

.section--light .section__orbs--subtle .orb { opacity: 0.05; }
.section--light .section__orbs--medium .orb { opacity: 0.10; }
.section--light .section__orbs--strong .orb { opacity: 0.18; }

/* Anything inside the section sits above the orbs */
.section > .container,
.section > .section__content {
  position: relative;
  z-index: 1;
}

/* Lucide icon — output of templates/macros/icons.html → render_icon.
 * Pre-swap, the <i> reserves the icon's footprint via inline width/height so
 * there's no CLS when Lucide's runtime swaps it for an <svg>. Lucide preserves
 * the class + inline style on the resulting <svg>, so post-swap rules apply. */
.lucide-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 0;
  flex-shrink: 0;
  vertical-align: middle;
}
.lucide-icon svg { display: block; width: 100%; height: 100%; }

/* Icon box variants */

.icon-box {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-lg);
  width: 48px;
  height: 48px;
  flex-shrink: 0;
}

.icon-box--subtle { background: rgba(59, 130, 246, 0.1); color: var(--color-accent-dark); }
.icon-box--solid-crisp { background: var(--color-accent-light); color: #ffffff; }
.icon-box--solid-glow {
  background: var(--color-accent-light);
  color: #ffffff;
  box-shadow: 0 0 20px rgba(0, 122, 255, 0.4);
}

.section--dark .icon-box--subtle { background: var(--color-accent-dark); color: #ffffff; }
.section--dark .icon-box--solid-crisp { background: var(--color-accent-dark); color: #ffffff; }
.section--dark .icon-box--solid-glow { background: var(--color-accent-dark); color: #ffffff; box-shadow: 0 0 24px rgba(59, 130, 246, 0.5); }

/* ── Feature list (shared) ─────────────────────────────────────────────
 * Vertical list with circular accent-bg icon + text rows.
 * Output of templates/macros/lists.html → render_feature_list. */

.tmm-feature-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.tmm-feature-list__item {
  display: flex;
  /* Top-align the icon plate to the first line of text. Centering caused
   * the icon to float between lines on wrapped rows; top-align keeps it
   * next to the first line, where the reader's eye lands. Single-line
   * rows look near-identical to the previous centered behaviour (the
   * icon's optical centre is nudged via .tmm-feature-list__icon below). */
  align-items: flex-start;
  gap: 12px;
  font-family: var(--font-primary);
  font-size: 14px;
  font-weight: 500;
  line-height: 1.5;
  color: var(--color-text-secondary-light);
}
/* audit-allow: list-item color is theme-aware secondary */
.section--dark .tmm-feature-list__item { color: #e4e4e7; }

.tmm-feature-list__icon {
  width: 24px;
  height: 24px;
  border-radius: var(--radius-md);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  /* Light sections: 10% blue wash + the lighter blue glyph (matches React reference). */
  background: rgba(59, 130, 246, 0.1);
  color: #60a5fa;
}
/* Dark sections: solid brand-blue plate with white glyph — same treatment
 * as a primary CTA, so the check icon reads as a confirmed/positive action.
 * Matches the dark-island pricing card and any future dark-feature-list usage. */
.section--dark .tmm-feature-list__icon {
  background: var(--color-accent-dark);
  color: var(--color-text-primary-dark);
}

.tmm-feature-list__icon svg {
  width: 16px;
  height: 16px;
}

/* Per-item divider — editor adds a list item with the "Render as divider"
 * toggle on, and that item renders as a hairline rule instead of icon+text.
 * Used to visually separate logical groups within a single feature list
 * (e.g. core features above the line, add-ons below). Aria-hidden in the
 * macro so AT skips it; the rule is purely decorative.
 *
 * Border-top colour mixes from currentColor at 12% so the line stays
 * subtle and theme-adaptive — picks up the right tone on light / dark
 * sections and on the featured pricing card without per-context overrides.
 * Vertical padding gives the line breathing room equivalent to one feature
 * row's gap, so the divider reads as a deliberate section break rather
 * than a tight rule between adjacent items. */
.tmm-feature-list__item--divider {
  display: block;
  padding: 0;
  margin: 0;
  border-top: 1px solid color-mix(in srgb, currentColor 12%, transparent);
}

/* ── Shared image wrapper ────────────────────────────────────────────────
 * Output of templates/macros/images.html → render_image.
 * Two fit modes:
 *   .tmm-img--cover  — fills the container, crops to aspect (default)
 *   .tmm-img--native — image dictates container aspect ratio via --img-aspect;
 *                      whole image is visible, no crop. Calling modules with a
 *                      fixed-height frame must relax that frame on .tmm-img--native
 *                      (see .feat-split__media-inner :has() rule for an example). */
.tmm-img {
  display: block;
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
}
.tmm-img img {
  display: block;
  width: 100%;
  height: 100%;
}
.tmm-img--cover img { object-fit: cover; }

/* Contain mode — whole image visible, no crop, no letterbox whitespace.
 * The wrapper itself adopts the image's aspect ratio (via --img-aspect
 * set inline by render_image), capped to the parent's dimensions. The
 * image fills this aspect-correct wrapper exactly so there's no internal
 * gap. If the parent is wider than the wrapper's natural width, the
 * wrapper centres horizontally. Different from --native (no max-height
 * cap) and from the old object-fit:contain approach (which did letterbox). */
.tmm-img--contain {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  aspect-ratio: var(--img-aspect, 16 / 10);
  margin-inline: auto;
}
.tmm-img--contain img { object-fit: cover; }

.tmm-img--native {
  height: auto;
  aspect-ratio: var(--img-aspect, 16 / 10);
}
.tmm-img--native img { object-fit: contain; }

/* ── Accordion (shared) ────────────────────────────────────────────── */

.tmm-accordion {
  display: flex;
  flex-direction: column;
  gap: 0;
  border-radius: var(--radius-2xl);
  overflow: hidden;
}

.tmm-accordion__item {
  border-bottom: 1px solid var(--color-divider-light);
}
.section--dark .tmm-accordion__item {
  border-bottom-color: var(--color-divider-dark);
}
.tmm-accordion__item:last-child { border-bottom: none; }

.tmm-accordion__trigger {
  width: 100%;
  background: none;
  border: none;
  padding: 24px 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  cursor: pointer;
  color: inherit;
  text-align: left;
  font-family: var(--font-primary);
}

.tmm-accordion__chevron {
  flex-shrink: 0;
  transition: transform 0.3s ease;
  opacity: 0.6;
}
.tmm-accordion__item.is-open .tmm-accordion__chevron {
  transform: rotate(180deg);
}

.tmm-accordion__panel {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.35s ease;
}
.tmm-accordion__item.is-open .tmm-accordion__panel {
  max-height: 600px;
}

/* Muted via a theme-aware secondary-text COLOUR, not opacity. opacity: 0.7
 * on the wrapper dimmed everything inside it — including inline links, so
 * a link's accent blue rendered at 70% and read as a different, duller
 * blue. A colour mutes the body copy while links keep their own
 * full-strength accent token. */
.tmm-accordion__answer {
  padding-bottom: 24px;
  line-height: 1.7;
  color: var(--color-text-secondary-light);
}
.section--dark .tmm-accordion__answer {
  color: var(--color-text-secondary-dark);
}
.tmm-accordion__answer p { margin: 0; }

/* Inline links inside answer copy are underlined at rest so they're
 * distinguishable from body text. Colour comes from the global `a` /
 * `.section--dark a` rules — scoped here (not on `.section--dark a`
 * globally) because some anchors are whole-card wrappers that must
 * never be underlined. */
.tmm-accordion__answer a {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* JS reveal animation — removed. The fade-in on translucent dark cards
 * caused a visible backdrop-filter shimmer that no amount of timing
 * tuning fully cleaned up. Sections now render at their final state on
 * page load. The .js-reveal class still emits on every section element
 * (from render_section) and the IntersectionObserver still adds
 * .is-visible (from main.js), but both are inert without these CSS
 * rules. Cheap to leave in case a future reveal pattern wants to hook
 * the same plumbing. */

/* ── Tile-card responsive grid (shared) ────────────────────────────────
 * Count-driven tile-card grid for like-shaped tile-card grids.
 * The caller sets --desk-cols inline (1–4) via the tile_cols(count)
 * macro; calc() picks each tile's flex basis from the column count.
 * Mobile clamps to min(desktop, 2). Orphan rows centre via flex-wrap +
 * justify-content: center.
 *
 * Caller markup (see MACROS.md for the full contract):
 *   div.section__tile-grid (style=--desk-cols set by tile_cols macro)
 *     > div.modulename__card.card.card--theme.card--compact.card--glass
 *       > inner stack
 *
 * Visual rule: DESIGN.md → Tile-card responsive layout (count→cols mapping).
 * Macro contract: MACROS.md → tile_cols.
 * NOTE: HubL is parsed in CSS files, including comments — never write
 * expression / tag delimiters here, even as documentation (HUBSPOT.md).
 *
 * Module-side responsibility: each tile gets the .card .card--{theme}
 * .card--compact .card--glass classes for the surface; the inner stack
 * (icon/title/subtitle column) is module-owned. */

.section__tile-grid {
  --tile-cols: var(--desk-cols, 4);
  --tile-gap:  var(--bento-gap);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--tile-gap);
  max-width: 1024px;
  margin-inline: auto;
}

.section__tile-grid > * {
  box-sizing: border-box;
  flex: 0 0 calc((100% - var(--tile-gap) * (var(--tile-cols) - 1)) / var(--tile-cols));
  max-width: calc((100% - var(--tile-gap) * (var(--tile-cols) - 1)) / var(--tile-cols));
}

@media (max-width: 767px) {
  .section__tile-grid {
    --tile-cols: min(var(--desk-cols, 4), 2);
    --tile-gap: 16px;
  }
}

/* ── Media frame (shared) ───────────────────────────────────────────────
 * Glassmorphic outer card around standalone editorial media (image, video,
 * embed). Lifted from video.module's canonical chrome — translucent white
 * bg + hairline border + soft drop-shadow + inset white highlight, with
 * decorative noise texture and brand-blue corner glow rendered as
 * pointer-events:none child layers.
 *
 * Caller is responsible for sizing (max-width, margin) and inner content.
 * Place .media-frame__texture and .media-frame__glow as direct children
 * BEFORE the content; inner content needs position:relative; z-index:1
 * to sit above the decoration layers.
 *
 * Output of templates/macros/media.html → render_media_frame:
 *   div.media-frame > div.media-frame__texture
 *                   > div.media-frame__glow
 *                   > [caller content — needs position:relative; z-index:1]
 *
 * Visual rule (which media gets the frame): DESIGN.md → Media frame.
 * Editor schema (media_frame group): SCHEMA.md → Media frame.
 * Macro contract: MACROS.md → render_media_frame.
 *
 * NOTE: HubL is parsed in CSS files too — never write HubL expression or
 * tag delimiters (double-curly or curly-percent) inside CSS comments.
 * See HUBSPOT.md for the full rule and symptoms.
 */

/* .media-frame chrome mirrors the gold-standard light card (DESIGN.md →
 * Cards): solid white + hairline border-solid + restrained 0 4px 16px
 * shadow. Old translucent glass values (45% white bg, 8% black border,
 * inset white-bevel rim) blended into #fafafa section bgs and the frame
 * read as invisible — same drift we standardised out of .card--light.
 *
 * Border-radius stays at 24px (NOT 12px var(--radius-card)) — media
 * frames are deliberately rounder than content cards. They're an
 * editorial chrome, not a content card. Documented in DESIGN.md →
 * Media frame. */
.media-frame {
  position: relative;
  width: 100%;
  border-radius: 24px;
  overflow: hidden;
  background: var(--color-surface-light);
  border: 1px solid var(--color-border-solid);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.04);
  transition: var(--transition-hover);
}

.section--dark .media-frame {
  background: var(--color-surface-dark);
  border-color: var(--color-border-dark-strong);
  box-shadow: none;
}

/* Padding variants — chrome scales with the visual weight the editor wants.
 * Mobile values are tighter; desktop ramps up at 768px. */
.media-frame--sm { padding: 8px; }
.media-frame--md { padding: 16px; }
.media-frame--lg { padding: 24px; }

@media (min-width: 768px) {
  .media-frame--sm { padding: 12px; }
  .media-frame--md { padding: 20px; }
  .media-frame--lg { padding: 32px; }
}

/* "None" — chrome disabled. Wrapper still emits for layout consistency
 * but renders fully transparent. Decorative children (.media-frame__texture,
 * .media-frame__glow) are also suppressed below. overflow:visible so the
 * inner content's box-shadow / overflow-into-next-section effects (e.g.
 * hero image's negative-bottom-margin overlap) aren't clipped. */
.media-frame--none {
  padding: 0;
  background: transparent;
  border: 0;
  box-shadow: none;
  overflow: visible;
}

.media-frame--none .media-frame__texture,
.media-frame--none .media-frame__glow {
  display: none;
}

/* Decorative noise — same SVG-feTurbulence pattern lifted from video/feat-split,
 * blended soft-light at 5% opacity. Adds glass-material depth without being
 * visible as a pattern. z-index:0 keeps it under the inner content. */
.media-frame__texture {
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: inherit;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 200px 200px;
  background-repeat: repeat;
  opacity: 0.05;
  mix-blend-mode: soft-light;
  z-index: 0;
}

/* Brand-blue corner glow — 400×400 blob at the top-right corner, blurred 80px,
 * translated 25% past the corner so 75% bleeds inside, 25% spills outside.
 * z-index:0 keeps it under the inner content. */
.media-frame__glow {
  position: absolute;
  top: 0;
  right: 0;
  width: 400px;
  height: 400px;
  border-radius: var(--radius-full);
  pointer-events: none;
  filter: blur(80px);
  background: rgba(59, 130, 246, 0.10);
  transform: translate(25%, -25%);
  z-index: 0;
}
/* Chip — filled pill with optional leading icon. Used as a top-of-section
 * eyebrow that's stronger visually than the .t-subheader / .badge family
 * (the chip is solid-coloured; badges and subheaders are typographic).
 *
 * Adopters:
 *   - case-study-meta.module — top of every case-study article
 *   - gated-form.module      — top of every gated-form section (demo,
 *                              brochure, etc.) with icon-per-form-purpose
 *
 * Same typography as .t-subheader (uppercase tracking-widest 12px), full
 * pill rounding to match the .badge family. Line-height collapses to 1
 * so padding owns the vertical rhythm; nowrap so the leading icon never
 * gets orphaned on a wrapped line.
 *
 * Colour variants (solid fill + white glyph + white label):
 *   .tmm-chip--accent   brand-blue solid (default in macro)
 *   .tmm-chip--success  success-green solid
 *   .tmm-chip--warning  amber solid (audit-allow: no token yet)
 *   .tmm-chip--dark     TMM dark on light sections
 */

.tmm-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 18px;
  border-radius: var(--radius-full);
  font-family: var(--font-primary);
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
  /* Component owns its own bottom rhythm — 24px is the Apple-style
     "chip → heading" gap (slightly tighter than the section h2's own
     descender breathing room above the description). Case-study
     overrides to 32px for the heavier editorial header. */
  margin-bottom: 24px;
  /* Defensive against flex-column parents (e.g. .gated-form__left)
     that would otherwise stretch the chip to fill the cross-axis.
     align-self is a no-op outside flex contexts so it's safe to ship
     as part of the component. */
  align-self: flex-start;
}

.tmm-chip__icon { flex-shrink: 0; }

.tmm-chip--accent  { background: var(--color-accent-light); color: #fff; }
.tmm-chip--success { background: var(--color-success-light); color: #fff; }
/* audit-allow: amber accent — no token yet for warning fill. */
.tmm-chip--warning { background: #f59e0b; color: #fff; }
.tmm-chip--dark    { background: var(--color-bg-dark); color: var(--color-text-primary-dark); }
/* Editorial body prose — shared typography for any rich-text-driven
 * body content (blog articles, legal pages, future content templates).
 * Lives in main.css so the .blog-prose class is available globally
 * without any specific template_css load.
 *
 * Class name kept as `.blog-prose` for backwards-compat with the
 * existing blog template + blog-* modules. The naming is now a
 * misnomer (it applies on legal pages too) — flag for a future
 * rename to `.t-prose` if/when the editorial system needs more uses.
 *
 * Editorial scale (intentionally larger than main site DESIGN.md):
 *   body       20px (1.25rem) / 1.75 / -0.011em / secondary text
 *   h2         36px / 1.15 / 700 / -0.025em / primary text
 *   h3         28px / 1.25 / 700 / -0.025em / primary text
 *   strong     700
 *   blockquote 28px (mobile) / 32px (desktop) / 500 italic / primary
 *
 * NOTE: This intentionally deviates from DESIGN.md's "headings 600
 * only" rule — editorial prose uses 700 (bold) for body-prose
 * headings. Scope limited to .blog-prose; main site .t-h* classes
 * stay 600 untouched. Rationale + full spec in BLOG.md → Typography. */

.blog-prose {
  color: var(--color-text-primary-light);
  font-size: 20px;
  line-height: 1.75;
  letter-spacing: -0.011em;
  /* Proper kerning + ligatures + contextual alternates — Inter looks
   * noticeably more refined at 20px+ with these enabled. */
  font-feature-settings: "kern" 1, "liga" 1, "calt" 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* Descendant selector (no `>`) so paragraphs nested inside HubSpot's
 * RTE wrappers (.hs_cos_wrapper, etc.) and inside individual blog-*
 * modules all get caught. Previously `.blog-prose > p` only matched
 * direct children — RTE-rendered paragraphs sat one level deeper and
 * fell back to the bare `p { font-size: 1rem }` rule (which is 16px,
 * not the editorial 20px). */
.blog-prose p {
  font-size: 20px;
  line-height: 1.75;
  letter-spacing: -0.011em;
  color: var(--color-text-secondary-light);
  margin: 0 0 28px;
}

.blog-prose a {
  color: var(--color-text-primary-light);
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-color: rgba(0, 0, 0, 0.2);
  transition: text-decoration-color 0.2s;
}

.blog-prose a:hover {
  /* Full primary text colour on hover — matches reference's
   * `hover:prose-a:decoration-black` (full opacity, not 70%). */
  text-decoration-color: var(--color-text-primary-light);
}

.blog-prose strong { font-weight: 700; }
.blog-prose em     { font-style: italic; }

.blog-prose ul,
.blog-prose ol {
  margin: 0 0 28px;
  padding-left: 28px;
}

/* Same descendant-selector fix as paragraphs above — `>` was too
 * narrow when list items are nested through wrappers. */
.blog-prose li {
  margin-bottom: 10px;
  font-size: 20px;
  line-height: 1.75;
  letter-spacing: -0.011em;
  color: var(--color-text-secondary-light);
}

/* Headings — h2 for major sections, h3 for sub-sections. Weight 700
 * (bold). Tracking eased from -0.025em to -0.02em: tight negative
 * tracking is an optical correction for LARGE type, but the headings
 * now scale down to ~26/21px on mobile (clamp below) where -0.025em
 * crushes the letters together. -0.02em stays crisp at the 36/28px
 * desktop end without hurting legibility at the small end.
 * scroll-margin-top reserved so anchor-driven scroll (blog TOC) clears
 * the (now-non-sticky) nav with breathing room. */
.blog-prose .blog-heading,
.blog-prose h2,
.blog-prose h3 {
  font-family: var(--font-primary);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--color-text-primary-light);
  scroll-margin-top: 128px;
}

/* Fluid heading sizes — clamp() with the `rem + vw` preferred term so
 * the value actually scales across phone widths (a bare `vw` term is
 * near-zero on phones and would just sit at the floor). Mobile lands
 * ~26px (h2) / ~21px (h3); desktop reaches the original 36 / 28px.
 * Hierarchy holds at both ends: post-title > h2 > h3. */
.blog-prose .blog-heading--h2,
.blog-prose h2 {
  font-size: clamp(26px, 1.3rem + 1.6vw, 36px);
  line-height: 1.2;
  /* em margins so the vertical rhythm scales WITH the clamped font-
   * size. 1.78em / 0.67em resolve to the original 64px / 24px at the
   * 36px desktop size, and ease to ~46px / ~17px at the 26px mobile
   * size. Fixed px would leave desktop-sized whitespace around the
   * now-smaller mobile heading — proportionally out of rhythm. */
  margin: 1.78em 0 0.67em;
}

.blog-prose .blog-heading--h3,
.blog-prose h3 {
  font-size: clamp(21px, 1.1rem + 1.1vw, 28px);
  line-height: 1.25;
  /* em margins — see the h2 note above. 1.71em / 0.57em ≈ 48px / 16px
   * at the 28px desktop size, ~36px / ~12px at the 21px mobile size. */
  margin: 1.71em 0 0.57em;
}

/* Mobile line-height bump. Unitless line-height scales the *number*
 * proportionally with font-size — but typographically the relationship
 * should be INVERSE: small type wants looser leading than large type.
 * On mobile the headings clamp down to ~26/21px AND the narrow column
 * wraps them to 3-4 lines, where leading matters most. The desktop
 * 1.2/1.25 reads cramped there, so loosen it for small viewports. */
@media (max-width: 767px) {
  .blog-prose .blog-heading--h2,
  .blog-prose h2 { line-height: 1.3; }

  .blog-prose .blog-heading--h3,
  .blog-prose h3 { line-height: 1.35; }
}

/* Blockquote — heavy editorial pull treatment. 3px primary-text
 * border + 32px padding-left + larger italic medium-weight type +
 * 56px vertical margin. Scaled up alongside the body bump. */
.blog-prose blockquote {
  border-left: 3px solid var(--color-text-primary-light);
  padding: 8px 0 8px 32px;
  margin: 56px 0;
  font-style: italic;
  font-weight: 500;
  font-size: 28px;
  line-height: 1.4;
  letter-spacing: -0.011em;
  color: var(--color-text-primary-light);
}

@media (min-width: 768px) {
  .blog-prose blockquote { font-size: 32px; }
}
/* Menu and simple menu */

.hs-menu-wrapper ul {
  display: flex;
  flex-wrap: wrap;
  list-style: none;
  margin: 0;
  padding-left: 0;
}

/* Horizontal menu */

.hs-menu-wrapper.hs-menu-flow-horizontal .hs-menu-children-wrapper {
  flex-direction: column;
}

@media (max-width: 767px) {
  .hs-menu-wrapper.hs-menu-flow-horizontal ul {
    flex-direction: column;
  }
}

/* Vertical menu */

.hs-menu-wrapper.hs-menu-flow-vertical ul {
  flex-direction: column;
}

/* Flyouts */

.hs-menu-wrapper.hs-menu-flow-vertical.flyouts ul {
  display: inline-flex;
}

@media (max-width: 767px) {
  .hs-menu-wrapper.hs-menu-flow-vertical ul {
    display: flex;
  }
}

.hs-menu-wrapper.flyouts .hs-item-has-children {
  position: relative;
}

.hs-menu-wrapper.flyouts .hs-menu-children-wrapper {
  left: -9999px;
  opacity: 0;
  position: absolute;
}

.hs-menu-wrapper.flyouts .hs-menu-children-wrapper a {
  display: block;
  white-space: nowrap;
}

.hs-menu-wrapper.hs-menu-flow-horizontal.flyouts .hs-item-has-children:hover > .hs-menu-children-wrapper {
  left: 0;
  opacity: 1;
  top: 100%;
}

.hs-menu-wrapper.hs-menu-flow-vertical.flyouts .hs-item-has-children:hover > .hs-menu-children-wrapper {
  left: 100%;
  opacity: 1;
  top: 0;
}

@media (max-width: 767px) {
  .hs-menu-wrapper.flyouts .hs-menu-children-wrapper,
  .hs-menu-wrapper.hs-menu-flow-horizontal.flyouts .hs-item-has-children:hover > .hs-menu-children-wrapper,
  .hs-menu-wrapper.hs-menu-flow-vertical.flyouts .hs-item-has-children:hover > .hs-menu-children-wrapper {
    left: 0;
    opacity: 1;
    position: relative;
    top: auto;
  }
}

/* CTA, logo, and rich text images */

.hs_cos_wrapper_type_cta img,
.hs_cos_wrapper_type_logo img,
.hs_cos_wrapper_type_rich_text img {
  height: auto;
  max-width: 100%;
}

/* Utilities */

/* For content that needs to be visually hidden but stay visible for screenreaders */

.show-for-sr {
  border: 0 !important;
  clip: rect(0, 0, 0, 0) !important;
  height: 1px !important;
  overflow: hidden !important;
  padding: 0 !important;
  position: absolute !important;
  white-space: nowrap !important;
  width: 1px !important;
}

@media (max-width: 767px) {
  .show-for-sr--mobile {
    border: 0 !important;
    clip: rect(0, 0, 0, 0) !important;
    height: 1px !important;
    overflow: hidden !important;
    padding: 0 !important;
    position: absolute !important;
    white-space: nowrap !important;
    width: 1px !important;
  }
}