/* ============================================================
   AnwendungSection — „Dein Alltag, einfach smart" als SPA-Sektion.
   Alltags-Anwendungsfälle (Story- oder App-Darstellung via variant).
   Markup + Logik aus „Smartmacherei - Anwendungsfälle"; CSS unter .sma.
============================================================ */
function AnwendungSection({ variant = "story" }) {
  const ref = React.useRef(null);

  const CSS = `
  .sma{ position:relative; color:var(--ink); background:#fff; font-family:'Inter',system-ui,sans-serif; -webkit-font-smoothing:antialiased;
    --cyan-grad: linear-gradient(125deg,#0a6cb6 0%,#11a8d4 28%,#1fc1c0 54%,#46bd6a 80%,#6fcf54 100%);
    --ink-faint:#8a9caa; }
  body[data-world="lox"] .sma, body[data-world="nb"] .sma{ --cyan-grad: linear-gradient(125deg,#2c8424 0%,#3c9f2c 30%,#5fc23f 62%,#8fd96a 100%); }
  .sma a{ color:inherit; text-decoration:none; }
  .sma .wrap{ max-width:1200px; margin:0 auto; padding:0 40px; }
  .sma h1, .sma h2, .sma h3{ font-family:'Outfit',sans-serif; }

  .sma .intro{ position:relative; overflow:hidden; background:var(--cyan-grad); color:#fff; padding:84px 0 96px; }
  .sma .intro::after{ content:""; position:absolute; right:-8%; top:-30%; width:60vw; height:60vw; max-width:720px; max-height:720px; border-radius:50%; pointer-events:none; background:radial-gradient(circle at 50% 50%, rgba(255,255,255,.85), rgba(255,255,255,0) 66%); opacity:.9; }
  .sma .intro .wrap{ position:relative; z-index:2; }
  .sma .eyebrow{ display:inline-flex; align-items:center; gap:9px; font-family:'JetBrains Mono',monospace; font-size:.68rem; font-weight:600; letter-spacing:.16em; text-transform:uppercase; }
  .sma .intro .eyebrow{ color:var(--on-dim); }
  .sma .eyebrow .dot{ width:7px; height:7px; border-radius:50%; background:currentColor; }
  .sma .intro h2{ font-size:clamp(2.4rem,5.4vw,4.2rem); font-weight:800; line-height:1.0; letter-spacing:-.035em; margin-top:18px; max-width:16ch; color:#fff; }
  .sma .intro h2 .light{ color:rgba(255,255,255,.6); }
  .sma .intro .lede{ margin-top:22px; font-size:1.12rem; line-height:1.55; color:var(--on); max-width:52ch; }
  .sma .intro .lede b{ font-weight:600; color:#fff; }
  .sma .daychips{ margin-top:30px; display:flex; flex-wrap:wrap; gap:9px; }
  .sma .daychip{ display:inline-flex; align-items:center; gap:8px; padding:9px 15px; border-radius:100px; background:rgba(255,255,255,.16); border:1px solid rgba(255,255,255,.26); font-size:.86rem; font-weight:500; color:#fff; cursor:pointer; transition:background .2s, transform .2s; }
  .sma .daychip:hover{ background:rgba(255,255,255,.28); transform:translateY(-1px); }
  .sma .daychip .cdot{ width:9px; height:9px; border-radius:50%; }

  .sma section.band{ padding:88px 0; }
  .sma .sec-head{ max-width:720px; }
  .sma .sec-head h2{ font-size:clamp(1.9rem,3.6vw,3rem); font-weight:700; letter-spacing:-.03em; line-height:1.04; margin-top:14px; color:var(--ink); }
  .sma .sec-head .sub{ margin-top:16px; font-size:1.06rem; line-height:1.55; color:var(--ink-soft); max-width:56ch; }
  .sma .sec-eyebrow{ color:var(--deep); }

  .sma .cases{ margin-top:56px; display:flex; flex-direction:column; gap:30px; }

  /* Timeline (desktop): links Tagesablauf-Liste, rechts eine grosse sticky Buehne. */
  .sma .cases-timeline{ display:grid; grid-template-columns:0.86fr 1.14fr; gap:54px; }
  .sma .tl-col{ position:relative; }
  .sma .tl-col::before{ content:""; position:absolute; left:6px; top:8px; bottom:8px; width:2px; background:var(--tile-line); }
  .sma .tl-entry{ position:relative; padding:18px 20px 18px 34px; border-radius:18px; border:1px solid transparent; transition:background .3s ease, border-color .3s ease, transform .3s ease, box-shadow .3s ease; }
  .sma .tl-dot{ position:absolute; left:0; top:22px; width:14px; height:14px; border-radius:50%; background:#fff; border:2px solid var(--uc-accent); transition:transform .3s ease, background .3s ease, box-shadow .3s ease; }
  .sma .tl-entry.active{ background:#fff; border-color:color-mix(in oklab, var(--uc-accent) 32%, transparent); box-shadow:0 14px 32px rgba(10,42,61,.10); transform:translateX(4px); }
  .sma .tl-entry.active .tl-dot{ background:var(--uc-accent); transform:scale(1.2); box-shadow:0 0 0 5px color-mix(in oklab, var(--uc-accent) 20%, transparent); }
  .sma .tl-time{ display:inline-flex; align-items:center; gap:8px; font-family:'JetBrains Mono',monospace; font-size:.7rem; font-weight:600; letter-spacing:.1em; color:var(--uc-deep); text-transform:uppercase; }
  .sma .tl-time .tdot{ width:7px; height:7px; border-radius:50%; background:var(--uc-accent); }
  .sma .tl-h{ margin-top:8px; font-family:'Outfit',sans-serif; font-size:1.18rem; font-weight:700; letter-spacing:-.02em; line-height:1.15; color:var(--ink); }
  .sma .tl-p{ margin-top:8px; font-size:.9rem; line-height:1.5; color:var(--ink-soft); max-width:40ch; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
  .sma .tl-chips{ margin-top:12px; display:flex; flex-wrap:wrap; gap:7px; }
  .sma .tl-chips .chip{ padding:6px 11px; font-size:.74rem; }
  .sma .tl-stage-outer{ position:relative; }
  .sma .tl-stage-sticky{ position:sticky; top:118px; border-radius:28px; overflow:hidden; background:linear-gradient(160deg,var(--uc-tint),var(--uc-tint2)); aspect-ratio:4/3.1; min-height:420px; }
  .sma .tl-badge{ position:absolute; top:18px; left:18px; z-index:8; font-family:'JetBrains Mono',monospace; font-size:.74rem; font-weight:700; letter-spacing:.08em; color:#fff; padding:8px 14px; border-radius:100px; background:rgba(10,20,30,.5); backdrop-filter:blur(4px); pointer-events:none; }
  .sma .tl-stage-stack{ position:absolute; inset:0; }
  .sma .tl-stage-item{ position:absolute; inset:0; opacity:0; transition:opacity .3s ease; pointer-events:none; }
  .sma .tl-stage-item.active{ opacity:1; pointer-events:auto; z-index:2; }
  .sma .tl-stage-item .uc-stage{ position:absolute; inset:0; min-height:0; }
  .sma .cases-mobile{ display:none; }
  .sma .uc{ --uc-accent:oklch(0.66 0.15 var(--h)); --uc-deep:oklch(0.47 0.13 var(--h)); --uc-tint:oklch(0.965 0.028 var(--h)); --uc-tint2:oklch(0.93 0.05 var(--h)); }
  .sma .uc-story{ display:grid; grid-template-columns:1.02fr 1fr; gap:0; border-radius:28px; overflow:hidden; background:#fff; border:1px solid var(--tile-line); box-shadow:0 1px 0 rgba(10,42,61,.02); opacity:0; transform:translateY(26px); transition:opacity .7s ease, transform .7s ease; }
  .sma .uc-story.in{ opacity:1; transform:none; }
  .sma .uc-story:nth-child(even){ grid-template-columns:1fr 1.02fr; }
  .sma .uc-story:nth-child(even) .uc-stage{ order:2; }
  .sma .uc-stage{ position:relative; min-height:340px; display:flex; align-items:center; justify-content:center; background:linear-gradient(160deg,var(--uc-tint),var(--uc-tint2)); overflow:hidden; }
  .sma .uc-video{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; opacity:0; z-index:3; pointer-events:none; transition:opacity .25s ease; }
  .sma .uc-poster{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; z-index:1; transition:opacity .2s ease; }
  .sma .uc-stage.playing .uc-poster{ opacity:0; }
  .sma .uc-stage:not(.has-video) .uc-video{ display:none; }
  .sma .uc-stage.playing .uc-video{ opacity:1; pointer-events:auto; }
  /* Vorher/Nachher-Vergleich */
  .sma .uc-vorher{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; z-index:2; clip-path:inset(0 calc(100% - var(--split,50%)) 0 0); }
  .sma .uc-divider{ position:absolute; top:0; bottom:0; left:var(--split,50%); width:44px; margin-left:-22px; z-index:5; background:none; border:none; padding:0; cursor:ew-resize; touch-action:none; -webkit-tap-highlight-color:transparent; }
  .sma .uc-divider::before{ content:""; position:absolute; top:0; bottom:0; left:50%; width:2px; background:rgba(255,255,255,.92); box-shadow:0 0 0 1px rgba(10,20,30,.14); transform:translateX(-50%); }
  .sma .uc-divider .grip{ position:absolute; top:76%; left:50%; transform:translate(-50%,-50%); width:38px; height:38px; border-radius:50%; background:#fff; box-shadow:0 6px 18px rgba(10,42,61,.3); display:flex; align-items:center; justify-content:center; color:var(--uc-deep); }
  .sma .uc-divider .grip svg{ width:17px; height:17px; }
  .sma .uc-divider:focus-visible .grip{ outline:2px solid var(--uc-accent); outline-offset:2px; }
  .sma .uc-label{ position:absolute; bottom:13px; z-index:4; font-size:.68rem; font-weight:600; letter-spacing:.03em; color:#fff; padding:5px 11px; border-radius:100px; background:rgba(10,20,30,.42); backdrop-filter:blur(3px); pointer-events:none; }
  .sma .uc-label.vorher{ left:13px; }
  .sma .uc-label.nachher{ right:13px; }
  .sma .uc-play{ position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); z-index:6; width:54px; height:54px; border-radius:50%; background:rgba(255,255,255,.86); backdrop-filter:blur(4px); border:1px solid rgba(255,255,255,.6); display:flex; align-items:center; justify-content:center; color:var(--uc-deep); cursor:pointer; box-shadow:0 10px 26px rgba(10,42,61,.24); transition:transform .2s ease, background .2s ease, opacity .2s ease; }
  .sma .uc-play:hover{ transform:translate(-50%,-50%) scale(1.06); background:#fff; }
  .sma .uc-play svg{ width:19px; height:19px; margin-left:3px; }
  .sma .uc-close{ position:absolute; top:12px; right:12px; z-index:7; width:30px; height:30px; border-radius:50%; background:rgba(10,20,30,.5); color:#fff; border:none; display:flex; align-items:center; justify-content:center; cursor:pointer; opacity:0; pointer-events:none; transition:opacity .2s ease; }
  .sma .uc-close svg{ width:13px; height:13px; }
  .sma .uc-stage.playing .uc-close{ opacity:1; pointer-events:auto; }
  .sma .uc-stage.playing .uc-vorher, .sma .uc-stage.playing .uc-divider, .sma .uc-stage.playing .uc-label, .sma .uc-stage.playing .uc-play{ opacity:0; pointer-events:none; }
  .sma .uc-stage.fallback .uc-vorher, .sma .uc-stage.fallback .uc-divider, .sma .uc-stage.fallback .uc-label, .sma .uc-stage.fallback .uc-play, .sma .uc-stage.fallback .uc-close{ display:none; }
  .sma .uc-copy{ padding:44px 46px; display:flex; flex-direction:column; justify-content:center; }
  .sma .uc-time{ display:inline-flex; align-items:center; gap:9px; font-family:'JetBrains Mono',monospace; font-size:.7rem; font-weight:600; letter-spacing:.12em; color:var(--uc-deep); text-transform:uppercase; }
  .sma .uc-time .tdot{ width:8px; height:8px; border-radius:50%; background:var(--uc-accent); }
  .sma .uc-scene{ margin-top:6px; font-size:.92rem; color:var(--ink-soft); font-weight:500; }
  .sma .uc-h{ margin-top:14px; font-family:'Outfit',sans-serif; font-size:clamp(1.5rem,2.5vw,2.1rem); font-weight:700; letter-spacing:-.025em; line-height:1.05; color:var(--ink); text-wrap:balance; }
  .sma .uc-body{ margin-top:14px; font-size:1rem; line-height:1.55; color:var(--ink-soft); max-width:42ch; }
  .sma .uc-equip-label{ margin-top:24px; font-family:'JetBrains Mono',monospace; font-size:.62rem; letter-spacing:.14em; text-transform:uppercase; color:var(--ink-faint); }
  .sma .uc-equip{ margin-top:11px; display:flex; flex-wrap:wrap; gap:8px; }
  .sma .chip{ display:inline-flex; align-items:center; gap:8px; padding:8px 13px; border-radius:100px; background:var(--uc-tint); border:1px solid color-mix(in oklab, var(--uc-accent) 24%, transparent); font-size:.82rem; font-weight:500; color:var(--uc-deep); }
  .sma .chip svg{ width:14px; height:14px; }

  .sma .uc-app{ display:grid; grid-template-columns:300px 1fr; gap:36px; align-items:center; padding:34px; border-radius:28px; background:#fff; border:1px solid var(--tile-line); opacity:0; transform:translateY(26px); transition:opacity .7s ease, transform .7s ease; }
  .sma .uc-app.in{ opacity:1; transform:none; }
  .sma .uc-app:nth-child(even){ grid-template-columns:1fr 300px; }
  .sma .uc-app:nth-child(even) .app-phonewrap{ order:2; }
  .sma .app-phonewrap{ display:flex; justify-content:center; }
  .sma .app-copy{ display:flex; flex-direction:column; }
  .sma .miniphone{ width:264px; background:#fff; border-radius:34px; padding:9px; box-shadow:0 30px 60px rgba(10,60,100,.16),0 6px 18px rgba(10,60,100,.10); border:1.5px solid #eef3f7; }
  .sma .miniscreen{ background:var(--card-soft); border-radius:26px; overflow:hidden; padding:16px 14px 18px; }
  .sma .mp-top{ display:flex; align-items:center; justify-content:space-between; margin-bottom:14px; }
  .sma .mp-room{ display:flex; align-items:center; gap:8px; font-weight:600; font-size:.9rem; color:var(--ink); }
  .sma .mp-room .rdot{ width:9px; height:9px; border-radius:50%; background:var(--uc-accent); }
  .sma .mp-time{ font-family:'JetBrains Mono',monospace; font-size:.72rem; color:var(--ink-faint); }
  .sma .mp-tile{ background:#fff; border:1px solid var(--tile-line); border-radius:16px; padding:13px 14px; display:flex; align-items:center; gap:12px; margin-bottom:9px; }
  .sma .mp-tile .mpi{ width:40px; height:40px; border-radius:12px; flex-shrink:0; display:flex; align-items:center; justify-content:center; background:var(--uc-tint); color:var(--uc-deep); }
  .sma .mp-tile .mpi svg{ width:21px; height:21px; }
  .sma .mp-tile.live .mpi{ background:var(--uc-accent); color:#fff; }
  .sma .mp-tx{ flex:1; min-width:0; }
  .sma .mp-tn{ font-size:.86rem; font-weight:600; color:var(--ink); }
  .sma .mp-ts{ font-size:.76rem; color:var(--ink-soft); }
  .sma .mp-tile.live .mp-ts{ color:var(--uc-deep); font-weight:600; }
  .sma .mp-toggle{ width:40px; height:23px; border-radius:100px; background:var(--tile-line); position:relative; flex-shrink:0; transition:background .3s; }
  .sma .mp-toggle::after{ content:""; position:absolute; width:19px; height:19px; border-radius:50%; background:#fff; top:2px; left:2px; box-shadow:0 1px 3px rgba(0,0,0,.18); transition:left .3s; }
  .sma .mp-tile.live .mp-toggle{ background:var(--uc-accent); } .sma .mp-tile.live .mp-toggle::after{ left:19px; }
  .sma .mp-bars{ display:flex; align-items:flex-end; gap:3px; height:30px; margin-top:4px; }
  .sma .mp-bars i{ flex:1; background:var(--uc-accent); border-radius:2px 2px 0 0; opacity:.85; }
  .sma .app-foot{ margin-top:12px; display:inline-flex; align-items:center; gap:8px; font-size:.82rem; color:var(--uc-deep); font-weight:600; }
  .sma .app-foot svg{ width:16px; height:16px; flex-shrink:0; }

  @media (prefers-reduced-motion: reduce){ .sma .uc-story, .sma .uc-app{ animation:none !important; transition:none !important; } }

  .sma .flexcard{ margin-top:30px; display:grid; grid-template-columns:auto 1fr; gap:30px; align-items:center; padding:34px 40px; border-radius:28px; background:linear-gradient(135deg,var(--uc-tint),var(--uc-tint2)); border:1px solid color-mix(in oklab, var(--uc-accent) 26%, transparent); opacity:0; transform:translateY(26px); transition:opacity .7s ease, transform .7s ease; }
  .sma .flexcard.in{ opacity:1; transform:none; }
  .sma .flex-ic{ width:88px; height:88px; border-radius:24px; background:#fff; flex-shrink:0; display:flex; align-items:center; justify-content:center; color:var(--uc-deep); box-shadow:0 10px 26px color-mix(in oklab, var(--uc-accent) 22%, transparent); }
  .sma .flex-ic svg{ width:42px; height:42px; }
  .sma .flex-eye{ color:var(--uc-deep); }
  .sma .flex-body h3{ font-family:'Outfit',sans-serif; font-size:clamp(1.4rem,2.3vw,1.95rem); font-weight:700; letter-spacing:-.025em; color:var(--ink); margin-top:10px; line-height:1.05; }
  .sma .flex-body p{ font-size:1.02rem; line-height:1.55; color:var(--ink-soft); margin-top:12px; max-width:66ch; }
  .sma .flex-equip{ margin-top:18px; }
  @media (max-width:880px){ .sma .flexcard{ grid-template-columns:1fr; padding:28px; } }

  .sma .reassure{ background:var(--cyan-grad); color:#fff; position:relative; overflow:hidden; }
  .sma .reassure::after{ content:""; position:absolute; left:-10%; bottom:-40%; width:50vw; height:50vw; max-width:600px; max-height:600px; border-radius:50%; background:radial-gradient(circle, rgba(255,255,255,.7), transparent 66%); opacity:.7; pointer-events:none; }
  .sma .reassure .wrap{ position:relative; z-index:2; }
  .sma .reassure h2{ color:#fff; } .sma .reassure .sub{ color:var(--on); }
  .sma .rgrid{ margin-top:48px; display:grid; grid-template-columns:repeat(3,1fr); gap:18px; }
  .sma .rcard{ background:rgba(255,255,255,.12); border:1px solid rgba(255,255,255,.22); border-radius:20px; padding:26px; }
  .sma .rcard .rn{ font-family:'JetBrains Mono',monospace; font-size:.72rem; letter-spacing:.14em; color:var(--on-dim); }
  .sma .rcard h3{ font-size:1.22rem; font-weight:600; margin-top:12px; color:#fff; }
  .sma .rcard p{ margin-top:9px; font-size:.96rem; line-height:1.55; color:var(--on); }

  @media (max-width:880px){
    .sma .uc-story, .sma .uc-story:nth-child(even){ grid-template-columns:1fr; }
    .sma .uc-story:nth-child(even) .uc-stage{ order:0; }
    .sma .uc-app, .sma .uc-app:nth-child(even){ grid-template-columns:1fr; gap:24px; }
    .sma .uc-app:nth-child(even) .app-phonewrap{ order:0; }
    .sma .uc-copy{ padding:32px 28px; }
    .sma .rgrid{ grid-template-columns:1fr; }
    .sma .cases-timeline{ display:none; }
    .sma .cases-mobile{ display:flex; flex-direction:column; gap:30px; }
  }
  @media (max-width:560px){ .sma .wrap{ padding:0 22px; } }
  `;

  const MARKUP = `
  <section class="intro">
    <div class="wrap">
      <span class="eyebrow"><span class="dot"></span>Dein Tag, einfach smart</span>
      <h2>Nicht Technik.<br /><span class="light">Sondern dein Alltag.</span></h2>
      <p class="lede">Smart Home ist kein Schaltschrank voller Kabel — es sind die kleinen Momente, in denen dein Zuhause <b>einfach mitdenkt</b>. Hier ein paar davon. Such dir aus, was dich am meisten nervt:</p>
      <div class="daychips" id="dayChips"></div>
    </div>
  </section>
  <section class="band" id="anwendungen">
    <div class="wrap">
      <div class="sec-head">
        <span class="eyebrow sec-eyebrow"><span class="dot"></span>Anwendungsfälle</span>
        <h2>Sieben Situationen, in denen es sich sofort lohnt.</h2>
        <p class="sub">Jeder Fall einzeln umsetzbar — du musst nicht alles auf einmal machen. Wir starten dort, wo dein Alltag am meisten gewinnt.</p>
      </div>
      <div class="cases" id="cases"></div>
      <article class="uc flexcard" style="--h:198" id="uc-funk">
        <div class="flex-ic"></div>
        <div class="flex-body">
          <span class="eyebrow flex-eye"><span class="dot"></span>Egal, was schon da ist</span>
          <h3>Kein Kabel? Dann eben Funk.</h3>
          <p>Nicht jedes Haus lässt sich aufstemmen — muss es auch nicht. Wo Kabel liegen, nutzen wir sie. Wo keine sind, läuft alles per Funk. Oft ein Mix aus beidem. Wir binden uns an keinen Hersteller: pro Raum wählen wir die saubere Lösung, alle gängigen Standards sind möglich.</p>
          <div class="uc-equip flex-equip"></div>
        </div>
      </article>
    </div>
  </section>
  <section class="band reassure" id="so-gehts">
    <div class="wrap">
      <div class="sec-head">
        <span class="eyebrow"><span class="dot"></span>So läuft's</span>
        <h2>Du erlebst den Alltag. Die Technik bleibt unsichtbar.</h2>
        <p class="sub">Welches System im Hintergrund arbeitet, entscheiden wir gemeinsam — du musst dich damit nie beschäftigen. Versprochen.</p>
      </div>
      <div class="rgrid">
        <div class="rcard"><div class="rn">01 · Kennenlernen</div><h3>Wir hören zu</h3><p>Kurzes Gespräch, was dich im Alltag stört und was du dir wünschst. Kostenlos und ohne Fachchinesisch.</p></div>
        <div class="rcard"><div class="rn">02 · Vorschlag</div><h3>Du bekommst einen Plan</h3><p>Pro Anwendungsfall ein klarer Vorschlag mit Ausstattung und Preisrahmen. Du wählst, was zuerst dran ist.</p></div>
        <div class="rcard"><div class="rn">03 · Umsetzung</div><h3>Wir machen's smart</h3><p>Sauber installiert, alles dokumentiert, eine einfache App für die ganze Familie. Erweiterbar, wann immer du willst.</p></div>
      </div>
    </div>
  </section>`;

  React.useEffect(() => {
    const root = ref.current;
    if (!root) return;
    const ICON = {
      bulb:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18h6M10 21h4"/><path d="M12 3a6 6 0 0 1 4 10.5c-.7.7-1 1.2-1 2H9c0-.8-.3-1.3-1-2A6 6 0 0 1 12 3Z"/></svg>',
      heat:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M7 12a5 5 0 0 1 10 0v6H7z"/><path d="M10 6a2 2 0 1 1 4 0v2h-4z"/></svg>',
      blind:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"><rect x="4" y="4" width="16" height="4"/><path d="M5 8v11M19 8v11M5 19h14M8 8v8M12 8v8M16 8v8"/></svg>',
      energy:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2 4 14h6l-1 8 9-12h-6z"/></svg>',
      car:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round" stroke-linecap="round"><path d="M5 11l2-5h10l2 5"/><path d="M3 11h18v6H3z"/><circle cx="7.5" cy="17" r="1.6"/><circle cx="16.5" cy="17" r="1.6"/></svg>',
      shield:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"><path d="M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6z"/><path d="M9 12l2 2 4-4"/></svg>',
      audio:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="7" y="3" width="10" height="18" rx="2"/><circle cx="12" cy="15" r="3"/><circle cx="12" cy="7" r="1"/></svg>',
      check:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 13l4 4L19 7"/></svg>',
      bolt:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M13 2 4 14h6l-1 8 9-12h-6z"/></svg>',
      signal:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><circle cx="12" cy="17" r="1.8" fill="currentColor" stroke="none"/><path d="M8 13.5a5.5 5.5 0 0 1 8 0"/><path d="M5.2 10.3a9.5 9.5 0 0 1 13.6 0"/></svg>',
      play:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>',
      close:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>',
      grip:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 6l-5 6 5 6"/><path d="M14 6l5 6-5 6"/></svg>',
    };
    const CASES = [
      { id:'licht', h:75, icon:'bulb', anim:'lamp', time:'17:30', scene:'Du kommst heim', h2:'Das Licht ist schon an.', body:'Tür auf — und es ist hell, warm, gemütlich. Abends dimmt sich alles von selbst herunter. Eine Szene für Kino, eine fürs Essen, eine für „alle ins Bett".', equip:['Stimmungs-Szenen','Automatisch nach Tageszeit','App, Taster & Sprache'], nachher:'hero-licht-an.webp', vorher:'hero-licht-aus.webp' },
      { id:'heizung', h:32, icon:'heat', anim:'heat', time:'06:45', scene:'Bevor der Wecker klingelt', h2:'Das Bad ist schon warm.', body:'Jeder Raum nur dann geheizt, wenn du ihn brauchst. Fenster auf? Heizung pausiert. Spart spürbar Energie — ohne dass du je an ein Thermostat denken musst.', equip:['Raum für Raum geregelt','Fenster-auf-Erkennung','15–25 % weniger Heizkosten'], nachher:'hero-heizung-warm.webp', vorher:'hero-heizung-kalt.webp' },
      { id:'beschattung', h:245, icon:'blind', anim:'blinds', time:'13:00', scene:'Die Mittagssonne knallt', h2:'Die Rollläden wissen Bescheid.', body:'Im Sommer fährt die Beschattung bei Sonne automatisch runter, es bleibt kühl. Wird es windig, fahren die Markisen rechtzeitig ein. Du musst nichts mehr nachlaufen.', equip:['Reagiert auf Sonne & Wind','Pro Fenster oder Fassade','Manuell jederzeit übersteuerbar'] },
      { id:'energie', h:150, icon:'energy', anim:'energy', time:'12:20', scene:'Die Sonne liefert', h2:'Dein Strom geht nicht verloren.', body:'Du siehst auf einen Blick, woher dein Strom kommt und wohin er fließt. Überschuss lädt automatisch den Speicher, die Wärmepumpe oder das Auto — statt billig ins Netz zu wandern.', equip:['PV, Speicher & Verbrauch live','Eigenverbrauch automatisch','Klare Energie-Kosten'] },
      { id:'wallbox', h:188, icon:'car', anim:'wallbox', time:'18:10', scene:'Auto an die Wallbox', h2:'Geladen wird, wenn Strom da ist.', body:'Das E-Auto tankt bevorzugt den eigenen Sonnenstrom — oder nachts, wenn er günstig ist. Lastspitzen werden vermieden, damit nie die Sicherung fliegt.', equip:['Laden mit PV-Überschuss','Günstige Zeitfenster','Lastmanagement im Haus'] },
      { id:'sicherheit', v:'r5', h:285, icon:'shield', anim:'secure', time:'22:30', scene:'„Alle im Bett"', h2:'Ein Tipp — und alles ist sicher.', body:'Licht aus, Türen zu, Rollläden unten, Anwesenheit simuliert. Bist du weg und etwas öffnet sich, bekommst du sofort eine Nachricht — mit Videobild von der Tür.', equip:['Tür- & Fensterstatus','Push bei Auffälligkeiten','Video-Türklingel'] },
      { id:'audio', h:322, icon:'audio', anim:'audio', time:'08:00', scene:'Guten Morgen', h2:'Deine Musik folgt dir durchs Haus.', body:'Im Bad die Nachrichten, in der Küche die Playlist, beim Rausgehen alles aus. In jedem Raum die richtige Lautstärke — gesteuert per App, Taster oder Sprache.', equip:['Multiroom in jedem Raum','Eigene Lautstärke pro Raum','Sonos, Loxone & mehr'] },
    ];
    const CHIP_ICON = ICON.check;
    const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    const ver = (c) => (c.v ? ('?v=' + c.v) : ''); // Cache-Bust pro Karte, wenn Video/Poster neu gerendert wurde
    const nachherSrc = (c) => 'assets/renders/' + (c.nachher || ('anw-' + c.id + '-start.webp')) + ver(c);
    const vorherSrc = (c) => 'assets/renders/' + (c.vorher || ('anw-' + c.id + '-vorher.webp'));
    const videoHTML = (c) => '<video class="uc-video" muted loop playsinline preload="none" '
      + 'poster="' + nachherSrc(c) + '" '
      + 'onerror="this.closest(\'.uc-stage\').classList.remove(\'has-video\')">'
      + '<source src="assets/renders/anw-' + c.id + '.mp4' + ver(c) + '" type="video/mp4"></video>';
    const chipsHTML = (equip) => equip.map((e) => '<span class="chip">'+CHIP_ICON+e+'</span>').join('');
    const compareHTML = (c) => '<div class="uc-divider" tabindex="0" role="slider" aria-label="Vorher/Nachher-Vergleich '+c.scene+'" aria-valuemin="0" aria-valuemax="100" aria-valuenow="50"><span class="grip">'+ICON.grip+'</span></div>'
      + '<span class="uc-label vorher">Vorher</span><span class="uc-label nachher">Nachher</span>'
      + (reducedMotion ? '' : '<button type="button" class="uc-play" aria-label="Video abspielen">'+ICON.play+'</button><button type="button" class="uc-close" aria-label="Vergleich wieder anzeigen">'+ICON.close+'</button>');
    const stageInnerHTML = (c) => '<img class="uc-poster" src="'+nachherSrc(c)+'" alt="" loading="lazy" decoding="async">'
      + '<img class="uc-vorher" src="'+vorherSrc(c)+'" alt="" loading="lazy" decoding="async" onerror="this.closest(\'.uc-stage\').classList.add(\'fallback\');this.style.display=\'none\';">'
      + compareHTML(c)
      + (reducedMotion ? '' : videoHTML(c));
    const renderStory = (c) => '<article class="uc uc-story" style="--h:'+c.h+'" data-anim="'+c.anim+'" id="uc-'+c.id+'"><div class="uc-stage has-video" data-id="'+c.id+'">'
      + stageInnerHTML(c)
      + '</div><div class="uc-copy"><span class="uc-time"><span class="tdot"></span>'+c.time+'</span><span class="uc-scene">'+c.scene+'</span><h3 class="uc-h">'+c.h2+'</h3><p class="uc-body">'+c.body+'</p><div class="uc-equip-label">Das ist dabei</div><div class="uc-equip">'+chipsHTML(c.equip)+'</div></div></article>';
    const renderTlEntry = (c, i) => '<div class="tl-entry uc'+(i === 0 ? ' active' : '')+'" style="--h:'+c.h+'" data-id="'+c.id+'">'
      + '<span class="tl-dot"></span>'
      + '<div class="tl-entry-body"><span class="tl-time"><span class="tdot"></span>'+c.time+'</span><h3 class="tl-h">'+c.h2+'</h3><p class="tl-p">'+c.body+'</p><div class="tl-chips">'+chipsHTML(c.equip)+'</div></div></div>';
    const renderTlStageItem = (c, i) => '<div class="uc tl-stage-item'+(i === 0 ? ' active' : '')+'" style="--h:'+c.h+'" data-anim="'+c.anim+'" data-id="'+c.id+'"><div class="uc-stage has-video" data-id="'+c.id+'">'
      + stageInnerHTML(c)
      + '</div></div>';
    const tileHTML = (c) => {
      const state = ({ licht:['Stehlampe','Szene · Abend','live','toggle'], heizung:['Bad','21,5° · warm','live','toggle'], beschattung:['Rollläden','fahren herunter','live','toggle'], energie:['PV-Überschuss','2,4 kW → Speicher','live','bars'], wallbox:['Wallbox','lädt mit Sonne','live','bars'], sicherheit:['Alles sicher','Türen zu · Nacht','live','toggle'], audio:['Multiroom','Playlist · 3 Räume','live','toggle'] })[c.id] || ['',''];
      const ctrl = state[3] === 'bars' ? '<div class="mp-bars"><i style="height:40%"></i><i style="height:62%"></i><i style="height:85%"></i><i style="height:70%"></i><i style="height:95%"></i><i style="height:58%"></i></div>' : '<span class="mp-toggle"></span>';
      const barsTile = state[3] === 'bars';
      return '<div class="miniphone"><div class="miniscreen"><div class="mp-top"><span class="mp-room"><span class="rdot"></span>'+c.scene+'</span><span class="mp-time">'+c.time+'</span></div><div class="mp-tile live'+(barsTile?' col':'')+'"'+(barsTile?' style="flex-direction:column;align-items:stretch;gap:8px"':'')+'>'+(barsTile?'<div style="display:flex;align-items:center;gap:12px"><span class="mpi">'+ICON[c.icon]+'</span><div class="mp-tx"><div class="mp-tn">'+state[0]+'</div><div class="mp-ts">'+state[1]+'</div></div></div>'+ctrl:'<span class="mpi">'+ICON[c.icon]+'</span><div class="mp-tx"><div class="mp-tn">'+state[0]+'</div><div class="mp-ts">'+state[1]+'</div></div>'+ctrl)+'</div><div class="mp-tile"><span class="mpi">'+ICON.check+'</span><div class="mp-tx"><div class="mp-tn">Automatik</div><div class="mp-ts">'+c.scene+'</div></div></div></div></div>';
    };
    const renderApp = (c) => '<article class="uc uc-app" style="--h:'+c.h+'" data-anim="'+c.anim+'" id="uc-'+c.id+'"><div class="app-phonewrap">'+tileHTML(c)+'</div><div class="app-copy"><span class="uc-time"><span class="tdot"></span>'+c.time+' · '+c.scene+'</span><h3 class="uc-h">'+c.h2+'</h3><p class="uc-body">'+c.body+'</p><div class="uc-equip-label">Das ist dabei</div><div class="uc-equip">'+chipsHTML(c.equip)+'</div><span class="app-foot">'+ICON.bolt+' Eine App für alles — die ganze Familie</span></div></article>';
    const CASES_SORTED = CASES.slice().sort((a,b) => { const m=(t)=>{const p=t.split(':');return (+p[0])*60+(+p[1]);}; return m(a.time)-m(b.time); });

    const chipsEl = root.querySelector('#dayChips');
    chipsEl.innerHTML = CASES_SORTED.map((c) => '<a class="daychip" href="#uc-'+c.id+'"><span class="cdot" style="background:oklch(0.7 0.16 '+c.h+')"></span>'+c.scene+'</a>').join('');

    let io = null;
    const observe = () => {
      if (io) io.disconnect();
      io = new IntersectionObserver((entries) => {
        entries.forEach((en) => { if (en.isIntersecting) en.target.classList.add('in'); });
      }, { threshold: 0.25 });
      root.querySelectorAll('.uc').forEach((u) => io.observe(u));
    };
    const host = root.querySelector('#cases');
    if (variant === 'app') {
      host.innerHTML = CASES_SORTED.map(renderApp).join('');
    } else {
      const timelineHTML = '<div class="cases-timeline" id="casesTimeline">'
        + '<div class="tl-col" id="tlCol">' + CASES_SORTED.map(renderTlEntry).join('') + '</div>'
        + '<div class="tl-stage-outer"><div class="tl-stage-sticky"><span class="tl-badge" id="tlBadge">'+(CASES_SORTED[0] ? CASES_SORTED[0].time : '')+'</span>'
        + '<div class="tl-stage-stack" id="tlStageStack">' + CASES_SORTED.map(renderTlStageItem).join('') + '</div>'
        + '</div></div></div>';
      host.innerHTML = timelineHTML + '<div class="cases-mobile" id="casesMobile">' + CASES_SORTED.map(renderStory).join('') + '</div>';
    }

    // Vorher/Nachher-Vergleich + Play-on-demand (nur variant="story").
    const teardowns = [];
    const on = (el, ev, handler, opts) => { el.addEventListener(ev, handler, opts); teardowns.push(() => el.removeEventListener(ev, handler, opts)); };
    const clamp01 = (n) => Math.max(0, Math.min(100, n));
    root.querySelectorAll('.uc-stage').forEach((stage) => {
      const card = stage.closest('.uc');
      const video = stage.querySelector('.uc-video');
      const divider = stage.querySelector('.uc-divider');
      const playBtn = stage.querySelector('.uc-play');
      const closeBtn = stage.querySelector('.uc-close');
      const isFallback = () => stage.classList.contains('fallback');

      const playVideo = () => { if (!video) return; try { video.currentTime = 0; } catch (err) {} video.play().catch(() => {}); };
      const resetVideo = () => { if (!video) return; video.pause(); try { video.currentTime = 0; } catch (err) {} };

      // Fallback (fehlendes Vorher-Bild): altes Poster+Hover-Video-Verhalten.
      if (card && video) {
        on(card, 'pointerenter', () => { if (isFallback()) playVideo(); });
        on(card, 'focusin', () => { if (isFallback()) playVideo(); });
        on(card, 'pointerleave', () => { if (isFallback()) resetVideo(); });
        on(card, 'focusout', () => { if (isFallback()) resetVideo(); });
      }

      // Play-Overlay: klick blendet Vergleich aus, spielt Video, bis ✕ geklickt wird.
      if (playBtn) on(playBtn, 'click', () => { stage.classList.add('playing'); playVideo(); });
      if (closeBtn) on(closeBtn, 'click', () => { stage.classList.remove('playing'); resetVideo(); });

      // Drag-Divider fuer den Bildvergleich.
      if (!divider) return;
      const setSplit = (pct) => {
        const clamped = clamp01(pct);
        stage.style.setProperty('--split', clamped + '%');
        divider.setAttribute('aria-valuenow', String(Math.round(clamped)));
      };
      const pctFromClientX = (clientX) => {
        const rect = stage.getBoundingClientRect();
        return ((clientX - rect.left) / rect.width) * 100;
      };
      let dragging = false;
      const onPointerDown = (e) => {
        dragging = true;
        try { divider.setPointerCapture(e.pointerId); } catch (err) {}
        setSplit(pctFromClientX(e.clientX));
        e.preventDefault();
      };
      const onPointerMove = (e) => { if (dragging) setSplit(pctFromClientX(e.clientX)); };
      const onPointerUp = (e) => { if (!dragging) return; dragging = false; try { divider.releasePointerCapture(e.pointerId); } catch (err) {} };
      const onKeydown = (e) => {
        const current = parseFloat(divider.getAttribute('aria-valuenow')) || 50;
        if (e.key === 'ArrowLeft') { setSplit(current - 5); e.preventDefault(); }
        else if (e.key === 'ArrowRight') { setSplit(current + 5); e.preventDefault(); }
      };
      on(divider, 'pointerdown', onPointerDown);
      on(divider, 'pointermove', onPointerMove);
      on(divider, 'pointerup', onPointerUp);
      on(divider, 'pointercancel', onPointerUp);
      on(divider, 'keydown', onKeydown);
    });

    // Timeline-Scrollsync (nur variant="story"): IntersectionObserver auf den
    // linken Eintraegen schaltet die rechte sticky Buehne + das Zeit-Badge um.
    let tlIo = null;
    let tlStageIo = null;
    let mobileVideoIo = null;
    if (variant !== 'app') {
      const tlEntries = Array.from(root.querySelectorAll('.tl-entry'));
      const tlStageItems = Array.from(root.querySelectorAll('.tl-stage-item'));
      const tlBadge = root.querySelector('#tlBadge');
      let activeCaseId = CASES_SORTED[0] && CASES_SORTED[0].id;
      let stageInView = true;
      const startStageVideo = (stage, video, restart) => {
        if (!stage || !video || reducedMotion) return;
        if (!stage.classList.contains('fallback')) stage.classList.add('playing');
        video.loop = true;
        video.muted = true;
        video.setAttribute('muted', '');
        video.setAttribute('playsinline', '');
        if (restart) {
          try { video.currentTime = 0; } catch (err) {}
        }
        const attemptPlay = () => video.play().catch(() => {});
        if (video.readyState < 2) {
          video.load();
          video.addEventListener('canplay', attemptPlay, { once: true });
        }
        attemptPlay();
      };
      const stopStageVideo = (stage, video, reset) => {
        if (stage) stage.classList.remove('playing');
        if (!video) return;
        video.pause();
        if (reset) {
          try { video.currentTime = 0; } catch (err) {}
        }
      };
      const playActiveCase = (restart) => {
        const activeItem = tlStageItems.find((si) => si.dataset.id === activeCaseId);
        if (!activeItem) return;
        const stage = activeItem.querySelector('.uc-stage');
        const video = stage && stage.querySelector('.uc-video');
        startStageVideo(stage, video, restart);
      };
      const setActiveCase = (id) => {
        const changed = activeCaseId !== id;
        activeCaseId = id;
        tlEntries.forEach((en) => en.classList.toggle('active', en.dataset.id === id));
        tlStageItems.forEach((si) => {
          const isActive = si.dataset.id === id;
          si.classList.toggle('active', isActive);
          const st = si.querySelector('.uc-stage');
          const v = st && st.querySelector('.uc-video');
          if (!isActive) {
            stopStageVideo(st, v, true);
          } else if (stageInView) {
            // Autoplay: das aktive Anwendungsvideo laeuft automatisch (muted, loop) statt Play-Klick.
            startStageVideo(st, v, changed);
          }
        });
        const active = CASES_SORTED.find((c) => c.id === id);
        if (tlBadge && active) tlBadge.textContent = active.time;
      };
      if (tlEntries.length) {
        setActiveCase(activeCaseId);
        const stageBox = root.querySelector('.tl-stage-sticky');
        if (stageBox) {
          tlStageIo = new IntersectionObserver((stageEntries) => {
            stageInView = stageEntries.some((en) => en.isIntersecting);
            if (stageInView) playActiveCase(false);
            else {
              tlStageItems.forEach((si) => {
                const st = si.querySelector('.uc-stage');
                const v = st && st.querySelector('.uc-video');
                stopStageVideo(st, v, false);
              });
            }
          }, { threshold: 0.2 });
          tlStageIo.observe(stageBox);
        }
        tlIo = new IntersectionObserver((ioEntries) => {
          const visible = ioEntries.filter((en) => en.isIntersecting);
          if (!visible.length) return;
          const centerY = window.innerHeight * 0.5;
          let best = visible[0], bestDist = Infinity;
          visible.forEach((en) => {
            const r = en.target.getBoundingClientRect();
            const dist = Math.abs((r.top + r.height / 2) - centerY);
            if (dist < bestDist) { bestDist = dist; best = en; }
          });
          setActiveCase(best.target.dataset.id);
        }, { rootMargin: '-40% 0px -40% 0px', threshold: 0 });
        tlEntries.forEach((en) => tlIo.observe(en));
        // F4: Timeline-Eintraege klickbar — pinnt die Szene gezielt (statt nur per Scroll),
        // damit man eine Anwendung anwaehlen und deren Video abspielen kann. Behebt das
        // User-Feedback "klickbar machen" + "Audio-Video liess sich nicht abspielen" (Scroll
        // sprang vorher weg, bevor man Play treffen konnte).
        tlEntries.forEach((en) => {
          en.style.cursor = 'pointer';
          on(en, 'click', () => { setActiveCase(en.dataset.id); en.scrollIntoView({ behavior: 'smooth', block: 'center' }); });
        });
      }
      const mobileStages = Array.from(root.querySelectorAll('.cases-mobile .uc-stage'));
      if (mobileStages.length && !reducedMotion) {
        mobileVideoIo = new IntersectionObserver((stageEntries) => {
          const mobileLayout = window.matchMedia('(max-width: 880px)').matches;
          stageEntries.forEach((entry) => {
            const st = entry.target;
            const v = st.querySelector('.uc-video');
            if (mobileLayout && entry.isIntersecting) startStageVideo(st, v, false);
            else stopStageVideo(st, v, false);
          });
        }, { threshold: 0.45 });
        mobileStages.forEach((st) => mobileVideoIo.observe(st));
      }
    }
    // flex card
    const ic = root.querySelector('.flex-ic'); if (ic) ic.innerHTML = ICON.signal;
    const eq = root.querySelector('.flex-equip'); if (eq) eq.innerHTML = ['Funk, Kabel oder Mix','Herstellerneutral','Alle gängigen Standards'].map((e) => '<span class="chip">'+CHIP_ICON+e+'</span>').join('');
    observe();

    // Anchor-scroll for daychips: zielt je nach Breakpoint auf den Timeline-Eintrag
    // (Desktop) oder die gestapelte Karte (Mobile-Fallback).
    const onChip = (e) => {
      const a = e.target.closest('.daychip'); if (!a) return; e.preventDefault();
      const id = (a.getAttribute('href') || '').replace('#uc-', '');
      const isDesktop = window.matchMedia('(min-width:881px)').matches;
      const el = isDesktop
        ? root.querySelector('.tl-entry[data-id="'+id+'"]')
        : root.querySelector('#uc-'+id);
      if (el) el.scrollIntoView({ behavior:'smooth', block:'center' });
    };
    chipsEl.addEventListener('click', onChip);

    return () => {
      if (io) io.disconnect();
      if (tlIo) tlIo.disconnect();
      if (tlStageIo) tlStageIo.disconnect();
      if (mobileVideoIo) mobileVideoIo.disconnect();
      chipsEl.removeEventListener('click', onChip);
      teardowns.forEach((fn) => fn());
    };
  }, [variant]);

  return (
    <React.Fragment>
      <style>{CSS}</style>
      <section className="sma" ref={ref} id="anwendung" dangerouslySetInnerHTML={{ __html: MARKUP }} />
    </React.Fragment>
  );
}

window.AnwendungSection = AnwendungSection;
