/* ===========================================================================
   si-components.css -- the SIAssist component layer
   ---------------------------------------------------------------------------
   Prefix `si-`. Beside is-components.css, not on top of it: the two share
   Bootstrap and nothing else (ADR-0009). Where a solution from the Innovation
   Scout fits, it is taken over because it is good -- never because it has to
   be shared.

   Source: agent_docs/design/si/si-fundament.md and the mockup under
   agent_docs/mockups/. Every value here is one of those two; no number is
   invented (ADR-0010).

   Sections
     1. Tokens
     2. The page ground and the type scale
     3. Spacing
     4. Scroll-in
     5. Components -- B2 si-statement
   =========================================================================== */

/* --- 1. Tokens ------------------------------------------------------------
   Taken from the mockup's :root, reduced to what is in use. The dark palette
   the mockup carries is deliberately NOT here: no night mode (Michael,
   2026-09-01), every colour is set exactly once. */
.si-page {
  /* The old site sets body{line-height:1.7; letter-spacing:.01em} and it reaches
     straight through here. Every line of the new pages was 6% taller and each
     character .16px wider than the mockup, which is a good part of what Michael
     described as "the mockup's type is finer" (konzept-siassist measured it in
     the rendered mockup, 2026-09-08). This is the counterpart to the mockup's
     own .si rule; it stays inside the new layer and leaves the old header and
     footer alone, and it corrects some fifteen single values at once. */
  line-height: 1.6;
  letter-spacing: normal;
  --si-bg:        #F7F8F6;
  --si-surface:   #FFFFFF;
  --si-panel:     #2F3E3A;
  /* The panel's own inks. They were rgba() literals spread over seven rules,
     and that is how an opaque colour turns translucent without anyone noticing:
     the heading sat at .92 and the partner name at .72, so the name of the firm
     carried the same ink as the sentence under it (konzept-siassist,
     2026-09-02). Named once, they can only be wrong in one place. */
  --si-panel-ink:    #EAEFEC;
  --si-panel-ink-70: rgba(234, 239, 236, .72);
  --si-panel-line:   rgba(255, 255, 255, .14);

  --si-ink:       #2F3E3A;
  --si-ink-70:    #5E6D68;
  --si-ink-45:    #8A9793;

  --si-line:      rgba(47, 62, 58, .12);
  --si-line-soft: rgba(47, 62, 58, .07);

  /* The gold wash: the ground the "In Entwicklung" mark stands on. Values from
     the mockup's light set -- it carries a dark one too, and we have no night
     mode, so only these three exist here.

     There is no --si-gold-wash-ink, although the delivery names one: its value
     is #5C4A08, which is --si-gold-ink to the byte. A second name for a colour
     we already have is the second truth this sheet keeps taking out. */
  --si-gold-wash:      #FDF4DC;
  --si-gold-wash-line: rgba(244, 180, 0, .4);

  /* Ink at 4.5% -- the ground of a tag and of a framed box (si-fundament.md
     § "si-tag"). Named in the foundation since 2026-09-01 and never added,
     because the home page has neither. The sub-pages have both. */
  --si-fill:      rgba(47, 62, 58, .045);

  /* The ground the solutions section stands on -- it is a field of its own in
     the mockup, not flush with the page. */
  --si-sol-band:  rgba(255, 255, 255, .62);

  /* Sign colours. They never carry text -- see the ink variants below. */
  --si-gold:      #F4B400;
  --si-terra:     #C85A2E;
  --si-ana:       #42796A;
  --si-dec:       #3A6A8C;

  /* The ink variants. Measured on white: gold 1.85:1 and terracotta 4.24:1 are
     both under the 4.5 floor, ana 5.03:1 and dec 5.80:1 pass -- but a group
     colour that sometimes carries text and sometimes does not is two rules, so
     text always takes the ink variant (si-fundament.md, section 4).

     Terracotta had no ink variant, which is the gap the rule itself left: it
     was the one mark whose raw value still carried type, and on the section
     ground that came to 3.98:1 (konzept-siassist, 2026-09-01). The raw #C85A2E
     stays a sign colour -- nodes, hexagons, numbers. */
  --si-gold-ink:  #5C4A08;
  --si-terra-ink: #B85028;
  --si-ana-ink:   #2B5347;
  --si-dec-ink:   #254F6B;
  --si-gold-on:   #3A2E05;   /* type ON gold */

  /* --- The type scale: the mockup's own ladder ---------------------------
     This used to be four values, on the reasoning that a small vocabulary is
     easier to keep. It was the wrong four: every size that got "put on the
     nearest declared step" flattened the page a little, and by the end all
     eight h2 were the same size where the mockup steps down section by section
     (Michael found it in the first screen; konzept-siassist, 2026-09-02).

     So the mockup's ladder IS the ladder. The guard did not get weaker -- it
     now guards the right rungs. Heading sizes are clamps and live with their
     section; these are the fixed steps below them. */
  --si-t-badge: .66rem;   /* 10.6 -- the DEMNAECHST badge  */
  --si-t-soon:  .70rem;   /* 11.2 -- the In-Entwicklung mark */
  --si-t-lead:  1.1875rem;/* 19.0 -- a section's lead; the mockup lets it
                             inherit its own 19px base, we have 16 */
  --si-t-note:  .95rem;   /* 15.2 -- the note under a grid, and the
                             closing line of the numbered section */
  --si-t-who:   .80rem;   /* 12.8 -- the partner line in a tile */
  --si-t-go:    .82rem;   /* 13.1 -- the way onward        */
  --si-t-micro: .72rem;   /* 11.5 -- eyebrow, stage, count */
  --si-t-tag:   .76rem;   /* 12.2 -- tag                   */
  --si-t-chip:  .86rem;   /* 13.8 -- filter chip           */
  --si-t-link:  .92rem;   /* 14.7 -- text link, role, who  */
  --si-t-btn:   .95rem;   /* 15.2 -- button                */
  --si-t-tile:  .97rem;   /* 15.5 -- tile body             */
  --si-t-body:  .98rem;   /* 15.7 -- card body, topic row  */
  --si-t-quote: 1.06rem;  /* 17.0 -- the statement's text  */
  --si-t-q:     1.14rem;  /* 18.2 -- card question         */
  --si-t-logo:  1.08rem;  /* 17.3 -- partner name          */
  --si-t-name:  1.16rem;  /* 18.6 -- card org              */
  --si-t-card:  1.2rem;   /* 19.2 -- tile and panel heads  */
  /* ONE size per heading level, across every section and every page kind --
     Michael, 2026-09-08: "vereinheitliche alle ueberschriftsgroessen im
     siassist css, egal was das mockup sagt". The mockup steps h2 through six
     values (45.6 / 41.6 / 38.4 / 34.4 / 32.8 / 31.2 / 30.4) and we matched it
     to the decimal; the jumps are what he saw, and they do not descend -- the
     second section is LARGER than the first. Two rungs replace all nine.

     The levels stay apart: h1 and h2 are one size EACH, not one size TOGETHER.
     Collapsing those two would leave the pages without a hierarchy at all. */
  --si-h1:      clamp(2rem, 4.4vw, 3.15rem);   /* 50.4 -- every h1 */
  --si-h2:      clamp(1.7rem, 3.2vw, 2.4rem);  /* 38.4 -- every h2 */
  --si-t-num:   1.6rem;   /* 25.6 -- the figure on a partner fact card;
                             the one size above --si-t-card, and the only
                             one on the ladder that is a display number */

  /* One source, two readers: the node row is this tall, and the rail lies at
     half of it. Written as a number in both places they drift the moment a chip
     inside the row grows -- measured, the row came out 28.4px and the rail sat
     2px above the dots. */
  --si-node-h: 26px;

  /* The air above the station row -- read twice, see .si-flow__steps. */
  --si-steps-pad: 3.75rem;

  /* The mockup's --shadow, one value for every raised surface. It was not a
     token here, and konzept-siassist said it was not worth a round of its own
     -- it is not getting one: a token and three uses, inside a round that was
     already open. */
  --si-shadow: 0 18px 40px -22px rgba(47, 62, 58, .22);

  --si-radius:    6px;
  --si-radius-lg: 12px;

  /* --- 3. Spacing: five steps, all multiples of 8 (si-fundament.md § 3) --- */
  --si-space-section: 6rem;    /* 96px -- between two sections */
  --si-space-xl:      3rem;    /* 48px -- head to content   */
  --si-space-l:       2rem;    /* 32px -- between blocks    */
  --si-space-m:       1rem;    /* 16px -- between elements  */
  --si-head-gap:      1.5rem;  /* 24px -- inside a head group: eyebrow, heading, lead */
  --si-gutter:        1.5rem;  /* 24px -- half of the g-5 row gutter; see .si-sec > .container */
  --si-space-s:       .5rem;   /*  8px -- inside an element */

  /* --- 2. The page ground ------------------------------------------------
     One number this sheet sets, and the only one: the base size. cms_core.css
     puts --bs-body-font-size at 1.25rem site-wide, and everything below a
     heading scales off it. The Scout solves the same thing with
     `.is-page { font-size: .875rem }` -- same shape, different value.

     Headings are NOT set here. They are Bootstrap's own (display-3 … h4),
     which compute with the viewport. That they do not render that way yet is
     cms_core.css:129-133, and tidying that sheet is its own round (ADR-0010).

     Ground and tokens share one rule on purpose: `.si-page` written twice is a
     second place to look, and the guard test caught exactly that. */
  font-size: 1rem;
  color: var(--si-ink);
  background: var(--si-bg);
}

/* The heading rule, and it is two corrections in one line. The weight was two
   steps too heavy (500 against 300) and the tracking ran the WRONG WAY: the
   mockup pulls the letters together, ours pushed them apart at +0.16px. That
   pair is what "the type in the mockup is finer" means (Michael, 2026-09-02).
   InterVariable carries wght 100..900, so 300 is really there -- read out of
   the font file, not assumed. */
.si-page :is(h1, h2, h3, h4) {
  margin: 0;
  font-weight: 300;
  letter-spacing: -.02em;
  line-height: 1.08;
  text-wrap: balance;
}

.si-page p { color: var(--si-ink-70); }

/* The line above a heading: uppercase, wide, quiet. `.small` is Bootstrap's
   own third text size -- .72rem in the mockup is not a step of anything. */
/* The size was the one property this rule did not set, so the `small` class the
   plugin carries won and the eyebrow came out 14px against the mockup's 11.5.
   Next to the stage name -- the same line of type, now 11.52 -- it showed
   (konzept-siassist, 2026-09-02). */
.si-eyebrow {
  font-size: var(--si-t-micro);
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--si-ink-45);
  /* The head group -- eyebrow, heading, lead -- sits on ONE gap, and it is
     1.5rem rather than the mockup's 1.1rem: Michael asked for text to have air
     against a heading and against a differently-set element (2026-09-08). That
     is a departure from the reference and it is deliberate; konzept-siassist
     measured 17.6 there and it stays reported, not silently kept.

     Before either value there was 0 between eyebrow and heading and Bootstrap's
     8px between heading and lead, which read as a heading with a caption stuck
     to it. Written as margins rather than a grid because the three are plugins
     of their own and no element wraps them. */
  margin: 0 0 var(--si-head-gap);
}

/* --- 3. Spacing -----------------------------------------------------------
   A section carries its air as PADDING, never as margin: the plugins these
   components are built from always emit their own spacing utility, and
   Bootstrap hangs !important on it -- a margin set here would be dead on
   arrival. The Scout learned that with a guard test; here it is designed in.

   Between two elements the gap belongs to the container, not to the child. */
.si-sec { padding-block: var(--si-space-section); }

/* Every section carries its OWN top and bottom padding, and the two add up
   between neighbours. There used to be a `.si-sec + .si-sec { padding-top: 0 }`
   here, from the delivery's "not 6rem on 6rem" -- it was simply wrong: the
   mockup wants the sum, and the sum is the breath of the page. Between hero and
   statement that is 96 + 88 = 184px where we had 96 (Michael, 2026-09-02).

   The partner band already needed an exception from that rule; the exception
   was the symptom.

   The nine values are the mockup's own clamps, resolving at >=1240px to
   112/96 - 88 - 104 - 104 - 88 - 88 - 72 - 88 - 88/96. */
.si-hero         { padding: clamp(3.5rem, 9vw, 7rem) 0 clamp(3.5rem, 8vw, 6rem); }
.si-statement    { padding-block: clamp(3rem, 7vw, 5.5rem); }
.si-flow         { padding-block: clamp(3.5rem, 8vw, 6.5rem); }
.si-tiles        { padding-block: clamp(3.5rem, 8vw, 6.5rem); }
.si-split--num   { padding-block: clamp(3.5rem, 7vw, 5.5rem); }
/* The one section the mockup rules off from the one above it. */
.si-split--bar   { padding-block: clamp(3.5rem, 7vw, 5.5rem); border-top: 1px solid var(--si-line-soft); }
.si-split--check { padding-block: clamp(3.5rem, 7vw, 5.5rem); }
.si-partners     { padding-block: clamp(3rem, 6vw, 4.5rem); }
.si-cta          { padding: clamp(3.5rem, 7vw, 5.5rem) 0 clamp(4rem, 8vw, 6rem); }

/* --- 4. Scroll-in (si-fundament.md § 7) -----------------------------------
   Decided for every page in the new style, not for the home page alone.

     .si-fx   above the fold -- pure CSS, paints in the first frame
     .si-rv   below it -- observer-driven, hidden only when JS can reveal it

   Two fallbacks are mandatory and both are here: without JavaScript nothing is
   ever hidden (the .si-js gate), and prefers-reduced-motion drops the movement
   rather than the content. Stagger runs through --i, 80ms a step. */
@media (prefers-reduced-motion: no-preference) {
  .si-fx {
    animation: si-rise .7s var(--si-ease, cubic-bezier(.16, 1, .3, 1)) both;
    animation-delay: calc(var(--i, 0) * 80ms);
  }
  .si-js .si-rv {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity .7s cubic-bezier(.16, 1, .3, 1), transform .7s cubic-bezier(.16, 1, .3, 1);
    transition-delay: calc(var(--i, 0) * 80ms);
  }
  .si-js .si-rv.si-rv--in { opacity: 1; transform: none; }
}

@keyframes si-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* --- 5. Components --------------------------------------------------------

   B2 si-statement -- heading left, two paragraphs right.

   The first section built, and deliberately the smallest: it forces the ladder,
   the spacing, the colours, the scroll-in, the template and the build path
   through without any of its own difficulty (2026-09-01).

   The mockup's grid is .92fr / 1.08fr. Bootstrap's twelve columns give 5/7 --
   0.833/1.167 against 0.852/1.148 of the mockup at the same gap. Close enough
   that the difference is invisible, and it costs no track definition of our
   own. Below lg the two stack, which the mockup does at 900px. */
.si-statement__body {
  display: grid;
  gap: 1.1rem;
  font-size: var(--si-t-quote);
}

.si-statement__body p { margin: 0; }
/* One rule for the whole style, not one per section: the same role carried 600
   in the statement and Bootstrap's 700 in the closing line, and in the closing
   line it also stayed on --si-ink-70 where the mockup darkens it. 500 and
   --si-ink, as the mockup has it in both places (konzept-siassist, 2026-09-01
   -- it belongs to the fundament, so it is written here at page level and not
   at a section's). */
.si-page strong { font-weight: 500; color: var(--si-ink); }

/* B1 si-hero -- opener. Text left, artwork right, logo row beneath.
   The mockup's 1.18fr/.82fr is Bootstrap's 7/5. */
/* The hero is the one place that computes its own heading size. Everywhere else
   the scale is Bootstrap's (ADR-0010); here the mockup asks for 2.35rem to 4rem
   with the viewport, and at 40px -- Bootstrap's h1 -- the opener stopped reading
   as one. Named as the exception it is, so nobody takes it for the rule. */
/* .si-sec sets `padding: 6rem 0` and thereby zeroes the horizontal padding a
   Bootstrap .container brings along. On a full-width ground that class sits on
   the ground itself, so the container inside keeps its 12px and insets that
   section's content against all the others. Zero it for every ground -- the
   selector only matches where a .container is a direct child of a .si-sec,
   which is exactly what _ground builds. */
.si-sec > .container,
.si-sec.container,
.si-psec,
.si-close,
.si-crumb__track {
  padding-inline: var(--si-gutter);
}

/* Header and footer come from the existing site and are shared with the old
   pages -- but THIS SHEET is loaded only by siassist_base.html, so a rule here
   reaches the old pages not at all. That is why the alignment is done in CSS and
   not by overriding the navbar block: overriding would mean copying base.html's
   markup into the si template, and a copy goes stale.

   Without it there were three edges on one page -- logo 52, content 64, footer
   52 (konzept-siassist, 2026-09-08). The mockup runs all three on one.

   The value is a LITERAL and not var(--si-gutter): the tokens are declared on
   .si-page, and these two elements sit outside it, so the variable is undefined
   there and the whole declaration falls to 0 -- measured, the edges moved to 40
   instead of to 64, which is worse than doing nothing. Declaring the token on
   :root instead would push one si value onto every page of the old site. The
   guard holds the literal and the token in step. */
#navbarContainer,
footer > .container {
  padding-inline: 1.5rem;
}

/* --- the navigation, on si pages only -------------------------------------
   Same reach as the gutter above: this sheet is loaded by siassist_base.html
   and by nothing else, so the old pages keep their navigation untouched.

   Michael asked for the navbar to behave like the page below it on hover, and
   for NO arrows there -- a menu is a place, not an action, and a row of arrows
   in a menu bar reads as six calls to action (2026-09-08).

   Two of the three changes are contrast, not taste, and both are measured:

     the Kontakt button carried WHITE type on gold -- 1.85:1, which is not
     readable type by any standard. It now takes the same dark ink our own gold
     buttons take, 7.23:1, and the same hover: dark gold with white on it,
     8.61:1.

     a nav link turned TERRACOTTA on hover -- #C85A2E, 3.98:1, the raw mark that
     this sheet keeps out of type everywhere else. The link keeps its ink and
     the gold rule underneath appears instead, which is what .si-tlink does.

   LITERALS, not var(). The tokens live on .si-page and the navigation is OUTSIDE
   it, so every var() here resolves to nothing and the whole declaration is
   dropped -- silently, and the rule reads correctly while doing nothing. This is
   the second time today: the header/footer gutter fifty lines up carries the
   same note, and I walked into it again anyway. #3A2E05 is --si-gold-on,
   #5C4A08 --si-gold-ink, #F4B400 --si-gold, #2F3E3A --si-ink. */
body:has(main.si-page) .navbar .nav-link-btn {
  /* `!important`, and it is the only tool that works here: cms_core.css writes
     `color: #fff !important` on this button, and nothing but another !important
     beats one. The alternative is editing that sheet, which the old pages read
     too -- and their navigation is not ours to change while both are live. */
  color: #3A2E05 !important;
}
body:has(main.si-page) .navbar .nav-link-btn:hover,
body:has(main.si-page) .navbar .nav-link-btn:focus-visible {
  /* `!important` here too, and for a reason worth naming: the resting rule above
     needs one to beat cms_core.css, and an !important beats a plain declaration
     even on :hover -- so without it the button kept its dark type on the dark
     hover ground. Measured, 1.55:1. One !important forces the next. */
  background: #5C4A08; border-color: #5C4A08; color: #FFF !important;
}
body:has(main.si-page) .navbar .nav-link:not(.nav-link-btn) {
  border-bottom: 2px solid transparent;
  transition: border-color .25s cubic-bezier(.16, 1, .3, 1);
}
body:has(main.si-page) .navbar .nav-link:not(.nav-link-btn):hover,
body:has(main.si-page) .navbar .nav-link:not(.nav-link-btn):focus-visible {
  color: #2F3E3A; border-bottom-color: #F4B400;
}

/* The dropdown -- the half of the navigation that was left in Bootstrap's own
   look. The links above it were brought over on 2026-09-08; the panel that
   opens under "Loesungen" was not, and Michael read it in the HTML before
   anyone had looked at it rendered (2026-09-08).

   LITERALS again, and this is the third rule in this sheet that has to say so:
   the panel is rendered outside main.si-page, so every var() would resolve to
   nothing and drop its whole declaration without a word. #FFFFFF is
   --si-surface, #2F3E3A --si-ink, rgba(47,62,58,.12) --si-line,
   rgba(47,62,58,.045) --si-fill, #F4B400 --si-gold, 6px --si-radius, and the
   shadow is --si-shadow.

   The hover mark is the gold BAR at the left edge, not a gold ground: the same
   decision as the nav links above, where terracotta type failed contrast and a
   rule under the word replaced it. A mark beside the word never touches the
   type it marks, so it cannot make it harder to read. */
body:has(main.si-page) .navbar .dropdown-menu {
  border: 1px solid rgba(47, 62, 58, .12);
  border-radius: 6px;
  box-shadow: 0 18px 40px -22px rgba(47, 62, 58, .22);
  background: #FFFFFF;
  padding: .35rem;
  margin-top: .5rem;
  min-width: 15rem;
}
body:has(main.si-page) .navbar .dropdown-item {
  color: #2F3E3A;
  border-radius: 4px;
  padding: .5rem .75rem .5rem .9rem;
  border-left: 3px solid transparent;
  transition: background-color .2s cubic-bezier(.16, 1, .3, 1),
              border-color .2s cubic-bezier(.16, 1, .3, 1);
}
body:has(main.si-page) .navbar .dropdown-item:hover,
body:has(main.si-page) .navbar .dropdown-item:focus-visible {
  background: rgba(47, 62, 58, .045);
  border-left-color: #F4B400;
  color: #2F3E3A;
}
/* Bootstrap paints .active with its own blue and white type. The page it is on
   is marked, not advertised: the gold bar stays, the ground stays quiet. */
body:has(main.si-page) .navbar .dropdown-item.active,
body:has(main.si-page) .navbar .dropdown-item:active {
  background: rgba(47, 62, 58, .045);
  border-left-color: #F4B400;
  color: #2F3E3A;
  font-weight: 500;
}

/* Why not 0. It WAS 0, and that is what let the page be pushed sideways on a
   phone: `.row.g-5` carries margin-inline -24px, and with a padless container
   there is nothing to absorb it -- measured 24px of overhang at 500 and 540,
   8px at 992 (konzept-siassist, 2026-09-08, reproduced here). Above 576 the
   centred container's auto margin happened to swallow it; below, the container
   is edge-to-edge and it does not.

   So the gutter must be at least the row's half-gutter, and g-5 is 3rem -> 24px.
   The alignment reason the 0 was written for is untouched: EVERY si container
   now carries the same value, so the sections still share one content edge --
   it has simply moved 24px inward, which is also why the text no longer touches
   the window edge at 360. */

/* Each section's heading is a step smaller than the one before -- the mockup's
   own clamps. Collapsed onto one size, all eight h2 came out at 32px and the
   page lost its order (konzept-siassist, 2026-09-02). At 2560px these resolve
   to 64 / 45.6 / 45.6 / 41.6 / 38.4 / 34.4 / 32.8. */
/* The hero alone: its eyebrow sits directly on the heading, where the head
   groups of flow, tiles and cta keep the 1.1rem (konzept-siassist measured all
   92 vertical pairs of the page, 2026-09-08). One section, not a family. */
/* It was 0 from 2026-09-08 morning, measured against the mockup, and Michael
   asked for air there the same afternoon. It takes the head group's own gap,
   so the hero opens like every other section rather than with a value of its
   own. A departure from the mockup, deliberate, third of the day. */
.si-hero .si-eyebrow { margin-bottom: var(--si-head-gap); }
.si-hero h1 { font-size: var(--si-h1); max-width: 19ch; }
.si-flow h2,
.si-tiles h2     { font-size: var(--si-h2); }
/* Both columns start at the top; without it the shorter one centres against the
   longer and the statement loses its baseline (mockup: align-items: start). */
.si-statement .row { align-items: start; }
.si-statement h2 { font-size: var(--si-h2); max-width: 20ch; }
.si-cta h2       { font-size: var(--si-h2); }
.si-partners h2  { font-size: var(--si-h2); }

/* The head group is capped as a GROUP -- eyebrow, heading and lead to the same
   width, which is what the mockup's .flow__head / .sol__head / .cta__head /
   .pband__head do with one max-width on the wrapper. Uncapped, "Wandel
   erkennen. Verstehen, was er verlangt. Vorteil daraus machen." stood on ONE
   line across 1320px where the mockup breaks it into three.

   Absolute pixels and not ch: ch resolves against the element's own font size,
   and the mockup's heads sit on rem values -- 16px there as here. Same size and
   same box means the same line break, which a ch value converted for a
   different base would not give (konzept-siassist measured the rendered mockup
   at 1400px, 2026-09-08; his first numbers were a conversion and wrong).

   It does not contradict Michael's rule that the lead takes the width of its
   heading -- capping the group is how that is produced. */
/* `> div >` alone caught the partner band and nothing else, so three of the four
   leads still ran the full 1272px while their headings were capped -- exactly
   the "heading capped, lead not" the cap was written to remove, only the other
   way round (measured here 2026-09-08). The reason is the same shape as the
   gutter bug: a section class sits sometimes on a wrapper AROUND the container
   and sometimes ON it, and the lead is a child in one case and a grandchild in
   the other. Both forms, once. */
:is(.si-flow, .si-flow > div) > :is(h2, .si-eyebrow, .si-split__lead) { max-width: 672px; }
:is(.si-tiles, .si-tiles > div) > :is(h2, .si-eyebrow, .si-split__lead) { max-width: 720px; }
:is(.si-cta, .si-cta > div) > :is(h2, .si-eyebrow, .si-split__lead) { max-width: 624px; }
:is(.si-partners, .si-partners > div) > :is(h2, .si-eyebrow, .si-split__lead) { max-width: 720px; }

/* 0px between heading and lead. It was there before too -- the old 1.5 line
   height left enough slack in the line box to hide it, and at 1.08 there is
   none left. A defect that another rule was covering (konzept-siassist,
   2026-09-02). */
.si-hero__lead {
  font-size: clamp(1.05rem, 1.7vw, 1.22rem); color: var(--si-ink-70);
  max-width: 46ch; margin: 1.6rem 0 0;
}

/* Two washes over the whole area, from the mockup. Without them the opener
   stands on flat white -- and put on the element that also holds the content
   width, they end at 1320px and read as a grey box instead. This class sits on
   the FULL-WIDTH ground now; the .container inside keeps the content in its
   track. Same shape as .is-process-band__ground in the Scout sheet. */
.si-hero {
  position: relative;
  overflow: hidden;
  background-image:
    radial-gradient(70% 90% at 88% 8%, rgba(244, 180, 0, .16), transparent 62%),
    radial-gradient(55% 70% at 2% 96%, rgba(209, 231, 221, .5), transparent 60%);
}

/* The drawing on the right. Decorative -- aria-hidden, no alt text -- and it
   drifts, 9s up and down by 10px. Same class of movement as the pulse, so it
   answers to the same gate. */
.si-hero__art { width: 100%; height: auto; display: block; }

@media (prefers-reduced-motion: no-preference) {
  .si-hero__art { animation: si-drift 9s ease-in-out infinite; }
}

@keyframes si-drift {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-10px); }
}
/* The mockup's own 2.4rem above and 2.6rem below, after the spacing ladder fell
   with the type ladder (konzept-siassist, 2026-09-02). Written as PADDING on
   this row rather than as margins on both: the plugins carry `m-0` and
   Bootstrap hangs !important on it, and the gap below has to sit ABOVE the logo
   row's border, where padding on that row could not put it. One element, two
   gaps, no !important anywhere. */
.si-hero__cta { display: flex; flex-wrap: wrap; gap: .85rem; margin: 0; padding: 2.4rem 0 2.6rem; }
/* The gold stroke under the lower third of the emphasised word -- the loudest
   mark in the mockup's heading, and here it had turned into a heavier word
   instead. Both together would say the same thing twice, so the weight goes
   back to the heading's own and the stroke carries the emphasis. nowrap keeps
   it from breaking across a line, where a stroke under half a word reads as a
   defect (konzept-siassist, 2026-09-01). */
.si-hero h1 em {
  font-style: normal;
  white-space: nowrap;
  background-image: linear-gradient(transparent 66%, rgba(244, 180, 0, .34) 66%);
  background-repeat: no-repeat;
  background-size: 100% 100%;
}
/* The stroke draws itself in -- and the base state above is the FULL stroke, so
   under reduced motion it simply stands there. Same lesson as the pulse: the
   quiet variant shows the thing, it does not remove it. */
@media (prefers-reduced-motion: no-preference) {
  .si-hero h1 em {
    animation: si-mark .9s var(--si-ease, cubic-bezier(.16, 1, .3, 1)) .55s both;
  }
}

@keyframes si-mark {
  from { background-size: 0% 100%; }
  to   { background-size: 100% 100%; }
}
/* The drawing is shorter than the text column, so left-aligned it hung from the
   top with 103.7px of nothing under it. The mockup's .hero__grid centres them
   (konzept-siassist, 2026-09-01). */
.si-hero .row { align-items: center; }

/* The logo row: equal optical height, unequal width. For brands that is the
   right way round -- never force a common width (delivery, section 1). */
.si-hero__logos {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--si-space-s);
  padding-top: 1.6rem; border-top: 1px solid var(--si-line);
  margin: 0; list-style: none;
}
/* Its own shadow, not --si-shadow: a raised surface lifts off the page, these
   plates only need to not disappear into the wash behind them. One value, one
   use, and it is the mockup's (konzept-siassist, 2026-09-01). */
.si-hero__logo {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--si-surface); border: 1px solid var(--si-line-soft);
  border-radius: var(--si-radius); padding: .75rem 1.15rem;
  box-shadow: 0 1px 3px rgba(47, 62, 58, .05);
}
.si-hero__logo img { height: 32px; width: auto; display: block; }

/* The measurements, on top of Bootstrap's .btn. Inheriting the skin was right;
   inheriting the SIZE was not -- Bootstrap's 6/12px padding and 16px type made
   a 38px button where the mockup has ~46 (Michael, 2026-09-02). Two class
   levels, because Bootstrap's own .btn is one. */
/* The gap is .3rem and the sign sits 8.8px from the word. Those are not the
   same number, and the difference is not a mistake: djangocms-frontend's link
   template hangs `ms-1` on the icon, and Bootstrap's spacing utilities carry
   !important -- measured, `margin-left: 0` from this sheet does not win. So the
   utility's 4px is counted IN rather than fought: 4.8 + 4 = 8.8, which is the
   value fundament.md sec 12 asks for. Change one and the other must follow;
   a guard holds them together. */
.si-page .btn {
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: var(--si-t-btn); font-weight: 500;
  padding: .85rem 1.5rem; border-radius: var(--si-radius);
}

/* Skins on Bootstrap's .btn, not buttons of our own: focus ring and states are
   inherited (delivery, "Wiederverwendete Kleinteile"). */
.si-btn--gold { background: var(--si-gold); color: var(--si-gold-on); border-color: var(--si-gold); }
/* On hover the button goes DARK and its type goes white -- Michael asked for
   white type and a white arrow because the old hover (#F4B400 -> #EDAE00) was
   barely a change (2026-09-08).

   The background has to move with it, and that is measured, not preferred:
   white on #EDAE00 is 1.97:1, which is not readable type by any standard. On
   --si-gold-ink it is 8.61:1, and the button reads as the same colour gone
   deeper rather than as a different one. The arrow follows through
   currentColor. */
.si-btn--gold:hover,
.si-btn--gold:focus-visible {
  background: var(--si-gold-ink); border-color: var(--si-gold-ink); color: #FFF;
}
.si-btn--ghost { border-color: var(--si-line); color: var(--si-ink); background: transparent; }
.si-btn--ghost:hover { border-color: var(--si-ink-45); background: rgba(47, 62, 58, .035); color: var(--si-ink); }

/* B3 si-flow -- three drawings, then three stations. */
.si-flow__viz { display: grid; grid-template-columns: 1fr auto 1fr auto 1fr; gap: var(--si-space-s); align-items: center; margin: 0; }
.si-flow__fig { margin: 0; display: grid; gap: var(--si-space-s); }
.si-flow__fig img { width: 100%; height: auto; display: block; }
/* The caption is the DARK one and the example under it the light one. We had
   both on the same grey, which put the order on its head (konzept-siassist,
   2026-09-08). */
/* `.si-page` in front, or `.si-page p` wins and the caption renders --si-ink-70 --
   the third time today that this trap has cost a rule that reads correctly. */
.si-page .si-flow__cap { text-align: center; font-size: var(--si-t-chip); font-weight: 500; line-height: 1.3; color: var(--si-ink); margin: 0; }
/* A quiet sub-line, not a label. The gold pill belongs to .flowviz__tag in the
   mockup -- the caption ABOVE the diagram, which this page does not have. The
   styling had wandered onto the wrong element: "z. B. Daten und Prognosen" is an
   aside, and an aside in a bordered capsule reads as a category. */
/* Third place under the same decision as .si-step__num and .si-tile__who: at
   12px --si-ink-45 came to 2.85:1 on the section ground. I put it here in the
   round before konzept-siassist took the colour off the other two -- found by
   sweeping every text colour on the page, not by being told. */
.si-flow__eg {
  display: block; margin-top: .25rem;
  font-size: var(--si-t-micro); font-weight: 400; line-height: 1.3;
  /* --si-ink-70 for the same reason as .si-tile__who: the mockup's --ink-45
     is 3.03:1. Only the line-height moves here. */
  color: var(--si-ink-70);
}
.si-flow__arrow { color: var(--si-gold); justify-self: center; line-height: 1; }

@media (max-width: 819.98px) {
  .si-flow__viz { grid-template-columns: 1fr; }
  .si-flow__arrow { transform: rotate(90deg); }
}

/* The three stations sit on one rail. A grid and not Bootstrap columns, because
   the chevron between two cards lives in the GAP -- with columns the space
   between them is padding inside each one, and there is nothing to sit in. */
/* One source, two readers again: the rail is absolutely positioned inside this
   element, so its `top` is measured from the padding edge -- add the air here
   only and the line ends up 60px above the dots it runs through. */
.si-flow__steps { display: grid; gap: var(--si-space-l); position: relative; padding-top: var(--si-steps-pad); }

/* The rail. It was missing from the first build: the delivery listed the
   pulsing dot as dropped, and the dot went with it -- but the pulse is
   decoration and the dot is the anchor of this line. Without it three cards
   stand side by side instead of forming a chain (konzept-siassist, 2026-09-01).

   Below 1000px it is off: the stations stack, and a horizontal line through a
   vertical list connects nothing. */
.si-flow__rail { display: none; }

/* A station: node row above, card below. The dot takes its colour from the step
   and paints it through currentColor -- a sign, never type. */
/* 1.4rem and not --si-space-m: the mockup puts 22.4px between the node row and
   the card (`.step__node { margin-bottom: 1.4rem }`), we had 16 (konzept-siassist,
   2026-09-08). Set on the gap and NOT additionally on the node -- the two would
   add up, which is how the split button reached 50px this morning. */
.si-step { display: flex; flex-direction: column; gap: 1.4rem; height: 100%; }
/* flex: 0 0 auto, or the row shrinks: it is a flex item in a column that is
   `height: 100%`, so its 26px are a suggestion until they are not. Measured
   without it: 24.19px, and the rail then ran a pixel off the dots. */
.si-step__node {
  display: flex; align-items: center; gap: .9rem;
  height: var(--si-node-h); flex: 0 0 auto;
}
.si-step--1 .si-step__node { color: var(--si-terra); }
.si-step--2 .si-step__node { color: var(--si-gold); }
.si-step--3 .si-step__node { color: var(--si-panel); }
.si-step__dot { position: relative; width: 14px; height: 14px; border-radius: 50%; background: var(--si-bg); border: 2px solid currentColor; flex: 0 0 auto; }
.si-step__dot::after { content: ""; position: absolute; inset: 2px; border-radius: 50%; background: currentColor; }

/* The pulsing ring. It was out for one day on a taste judgement that was not
   Michael's; he asked for it on 2026-09-01 ("ja soll mit rein").

   It is defined here and animated only below, under no-preference. At rest it
   is fully transparent, so under `prefers-reduced-motion: reduce` there is
   nothing standing still on the page -- the ring is simply not there, which is
   what the mockup does too. That is a duty, not an extra.

   `currentColor` again: the ring takes the phase colour from the node without
   being told, exactly as the dot and its core do. */
.si-step__dot::before {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 1px solid currentColor;
  opacity: 0;
}

@media (prefers-reduced-motion: no-preference) {
  .si-step__dot::before { animation: si-pulse 3.2s ease-out infinite; }
}

@keyframes si-pulse {
  0%          { transform: scale(.6);  opacity: .7; }
  70%, 100%   { transform: scale(1.5); opacity: 0; }
}
/* A DELIBERATE DEPARTURE FROM THE MOCKUP, not an oversight: the mockup sets
   --ink-45 here (#8A9793, 3.03:1 on white) and is itself under the floor.
   Michael wants the line on the process rail readable ("text auf der
   prozesslinie nicht zu sehr transparent"), so it takes --si-ink-70 (#5E6D68,
   5.44:1) -- still clearly quieter than the stage name beside it. Same call
   for .si-tile__who below. Do not "correct" either back to the mockup
   (konzept-siassist, 2026-09-01). */
.si-step__num { font-size: var(--si-t-micro); font-weight: 600; letter-spacing: .16em; color: var(--si-ink-70); }
/* `position: relative` is the load-bearing half, not the colour. The rail is
   `position: absolute` and the chip was `static`, so the rail painted OVER it --
   a positioned element wins against a non-positioned one in the same stacking
   context whatever the source order, and the gold line ran straight through the
   word (Michael diagnosed it, 2026-09-08). The background was already opaque
   white; making it whiter would have changed nothing at all.
   The .78 is the second half of his ask: the chip sits ON the rail rather than
   cutting a hole in it, so the line stays visible through the word. Lowered from
   .92 at his word; the contrast is measured after every change to it and must
   stay far above 4.5:1 -- at .78 it is 10.3:1. */
.si-step__stage {
  position: relative; z-index: 1;
  font-size: var(--si-t-micro); font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: var(--si-ink); padding: .26rem .6rem; border-radius: 99px; line-height: 1.15;
  background: rgba(255, 255, 255, .78); border: 1px solid var(--si-line);
}
.si-step__card {
  position: relative;
  background: var(--si-surface); border: 1px solid var(--si-line-soft);
  border-radius: var(--si-radius-lg); padding: clamp(1.5rem, 2.6vw, 2rem); box-shadow: var(--si-shadow);
  display: flex; flex-direction: column; height: 100%;
}
/* NO `gap` on the card. The mockup staggers these five from tight to wide --
   14.4 / 18.4 / 12.8 / 24 / 27.2 -- and question and body belong close together
   while the tags and the foot stand well clear. One even gap turns a staggered
   card into a list (konzept-siassist, 2026-09-02). Each child brings its own
   distance below, which is why the numbers sit on the children and not here. */
.si-step__card > * { margin-top: 0; }
/* The partner's name carries weight, the role stays small beside it -- the
   mockup's .card__who: ONE baseline row with the two ends apart, wrapping only
   when the card gets narrow (not two stacked lines). Pulled into a single 14px
   footnote joined by a middot, the head had no order left and kipped under the
   question above it (konzept-siassist, 2026-09-01).

   The sizes are the declared steps, not the mockup's literal 1.16/.8rem: the
   sheet spends four sizes on purpose (ADR-0010, si-fundament section 1), and
   two new ones for one card head would be the first of several. 1.25rem is the
   nearest step up, .875rem is the declared meta line -- which is what a role
   is. */
/* The question is 1.25rem/400, the same declared step as the name beside it and
   the lighter weight of the two. Bootstrap's h3 gave it 28px/500, so it towered
   over a 20px head; the mockup puts the two almost level (18.24 against 18.56)
   and that is what makes the card quiet. It stays an h3 -- inside a card a
   heading may carry its own size (konzept-siassist, 2026-09-01). */
/* No top margin: the gap comes from .si-step__who's padding and its rule, the
   way the mockup builds it. Set here as well it came to 18px too much. */
/* 14px, and it is a DEPARTURE from the mockup, asked for by name: the mockup
   renders 0 there -- its own `.card__q { margin-top: 1.15rem }` is overridden
   further down -- and the question then sits on the rule above it, which looks
   wrong in the mockup too. konzept-siassist withdrew his own instruction of a
   few hours earlier for this (2026-09-08). It was 1.15rem before that, which is
   why this line has now carried three different values in one day.

   `.si-step__card h3` is (0,1,1) and beats `.si-step__card > *` (0,1,0) above --
   which is what makes the value arrive at all. */
.si-step__card h3 { margin-top: 14px; font-size: var(--si-t-q); font-weight: 400; line-height: 1.3; }
/* The card's running text: the mockup's .card__body. */
/* `flex: 1` is what puts the three feet on one line. The foot's own
   `margin-top: auto` -- the mockup's mechanism, and it is still written there --
   is dead: the plugin emits `m-0` and Bootstrap hangs !important on it. Growing
   the body text pushes the foot down instead, which is the move .si-cta__box p
   already makes in this sheet (konzept-siassist, 2026-09-08: feet at 670/634/634). */
.si-step__card > p { flex: 1; margin: .8rem 0 0; font-size: var(--si-t-body); line-height: 1.62; color: var(--si-ink-70); }
.si-step__who {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: .35rem 1rem; flex-wrap: wrap; margin: 0;
  padding-bottom: .9rem; border-bottom: 1px solid var(--si-line-soft);
}
.si-step__org { font-size: var(--si-t-name); font-weight: 500; letter-spacing: -.02em; color: var(--si-ink); }
.si-step__role { font-size: var(--si-t-link); font-weight: 500; color: var(--si-ink-70); }
/* The bottom margin is 1.15rem and it is a DEPARTURE from the mockup, asked for
   by Michael (2026-09-08): there the rule of the card foot sits directly on the
   tags, 0px, measured in both. 1.15rem is the foot's own padding-top, so the
   line now has the same air above it as below -- the number is taken from the
   card rather than invented.

   Used in exactly one place, the process card, so the scope needs no selector. */
.si-tags { display: flex; flex-wrap: wrap; gap: .4rem; margin: 1.5rem 0 1.15rem; padding: 0; list-style: none; }
.si-tag { font-size: var(--si-t-tag); font-weight: 500; color: var(--si-ink-70); background: rgba(47, 62, 58, .045); border-radius: var(--si-radius); padding: .34rem .62rem; }

/* B7 si-tlink -- the quiet text link. Six of them have no target yet, and
   those were carrying Bootstrap's `text-body-secondary`: the first foreign
   colour to fall into the page, and at 14px/400 it read as text somebody left
   lying rather than as a link. A switched-off link now keeps the size, the
   weight and the si palette of an active one and only loses its colour and its
   solid edge -- the dashed edge is where the target would be. The size is the
   declared .875rem rather than the mockup's .92rem, for the reason given at
   .si-step__who. */
/* Same arithmetic as .si-page .btn above: `ms-1` adds 4px that cannot be
   overridden, so the gap carries the rest. .2rem + 4 = 7.2. */
.si-tlink {
  display: inline-flex; align-items: center; gap: .2rem;
  font-size: var(--si-t-link); font-weight: 500;
  /* Not --bs-link-color (#C85A2E): that is the raw mark, and it carries type at
     3.98:1 on the section ground. Its ink variant is what type takes. */
  color: var(--si-terra-ink);
  border-bottom: 1px solid var(--si-line); padding-bottom: 2px;
  /* The switched-off link is a direct child of .si-step__card, which is a
     column flex container -- and a flex item's `inline-flex` blockifies to
     `flex` and then stretches. Without this the dashed edge ran the full 352.7px
     of the card instead of hugging its words. Harmless where the link is not a
     flex item. */
  align-self: flex-start;
  transition:
    border-color .3s var(--si-ease, cubic-bezier(.16, 1, .3, 1)),
    gap .3s var(--si-ease, cubic-bezier(.16, 1, .3, 1));
}
/* The sign steps forward on hover. One idiom for every live text link on the
   site -- Michael asked for one sign used everywhere rather than a chevron
   here and an arrow there (2026-09-08). The gap grows as well, so the arrow
   moves and the words stay put. */
.si-tlink .bi { transition: transform .25s var(--si-ease, cubic-bezier(.16, 1, .3, 1)); }
.si-tlink:hover { border-color: var(--si-gold); gap: .45rem; }
.si-tlink:hover .bi { transform: translateX(3px); }
.si-tlink[aria-disabled="true"] {
  color: var(--si-ink-70); border-bottom-style: dashed; cursor: default;
}

/* The card's foot: a rule the width of the card, the link under it. It is a
   wrapper of its own because the mockup's line runs the full width while the
   link is only as wide as its words -- a border on the link itself would be a
   line under two words. `margin-top: auto` pushes it to the bottom, so three
   cards of different length still line their feet up. */
.si-step__foot {
  margin-top: auto; padding-top: 1.15rem; border-top: 1px solid var(--si-line-soft);
}

/* B4 si-tiles -- nine tiles in three groups. The group colour is set ONCE per
   tile as --si-cat and read by the hexagon and the rule on the left edge; a
   tile carries its key, never a colour (delivery, section 4). */
/* Padding, not margin: the plugin carries a Bootstrap spacing class and those
   are !important. The mockup gives the filter clamp(2rem,4vw,2.75rem) from the
   head, and the grid 2rem from the filter; ours had 24 and 10. */
.si-tiles__filter { display: flex; flex-wrap: wrap; gap: var(--si-space-s); margin: 0; padding: .75rem 0 0; }
/* .75rem, not the 2.75 that stood here: the lead above now brings 2rem of its
   own, and the two together made 76px to the first chip. The mockup measures 44
   there (konzept-siassist), and 12 + 32 is that. */
.si-chip {
  display: inline-flex; align-items: center; gap: .45rem; font-size: var(--si-t-chip); font-weight: 500;
  border: 1px solid var(--si-line); border-radius: 99px; padding: .45rem .9rem;
  background: transparent; color: var(--si-ink-70); cursor: pointer;
}
.si-chip i { width: 8px; height: 8px; border-radius: 50%; background: var(--si-cat, var(--si-ink-45)); flex: 0 0 auto; }
.si-chip b { font-weight: 500; font-variant-numeric: tabular-nums; }
.si-chip[aria-pressed="true"] { color: var(--si-cat-ink, var(--si-ink)); background: var(--si-cat-wash, rgba(47, 62, 58, .045)); border-color: var(--si-cat, var(--si-ink-45)); }

/* A real grid, not Bootstrap columns. The filter sets `hidden` on the tile, and
   a tile inside a column leaves the column standing -- the space stays occupied
   and the grid does not close up. That is exactly what Michael saw. As direct
   grid children the tiles are the tracks, so hiding one removes its track and
   auto-fill re-lays the rest. */
.si-tiles__grid {
  padding-top: var(--si-space-l);
  display: grid;
  gap: var(--si-space-m);
  grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr));
}

.si-tile,
.si-rel,
.si-na {
  position: relative; display: flex; flex-direction: column; height: 100%;
  background: var(--si-surface); border: 1px solid var(--si-line-soft);
  border-radius: var(--si-radius-lg); padding: clamp(1.4rem, 2.4vw, 1.9rem);
  box-shadow: var(--si-shadow);
  overflow: hidden; text-decoration: none; color: inherit;
}
.si-tile::before,
.si-rel::before,
.si-na::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: var(--si-cat, var(--si-gold)); transform: scaleY(0); transform-origin: top;
  transition: transform .5s cubic-bezier(.16, 1, .3, 1);
}
.si-tile:hover::before, .si-rel:hover::before, .si-na:hover::before { transform: scaleY(1); }
.si-tile[hidden] { display: none; }
/* display: flex, or nothing is drawn. The row is a <span>, and so is the
   hexagon -- an inline box ignores width and height, so the 44px square came out
   as 2 x 22px and the mask had nothing to fill. Measured, not guessed. */
.si-tile__top { display: flex; align-items: flex-start; justify-content: space-between; gap: .75rem; }

.si-tile__foot { display: flex; }

.si-tile__hex {
  display: block;
  width: 44px; height: 44px; border-radius: var(--si-radius); flex: 0 0 auto;
  background: var(--si-cat-wash, #FDF4DC);
  border: 1px solid var(--si-cat-line, rgba(244, 180, 0, .45));
  position: relative;
}

/* The stencil sits inside the plate and is filled with the group colour --
   that is the whole point of a mask here: the shape comes from the file, the
   colour from the sheet, exactly as currentColor would have done inline. */
.si-tile__hex::before {
  content: ""; position: absolute; inset: 7px;
  background: var(--si-cat, var(--si-gold));
  -webkit-mask: var(--si-hex) center / contain no-repeat;
  mask: var(--si-hex) center / contain no-repeat;
}

/* --- the nine hexagons, as CSS masks --------------------------------------
   They stay symbols in the code and not pictures in the Filer (Michael,
   2026-09-01) -- but not as inline markup, which is where the first attempt
   went. The text plugin sanitises its body and removes `<svg>` outright, so an
   inline symbol never reaches the page.

   A mask does reach it, and it keeps the property the whole decision rested on:
   the shape is a stencil, `background: currentColor` fills it, so a tile still
   inherits its group colour from the stylesheet. konzept-siassist weighed this
   route on 2026-09-01 and set it aside only because it would have meant two
   mechanisms for twelve files -- the three drawings went to the Filer instead,
   so it is now the only mechanism for the nine that stayed.

   Each stencil is the mockup's path data, unchanged, url-encoded. */
.si-hex--innovation-scout { --si-hex: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M16%202.5%2028%209.5v13L16%2029.5%204%2022.5v-13z%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.8%22%2F%3E%3Ccircle%20cx%3D%2214.5%22%20cy%3D%2214.5%22%20r%3D%224.5%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.8%22%2F%3E%3Cpath%20d%3D%22M18%2018l4%204%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.8%22%20stroke-linecap%3D%22round%22%2F%3E%3C%2Fsvg%3E"); }
.si-hex--kompetenz-kompass { --si-hex: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M16%202.5%2028%209.5v13L16%2029.5%204%2022.5v-13z%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.8%22%2F%3E%3Cpath%20d%3D%22M11%2020l4.5-9%204.5%209-4.5-2.5z%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.8%22%20stroke-linejoin%3D%22round%22%2F%3E%3C%2Fsvg%3E"); }
.si-hex--green-skills-kompass { --si-hex: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M16%202.5%2028%209.5v13L16%2029.5%204%2022.5v-13z%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.8%22%2F%3E%3Cpath%20d%3D%22M16%2021.5c0-4%202-6.5%205.5-7.5-.5%204.5-2.5%207-5.5%207.5zM16%2021.5c0-4-2-6.5-5.5-7.5.5%204.5%202.5%207%205.5%207.5z%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linejoin%3D%22round%22%2F%3E%3C%2Fsvg%3E"); }
.si-hex--econa { --si-hex: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M16%202.5%2028%209.5v13L16%2029.5%204%2022.5v-13z%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.8%22%2F%3E%3Cpath%20d%3D%22M11%2020.5v-4M15%2020.5v-8M19%2020.5v-5.5M23%2020.5v-9%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.8%22%20stroke-linecap%3D%22round%22%2F%3E%3C%2Fsvg%3E"); }
.si-hex--future-skills-map { --si-hex: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M16%202.5%2028%209.5v13L16%2029.5%204%2022.5v-13z%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.8%22%2F%3E%3Cpath%20d%3D%22M10.5%2020.5l4-4%203%202.5%204-6.5%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.8%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%2F%3E%3Ccircle%20cx%3D%2221.5%22%20cy%3D%2212.5%22%20r%3D%221.7%22%20fill%3D%22currentColor%22%2F%3E%3C%2Fsvg%3E"); }
.si-hex--job-architektur { --si-hex: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M16%202.5%2028%209.5v13L16%2029.5%204%2022.5v-13z%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.8%22%2F%3E%3Cpath%20d%3D%22M16%2012.5v3.5M11%2021v-2.5h10V21%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%2F%3E%3Ccircle%20cx%3D%2216%22%20cy%3D%2211%22%20r%3D%221.7%22%20fill%3D%22currentColor%22%2F%3E%3Ccircle%20cx%3D%2211%22%20cy%3D%2222%22%20r%3D%221.7%22%20fill%3D%22currentColor%22%2F%3E%3Ccircle%20cx%3D%2221%22%20cy%3D%2222%22%20r%3D%221.7%22%20fill%3D%22currentColor%22%2F%3E%3C%2Fsvg%3E"); }
.si-hex--szenarioplanung { --si-hex: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M16%202.5%2028%209.5v13L16%2029.5%204%2022.5v-13z%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.8%22%2F%3E%3Cpath%20d%3D%22M10.5%2016.5h3.5l3.5-4.5h4.5M17.5%2021h4.5%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%2F%3E%3Cpath%20d%3D%22M14%2016.5l3.5%204.5%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%2F%3E%3C%2Fsvg%3E"); }
.si-hex--toolbox { --si-hex: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M16%202.5%2028%209.5v13L16%2029.5%204%2022.5v-13z%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.8%22%2F%3E%3Cpath%20d%3D%22M10.5%2012.5h11M10.5%2016h11M10.5%2019.5h7%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.8%22%20stroke-linecap%3D%22round%22%2F%3E%3C%2Fsvg%3E"); }
.si-hex--kompetenz-landkarte { --si-hex: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M16%202.5%2028%209.5v13L16%2029.5%204%2022.5v-13z%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.8%22%2F%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%2213%22%20r%3D%221.8%22%20fill%3D%22currentColor%22%2F%3E%3Ccircle%20cx%3D%2220%22%20cy%3D%2212%22%20r%3D%221.8%22%20fill%3D%22currentColor%22%2F%3E%3Ccircle%20cx%3D%2216%22%20cy%3D%2220%22%20r%3D%221.8%22%20fill%3D%22currentColor%22%2F%3E%3Cpath%20d%3D%22M12%2013l8-1-4%208z%22%20stroke%3D%22currentColor%22%20stroke-width%3D%221.4%22%20stroke-linejoin%3D%22round%22%2F%3E%3C%2Fsvg%3E"); }

.si-tile h3, .si-rel h3 { margin: 1.1rem 0 0; font-size: var(--si-t-card); font-weight: 500; letter-spacing: -.02em; line-height: 1.25; }
.si-tile p:not(.si-pident), .si-rel p:not(.si-pident) { margin: .7rem 0 0; font-size: var(--si-t-tile); color: var(--si-ink-70); flex: 1; }
.si-tile__foot {
  margin-top: 1.4rem; padding-top: .9rem; border-top: 1px solid var(--si-line-soft);
  display: flex; align-items: center; justify-content: space-between; gap: .75rem;
}
/* --si-ink-70, not the mockup's --ink-45: 3.03:1 is under the floor and
   Michael asked for it readable (2026-09-01). Size and line-height follow
   the mockup, the colour does not -- see the guard that says so. */
.si-tile__who { font-size: var(--si-t-who); line-height: 1.3; color: var(--si-ink-70); }
.si-tile__badge {
  font-size: var(--si-t-badge); font-weight: 600; letter-spacing: .1em; padding: .22rem .58rem;
  border-radius: 99px; color: var(--si-cat-ink, var(--si-ink)); background: var(--si-cat-wash, rgba(47, 62, 58, .045));
}
.si-tile__foot i { color: var(--si-cat, var(--si-gold)); }

/* One column, two from 760, three from 1100 -- the mockup's `.rel` and `.rel--3`
   (konzept-siassist measured them, 2026-09-08). It used to jump straight from one
   to three at 768, which put three 240px cards on a tablet. The top margin is the
   head group's gap: the eyebrow above belongs to this block. */
.si-rel-grid { display: grid; gap: var(--si-space-m); margin-top: var(--si-head-gap); }
@media (min-width: 760px) { .si-rel-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .si-rel-grid { grid-template-columns: repeat(3, 1fr); } }
/* The stacked section head: the lead under the heading, not beside it (mockup
   `.wrap` without `sec__grid`). 570px and not the delivery's first "30ch" --
   fundament sec 13, absolute numbers, because our ch is not the mockup's ch. */
/* `.si-page` in front, or `.si-psec h2` (0,1,1) beats the class (0,1,0) and the
   cap stays at its 22ch -- 396px, measured. Fifth time today. */
.si-page .si-psec__head { max-width: 570px; margin-top: 1rem; }
/* The head group's own gap, like everywhere else -- it was 0 here, and the
   lead touched the heading (Michael, 2026-09-08). */
.si-page .si-psec__head + .si-psec__lead { margin-top: var(--si-head-gap); }

/* --- the partner pages: number strip, people, screenshots ------------------
   Values from partner.md part A (konzept-siassist, 2026-09-08), measured in the
   rendered mockup at 1400px -- but written as LADDER RUNGS, not as those raw
   numbers. The ladder guard refused the raw set and it was right to: six sizes
   appeared that no rung declares. Five of them land within 0.32px of an existing
   rung and take it (13.6 and 14.08 -> --si-t-chip, 14.72 -> --si-t-link,
   15.2 -> --si-t-btn, 16.8 -> --si-t-quote), which is the same call
   konzept-siassist made three times today for differences of that size. The
   figure on a fact card is the exception: 25.6px is a display size with nothing
   near it, so it becomes a rung of its own rather than a number in a rule. */

/* The top margin is the head group's gap where an eyebrow stands above the
   strip (newsletter page, 24px) and the section's step where it follows text.
   One value: 24 reads correctly in both. */
.si-facts { display: grid; gap: .85rem; margin-top: var(--si-head-gap); }
@media (min-width: 700px) { .si-facts { grid-template-columns: repeat(3, 1fr); } }
.si-fact {
  background: var(--si-surface); border: 1px solid var(--si-line-soft);
  border-radius: var(--si-radius-lg); padding: 1.35rem 1.5rem; box-shadow: var(--si-shadow);
}
/* `.si-page p` (0,1,1) would take both of these, so both carry the page class --
   the trap that cost five corrections on "Ueber SIAssist" the same day. */
.si-page .si-fact__n { margin: 0; font-size: var(--si-t-num); font-weight: 300; letter-spacing: -.03em; color: var(--si-ink); }
.si-page .si-fact__t { margin: .35rem 0 0; font-size: var(--si-t-chip); color: var(--si-ink-70); }

.si-people { display: grid; gap: .85rem; margin-top: var(--si-space-m); }
@media (min-width: 760px) { .si-people { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); } }
.si-person {
  background: var(--si-surface); border: 1px solid var(--si-line-soft);
  border-radius: var(--si-radius-lg); padding: clamp(1.4rem, 2.4vw, 1.85rem);
  box-shadow: var(--si-shadow); display: grid; gap: .9rem;
}
.si-person__head { display: flex; align-items: center; gap: .9rem; }
.si-person__badge {
  width: 44px; height: 44px; flex: none; border-radius: 50%;
  background: var(--si-gold-wash); border: 1px solid var(--si-gold-wash-line);
  color: var(--si-gold-ink); font-size: var(--si-t-btn); font-weight: 500; letter-spacing: .02em;
  display: flex; align-items: center; justify-content: center;
}
.si-person__who { display: grid; }
.si-person__who b { font-size: var(--si-t-quote); font-weight: 500; letter-spacing: -.02em; color: var(--si-ink); }
.si-page .si-person__role { margin: 0; font-size: var(--si-t-chip); color: var(--si-ink-45); }
/* An address is content, so it wraps rather than pushing the card wide. */
.si-person__ways { display: grid; gap: .2rem; font-size: var(--si-t-link); overflow-wrap: anywhere; }
.si-person__ways a { color: var(--si-ink-70); text-decoration: none; border-bottom: 1px solid var(--si-line); }
.si-person__ways a:hover { color: var(--si-ink); border-color: var(--si-gold); }

.si-shots { display: grid; gap: 1rem; margin-top: var(--si-space-l); }
@media (min-width: 900px) {
  .si-shots { grid-template-columns: 1fr 1fr; }
  /* The first one runs across both columns -- delivery, part A/4. */
  .si-shot:first-child { grid-column: 1 / -1; }
}
.si-shot img {
  display: block; width: 100%; height: auto; background: #FFF;
  border: 1px solid var(--si-line-soft); border-radius: var(--si-radius-lg); box-shadow: var(--si-shadow);
}
.si-page .si-shot__cap { margin: .55rem 0 0; font-size: var(--si-t-chip); line-height: 1.4; color: var(--si-ink-45); }

/* The variant whose items open with a line of their own. In si_checks a marked
   opening stays IN the line; here it is a block above the body -- two different
   things the mockup keeps apart, so the sheet does too. */
.si-checks--lead .si-checks__lead { display: block; font-weight: 500; color: var(--si-ink); }

/* A subheading inside running text. Its size is a heading's, not emphasis's --
   which is why it is an h2 and not a bold paragraph (news.md part B). */
/* .75rem ON TOP of the grid gap, not instead of it: the delivery's "12px
   above" is a margin, and .si-prose is a grid whose gap already separates the
   blocks. 24 + 12 = 36 above a subheading, 24 between paragraphs. */
.si-page .si-prose__h { font-size: var(--si-t-num); font-weight: 300; color: var(--si-ink); margin: .75rem 0 0; }
.si-page .si-prose__h:first-child { margin-top: 0; }

/* The head of a news post, and the body under it. Absolute caps, fundament
   sec 13 -- news.md part B. The post has no second column: head and body stand
   at the content edge, not centred. */
.si-natop { max-width: 840px; }
.si-page .si-natop h1 { font-size: var(--si-h1); font-weight: 300; margin: 1.1rem 0 0; max-width: none; }
.si-page .si-natop__lead { font-size: var(--si-t-lead); color: var(--si-ink-70); max-width: 696px; margin: 1.35rem 0 0; }
/* `.si-page` in front, and it is load-bearing: `.si-prose` ties this on
   specificity (both 0,1,0) and stands 400 lines LATER, so it won -- the body
   measured 680px, its 68ch, instead of 816. Sixth time today that a correct-
   looking rule lost to one that merely came after it.

   The paragraph gap is the grid's `gap`, not a margin: .si-prose is a grid, and
   a margin would have been ADDED to the 1.05rem gap rather than replacing it. */
.si-page .si-prose--wide { max-width: 816px; margin-top: 2.75rem; gap: 1.5rem; }

/* --- the contact form -----------------------------------------------------
   The plugin is `cms_plugin_contact`, unchanged: it sends mail and carries the
   reCAPTCHA consent gate, and the mockup's form does neither. Everything here
   is scoped to `.si-page`, so the same plugin on an old page is untouched.

   What this CANNOT reach is the markup: the template uses Bootstrap's
   `form-floating`, so the label sits IN the field and shrinks on focus, where
   the mockup puts it above. Changing that means a second template for a shared
   plugin -- reported rather than done. Values from kontakt.md part B. */
.si-page .si-form {
  background: var(--si-surface); border: 1px solid var(--si-line-soft);
  border-radius: var(--si-radius-lg); padding: clamp(1.5rem, 3vw, 2.15rem);
  box-shadow: var(--si-shadow); max-width: 544px;
}
.si-page .si-form__fields { display: grid; gap: 1.1rem; }
.si-page .si-field { display: grid; gap: .45rem; }
.si-page .si-field > label { font-size: var(--si-t-chip); font-weight: 500; color: var(--si-ink); }
.si-page .si-form .form-control {
  font-size: var(--si-t-tile); background: var(--si-bg);
  border: 1px solid var(--si-line); border-radius: var(--si-radius);
  padding: .7rem .85rem;
}
.si-page .si-field__fine { margin: .15rem 0 0; font-size: var(--si-t-who); color: var(--si-ink-45); }
.si-page .si-form .contact-submit { margin-top: 1.35rem; }
.si-page .si-form .form-control:focus {
  border-color: transparent; box-shadow: 0 0 0 2px var(--si-gold); background: var(--si-bg);
}
.si-page .si-form textarea.form-control { min-height: 7rem; resize: vertical; }
/* The submit button takes the gold skin without carrying its class: the template
   is shared and writes `btn btn-secondary`. */
.si-page .si-form .contact-submit {
  background: var(--si-gold); border-color: var(--si-gold); color: var(--si-gold-on);
  font-size: var(--si-t-btn); font-weight: 500; padding: .85rem 1.5rem; border-radius: var(--si-radius);
}
/* The same hover as .si-btn--gold above -- it is the same button wearing the
   plugin's class instead of ours. */
.si-page .si-form .contact-submit:hover:not(:disabled) {
  background: var(--si-gold-ink); border-color: var(--si-gold-ink); color: #FFF;
}
.si-page .si-form__note { max-width: 544px; margin: 1rem 0 0; font-size: var(--si-t-chip); color: var(--si-ink-45); }

/* One sentence on a contact card, above the ways to reach the person. */
.si-page .si-person__line { margin: 0; font-size: var(--si-t-go); color: var(--si-ink-70); }
@media (min-width: 1100px) { .si-people { grid-template-columns: repeat(3, 1fr); } }

/* --- a legal text ----------------------------------------------------------
   One column, three levels, no ornament. Values from rechtstexte.md part B.
   720px is about 75 characters: a legal text is read, not skimmed.

   h3 is the third level -- 25.6/400 -- and it is the same size and the same role
   as the subheadings inside a news article: a heading that divides a flow of
   text rather than opening a section. */
/* No top margin of its own: the head section and this one already bring their
   own padding, and adding 48 on top made 172px where the delivery asks for 48.
   The number it lands on is reported rather than forced -- forcing it would
   mean taking the padding off one section, which breaks the page's rhythm for
   one page. */
.si-legal { max-width: 720px; }
.si-page .si-legal p { margin: 0 0 1.05rem; font-size: var(--si-t-tile); line-height: 1.62; color: var(--si-ink-70); }
.si-page .si-legal h2 { font-size: var(--si-h2); font-weight: 300; color: var(--si-ink); margin: var(--si-space-xl) 0 var(--si-head-gap); }
.si-page .si-legal h3 { font-size: var(--si-t-num); font-weight: 400; color: var(--si-ink); margin: var(--si-space-l) 0 .75rem; }
.si-page .si-legal :is(h2, h3):first-child { margin-top: 0; }
.si-legal ul, .si-legal ol { margin: 0 0 1.05rem; padding-left: 1.15rem; }
.si-page .si-legal li { font-size: var(--si-t-tile); line-height: 1.62; color: var(--si-ink-70); margin-bottom: .75rem; }
/* `overflow-wrap: anywhere` because a legal text quotes URLs in full, and one
   of them is 435px wide: at 360 the whole page could be pushed 99px sideways
   (measured on the Datenschutzerklaerung). A legal text cannot shorten its
   own links, so the setting has to allow the break. */
.si-legal a { color: var(--si-terra-ink); text-decoration: none; border-bottom: 1px solid var(--si-line);
  overflow-wrap: anywhere; }
.si-legal a:hover { border-color: var(--si-gold); }

/* --- the news card ---------------------------------------------------------
   Shell shared with .si-tile (see the selector lists above); innards its own --
   a header row instead of a symbol, no foot rule, and a lift on hover.
   Values from news.md part A. */
.si-na-grid { display: grid; gap: .9rem; margin-top: var(--si-space-l); }
@media (min-width: 820px) { .si-na-grid { grid-template-columns: 1fr 1fr; } }
.si-na { gap: .75rem; transition: transform .3s var(--si-ease, cubic-bezier(.16, 1, .3, 1)), border-color .3s; }
.si-na:hover { transform: translateY(-4px); border-color: var(--si-line); }
.si-na__head { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .8rem; }
.si-na__tag {
  font-size: var(--si-t-micro); font-weight: 600; letter-spacing: .12em; text-transform: uppercase;
  color: var(--si-gold-ink); background: var(--si-gold-wash);
  border: 1px solid var(--si-gold-wash-line); border-radius: 99px; padding: .22rem .6rem;
}
/* Tabular figures, so five dates under each other line up on the dot. */
.si-na__date { font-size: var(--si-t-micro); color: var(--si-ink-45); font-variant-numeric: tabular-nums; }
.si-page .si-na h3 { margin: 0; font-size: var(--si-t-q); font-weight: 500; letter-spacing: -.02em; line-height: 1.3; }
.si-page .si-na p { margin: 0; font-size: var(--si-t-tile); color: var(--si-ink-70); flex: 1; }
.si-na__go { display: flex; align-items: center; gap: .3rem; font-size: var(--si-t-go); font-weight: 500; color: var(--si-gold-ink); }
.si-na__go--off { color: var(--si-ink-45); border-bottom: 1px dashed currentColor; align-self: flex-start; }

/* --- the partner tile ------------------------------------------------------
   Shell shared with .si-tile above, innards its own: no hexagon, no family, and
   a foot that LEADS instead of naming who is behind it. The left edge stays gold:
   the mockup sets no category on these tiles either, so the fallback is the
   value -- not an omission. */
.si-rel__foot {
  margin-top: 1.4rem; padding-top: .9rem; border-top: 1px solid var(--si-line-soft);
  display: flex; align-items: center; gap: .55rem;
  font-size: var(--si-t-go); font-weight: 500; color: var(--si-cat, var(--si-gold));
}
/* No arrow while the target does not exist: it would promise a click the page
   cannot honour. The dashed rule is the same sign .si-tlink uses for it. */
/* The switched-off foot is the same shape as the live one, only muted -- it
   carries the arrow too since 2026-09-08. The dashed stub that stood here
   instead was a second vocabulary for 'not yet', and one sign everywhere was
   what Michael asked for. */
.si-rel__go--off, .si-na__go--off { opacity: .55; }

/* The three partner marks. Same component as the family mark, different
   vocabulary -- konzept-siassist, 2026-09-08. --si-cat rides along so the
   tile's left edge and the dot cannot drift apart. */
/* No `.si-rel .si-pident { color: inherit }` here, although it looks tidy: it is
   (0,2,0) and the three variants are (0,1,0), so it beat all three and every mark
   came out --si-ink. Measured, not reasoned. The dot already takes currentColor
   from the shared rule above. */

/* The three groups, each named once. */
.si-cat--innovation   { --si-cat: var(--si-gold);  --si-cat-ink: var(--si-gold-ink); --si-cat-wash: #FDF4DC; --si-cat-line: rgba(244, 180, 0, .45); }
.si-cat--analyse      { --si-cat: var(--si-ana);   --si-cat-ink: var(--si-ana-ink);  --si-cat-wash: #E7F1ED; --si-cat-line: rgba(66, 121, 106, .34); }
.si-cat--entscheidung { --si-cat: var(--si-dec);   --si-cat-ink: var(--si-dec-ink);  --si-cat-wash: #E5EEF4; --si-cat-line: rgba(58, 106, 140, .32); }

/* B5/6/8 si-split -- head left, list right. One form, three marks: a count, a
   bar, a check. Three components would be three truths for one grid. */
/* No max-width: the lead runs to the width of its own heading. The Scout
   settled the same question on 2026-09-01 -- there the element was
   is-sec__intro and Michael asked for the full width. Same thing, other sheet. */
/* No size of its own: the mockup's section leads are the base size, and 1.25rem
   is not a rung of its ladder. It read as a lead because it is grey and stands
   under a heading, not because it was 20px. */
/* 19px, because the mockup's section leads inherit ITS base of 19 and ours
   inherit 16 -- the same "no size of its own" produced two different sizes
   (konzept-siassist, 2026-09-08). The numbered section is the mockup's own
   exception: .appr__head p sets 1rem there, so --num keeps 16.
   Only the home page uses this class; the sub-pages have si-psec__lead. */
/* Bottom margin as well as top: the lead is the last line of a head group and
   whatever follows it is set differently -- a button, a card row, a filter bar.
   With none, the partner band's cards overlapped it by 16px and the buttons of
   the two split sections sat 18px under their text (Michael, 2026-09-08). */
.si-split__lead { font-size: var(--si-t-lead); color: var(--si-ink-70); margin: var(--si-head-gap) 0 var(--si-space-l); }
.si-split--num .si-split__lead { font-size: 1rem; }
/* The CTA is the last element of the head column and carried no spacing at all:
   the lead sets its own top margin, the button set none, so it sat flush under
   the paragraph -- 0px, measured in the draft by konzept-siassist on
   2026-09-08. The mockup groups head and button in one grid at gap: 1.1rem, so
   1.1rem is the delivered value; it is set here the way this sheet sets every
   other one, as a top margin on the element itself, like the lead above.
   Scoped to .si-split rather than to the button skin: si_split builds exactly
   one button and it is always this one. si_flow, si_cta and the contact card
   were measured in the same pass and are right as they stand -- a rule on
   .si-btn--gold would have moved those too. */
/* 0, not 1.1rem: the lead above it now carries the whole gap. Both together
   measured 50px where the section wants 32 (Michael, 2026-09-08). A button
   that does NOT follow a lead keeps this at 0 as well -- there is none on
   these pages, and the day one appears it should say its own distance. */
.si-split .btn { margin-top: 0; }
/* The measure belongs to the heading, not to the lead: with the head column
   grown from 4/12 to 5/12 and 6/12, a heading would otherwise run the whole
   width of it. The three values are the mockup's own (konzept-siassist,
   2026-09-01). The lead stays uncapped -- that was decided and does not move. */
.si-split--num h2   { font-size: var(--si-h2); max-width: 24ch; }
.si-split--bar h2   { font-size: var(--si-h2); max-width: 26ch; }
.si-split--check h2 { font-size: var(--si-h2); max-width: 22ch; }
/* .ins__grid is the one of the three that centres its two columns. */
.si-split--bar > .row { align-items: center; }
.si-split__list { display: grid; border-top: 1px solid var(--si-line); margin: 0; padding: 0; list-style: none; }
.si-split__list li {
  display: grid; grid-template-columns: auto 1fr; gap: var(--si-space-m); align-items: baseline;
  padding: .95rem .25rem; border-bottom: 1px solid var(--si-line-soft);
}
.si-split__list li::before { color: var(--si-ink-45); font-weight: 600; }
.si-split--num .si-split__list { counter-reset: si-split; }
.si-split--num .si-split__list li { counter-increment: si-split; }
.si-split--num .si-split__list li::before { content: counter(si-split, decimal-leading-zero); font-size: var(--si-t-micro); letter-spacing: .08em; font-variant-numeric: tabular-nums; }
/* NOT the same form with another mark. The delivery said "three sections, one
   component, three marks"; that holds for --num and --check, both ruled lists,
   and not for this one: the mockup's .topics are white cards with a 1px edge
   and a 6px radius, and no rules at all (konzept-siassist, 2026-09-01, who
   corrected their own delivery). The bar is a fixed 3 x 20, not a stretch --
   the cards are not all one height. */
.si-split--bar .si-split__list { border-top: 0; gap: .55rem; }
.si-split--bar .si-split__list li {
  align-items: center; gap: .85rem; font-size: var(--si-t-body);
  background: var(--si-surface); border: 1px solid var(--si-line-soft);
  border-radius: var(--si-radius); padding: .9rem 1.1rem;
}
.si-split--bar .si-split__list li::before {
  content: ""; width: 3px; height: 20px; background: var(--si-gold); border-radius: 2px;
}
.si-split--check .si-split__list li::before { content: "\f26e"; font-family: bootstrap-icons; color: var(--si-gold); }

/* The closing line is a foot, not a block: a rule above it, the sentence left,
   the button right on the same line -- the mockup's .flow__foot. It stacked,
   with the button below the sentence and no rule at all. The 820px breakpoint
   is the mockup's own; below it the two stack, which is what they should do. */
.si-flow__closing {
  border-top: 1px solid var(--si-line); padding-top: 1.75rem;
  display: grid; gap: 1.25rem; align-items: center;
}
@media (min-width: 820px) {
  .si-flow__closing { grid-template-columns: 1fr auto; }
}
/* Bootstrap's `p { margin-bottom: 1rem }` survives into the grid, and
   align-items centres the MARGIN box -- which put the sentence 8px above the
   button's centre. The gap between two items belongs to the container here,
   like everywhere else in this sheet. */
.si-flow__closing p { margin-bottom: 0; }

/* B7 si-partners -- three cards on the dark panel. Names as type, no logos:
   the same three marks twice on one page is repetition without gain. */
/* No radius and no padding of its own: it is a band across the window, and a
   band has no corners. The vertical rhythm comes from .si-sec like everywhere
   else, the width from the .container inside (konzept-siassist, 2026-09-01). */
.si-partners { background: var(--si-panel); color: var(--si-panel-ink); }
.si-partners h2, .si-partners .si-eyebrow { color: inherit; }
/* Two rules, and the pair is the point. `.si-page p` sets --si-ink-70 for every
   paragraph on the page, and on this ground that is dark green on dark green --
   so the panel needs a default of its own at the same weight (0,1,1). But that
   default then also beats `.si-partner__name` at (0,1,0), which is how the
   firm's name came to carry the ink of the sentence under it. Giving the name a
   second class is what lifts it clear.

   Both halves were only visible at the built page: removing the panel default
   made the name WORSE (1.81:1), because the rule it had been masking was the
   page-wide one. */
.si-partners p { color: var(--si-panel-ink-70); }
.si-partners .si-partner__name { color: var(--si-panel-ink); }
.si-partner {
  border: 1px solid var(--si-panel-line); border-radius: var(--si-radius-lg);
  padding: 1.35rem 1.5rem; background: rgba(255, 255, 255, .045);
  /* A hairline of light on the top edge -- on a dark ground that is the whole
     difference between a surface and a card. Its own value, like the hero's
     logo plates: --si-shadow lifts something off the page, this only draws an
     edge (konzept-siassist, 2026-09-02). */
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .09);
  display: flex; flex-direction: column; height: 100%;
}
/* The brightest type on the card: it is the reason the card is there. */
.si-partner__name { font-size: var(--si-t-logo); font-weight: 500; letter-spacing: -.02em; margin: 0; }
.si-partner__what { margin: .45rem 0 0; font-size: var(--si-t-chip); color: var(--si-panel-ink-70); }
/* Gold on the dark panel: 6.08:1, the one place a raw mark carries type and
   the only one that passes (si-fundament.md, section 4). */
.si-partner__go {
  margin-top: auto; padding-top: .55rem;
  font-size: var(--si-t-go); font-weight: 500; color: var(--si-gold);
  display: inline-flex; align-items: center; gap: .55rem;
  /* Blockification, the same trap .si-tlink carries a note about: this is a flex
     item of the card, so `inline-flex` computes to `flex` and would stretch the
     full width of the card -- and the stroke would then sit at its far edge
     instead of after the words. */
  align-self: flex-start;
}
/* It carried the mockup's stroke until 2026-09-08 -- 20px, drawn at 60% and
   growing on hover. Michael asked for ONE sign across the site rather than a
   stroke here and an arrow on the link right below it, and the two sat on the
   same dark band a few pixels apart. So this takes the arrow like every other
   live text link, and the hover moves it the same way.
   The stroke is not "wrong" and it is the mockup's; being the only one of its
   kind is what made it go. */
.si-partner__go .bi { transition: transform .25s var(--si-ease, cubic-bezier(.16, 1, .3, 1)); }
.si-partner:hover .si-partner__go .bi { transform: translateX(3px); }

/* Link left, funding notice right, on one line -- the mockup's .pband__foot.
   Stacked, the white plate landed in the middle of the line. */
.si-partners__foot {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 1.25rem 2rem; padding-top: 1.6rem; border-top: 1px solid var(--si-panel-line);
}

/* On the dark band the link takes the panel's own line and ink -- as the mockup
   does, where .pband .tlink inherits --panel-ink. Both states needed it and for
   the same reason: the active one came out terracotta on dark green (2.65:1),
   the switched-off one would have read --si-ink-70, which is dark green on dark
   green. */
.si-partners .si-tlink { color: inherit; border-color: var(--si-panel-line); }
.si-partners .si-tlink[aria-disabled="true"] { color: var(--si-panel-ink-70); }

/* The funding logo is a JPEG and cannot be transparent, so it gets its own
   white plate rather than a white rectangle in a dark band. */
.si-partners__funding { background: var(--si-surface); border-radius: var(--si-radius); padding: var(--si-space-m); display: inline-flex; }
.si-partners__funding { max-width: 100%; }
/* The funding logo is the only image on the page without a cap, and it is
   13888x2000 -- at height:60px that is 417px, wider than a phone. It pushed
   89px past the window edge at 360 (konzept-siassist, 2026-09-08). Capping the
   HEIGHT rather than setting height:60px keeps the aspect ratio while the width
   is free to shrink. */
.si-partners__funding img { max-height: 60px; max-width: 100%; height: auto; width: auto; display: block; }

/* B9 si-cta -- two equal fields. */
.si-cta__pair { display: grid; gap: var(--si-space-m); }
/* align-items: flex-start is what keeps the button the width of its own words.
   Without it the two buttons here were the only ones on the page that stretched
   -- 586.7px against the 187-227px of the other five (konzept-siassist,
   2026-09-01). Paragraphs are unaffected: a text block sized by content still
   fills the container, because fit-content is capped by what is available. */
.si-cta__box { background: var(--si-surface); border: 1px solid var(--si-line-soft); border-radius: var(--si-radius-lg); padding: var(--si-space-l); box-shadow: var(--si-shadow); display: flex; flex-direction: column; align-items: flex-start; gap: .75rem; height: 100%; }
/* The button gets the mockup's SECOND value on top of the card's gap -- .75 + .85
   is the 26px that sets the action apart from the sentence above it, where one gap
   would space it like any other line (konzept-siassist, 2026-09-08). */
.si-cta__box .btn { margin-top: .85rem; }
/* The mockup's 1.2rem is not on the ladder; 1.25rem is the declared step above
   it, and Bootstrap's h3 (28px) was two steps too big for a card heading. */
.si-cta__box h3 { margin: 0; font-size: var(--si-t-card); font-weight: 500; }
.si-cta__box p { margin: 0; flex: 1; }

@media (min-width: 768px) {
  .si-cta__pair { grid-template-columns: 1fr 1fr; }
}

/* --- the rail, the nodes on it, and the chevron between the cards ---------- */

/* The ladder is written out instead of left to auto-fill, because auto-fill
   cannot see the difference that matters here. Bootstrap's .container steps
   540 -> 720 at 768, so the grid is 492px wide at EVERY width from 540 to 767 --
   a 600px window and a 700px one are the same number of columns to auto-fill,
   whatever the minmax. The mockup flips to two at 600 (konzept-siassist measured
   `.bento`, 2026-09-08), and only a media query can say that.

   It also keeps what auto-fill got wrong at the other end: alone it put FIVE
   251px tiles in a 1320px row and broke three of the nine titles over two lines.
   Below 600 auto-fill still governs and yields one column. */
@media (min-width: 600px) {
  .si-tiles__grid { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 992px) {
  .si-tiles__grid { grid-template-columns: repeat(3, 1fr); }
}

@media (min-width: 992px) {
  .si-flow__steps { grid-template-columns: repeat(3, 1fr); }

  /* The sign between two cards sits in the gap, on half the card's height. Not
     the mockup's rotated box -- bi-chevron-right, like every other sign on this
     page. */
  .si-step:not(:last-child) .si-step__card::after {
    content: "\f285";
    font-family: bootstrap-icons;
    position: absolute;
    top: 50%;
    right: calc(-1 * var(--si-space-l) / 2);
    transform: translate(50%, -50%);
    color: var(--si-gold);
    opacity: .75;
    line-height: 1;
  }
}

@media (min-width: 1000px) {
  .si-flow__rail {
    display: block;
    position: absolute;
    left: 0;
    right: 0;
    /* Half the node row minus half the line: the rail runs through the middle
       of the dots, and both come from --si-node-h. */
    top: calc(var(--si-steps-pad) + var(--si-node-h) / 2 - 1px);
    height: 2px;
    background: linear-gradient(90deg, #C85A2E 0%, #F4B400 50%, #2F3E3A 100%);
    opacity: .32;
    transform-origin: left;
  }

  /* It runs out from the left when the section is scrolled to. The generic
     .si-rv rule would fade and lift it instead, which is wrong for a line -- so
     the rail overrides both properties. Without JavaScript neither rule applies
     and the rail simply stands there, drawn. */
  .si-js .si-flow__rail.si-rv {
    opacity: .32;
    transform: scaleX(0);
    transition: transform 1.4s cubic-bezier(.16, 1, .3, 1);
  }

  .si-js .si-flow__rail.si-rv--in { transform: scaleX(1); }
}

/* ===========================================================================
   The sub-page layer

   The home page opens the site; these open a page. Same vocabulary, different
   rhythm -- the sections are tighter, they carry a hairline, and the head is a
   different animal from the hero. Values are the delivery's own, resolved from
   the mockup (konzept-siassist, "Loesungen", part A).
   =========================================================================== */

/* --- Breadcrumb ------------------------------------------------------------
   The separator is the sheet's chevron, not the mockup's inline <svg>: the text
   plugin drops <svg> outright. Half opacity, so it reads as punctuation. */
.si-crumb { padding-top: clamp(1.5rem, 3vw, 2.25rem); display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; font-size: var(--si-t-chip); color: var(--si-ink-45); }
.si-crumb a { color: var(--si-ink-45); text-decoration: none; }
.si-crumb a:hover { color: var(--si-ink); }
.si-crumb .bi { opacity: .5; }
.si-crumb [aria-current="page"] { color: var(--si-ink); }

/* --- The family mark -------------------------------------------------------
   The dot takes its colour from the family class the tiles already use, so a
   family is named in exactly one place. */
.si-pident { display: flex; align-items: center; gap: .5rem; margin: 0; font-size: var(--si-t-tag); font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--si-ink-70); }
.si-pident__dot { width: 9px; height: 9px; border-radius: 50%; background: currentColor; }
/* Gold, not terracotta. The family's own token is --si-cat-ink, which every
   family already sets -- naming the colour a second time here is what let this
   one drift (konzept-siassist, 2026-09-08). */
.si-cat--innovation .si-pident__dot, .si-pident.si-cat--innovation { color: var(--si-cat-ink); }
.si-cat--analyse .si-pident__dot, .si-pident.si-cat--analyse { color: var(--si-ana-ink); }
.si-cat--entscheidung .si-pident__dot, .si-pident.si-cat--entscheidung { color: var(--si-dec-ink); }

/* --si-terra-ink (#B85028) and NOT the delivery's #C85A2E, which is --si-terra:
   that is the raw mark and carries type at 3.98:1, under the floor for a 12.2px
   uppercase label. Same call as .si-tlink two hundred lines up, and the same one
   the contrast guard already records for four other roles. The other two are the
   delivery's own values: #5C4A08 is --si-gold-ink (the delivery calls it
   --si-gold-wash-ink, a second name for a colour we have), #2F3E3A is --si-ink. */
.si-page .si-pident--tecintelli { color: var(--si-terra-ink); }
.si-page .si-pident--appose     { color: var(--si-gold-ink); }
.si-page .si-pident--fraunhofer { color: var(--si-ink); }
/* `.si-page` in front is what makes these work, and it took three measurements
   to find out. The mark is a <p>, so `.si-page p` (0,1,1) outranks a bare
   `.si-pident--appose` (0,1,0) and all three rendered --si-ink-70 -- the same
   value the base rule sets, which is why it looked like the base rule winning
   and sent me after source order first. It is the fourth appearance today of the
   trap in CLAUDE.md's Gotchas. Keep the block after `.si-pident` all the same:
   with the page class they are (0,2,0) and order no longer decides, but a later
   reader moving them back would restore half the bug. */


/* --- The page head ---------------------------------------------------------
   The two washes are the hero's, on the section itself -- no bg element. */
.si-phero {
  position: relative; overflow: hidden;
  padding: clamp(1.75rem, 4vw, 2.75rem) 0 clamp(2.5rem, 5vw, 3.75rem);
  background-image:
    radial-gradient(70% 90% at 88% 8%, rgba(244, 180, 0, .16), transparent 62%),
    radial-gradient(55% 70% at 2% 96%, rgba(209, 231, 221, .5), transparent 60%);
}
.si-phero h1 { font-size: var(--si-h1); max-width: 24ch; margin: 1rem 0 0; }
/* EcoNa's second line: smaller, and part of the same heading -- not an h2. */
.si-phero__second { display: block; font-size: .6em; }
/* `.si-page` in front is load-bearing, not decoration: `.si-page p` (0,1,1) beat
   the bare class (0,1,0), so this line said --si-ink and the page rendered
   --si-ink-70. It is the sentence the page is built around; at 1.6 and grey it
   read as a second-order lead (konzept-siassist, 2026-09-08). */
.si-page .si-phero__q { font-size: clamp(1.08rem, 1.7vw, 1.28rem); line-height: 1.4; color: var(--si-ink); max-width: 44ch; margin: 1.1rem 0 0; }
.si-phero__promise { color: var(--si-ink-70); max-width: 52ch; margin: 1rem 0 0; }
/* PADDING, not margin. The plugin emits `m-0` and Bootstrap hangs !important on
   it, so the margin that stood here was dead on arrival and the gold button sat
   on the baseline of the sentence above it -- 0px, on all ten pages
   (konzept-siassist, 2026-09-08). 2.4rem is the mockup's value. */
/* A row, because a page head may carry two actions -- gold first, pale beside
   it (partner.md part B: 13.6px between them). Flex and not a margin: the
   plugin emits m-0, as everywhere. */
.si-phero__cta { padding-top: 2.4rem; display: flex; flex-wrap: wrap; gap: .85rem; }
.si-phero__side { display: grid; gap: .9rem; align-content: start; justify-items: start; }
/* The ministry's picture in a page head wears the same plate as in the partner
   band: it is a JPEG and cannot be transparent, so without one its own white
   ground stands as a hard rectangle on the hero's wash. "Dasselbe wie auf der
   Startseite" (Michael, 2026-09-08) includes the plate it sits on there. */
.si-phero__plate {
  background: var(--si-surface); border-radius: var(--si-radius);
  padding: var(--si-space-s); max-width: 100%;
}
.si-phero__plate img { display: block; width: 100%; height: auto; }
/* From 960px the side column sits at the BOTTOM RIGHT of the head, against the
   baseline of the heading block beside it. The delivery says so -- "Seitenspalte
   417 px breit, ab 960 px rechtsbuendig" (loesungen.md part B, and again in
   partner.md) -- and I built only the width. Michael saw it on the contact page
   (2026-09-08); it was wrong on all four kinds of sub-page.

   `align-items: end` goes on the row, not on the column: the column cannot move
   itself to the bottom of a flex line, only the line can put it there.

   992 and not the delivery's 960, and the difference is measured: our columns
   are Bootstrap's `col-lg`, which stack below 992. Between 960 and 991 the
   delivery's number would have produced a column standing UNDER the heading and
   still right-aligned, which is neither shape. The rule follows where the
   columns actually sit beside each other. */
@media (min-width: 992px) {
  .si-phero .row { align-items: end; }
  .si-phero__side { justify-items: end; text-align: right; }
}
.si-byline { margin: 0; font-size: var(--si-t-chip); color: var(--si-ink-45); }
.si-byline b { display: block; font-size: 1rem; font-weight: 500; color: var(--si-ink); }
.si-soon { margin: .75rem 0 0; }
/* The mark is a PILL, and that is the one place this sheet allows one -- the
   foundation reserves pills for stage names and filter buttons, and "In
   Entwicklung" is a stage name. It had become the nearest existing tag instead,
   because the delivery named the mark without giving it values; measured
   12,16/500 flat grey where the mockup has 11,2/600 in gold on gold
   (konzept-siassist, 2026-09-08). */
.si-soon__tag {
  display: inline-block; padding: .28rem .68rem;
  border: 1px solid var(--si-gold-wash-line); border-radius: 99px;
  background: var(--si-gold-wash); color: var(--si-gold-ink);
  font-size: var(--si-t-soon); font-weight: 600; letter-spacing: .12em; text-transform: uppercase;
}

/* --- A section of a sub-page ----------------------------------------------
   Tighter than .si-sec and with a hairline above; --plain drops the line for
   the opening section, which would otherwise draw one right under the head. */
.si-psec { padding-block: clamp(2.5rem, 5vw, 4rem); border-top: 1px solid var(--si-line-soft); }
.si-psec--plain { border-top: 0; }
.si-psec > .row { align-items: start; }
.si-psec h2 { font-size: var(--si-h2); max-width: 22ch; margin: 0; }
.si-psec__lead { color: var(--si-ink-70); max-width: 62ch; margin: 0 0 1.4rem; }

/* --- Running text, checked list, numbered list ----------------------------- */
.si-prose { display: grid; gap: 1.05rem; max-width: 68ch; }
.si-prose p { margin: 0; color: var(--si-ink-70); }

.si-checks { display: grid; gap: .9rem; max-width: 68ch; margin: 0; padding: 0; list-style: none; }
/* A checked list is a differently-set block, so whatever follows it keeps the
   section's distance -- 32px, fundament sec 18. It stood at 0 twice on
   "Ueber SIAssist" (Michael, 2026-09-08). The sibling selector fires only when
   something actually follows: a list that ends its section keeps its own
   spacing and does not push the section's padding out. */
.si-checks + * { margin-top: var(--si-space-l); }
.si-checks li { display: grid; grid-template-columns: auto 1fr; gap: .75rem; align-items: start; color: var(--si-ink-70); }
/* The tick is a pseudo-element, like .si-split--check: a decoration has no
   business in the content. */
.si-checks li::before { content: "\f26e"; font-family: bootstrap-icons; line-height: 1; color: var(--si-gold); transform: translateY(4px); }

.si-steps { display: grid; border-top: 1px solid var(--si-line); max-width: 74ch; margin: 0; padding: 0; list-style: none; counter-reset: si-steps; }
.si-steps li { display: grid; grid-template-columns: auto 1fr; gap: 1rem; align-items: baseline; padding: .95rem .25rem; border-bottom: 1px solid var(--si-line-soft); color: var(--si-ink-70); counter-increment: si-steps; }
/* Counted, never typed -- same rule as si_split--num and the Scout's chapters. */
.si-steps li::before { content: counter(si-steps, decimal-leading-zero); font-size: var(--si-t-micro); font-weight: 600; letter-spacing: .08em; font-variant-numeric: tabular-nums; color: var(--si-ink-45); }

/* --- The framed box (EcoNa) ------------------------------------------------ */
/* 666px and not 74ch. Our ch is not the mockup's ch -- the head groups of the
   home page made that expensive once already, so the width the mockup renders to
   is written as the number it renders to (konzept-siassist, 2026-09-08: we ran
   1272px where the mockup runs 666).

   The size is --si-t-link (14.72) and not the mockup's .93rem (14.88). The
   ladder guard refused the raw value, rightly: 0.16px is exactly the size of
   difference konzept-siassist himself ruled not worth a new rung
   (2026-09-08), and an undeclared value is how a ladder stops being one. */
.si-frame { background: var(--si-fill); border-radius: var(--si-radius-lg); padding: clamp(1.3rem, 2.2vw, 1.7rem); max-width: 666px; font-size: var(--si-t-link); }
.si-frame__label { margin: 0 0 .6rem; font-size: var(--si-t-micro); font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--si-ink-45); }
.si-frame p { margin: 0 0 .8rem; color: var(--si-ink-70); }
.si-frame p:last-child { margin-bottom: 0; }

/* --- The closing box -------------------------------------------------------
   A panel inside the track, not a band: _section and not _ground. A ground
   reaching the window would square its 12px corners off against the viewport. */
.si-close { padding-block: clamp(2.75rem, 6vw, 4.5rem); }
.si-close__in { background: var(--si-panel); border-radius: var(--si-radius-lg); padding: clamp(1.75rem, 4vw, 2.75rem);
}
.si-close__in h2 { font-size: var(--si-h2); max-width: 26ch; margin: 0; color: var(--si-panel-ink); }
/* 1.5rem above, not 1rem: the head group's gap, so this box does not sit at 16
   while every other heading on the page sits at 24 (konzept-siassist,
   2026-09-08 -- "sonst tauschen wir eine Uneinheitlichkeit gegen die naechste"). */
.si-close__in p { margin: var(--si-head-gap) 0 1.5rem; font-size: 1rem; color: var(--si-panel-ink-70); max-width: 56ch; }

/* AFTER the base rules above, not before them: this block and
   `.si-close__in p` tie on specificity, so the later one wins. Placed first, the
   paragraph kept its 1rem/1.5rem margins, they went into the grid row, and the
   button -- centred across the rows -- came out 12px off the text's middle.
   Measured twice before I looked at the order.

   Text left, button right, both on the middle line -- the mockup builds
   `.close__in` as a two-column grid (783/257 at 1400, align-items: center) and
   ours was a plain block, so the button dropped underneath (Michael, 2026-09-08).
   From 992 only: below it the two stack, which is right on a phone. */
@media (min-width: 992px) {
  .si-close__in {
    display: grid; grid-template-columns: 1fr auto; align-items: start;
    column-gap: var(--si-space-xl);
  }
  /* The three are direct children -- heading, sentence, button -- with no
     wrapper around the text, so the columns are assigned by hand. Left to the
     grid's own order the sentence would have gone into the button's column. */
  .si-close__in h2, .si-close__in p { grid-column: 1; }
  /* Two things here, and both were measured wrong first.

     `span 2`, not `1 / -1`: the rows are IMPLICIT (nothing declares
     grid-template-rows) and -1 counts the last line of the EXPLICIT grid, which
     is line 1 -- so `1 / -1` silently became one row and the button centred
     against the heading alone, 46px too high.

     And the container aligns its items to START, not center. With `center` every
     item floats in the middle of its row, including the sentence -- and the
     button, spanning both rows, made those rows taller than the text. The button
     then centred against rows that were not the text: 12px out. Items at the top,
     button centred across their span, and the two middles are the same. */
  .si-close__in .btn { grid-column: 2; grid-row: 1 / span 2; align-self: center; }
  /* The sentence's margins become the grid's row gap. As margins they sat INSIDE
     the row, so the button -- centred across both rows -- came out 12px above the
     text's own middle. Measured; as a gap the rows are exactly the two elements
     and the centre is true. */
  .si-close__in { row-gap: var(--si-head-gap); }
  .si-close__in p { margin: 0; }
}


.si-tiles {
  background: linear-gradient(180deg, transparent, var(--si-sol-band) 14%, var(--si-sol-band) 86%, transparent);
  border-block: 1px solid var(--si-line-soft);
}

/* The note under the tile grid is ONE line -- sentence and link beside each
   other, both quiet. Ours stacked them and painted the link terracotta; the
   mockup lets it inherit (konzept-siassist, 2026-09-08).

   --si-ink-70 and not the mockup's --ink-45: a whole sentence takes ink-70, a
   label without sentence structure takes ink-45 (konzept-siassist, 2026-09-08,
   after this sheet had briefly carried both). ink-45 is 3.03:1. */
.si-tiles__foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: 1rem 1.75rem;
  font-size: var(--si-t-note); color: var(--si-ink-70);
}
.si-tiles__foot p { margin: 0; color: inherit; }
.si-tiles__foot .si-tlink { font-size: inherit; color: inherit; }

/* The closing line of the numbered section, same voice as the note above. */
/* 1.4rem above it: the closing sentence sat flush on the numbered list, 0px
   (Michael, 2026-09-08). The value is the mockup's own -- `.appr__out` carries
   margin-top: 22.4px there, measured -- so it is taken, not chosen. */
.si-page .si-split__out { font-size: var(--si-t-note); color: var(--si-ink-70); margin-top: 1.4rem; }

/* Only the hero's eyebrow. `.si-page p` (0,1,1) outranks `.si-eyebrow` (0,1,0),
   so it took --si-ink-70; in the mockup it is --ink-45. The other five are
   --ink-70 there too, because .flow__head p and its siblings do the same --
   so this is one rule for one place, not a sweep. */
.si-hero .si-eyebrow { color: var(--si-ink-45); }

/* The box text in the closing section: .97rem, not the 1rem it inherited. */
.si-cta__box p { font-size: var(--si-t-tile); }
