/*
 * Shared layout for the Product / Product details / Who we serve /
 * About / Contact page templates. Hand-authored translation of the
 * design export's own React inline `style={{}}` values (there are no
 * named CSS classes for these components in the source — unlike
 * landing.css's eco-home-* Home components) into real CSS, using this
 * theme's tokens (--eco-*, --radius-*, --shadow-*, --text-*) the same
 * way landing.css does. Enqueued on every Public page except Home
 * (functions.php) — .eco-home-section/__inner, .eco-home-eyebrow/
 * display/lede, .eco-home-value__*, .ec-* utilities and .eco-btn* all
 * come from landing.css, loaded first.
 */

/* Smooth-scrolls every #anchor jump on these pages (Who we serve's
   subnav, Scoring/Reporting's "See a sample score" → #output, etc.) —
   scoped to this stylesheet (not global) since it's only enqueued on
   these public pages, not Home. Respects prefers-reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

/* ---------- Product page intro — was a full navy "statement hero"
   (radial glow + grid-mesh, white text) sized like a landing-page
   hero; now a plain compact intro on the page's normal white
   background with normal ink/indigo text, since the 3 product cards
   right below it already carry the page's visual weight — this is
   just a heading, not a hero. Only page-product.php uses this
   section; .eco-pub-hero__notes is a separate reused child class
   (also nested inside .eco-pub-statement__inner elsewhere) so it's
   untouched here. */
.eco-pub-hero { padding: 56px 0 16px; }
.eco-pub-hero--tight-bottom { padding-bottom: 8px; }
.eco-pub-hero__inner { max-width: 1440px; margin: 0 auto; padding: 0 40px; }
.eco-pub-hero .eco-home-display { max-width: 760px; }
.eco-pub-hero .eco-home-lede { max-width: 620px; }
.eco-pub-hero__notes { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 22px; }

/* ---------- Who we serve: cinematic full-bleed hero (MSCI-editorial
   layout rhythm — msci.com/discover-msci/artificial-intelligence) —
   left-aligned text sitting low on the image, like the reference.
   Real photo supplied by the client (assets/images/serve-hero-bg.webp,
   converted from their own downloaded source at q80) — a dual overlay
   (darker on the left where the text sits + darker toward the bottom)
   keeps the white text legible against the photo's bright colors while
   still letting it show through on the right. */
.eco-pub-serve-hero { position: relative; min-height: 620px; display: flex; align-items: flex-end; overflow: hidden; background: var(--eco-indigo); }
.eco-pub-serve-hero__bg {
  position: absolute; inset: 0; pointer-events: none;
  background-image: url("../images/serve-hero-bg.webp");
  background-size: cover;
  background-position: center;
}
.eco-pub-serve-hero__bg::after {
  content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(90deg, rgba(8, 6, 30, .8) 0%, rgba(8, 6, 30, .35) 45%, rgba(8, 6, 30, .12) 70%),
    linear-gradient(180deg, rgba(8, 6, 30, .05) 0%, rgba(8, 6, 30, .5) 60%, rgba(8, 6, 30, .85) 100%);
}
/* Who we serve detail pages (SMEs/Funds/Banks): same real photo as
   the parent /who-we-serve/ hero, reused with a different color wash
   per audience instead of 3 separate images (client doesn't have 3
   distinct photos yet) — differentiates the 3 pages without
   fabricating imagery. */
.eco-pub-serve-hero--smes .eco-pub-serve-hero__bg::after {
  background:
    linear-gradient(90deg, rgba(8, 10, 42, .82) 0%, rgba(8, 10, 42, .35) 45%, rgba(8, 10, 42, .12) 70%),
    linear-gradient(180deg, rgba(8, 10, 42, .05) 0%, rgba(8, 10, 42, .5) 60%, rgba(8, 10, 42, .85) 100%);
}
.eco-pub-serve-hero--funds .eco-pub-serve-hero__bg::after {
  background:
    linear-gradient(90deg, rgba(6, 30, 22, .82) 0%, rgba(6, 30, 22, .35) 45%, rgba(6, 30, 22, .12) 70%),
    linear-gradient(180deg, rgba(6, 30, 22, .05) 0%, rgba(6, 30, 22, .5) 60%, rgba(6, 30, 22, .85) 100%);
}
.eco-pub-serve-hero--banks .eco-pub-serve-hero__bg::after {
  background:
    linear-gradient(90deg, rgba(30, 8, 36, .82) 0%, rgba(30, 8, 36, .35) 45%, rgba(30, 8, 36, .12) 70%),
    linear-gradient(180deg, rgba(30, 8, 36, .05) 0%, rgba(30, 8, 36, .5) 60%, rgba(30, 8, 36, .85) 100%);
}
.eco-pub-serve-hero__inner { position: relative; z-index: 1; max-width: 1440px; width: 100%; margin: 0 auto; padding: 210px 40px 72px; text-align: left; }
/* Breadcrumb — was a plain underlined text link that read too close to
   the photo's own bright tones; a frosted pill (same glass recipe as
   the header's user-menu trigger) plus a "back" arrow gives it a
   fixed-contrast surface regardless of what's behind it, and reads
   immediately as a way back up a level. */
.eco-pub-serve-hero__crumb { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 700; color: var(--eco-white); text-decoration: none; margin-bottom: 24px; padding: 9px 18px 9px 14px; border-radius: var(--radius-pill); background: rgba(255, 255, 255, .14); border: 1px solid rgba(255, 255, 255, .3); backdrop-filter: blur(10px) saturate(160%); -webkit-backdrop-filter: blur(10px) saturate(160%); transition: background .18s ease, border-color .18s ease, transform .18s ease; }
.eco-pub-serve-hero__crumb-icon { display: inline-flex; transform: rotate(180deg); }
.eco-pub-serve-hero__crumb:hover { background: rgba(255, 255, 255, .24); border-color: rgba(255, 255, 255, .48); transform: translateX(-2px); }
.eco-pub-serve-hero__inner .eco-home-display { max-width: 780px; margin: 16px 0 18px; }
.eco-pub-serve-hero__inner .eco-home-lede { max-width: 560px; margin: 0; }
.eco-pub-serve-hero__ctas { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 32px; }
.eco-pub-serve-hero__ctas .eco-btn--ghost { border: 2px solid rgba(255, 255, 255, .3); color: var(--eco-white); }
.eco-pub-serve-hero__ctas .eco-btn--ghost:hover { background: rgba(255, 255, 255, .08); }
@media (max-width: 820px) {
  .eco-pub-serve-hero { min-height: 520px; }
  .eco-pub-serve-hero__inner { padding: 150px 24px 56px; }
}

/* ---------- Who we serve: secondary anchor nav under the hero — same
   "jump to a section" role MSCI's own sub-nav bar plays. Deliberately
   NOT position:sticky (the audience sidebar's sticky already caused a
   mobile overlap bug once this session — not worth risking a second
   sticky element). */
.eco-pub-serve-subnav { background: var(--eco-slate-50); border-bottom: 1px solid var(--border-subtle); }
.eco-pub-serve-subnav__inner { max-width: 1440px; margin: 0 auto; padding: 0 40px; display: flex; align-items: center; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
.eco-pub-serve-subnav__links { display: flex; gap: 28px; flex-wrap: wrap; }
.eco-pub-serve-subnav__links a { display: inline-block; padding: 20px 0; font-size: 15.5px; font-weight: 700; color: var(--text-body); text-decoration: none; }
.eco-pub-serve-subnav__links a:hover { color: var(--eco-blue); }
@media (max-width: 820px) {
  .eco-pub-serve-subnav__inner { padding: 12px 24px; }
  .eco-pub-serve-subnav__links { gap: 18px; }
  .eco-pub-serve-subnav__links a { padding: 6px 0; }
}

/* ---------- Who we serve: "Where do you fit?" 3-col icon/headline/body
   row — left-aligned columns on plain white, matching MSCI's own
   opener-row pattern (icon, bold headline, short body). ---------- */
.eco-pub-serve-intro { display: grid; grid-template-columns: repeat(3, 1fr); gap: 40px; margin-top: 40px; }
.eco-pub-serve-intro__icon { display: flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 10px; background: var(--eco-blue-50); color: var(--eco-blue); margin-bottom: 18px; }
.eco-pub-serve-intro__t { font-family: var(--font-display); font-weight: 800; font-size: 23px; color: var(--eco-ink); margin: 0 0 10px; }
.eco-pub-serve-intro__d { font-size: 16.5px; line-height: 1.6; color: var(--text-muted); }
.eco-pub-serve-intro__link { display: inline-block; margin-top: 14px; font-size: 15.5px; font-weight: 700; color: var(--eco-blue); text-decoration: none; }
.eco-pub-serve-intro__link:hover { text-decoration: underline; }
@media (max-width: 820px) {
  .eco-pub-serve-intro { grid-template-columns: 1fr; gap: 32px; }
}

/* ---------- Who we serve: recurring two-tone section-opener heading —
   bold brand color + a lighter tint of the same color directly below,
   the signature MSCI repeats on every major section ("AI in action /
   Purpose-built for..."). ---------- */
.eco-pub-split-heading { font-family: var(--font-display); font-weight: 800; line-height: 1.1; }
.eco-pub-split-heading__hi,
.eco-pub-split-heading__lo { display: block; font-size: 36px; }
.eco-pub-split-heading__hi { color: var(--eco-blue); }
.eco-pub-split-heading__lo { color: var(--eco-blue-100); }
@media (max-width: 820px) {
  .eco-pub-split-heading__hi,
  .eco-pub-split-heading__lo { font-size: 28px; }
}

/* ---------- About: one continuous soft gradient behind all 3 numbered
   sections, instead of each section painting its own flat
   background-color + border-top/bottom seam (.eco-home-section's own
   background is switched off inside this wrapper so the gradient
   shows through underneath every section in it). A faint indigo wash
   up top (echoes the removed hero's brand color) settles to white
   through the middle and warms very slightly toward green by the
   partners/press section at the bottom — one seamless surface. ---------- */
.eco-pub-flow { background: linear-gradient(180deg, #F1F3FD 0%, #FFFFFF 26%, #FFFFFF 62%, #F3FBEA 100%); }
.eco-pub-flow .eco-home-section { background: transparent; padding: 72px 0; }

/* ---------- About "01 — What is EcoChain?" / Contact hero — a
   full-width centered statement instead of a flat navy hero band or
   the eyebrow/label-column split used elsewhere. Doubles as each
   page's opener (--lead), so it carries a touch more top space and a
   slightly bigger, tighter headline. Shared between About and Contact
   on purpose — same "page opener" panel language on both. ---------- */
.eco-pub-statement__inner { max-width: 900px; margin: 0 auto; text-align: center; }
.eco-pub-statement__title { font-size: 47px; margin: 16px auto 26px; max-width: 660px; }
.eco-pub-statement__body { display: flex; flex-direction: column; gap: 16px; max-width: 600px; margin: 0 auto; }
.eco-pub-statement__body .eco-home-lede { max-width: none; }
.eco-pub-statement__inner .eco-pub-hero__notes { justify-content: center; margin-top: 22px; }
.eco-home-section.eco-pub-statement--lead { padding: 44px 0 52px; }
.eco-pub-statement--lead .eco-pub-statement__title { font-size: 53px; line-height: 1.08; }
@media (max-width: 820px) {
  .eco-pub-statement__title { font-size: 34px; }
  .eco-home-section.eco-pub-statement--lead { padding: 28px 0 52px; }
  .eco-pub-statement--lead .eco-pub-statement__title { font-size: 36px; }
}

/* The "01" panel gets the same treatment as .eco-home-serve3's card —
   soft green corner glow + faint grid mesh + film-grain noise — so the
   page's opening still carries real crafted depth now that the flat
   navy hero is gone, using the exact same gradient/mesh/noise recipe
   (not a new visual language). */
.eco-pub-lead-panel { position: relative; overflow: hidden; border-radius: 28px; background: radial-gradient(120% 115% at 92% 100%, rgba(188, 237, 9, .85), rgba(188, 237, 9, .35) 45%, rgba(188, 237, 9, .08) 70%, transparent 85%), var(--eco-white); padding: 116px 40px; }
.eco-pub-lead-panel::before { content: ''; position: absolute; inset: 0; pointer-events: none; background-image: linear-gradient(rgba(255, 255, 255, .75) 1px, transparent 1px), linear-gradient(90deg, rgba(255, 255, 255, .75) 1px, transparent 1px); background-size: 80px 80px; mask-image: radial-gradient(110% 100% at 80% 95%, #000 25%, rgba(0, 0, 0, .4) 65%, transparent 92%); -webkit-mask-image: radial-gradient(110% 100% at 80% 95%, #000 25%, rgba(0, 0, 0, .4) 65%, transparent 92%); }
.eco-pub-lead-panel::after { content: ''; position: absolute; inset: 0; opacity: .22; mix-blend-mode: multiply; pointer-events: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%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"); }
.eco-pub-lead-panel > * { position: relative; z-index: 1; }
@media (max-width: 820px) {
  .eco-pub-lead-panel { padding: 48px 24px; border-radius: 20px; }
}

/* ---------- Generic card — soft elevation instead of a flat border,
   using the theme's own --shadow tokens (defined in tokens/effects.css,
   previously unused anywhere) for the Stripe/Mercury-style "lifted
   card" look. ---------- */
.eco-pub-card { background: var(--eco-white); border: 1px solid var(--border-subtle); border-radius: var(--radius-lg, 16px); padding: 28px; box-shadow: var(--shadow-sm); }
.eco-pub-card--tint { background: var(--eco-slate-50); box-shadow: none; }
/* Who we serve: "How EcoChain helps" card when it sits on an already-
   dark .eco-pub-band--dark section — the card's usual solid indigo
   fill (still used on light sections) would disappear into a
   same-color section background, so this translucent variant takes
   over instead, same recipe as .eco-pub-imgslot--dark. */
.eco-pub-card--dark-panel { background: rgba(255, 255, 255, .06); border-color: rgba(255, 255, 255, .14); box-shadow: none; }

/* ---------- Contact: form card highlighted with the same
   gradient+noise language as .eco-pub-lead-panel (no grid mesh here —
   busy lines behind form fields would fight the inputs), so the card
   holding the actual conversion action stands out instead of reading
   as a plain white box. ---------- */
.eco-pub-card--form { position: relative; overflow: hidden; border-color: var(--eco-blue-100); background: linear-gradient(135deg, rgba(47, 82, 224, .07), rgba(188, 237, 9, .1)), var(--eco-white); box-shadow: var(--shadow-md); }
.eco-pub-card--form::after { content: ''; position: absolute; inset: 0; opacity: .16; mix-blend-mode: multiply; pointer-events: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%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"); }
.eco-pub-card--form > * { position: relative; z-index: 1; }

/* ---------- About: "03 — The People Behind EcoChain" — the two real
   partner orgs as plain side-by-side cards (no connector line/equation
   symbols, no third "result" node — just Impact Link and MicroFund),
   each fronted by its actual logo. Both supplied logo files are
   white/light artwork made for a dark plate, so .eco-pub-partners__logo
   is a dark indigo panel rather than sitting directly on the white
   card. ---------- */
.eco-pub-partners { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 44px; }
.eco-pub-partners__card { display: block; background: var(--eco-white); border: 1px solid var(--border-subtle); border-radius: var(--radius-lg, 16px); overflow: hidden; box-shadow: var(--shadow-sm); text-decoration: none; color: inherit; transition: transform .2s var(--ease-out, ease), box-shadow .2s var(--ease-out, ease), border-color .2s var(--ease-out, ease); }
.eco-pub-partners__card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--eco-blue-100); }
.eco-pub-partners__logo { display: flex; align-items: center; justify-content: center; padding: 36px; background: linear-gradient(135deg, var(--eco-indigo), var(--eco-indigo-800)); }
.eco-pub-partners__logo img { max-width: 200px; max-height: 48px; width: auto; height: auto; }
.eco-pub-partners__body { padding: 26px 28px 30px; text-align: center; }
.eco-pub-partners__name { font-size: 22px; font-weight: 700; color: var(--eco-ink); margin-bottom: 10px; }
.eco-pub-partners__d { font-size: 17.5px; line-height: 1.6; color: var(--text-muted); margin: 0 auto; max-width: 320px; }
@media (max-width: 820px) {
  .eco-pub-partners { grid-template-columns: 1fr; }
}

/* ---------- About: press/news strip — real outbound links, verified
   titles (not guessed from the URL), each fronted by the real launch
   photo (the only press image supplied — used for both cards, which
   is accurate since both articles cover the same launch). ---------- */
.eco-pub-press { margin-top: 52px; padding-top: 36px; }
.eco-pub-press::before { content: ''; display: block; height: 1px; margin-bottom: 36px; background: linear-gradient(90deg, transparent, var(--border-subtle) 15%, var(--border-subtle) 85%, transparent); }
/* Small pill "highlight" leading into a bigger, bolder intro line —
   same eyebrow-pill language as the press-card source tags, giving the
   line more presence than a plain muted paragraph. */
.eco-pub-press__tag { display: table; margin: 0 auto 14px; padding: 6px 14px; border-radius: var(--radius-pill); background: var(--eco-blue-50); color: var(--eco-blue); font-size: 13px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.eco-pub-press__intro { font-family: var(--font-display); font-size: 28px; font-weight: 700; line-height: 1.35; letter-spacing: -.005em; color: var(--eco-ink); max-width: 620px; margin: 0 auto 32px; text-align: center; }
.eco-pub-press__list { display: grid; grid-template-columns: 1fr 1fr; gap: 3rem; align-items: stretch; }

/* Editorial media-card redesign — taller photo with a dark gradient
   wash, a bold blue eyebrow instead of a muted caption, a bigger
   display-font headline, and the CTA promoted to a real outlined pill
   button — reads as a featured press clipping, not a plain link card. */
.eco-pub-press__item { display: flex; flex-direction: column; background: var(--eco-white); border: 1px solid var(--border-subtle); border-radius: var(--radius-lg, 16px); overflow: hidden; text-decoration: none; box-shadow: var(--shadow-md); transition: transform .25s var(--ease-out, ease), box-shadow .25s var(--ease-out, ease), border-color .25s var(--ease-out, ease); }
.eco-pub-press__item:hover { box-shadow: var(--shadow-lg); border-color: var(--eco-blue-100); }
.eco-pub-press__thumb { position: relative; display: block; aspect-ratio: 4 / 3; overflow: hidden; background: var(--eco-slate-100); }
.eco-pub-press__thumb img { width: 100%; height: 100%; object-fit: cover; object-position: center 20%; transition: transform .4s var(--ease-out, ease); }
.eco-pub-press__item:hover .eco-pub-press__thumb img { transform: scale(1.06); }
.eco-pub-press__thumb::after { content: ''; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(14, 12, 64, 0) 55%, rgba(14, 12, 64, .5) 100%); pointer-events: none; }
/* flex column + a flexible spacer before the CTA (below) so "Read the
   article" sits at the same bottom row in both cards regardless of how
   many lines the title wraps to, instead of trailing right under a
   short title while the other card's button sits lower. */
.eco-pub-press__body { display: flex; flex-direction: column; flex: 1; padding: 24px 26px 28px; }
.eco-pub-press__source { display: block; font-size: 15px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase; color: var(--eco-blue); margin-bottom: 12px; }
.eco-pub-press__title { display: block; font-family: var(--font-display); font-size: var(--text-3xl); font-weight: 800; letter-spacing: -.01em; color: var(--eco-ink); line-height: 1.25; }
.eco-pub-press__spacer { flex: 1 0 20px; }
.eco-pub-press__cta { display: inline-flex; align-items: center; gap: 8px; align-self: flex-start; font-size: 16.5px; font-weight: 700; color: var(--eco-blue); border: 1.5px solid var(--eco-blue-100); border-radius: var(--radius-pill); padding: 9px 16px; transition: background .2s var(--ease-out, ease), color .2s var(--ease-out, ease), border-color .2s var(--ease-out, ease); }
.eco-pub-press__item:hover .eco-pub-press__cta { background: var(--eco-blue); color: var(--eco-white); border-color: var(--eco-blue); }
@media (max-width: 820px) {
  .eco-pub-press__list { grid-template-columns: 1fr; }
}

/* ---------- About: scroll-reveal — reuses the sitewide [data-reveal]
   fade-up mechanism (landing.css/landing.js, already loaded on every
   Public page) rather than a new animation system; grouped items get
   a small transition-delay stagger via nth-child so they cascade in
   instead of all fading in at once. ---------- */
.eco-home-value__item[data-reveal]:nth-child(2) { transition-delay: .08s; }
.eco-home-value__item[data-reveal]:nth-child(3) { transition-delay: .16s; }
.eco-home-value__item[data-reveal]:nth-child(4) { transition-delay: .24s; }
.eco-pub-partners__card[data-reveal]:nth-child(2) { transition-delay: .12s; }
.eco-pub-press__item[data-reveal]:nth-child(2) { transition-delay: .12s; }

/* ---------- Contact: form ---------- */
.eco-pub-form { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.eco-pub-form__field--full { grid-column: 1 / -1; }
.eco-pub-form__label { display: block; font-size: 15px; font-weight: 600; color: var(--text-body); margin-bottom: 6px; }
.eco-pub-form__field input,
.eco-pub-form__field textarea {
  width: 100%; box-sizing: border-box; font: inherit; font-size: 16.5px; color: var(--eco-ink);
  border: 1px solid var(--border-default); border-radius: var(--radius-sm, 8px); padding: 11px 13px;
  background: var(--eco-white);
}
.eco-pub-form__field input:focus,
.eco-pub-form__field textarea:focus { outline: none; border-color: var(--eco-blue); box-shadow: var(--shadow-focus); }
.eco-pub-form__reasons { display: flex; flex-wrap: wrap; gap: 8px; }
.eco-pub-form__reason { font-size: 15px; font-weight: 600; padding: 8px 14px; border-radius: var(--radius-pill); border: 1px solid var(--border-default); background: var(--eco-white); color: var(--text-body); cursor: pointer; }
.eco-pub-form__reason:hover { border-color: var(--eco-blue); }
.eco-pub-form__reason.is-selected { background: var(--eco-indigo); border-color: var(--eco-indigo); color: var(--eco-white); }
.eco-pub-form__foot { grid-column: 1 / -1; display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-top: 4px; flex-wrap: wrap; }
.eco-pub-form__foot-note { font-size: 13.5px; color: var(--text-muted); margin: 0; }
.eco-pub-form__success { text-align: center; padding: 40px 20px; }
.eco-pub-form__success-badge { display: inline-grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; background: var(--eco-green); color: var(--eco-indigo); font-weight: 800; margin-bottom: 16px; }
.eco-pub-form__success h3 { font-family: var(--font-display); font-size: 26px; font-weight: 800; color: var(--eco-ink); margin: 0 0 6px; }
.eco-pub-form__success p { color: var(--text-muted); margin: 0 0 20px; }

/* Contact: native Bricks `form` element styling (replaces the old
   hand-coded .eco-pub-form markup) — Bricks renders bare .form-group
   wrappers with no classes on the inputs themselves, so every rule here
   targets that native structure directly, reusing the same tokens the
   old .eco-pub-form__* rules used above for visual continuity. */
.eco-contact-form { display: flex; flex-wrap: wrap; gap: 18px; }
.eco-contact-form .form-group { box-sizing: border-box; width: 100%; }
.eco-contact-form .form-group > label,
.eco-contact-form .form-group > .label { display: block; font-size: 15px; font-weight: 600; letter-spacing: normal; text-transform: none; color: var(--text-body); margin-bottom: 6px; }
.eco-contact-form .form-group input[type="text"],
.eco-contact-form .form-group input[type="email"],
.eco-contact-form .form-group textarea {
  width: 100%; box-sizing: border-box; font: inherit; font-size: 16.5px; color: var(--eco-ink);
  border: 1px solid var(--border-default); border-radius: var(--radius-sm, 8px); padding: 11px 13px;
  background: var(--eco-white);
}
.eco-contact-form .form-group input[type="text"]:focus,
.eco-contact-form .form-group input[type="email"]:focus,
.eco-contact-form .form-group textarea:focus { outline: none; border-color: var(--eco-blue); box-shadow: var(--shadow-focus); }
/* Topic picker (native checkbox group) restyled as pill buttons, same
   look as the old hand-rolled .eco-pub-form__reason buttons. */
.eco-contact-form .options-wrapper { display: flex; flex-wrap: wrap; gap: 8px; list-style: none; margin: 0; padding: 0; }
.eco-contact-form .options-wrapper li { margin: 0; }
.eco-contact-form .options-wrapper input[type="checkbox"] { position: absolute; opacity: 0; width: 1px; height: 1px; }
.eco-contact-form .options-wrapper label {
  display: inline-block; font-size: 15px; font-weight: 600; padding: 8px 14px; border-radius: var(--radius-pill);
  border: 1px solid var(--border-default); background: var(--eco-white); color: var(--text-body); cursor: pointer;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.eco-contact-form .options-wrapper label:hover { border-color: var(--eco-blue); }
.eco-contact-form .options-wrapper input[type="checkbox"]:checked + label { background: var(--eco-indigo); border-color: var(--eco-indigo); color: var(--eco-white); }
.eco-contact-form .options-wrapper input[type="checkbox"]:focus-visible + label { box-shadow: var(--shadow-focus); }
.eco-contact-form .submit-button-wrapper {
  display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-top: 4px; flex-wrap: wrap;
}
.eco-contact-form .bricks-button {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; font-family: var(--font-body);
  font-weight: 700; border-radius: var(--radius-pill); border: var(--border-width-strong) solid transparent;
  cursor: pointer; text-decoration: none; padding: 11px 22px; font-size: var(--text-sm);
  background: var(--action-primary); color: var(--action-primary-text);
}
.eco-contact-form .bricks-button:hover { filter: brightness(0.94); }
@media (max-width: 640px) {
  .eco-contact-form .form-group { width: 100% !important; }
}

/* ---------- Contact: page grid (form + sidebar) ---------- */
/* Contact-page-only: match the hero panel's own reduced padding
   (44px/52px) so both sections on this page share the same tighter
   rhythm instead of the hero being compact and this section still
   sitting at the sitewide default 104px. */
.eco-pub-section--tight { padding: 44px 0 52px; }
.eco-pub-contact-grid { display: grid; grid-template-columns: 1.6fr .65fr; gap: 40px; align-items: start; }
.eco-pub-sidebar { display: flex; flex-direction: column; gap: 20px; }
@media (max-width: 1080px) {
  .eco-pub-contact-grid { grid-template-columns: 1fr; }
}

/* ---------- Contact: "Direct channels" list — streamlined (was
   30px-heavier rows with a title + description line each, copied from
   the Product page's bigger link-row component); trimmed to just a
   title + CTA per row, tighter padding, real classes instead of
   one-off inline styles. ---------- */
.eco-pub-channels .eco-home-eyebrow { margin-bottom: 8px; }
.eco-pub-channels .ec-ovrow { padding: 10px 2px; gap: 10px; }
.eco-pub-channels .ec-ovrow__t { font-size: 15.5px; font-family: var(--font-body); font-weight: 700; letter-spacing: 0; }
.eco-pub-channels .ec-ovrow__a { font-size: 15px; }

/* ---------- Contact: office info card ---------- */
.eco-pub-office { font-size: 16.5px; line-height: 1.7; color: var(--text-body); }
.eco-pub-office__hours { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border-subtle); color: var(--text-muted); font-size: 15.5px; }

/* ---------- Product overview / Product details section band ---------- */
.eco-pub-band { padding: 96px 0; }
.eco-pub-band--dark { background: var(--eco-indigo); color: var(--eco-white); }
.eco-pub-band--tint { background: var(--eco-slate-50); }
.eco-pub-band__cols { display: grid; grid-template-columns: 340px 1fr; gap: 40px; }
.eco-pub-band__side-eyebrow { font-family: var(--font-display); font-weight: 800; font-size: 17px; color: var(--text-muted); }
.eco-pub-band--dark .eco-pub-band__side-eyebrow { color: rgba(255, 255, 255, 0.5); }
.eco-pub-band__side-title { font-family: var(--font-display); font-weight: 800; font-size: 43px; margin: 10px 0 8px; color: var(--eco-ink); }
.eco-pub-band--dark .eco-pub-band__side-title { color: var(--eco-white); }
.eco-pub-band__side-note { font-size: 15.5px; color: var(--text-muted); }
.eco-pub-band--dark .eco-pub-band__side-note { color: rgba(255, 255, 255, 0.55); }

/* ---------- Product overview: 3 stacked product cards — the 3 tracks
   (Scoring/Reporting/Match-making) used to be plain .eco-pub-band
   bands, each a different full-bleed background (white → navy →
   grey) running edge to edge with a hard seam where the next one
   started. Now each track is a .eco-pub-lead-panel — the same
   lime-glow-on-white recipe as Home's .eco-home-serve3 (also reused
   on About/Contact) — so all 3 share one consistent background
   instead of reading as 3 different kinds of card, with a visible
   gap between them on the page's own white background. */
.eco-pub-product-cards { display: flex; flex-direction: column; gap: 28px; padding: 72px 0 100px; }
.eco-pub-product-card.eco-pub-lead-panel { border: 1px solid var(--border-subtle); box-shadow: var(--shadow-sm); }
/* Content length differs a lot per track (Reporting's framework list
   vs. Match-making's one-liner); a shared min-height + vertically-
   centered content keeps them visually even without clipping or
   stretching whichever one has the most to say. Sized up from the
   first pass so each card carries more presence. */
.eco-pub-product-card.eco-pub-band { padding: 88px 64px; border-radius: 32px; min-height: 560px; display: flex; align-items: center; }
.eco-pub-product-card .eco-pub-band__cols { width: 100%; }
@media (max-width: 820px) {
  .eco-pub-product-cards { gap: 16px; padding: 48px 0 72px; }
  .eco-pub-product-card.eco-pub-band { padding: 44px 28px; border-radius: 20px; min-height: 0; }
}

/* ---------- Who we serve detail pages (SMEs/Funds/Banks): pain-point
   tiles ("02 — Your challenge") + solution checklist ("03 — How
   EcoChain helps") as real classes — this pattern previously lived as
   repeated inline styles on the old single /who-we-serve/ page; now
   that it's reused identically across 3 dedicated detail pages, it's
   worth a proper component instead of copy-pasted inline style="". ---------- */
.eco-pub-pain-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
/* Friendlier than a flat grey box: a card with an icon badge (same
   orange-tint chip recipe as .eco-home-panel__icon-chip--orange on
   Home) so each pain point reads as a distinct, slightly-illustrated
   point rather than a wall of text, plus a hover lift for a touch of
   interactivity. */
.eco-pub-pain-tile { display: flex; align-items: flex-start; gap: 14px; background: var(--eco-white); border: 1px solid var(--border-subtle); border-radius: var(--radius-md, 14px); padding: 20px 22px; box-shadow: var(--shadow-sm); transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease; }
.eco-pub-pain-tile:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: rgba(241, 115, 0, .35); }
.eco-pub-pain-tile__icon { flex: none; width: 36px; height: 36px; border-radius: 50%; background: rgba(241, 115, 0, .12); color: var(--eco-orange); display: grid; place-items: center; }
.eco-pub-pain-tile__t { font-size: 15.5px; font-weight: 600; line-height: 1.45; color: var(--text-body); padding-top: 6px; }
.eco-pub-sol-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.eco-pub-sol-item { display: flex; gap: 14px; }
.eco-pub-sol-item__icon { flex: none; width: 28px; height: 28px; border-radius: 50%; background: var(--eco-green); color: var(--eco-indigo); display: grid; place-items: center; }
.eco-pub-sol-item__t { font-size: 16px; font-weight: 700; color: var(--eco-white); }
.eco-pub-sol-item__d { font-size: 14px; color: rgba(255, 255, 255, .65); margin: 5px 0 0; line-height: 1.5; }
@media (max-width: 640px) {
  .eco-pub-pain-grid { grid-template-columns: 1fr; }
  .eco-pub-sol-grid { grid-template-columns: 1fr; }
}

/* ---------- Who we serve detail: "Relevant solutions" band — was a
   flat .eco-home-section--tint slab with the link list stacked under
   the heading; now a full-bleed photo section (reusing the Scoring
   page's finance photo via the same reuse-with-wash approach as
   .eco-pub-serve-hero__bg — the client doesn't have a dedicated shot)
   with the link list moved beside the heading instead of under it, so
   the two read as one "here's where to go next" pairing. ---------- */
.eco-pub-relsol { position: relative; padding: 100px 0; overflow: hidden; background-color: var(--eco-indigo); }
.eco-pub-relsol__bg { position: absolute; inset: 0; pointer-events: none; background-image: url("../images/scoring-finance.webp"); background-size: cover; background-position: center; }
.eco-pub-relsol__bg::after { content: ''; position: absolute; inset: 0; background: linear-gradient(100deg, rgba(8, 6, 30, .92) 0%, rgba(8, 6, 30, .74) 48%, rgba(8, 6, 30, .55) 100%); }
.eco-pub-relsol__inner { position: relative; z-index: 1; display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center; }
@media (max-width: 820px) {
  .eco-pub-relsol { padding: 72px 0; }
  .eco-pub-relsol__inner { grid-template-columns: 1fr; gap: 28px; }
}

@media (max-width: 820px) {
  /* Restack (num+title+value on one line, track bar full-width below)
   * instead of squeezing 4 fixed columns into a narrow card — the
   * label text was wrapping to 2-3 lines with the vertically-centered
   * track bar crossing through the middle of it. Unconditional on the
   * base component (not scoped to one parent) since .eco-pub-dim-list
   * now shows up in more than one narrow-card context (Scoring page's
   * own hero use is full-width and unaffected by this). */
  .eco-pub-dim-list { padding: 8px 14px 12px; }
  .eco-pub-dim-row {
    grid-template-columns: 16px 1fr auto; grid-template-areas: "num t val" "track track track";
    row-gap: 8px; column-gap: 10px; padding: 14px 0;
  }
  .eco-pub-dim-row > * { min-width: 0; }
  .eco-pub-dim-row__num { grid-area: num; }
  .eco-pub-dim-row__t { grid-area: t; font-size: 16px; }
  .eco-pub-dim-row__val { grid-area: val; font-size: 17px; }
  .eco-pub-dim-row__track { grid-area: track; }
}

/* ---------- Who we serve: stat band — boxed cards (light gray rounded
   rect, left-aligned number + label), matching MSCI's own stat-card
   treatment instead of bare centered numerals. Values are facts already
   established elsewhere on the site (audience count, Scoring's
   dimension count, Reporting's framework count), not fabricated
   business metrics. ---------- */
.eco-pub-stat-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.eco-pub-stat-card { background: var(--eco-slate-50); border-radius: var(--radius-lg, 16px); padding: 28px 24px; }
.eco-pub-stat-card__num { font-family: var(--font-display); font-weight: 800; font-size: 34px; color: var(--eco-ink); }
.eco-pub-stat-card__label { margin-top: 8px; font-size: 16px; color: var(--text-muted); }
@media (max-width: 820px) {
  .eco-pub-stat-row { grid-template-columns: 1fr; gap: 16px; }
}

/* ---------- Who we serve: FAQ accordion — native <details>/<summary>,
   no JS. Chevron rotates via the [open] attribute selector. Was
   capped at 760px and centered, reading small/timid against the
   section's full 1140px container; now spans the full container
   width with noticeably bigger question text, so it carries as much
   visual weight as the sections above it — the answer text keeps its
   own narrower max-width so lines don't run edge-to-edge at 1140px. */
.eco-pub-faq { display: flex; flex-direction: column; }
.eco-pub-faq__item { border-top: 1px solid var(--border-subtle); }
.eco-pub-faq__item:last-child { border-bottom: 1px solid var(--border-subtle); }
.eco-pub-faq__q { display: flex; align-items: center; justify-content: space-between; gap: 24px; padding: 30px 4px; cursor: pointer; list-style: none; font-family: var(--font-display); font-weight: 700; font-size: 26px; line-height: 1.3; color: var(--eco-ink); }
.eco-pub-faq__q::-webkit-details-marker { display: none; }
.eco-pub-faq__icon { flex: none; color: var(--text-muted); transition: transform .2s; }
.eco-pub-faq__item[open] .eco-pub-faq__icon { transform: rotate(180deg); }
.eco-pub-faq__a { margin: 0 4px 30px; max-width: 780px; font-size: 17.5px; line-height: 1.65; color: var(--text-muted); }
@media (max-width: 640px) {
  .eco-pub-faq__q { font-size: 20px; padding: 22px 4px; }
}

/* ---------- Product Scoring: image-led redesign (Claude Design import,
   ui_kits/website/scoring.html) — shared container width (1240, matching
   the design's own MAXW) + labelled photo-placeholder boxes for every
   <image-slot> in the source. No photo assets exist in this theme for
   any of these (team/site visit, factory floor, analyst at work,
   diligence meeting) — same "clearly-marked slot, not fabricated"
   convention as the founder video placeholder on Home. */
.eco-pub-scoring-inner { max-width: 1240px; margin: 0 auto; padding: 0 40px; }
/* No position:relative here on purpose — it isn't needed (no
   absolutely-positioned children/pseudo-elements) and would promote
   this box to a later CSS paint layer than its .eco-pub-scoring-hero__chip
   sibling on the mobile hero (where the chip becomes position:static
   and overlaps this box via a negative margin) — that mismatch was
   covering part of the chip's own text with this box, even though the
   chip comes later in the DOM. */
.eco-pub-imgslot { display: flex; align-items: center; justify-content: center; text-align: center; padding: 24px; overflow: hidden; border-radius: 18px; border: 1px solid var(--border-subtle); background-color: var(--eco-slate-50); background-image: repeating-linear-gradient(135deg, var(--eco-slate-100) 0 2px, transparent 2px 14px); }
.eco-pub-imgslot--dark { border: none; background-color: rgba(255, 255, 255, .06); background-image: repeating-linear-gradient(135deg, rgba(255, 255, 255, .08) 0 2px, transparent 2px 14px); }
.eco-pub-imgslot__label { max-width: 220px; font-size: 13px; font-weight: 600; color: var(--text-muted); }
.eco-pub-imgslot--dark .eco-pub-imgslot__label { color: rgba(255, 255, 255, .55); }
/* Filled slot — once a real photo replaces the dashed placeholder
   (Scoring page: hero/operations/analyst/finance), drop the dashed
   background/border and let the img cover the box, same recipe as
   .eco-pub-press__thumb img. */
.eco-pub-imgslot--photo { padding: 0; border: none; background: none; }
.eco-pub-imgslot--photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

.eco-pub-scoring-hero { background: var(--eco-white); padding: 72px 0 20px; }
.eco-pub-scoring-hero__chip { position: absolute; left: -28px; bottom: 38px; display: flex; align-items: center; gap: 18px; background: var(--eco-white); border: 1px solid var(--border-subtle); border-radius: 18px; padding: 20px 24px; box-shadow: 0 18px 44px -22px rgba(18, 15, 136, .35); }

/* "01 — What we measure": dimension rows (num · label · mini-bar ·
   value) instead of a card grid — matches the design's compact list. */
.eco-pub-dim-list { border: 1px solid var(--border-subtle); border-radius: 18px; padding: 12px 26px 18px; }
.eco-pub-dim-row { display: grid; grid-template-columns: 22px 1fr 120px 34px; align-items: center; gap: 16px; padding: 17px 0; border-top: 1px solid var(--border-subtle); }
.eco-pub-dim-row > * { min-width: 0; }
.eco-pub-dim-row:first-child { border-top: none; }
.eco-pub-dim-row__num { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; color: var(--text-muted); }
.eco-pub-dim-row__t { font-size: 18px; font-weight: 600; color: var(--eco-ink); }
.eco-pub-dim-row__track { display: block; height: 5px; border-radius: 3px; background: var(--eco-slate-100); }
.eco-pub-dim-row__fill { display: block; height: 100%; border-radius: 3px; }
.eco-pub-dim-row__val { font-family: var(--font-display); font-weight: 800; font-size: 19px; text-align: right; color: var(--eco-ink); }

/* "02 — How it works": dark rounded panel housing the steps + photo. */
.eco-pub-how-panel { background: var(--eco-indigo); color: var(--eco-white); border-radius: 26px; overflow: hidden; }

/* "05 — Start": left text / right stacked-buttons row instead of the
   shared .eco-pub-cta's centered-stack layout (Reporting keeps that
   default — this modifier is Scoring-only). Compound selector
   (.eco-pub-cta.eco-pub-cta--split) throughout so these reliably win
   over the base .eco-pub-cta rules regardless of source order —
   two single-class selectors of equal specificity previously left the
   winner up to file order, which is how the base rule's wider 64/56px
   padding silently overrode this block's own value. */
.eco-pub-cta.eco-pub-cta--split {
  text-align: left; display: flex; justify-content: space-between; align-items: center; gap: 40px; flex-wrap: wrap;
  padding: 40px 44px;
  /* Same glow-panel recipe as .eco-home-serve3 / .eco-pub-lead-panel
     (lime radial glow over white, masked grid mesh, film-grain noise)
     instead of a flat lime fill. */
  background: radial-gradient(120% 115% at 92% 100%, rgba(188, 237, 9, .85), rgba(188, 237, 9, .35) 45%, rgba(188, 237, 9, .08) 70%, transparent 85%), var(--eco-white);
  border: 1px solid var(--border-subtle);
}
.eco-pub-cta.eco-pub-cta--split::before {
  background-image: linear-gradient(rgba(255, 255, 255, .75) 1px, transparent 1px), linear-gradient(90deg, rgba(255, 255, 255, .75) 1px, transparent 1px);
  background-size: 80px 80px;
  background-position: right bottom;
  mask-image: radial-gradient(110% 100% at 80% 95%, #000 25%, rgba(0, 0, 0, .4) 65%, transparent 92%);
  -webkit-mask-image: radial-gradient(110% 100% at 80% 95%, #000 25%, rgba(0, 0, 0, .4) 65%, transparent 92%);
}
.eco-pub-cta.eco-pub-cta--split .eco-pub-cta__col { max-width: 560px; }
.eco-pub-cta.eco-pub-cta--split .eco-pub-cta__title { font-size: 47px; margin: 14px 0; }
.eco-pub-cta.eco-pub-cta--split .eco-pub-cta__lede { max-width: 460px; font-size: 18px; margin: 12px 0 0; }
.eco-pub-cta.eco-pub-cta--split .eco-pub-cta__ctas { justify-content: flex-start; flex-direction: column; }
.eco-pub-cta.eco-pub-cta--split .eco-btn--ghost { border-width: 2px; border-style: solid; color: var(--eco-indigo); border-color: rgba(18, 15, 136, .3); }

@media (max-width: 1080px) {
  .ec-hero2 { grid-template-columns: 1fr !important; gap: 36px !important; }
  .eco-pub-scoring-hero__chip { position: static !important; margin-top: -46px; margin-left: 16px; }
  .ec-radar { grid-template-columns: 1fr !important; justify-items: center; }
}

/* ---------- Product details: demo placeholder ---------- */
.eco-pub-demo {
  position: relative; aspect-ratio: 16 / 9; border-radius: var(--radius-lg, 16px); overflow: hidden; cursor: pointer;
  background-image: repeating-linear-gradient(135deg, var(--eco-slate-100) 0 2px, transparent 2px 14px);
  background-color: var(--eco-slate-50); border: 1px solid var(--border-subtle);
  display: flex; align-items: center; justify-content: center;
}
.eco-pub-demo__play {
  width: 56px; height: 56px; border-radius: 50%; background: var(--eco-green); color: var(--eco-indigo);
  display: grid; place-items: center; transition: transform .2s;
}
.eco-pub-demo:hover .eco-pub-demo__play { transform: scale(1.06); }
.eco-pub-demo__caption { position: absolute; left: 16px; bottom: 14px; font-size: 12px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); }

/* ---------- Product Reporting: "02 — What it covers" rows — same
   .eco-pub-dim-row num/title styling as Scoring's dimension list
   (__num, __t reused as-is), plus a description line since these
   items don't have a numeric score/bar to show instead. ---------- */
.eco-pub-cover-row { display: flex; gap: 16px; padding: 17px 0; border-top: 1px solid var(--border-subtle); }
.eco-pub-cover-row:first-child { border-top: none; }
.eco-pub-cover-row__d { margin: 4px 0 0; font-size: 15px; line-height: 1.5; color: var(--text-muted); }

/* ---------- Product Reporting: "04 — What you get" band — was a flat
   .eco-home-section on plain slate-50, which left the two UI cards
   floating on featureless grey. First pass here put a strong lime
   mid-tone over the textured photo and the two muddied into a
   blotchy yellow-green smear, so the wash now leans almost entirely
   on a clean brand-blue gradient (the section's own background, not
   a photo overlay) with the photo underneath at very low opacity —
   just enough texture to feel like more than a flat tint, not enough
   for its own color to fight the gradient. The "color" the client
   asked for now mostly lives in the cards themselves (gradient top
   bar, per-scope figure colors, colored card rails below). ---------- */
.eco-pub-report-band { position: relative; overflow: hidden; padding: 96px 0 104px; background: var(--eco-white); }
.eco-pub-report-band__bg { display: none; }
.eco-pub-report-band > .eco-pub-scoring-inner { position: relative; z-index: 1; }

/* Report page mock — a slim brand-gradient bar on top gives the card
   its own point of color instead of relying only on the section
   backdrop, and the shadow lifts it off the now-colorful band. */
.eco-pub-report-mock { position: relative; overflow: hidden; background: var(--eco-white); color: var(--eco-ink); border-radius: var(--radius-lg, 16px); padding: 26px 24px 24px; box-shadow: var(--shadow-md); }
.eco-pub-report-mock::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 5px; background: var(--eco-gradient); }
.eco-pub-report-mock__row { display: flex; justify-content: space-between; gap: 12px; padding: 10px 0; border-top: 1px solid var(--border-subtle); font-size: 15.5px; }
.eco-pub-report-mock__row:first-of-type { border-top: none; }
.eco-pub-report-mock__row strong { color: var(--eco-ink); }
.eco-pub-report-mock__row span:last-child { color: var(--text-muted); }
.eco-pub-metrics { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: 16px; }
/* Scope 1/2/3 color-coded (blue/green/orange) instead of uniform ink —
   a quick, colorful read of three distinct figures rather than a grey
   number block. */
.eco-pub-metrics__v { font-family: var(--font-display); font-weight: 800; font-size: 22px; }
.eco-pub-metrics > div:nth-child(1) .eco-pub-metrics__v { color: var(--eco-blue); }
.eco-pub-metrics > div:nth-child(2) .eco-pub-metrics__v { color: var(--eco-green-600); }
.eco-pub-metrics > div:nth-child(3) .eco-pub-metrics__v { color: var(--eco-orange); }
.eco-pub-metrics__u { font-size: 12px; color: var(--text-muted); }
/* Cards get a colored left rail (cycling brand colors) + shadow so
   they read as distinct, slightly playful items rather than identical
   grey-bordered boxes — same elevation as .eco-pub-report-mock so the
   two sit at the same visual weight on the colorful band. */
.eco-pub-report-cards { display: flex; flex-direction: column; gap: 14px; }
.eco-pub-report-cards__item { position: relative; background: var(--eco-white); border: 1px solid var(--border-subtle); border-left: 4px solid var(--eco-blue); border-radius: 14px; padding: 18px 20px 18px 22px; box-shadow: var(--shadow-sm); transition: transform .18s ease, box-shadow .18s ease; }
.eco-pub-report-cards__item:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.eco-pub-report-cards__item:nth-child(2) { border-left-color: var(--eco-green-600); }
.eco-pub-report-cards__item:nth-child(3) { border-left-color: var(--eco-orange); }
.eco-pub-report-cards__item:nth-child(4) { border-left-color: var(--eco-indigo); }
.eco-pub-report-cards__t { font-size: 16.5px; font-weight: 700; color: var(--eco-ink); }
.eco-pub-report-cards__d { margin: 6px 0 0; font-size: 15px; line-height: 1.5; color: var(--text-muted); }

/* ---------- Product details: lime ProductCta ---------- */
.eco-pub-cta {
  background: var(--eco-green); border-radius: var(--radius-xl, 32px); padding: 64px 56px; text-align: center;
  max-width: 1440px; margin: 0 auto; color: var(--eco-indigo);
}
.eco-pub-cta__eyebrow { font-size: 13px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; color: rgba(18, 15, 136, 0.6); }
.eco-pub-cta__title { font-family: var(--font-display); font-weight: 800; font-size: 47px; margin: 14px 0; color: var(--eco-indigo); }
.eco-pub-cta__lede { font-size: 18px; color: rgba(18, 15, 136, 0.72); max-width: 560px; margin: 0 auto 28px; }
.eco-pub-cta__ctas { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }
.eco-pub-cta .eco-btn--ghost { border-color: var(--eco-indigo); color: var(--eco-indigo); }
/* Grid lines + noise, same techniques used across the theme (.eco-pub-hero's
   grid, .eco-home-shot/.eco-pub-lead-panel's noise) — ties the CTA into the
   same textured-surface language instead of sitting flat. Grid uses the
   indigo text color at low opacity (dark-on-lime, mirroring how the hero's
   grid uses white-on-dark) rather than the hero's radial-mask fade — this
   card is a bounded shape, not a full-viewport section, so an even grid
   reads better than one fading toward a corner. */
.eco-pub-cta { position: relative; overflow: hidden; }
.eco-pub-cta::before { content: ''; position: absolute; inset: 0; pointer-events: none; background-image: linear-gradient(rgba(18, 15, 136, .1) 1px, transparent 1px), linear-gradient(90deg, rgba(18, 15, 136, .1) 1px, transparent 1px); background-size: 56px 56px; }
.eco-pub-cta::after { content: ''; position: absolute; inset: 0; opacity: 0.12; mix-blend-mode: multiply; pointer-events: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%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"); }
.eco-pub-cta > * { position: relative; z-index: 1; }

@media (max-width: 1080px) {
  .eco-pub-band__cols { grid-template-columns: 1fr; }
  /* Who we serve: the sidebar's position:sticky (set inline, meant for
     the 340px/1fr desktop grid) has nothing to scroll past once the
     grid collapses to one column — it stays pinned over the stacked
     content below it instead of flowing normally. */
  .eco-pub-band__cols > *:first-child { position: static !important; }
  .eco-pub-tracks { grid-template-columns: 1fr; }
}
@media (max-width: 820px) {
  .eco-pub-metrics { grid-template-columns: 1fr; }
  .eco-pub-form { grid-template-columns: 1fr; }
}
