/* ==========================================================================
   SOLUTION PAGE SYSTEM  ·  namespace: .sp-*
   ==========================================================================
   The marketing-copy side of the three Solutions pages, built to the block
   formula the vault specs are written in:

       Eyebrow  ·  Aphorism  ·  Headline  ·  Body  ·  Benefit tag

   Every capability section on every Solutions page is one .sp-block with
   those five slots. Nothing else. That constraint is why three pages written
   separately read as one site.

   Pairs with css/demo-system.css, which owns the animated product demos.
   Deliberately separate: copy styling and product-surface styling must not
   be able to bleed into each other.

   Replaces css/solutions.css (2026-07 pages, kept for reference only).

   WHERE TO CHANGE WHAT
     type + spacing scale        -> the token block below
     a block slot's appearance   -> § BLOCK FORMULA
     FAQ appearance              -> § FAQ  (uses js/blocks/sol-accordion.js)
     the demo frame's placement  -> § DEMO FIGURE
   ========================================================================== */

:root {
  /* Spacing — the only values components here may use. No inline margins. */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 48px;
  --sp-8: 64px;

  /* Type roles. Named for the slot they serve, not their size, so a change
     of mind about scale is one edit and not a search for "1.15rem".

     ALIGNED TO main.css, DELIBERATELY. The first version of this file set its
     own headline size, weight and tracking — 600 at -0.015em against the site's
     h2 of 700 at -0.03em — so every block heading on these three pages was
     visibly lighter and looser than every other heading on the site. The
     headline slot no longer restyles type at all: it is an <h2>, so it takes
     main.css's h2 and matches Home, Platform and Why PULSAR exactly. Only the
     aphorism defines its own size, because the site has no equivalent role. */
  --sp-aphorism: clamp(1.15rem, 0.9rem + 1vw, 1.5rem);
  --sp-body: 1rem;
  --sp-body-sm: 0.9rem;
  --sp-tag: 0.7rem;
  --sp-micro: 0.66rem;

  --sp-measure: 62ch;   /* body copy never runs wider than this */
}

/* --------------------------------------------------------------------------
   REVEAL  ·  paired with js/blocks/sol-reveal.js
   A pacing device, not a layout. Bands arrive one at a time on scroll.
   -------------------------------------------------------------------------- */

.sol-reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 620ms cubic-bezier(0.22, 0.8, 0.28, 1),
    transform 620ms cubic-bezier(0.22, 0.8, 0.28, 1);
}

.sol-reveal.is-revealed {
  opacity: 1;
  transform: none;
}

/* WITHOUT JAVASCRIPT, EVERY BAND MUST STILL BE VISIBLE.
   `.is-revealed` is added by js/blocks/sol-reveal.js. With scripting off it is
   never added, so every band below the hero sat at opacity 0 — the whole page
   rendered blank on all three Solutions pages. A pacing device is not allowed
   to be the thing that hides the content.

   `scripting: none` is the correct query for this and needs no markup change or
   head script, so it cannot flash. It covers current Chrome, Safari and Firefox;
   an older engine falls back to the reveal never running, which is the bug this
   fixes — so if that matters, the belt-and-braces addition is a <noscript>
   style block per page, not a change here. */
@media (scripting: none) {
  .sol-reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .sol-reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* --------------------------------------------------------------------------
   MICRO LABEL  ·  the shared "tiny caps" role
   -------------------------------------------------------------------------- */

/* Screen-reader-only alias.
   The site's real utility is .sr-only in main.css. The legacy solutions.css
   also defined .visually-hidden, and the 2026-07 pages used that name — so
   any markup carried over from them would silently render visible text now
   that solutions.css is no longer linked. Aliased rather than left to fail.
   Prefer .sr-only in new markup. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.sp-label {
  display: block;
  font-family: var(--mono);
  font-size: var(--sp-micro);
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--dim);
}

/* ==========================================================================
   § BLOCK FORMULA
   ========================================================================== */

.sp-block {
  max-width: var(--sp-measure);
}

.sp-block + .sp-block {
  margin-top: var(--sp-8);
}

/* Sibling blocks side by side.
   A .sp-block body is capped at 62ch for readability, so a band holding only
   stacked blocks reads as half empty in a 1230px section — which is the
   default outcome on any band without a figure. Put peer blocks in this grid
   instead of stacking them: the measure stays honest and the band fills.
   Use it for genuinely parallel blocks (Ask/Detect/Explain, two agent
   blocks), not for a sequence the reader must follow in order. */
.sp-block-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: var(--sp-7);
  align-items: start;
}

.sp-block-grid > .sp-block {
  max-width: none;
}

.sp-block-grid > .sp-block + .sp-block {
  margin-top: 0;
}

/* An intro block followed by the grid is the obvious composition — one block
   framing a set of peers. Without this the intro's benefit tag collides into
   the first grid eyebrow, which forced a page into splitting them across two
   bands to get air. */
.sp-block + .sp-block-grid,
.sp-lead + .sp-block-grid {
  margin-top: var(--sp-8);
}

/* — Slot 1: eyebrow. Reuses the site's existing .eyebrow; this only handles
     the spacing to the slot below it. — */
.sp-block > .eyebrow {
  margin-bottom: var(--sp-4);
}

/* — Slot 2: aphorism —
   A new component. The specs give every block one quotable line that has to
   carry the whole section for a non-technical reader, and the site had no
   treatment for it. Choices: larger than body but smaller than the headline
   (it precedes the headline, so it must not outrank it), a teal rule instead
   of quote marks (this is a statement, not a citation), and a tighter
   letter-spacing so it reads as composed rather than emphatic. */
.sp-block__aphorism {
  margin: 0 0 var(--sp-4);
  padding-left: var(--sp-4);
  border-left: 2px solid var(--accent);
  font-size: var(--sp-aphorism);
  font-weight: 500;
  line-height: 1.4;
  /* Tracking from the site's heading family (-0.02em/-0.03em) rather than a
     value of its own, so it reads as part of the same typographic system even
     though the role is new. */
  letter-spacing: -0.02em;
  color: var(--text);
  text-wrap: balance;
}

/* — Slot 3: headline. Declarative, carries the "not X, but Y" contrast. —
   Sets NO type properties: it is an <h2>, so main.css gives it the site's
   heading size, weight (700) and tracking (-0.03em). Anything set here would be
   a second, competing heading style on the same site. Only rhythm and wrapping
   belong to this component. */
.sp-block__headline {
  margin: 0 0 var(--sp-4);
  line-height: 1.2;
  text-wrap: balance;
}

/* — Slot 4: body. Two or three sentences, outcome and consequence only. — */
.sp-block__body {
  margin: 0;
  font-size: var(--sp-body);
  line-height: 1.65;
  color: var(--muted);
}

.sp-block__body + .sp-block__body {
  margin-top: var(--sp-4);
}

/* — Slot 5: benefit tag —
   The slot that makes a page work for engineers and investors at once: the
   engineer reads the block, the investor reads the tag.

   NOT A PILL, and this matters more than it looks. The first version was an
   orange-bordered uppercase pill, which is the exact visual language of
   .btn--primary — so it sat at the end of a paragraph reading as a call to
   action, and an investor's eye skipped it as chrome. That cost the slot the
   one job it exists to do. It also spent the functional accent (orange =
   action, and the single flagged deviation) on a copy slot, on every block of
   every page.

   Now: a short orange rule, then the claim in ink. The rule keeps a trace of
   the accent so the tag still catches a skimming eye; nothing about it
   suggests it can be clicked. */
.sp-block__tag {
  display: block;
  margin-top: var(--sp-5);
  padding-top: var(--sp-4);
  font-family: var(--mono);
  font-size: var(--sp-tag);
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text);
}

.sp-block__tag::before {
  content: "";
  display: block;
  width: 28px;
  height: 2px;
  margin-bottom: var(--sp-4);
  background: var(--action);
}

/* NO .band--dark OVERRIDES ANYWHERE IN THIS FILE, AND THAT IS THE POINT.
   main.css's `.band--dark` rule re-keys the semantic tokens themselves — --text,
   --muted, --dim, --line, --bg-card, --accent — so every component built on
   those tokens flips automatically, exactly as Home and Why PULSAR do. This
   file used to carry seventeen hardcoded dark-band colours (#b9c2d0 and
   friends), which fought that mechanism and drifted from the rest of the site
   the moment either changed. Build on the tokens and dark bands take care of
   themselves. */

/* --------------------------------------------------------------------------
   BLOCK + DEMO  ·  a block beside its product surface
   Copy left, demo right, stacking to copy-then-demo. The demo never leads on
   mobile: the reader needs the sentence before the picture means anything.
   -------------------------------------------------------------------------- */

.sp-duo {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--sp-7);
  align-items: center;
}

.sp-duo--copy-right { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.sp-duo--copy-right > .sp-block { order: 2; }
.sp-duo--copy-right > .sp-figure { order: 1; }

.sp-duo > .sp-block { max-width: none; }

@media (max-width: 900px) {
  .sp-duo,
  .sp-duo--copy-right {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--sp-6);
  }
  .sp-duo--copy-right > .sp-block { order: 0; }
  .sp-duo--copy-right > .sp-figure { order: 0; }
}

/* ==========================================================================
   § DEMO FIGURE  ·  the frame around a .pd demo
   The demo system owns the surface; this owns only its placement and caption.
   ========================================================================== */

.sp-figure {
  margin: 0;
  min-width: 0;
}

.sp-figure--wide {
  margin-top: var(--sp-6);
}

/* The caption is not decoration: it is the text alternative for a reader who
   will not watch an animation, and it must state the point of the demo. */
.sp-figure__caption {
  margin-top: var(--sp-3);
  font-size: var(--sp-body-sm);
  line-height: 1.55;
  color: var(--dim);
}


/* ==========================================================================
   § HERO
   ========================================================================== */

.sp-hero {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--sp-7);
  align-items: center;
}

.sp-hero__text { max-width: 54ch; }

.sp-hero__text h1 {
  margin: 0 0 var(--sp-5);
  text-wrap: balance;
}

.sp-hero__actions { margin-top: var(--sp-6); }

@media (max-width: 900px) {
  .sp-hero {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--sp-6);
  }
}

/* ==========================================================================
   § CHIP ROW
   A ruled index of bare domain tags, signalling fluency at zero copyable
   detail. Must stay honest about what is actually handled. It sits on its
   own band and section on all three Solutions pages.

   BAND HEADINGS: THE POLICY.
   A chip row takes NO heading — not an eyebrow, not an h2. The specs give it
   none, so any heading here is copy nobody approved, and three separate
   builders each invented a different one. The chips are self-explaining; they
   belong directly under the block whose claim they evidence.

   The FAQ band takes an .eyebrow of "FAQ" and no h2, for the same reason.
   Where the specs supply real heading copy, use .sp-lead. Where they do not,
   there is no heading. Do not invent one.
   ========================================================================== */

/* AN INDEX, NOT A PILL BLOB.
   The first version was a wrapped mass of same-weight pills — ten to fourteen
   of them, two or three ragged lines, no reading order, and a shape that
   changed with every viewport. It is the one part of these pages that read as
   decoration on pages whose whole argument is precision.

   What replaced it is a ruled index: a responsive column grid, one item per
   cell, each cell opened by a hairline and a small accent tick. Every item is
   visible at once, the columns give the eye a reading order, the alignment is
   the same on all three pages regardless of item count, and it is static —
   selectable, findable with Cmd-F, indexable. No motion, so nothing to
   pause and nothing for prefers-reduced-motion to undo.

   A running line was considered and rejected: moving text cannot be read at a
   glance, never shows the whole set, and is a WCAG 2.2.2 obligation (a visible
   pause control, not merely reduced-motion) for content that is not essential. */

/* GROUPED, NOT FLAT.
   The index is now grouped. A flat run of ten to fourteen tags is a list; the
   same tags under two or three labels are a statement, because the labels say
   what kind of thing each run of tags is — what the product compares against,
   what it compares, what it hands back. The index treatment is unchanged: same
   column grid, same hairline, same tick. Only the wrapper is new.

   One group is legitimate. Where the tags are all one kind (AI Engineering
   Agents), a single leading label still earns its place: it frames the run
   rather than sorting it. */

.sp-chips {
  margin: 0;
  padding: 0;
}

.sp-chips__group + .sp-chips__group {
  margin-top: var(--sp-6);
}

/* The label. Mono and --dim: it is apparatus, not a heading — it must sit under
   the tags in weight, or the row reads as three headings with footnotes. */
.sp-chips__label {
  margin: 0 0 var(--sp-2);
  font-family: var(--mono);
  font-size: var(--sp-micro);
  line-height: 1.5;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
}

.sp-chips__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
  column-gap: var(--sp-6);
  margin: 0;
  padding: 0;
  list-style: none;
}

.sp-chips__item {
  position: relative;
  padding: var(--sp-3) 0 var(--sp-3) var(--sp-4);
  /* Top rules only. The last row is usually short; a closing rule under a
     half-filled row reads as a broken table, an opening rule does not. */
  border-top: 1px solid var(--line);
  font-family: var(--mono);
  font-size: var(--sp-micro);
  line-height: 1.5;
  letter-spacing: 0.05em;
  color: var(--muted);
}

/* The tick. Structure, not emphasis — it marks where each entry begins so the
   columns read down as well as across. */
.sp-chips__item::before {
  content: "";
  position: absolute;
  top: calc(var(--sp-3) + 0.55em);
  left: 0;
  width: 6px;
  height: 1px;
  background: var(--accent);
}

/* Kept for a chip index placed inside a block rather than on its own band.
   All three Solutions pages now give it a band, so this normally does not
   match; it exists so nothing has to inline a margin if that changes. */
.sp-block + .sp-chips,
.sp-lead + .sp-chips {
  margin-top: var(--sp-6);
}

.sp-chips__note {
  max-width: var(--sp-measure);
  margin: var(--sp-6) 0 0;
  font-size: var(--sp-body-sm);
  line-height: 1.6;
  color: var(--muted);
}


/* ==========================================================================
   § QUESTION LIST  ·  "What teams can answer"
   Genuinely parallel items, none deserving more weight: a plain list with a
   marker, not a card grid dressed up as substance.
   ========================================================================== */

.sp-questions {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: var(--sp-4);
  margin: var(--sp-6) 0 0;
  padding: 0;
  list-style: none;
}

.sp-questions__item {
  position: relative;
  padding: var(--sp-4) var(--sp-4) var(--sp-4) var(--sp-6);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-card);
  font-size: var(--sp-body-sm);
  line-height: 1.55;
}

.sp-questions__item::before {
  content: "?";
  position: absolute;
  top: var(--sp-4);
  left: var(--sp-4);
  font-family: var(--mono);
  font-weight: 700;
  color: var(--accent);
}

/* ==========================================================================
   § WHO BENEFITS
   ========================================================================== */

/* The roles a page serves, as a designed set rather than a sentence.

   WHY THIS EXISTS. "Who benefits" was one bare line of comma-separated role
   names under a heading — true, but it read as a draft note, and it wasted the
   one place on the page where a visitor looks for themselves. A reader scanning
   for "is this for me" scans shapes, not prose.

   WHAT IT DELIBERATELY DOES NOT DO: invent a claim per role. The approved copy
   gives role names and nothing else, so the design earns its keep through
   structure — one card per role, a marker, an even grid — not by attaching a
   benefit sentence nobody wrote. The count is also the point on the System
   Intelligence page, where four roles are a deliberate subset of the seven the
   Agents page serves; four evenly-weighted cards say "these four" far more
   clearly than a sentence listing four names does. */
.sp-roles {
  display: grid;
  /* 260px, not the 190px the label-only version used: each card now carries a
     sentence, and a 190px column breaks that sentence into a ragged stack. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  gap: var(--sp-4);
  margin: var(--sp-6) 0 0;
  padding: 0;
  list-style: none;
}

.sp-roles__item {
  display: grid;
  /* marker column, then content */
  grid-template-columns: auto minmax(0, 1fr);
  gap: 4px var(--sp-4);
  align-content: start;
  padding: var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-card);
}

.sp-roles__name {
  grid-column: 2;
  font-size: var(--sp-body-sm);
  font-weight: 600;
  line-height: 1.35;
  color: var(--text);
}

/* The value sentence. Smaller and quieter than the name, so the set still
   scans as a list of roles first and reads as detail second — a visitor
   looking for themselves finds the label, then the reason to care. */
.sp-roles__value {
  grid-column: 2;
  font-size: var(--sp-body-sm);
  line-height: 1.55;
  color: var(--muted);
}

/* A drawn marker, not an icon set. Icons for "tester" and "release lead" would
   be arbitrary pictograms a reader has to decode; a consistent geometric mark
   carries the same rhythm and claims nothing. */
.sp-roles__item::before {
  content: "";
  /* SOLID, not an outlined box. The outlined version read as an unchecked
     checkbox — the same shape the demo shell uses for sidebar nav items — so a
     row of roles looked like a form waiting to be filled in. A solid mark is
     unambiguously a marker and cannot be mistaken for a control. */
  grid-column: 1;
  grid-row: 1;
  width: 10px;
  height: 10px;
  /* Optical alignment to the cap height of the name beside it, not to the top
     of its line box. */
  margin-top: 0.4em;
  border-radius: 3px;
  background: var(--accent);
}

.sp-roles__note {
  max-width: var(--sp-measure);
  margin: var(--sp-5) 0 0;
  font-size: var(--sp-body-sm);
  line-height: 1.6;
  color: var(--muted);
}

/* THE HOMEPAGE'S BENEFIT CARDS, REUSED ON A SOLUTIONS PAGE.
   `.home-value-props__grid` and `.benefit-card` are styled in main.css and are
   reused here verbatim so "Who benefits" is one component across the site
   rather than two lookalikes. Only the container behaviour is overridden.

   WHY: the homepage grid is a horizontal scroller — `display: flex`,
   `flex-wrap: nowrap`, `overflow-x: auto` — which is right for its six cards.
   With four it simply clipped the last card at the section edge, and a scroller
   that only just overflows reads as broken rather than as scrollable. Here the
   set is small enough to fit, so it wraps instead: four across when there is
   room, two-up and then one-up as the column narrows. The cards themselves are
   untouched. */
.solution-page .home-value-props__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
  justify-content: stretch;
  overflow: visible;
  margin-top: var(--sp-6);
}

/* The card carries a hard `width: 260px` for the scroller — correct there,
   wrong in a grid cell, where it overflowed the computed 252.5px column by
   7.5px and pushed the last card past the edge. In the grid the cell decides
   the width. (`flex: 0 0 260px` is inert here, so only `width` needs undoing.) */
.solution-page .home-value-props__grid > .benefit-card {
  width: auto;
  max-width: none;
}

/* Kept as an alias: the earlier single-sentence treatment. Anything still using
   it renders as body copy rather than breaking. */
.sp-who {
  max-width: var(--sp-measure);
  margin-top: var(--sp-5);
  font-size: var(--sp-body);
  line-height: 1.65;
  color: var(--muted);
}

/* ==========================================================================
   § RECESSED GROUP  ·  Page 3's header-only rows
   Carries a maturity difference with visual weight instead of a status label:
   lower contrast, one line each, no body copy, no benefit tag, no visual.
   The reader takes "these two are here, the rest is what the foundation
   enables" from the layout, and no sentence has to say it.

   Do not add a description, an icon, or a badge to these rows. The absence
   IS the content.
   ========================================================================== */

/* Wider than the body measure, deliberately. These rows are one line each by
   rule, and the longest piece of approved copy here runs ~100 characters — at
   the 62ch body measure it wrapped while its two peers did not, so the group
   read as two treatments rather than three peers. The one-line rule is what
   carries the maturity difference, so the measure yields to it. */
.sp-recessed {
  max-width: 84ch;
  margin: var(--sp-6) 0 0;
  padding: 0;
  border-top: 1px solid var(--line);
  list-style: none;
}

.sp-recessed__item {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-3);
  padding: var(--sp-4) 0;
  border-bottom: 1px solid var(--line);
  font-size: var(--sp-body-sm);
  color: var(--muted);
}

.sp-recessed__name {
  font-weight: 600;
  color: var(--text);
}


/* ==========================================================================
   § FAQ  ·  reuses js/blocks/sol-accordion.js (.sol-accordion__* contract)
   Where mechanism copy pulled out of body text goes to live. Short blocks,
   collapsed by default, so the page stays scannable while full depth is one
   click away.
   ========================================================================== */

/* DESIGNED, NOT JUST FUNCTIONAL.
   The first version was four hairlines with a chevron — it worked, and it read
   as an unstyled details list. Four changes earn their keep:

     · Each question is a CARD, not a row in a rule-separated stack, so a closed
       FAQ reads as a considered set of four things rather than leftover text.
     · A mono counter numbers them. Numbering says "this is a short, finite set,
       you can read all of it", which is exactly the promise a 4-question block
       should make. It comes from a CSS counter, so it survives the two different
       trigger markups the pages already have.
     · The open item takes an accent left rule and a tinted ground, so the thing
       you are reading is obvious when three neighbours are still closed.
     · The chevron sits in a bordered disc. A bare chevron at the far end of a
       wide row is easy to miss; a disc reads as a control.

   Built entirely on semantic tokens, so dark bands re-key automatically. */

.sol-accordion {
  /* Wider than the body measure. Once the questions became cards rather than
     rules, a 62ch column left the whole right half of the band empty and the
     section read as unfinished. The cards fill the band; the ANSWER keeps the
     honest reading measure via .sol-accordion__panel-inner p below, so nothing
     is traded away for the extra width. */
  max-width: min(100%, 84ch);
  margin-top: var(--sp-6);
  /* Counter for the question numbers. */
  counter-reset: sp-faq;
}

.sol-accordion__item {
  counter-increment: sp-faq;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-card);
  transition: border-color 220ms cubic-bezier(0.22, 0.8, 0.28, 1),
    background 220ms cubic-bezier(0.22, 0.8, 0.28, 1);
}

.sol-accordion__item + .sol-accordion__item { margin-top: var(--sp-3); }

.sol-accordion__item:hover { border-color: var(--accent); }

.sol-accordion__item.is-open {
  border-color: var(--accent);
  background: var(--accent-soft);
  /* The left rule is what makes the open one findable in a stack. */
  box-shadow: inset 3px 0 0 var(--accent);
}

.sol-accordion__trigger {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  width: 100%;
  padding: var(--sp-5);
  border: 0;
  background: none;
  font-family: var(--font);
  /* One step up from body: a question is a heading for its answer. */
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: -0.01em;
  text-align: left;
  color: var(--text);
  cursor: pointer;
}

/* The number. Tabular and dimmed — structure, not emphasis. */
.sol-accordion__trigger::before {
  content: counter(sp-faq, decimal-leading-zero);
  flex: none;
  align-self: flex-start;
  padding-top: 2px;
  font-family: var(--mono);
  font-size: var(--sp-micro);
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--dim);
  transition: color 220ms cubic-bezier(0.22, 0.8, 0.28, 1);
}

.sol-accordion__item.is-open .sol-accordion__trigger::before { color: var(--accent); }

.sol-accordion__trigger:hover { color: var(--accent); }

.sol-accordion__trigger:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: calc(var(--radius) - 6px);
}

/* The chevron, in a disc. The glyph is a rotated corner rather than a font
   character, so it needs no icon dependency and scales with the disc. */
.sol-accordion__caret {
  position: relative;
  flex: none;
  margin-left: auto;
  align-self: flex-start;
  width: 26px;
  height: 26px;
  border: 1px solid var(--line);
  border-radius: 50%;
  transition: border-color 220ms cubic-bezier(0.22, 0.8, 0.28, 1),
    transform 260ms cubic-bezier(0.22, 0.8, 0.28, 1);
}

.sol-accordion__caret::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 7px;
  height: 7px;
  margin: -5px 0 0 -4px;
  border-right: 1.75px solid var(--accent);
  border-bottom: 1.75px solid var(--accent);
  transform: rotate(45deg);
}

.sol-accordion__item:hover .sol-accordion__caret { border-color: var(--accent); }

.sol-accordion__item.is-open .sol-accordion__caret {
  border-color: var(--accent);
  transform: rotate(180deg);
}

/* Grid-rows animation: transitions height without measuring anything in JS,
   so the accordion never fights a resize or a font swap. */
.sol-accordion__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 280ms cubic-bezier(0.22, 0.8, 0.28, 1);
}

.sol-accordion__item.is-open .sol-accordion__panel {
  grid-template-rows: 1fr;
}

.sol-accordion__panel-inner {
  overflow: hidden;
  font-size: var(--sp-body);
  line-height: 1.65;
  color: var(--muted);
}

/* The answer aligns to the question's text, not to the card edge — it sits
   past the number, so the two read as one column. */
.sol-accordion__item.is-open .sol-accordion__panel-inner {
  padding: 0 var(--sp-5) var(--sp-5) calc(var(--sp-5) + 2.4em);
}

@media (max-width: 560px) {
  /* The indent costs more than the alignment buys once the measure is narrow. */
  .sol-accordion__item.is-open .sol-accordion__panel-inner {
    padding-left: var(--sp-5);
  }
}

/* The card may be 84ch wide; the prose inside it must not be. */
.sol-accordion__panel-inner p {
  max-width: var(--sp-measure);
  margin: 0;
}

.sol-accordion__panel-inner p + p { margin-top: var(--sp-4); }

@media (prefers-reduced-motion: reduce) {
  .sol-accordion__panel,
  .sol-accordion__caret { transition: none; }
}


/* ==========================================================================
   § IN-PAGE INVITATION  ·  Page 3 only
   "Shape the next agent with us" is the one page-specific CTA on the site;
   every other CTA lives in the global footer. It invites a conversation
   rather than a queue, and it is true — customer demand decides build order.
   ========================================================================== */

.sp-invite {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-4) var(--sp-5);
  margin-top: var(--sp-6);
  padding: var(--sp-5);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  background: var(--accent-soft);
}

.sp-invite__text {
  margin: 0;
  font-size: var(--sp-body);
  font-weight: 600;
  line-height: 1.45;
  color: var(--text);
}


/* ==========================================================================
   § SECTION LEAD  ·  a band-level heading above a group of blocks
   ========================================================================== */

.sp-lead {
  max-width: var(--sp-measure);
  margin-bottom: var(--sp-7);
}

.sp-lead h2 {
  margin: 0;
  text-wrap: balance;
}

.sp-lead p {
  margin: var(--sp-4) 0 0;
  font-size: var(--sp-body);
  line-height: 1.65;
  color: var(--muted);
}

