/* ============================================================
   SOLUTIONS / ICP VARIANT PAGES (2026-08-18)
   Six shared modules and four bespoke ones. The shared six are byte-identical across every variant;
   only the hero, the pain-and-pride block, the proof and the FAQ change. That ratio is the whole
   economics of running three ICP pages: it is one build and three content files, not three builds.

   ⚠️ EACH VARIANT CARRIES ITS OWN ACCENT VIA THREE TOKENS, NOT ONE. Measured against the real grounds,
   every raw department hue fails a DIFFERENT theme (Practices blue 3.80 dark, Studios pink 3.20 light,
   Stores green 2.90 light) and the on-fill label colour is not shared either (blue takes white; pink
   and green take near-black). A single --accent override would break two of three variants in a way no
   theme toggle reveals.
     --fill  decorative only, never carries text. Same in both themes.
     --ink   text and links. The ONLY one that changes per theme.
     --on    the label sitting on --fill. Same in both themes: a fill is judged against its own label.
   ============================================================ */
/* ⚠️ KEYED ON THE ATTRIBUTE ALONE, NOT ON .sol-body[data-variant]. It was scoped to the body class
   first, which worked on the variant pages and silently failed on the index, where the three cards
   carry data-variant WITHOUT the body class: --fill and --ink resolved to nothing and every card fell
   back to the browser's default link blue, rgb(0,0,238), on all three at once. Attribute-only means a
   variant scope can be opened anywhere a variant is being previewed, which is what the index needs. */
/* ⚠️ FOUR TOKENS NOW, AND --fill-deep IS WHY. Owner 2026-08-18: every variant button takes a WHITE
   label. On the palette hues that does not clear the 4.5:1 floor a button label needs, measured: white
   on #e05d96 is 3.40:1 and on #14a777 is 3.08:1. Blue was already fine at 4.85.
   Rather than darken the palette everywhere (the homepage hero chips use these exact hues, and moving
   them would split the brand across two pinks), --fill stays EXACTLY the department colour for
   decorative use, and --fill-deep is the same hue pushed until white sits on it legibly. It is used
   in one place: solid surfaces carrying white text.
     studios  #e05d96 -> #b82a69   white 5.88:1
     stores   #14a777 -> #0d7d57   white 5.14:1
   Both still clear the 3:1 line-art floor on both grounds, so a deep fill can carry a border too. */
[data-variant='practices'] { --fill: #0269f4; --fill-deep: #0269f4; --ink: #4d9bff; --on: #ffffff; }
[data-variant='studios']   { --fill: #e05d96; --fill-deep: #b82a69; --ink: #f07aab; --on: #ffffff; }
[data-variant='stores']    { --fill: #14a777; --fill-deep: #0d7d57; --ink: #2fc796; --on: #ffffff; }
[data-theme='light'] [data-variant='practices'] { --ink: #0a58c9; }
[data-theme='light'] [data-variant='studios']   { --ink: #a82a5d; }
[data-theme='light'] [data-variant='stores']    { --ink: #08674b; }

/* ⚠️ THE INDEX HAS NO data-variant, SO IT HAD NO TOKENS AT ALL. The comment further down says the index
   "takes the brand accent", which was the intent and never the behaviour: --fill / --ink / --on were
   simply undefined on <body class="sol-body">, and an undefined custom property does not fall back, it
   invalidates the whole declaration silently. `.sol-card:hover` was already dead there for that reason
   (its border-color is a color-mix on --fill). Scoped :not() so a card that opens a variant still wins.
   The deep red is the same #d02400 the light-theme hero cue uses, and it is here for the same reason the
   variants have a --fill-deep: white on the raw accent is 3.72:1, which is not a button label. Measured
   on this site's grounds: #d02400 carries white at 5.34:1, and as ink it reads 5.02:1 on the light bg
   while the raw accent manages only 3.50:1 there. */
.sol-body:not([data-variant]) { --fill: #ff2e00; --fill-deep: #d02400; --ink: #ff2e00; --on: #ffffff; }
[data-theme='light'] .sol-body:not([data-variant]) { --ink: #d02400; }

/* Every heading on this page is a system token. The funnel spent a week at four bespoke scales before
   anyone noticed, so these start on the scale rather than being snapped onto it later. */
.sol-h2 { font-size: var(--fs-h2-lg); letter-spacing: -0.025em; margin: 0 0 14px; text-wrap: balance; }
.sol-lede { max-width: 58ch; font-size: 16.5px; line-height: 1.65; color: var(--text-muted);
  margin: 0; text-wrap: pretty; }
.sol-eyebrow { font-family: var(--mono); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink); margin: 0 0 14px; }

.sol-hero { padding: calc(var(--nav-h) + 76px) 0 72px; text-align: center; }
.sol-hero__title { margin: 0 auto; max-width: 17ch; font-size: var(--fs-display); line-height: 1.06;
  letter-spacing: -0.03em; text-wrap: balance; }
.sol-hero__sub { margin: 20px auto 0; max-width: 52ch; font-size: 17.5px; line-height: 1.55;
  color: var(--text-muted); text-wrap: pretty; }
.sol-hero__cta { margin-top: 32px; display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }
/* The variant button, and the reason --on exists. A shared component hardcoding white here would read
   3.40:1 on Studios pink and 3.08:1 on Stores green. */
/* The variant button, and the only consumer of --fill-deep. --on is white on all three now, which is
   exactly why the background cannot be the raw palette hue. */
.sol-btn { background: var(--fill-deep); border-color: var(--fill-deep); color: var(--on); }
.sol-btn:hover { background: var(--fill-deep); opacity: 0.9; color: var(--on); }
.sol-chips { margin: 34px 0 0; padding: 0; list-style: none; display: flex; flex-wrap: wrap; gap: 10px;
  justify-content: center; }
.sol-chips li { padding: 7px 15px; border: 1px solid var(--border); border-radius: 999px;
  background: var(--bg-surface); font-family: var(--mono); font-size: 11px; letter-spacing: 0.07em;
  text-transform: uppercase; }

/* Pain and pride sit side by side so the turn between them is visible rather than scrolled past. */
.sol-pp { padding: 84px 0; border-top: 1px solid var(--border); }
.sol-pp .container { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 48px; }
.sol-pp__title { font-size: var(--fs-h3); letter-spacing: -0.02em; margin: 0 0 14px; text-wrap: balance; }
.sol-pp__half p { max-width: 46ch; font-size: 16px; line-height: 1.65; color: var(--text-muted);
  margin: 0 0 12px; text-wrap: pretty; }
.sol-pp__half--pride { border-left: 2px solid var(--fill); padding-left: 32px; }
.sol-pp__kicker { color: var(--text) !important; font-weight: 600; }

/* The pain half on the Online variant carries a list as well as a paragraph, because its pain is two
   strands (stock that will not move, and one person doing everything) and a single paragraph makes them
   read as one grievance. Markers use --fill rather than a bullet: the department colour is already the
   page's accent and a disc would be one more shape to look at.
   ⚠️ --ink, NOT --fill, AND THE FIRST PASS GOT IT WRONG. --fill is the raw department hue for decorative
   use; a 1px rule is LINE ART and owes 3:1. Measured on stores green #14a777: 6.40:1 on the dark ground
   and 2.90:1 on the light one, so it failed in exactly one theme, which is the whole reason this page
   carries --ink as a separate per-theme token. --ink is 2fc796 dark / 08674b light and clears both. */
.sol-pp__list { margin: 16px 0 0; padding: 0; list-style: none; max-width: 46ch; }
.sol-pp__list li {
  position: relative;
  padding: 0 0 9px 18px;
  font-size: 15px;
  line-height: 1.6;
  color: var(--text-muted);
  text-wrap: pretty;
}
.sol-pp__list li::before {
  content: '';
  position: absolute;
  left: 0; top: 9px;
  width: 6px; height: 1px;
  background: var(--ink);
}

.sol-how, .sol-proof, .sol-signals, .sol-bench, .sol-gate, .sol-faq {
  padding: 84px 0; border-top: 1px solid var(--border);
}
.sol-steps { margin: 26px 0 0; padding: 0; list-style: none; counter-reset: s; max-width: 62ch; }
.sol-steps li { counter-increment: s; position: relative; padding: 0 0 20px 44px; }
.sol-steps li::before { content: counter(s, decimal-leading-zero); position: absolute; left: 0; top: 0;
  width: 28px; height: 28px; display: grid; place-items: center; border-radius: 50%;
  border: 1px solid var(--border); font-family: var(--mono); font-size: 11px; color: var(--ink); }
.sol-steps b { display: block; font-size: 16px; margin-bottom: 3px; }
.sol-steps span { color: var(--text-muted); font-size: 15px; line-height: 1.6; }

/* An empty state that ADMITS it is empty. A placeholder pretending to be proof is worse than a gap,
   and on this variant the proof and the product are the same photograph. */
.sol-empty { margin-top: 8px; padding: 44px 32px; border: 1px dashed var(--border); border-radius: 14px;
  background: var(--bg-surface); text-align: center; }
.sol-empty__t { margin: 0 0 10px; font-size: var(--fs-h3); letter-spacing: -0.02em; color: var(--text-muted); }
.sol-empty__b { margin: 0 auto; max-width: 56ch; font-size: 15px; line-height: 1.65;
  color: var(--text-muted); text-wrap: pretty; }

.sol-faq__list { max-width: 720px; margin: 24px 0 0; border-top: 1px solid var(--border); }
.sol-faq__list details { border-bottom: 1px solid var(--border); }
.sol-faq__list summary { padding: 20px 0; cursor: pointer; font-size: 17px; font-weight: 600;
  list-style: none; display: flex; justify-content: space-between; gap: 16px; }
.sol-faq__list summary::-webkit-details-marker { display: none; }
.sol-faq__list summary::after { content: '+'; color: var(--ink); font-weight: 400; flex: none; }
.sol-faq__list details[open] summary::after { content: '\2212'; }
.sol-faq__list p { margin: 0 0 20px; max-width: 62ch; font-size: 15.5px; line-height: 1.65;
  color: var(--text-muted); text-wrap: pretty; }

/* ══ PRICING (2026-08-18) ══════════════════════════════════════════════════════════════════════════
   SHARED, and the prices are exactly why. Three ICP pages quoting three numbers is the one drift a
   reader punishes instantly, and it is the failure this directory was built to prevent, so the block is
   byte-identical on all four pages and check-variants.mjs enforces it (the index included, which it did
   not used to read). The ICP voice lives in the bespoke blocks. A price does not get a dialect.
   ⚠️ LANES AND SPECIALISTS, NOT DEPARTMENTS. .sol-bench promises five departments and one brief. Set a
   price beside that with no qualifier and it reads as all five, every month, which is not what /pricing
   sells: it sells how many things run at once and how many people run them. If the tiers move, move
   them here and on /pricing in the SAME commit. */
.sol-pricing { padding: 84px 0; border-top: 1px solid var(--border); }
.sol-pricing .sol-lede b { color: var(--text); font-weight: 600; }

.sol-pricing__entry { margin: 30px 0 0; padding: 26px 28px; border: 1px solid var(--fill-deep);
  border-radius: 14px; background: var(--bg-surface); display: flex; flex-wrap: wrap;
  align-items: center; gap: 22px 30px; }
.sol-pricing__entry-main { flex: 1 1 340px; }
.sol-pricing__tag { display: inline-block; margin-bottom: 10px; padding: 4px 11px; border-radius: 999px;
  background: var(--fill-deep); color: var(--on); font-family: var(--mono); font-size: 10.5px;
  letter-spacing: 0.11em; text-transform: uppercase; }
.sol-pricing__entry-t { margin: 0 0 9px; font-size: var(--fs-h3); letter-spacing: -0.02em; }
.sol-pricing__entry-b { margin: 0; max-width: 62ch; font-size: 15px; line-height: 1.65;
  color: var(--text-muted); text-wrap: pretty; }
.sol-pricing__entry-side { flex: none; }
.sol-pricing__amount { display: block; font-size: 32px; letter-spacing: -0.03em; font-weight: 650;
  font-variant-numeric: tabular-nums; }
.sol-pricing__per { display: block; margin: 2px 0 16px; font-family: var(--mono); font-size: 11px;
  letter-spacing: 0.06em; color: var(--text-muted); }

.sol-pricing__tiers { margin: 14px 0 0; padding: 0; list-style: none; display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 14px; }
.sol-pricing__tier { padding: 22px 22px 24px; border: 1px solid var(--border); border-radius: 14px; }
.sol-pricing__name { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.sol-pricing__name b { font-size: 17.5px; letter-spacing: -0.015em; }
.sol-pricing__name span { font-family: var(--mono); font-size: 13px; color: var(--ink);
  font-variant-numeric: tabular-nums; }
.sol-pricing__spec { margin: 13px 0 0; padding: 13px 0 0; border-top: 1px solid var(--border);
  font-size: 14.5px; line-height: 1.55; color: var(--text); }
.sol-pricing__note { margin: 8px 0 0; font-size: 14.5px; line-height: 1.6; color: var(--text-muted);
  text-wrap: pretty; }
.sol-pricing__foot { margin: 24px 0 0; max-width: 68ch; font-size: 15px; line-height: 1.65;
  color: var(--text-muted); text-wrap: pretty; }
.sol-pricing__foot a { color: var(--ink); }

.sol-close { padding: 84px 0 96px; border-top: 1px solid var(--border); text-align: center; }
.sol-close__title { margin: 0 0 14px; font-size: var(--fs-h2-lg); letter-spacing: -0.028em; }
.sol-close .sol-lede { margin: 0 auto 28px; }

@media (max-width: 720px) {
  .sol-hero { padding: calc(var(--nav-h) + 44px) 0 52px; }
  .sol-how, .sol-proof, .sol-signals, .sol-bench, .sol-gate, .sol-faq, .sol-pp,
  .sol-pricing { padding: 58px 0; }
  .sol-pricing__entry { padding: 22px 20px; }
  .sol-pricing__entry-side { flex: 1 1 100%; }
  .sol-close { padding: 58px 0 72px; }
  .sol-pp .container { gap: 34px; }
  .sol-pp__half--pride { border-left: 0; padding-left: 0; border-top: 2px solid var(--fill); padding-top: 26px; }
}

/* ============================================================
   SOLUTIONS INDEX (2026-08-18)
   The landing surface for the Solutions nav item. Two axes, then the same spine every variant carries.
   ⚠️ NO data-variant ON <body> HERE. The index belongs to no single ICP, so it takes the brand accent;
   the variant tokens are scoped to the CARDS instead, where each one previews the colour of the page it
   leads to. Three decorative hues that did not match their destinations would be worse than none.
   ============================================================ */
.sol-hero--index { padding-bottom: 56px; }
.sol-hero--index .sol-eyebrow { color: var(--accent); }

.sol-axis { padding: 84px 0; border-top: 1px solid var(--border); }
.sol-axis__label { margin: 0 0 12px; font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--text-muted); }

.sol-cards { margin-top: 34px; display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px; }
.sol-card {
  display: flex; flex-direction: column; gap: 10px;
  padding: 26px 24px 22px;
  border: 1px solid var(--border);
  /* The tint is the only thing that differs between the three, and it is deliberately restrained:
     a 3px top rule and the link colour. A fully-tinted card would put --fill behind text, which is
     exactly what the three-token split exists to prevent. */
  border-top: 3px solid var(--fill);
  border-radius: 14px;
  background: var(--bg-surface);
  transition: transform 200ms var(--ease-smooth), border-color 200ms var(--ease-smooth);
}
.sol-card:hover { transform: translateY(-3px); border-color: color-mix(in srgb, var(--fill) 45%, var(--border)); }
/* ⚠️ The whole card is one <a>, so the sitewide link underline lands on EVERY line inside it: the
   heading, the description and the go-label all struck through with a rule. Killing it on the anchor
   and re-declaring the colours is what turns a link into a card. */
.sol-card, .sol-card:hover, .sol-needs a, .sol-needs a:hover { text-decoration: none; }
.sol-card__k { font-size: var(--fs-h3); letter-spacing: -0.02em; font-weight: 650; color: var(--text); }
.sol-card__d { margin: 0; font-size: 15px; line-height: 1.6; color: var(--text-muted); flex: 1; text-wrap: pretty; }
.sol-card__go { font-family: var(--mono); font-size: 11px; letter-spacing: 0.07em; text-transform: uppercase;
  color: var(--ink); }

.sol-needs { margin: 30px 0 0; padding: 0; list-style: none; border-top: 1px solid var(--border); }
.sol-needs li { border-bottom: 1px solid var(--border); }
.sol-needs a { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 20px; padding: 22px 4px;
  transition: padding-left 200ms var(--ease-smooth), background-color 200ms var(--ease-smooth); }
.sol-needs a:hover { padding-left: 14px; background: var(--bg-surface); }
.sol-needs b { flex: none; min-width: 300px; font-size: 17.5px; letter-spacing: -0.015em; color: var(--text); }
.sol-needs span { flex: 1; min-width: 260px; font-size: 15px; line-height: 1.6; color: var(--text-muted);
  text-wrap: pretty; }

@media (max-width: 720px) {
  .sol-hero--index { padding-bottom: 36px; }
  .sol-axis { padding: 58px 0; }
  .sol-needs b { min-width: 0; }
  .sol-needs a { gap: 4px; }
}
