<!doctype html>

<html lang="de">

<head>

  <meta charset="utf-8" />

  <meta name="viewport" content="width=device-width, initial-scale=1" />

  <title>Shadow DOM – minimal test page</title>

  <style>

    body { font-family: system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif; margin: 2rem; }

    h1 { font-size: 1.25rem; }

    .note { font-size: .9rem; color: #444; margin-bottom: 1rem; }

    section { border: 1px solid #ddd; border-radius: 8px; padding: 1rem; margin-bottom: 1.25rem; }

    code { background: #f6f7f8; padding: 0 .25rem; border-radius: 4px; }

  </style>

</head>

<body>

  <h1>Shadow DOM – abgespeckte Testseite</h1>

  <p class="note">

    Diese Seite enthält mehrere Varianten, damit ihr Locators/Shadow‑Piercing in Playwright/TestWeasel prüfen könnt:

    <br>1) <code>&lt;cookie-banner-demo open&gt;</code> (offenes ShadowRoot)

    <br>2) <code>&lt;cookie-banner-demo-closed&gt;</code> (geschlossenes ShadowRoot)

    <br>3) Geschachtelte Shadow‑Roots via <code>&lt;brand-logo&gt;</code>

    <br>4) <code>&lt;slot&gt;</code> / <code>::slotted</code>

    <br>5) Iframe im ShadowRoot (separater Frame‑Context nötig)

  </p>


  <section>

    <cookie-banner-demo id="open-banner" data-testid="open-banner">

      <span slot="headline">Ein Moment für Deine Privatsphäre (Demo)</span>

      <a slot="policy" href="#" target="_blank">Datenschutzerklärung</a>

      <a slot="imprint" href="#" target="_blank">Impressum</a>

    </cookie-banner-demo>

  </section>


  <section>

    <cookie-banner-demo-closed id="closed-banner" data-testid="closed-banner"></cookie-banner-demo-closed>

    <p class="note">Der obige Banner hat ein <strong>geschlossenes</strong> ShadowRoot. Playwright‑Standard‑Locators sollten hier <em>nicht</em> hineinsehen können.</p>

  </section>


  <template id="cookie-banner-template">

    <style>

      :host { --bg:#ffffff; --fg:#1a1a1a; --accent:#002878; font: 14px/1.4 system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif; }

      .container { position: relative; max-width: 720px; margin: 0 auto; box-shadow: 0 10px 30px rgba(0,0,0,.15); border-radius: 8px; overflow: hidden; border: 1px solid #e6e6e6; }

      header { display:flex; gap:.75rem; align-items:center; padding: 1rem; background: var(--bg); color: var(--fg); }

      .text { flex: 1; }

      .title { margin:0; font-weight:700; }

      .links { display:flex; gap:1rem; font-size:.9rem; }

      .actions { display:flex; gap:.5rem; padding: .75rem 1rem 1rem; }

      button { border: 0; border-radius: 20px; padding:.6rem .9rem; font-weight:700; }

      [data-testid="uc-deny-all-button"] { background:#e9e9ef; color:#111; }

      [data-testid="uc-accept-all-button"] { background: var(--accent); color: white; }

      .floating { position:absolute; right: .5rem; top:.5rem; }

      .floating > button { width: 44px; height: 44px; border-radius: 50%; display:grid; place-items:center; background: var(--accent); color:#fff; }

      /* Slot demo */

      ::slotted([slot="headline"]) { font-weight:700; }

      ::slotted(a[slot]) { color: var(--accent); text-decoration: underline; }

      /* Nested component host area */

      .brand { padding-left: .25rem; }

      iframe { width:100%; height:100px; border:0; border-top: 1px dashed #dde; }

    </style>

    <div class="container" role="dialog" aria-modal="true">

      <div class="floating">

        <button aria-label="Öffnen Privatsphäre-Einstellungen" data-testid="uc-privacy-button">⚙️</button>

      </div>

      <header>

        <brand-logo data-testid="brand-logo"></brand-logo>

        <div class="text">

          <h2 class="title" data-testid="uc-heading-title"><slot name="headline">Ein Moment für Deine Privatsphäre</slot></h2>

          <div class="links">

            <slot name="policy"></slot>

            <slot name="imprint"></slot>

          </div>

        </div>

      </header>

      <div class="content" data-testid="uc-message-container" style="padding:0 1rem 1rem">

        <p>Wir verwenden Cookies und ähnliche Technologien, um Inhalte zu personalisieren und die Nutzung zu analysieren.</p>

      </div>

      <div class="actions" data-testid="uc-buttons-container">

        <button role="button" data-testid="uc-deny-all-button">Einwilligung ablehnen</button>

        <button role="button" data-testid="uc-accept-all-button">Alles akzeptieren</button>

      </div>

      <iframe title="Demo Iframe" data-testid="uc-iframe" srcdoc="<!doctype html><html><body><p>Iframe im ShadowRoot. Frame‑Context nötig.</p><button id='inside-frame'>Klick mich</button></body></html>"></iframe>

    </div>

  </template>


  <template id="brand-logo-template">

    <style>

      :host { display:inline-flex; align-items:center; gap:.5rem; }

      .circle { width: 36px; height: 36px; border-radius: 50%; background: #002878; display:grid; place-items:center; color:#fff; font-weight: 800; }

      .name { font-weight: 700; }

    </style>

    <div class="circle" aria-hidden="true">TW</div>

    <div class="brand"><span class="name">TestWeasel</span></div>

  </template>


  <script>

    // Brand logo with its own (nested) open ShadowRoot

    class BrandLogo extends HTMLElement {

      constructor(){ super(); this.attachShadow({mode:'open'}).append(document.getElementById('brand-logo-template').content.cloneNode(true)); }

    }

    customElements.define('brand-logo', BrandLogo);


    // Open shadow-root banner

    class CookieBannerDemo extends HTMLElement {

      constructor(){

        super();

        const root = this.attachShadow({mode:'open'});

        root.append(document.getElementById('cookie-banner-template').content.cloneNode(true));

      }

    }

    customElements.define('cookie-banner-demo', CookieBannerDemo);


    // Closed shadow-root variant

    class CookieBannerDemoClosed extends HTMLElement {

      constructor(){

        super();

        const root = this.attachShadow({mode:'closed'});

        root.append(document.getElementById('cookie-banner-template').content.cloneNode(true));

        // expose a tiny test handle to confirm it's closed (will be undefined from the outside)

        this._shadowRootRef = root; // not reachable via element.shadowRoot

      }

    }

    customElements.define('cookie-banner-demo-closed', CookieBannerDemoClosed);

  </script>

</body>

</html>