/* ==========================================================================
   Inovbi Solutions — public site

   The "signal board" marketing expression (hairline grids, plotted data
   marks, monospace readouts, one gold signal accent) — now built on the
   SAME token layer as the ERP console (static/erp/tokens.css), so
   Website -> Login -> ERP is one continuous surface. The site keeps its
   own layout and rhythm; it no longer keeps its own design system.

   The names below are marketing-local aliases onto the shared tokens,
   kept so the ~800 lines of rules underneath don't all have to change.
   ========================================================================== */


:root {
  --ink:        var(--text);
  --ink-soft:   var(--text-muted);
  --ink-faint:  var(--text-subtle);

  --paper:      var(--surface);
  --mist:       var(--surface-sunken);
  --mist-deep:  var(--surface-hover);
  --line-soft:  #e7ece9;

  /* --spruce, --spruce-2, --brand, --signal, --line and the --font-*
     families are defined identically in tokens.css and inherited as-is. */
  --on-spruce:      var(--on-dark);
  --on-spruce-dim:  var(--on-dark-muted);
  --on-spruce-line: var(--on-dark-line);

  --brand-deep: var(--brand-strong);
  --signal-soft: var(--signal-tint);

  --danger:      var(--crit);
  --danger-tint: var(--crit-bg);

  --r-xs: var(--radius-xs);
  --r-sm: var(--radius-sm);
  --r-md: var(--radius-md);
  --r-lg: var(--radius-lg);

  --shadow-sm: var(--elev-1);
  --shadow-md: var(--elev-2);
  --shadow-lg: var(--elev-3);

  --maxw: 1120px;
  --gutter: var(--space-6);
}

/* ---------- reset / base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-padding-top: 84px; }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.02em;
  margin: 0;
  color: var(--ink);
}
p { margin: 0; }
a { color: inherit; text-decoration: none; }
img, svg { max-width: 100%; display: block; }
:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; border-radius: 2px; }
::selection { background: var(--signal-soft); }

/* ======================================================================
   Motion — scroll-reveal + entrance choreography

   Two independent layers, both strictly additive to the static layout
   below and both reduced-motion-safe by construction:

   1. Hero/slab entrance — pure CSS `@keyframes` gated by
      `prefers-reduced-motion: no-preference`. No JS involved, so a
      visitor always sees the finished layout even if a script fails to
      load; browsers without the media feature just skip the rule and
      render the plain, always-visible layout underneath.

   2. Scroll-reveal for everything below the fold — progressive
      enhancement in the same spirit as `.story` (see story.js's own
      comment): the *default* state (no `.js-reveal-armed` on <html>)
      is the plain, fully visible layout. static/site/motion.js adds
      `.js-reveal-armed` synchronously, from an inline snippet in
      base_public.html's <head>, before first paint — so there is never
      a flash of visible-then-hidden content — and only once it has
      confirmed IntersectionObserver exists and the visitor hasn't
      asked for reduced motion. Only then do cards/sections start
      hidden and settle into place as they're scrolled into view.
   ====================================================================== */
@media (prefers-reduced-motion: no-preference) {
  @keyframes hero-rise {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: none; }
  }
  @keyframes hero-fade {
    from { opacity: 0; }
    to   { opacity: 1; }
  }
  .hero .breadcrumb    { animation: hero-rise 0.6s var(--ease) both; }
  .hero .kicker        { animation: hero-rise 0.6s var(--ease) 0.05s both; }
  .hero h1              { animation: hero-rise 0.7s var(--ease) 0.1s both; }
  .hero .hero__lede    { animation: hero-rise 0.7s var(--ease) 0.18s both; }
  .hero .hero__actions { animation: hero-rise 0.7s var(--ease) 0.26s both; }
  .hero .hero__note    { animation: hero-rise 0.6s var(--ease) 0.32s both; }
  .hero .hero__note + .hero__note { animation-delay: 0.37s; }
  /* Fades only — never a transform, so it never fights the mousemove
     tilt further down (see .hero .board's own comment there): the two
     would otherwise both be driving the same `transform` and the
     entrance animation's fill-forwards would win, freezing the tilt. */
  .hero .board          { animation: hero-fade 0.9s var(--ease) 0.18s both; }

  .slab__inner > *              { animation: hero-rise 0.55s var(--ease) both; }
  .slab__inner > *:nth-child(2) { animation-delay: 0.06s; }
  .slab__inner > *:nth-child(3) { animation-delay: 0.12s; }
  .slab__inner > *:nth-child(4) { animation-delay: 0.18s; }
  .slab__inner > *:nth-child(n+5) { animation-delay: 0.22s; }
}

.js-reveal-armed :is(
  .section-head, .capability, .sol, .tile, .industry, .metric,
  .pipeline__step, .compare__row, .step, .showcase__grid, .module-group
) {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}
.js-reveal-armed .is-in { opacity: 1; transform: none; }

/* Stagger siblings inside the same grid/row so a section doesn't pop in
   as one flat sheet — each item settles a beat after the one before it. */
.js-reveal-armed .capabilities > .capability:nth-child(2),
.js-reveal-armed .tiles > .tile:nth-child(2),
.js-reveal-armed .industries > .industry:nth-child(2),
.js-reveal-armed .metrics > .metric:nth-child(2),
.js-reveal-armed .solutions > .sol:nth-child(2),
.js-reveal-armed .pipeline > .pipeline__step:nth-child(2),
.js-reveal-armed .module-eco__grid > .module-group:nth-child(2) { transition-delay: 0.08s; }
.js-reveal-armed .capabilities > .capability:nth-child(3),
.js-reveal-armed .tiles > .tile:nth-child(3),
.js-reveal-armed .industries > .industry:nth-child(3),
.js-reveal-armed .metrics > .metric:nth-child(3),
.js-reveal-armed .pipeline > .pipeline__step:nth-child(3),
.js-reveal-armed .module-eco__grid > .module-group:nth-child(3) { transition-delay: 0.16s; }
.js-reveal-armed .capabilities > .capability:nth-child(4),
.js-reveal-armed .tiles > .tile:nth-child(4),
.js-reveal-armed .pipeline > .pipeline__step:nth-child(4),
.js-reveal-armed .module-eco__grid > .module-group:nth-child(4) { transition-delay: 0.24s; }
.js-reveal-armed .tiles > .tile:nth-child(5) { transition-delay: 0.32s; }
.js-reveal-armed .tiles > .tile:nth-child(n+6) { transition-delay: 0.4s; }

.wrap { max-width: var(--maxw); margin: 0 auto; padding-inline: var(--gutter); }

/* A quiet grouping label: a short hairline followed by sentence-case text.
   Deliberately not an all-caps tracked-out eyebrow. */
.kicker {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--ink-faint);
  margin-bottom: 22px;
}
.kicker::before {
  content: "";
  width: 28px;
  height: 1px;
  background: var(--brand);
}
.section--dark .kicker { color: var(--on-spruce-dim); }
.section--dark .kicker::before { background: var(--signal); }

/* The brand motif: three ascending bars (also the favicon). Reused as a
   small mark instead of clip-art icons. */
.mark {
  display: inline-flex;
  align-items: flex-end;
  gap: 3px;
  height: 20px;
}
.mark i { width: 4px; background: var(--brand); border-radius: 1px; display: block; }
.mark i:nth-child(1) { height: 45%; }
.mark i:nth-child(2) { height: 70%; }
.mark i:nth-child(3) { height: 100%; background: var(--signal); }

/* ======================================================================
   Navigation
   ====================================================================== */
.site-nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255,255,255,0.86);
  backdrop-filter: saturate(180%) blur(12px);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line-soft);
  transition: box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
/* A thin readout of scroll depth along the nav's own top edge — motion.js
   keeps --scroll-progress current; no JS means it just stays at 0% and
   the line is invisible, so this never depends on the script running. */
.site-nav::before {
  content: "";
  position: absolute;
  top: 0; inset-inline-start: 0;
  height: 2px;
  width: calc(var(--scroll-progress, 0) * 1%);
  background: linear-gradient(90deg, var(--brand), var(--signal));
  pointer-events: none;
}
.site-nav.is-scrolled { box-shadow: var(--shadow-sm); }
.site-nav__inner {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 14px var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -0.02em;
  color: var(--ink);
}
.brand .mark { height: 18px; }
.brand span b { font-weight: 700; }
.brand span i { font-style: normal; color: var(--ink-faint); font-weight: 500; }

/* site-nav__inner has exactly two flex children — brand, and this
   wrapper — so `justify-content: space-between` still splits the header
   into "logo" / "everything else" regardless of how many pieces
   "everything else" is made of. */
.site-nav__right { display: flex; align-items: center; gap: 14px; }

/* Desktop: <details> and its panel are just flex containers; the summary
   (the "Menu" button) is hidden. Mobile: summary becomes a real button and
   the panel drops down under the header when the <details> is open.
   site-nav__cta (Sign in / Start free trial) lives outside the <details>
   entirely and is always rendered, at every width — the primary calls to
   action should never depend on a toggle being opened first. */
.nav-menu { display: flex; align-items: center; }
.nav-menu__panel { display: flex; align-items: center; gap: 22px; }
.nav-toggle { list-style: none; display: none; }
.nav-toggle::-webkit-details-marker { display: none; }

.site-nav__links { display: flex; align-items: center; gap: 4px; }
.site-nav__links a {
  padding: 8px 12px;
  font-size: 14.5px;
  font-weight: 500;
  color: var(--ink-soft);
  border-radius: var(--r-sm);
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.site-nav__links a:hover { color: var(--ink); background: var(--mist); }
/* Duplicated into the dropdown for phone widths only — see the 960px
   breakpoint below, and the comment in base_public.html next to these
   links' other copies in .site-nav__cta. */
.nav-link--mobile-only { display: none; }
.site-nav__cta { display: flex; align-items: center; gap: 10px; }

/* ---- Demo dropdown: ESM and CSM each have their own live demo, so
   "Demo" opens a small choice instead of silently launching one of
   them. Same <details>/<summary> pattern as .nav-menu above — no JS,
   native keyboard/screen-reader support, closed by default. ---- */
.demo-menu { position: relative; }
.demo-menu__toggle { list-style: none; }
.demo-menu__toggle::-webkit-details-marker { display: none; }
.demo-menu__toggle svg { transition: transform var(--dur) var(--ease); }
.demo-menu[open] .demo-menu__toggle svg { transform: rotate(180deg); }

.demo-menu__panel { display: none; }
.demo-menu[open] .demo-menu__panel {
  display: flex;
  flex-direction: column;
  gap: 2px;
  position: absolute;
  top: calc(100% + 8px);
  inset-inline-end: 0;
  min-width: 220px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-md);
  padding: 6px;
  z-index: 60;
}
@media (prefers-reduced-motion: no-preference) {
  .demo-menu[open] .demo-menu__panel {
    transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease), display var(--dur) allow-discrete;
  }
  @starting-style {
    .demo-menu[open] .demo-menu__panel { opacity: 0; transform: translateY(-6px); }
  }
}
.demo-menu__panel a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: var(--r-sm);
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
  transition: background-color var(--dur) var(--ease);
}
.demo-menu__panel a:hover { background: var(--mist); }
.demo-menu__code {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--brand);
  padding: 2px 6px;
  border: 1px solid var(--line);
  border-radius: 4px;
  flex-shrink: 0;
}

/* language switcher — a small segmented EN | FR control */
/* Language dropdown (tenants/_lang_switcher.html). */
.lang-switch { position: relative; display: inline-block; margin: 0; }
.lang-switch > summary { list-style: none; }
.lang-switch > summary::-webkit-details-marker { display: none; }
.lang-switch__current {
  display: inline-flex; align-items: center; gap: 6px;
  height: 32px; padding: 0 10px; cursor: pointer; user-select: none;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  color: var(--ink); font: inherit; font-size: 13px; font-weight: 600; line-height: 1;
  transition: background-color .15s ease, border-color .15s ease;
}
.lang-switch__current:hover, .lang-switch[open] > .lang-switch__current { background: var(--surface-sunken); }
.lang-switch__current:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.lang-switch__globe { opacity: .8; }
.lang-switch__chevron { opacity: .7; transition: transform .15s ease; }
.lang-switch[open] .lang-switch__chevron { transform: rotate(180deg); }
.lang-switch__menu {
  position: absolute; inset-inline-end: 0; top: calc(100% + 6px); z-index: 300;
  min-width: 180px; margin: 0; padding: 6px;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--elev-3);
}
.lang-switch__opt {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  width: 100%; padding: 8px 10px; border: 0; border-radius: 6px;
  background: none; color: var(--text); font: inherit; font-size: 14px; text-align: start; cursor: pointer;
}
.lang-switch__opt:hover { background: var(--surface-sunken); }
.lang-switch__opt.is-active { background: var(--surface-sunken); font-weight: 600; }
.lang-switch__opt.is-active .lang-switch__name::before { content: "\2713"; margin-inline-end: 8px; color: var(--brand); }
.lang-switch__code { font-size: 11px; font-weight: 600; letter-spacing: .04em; color: var(--text-subtle); }
@media (pointer: coarse) { .lang-switch__current { height: 40px; } .lang-switch__opt { padding: 12px; } }

/* 960px, not 860px: with Pricing and About us added, the French header
   (longest labels) needs ~930px before it would scroll sideways. */
@media (max-width: 960px) {
  .nav-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    background: none;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    color: var(--ink);
    cursor: pointer;
  }
  .nav-menu[open] .nav-toggle { border-color: var(--ink-faint); }
  .nav-menu__panel { display: none; }
  .nav-menu[open] .nav-menu__panel {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    position: absolute;
    inset-inline-start: 0;
    inset-inline-end: 0;
    top: 100%;
    background: var(--paper);
    border-bottom: 1px solid var(--line);
    padding: 10px var(--gutter) 20px;
    box-shadow: var(--shadow-md);
  }
  /* Progressive enhancement: a browser that understands `@starting-style`
     and discrete `display` transitions animates the dropdown open/closed
     (fade + a short drop); everything else keeps the instant snap above
     — same "plain layout is always correct" fallback the rest of this
     file uses (see .story's own comment). */
  @media (prefers-reduced-motion: no-preference) {
    .nav-menu[open] .nav-menu__panel {
      transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease), display var(--dur) allow-discrete;
    }
    @starting-style {
      .nav-menu[open] .nav-menu__panel { opacity: 0; transform: translateY(-6px); }
    }
  }
  .nav-menu[open] .site-nav__links { flex-direction: column; align-items: stretch; gap: 0; }
  .nav-menu[open] .site-nav__links a {
    padding: 13px 4px;
    font-size: 15px;
    border-bottom: 1px solid var(--line-soft);
  }
  .nav-menu[open] .lang-switch { align-self: flex-start; margin-top: 8px; }
  .nav-menu[open] .lang-switch__menu { position: static; margin-top: 6px; box-shadow: none; }

  /* Phone header shows just the logo and this one toggle — every nav
     link and CTA (Solutions/Pricing/About us/Contact us/Sign in/Demo)
     moves into the dropdown instead, stacked as full-width rows, so
     there's never a second row of pill buttons squeezed under the logo. */
  .site-nav__cta { display: none; }
  .nav-link--mobile-only { display: block; }
  /* .demo-menu__mobile wraps the ESM/CSM pair — see .demo-menu itself
     (desktop's click-to-choose dropdown) below for why "Demo" needs two
     destinations instead of one. */
  .nav-cta--mobile-only { display: none; }
  .nav-menu[open] .nav-cta--mobile-only { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
}

/* ======================================================================
   Buttons
   ====================================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 20px;
  border-radius: var(--r-sm);
  border: 1px solid transparent;
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
  white-space: nowrap;
}
.btn--primary { background: var(--brand); color: #fff; }
.btn--primary:hover { background: var(--brand-deep); }
.btn--ghost { background: transparent; color: var(--ink); border-color: var(--line); }
.btn--ghost:hover { border-color: var(--ink-faint); background: var(--mist); }
.btn--on-dark { background: #fff; color: var(--spruce); }
.btn--on-dark:hover { background: var(--signal-soft); }
.btn--ghost-dark { background: transparent; color: #fff; border-color: var(--on-spruce-line); }
.btn--ghost-dark:hover { border-color: rgba(255,255,255,0.4); }
.btn--lg { padding: 15px 26px; font-size: 16px; }
.btn--sm { padding: 9px 15px; font-size: 14px; }
.btn--block { width: 100%; }
/* Touch-specific, not a breakpoint (mirrors static/erp/base.css's own
   .btn-sm rule): this site's own .btn has no explicit min-height, so its
   ~40px padded height is fine for a mouse but tight for a finger — the
   global tenant login form's "Sign in" button is the highest-traffic
   button behind this class. pointer:coarse targets actual touch input
   regardless of viewport width. */
@media (pointer: coarse) {
  .btn { min-height: 44px; }
}

/* A text link with the single gold underline — the one place the signal
   colour appears in body copy. Used for the primary in-text action. */
.link-signal {
  font-weight: 600;
  color: var(--ink);
  box-shadow: inset 0 -2px 0 var(--signal);
  transition: box-shadow 0.15s ease;
}
.link-signal:hover { box-shadow: inset 0 -10px 0 var(--signal-soft); }

/* ======================================================================
   Sections
   ====================================================================== */
.section { padding: 96px 0; }
.section--mist { background: var(--mist); }
.section--dark { background: var(--spruce); color: var(--on-spruce); }
.section--dark h2, .section--dark h3 { color: #fff; }
.section--tight { padding: 64px 0; }

.section-head { max-width: 640px; margin-bottom: 56px; }
.section-head h2 {
  font-size: clamp(1.9rem, 3.6vw, 2.7rem);
  margin-bottom: 16px;
}
.section-head p {
  font-size: 1.05rem;
  color: var(--ink-soft);
  line-height: 1.65;
}
.section--dark .section-head p { color: var(--on-spruce); }

/* ======================================================================
   Hero
   ====================================================================== */
.hero {
  padding: 84px 0 96px;
  border-bottom: 1px solid var(--line-soft);
  background-color: var(--paper);
  /* faint instrument-paper ruling, barely there */
  background-image: repeating-linear-gradient(
    0deg, transparent 0 39px, rgba(14,110,92,0.045) 39px 40px);
  /* lets .board tilt in 3D under the pointer (see .board's own comment) */
  perspective: 1400px;
}
.hero__grid {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 64px;
  align-items: center;
}
/* A solution with no real product screenshot yet (CSM) gets one centred
   column instead of an empty second one. */
.wrap.hero__grid--single { grid-template-columns: 1fr; max-width: 780px; }

.breadcrumb {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink-faint);
  margin-bottom: 28px;
}
.breadcrumb a { transition: color var(--dur) var(--ease); }
.breadcrumb a:hover { color: var(--ink); }
.breadcrumb [aria-current] { color: var(--ink-soft); }
.hero h1 {
  font-size: clamp(2.5rem, 5.4vw, 4rem);
  letter-spacing: -0.03em;
  margin-bottom: 22px;
}
.hero__lede {
  font-size: 1.16rem;
  line-height: 1.6;
  color: var(--ink-soft);
  max-width: 30em;
  margin-bottom: 32px;
}
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 20px;
}
.hero__note {
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--ink-faint);
}

/* ---- the signal board: the hero's instrument panel ---- */
.board {
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--paper);
  box-shadow: var(--shadow-md);
  overflow: hidden;
  /* motion.js tracks the pointer over .hero .board and writes a
     rotateX/rotateY transform directly here (desktop, fine pointer,
     motion allowed) — like the panel catching the light as you move
     across it. This transition is what smooths that out; the entrance
     animation above is opacity-only on purpose so it never fights this
     transform (see the Motion section's own comment on why). */
  transition: transform 0.2s var(--ease);
  transform-style: preserve-3d;
}
.board__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line-soft);
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--ink-faint);
  background: var(--mist);
}
.board__live { display: inline-flex; align-items: center; gap: 7px; color: var(--brand); }
.board__live::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--signal);
  box-shadow: 0 0 0 0 var(--signal);
  animation: pulse 2.4s ease-out infinite;
}
@keyframes pulse {
  0%   { box-shadow: 0 0 0 0 rgba(224,161,43,0.5); }
  70%  { box-shadow: 0 0 0 8px rgba(224,161,43,0); }
  100% { box-shadow: 0 0 0 0 rgba(224,161,43,0); }
}
/* The real product screenshot, framed like a window onto the running
   app rather than a plain rectangle — .board__bar above already reads
   as "chrome", so the frame itself stays unadorned. */
.board__frame { line-height: 0; background: var(--paper); }
.board__frame img { width: 100%; height: auto; display: block; }

.board__readouts {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid var(--line-soft);
}
.readout { padding: 16px; border-inline-end: 1px solid var(--line-soft); }
.readout:last-child { border-inline-end: none; }
.readout__label {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.02em;
  color: var(--ink-faint);
  text-transform: lowercase;
  margin-bottom: 6px;
}
.readout__value {
  font-family: var(--font-mono);
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--ink);
}
.readout__delta { font-size: 11px; font-weight: 500; color: var(--brand); }
.readout__delta--down { color: var(--danger); }

@media (prefers-reduced-motion: reduce) {
  .board__live::before { animation: none; }
}

/* ======================================================================
   Capability row  (why Inovbi — not a sequence, so no numbers)
   ====================================================================== */
.capabilities {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--line-soft);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-md);
  overflow: hidden;
}
.capability {
  background: var(--paper);
  padding: 28px 24px 30px;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.capability:hover { transform: translateY(-3px); box-shadow: var(--shadow-sm); position: relative; z-index: 1; }
.capabilities--3 { grid-template-columns: repeat(3, 1fr); }
.capability .mark { margin-bottom: 18px; }
.capability h3 {
  font-size: 1.02rem;
  margin-bottom: 8px;
}
.capability p {
  font-size: 0.92rem;
  color: var(--ink-soft);
  line-height: 1.6;
}
.capability--lg { padding: 32px 28px 34px; }
.capability--lg h3 { font-size: 1.2rem; margin-bottom: 10px; }
.capability--lg p { font-size: 0.98rem; }

/* ======================================================================
   Solutions
   ====================================================================== */
.solutions {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 24px;
  align-items: start;
}
.sol {
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--paper);
  padding: 32px;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.sol:hover { transform: translateY(-3px); box-shadow: var(--shadow-sm); }
.sol--lead { border-color: var(--brand); box-shadow: var(--shadow-md); }
.sol--lead:hover { box-shadow: var(--shadow-lg); }
.sol--soon { background: var(--mist); border-style: dashed; border-color: var(--line); }

.sol__status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  padding: 4px 10px;
  border-radius: 999px;
  margin-bottom: 18px;
}
.sol__status--live { background: var(--brand-tint); color: var(--brand-deep); }
.sol__status--live::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--brand); }
.sol__status--soon { background: var(--signal-soft); color: #8a5a12; }

.sol__code {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.75rem;
  letter-spacing: -0.02em;
}
.sol__name {
  font-size: 0.95rem;
  color: var(--ink-faint);
  margin-bottom: 14px;
}
.sol__desc { color: var(--ink-soft); line-height: 1.62; margin-bottom: 14px; }
.sol__count { font-family: var(--font-mono); font-size: 12.5px; color: var(--ink-faint); margin-bottom: 22px; }

.sol__foot { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; }
.sol__foot .fineprint { font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-faint); }

/* ---- module ecosystem: grouped the way the app's own sidebar groups
   them (see erp/shell sidebar), not a marketing-invented taxonomy — real
   categories, so a panel's size follows how many modules it really has
   instead of forcing every group into one identical card. ---- */
.module-eco { margin-top: 56px; }
.module-eco__head { max-width: 46em; margin-bottom: 28px; }
.module-eco__head h3 { font-size: 1.3rem; margin-bottom: 8px; }
.module-eco__head p { color: var(--ink-soft); line-height: 1.6; }
.module-eco__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 1px;
  background: var(--line-soft);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-md);
  overflow: hidden;
}
.module-group { background: var(--paper); padding: 22px 22px 8px; }
.module-group h4 {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-faint);
  text-transform: lowercase;
  margin-bottom: 14px;
}
.module-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding-bottom: 16px;
}
.module-row__icon { color: var(--brand); flex-shrink: 0; margin-top: 1px; }
.module-row__name { font-size: 0.92rem; font-weight: 600; margin-bottom: 2px; }
.module-row__desc { font-size: 0.82rem; color: var(--ink-faint); line-height: 1.5; }

/* ======================================================================
   Solutions page — one showcase row per product (tenants/templates/
   tenants/solutions.html). Text + a live .board (see the hero's own
   .board above) alternate sides between rows so ESM and CSM read as two
   distinct products, not a matched pair of identical cards. Each board
   cycles through real product screenshots instead of showing one static
   frame — the closest thing this kind of software has to "footage."
   ====================================================================== */
.showcase { padding: 72px 0; }
.showcase:nth-child(even) { background: var(--mist); }
.showcase__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 64px;
  align-items: center;
}
.showcase--reverse .showcase__grid { grid-template-columns: 1fr 1fr; }
.showcase--reverse .showcase__media { order: -1; }
/* ESM on the Solutions page: the second-level offer, visually quieter than CSM. */
.showcase--second { background: var(--mist); }
.showcase--second .showcase__name { font-size: clamp(24px, 2.6vw, 32px); }
.showcase__eyebrow {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--brand);
  letter-spacing: 0.02em;
  margin: 0 0 10px;
}
.showcase__name { font-size: clamp(1.7rem, 2.6vw, 2.2rem); letter-spacing: -0.02em; margin: 0 0 14px; }
.showcase__lede { font-size: 1.05rem; line-height: 1.6; color: var(--ink-soft); max-width: 34em; margin-bottom: 24px; }
.showcase__facts { list-style: none; margin: 0 0 30px; padding: 0; display: grid; gap: 10px; }
.showcase__facts li {
  position: relative;
  padding-inline-start: 20px;
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--ink-soft);
}
.showcase__facts li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: 0.55em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--brand);
}
.showcase__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; }

/* the cycling screenshot frame */
.board__frame--cycle { position: relative; aspect-ratio: 1440 / 900; overflow: hidden; }
.board__slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  opacity: 0;
  animation: board-slide-1 16s infinite cubic-bezier(0.4, 0, 0.6, 1);
}
.board__slide:nth-child(2) { animation-name: board-slide-2; }
.board__slide:nth-child(3) { animation-name: board-slide-3; }
@keyframes board-slide-1 { 0%, 27% { opacity: 1; } 33%, 93% { opacity: 0; } 100% { opacity: 1; } }
@keyframes board-slide-2 { 0%, 27% { opacity: 0; } 33%, 60% { opacity: 1; } 66%, 100% { opacity: 0; } }
@keyframes board-slide-3 { 0%, 60% { opacity: 0; } 66%, 93% { opacity: 1; } 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .board__slide { animation: none; opacity: 0; }
  .board__slide:first-child { opacity: 1; }
}
@media (max-width: 960px) {
  .showcase__grid { grid-template-columns: 1fr; gap: 32px; }
  .showcase--reverse .showcase__media { order: 0; }
}

/* ======================================================================
   Industries — grouped by real module combinations, not a stock-photo
   grid; deliberately a different shape from the module ecosystem grid
   above (left accent bar + inline tag row) so two adjacent sections
   don't read as the same card repeated.
   ====================================================================== */
.industries {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  background: var(--line-soft);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-md);
  overflow: hidden;
}
.industry {
  background: var(--paper);
  padding: 28px 30px;
  border-inline-start: 3px solid var(--brand);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.industry:hover { transform: translateY(-3px); box-shadow: var(--shadow-sm); position: relative; z-index: 1; }
.industry h3 { font-size: 1.05rem; margin-bottom: 8px; }
.industry p { color: var(--ink-soft); line-height: 1.6; margin-bottom: 18px; max-width: 42em; }
.industry__mods { display: flex; flex-wrap: wrap; gap: 8px; }
.industry__mods a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 11px;
  border-radius: var(--r-pill, 999px);
  border: 1px solid var(--line);
  font-size: 0.8rem;
  color: var(--ink-soft);
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.industry__mods a:hover { border-color: var(--brand); color: var(--ink); }
.industry__mods svg { color: var(--brand); }

/* ======================================================================
   Platform pipeline — a genuine sequence (data becomes a decision in
   six real stages), so numbering is earned here. Each step carries its
   own top tick rather than one continuous connector line, so the grid
   can wrap at any width without a line to reposition.
   ====================================================================== */
.pipeline {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 28px 24px;
}
.pipeline__step {
  border-top: 2px solid var(--brand);
  padding-top: 18px;
}
.pipeline__step:last-child { border-top-color: var(--signal); }
.pipeline__no {
  display: block;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-faint);
  margin-bottom: 10px;
}
.pipeline__step h4 { font-size: 0.98rem; margin-bottom: 6px; }
.pipeline__step p { font-size: 0.85rem; color: var(--ink-soft); line-height: 1.55; }

/* ======================================================================
   Comparison — plain claims on the left, what's actually true of this
   platform on the right (a left accent rule, not a generic red-X/green-
   check table).
   ====================================================================== */
.compare { border: 1px solid var(--line-soft); border-radius: var(--r-md); overflow: hidden; background: var(--paper); }
.compare__head { display: grid; grid-template-columns: 1fr 1fr; background: var(--mist); }
.compare__head span {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--ink-faint);
  padding: 12px 26px;
  text-transform: lowercase;
}
.compare__row { display: grid; grid-template-columns: 1fr 1fr; border-top: 1px solid var(--line-soft); }
.compare__row > div { padding: 20px 26px; font-size: 0.94rem; line-height: 1.55; }
.compare__row > div:first-child { color: var(--ink-faint); border-inline-end: 1px solid var(--line-soft); }
.compare__row > div:last-child { color: var(--ink); font-weight: 500; border-inline-start: 3px solid var(--brand); margin-inline-start: -1px; }

/* ======================================================================
   How it works  (a real sequence — numbered markers are earned here)
   ====================================================================== */
.steps { counter-reset: step; display: grid; gap: 0; }
.step {
  display: grid;
  grid-template-columns: 64px 1fr;
  gap: 24px;
  padding: 28px 0;
  border-top: 1px solid var(--on-spruce-line);
}
.step:last-child { border-bottom: 1px solid var(--on-spruce-line); }
.step::before {
  counter-increment: step;
  content: counter(step, decimal-leading-zero);
  font-family: var(--font-mono);
  font-size: 14px;
  color: var(--signal);
  padding-top: 4px;
}
.step h3 { font-size: 1.15rem; margin-bottom: 6px; }
.step p { color: var(--on-spruce); max-width: 46em; line-height: 1.62; }

/* ======================================================================
   Metrics strip
   ====================================================================== */
.metrics {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}
.metric { border-inline-start: 2px solid var(--brand); padding-inline-start: 18px; }
.metric__value {
  font-family: var(--font-mono);
  font-size: clamp(1.8rem, 3.5vw, 2.4rem);
  font-weight: 600;
  letter-spacing: -0.02em;
}
.metric__label { font-size: 0.9rem; color: var(--ink-soft); margin-top: 4px; }

/* ======================================================================
   CTA band
   ====================================================================== */
.cta-band {
  background: var(--spruce);
  color: #fff;
  padding: 88px 0;
  text-align: center;
}
.cta-band h2 { color: #fff; font-size: clamp(1.9rem, 4vw, 2.8rem); margin-bottom: 14px; }
.cta-band p { color: var(--on-spruce); max-width: 34em; margin: 0 auto 30px; font-size: 1.05rem; }
.cta-band__actions { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }

/* ======================================================================
   Footer
   ====================================================================== */
.site-footer {
  background: #08161300;
  background: #071410;
  color: var(--on-spruce-dim);
  padding: 64px 0 32px;
}
.site-footer__grid {
  display: grid;
  grid-template-columns: 1.6fr repeat(3, 1fr);
  gap: 40px;
  padding-bottom: 40px;
  border-bottom: 1px solid var(--on-spruce-line);
}
.site-footer .brand { color: #fff; margin-bottom: 14px; }
.site-footer__blurb { font-size: 0.9rem; line-height: 1.6; max-width: 26em; }
.site-footer__loc { font-family: var(--font-mono); font-size: 11.5px; margin-top: 14px; color: var(--on-spruce-dim); }
.site-footer h4 {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: rgba(255,255,255,0.5);
  margin-bottom: 14px;
}
.site-footer__grid a { display: block; padding: 5px 0; font-size: 0.9rem; color: var(--on-spruce); transition: color var(--dur) var(--ease); }
.site-footer__grid a:hover { color: #fff; }
.site-footer__base {
  padding-top: 24px;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: rgba(255,255,255,0.4);
}

/* ======================================================================
   Forms  (contact, signup, auth)
   ====================================================================== */
.field { margin-bottom: 18px; }
.field label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: 7px;
}
.field input,
.field textarea {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  font-family: var(--font-body);
  font-size: 16px;
  color: var(--ink);
  background: #fff;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.field textarea { resize: vertical; min-height: 130px; }
.field input:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-tint);
}
.field__error { color: var(--danger); font-size: 12.5px; margin-top: 6px; }

.alert {
  padding: 13px 16px;
  border-radius: var(--r-sm);
  font-size: 14px;
  margin-bottom: 20px;
  border: 1px solid transparent;
}
.alert--ok { background: var(--brand-tint); color: var(--brand-deep); border-color: #bfdcd4; }
.alert--error { background: var(--danger-tint); color: var(--danger); border-color: #e6c4bc; }

.panel {
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: #fff;
  padding: 28px;
}

/* multi-workspace login picker */
.workspace-choices { display: flex; flex-direction: column; gap: 10px; }
.workspace-choice {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  width: 100%;
  text-align: start;
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: #fff;
  cursor: pointer;
  font: inherit;
  color: inherit;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.workspace-choice:hover,
.workspace-choice:focus-visible { border-color: var(--brand); background: var(--brand-tint); }
.workspace-choice__solution {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.03em;
  color: var(--brand);
  text-transform: uppercase;
}
.workspace-choice__name { font-size: 16px; font-weight: 600; }
.workspace-choice__tagline { font-size: 13px; color: var(--ink-soft); }

/* narrow single-column page (contact, auth) */
.slab { padding: 72px 0; }
.slab--mist { background: var(--mist); min-height: calc(100vh - 63px); }
.slab__inner { max-width: 460px; margin: 0 auto; padding-inline: var(--gutter); }
.slab__inner--wide { max-width: 560px; }
.slab h1 { font-size: 1.9rem; margin-bottom: 10px; }
.slab__lede { color: var(--ink-soft); margin-bottom: 28px; }
.slab__foot { margin-top: 22px; font-size: 14px; color: var(--ink-soft); }
.slab__foot a { color: var(--brand); font-weight: 600; }
.slab__foot a:hover { text-decoration: underline; }

.field-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 7px;
}
.field-row label { margin-bottom: 0; }
.field-row a { font-size: 12.5px; color: var(--brand); font-weight: 600; }
.field-row a:hover { text-decoration: underline; }
/* Touch-specific (see .btn's own pointer:coarse rule above): "Forgot
   password?" sits right next to the Password label at 12.5px with no
   padding — comfortable to read, cramped to actually tap. Padding
   (not a taller line-height) adds real tap area without visually
   enlarging the link text itself. */
@media (pointer: coarse) {
  .field input, .field textarea { min-height: 44px; }
  .field-row a { display: inline-block; padding: 10px 0; margin: -10px 0; }
}

/* progress rail for the 3-step signup */
.rail {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--ink-faint);
  margin-bottom: 28px;
}
.rail b { color: var(--brand); font-weight: 500; }
.rail span { width: 22px; height: 1px; background: var(--line); }

/* chosen-module chips */
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 12.5px;
  background: #fff;
}

/* ======================================================================
   Module picker  (signup step 2 + solution detail)
   ====================================================================== */
.cat-label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.03em;
  color: var(--ink-faint);
  margin: 32px 0 14px;
}
.cat-label:first-child { margin-top: 0; }

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 14px;
}
.tile {
  position: relative;
  display: block;
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: #fff;
  cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease, transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.tile:hover { border-color: var(--ink-faint); transform: translateY(-3px); box-shadow: var(--shadow-sm); }
.tile:has(input:checked) { border-color: var(--brand); background: var(--brand-tint); }
.tile input {
  position: absolute;
  top: 18px; inset-inline-end: 18px;
  width: 18px; height: 18px;
  accent-color: var(--brand);
}
.tile--static { cursor: default; }
.tile--static:hover { border-color: var(--line); }

/* auto-selected because another chosen module depends on it */
.tile--locked { cursor: default; border-color: var(--brand); background: var(--brand-tint); }
.tile--locked .tile__icon, .tile--locked .tile__name, .tile--locked .tile__desc { opacity: 0.65; }
.tile--locked input { accent-color: var(--ink-faint); }
.tile--locked [data-lock-note] { color: var(--ink-soft); }
.tile__icon { color: var(--brand); margin-bottom: 12px; }
.tile__name { font-family: var(--font-display); font-weight: 600; font-size: 1rem; padding-inline-end: 26px; }
.tile__desc { font-size: 0.85rem; color: var(--ink-soft); margin-top: 6px; line-height: 1.55; }
.tile__rec { font-family: var(--font-mono); font-size: 10px; color: var(--brand); margin-top: 10px; }

.empty {
  padding: 32px;
  text-align: center;
  border: 1px dashed var(--line);
  border-radius: var(--r-md);
  color: var(--ink-soft);
  font-size: 14px;
}

/* ======================================================================
   Feature story — "Modules in X" (solution_detail.html). Each category
   is a slide: its screenshot as a true background, its module list
   overlaid in the foreground on top via a left-to-right scrim (dark
   where the text sits, fading away to let the screenshot read
   clearly), like light projected onto a wall.

   Default markup/CSS (always correct, no JS required): slides stack
   as plain full-bleed sections and the page scrolls through them
   normally — this is also the deliberate fallback for no-JS visits,
   reduced-motion visits, and browsers without IntersectionObserver.

   static/site/story.js progressively upgrades this into a pinned
   "scrollytelling" section (`.story--pinned`, added only once the
   script actually runs): the section locks in the viewport and the
   scroll gesture instead scrubs directly between slides — image and
   module list crossfading together as one unit — releasing back to
   normal page scroll once the last slide has been reached. The pin's
   scroll distance comes from `.story`'s own height in that mode
   (`--story-count` categories × 120vh, set inline by the template);
   JS reads real scroll position against that distance every frame, so
   the crossfade is a direct function of scroll position (scrubbed),
   not a fixed-duration animation racing against it.
   ====================================================================== */
.story {
  position: relative;
  width: 100vw;
  margin-inline: calc(50% - 50vw);
}
.story--pinned { height: calc(var(--story-count, 1) * 120vh); }

.story__pin { display: block; }
.story--pinned .story__pin {
  position: sticky;
  top: 63px; /* clears the sticky .site-nav header */
  height: calc(100vh - 63px);
  overflow: hidden;
  z-index: 10;
}

.story__frame { display: block; }
.story--pinned .story__frame { position: relative; width: 100%; height: 100%; }

.story__slide {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  background: var(--spruce);
}
.story__slide + .story__slide { border-top: 1px solid rgba(255, 255, 255, 0.08); }
.story--pinned .story__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  border-top: none;
}
.story--pinned .story__slide.is-active { opacity: 1; }

.story__visual {
  grid-area: 1 / 1;
  align-self: start;
  position: sticky;
  top: 63px; /* clears the sticky .site-nav header */
  height: clamp(560px, 82vh, 760px);
  overflow: hidden;
  z-index: 0;
}
.story--pinned .story__visual { position: absolute; inset: 0; height: 100%; }
.story__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
}
.story__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(13, 33, 29, 0.94) 0%, rgba(13, 33, 29, 0.82) 30%, rgba(13, 33, 29, 0.32) 56%, rgba(13, 33, 29, 0) 74%);
  pointer-events: none;
}
.story__chrome {
  position: absolute;
  top: 0; inset-inline-start: 0; inset-inline-end: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px clamp(24px, 6vw, 96px);
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--on-spruce-dim);
}
.story__content {
  grid-area: 1 / 1;
  align-self: start;
  position: relative;
  z-index: 2;
  max-width: 480px;
  padding: 64px clamp(24px, 6vw, 96px);
  color: var(--on-spruce);
}
.story--pinned .story__content { align-self: stretch; display: flex; flex-direction: column; justify-content: center; max-height: 100%; }
.story__name { font-size: clamp(1.6rem, 3vw, 2rem); letter-spacing: -0.02em; color: #fff; margin: 0 0 6px; }
.story__count { font-family: var(--font-mono); font-size: 12.5px; color: var(--on-spruce-dim); margin: 0 0 28px; }
.story__modules { display: grid; gap: 20px; }
.story--pinned .story__modules { overflow-y: auto; max-height: 100%; padding-inline-end: 4px; }
.story__module { display: flex; gap: 13px; }
.story__module-icon { color: var(--signal); flex-shrink: 0; margin-top: 1px; }
.story__module-name { font-weight: 600; font-size: 0.96rem; color: #fff; margin-bottom: 3px; }
.story__module-desc { font-size: 0.87rem; color: var(--on-spruce-dim); line-height: 1.58; }
.story--pinned .story__modules:has(.story__module:nth-child(6)) { gap: 12px; }
.story--pinned .story__modules:has(.story__module:nth-child(6)) .story__module-desc { font-size: 0.82rem; line-height: 1.45; }

@media (max-width: 720px) {
  .story--pinned { height: auto; }
  .story--pinned .story__pin,
  .story--pinned .story__frame,
  .story--pinned .story__slide,
  .story--pinned .story__visual { position: static; height: auto; opacity: 1; }
  .story--pinned .story__content { max-height: none; display: block; }
  .story--pinned .story__modules { overflow: visible; max-height: none; }

  .story__visual { height: 46vh; min-height: 320px; }
  .story__scrim {
    background: linear-gradient(180deg, rgba(13, 33, 29, 0.2) 0%, rgba(13, 33, 29, 0.85) 60%, rgba(13, 33, 29, 0.94) 100%);
  }
  .story__slide { grid-template-columns: 1fr; }
  .story__content { grid-area: 2 / 1; max-width: 100%; padding: 24px 20px 40px; }
  .story__chrome { padding: 14px 20px; }
}

/* ======================================================================
   Responsive
   ====================================================================== */
@media (max-width: 960px) {
  .hero__grid { grid-template-columns: 1fr; gap: 44px; }
  .capabilities { grid-template-columns: repeat(2, 1fr); }
  .capabilities--3 { grid-template-columns: repeat(2, 1fr); }
  .solutions { grid-template-columns: 1fr; }
  .industries { grid-template-columns: 1fr; }
  .site-footer__grid { grid-template-columns: 1fr 1fr; gap: 32px; }
}
@media (max-width: 620px) {
  .section { padding: 64px 0; }
  .hero { padding: 56px 0 64px; }
  .capabilities { grid-template-columns: 1fr; }
  .metrics { grid-template-columns: 1fr; gap: 20px; }
  .board__readouts { grid-template-columns: 1fr; }
  .readout { border-inline-end: none; border-bottom: 1px solid var(--line-soft); }
  .readout:last-child { border-bottom: none; }
  .site-footer__grid { grid-template-columns: 1fr; }
  .step { grid-template-columns: 1fr; gap: 6px; }
  .cta-band, .slab { padding: 56px 0; }
  .compare__head, .compare__row { grid-template-columns: 1fr; }
  .compare__head span:first-child { border-bottom: 1px solid var(--line-soft); }
  .compare__row > div:first-child { border-inline-end: none; border-bottom: 1px solid var(--line-soft); }
  .compare__row > div:last-child { border-inline-start: none; border-top: 3px solid var(--brand); margin-inline-start: 0; }
}

/* Desktop EN | FR switcher in .site-nav__cta (see base_public.html); the
   phone copy lives in the .nav-menu dropdown. */
.lang-switch-wrap--desktop { display: flex; margin-inline-start: 4px; }
@media (max-width: 960px) { .lang-switch-wrap--desktop { display: none; } }

/* ---- Home: CSM promo in the hero, ERP chips, second-level ESM band ---- */
.hero-promo { align-self: center; }
.erp-chips { display: flex; flex-wrap: wrap; gap: 12px; }
.erp-chip { display: inline-flex; align-items: center; padding: 10px 18px; border-radius: 999px; font-weight: 600;
  border: 1px solid var(--line); background: var(--paper); color: var(--ink); }
.erp-chip--lead { background: var(--brand-tint, #e1efe9); border-color: transparent; color: var(--brand-deep, #08564a); }
.erp-chip--esm { border-style: dashed; }
.esm-band { border: 1px solid var(--line); border-radius: var(--r-lg); padding: 36px; background: var(--mist); }
.esm-band__text h2 { margin: 6px 0 12px; font-size: clamp(26px, 3vw, 34px); }
.esm-band__text p { color: var(--ink-soft); max-width: 760px; }
.esm-band .sol__foot { margin-top: 20px; }
.esm-band__modules { margin-top: 24px; border-top: 1px solid var(--line); padding-top: 18px; }
.esm-band__modules summary { cursor: pointer; font-weight: 600; color: var(--brand-deep, #08564a); }
.esm-band__modules .module-eco__grid { margin-top: 20px; }
@media (max-width: 720px) { .esm-band { padding: 24px 18px; } }

/* ---- Demo videos (CSM solution page) — two how-to recordings side by side ---- */
.demo-videos { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 28px; }
@media (max-width: 1080px) { .demo-videos { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 720px) { .demo-videos { grid-template-columns: 1fr; } }
.demo-videos__item h3 { font-size: 22px; margin-top: 18px; }
.demo-videos__item p { color: var(--ink-soft); margin-top: 6px; }

/* ---- Promo video (solution page) — first thing under the breadcrumb ---- */
.hero-video { margin-top: 20px; margin-bottom: 64px; }
@media (max-width: 720px) { .hero-video { margin-bottom: 40px; } }
.demo-video {
  margin: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--paper);
  box-shadow: var(--shadow-md);
  overflow: hidden;
}
.demo-video video {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  background: var(--spruce);
}
.demo-video__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 20px;
  margin-top: 28px;
}
.demo-video__actions .hero__note { margin: 0; }
