/* ─────────────────────────────────────────────────────────────────────────
   /partners — S-Docs for HubSpot solutions partners.

   Layers on top of microsite.css (tokens, primitives, masthead, the hero
   shell, the closing section, the footer, scroll reveals), demo.css (the form
   card and its fields) and home-v5.css (the closing section's copy-beside-form
   layout). This file only adds what this page has and the homepage does not:
   the hero's bullet list, the needs grid, the comparison table, and the
   partner-program offer beside the form, and the mesh canvas behind
   the hero and the closing section. Everything is scoped to partners-*,
   split-head*, need-*, compare-*, offer-* and partner-* classes.
   ───────────────────────────────────────────────────────────────────────── */

/* ───────── 01 hero ───────── */

/* The headline is one sentence, capped so it breaks into two even lines.
   The sub is one long sentence on a 694px measure, 20% wider than the
   578px it started at. */
.partners-hero .h1 { max-width: 850px; }
.partners-hero .hero-sub { max-width: 694px; text-wrap: pretty; }

/* ───────── the orbs ─────────
   partners-mesh.js draws a homepage mesh gradient into this canvas, in the
   hero and in the closing section: "bruise" here, "lagoon" on the HubSpot
   homepage (data-mesh on the section picks it). It sits where the fluid canvas sits
   on the homepage, inside the section's atmosphere layer, so the atmosphere's
   mask and left-hand scrim still shape it. It fades in once the first frame
   has drawn. */
.partners-mesh-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.2s ease .35s;
}
.is-mesh-ready .partners-mesh-canvas { opacity: 1; }

/* The homepage hero's scrim, not microsite.css's heavier default: the default
   was tuned for the brighter fluid and buries the lagoon's blues on the left
   half. This is the veil the homepage shows the same mesh through. Desktop
   and tablet only: on a phone the copy spans the full width and sits right
   on the mesh's brightest blob, so there the heavier default stays. */
@media (min-width: 641px) {
  .partners-hero .hero-atmosphere::after {
    background:
      linear-gradient(to right,
        color-mix(in oklab, var(--bg) 52%, transparent) 0%,
        color-mix(in oklab, var(--bg) 40%, transparent) 30%,
        color-mix(in oklab, var(--bg) 18%, transparent) 54%,
        color-mix(in oklab, var(--bg) 4%, transparent) 78%,
        transparent 100%),
      linear-gradient(to bottom,
        color-mix(in oklab, var(--bg) 26%, transparent),
        transparent 28%,
        color-mix(in oklab, var(--bg) 22%, transparent));
  }
}
/* The closing section's CSS glow is violet and accent orange, tuned to the
   homepage fluid. Under the lagoon it muddies the blues, so the ground goes
   back to plain canvas and the mesh supplies all the colour. */
.partners-register .closing-atmosphere { background: var(--bg); }
/* Stacked (under 1025px) the copy sits above the form, across the full
   width, so microsite.css's left-to-right scrim leaves the right half of
   every line on the bright mesh: white text on light blue. The scrim turns
   to run top to bottom instead. It holds dark behind the copy, the top ~45%
   of the section, and lifts behind the form card, which has its own dark
   panel, so the colour still shows around it. */
@media (max-width: 1024px) {
  .partners-register .closing-atmosphere::after {
    background: linear-gradient(to bottom,
      color-mix(in oklab, var(--bg) 78%, transparent) 0%,
      color-mix(in oklab, var(--bg) 72%, transparent) 38%,
      color-mix(in oklab, var(--bg) 36%, transparent) 56%,
      color-mix(in oklab, var(--bg) 10%, transparent) 72%,
      transparent 100%);
  }
}

/* The homepage hero adds --gutter-wide (up to 60px) on each side on top of
   the frame's --pad, which inset this hero's text from every section below
   it. Back to the frame's own padding, so the hero lines up with the body. */
.partners-hero .hero-content-and-logo-bar { padding-inline: var(--pad); }
/* The unpinned logo carries a 40px inset (microsite.css) to line up with that
   wider hero. With the hero back on the frame edge, the logo comes back too. */
.partners-page .topnav:not(.is-pinned) .brand { margin-left: 0; }

/* The CTA group carries .works-with so microsite.js pins the masthead once
   the button has scrolled off (see the note in partners.html). That class
   brings the homepage logo row's two-column grid and top margin, which a
   single button does not want, so they come off here. */
.partners-hero .hero-cta-group.works-with {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-s) var(--space-l);
  margin-top: 0;
}
/* The commission line beside the button: "and earn a 20% commission",
   continuing the button's sentence. The offer itself is underlined as a link;
   a click scrolls down to the partner program where it is spelled out. */
.hero-commission {
  margin: 0;
  color: color-mix(in oklab, var(--text-primary) 72%, var(--text-secondary));
  font-size: var(--fs-body);
}
.hero-commission a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.hero-commission a:hover,
.hero-commission a:focus-visible { color: var(--text-primary); }

/* Three short claims between the sub and the button: a plain stacked list
   in the sub's colour, an accent check on each. A step more room above
   (the sub's margin) and below than the sub alone gets, so the list reads as
   its own block rather than the sub's last lines. */
.partners-proof {
  display: grid;
  gap: var(--space-2xs);
  margin: 0 0 var(--space-xl);
  padding: 0;
  list-style: none;
  color: color-mix(in oklab, var(--text-primary) 72%, var(--text-secondary));
}
.partners-proof li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: var(--fs-body);
  line-height: 1.35;
}
/* Top-aligned and nudged onto the first line's centre, so a claim that wraps
   on a phone keeps its check beside its first line, not between the two. */
.partners-proof svg { flex: none; width: 18px; height: 18px; margin-top: .12em; color: var(--accent); }
/* Rises in on the hero's load sequence, between the sub (300ms) and the
   button (400ms), and waits on the fonts like the rest of the hero. */
@media (prefers-reduced-motion: no-preference) {
  .partners-hero .partners-proof { animation: heroRise .85s var(--ease-motion) 350ms backwards; }
  html.fonts-pending .partners-hero .partners-proof { animation-play-state: paused; }
}

/* ───────── shared section head ─────────
   Headline on top, sub underneath, both left-aligned. The sub sets in a grey
   between the two text greys: a step quieter than the headline above it. */
.split-head {
  display: grid;
  gap: var(--space-m);
  margin-bottom: var(--space-2xl);
}
/* The eyebrow sits one grid gap above the headline, the same space the
   partner program's eyebrow keeps with its own margin. */
.split-head .eyebrow { margin: 0; }
/* Capped at the size the partner-program headline reaches on a desktop
   (43px, set by its column width), so all three section headlines on the page
   read at one size. Below ~1100px --fs-section is already under the cap and
   the two ramps are the same. */
.split-head .section-headline { margin: 0; max-width: 18em; font-size: min(var(--fs-section), 2.71rem); }
.split-head-sub {
  margin: 0;
  max-width: 36.4em; /* 30% wider than the 28em it was */
  font-size: clamp(0.9rem, 0.776rem + 0.528vw, 1.2rem); /* 14.4 → 19.2 */
  line-height: 1.42;
  color: color-mix(in oklab, var(--text-primary) 55%, var(--text-secondary));
  text-wrap: pretty;
}

/* ───────── 02 what it does for your clients ───────── */

/* The hero closes on --space-4xl of its own (the .hero-stack margin), so
   this section does not need the full section rhythm on top of it as well. */
.partners-fit { padding-top: var(--space-2xl); }

/* Six client needs set exactly like the homepage AI section's cards
   (.ai-cards): same panel, padding, title size and body size. A dark
   rounded panel, a title naming the need, and a paragraph on what S-Docs does
   about it. The homepage cards also carry backdrop-filter: blur, because they
   sit over that section's glow. Nothing sits behind these, so the blur would
   cost a GPU pass per card on every scrolled frame and change nothing on
   screen; it is left off. */
.needs-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-s);
}
.need {
  display: grid;
  align-content: start;
  gap: var(--space-xs);
  padding: var(--space-l);
  background: color-mix(in oklab, var(--surface-card) 62%, transparent);
  border: 1px solid var(--border-subtle);
  border-radius: 14px;
}
.need-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--fs-h3);
  line-height: 1.22;
  color: var(--text-primary);
}
.need-body {
  color: var(--text-secondary);
  font-size: var(--fs-small);
  line-height: 1.55;
}
/* ───────── 03 how we compare ───────── */

/* The table is 760px at its narrowest legible width, so under that it scrolls
   sideways inside this wrapper rather than squeezing four columns of marks
   into a phone. The wrapper is focusable so a keyboard can scroll it too. */
.compare-scroll {
  overflow-x: auto;
  scrollbar-width: thin;
  /* Room above for the S-Docs column's accent edge; none at the sides, or
     the pinned capability column would sit inset from the tinted column
     scrolling under it and a sliver of the tint would show past its edge. */
  padding-block: 4px;
}
.compare-scroll:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 8px; }

/* Drawn with the same single-pixel rule the integrations grid uses. The
   S-Docs column is the one thing that departs from the rule grid: a tint,
   an accent top edge, and rounded ends so it reads as one highlighted
   card laid over the table rather than a coloured stripe. */
.compare {
  width: 100%;
  min-width: 760px;
  border-collapse: separate;
  border-spacing: 0;
  --compare-line: color-mix(in oklab, var(--text-primary) 16%, transparent);
  --compare-tint: color-mix(in oklab, var(--accent) 9%, transparent);
}
.compare th,
.compare td {
  border-bottom: 1px solid var(--compare-line);
  vertical-align: top;
}
.compare thead th {
  padding: var(--space-s) var(--space-m) var(--space-m);
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--fs-body);
  line-height: 1.3;
  color: var(--text-primary);
  text-align: center;
  /* "S-Docs" has a hyphen the browser is happy to break at, which it did at
     1024px: "S-" over "Docs". Every name here is short enough to hold one
     line once the column is at its 760px minimum, so none of them wrap. */
  white-space: nowrap;
}
.compare thead th.compare-cap { padding-left: 0; text-align: left; }
/* The capability column stays put while the four product columns scroll
   under it. Sticky is inert on a screen wide enough to show the whole table,
   so this needs no breakpoint — but it does need an opaque ground, or the
   scrolling cells would show through the pinned text. */
.compare thead th.compare-cap,
.compare tbody th {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--bg);
}
.compare tbody th {
  width: 34%;
  min-width: 13.5rem;
  padding: var(--space-m) var(--space-l) var(--space-m) 0;
  font-weight: 500;
  font-size: var(--fs-body);
  line-height: 1.4;
  color: var(--text-primary);
  text-align: left;
}
.compare td { padding: var(--space-m); text-align: center; }
.compare .is-sdocs { background: var(--compare-tint); }
.compare thead th.is-sdocs {
  border-top: 2px solid var(--accent);
  border-radius: 12px 12px 0 0;
  color: var(--accent);
}
.compare tbody tr:last-child .is-sdocs { border-radius: 0 0 12px 12px; }

/* Marks. Green for yes, the logo's amber for partly, red for no. There is no
   legend, so each mark has to read on its own at a glance: saturated colour,
   a heavy stroke (set on the sprite symbols), a stronger tint and a ring. */
.mark {
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 999px;
  background: color-mix(in oklab, currentColor 26%, transparent);
  box-shadow: inset 0 0 0 1.5px color-mix(in oklab, currentColor 55%, transparent);
}
.mark svg { width: 20px; height: 20px; }
.mark--yes { color: #5EE07A; }
.mark--partly { color: #FFC23D; }
.mark--no { color: #FF5A5A; }
/* The detail line under a capability: the same quiet grey and size as the
   notes under the marks, so the short label still leads the row. */
.compare-cap-note {
  display: block;
  margin-top: 4px;
  font-weight: 400;
  color: var(--text-secondary);
  font-size: var(--fs-small);
  line-height: 1.45;
}
.mark-note {
  display: block;
  max-width: 18ch;
  margin: 6px auto 0;
  color: var(--text-secondary);
  font-size: var(--fs-cap);
  line-height: 1.35;
  text-wrap: balance;
}

/* ───────── 04 the partner program + register ─────────
   The card, fields, copy column and two-column split all come from demo.css
   and home-v5.css. This page adds the program's offer list in the copy
   column and a quiet "Optional" tag on the labels of the two fields that
   are. */

/* home-v5.css stacks the copy over the form at 1260px, because the homepage
   headline needs ~530px to hold three lines. This column is a pitch next to
   its form, so it holds the side-by-side split down to the tablet
   breakpoint and lets the headline wrap to more lines instead. */
@media (min-width: 1025px) and (max-width: 1260px) {
  .partners-register .closing-form-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 30rem); }
  .partners-register .closing-form-copy,
  .partners-register .demo-form-card { max-width: none; }
}

/* home-v5.css sizes this headline at --fs-hero to close the homepage on the
   hero's note. Here it is one section among several, so it tops out at the
   section-headline size. Two sentences, one per line (the <br> sets the
   break). The longer, "Your agency gets S-Docs free.", is ~14.3em wide,
   so the size also tracks the copy column (6.3cqi, under 100/14.3) and
   that line never wraps on a desktop. On a phone the 1.75rem floor wins and it wraps as it must. */
.partners-offer {
  container-type: inline-size;
  /* The hero's commission line jumps here: clear the pinned masthead. */
  scroll-margin-top: calc(var(--nav-h) + var(--space-l));
}
.partners-offer .closing-form-headline {
  max-width: none;
  font-size: clamp(1.75rem, 6.3cqi, var(--fs-section));
  line-height: 1.08;
  letter-spacing: -0.01em;
}
/* The sub carries the whole pitch now, so it gets a wider measure than the
   homepage's 46ch. */
.partners-offer .demo-sub { max-width: 52ch; }

/* Three one-line benefits that restate the sub: an accent check and a short
   line each, at body size, no rules between them. */
.offer-list {
  display: grid;
  gap: var(--space-xs);
  margin: 0;
  padding: 0;
  list-style: none;
}
.offer-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: var(--fs-body);
  line-height: 1.35;
  color: var(--text-primary);
}
.offer-list svg { flex: none; width: 18px; height: 18px; color: var(--accent); }

/* "S-Docs" carries a hyphen the browser will break at on a phone
   ("S- / Docs"). One word, one line. */
.nobr { white-space: nowrap; }

/* ───────── shape breakpoints ─────────
   Sizes come from the fluid ramp in microsite.css. These only change shape. */
/* Three cards across only fit a two-line title from ~1360px up; under
   that the grid goes two-up rather than let the titles run to three lines. */
@media (max-width: 1360px) {
  .needs-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  .needs-grid { grid-template-columns: 1fr; row-gap: var(--space-xl); }
  /* The pinned capability column at its desktop width would leave a phone
     ~125px for the four product columns to scroll through. Narrower text
     and a smaller minimum give the scrolling half of the table the room. */
  .compare tbody th { padding-right: var(--space-m); font-size: var(--fs-small); }
  .compare-cap-note { font-size: var(--fs-cap); }
  /* Split the visible width 60/40: the pinned capability column takes 60%,
     so its labels and notes have room to read, and one product column at a
     time fills the other 40% as the table scrolls under it. cqi is the
     scroll wrapper's own width, so the split holds at any phone size. */
  .compare-scroll { container-type: inline-size; }
  .compare { table-layout: fixed; width: 220cqi; min-width: 0; }
  .compare thead th.compare-cap,
  .compare tbody th { width: 60cqi; min-width: 0; }
  .compare thead th:not(.compare-cap),
  .compare td { width: 40cqi; }
  .compare td { padding: var(--space-m) var(--space-s); }
  .compare thead th:not(.compare-cap) { padding-inline: var(--space-s); }
}
/* On a phone the ordinary ramp leaves the hero headline at ~34px, no bigger
   than a section headline. It tracks the screen width instead: ~41px at
   390px, capped at 52px. This also overrides microsite.css's under-470px
   size, which is tuned for the homepage's four-line shape. */
@media (max-width: 640px) {
  .partners-hero .h1 { font-size: clamp(2.25rem, 10.5vw, 3.25rem); line-height: 1.04; }
}

/* ───────── footer ─────────
   The offer's asterisk note, under the trademark line. The logo spans the
   footer's first two rows, so the note is pinned to the last column to stay
   under the text on a desktop and in the single column on a phone. */
.foot-offer-terms { grid-column: -2 / -1; }
/* On a desktop the right-hand column (links, trademark line, offer note)
   takes 60% of the footer, and its text fills that column. Under 520px
   microsite.css drops the footer to one column, which this leaves alone. */
@media (min-width: 521px) {
  .partners-page .foot-base { grid-template-columns: minmax(0, 1fr) 60%; }
  .partners-page .foot-trademarks { max-width: none; }
}
