
      /* ([x-cloak]: app.css, on every page. The headline bands this block once hid are gone from the markup.) */
      /* 18. Split pane headers (prototype): DARSTELLUNG + "open in playground"
             over the viz, API-Antwort over the JSON. A tinted band with
             full-width dividers so the eye reads header→content; endpoint URL
             moves to the detailed playground. */
      /* The Darstellung header is dropped: the visualization fills its column
         from the top with no header. The header is now just the API-Antwort
         bar, floated over the top of the JSON column only (right 1/3 of the
         2fr·1fr split), anchored to the position:relative card. */
      #playground .fold-split-header {
        position: absolute; top: 0; right: 0; width: 33.333%; z-index: 6;
        border-bottom: 1px solid var(--ds-line-soft);
        /* No border-left: the viz pane's border-right already draws the divider,
           and the bar's bg is transparent so the JSON pane's single frost shows
           through — no frost-over-frost whitening, no doubled line. */
      }
      #playground .fold-split-header-json {
        display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
        min-height: 44px; padding: 0 1.25rem;
        background: transparent;
      }
      /* Once the JSON under it scrolls (Kevin, 2026-09-30: the rows showed through the transparent bar and
         looked broken), the bar frosts over: near-opaque, blurred, a soft shadow. At the top it stays
         transparent as above. The class is set by the scroll listener below the page's styles. */
      #playground .fold-split-header { transition: background-color var(--ds-dur) var(--ds-ease), box-shadow var(--ds-dur) var(--ds-ease); }
      #playground .fold-split-header.is-scrolled { background: var(--ds-solid); box-shadow: 0 6px 12px -10px rgb(0 0 0 / .25); }
      /* Person's <section> IS the split grid; with the header floated out of
         flow the panes fill a single row, and the section anchors the bar. */
      #playground .psp .pg-split { grid-template-rows: minmax(0, 1fr); position: relative; }
      /* The label: the system's label style (11px uppercase +8 %, faint). */
      #playground .fold-split-header-label {
        font-family: var(--ds-font-body); font-size: 11px; line-height: 16px; text-transform: uppercase; letter-spacing: .08em;
        font-weight: 600; color: rgb(var(--ds-faint));
      }
      /* "Im Playground öffnen" lives in the API-Antwort header (its look: the design-system block at the end). */
      #playground .fold-open-pg { white-space: nowrap; text-decoration: none; }
      /* Align both panes' content to the header labels. The header inset is the
         reference (1.25rem); the viz content ships with p-6 (24px) and the JSON
         with p-4 (16px), so normalize both to 1.25rem horizontally — content
         then sits directly under "Darstellung" / "API-Antwort". Direct-child /
         pt-12 selectors avoid the nested empty-state (p-6) and code-sample
         (pt-11) blocks. */
      /* (Suche's pane, nested under an .overflow-auto wrapper, carries the same insets in its classes) */
      #playground .pg-split > [x-show*="visualization"] > .p-6 {
        padding-left: 1.25rem; padding-right: 1.25rem;
        /* Breathing room at the end of the scroll so content isn't flush to
           the card edge. */
        padding-bottom: 3rem;
      }
      #playground .pg-split > [x-show*="json"] .p-4.pt-12 {
        padding-left: 1.25rem; padding-right: 1.25rem;
        /* Clear the 45px floating API-Antwort bar so its first row (the opening
           brace) isn't hidden behind it. Reduced back down on mobile, where the
           bar is gone. */
        padding-top: 3.5rem;
        padding-bottom: 3rem;
      }
      /* The decorative bottom fade over the JSON made the last lines read as
         cut off when scrolled to the end — drop it in the split. */
      #playground .pg-split > [x-show*="json"] .absolute.inset-x-0.bottom-0.h-16 { display: none !important; }
      @media (max-width: 880px) {
        /* On mobile the two-pane header row is dropped (matching the
           prototype): the JSON sliver in the pane row below carries the whole
           affordance, so there is no thin header cell to keep in sync with the
           sliding pane. */
        #playground .fold-split-header { display: none !important; }
        /* No floating bar on mobile, so the JSON doesn't need to clear it. */
        #playground .pg-split > [x-show*="json"] .p-4.pt-12 { padding-top: 1.5rem; }
      }
      /* 15. Split output: viz 2/3 + JSON 1/3 (desktop); JSON sliver on mobile
             (variant D). The playground component sets $split=true, which turns
             its Content Container into .pg-split and shows both panes. */
      #playground .pg-split {
        display: grid !important;
        grid-template-columns: 2fr 1fr;
        gap: 0;
        height: 100% !important;
        transition: grid-template-columns .38s cubic-bezier(.32, .72, 0, 1);
      }
      #playground .pg-split > [x-show*="visualization"],
      #playground .pg-split > [x-show*="json"] {
        min-width: 0; min-height: 0; height: 100% !important; overflow: auto;
      }
      #playground .pg-split > [x-show*="json"] { position: relative; }
      /* 20. Two-tone panes inside the card: the visualization on the glass surface draws the eye, the JSON a step
             back (the page tone) with a soft inset shadow on the seam. */
      #playground .pg-split > [x-show*="visualization"] {
        border-right: 1px solid var(--ds-line-soft); background: var(--ds-surface);
        -webkit-backdrop-filter: blur(var(--ds-glass-blur)); backdrop-filter: blur(var(--ds-glass-blur));
      }
      #playground .pg-split > [x-show*="json"] {
        background: rgb(var(--ds-page) / .72); box-shadow: inset 9px 0 12px -9px rgb(0 0 0 / .08);
        -webkit-backdrop-filter: blur(var(--ds-glass-blur)); backdrop-filter: blur(var(--ds-glass-blur));
      }
      @media (prefers-color-scheme: dark) {
        #playground .pg-split > [x-show*="json"] { box-shadow: inset 9px 0 12px -9px rgb(0 0 0 / .45); }
      }
      #playground .pg-split > [x-show*="json"] pre,
      #playground .pg-split > [x-show*="json"] code { white-space: pre-wrap !important; overflow-wrap: anywhere; }
      /* The JSON sliver and its open-state stub are one handle (2026-10-02): 40px wide (was 52/44) — the whole
         column is the tap target over the card's full height, so it stays easy to hit while the viz gets 12px —
         in quiet neutrals: the amber strip, label and glowing caret were too loud, in dark mode most of all.
         The caret is the text colour on a plain round chip; the label is muted. Signals (.sig-split) uses the same. */
      #playground {
        --pg-rail-w: 40px;
        --pg-rail-pane: var(--ds-surface);
        --pg-rail-wash: var(--ds-line-soft);
        --pg-rail-label: rgb(var(--ds-muted));
        --pg-rail-chip: rgb(var(--ds-card));
        --pg-rail-chip-border: var(--ds-line);
        --pg-rail-caret-open: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234b5563' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 6l-6 6 6 6'/%3E%3C/svg%3E");
        --pg-rail-caret-back: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234b5563' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 6l6 6-6 6'/%3E%3C/svg%3E");
      }
      @media (prefers-color-scheme: dark) {
        #playground {
          --pg-rail-caret-open: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23f1f5f9' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 6l-6 6 6 6'/%3E%3C/svg%3E");
          --pg-rail-caret-back: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23f1f5f9' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 6l6 6-6 6'/%3E%3C/svg%3E");
        }
      }
      @media (max-width: 880px) {
        /* Variant D — the JSON is a tappable sliver, not a stacked full pane.
           Bounding the split's height is what stops the "very long element":
           the single grid row can no longer grow to the JSON's length; the viz
           scrolls inside it. Tapping the sliver toggles jsonOpen (handler on
           the container), sliding the JSON in from the right. */
        #playground .pg-split {
          height: 68vh !important;
          max-height: 560px;
          grid-template-columns: 1fr var(--pg-rail-w);
        }
        #playground .pg-split.pg-json-open { grid-template-columns: var(--pg-rail-w) 1fr; }
        /* Tablets (768–880 px) keep the card's fixed height (md:h-[500px]): the phones' 68vh/560px ran 60px past
           it and cut off the end of the result (Kevin, 2026-10-30, with the "more below" pill). */
        @media (min-width: 768px) {
          #playground .pg-split { height: 100% !important; max-height: none; }
        }

        /* Viz scrolls within the bounded height; when the JSON is open it
           collapses to a quiet "back to Darstellung" stub that mirrors the
           sliver — a neutral strip with a vertical label + a caret ("›",
           pointing back to where the viz reopens). Tapping it closes the JSON
           (handler on the container). Same handle as the sliver (see the
           --pg-rail-* tokens above). */
        #playground .pg-split.pg-json-open > [x-show*="visualization"] { overflow: hidden; cursor: pointer; }
        #playground .pg-split.pg-json-open > [x-show*="visualization"] > * { opacity: 0; pointer-events: none; }
        #playground .pg-split.pg-json-open > [x-show*="visualization"]::before {
          content: "Darstellung"; position: absolute; inset: 0; z-index: 5;
          display: flex; align-items: center; justify-content: center;
          writing-mode: vertical-rl; transform: rotate(180deg);
          font-family: inherit; font-size: 10px; font-weight: 700;
          letter-spacing: 0.13em; text-transform: uppercase;
          color: var(--pg-rail-label);
          background: var(--pg-rail-wash);
          pointer-events: none;
        }
        #playground .pg-split.pg-json-open > [x-show*="visualization"]::after {
          content: ""; position: absolute; top: 12px; left: 50%; transform: translateX(-50%);
          z-index: 6; width: 24px; height: 24px; border-radius: 50%;
          /* Chevron as a centered SVG background — font-metric independent. */
          background: var(--pg-rail-caret-back) center / 11px 11px no-repeat, var(--pg-rail-chip);
          border: 1px solid var(--pg-rail-chip-border); pointer-events: none;
        }

        /* JSON column is the tap target; overflow hidden while closed so the
           payload can't stretch the row, scrollable once open. */
        #playground .pg-split > [x-show*="json"] { overflow: hidden; cursor: pointer; }
        #playground .pg-split.pg-json-open > [x-show*="json"] { overflow: auto; cursor: default; }
        /* Closed, the response underneath takes no taps (2026-10-02): the tap that opens the sliver landed on
           a JSON row and folded it (the root, under the caret chip). Signals' sliver does the same below. */
        #playground .pg-split:not(.pg-json-open) > [x-show*="json"] > * { pointer-events: none; }
        /* While closed the sliver shows only its toggle, never the waiting placeholder (Kevin, 2026-09-30):
           opened during a request, the pane shows its regular loading state. */
        #playground .pg-split:not(.pg-json-open) .pg-json-wait,
        #playground .sig-split:not(.sig-json-open) .pg-json-wait { display: none !important; }

        /* Closed: the JSON is a faint, NON-WRAPPING texture behind the sliver
           label — pre (never pre-wrap) so it cannot grow tall — masked to fade
           out toward the sliver. */
        #playground .pg-split:not(.pg-json-open) > [x-show*="json"] pre,
        #playground .pg-split:not(.pg-json-open) > [x-show*="json"] code { white-space: pre !important; }
        #playground .pg-split:not(.pg-json-open) > [x-show*="json"] .p-4.pt-12 {
          opacity: 0.16; filter: grayscale(1);
          -webkit-mask-image: linear-gradient(to right, black 0, transparent 74%);
          mask-image: linear-gradient(to right, black 0, transparent 74%);
        }

        /* Sliver affordance: a quiet strip on the viz's own surface (no recessed seam shadow) with the vertical
           "API-Antwort" label and a round caret, so it plainly reads as "tap to open the response". */
        #playground .pg-split:not(.pg-json-open) > [x-show*="json"] { background: var(--pg-rail-pane); box-shadow: none; }
        #playground .pg-split:not(.pg-json-open) > [x-show*="json"]::before {
          content: "API-Antwort"; position: absolute; inset: 0; z-index: 5;
          display: flex; align-items: center; justify-content: center;
          writing-mode: vertical-rl; transform: rotate(180deg);
          font-family: inherit; font-size: 10px; font-weight: 700;
          letter-spacing: 0.13em; text-transform: uppercase;
          color: var(--pg-rail-label);
          background: var(--pg-rail-wash);
          pointer-events: none;
        }
        #playground .pg-split:not(.pg-json-open) > [x-show*="json"]::after {
          content: ""; position: absolute; top: 12px; left: 50%; transform: translateX(-50%);
          z-index: 6; width: 24px; height: 24px; border-radius: 50%;
          /* Chevron as a centered SVG background (not a text glyph) so it is
             perfectly centered regardless of the font's glyph metrics. */
          background: var(--pg-rail-caret-open) center / 11px 11px no-repeat, var(--pg-rail-chip);
          border: 1px solid var(--pg-rail-chip-border);
          box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06); pointer-events: none;
        }

      }
    

      /* 8. Guest redaction hint ("Öffentliche Vorschau: Einige personen-
            bezogene Daten können geschwärzt sein.") removed — it is the
            sibling of the Turnstile widget in both guest blocks. */
      #playground .cf-turnstile + p { display: none !important; }
      /* 12. Submit buttons do not sit INSIDE the input pill: the shared .playground-input-shell is a plain row
             (no chrome), the input fields carry the field look and the buttons stand beside them. (Search's token
             bar is the field there.) The row's gap: 6px, 4px on phones (it came from the old theme until
             2026-10-31; the markup's gap-2 / sm:gap-3 would open it to 8 / 12). */
      #playground .playground-input-shell { gap: 6px; }
      @media (max-width: 639px) { #playground .playground-input-shell { gap: 4px; } }
      /*     The shell inputs (.playground-shell-input) wear the system's field (44px: the field is the row's
             protagonist). */
      #playground .playground-input-shell > div > .playground-shell-input {
        background: var(--ds-solid) !important; border: 1px solid var(--ds-line) !important; border-radius: var(--ds-radius-control) !important;
        box-shadow: none !important; font-family: var(--ds-font-body) !important; font-size: 14px !important; color: rgb(var(--ds-heading)) !important;
        transition: border-color var(--ds-dur-fast) var(--ds-ease), box-shadow var(--ds-dur-fast) var(--ds-ease);
        min-height: 2.75rem !important;
        height: auto !important;
        padding-left: 0.875rem !important;
      }
      /*     The row's controls (Datenpunkte / Filter, Abrufen / Suchen / Filtern and
             their loading twins) match the field's height (Kevin, 2026-09-30), in the system's button shape and type. */
      #playground .playground-input-shell > button {
        height: 2.75rem !important;
        border-radius: var(--ds-radius-control) !important; font-family: var(--ds-font-body) !important; font-size: 14px !important; font-weight: 600 !important;
      }
      /*     Phones (2026-10-02): the option (Datenpunkte / Filter) and the action (Abrufen / Suchen / Filtern) share
             one row under the field instead of two full-width rows; the action takes the rest of the width. */
      @media (max-width: 639px) {
        #playground .playground-input-shell.pg-ctl-row { flex-direction: row; flex-wrap: wrap; }
        #playground .playground-input-shell.pg-ctl-row > :not(.pg-ctl-opt):not(.pg-ctl-go) { flex: 1 1 100%; }
        #playground .playground-input-shell.pg-ctl-row > .pg-ctl-opt { flex: 0 0 auto; width: auto; }
        #playground .playground-input-shell.pg-ctl-row > .pg-ctl-go { flex: 1 1 0%; width: auto; min-width: 0; }
      }
      /*     Person fields carry leading icons — the 14px re-chrome padding above
             put the placeholder underneath them; restore the icon clearance. */
      #playground #person_q_input,
      #playground #organization_q_input,
      #playground #person_q_input_ph,
      #playground #organization_q_input_ph,
      #playground #playgroundSuggestInput,
      #playground #signals_org_input,
      #playground #signals_org_input_ph {
        padding-left: 2.25rem !important;
      }

      /*     Dokumente's two fields carry the person fields' 16px icon at left-3 too (2026-10-02): the same clearance;
             the type select's empty choice in the placeholder colour. */
      #playground #document_company_id_input,
      #playground #document_type_select,
      #playground #document_company_id_input_ph,
      #playground #document_type_select_ph {
        padding-left: 2.25rem !important;
      }
      /*     (the empty choice's placeholder colour and the blocked-submit error state: the design-system block below) */
      /* 22. Uniform output-card height across all playgrounds, pinned to the
             org card's (md 500px / lg 650px). Person's card grid had no height
             cap, so long JSON stretched the card to ~2000px — now the panes
             scroll internally like org's. Search/signals wrappers align their
             640px to the same 650px at lg. */
      @media (min-width: 768px) {
        #playground .psp div.grid.relative { height: 500px; }
        #playground .psp section > div.relative { height: 100%; }
        /* (Suche's card carries md:h-[500px] lg:h-[650px] in its markup) */
      }
      @media (min-width: 1024px) {
        #playground .psp div.grid.relative { height: 650px; }
        #playground [class*="h-[640px]"] { height: 650px !important; }
      }
      /* 22b. The org card is the one the others are pinned to — but its own
              height lives in an :class binding (isFullscreen ? h-[85vh] :
              md:h-[500px] lg:h-[650px]), so until Alpine evaluates it the card
              has NO height and shrinks to whatever is inside: the skeleton.
              When the real content arrives the card jumps to full height.
              Pinning it in CSS gives it the height at first paint. Scoped
              :not(.fullscreen-overlay) so the binding still owns fullscreen —
              an id selector would otherwise outrank Tailwind's h-[85vh]. */
      @media (min-width: 768px) {
        #playground #fullscreen-container:not(.fullscreen-overlay) #fullscreen-content { height: 500px; }
      }
      @media (min-width: 1024px) {
        #playground #fullscreen-container:not(.fullscreen-overlay) #fullscreen-content { height: 650px; }
      }
      /* 23. Document card's response-headers pane (fold split): right 1/3 under
             the API-Antwort bar; the viewer keeps cols 1-2. Panes wear the same
             two-tone surfaces as the other tabs' split (design system, 2026-10-26:
             viz on the glass surface, response on the page tone + seam shadow),
             same content padding (3.5rem clears the bar), and the grid gap closes
             so the panes touch. The loading page, the headers' code rows and the PDF frame's arrival:
             resources/css/playground-results/document.css (shared with /playground). */
      #playground .dk-grid { gap: 0; }
      /* The endpoints section on phones (partials/home/sections/endpoints, Kevin 2026-10-25): no tabs, every endpoint
         as a card below the other; outranks x-show's inline display and [x-cloak]. */
      @media (max-width: 639px) { #features .ep-panel { display: block !important; } }
      #playground .doc-headers-pane { order: 2; padding: 1rem 1.25rem; text-align: left; }
      @media (min-width: 768px) {
        #playground .doc-headers-pane {
          order: 0;
          grid-column: 3;
          grid-row: 1;
          padding: 3.5rem 1.25rem 3rem;
          height: 100%;
          overflow: auto;
          background: rgb(var(--ds-page) / .72);
          -webkit-backdrop-filter: blur(var(--ds-glass-blur)); backdrop-filter: blur(var(--ds-glass-blur));
          box-shadow: inset 9px 0 12px -9px rgb(0 0 0 / .08);
        }
        #playground .dk-viewer {
          background: var(--ds-surface);
          -webkit-backdrop-filter: blur(var(--ds-glass-blur)); backdrop-filter: blur(var(--ds-glass-blur));
          border-right: 1px solid var(--ds-line-soft);
        }
      }
      @media (prefers-color-scheme: dark) and (min-width: 768px) {
        #playground .doc-headers-pane { box-shadow: inset 9px 0 12px -9px rgb(0 0 0 / .45); }
      }
      /* 27. The option strips under the control rows (Datenpunkte, Filter): x-ds.option-strip and its parts
             (2026-10-27); what stays here is the fields inside them. The height opens with x-collapse. */
      @media (prefers-reduced-motion: reduce) {
        #playground [x-collapse] { transition: none !important; }
      }
      /* the tab a link opened, marked for a moment on arrival (playgroundTabs' arrive), in the tabs' blue */
      @keyframes pgArrive {
        0% { box-shadow: 0 0 0 0 rgb(var(--ds-primary) / .45); }
        70% { box-shadow: 0 0 0 8px rgb(var(--ds-primary) / 0); }
        100% { box-shadow: 0 0 0 0 rgb(var(--ds-primary) / 0); }
      }
      #playground .pg-tabs-top [role=tab].pg-arrive { animation: pgArrive 0.8s ease-out 2; }
      #playground .fold-finput { width: 170px; }
      #playground .fold-finput--s { width: 110px; }
      /* Guest locks on the strips' fields and prefills (Kevin, 2026-09-29; chips: x-ds.toggle-chip locked): what a
         guest cannot use stays visible and readable, with a padlock; a click shows the guest hint (x-ds.gate). */
      #playground [data-ds-strip] .is-guest-locked { cursor: pointer; }
      #playground [data-ds-strip] .guest-lock-ic { width: 11px; height: 11px; flex-shrink: 0; }
      /* the padlock on a run button (Personenprofil, Dokumente, Signals) and in the Signals company field */
      #playground .guest-lock-cta-ic { display: inline-block; position: relative; z-index: 1; width: 13px; height: 13px; margin-left: 6px; flex-shrink: 0; color: currentColor; opacity: .85; vertical-align: -2px; }
      #playground .guest-lock-field-ic { position: absolute; right: 12px; top: 50%; width: 12px; height: 12px; transform: translateY(-50%); pointer-events: none; }
      #playground [data-ds-strip] .guest-locked-field { position: relative; cursor: pointer; }
      #playground [data-ds-strip] .guest-locked-field > .guest-lock-ic { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); pointer-events: none; }
      #playground [data-ds-strip] .guest-locked-field input:disabled, #playground [data-ds-strip] .guest-locked-field select:disabled { pointer-events: none; cursor: pointer; }
      /* a locked field stays readable (the padlock says why), so not x-ds.field's flat disabled look */
      #playground [data-ds-strip] .guest-locked-field input:disabled { opacity: 1; background: rgb(var(--ds-field)); box-shadow: var(--ds-shadow-field); }
      /* between the control row and the strip on every tab; enters like the fold's mode hint (fade + short
         drop), leaves with a quick fade */
      /* No flex gap in the control forms (Kevin, 2026-09-30): their empty wrappers after the input row (lock
         hints, Turnstile, closed strips) each added 8px, so the result card sat 20–36px below the inputs
         depending on the tab. Whatever shows there brings its own 8px margin; the card sits 20px below on
         every tab. */
      #playground form:has(> .playground-input-shell) { row-gap: 0 !important; }
      #playground .guest-lock-hint-wrap { margin-top: 8px; }
      #playground .guest-lock-hint-wrap:has(> [data-ds-gate][style*="display: none"]),
      #playground .guest-lock-hint-wrap:has(> [data-ds-gate][x-cloak]) { margin-top: 0; }
      /* the hints under the row (guest lock, plan lock, credit box, the Firmenprofil AI/realtime hint): the system's
         toast look in place — a card, 14/13 type, the cost button sm (sign up, top up) and the secondary button sm */
      /* the hints themselves (guest lock, plan lock, credit box, the Firmenprofil AI/realtime hint, the Personenprofil
         gate): x-ds.gate (2026-10-27); here their leave fade */
      #playground .guest-lock-hint-leave { transition: opacity .15s ease; }
      #playground .guest-lock-hint-leave-start { opacity: 1; }
      #playground .guest-lock-hint-leave-end { opacity: 0; }
      /* Signals filter pane = the full playground's controls (Kevin, 2026-09-25): the dates in the shell, the
         ranges as prefill links under them. Their look (chips, fields, prefills) is the design-system block at the
         end of this file; this is the prefills' layout. */
      #playground [data-ds-strip].sig-fstrip .pgw-prefills { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-top: 7px; }
      #playground [data-ds-strip].sig-fstrip .pgw-prefill {
        padding: 0; margin: 0; border: 0; background: none; border-radius: 0 !important; cursor: pointer; text-align: left;
        text-decoration: underline; text-underline-offset: 3px;
        transition: color var(--ds-dur-fast) var(--ds-ease), text-decoration-color var(--ds-dur-fast) var(--ds-ease);
      }
      /* the strips' fields: the design-system block at the end of this file; date fields drop their raw native chrome */
      #playground [data-ds-strip] input[type="date"] {
        -webkit-appearance: none;
        appearance: none;
        font-family: inherit;
      }
      #playground [data-ds-strip] input[type="date"]::-webkit-calendar-picker-indicator {
        opacity: 0.5;
        cursor: pointer;
      }
      /* The playground handoff reuses the split-pane headers' fold-open-pg
         ghost link ("Im Playground öffnen") — classes live in the markup,
         nowrap/no-underline comes from the shared rule above. */
      /* 14. Signals (rebuilt 2026-09-09; on the design system 2026-10-26, /playground's styles-signals as the
             reference): .sig-controls (the request builder) ABOVE the card, .sig-card (the output card: the live
             feed | the JSON) below. Tokens only; the layout (heights, split, strip beside the open detail, the
             mobile sliver) is unchanged. The frame both pages share (pane head, list box, detail panel, back
             link, loading rows): resources/css/playground-results/signals.css. */
      /* Same vertical rhythm as the other control rows: cut #9 gives their
         forms (form.flex.gap-2.flex-col) 0.5rem above and 1.25rem below —
         signals' controls are a div, so they take the same values here. */
      #playground .sig-controls { margin-top: 0.5rem; margin-bottom: 1.25rem; }
      /* Applied filters, named in the feed header: the feed is still live, these say how it is narrowed.
         Neutral, square-cornered tags (x-ds.badge's neutral look). */
      #playground .sig-ftags {
        display: inline-flex; align-items: center; gap: 5px;
        min-width: 0; overflow: hidden;
      }
      #playground .sig-ftag {
        flex-shrink: 1; min-width: 0;
        max-width: 34ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
        padding: 1px 6px; border-radius: var(--ds-radius-chip);
        border: 1px solid var(--ds-line-soft); background: var(--ds-line-soft);
        font-family: var(--ds-font-body); font-size: 12px; font-weight: 500; letter-spacing: 0; text-transform: none;
        color: rgb(var(--ds-body)); line-height: 16px;
      }
      /* The output card: the system's card (hairline, card shadow) over a transparent body — its two panes are
         the glass, like the other tabs' .pg-split. Uniform height; overflow:hidden clips the rows to the corners. */
      #playground .sig-card {
        border: 1px solid var(--ds-line-soft);
        background: transparent;
        border-radius: var(--pg-card-radius, var(--ds-radius-card));
        box-shadow: var(--ds-shadow-card);
        overflow: hidden;
        height: 500px;
      }
      @media (min-width: 1024px) { #playground .sig-card { height: 650px; } }

      /* ---- Signals split: viz feed | JSON, coupled on select ---- */
      /* The split body: feed 2/3, JSON 1/3 — the other tabs' grid-cols-3 widths (Kevin, 2026-09-30). */
      #playground .sig-split { display: grid; grid-template-columns: 2fr 1fr; }
      /* the other tabs' two panes: the feed on the glass surface, the JSON a step back */
      #playground .sig-viz {
        position: relative; overflow: hidden;
        border-right: 1px solid var(--ds-line-soft);
        background: var(--ds-surface);
        -webkit-backdrop-filter: blur(var(--ds-glass-blur)); backdrop-filter: blur(var(--ds-glass-blur));
      }
      #playground .sig-json-pane {
        background: rgb(var(--ds-page) / .72);
        -webkit-backdrop-filter: blur(var(--ds-glass-blur)); backdrop-filter: blur(var(--ds-glass-blur));
        box-shadow: inset 9px 0 12px -9px rgb(0 0 0 / .08);
      }
      @media (prefers-color-scheme: dark) { #playground .sig-json-pane { box-shadow: inset 9px 0 12px -9px rgb(0 0 0 / .45); } }
      /* The pane labels (Live-Feed, API-Antwort): DESIGN.md's label — 11px, 600, uppercase +8 %, faint; the live
         indicator beside it is a tiny live register (.sig-reg, below), the newest entry in the status green. */
      #playground .sig-live,
      #playground .sig-json-label {
        display: inline-flex; align-items: center; gap: 10px;
        font-family: var(--ds-font-body); font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em;
        font-weight: 600; color: rgb(var(--ds-faint)); line-height: 1;
      }
      /* The register sits in an icon-width slot so it centres over the row icons, and "Live-Feed" lines up with
         the row text (mirrors a row: 28px icon + 10px gap). */
      #playground .sig-live-slot { width: 28px; display: inline-flex; justify-content: center; flex-shrink: 0; }
      /* The live register: an 18x14 ledger of 2px entries (a bullet, then the line). Five run one conveyor (one keyframe set, each line a
         fifth of the 7s cycle behind the last): an entry writes itself in at the top (it grows from the left, in
         green), holds, then steps down a row every 1.4s, greys out, fades in the last row and drops out while the
         next one writes in. Line lengths differ, so the ledger reads like entries, not stripes. */
      #playground .sig-reg { --reg-line: rgb(var(--ds-faint)); --reg-new: rgb(var(--ds-ok)); position: relative; display: block; width: 18px; height: 14px; overflow: hidden; }
      #playground .sig-reg > i {
        position: absolute; left: 0; top: 0; height: 2px; border-radius: 1px;
        color: var(--reg-line); background: linear-gradient(to right, currentColor 0 2px, transparent 2px 4px, currentColor 4px);
        transform-origin: left center; opacity: 0;
        animation: sigRegRow 7s cubic-bezier(.32, .72, 0, 1) infinite, sigRegInk 7s linear infinite;
      }
      #playground .sig-reg > i:nth-child(1) { width: 18px; animation-delay: 0s; }
      #playground .sig-reg > i:nth-child(2) { width: 13px; animation-delay: -1.4s; }
      #playground .sig-reg > i:nth-child(3) { width: 16px; animation-delay: -2.8s; }
      #playground .sig-reg > i:nth-child(4) { width: 11px; animation-delay: -4.2s; }
      #playground .sig-reg > i:nth-child(5) { width: 15px; animation-delay: -5.6s; }
      @keyframes sigRegRow {
        0% { transform: translateY(-3px) scaleX(0.15); opacity: 0; }
        7% { transform: translateY(0) scaleX(1); opacity: 1; }
        20% { transform: translateY(0) scaleX(1); opacity: 1; }
        26% { transform: translateY(4px) scaleX(1); opacity: 1; }
        40% { transform: translateY(4px) scaleX(1); opacity: 0.85; }
        46% { transform: translateY(8px) scaleX(1); opacity: 0.7; }
        60% { transform: translateY(8px) scaleX(1); opacity: 0.7; }
        66% { transform: translateY(12px) scaleX(1); opacity: 0.4; }
        80% { transform: translateY(12px) scaleX(1); opacity: 0.4; }
        86% { transform: translateY(15px) scaleX(1); opacity: 0; }
        100% { transform: translateY(15px) scaleX(1); opacity: 0; }
      }
      @keyframes sigRegInk { 0%, 17% { color: var(--reg-new); } 27%, 100% { color: var(--reg-line); } }
      @media (prefers-reduced-motion: reduce) {
        #playground .sig-reg > i { animation: none; opacity: 1; }
        #playground .sig-reg > i:nth-child(1) { color: var(--reg-new); }
        #playground .sig-reg > i:nth-child(2) { transform: translateY(4px); opacity: 0.85; }
        #playground .sig-reg > i:nth-child(3) { transform: translateY(8px); opacity: 0.7; }
        #playground .sig-reg > i:nth-child(4) { transform: translateY(12px); opacity: 0.4; }
        #playground .sig-reg > i:nth-child(5) { display: none; }
      }
      /* the count and the feed's age: meta type (13px muted), the number in the heading colour */
      #playground .sig-fresh {
        display: inline-flex; align-items: center; gap: 5px;
        font-family: var(--ds-font-body); font-size: 13px; font-weight: 400; color: rgb(var(--ds-muted)); white-space: nowrap; line-height: 1;
      }
      #playground .sig-fresh .tabular-nums { color: rgb(var(--ds-heading)); font-weight: 600; }
      #playground .sig-fresh > span { line-height: 1; }
      #playground .sig-fresh-sep { color: rgb(var(--ds-faint)); }
      /* the lazy placeholder: the narration sits in the head, so the loading rows start at the top */
      #playground .sig-viz-head + .sig-list .sig-sk-rows { margin-top: 0; }
      /* The detail (shared frame: signals.css) covers the list's header here (z 2), from the top; phones keep the
         icon column of the list as the strip. */
      #playground .sig-detail-fold { top: 0; z-index: 3; }
      @media (max-width: 640px) { #playground .sig-detail-fold { left: 48px; } }
      /* the detail's own head (44px, like the live-feed header beside it) with the back control */
      #playground .sig-detail-head {
        flex-shrink: 0; display: flex; align-items: center; min-height: 44px; padding: 0 1.25rem;
        border-bottom: 1px solid var(--ds-line-soft);
      }
      /* JSON pane — the API-Antwort bar over /playground's viewer (partials/playground/json-viewer, .pgw-jv) */
      #playground .sig-json-head {
        display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
        min-height: 44px; padding: 0 1.25rem; flex-shrink: 0;
        border-bottom: 1px solid var(--ds-line-soft);
      }
      /* 20px sides like the other tabs' JSON body: the shared viewer's lines (.csp-jl) carry no inset of
         their own (Kevin, 2026-09-30: "no left padding"). */
      #playground .sig-json-scroll { padding: 10px 20px 20px; }

      /* Mobile (Kevin, 2026-09-28): the other fold cards' JSON sliver (Variant D, .pg-split above) instead of the
         JSON stacked under the list — the feed keeps the width, the response is a tappable strip that slides
         in (jsonOpen / openJson() in the signals view); the open state leaves a muted "Darstellung" stub. */
      @media (max-width: 880px) {
        #playground .sig-split { grid-template-columns: 1fr var(--pg-rail-w); grid-template-rows: minmax(0, 1fr); transition: grid-template-columns .28s cubic-bezier(.32,.72,0,1); }
        #playground .sig-split.sig-json-open { grid-template-columns: var(--pg-rail-w) 1fr; }
        #playground .sig-split > .sig-viz, #playground .sig-split > .sig-json-pane { position: relative; min-width: 0; }

        /* closed: the JSON is a faint texture behind the sliver label, not clickable content */
        #playground .sig-split:not(.sig-json-open) > .sig-json-pane { overflow: hidden; cursor: pointer; background: var(--pg-rail-pane); box-shadow: none; }
        #playground .sig-split:not(.sig-json-open) > .sig-json-pane > * { pointer-events: none; opacity: 0.16; filter: grayscale(1);
          -webkit-mask-image: linear-gradient(to right, #000 0, transparent 74%); mask-image: linear-gradient(to right, #000 0, transparent 74%); }
        #playground .sig-split:not(.sig-json-open) > .sig-json-pane::before {
          content: "API-Antwort"; position: absolute; inset: 0; z-index: 5;
          display: flex; align-items: center; justify-content: center;
          writing-mode: vertical-rl; transform: rotate(180deg);
          font-size: 10px; font-weight: 700; letter-spacing: 0.13em; text-transform: uppercase;
          color: var(--pg-rail-label); background: var(--pg-rail-wash); pointer-events: none;
        }
        #playground .sig-split:not(.sig-json-open) > .sig-json-pane::after {
          content: ""; position: absolute; top: 12px; left: 50%; transform: translateX(-50%);
          z-index: 6; width: 24px; height: 24px; border-radius: 50%;
          background: var(--pg-rail-caret-open) center / 11px 11px no-repeat, var(--pg-rail-chip);
          border: 1px solid var(--pg-rail-chip-border);
          box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06); pointer-events: none;
        }
        #playground .sig-live { white-space: nowrap; }   /* the narrower feed wrapped "LIVE-FEED" onto two lines */
        #playground .sig-fresh-age { display: none; }     /* the count stays; the feed's age does not fit beside it */

        /* open: the feed collapses to the muted "Darstellung" stub (tap = back) */
        #playground .sig-split.sig-json-open > .sig-viz { overflow: hidden; cursor: pointer; }
        #playground .sig-split.sig-json-open > .sig-viz > * { opacity: 0; pointer-events: none; }
        #playground .sig-split.sig-json-open > .sig-viz::before {
          content: "Darstellung"; position: absolute; inset: 0; z-index: 5;
          display: flex; align-items: center; justify-content: center;
          writing-mode: vertical-rl; transform: rotate(180deg);
          font-size: 10px; font-weight: 700; letter-spacing: 0.13em; text-transform: uppercase;
          color: var(--pg-rail-label); background: var(--pg-rail-wash); pointer-events: none;
        }
        #playground .sig-split.sig-json-open > .sig-viz::after {
          content: ""; position: absolute; top: 12px; left: 50%; transform: translateX(-50%);
          z-index: 6; width: 24px; height: 24px; border-radius: 50%;
          background: var(--pg-rail-caret-back) center / 11px 11px no-repeat, var(--pg-rail-chip);
          border: 1px solid var(--pg-rail-chip-border); pointer-events: none;
        }
      }
      @media (max-width: 880px) and (prefers-reduced-motion: reduce) { #playground .sig-split { transition: none; } }
      /* 10. Endpoint tabs: the label cross-fade and the sliding underline, shared with /playground */
#playground .pgw-tl { position: relative; display: inline-flex; flex-direction: column; transition: color .18s ease; }
      #playground .pgw-tl::after {
        content: attr(data-text); font-weight: 600; height: 0; overflow: hidden; visibility: hidden;
        white-space: nowrap; pointer-events: none;
      }
      #playground .pgw-tl::before {
        content: attr(data-text); position: absolute; left: 0; top: 0; font-weight: 600; white-space: nowrap;
        color: rgb(var(--ds-heading)); opacity: 0; transition: opacity .18s ease; pointer-events: none;
      }
      #playground .pgw-etabs [aria-selected="true"] .pgw-tl { color: transparent; }
      #playground .pgw-etabs [aria-selected="true"] .pgw-tl::before { opacity: 1; }
      /* The underline: one element, moved under the active tab; slides only after its first placement. */
      #playground .pgw-tab-ink {
        position: absolute; left: 0; height: 2px; background: rgb(var(--ds-primary));
        opacity: 0; pointer-events: none; will-change: transform, width;
      }
      #playground .pgw-tab-ink.is-on { opacity: 1; }
      #playground .pgw-tab-ink.is-ready {
        transition: transform .28s cubic-bezier(.32,.72,0,1), width .28s cubic-bezier(.32,.72,0,1), opacity .18s ease;
      }
      @media (prefers-reduced-motion: reduce) {
        #playground .pgw-tl, #playground .pgw-tl::before, #playground .pgw-tab-ink.is-ready { transition: none; }
      }
      /* 9. Output card pulled close to the inputs: every playground's main
            form (and its fullscreen clone) carries pb-6 — trimmed to a small
            deliberate gap toward the card; the collapsed guest wrapper loses
            its margin too. */
      #playground form.flex.gap-2.flex-col { padding-bottom: 1.25rem !important; margin-top: 0.5rem !important; }
      #playground form div:has(> .cf-turnstile) { margin: 0 !important; }
      /* 19. Input row left-aligned with the first tab for a tidier column.
             Desktop: the centered form (max-w-2xl) is a hair narrower than the
             tab strip, so it landed right of the first tab — widen it so its
             centered left edge meets the first tab. Mobile tweak follows in
             the media query below. */
      @media (min-width: 641px) {
        #playground form.flex.gap-2.flex-col { max-width: 43rem !important; }
      }
      /* One input column on every tab (Kevin, 2026-09-25): Personenprofil's form carries the homepage's px-4
         and the signals controls are a max-w-2xl div (672px), so both sat inside the others' 43rem column —
         switching tabs looked like a shift. Same width, no side padding, the same mobile nudge. */
      #playground .psp form.flex.gap-2.flex-col { padding-left: 0; padding-right: 0; }
      @media (min-width: 641px) {
        #playground .sig-controls { max-width: 43rem; }
      }
      @media (max-width: 640px) {
        /* Phones (Patrick, 2026-10-02): every tab's controls on the page's 16px edge, like the tabs and the card
           (the 7px nudge matched the tabs' old extra inset), 12px under the tabs and 16px above the card. */
        #playground form.flex.gap-2.flex-col,
        #playground .psp form.flex.gap-2.flex-col { padding-left: 0; margin-top: 12px !important; padding-bottom: 16px !important; }
        #playground .sig-controls { padding-left: 0; margin-top: 12px; margin-bottom: 16px; }
      }
      /* 7. Turnstile: interaction-only appearance (attribute set by the
            script below) — invisible unless a challenge actually needs the
            user; the reserved 65px box goes with it. */
      #playground .cf-turnstile { min-height: 0 !important; }
      /* While Cloudflare shows its challenge the widget has a box (marked by partials/playground/turnstile): room
         above it, so it does not sit flush under the input; below it the form's own padding stands
         (Patrick, 2026-11-11). */
      #playground .cf-turnstile.has-challenge { margin-top: 1rem; }
      /* 17. Person: the profile + JSON split spans the card (2/3 · 1/3); the tab has no settings column. */
      #playground .psp .grid.gap-5.relative > section.md\:col-span-2 { grid-column: 1 / -1 !important; }
      /* 4. Input controls sit OUTSIDE the card: the page-level glass panel is
            deleted; ONE output-card style is drawn around every API response —
            the four grid playgrounds (org/search/person/document) and the
            signals feed body — so they all match. The person paywall is not on
            this grid, so it stays uncarded (non-API surface), as intended. */
      /* The frame: the system's card (hairline, card shadow, the card radius) over a transparent body: its two panes
         are the glass. .fcr-card is the output card's hook (partials/fold-credits) on every tab; Signals carries
         its own frame on .sig-card (rule #14). */
      #playground .fcr-card {
        border: 1px solid var(--ds-line-soft);
        border-radius: var(--pg-card-radius);
        box-shadow: var(--ds-shadow-card);
        background: transparent;
        padding: 0;
        overflow: hidden;
      }
      /* The radiant + STRUCTURE live on the section BEHIND the card, not on the
         card, so the translucent frosted panes have real texture to refract
         (that's what makes the glass read as glass): the brand graphics' orange
         and blue glow over the dot grid (tokens.css › Brand graphics); transparent
         base so the page shows through. Viewport-anchored so it stays put behind
         the card regardless of section height. */
      /* The backdrop sits on its own layer behind the content (.pg-backdrop, the section's first child) so it
         can fade out at the bottom (Kevin, 2026-09-30: it ended in a hard line above the next section); the
         glass panes still refract it. Isolation keeps the layer behind the section's content and above the page. */
      #playground { position: relative; isolation: isolate; }
      /* The soft blue glow behind the hero and the tabs, dark mode only (in light it was invisible, 2% at most).
         It came from the old theme's section glow until 2026-10-31; now the brand glow token. */
      @media (prefers-color-scheme: dark) {
        :root:not(.light) #playground::before {
          content: ""; position: absolute; left: 8%; right: 8%; top: 4%; height: 210px; z-index: -1; pointer-events: none;
          border-radius: 9999px; background: radial-gradient(circle, var(--ds-glow-brand), transparent 65%); filter: blur(28px);
        }
      }
      #playground > .pg-backdrop {
        position: absolute; inset: 0; z-index: -1; pointer-events: none;
        background:
          radial-gradient(var(--ds-dots) 1px, transparent 1.5px) 0 0 / 23px 23px,
          radial-gradient(46% 40% at 13% 62%, var(--ds-glow-cost), transparent 60%),
          radial-gradient(44% 38% at 89% 55%, var(--ds-glow-brand), transparent 60%);
        background-attachment: fixed, fixed, fixed;
        -webkit-mask-image: linear-gradient(to bottom, black calc(100% - 160px), transparent);
        mask-image: linear-gradient(to bottom, black calc(100% - 160px), transparent);
      }

    

      /* Mobile scrolling for tabs */
      @media (max-width: 640px) {
        .overflow-x-auto {
          -webkit-overflow-scrolling: touch;
          scrollbar-width: none;
          -ms-overflow-style: none;
        }
        .overflow-x-auto::-webkit-scrollbar {
          display: none;
        }
      }
    

  /* On the design system since 2026-10-26: tokens only (light and dark follow the page), the credit figures in the
     cost colour of the credit box, the window like /playground's credit modal (title as in x-ds.dialog, 14px rows,
     the system's buttons). */
  /* the cost footer: the output card's last row, full width under both panes (it covers neither); the whole row
     opens the credit window. Desktop cards have a fixed height: the content row gives up the footer's height. */
  #playground .fcr-card { row-gap: 0; }
  @media (min-width: 768px) {
    #playground .fcr-card { grid-template-rows: minmax(0, 1fr) auto; }
  }
  /* with the footer under it, the content's rounded bottom corners would show against it (a selector, not a
     class: Livewire would take a class off the card on its next render) */
  #playground .fcr-card:has(.fcr-foot:not([x-cloak]):not([style*="none"])) > * { border-bottom-left-radius: 0 !important; border-bottom-right-radius: 0 !important; }
  #playground .fcr-card .fcr-foot { order: 999; grid-column: 1 / -1; flex: 0 0 auto; display: flex; align-items: center; gap: 10px; width: 100%;
    min-height: 40px; margin: 0; padding: 8px 16px; border: 0; border-top: 1px solid var(--ds-line-soft); border-radius: 0 !important;
    background: var(--ds-cost-tint); box-shadow: none; font: inherit; font-family: var(--ds-font-body); text-align: left; cursor: pointer;
    transition: filter var(--ds-dur-fast) var(--ds-ease); }
  #playground .fcr-card .fcr-foot:hover { filter: brightness(.98) saturate(1.1); }
  #playground .fcr-card .fcr-foot:focus-visible { outline: 2px solid rgb(var(--ds-primary)); outline-offset: -2px; }
  #playground .fcr-foot-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; font-weight: 600; color: rgb(var(--ds-heading)); }
  #playground .fcr-foot-more { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 2px; font-size: 13px; font-weight: 600; color: rgb(var(--ds-cost-text)); }
  #playground .fcr-foot:hover .fcr-foot-more-l { text-decoration: underline; text-underline-offset: 3px; }
  /* phones: the sentence gets the room, the chevron still says there is more */
  @media (max-width: 639px) {
    #playground .fcr-foot-more-l { display: none; }
  }
  /* the credit window: x-ds.dialog with x-ds.table (partials/fold-credit-banner, 2026-10-30) */


  /* On the design system since 2026-10-26 (Kevin): tokens only, so light and dark follow the page; the code in IBM
     Plex Mono 12/20 with the code colours of the request bar and the code example (key, string, number, punct);
     the bar's controls in the system's field and button looks; search marks and the focused block in the brand blue
     (orange is the one action, never a highlight). */
  #playground .pgw-jv { display: flex; flex-direction: column; }
  #playground .pgw-jv-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; position: relative; }
  /* header bar: search · counter · prev/next · (spacer) · fold all · unfold all · copy */
  #playground .pgw-jbar { flex-shrink: 0; display: flex; align-items: center; gap: 6px; height: 44px; padding: 0 20px;
    border-bottom: 1px solid var(--ds-line-soft); font-family: var(--ds-font-body); }
  /* the search field: one box (icon + input) in the field look; the theme's input rules are switched off with
     !important because they beat this scope */
  #playground .pgw-jsearch { display: flex; align-items: center; gap: 8px; width: 240px; max-width: 45%; height: 30px; padding: 0 10px;
    color: rgb(var(--ds-faint)); border: 1px solid var(--ds-field-line); border-radius: var(--ds-radius-control); background: rgb(var(--ds-field)); box-shadow: var(--ds-shadow-field);
    transition: border-color var(--ds-dur-fast) var(--ds-ease), box-shadow var(--ds-dur-fast) var(--ds-ease); }
  #playground .pgw-jsearch:focus-within { border-color: rgb(var(--ds-primary)); box-shadow: var(--ds-focus-field); }
  #playground .pgw-jsearch svg { width: 14px; height: 14px; flex-shrink: 0; }
  #playground .pgw-jsearch input { flex: 1 1 auto; min-width: 0; height: 28px; padding: 0 !important; margin: 0; border: 0 !important; outline: 0 !important; background: transparent !important;
    box-shadow: none !important; border-radius: 0; font-family: var(--ds-font-body); font-size: 13px; line-height: 28px; color: rgb(var(--ds-heading)); }
  #playground .pgw-jsearch input::placeholder { color: rgb(var(--ds-faint)); }
  #playground .pgw-jcount { flex-shrink: 0; min-width: 44px; font-family: var(--ds-font-code); font-size: 12px; color: rgb(var(--ds-muted)); white-space: nowrap; }
  /* ghost buttons (prev/next, fold all, unfold all) and the copy button in the secondary look */
  #playground .pgw-jbtn { flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: 30px; min-width: 30px; padding: 0 8px; margin: 0;
    border: 1px solid transparent; border-radius: var(--ds-radius-control) !important; background: transparent; color: rgb(var(--ds-muted));
    font-family: var(--ds-font-body); font-size: 13px; font-weight: 500; line-height: 1; cursor: pointer;
    transition: color var(--ds-dur-fast) var(--ds-ease), background-color var(--ds-dur-fast) var(--ds-ease), border-color var(--ds-dur-fast) var(--ds-ease); }
  #playground .pgw-jbtn svg { width: 14px; height: 14px; }
  #playground .pgw-jbtn:hover:not(:disabled) { color: rgb(var(--ds-heading)); background: var(--ds-line-soft); }
  #playground .pgw-jbtn:focus-visible { outline: 2px solid rgb(var(--ds-primary)); outline-offset: 2px; }
  #playground .pgw-jbtn:disabled { opacity: .4; cursor: default; }
  #playground .pgw-jbtn--copy { margin-left: 4px; padding: 0 12px; border-color: var(--ds-line); background: rgb(var(--ds-card)); color: rgb(var(--ds-heading)); font-weight: 600; }
  #playground .pgw-jbtn--copy:hover:not(:disabled) { background: rgb(var(--ds-card)); border-color: rgb(var(--ds-primary) / .45); }
  #playground .pgw-jbtn--copy .is-copied { color: rgb(var(--ds-ok)); }
  #playground .pgw-jspacer { flex: 1 1 auto; }
  #playground .pgw-jstatus { flex-shrink: 0; margin-left: 6px; font-family: var(--ds-font-code); font-size: 12px; font-weight: 600; color: rgb(var(--ds-muted)); }
  #playground .pgw-jstatus.is-bad { color: rgb(var(--ds-warn)); }
  /* while a request runs the bar keeps its box and border, only its controls fade (no layout shift) */
  #playground .pgw-jbar > * { transition: opacity .35s ease; }
  #playground .pgw-jbar.is-loading > * { opacity: 0; pointer-events: none; }
  /* the code: one row per line, gutter caret, line number, the highlighted line */
  #playground .pgw-jv .csp-jl { display: flex; align-items: flex-start; }
  #playground .pgw-jv .csp-ln { flex-shrink: 0; width: 2.75em; padding-right: 0.75em; text-align: right; user-select: none;
    font-family: var(--ds-font-code); font-size: 12px; line-height: 20px; color: rgb(var(--ds-faint)); opacity: .8; }
  #playground .pgw-jv .csp-jc { min-width: 0; font-family: var(--ds-font-code); font-size: 12px; line-height: 20px; white-space: pre; color: rgb(var(--ds-code-key)); }
  /* token colours: design-system/code.css; keys 600 */
  #playground .pgw-jv .sig-jk { font-weight: 600; }
  /* a masking token (docs/MASKING.md, DESIGN.md › Masked data): muted, a padlock before it; the padlock is a
     pseudo-element, so selecting and copying give the token unchanged */
  #playground .pgw-jv .sig-jm::before { content: ""; display: inline-block; width: 11px; height: 11px; margin-right: 4px; vertical-align: -1px;
    background: currentColor; -webkit-mask: var(--pgw-lock) center / contain no-repeat; mask: var(--pgw-lock) center / contain no-repeat; }
  #playground .pgw-jv { --pgw-lock: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='5' y='11' width='14' height='10' rx='2'/%3E%3Cpath d='M8 11V8a4 4 0 018 0v3'/%3E%3C/svg%3E"); }
  /* gutter caret: appears on row hover, stays while folded */
  /* the caret: the system's chevron icon at 12px in the muted colour (was a 9px "▸" in the faint one, barely readable) */
  #playground .pgw-jv .csp-fc { flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 20px; color: rgb(var(--ds-muted));
    user-select: none; cursor: pointer; opacity: 0; transition: opacity var(--ds-dur-fast), transform var(--ds-dur-fast), color var(--ds-dur-fast); }
  #playground .pgw-jv .csp-fc svg { width: 12px; height: 12px; pointer-events: none; }
  #playground .pgw-jv .csp-fc:hover { color: rgb(var(--ds-heading)); }
  #playground .pgw-jv .csp-fc:empty { cursor: default; }
  #playground .pgw-jv .csp-jl:hover .csp-fc, #playground .pgw-jv .csp-fc.is-folded { opacity: 1; }
  #playground .pgw-jv .csp-fc:not(.is-folded):not(:empty) { transform: rotate(90deg); }
  /* a folded block's summary ("… 12 Felder") reads as a quiet link */
  #playground .pgw-jv .csp-fold-sum { font-family: var(--ds-font-body); font-size: 12px; color: rgb(var(--ds-muted)); cursor: pointer; }
  #playground .pgw-jv .csp-fold-sum:hover { color: rgb(var(--ds-link)); text-decoration: underline; text-underline-offset: 2px; }
  /* Touch screens (Kevin, 2026-09-30: "a user has to tap more or less exactly at the expand arrow"): there is no
     hover, so every caret shows; the caret gets a wider hit area and a whole foldable row toggles (onClick). */
  @media (pointer: coarse) {
    #playground .pgw-jv .csp-fc:not(:empty) { opacity: 1; width: 24px; margin-left: -4px; }
    #playground .pgw-jv .csp-jl:has(> .csp-fc:not(:empty)) { cursor: pointer; }
  }
  /* search: every match tinted, the current one solid */
  #playground .pgw-jv .csp-mark { background: var(--ds-primary-soft); color: inherit; border-radius: 2px; padding: 0; }
  #playground .pgw-jv .csp-mark.is-cur { background: rgb(var(--ds-primary)); color: rgb(var(--ds-primary-fg)); }
  /* focusBlock(): the element a view points at (Signals), tinted with an inset bar (no layout shift) */
  #playground .pgw-jv .csp-jl.is-hot { background: var(--ds-primary-tint); box-shadow: inset 2px 0 0 rgb(var(--ds-primary)); }
  /* … across the pane's whole width (Kevin, 2026-10-30: it stopped short of the edges): the rows share one column as
     wide as the widest line, so the tint also runs under lines scrolled into view, and a tinted row reaches through the
     20px sides the Signals panes (the only ones that focus a block) keep around their rows */
  #playground .pgw-jv [x-html="html()"] { display: grid; grid-template-columns: minmax(100%, max-content); }
  #playground .pgw-jv .csp-jl.is-hot { margin-inline: -20px; padding-inline: 20px; }


  /* One edge, one rhythm, one radius (Patrick, 2026-10-02). On phones the claim, the tab bar, the input box and the
     result card share the page's 16px edge (the tabs had 16px more, the input box 12px more, unevenly), with calmer
     gaps: 20px from the subline to the tabs (was 48), 12px to the input box (was 8), 16px to the card (was 20). The
     result card's corners: the system's card radius on every width since 2026-10-26 (--pg-card-radius, the frames
     .fcr-card and .sig-card read it). */
  #playground { --pg-card-radius: var(--ds-radius-card); }
  @media (max-width: 639px) {
    #playground .pg-tabs-top { padding-top: 4px; }
    #playground .pg-tabs-row { padding-left: 0; padding-right: 0; }
    /* iPhone Safari zooms into a field whose text is under 16px when it gets focus: 16px in every playground field,
       so a tap opens the keyboard without zooming the page. */
    #playground input:not([type=checkbox]):not([type=radio]):not([type=range]),
    #playground select, #playground textarea { font-size: 16px !important; }
    #playground .fk-head-stats { margin-top: 8px; }
  }
    /* Phones, calmer start (2026-10-02): one column, one rhythm, the playground on the first screen.
       Revert this block (and the .har rules in home-app-release.css) to get the earlier phone layout back. */
    @media (max-width: 639px) {
      #playground { padding-top: 20px; }
      /* the claim and its subline: Tailwind classes in home.blade.php (design system, 2026-10-26) */
      #playground .pg-tabs-top { padding-top: 16px; }

      /* five tabs that fit the width: text only, equal shares, no sideways scroll */
      #playground .pg-tabs-row > div { overflow: visible; }
      #playground .pgw-etabs { display: flex; width: 100%; min-width: 0; gap: 0; }
      #playground .pgw-etabs > [role=tab] { flex: 1 1 0; min-width: 0; padding-left: 2px; padding-right: 2px; }
      #playground .pgw-etabs > [role=tab] > svg { display: none; }

      /* the result card at full width: the JSON is a strip under it, not a rail beside it. Person's card
         (.psp) sets its own single row for every width (the floating header, above); it is named here too,
         or that rule wins and the closed JSON took half the card (2026-10-22). */
      #playground .pg-split, #playground .sig-split, #playground .psp .pg-split { grid-template-columns: minmax(0, 1fr) !important; grid-template-rows: minmax(0, 1fr) 44px; }
      #playground .pg-split.pg-json-open, #playground .sig-split.sig-json-open, #playground .psp .pg-split.pg-json-open { grid-template-columns: minmax(0, 1fr) !important; grid-template-rows: 44px minmax(0, 1fr); }
      #playground .pg-split > [x-show*="visualization"], #playground .sig-split > .sig-viz { border-right: 0 !important; }
      #playground .pg-split:not(.pg-json-open) > [x-show*="json"], #playground .sig-split:not(.sig-json-open) > .sig-json-pane { border-top: 1px solid var(--ds-line-soft); }
      #playground .pg-split:not(.pg-json-open) > [x-show*="json"] .p-4.pt-12,
      #playground .sig-split:not(.sig-json-open) > .sig-json-pane > * { opacity: 0 !important; }
      #playground .pg-split:not(.pg-json-open) > [x-show*="json"]::before,
      #playground .pg-split.pg-json-open > [x-show*="visualization"]::before,
      #playground .sig-split:not(.sig-json-open) > .sig-json-pane::before,
      #playground .sig-split.sig-json-open > .sig-viz::before { writing-mode: horizontal-tb; transform: none; }
      /* the caret chip sits at the strip's right end, pointing to where the pane opens */
      #playground .pg-split:not(.pg-json-open) > [x-show*="json"]::after,
      #playground .sig-split:not(.sig-json-open) > .sig-json-pane::after { top: 50%; left: auto; right: 12px; transform: translateY(-50%) rotate(90deg); }
      #playground .pg-split.pg-json-open > [x-show*="visualization"]::after,
      #playground .sig-split.sig-json-open > .sig-viz::after { top: 50%; left: auto; right: 12px; transform: translateY(-50%) rotate(90deg); }

      /* a little more width for the card's content */
      #playground .pg-split > [x-show*="visualization"] > .p-6 { padding-left: 1rem; padding-right: 1rem; --pg-pane-x: 1rem; }
      /* … and the full-width rules of the Firmenprofil (head, section dividers) and the search list (--pg-pane-x) follow
         that 1rem: at their 20px they stuck out 4px and the pane scrolled sideways (Kevin, 2026-10-30) */
      #playground .pg-split > [x-show*="visualization"] .fk-head { margin-left: -1rem; margin-right: -1rem; padding-left: 1rem; padding-right: 1rem; }
      #playground .pg-split > [x-show*="visualization"] .fk-src { margin-left: -1rem; margin-right: -1rem; }
      #playground .pg-split > [x-show*="visualization"] .fk-src-badge { left: 7px; }
    }
    @media (max-width: 639px) {
      /* below the playground: one rhythm, calmer body text, so it reads as the same page */
      #playground { padding-bottom: 24px; }
      #playground ~ section { padding-top: 40px !important; padding-bottom: 40px !important; }
      #playground ~ section p { line-height: 1.6 !important; }
    }
    /* phones: the run button stays amber while it cannot run yet, only a touch lighter (desktop keeps its own) */
    @media (max-width: 639px) {
      #playground .pg-ctl-go:disabled:not(.animate-pulse) { opacity: .82 !important; }
    }
    

  /* The start page's playground block on the design system (Kevin, 2026-10-26): the tab row, every tab's control
     row (fields, the Datenpunkte / Filter option, the run button and its loading state), the option strips, the
     hints under the row, and the output card's frame with its API-Antwort bar. The layouts stay as they are
     (DESIGN.md: a deliberate layout keeps its form); type, colours, surfaces and controls come from the tokens and
     the system's components. The Firmenprofil result is the shared view (already on the system); the other tabs'
     visualisations are not part of this pass. These rules come last in the bundle and use the selectors (and the
     !important) of the rules they supersede above. The card radius, the tabs (partials/playground/endpoint-tabs-css),
     the fields' and buttons' shape and the panes' surfaces sit in their rules above since 2026-10-30. */

  /* The control row's fields (the field look itself: the rule above) */
  #playground .playground-input-shell > div > .playground-shell-input::placeholder { color: rgb(var(--ds-faint)) !important; opacity: 1; }
  #playground .playground-input-shell > div > .playground-shell-input:focus,
  #playground .playground-input-shell > div > .playground-shell-input:focus-visible {
    outline: none !important; border-color: rgb(var(--ds-primary)) !important; box-shadow: var(--ds-focus-field) !important;
  }
  #playground .playground-input-shell > div > svg, #playground .playground-input-shell > div > .absolute > svg { color: rgb(var(--ds-faint)) !important; }
  #playground .playground-input-shell > div > .playground-shell-input.doc-err { border-color: rgb(var(--ds-bad)) !important; box-shadow: 0 0 0 3px rgb(var(--ds-bad) / .12) !important; }
  #playground #document_type_select.doc-type-empty, #playground #document_type_select_ph.doc-type-empty { color: rgb(var(--ds-faint)) !important; }
  /* the option (Datenpunkte, Filter): x-ds.option-trigger */
  /* the run button (Abrufen, Suchen, Filtern): the cost button; disabled greyed, loading locked in full colour */
  #playground .playground-input-shell > button:not(.pg-ctl-opt) {
    border: 0 !important; background: var(--ds-cost-grad) !important; color: rgb(var(--ds-cost-fg)) !important; box-shadow: var(--ds-shadow-cost) !important;
  }
  #playground .playground-input-shell > button:not(.pg-ctl-opt):hover:not(:disabled) { filter: brightness(1.05) saturate(1.05); }
  #playground .playground-input-shell > button:not(.pg-ctl-opt):disabled { opacity: .45 !important; filter: saturate(.6); box-shadow: none !important; }
  #playground .playground-input-shell > button[aria-busy="true"]:disabled { opacity: 1 !important; filter: none; box-shadow: var(--ds-shadow-cost) !important; cursor: progress; }

  /* Option strips (Datenpunkte, Filter): x-ds.option-strip, -row, toggle-chip, option-more (2026-10-27) */
  #playground [data-ds-strip] .pgw-prefill.is-guest-locked { color: rgb(var(--ds-muted)); }
  #playground [data-ds-strip] .guest-lock-ic, #playground .guest-lock-field-ic { color: rgb(var(--ds-faint)); }
  /* fields in the strips (Suche, Signals): the system's field, compact */
  /* (the Suche strip's fields are x-ds.field size="sm" since 2026-10-30) */
  #playground [data-ds-strip].sig-fstrip .playground-input-shell .sig-field {
    height: 34px !important; min-height: 34px !important; padding: 0 0.625rem !important; font-family: var(--ds-font-body) !important; font-size: 14px !important;
    color: rgb(var(--ds-heading)) !important; border: 1px solid var(--ds-line) !important; border-radius: var(--ds-radius-control) !important;
    background: var(--ds-solid) !important; box-shadow: none !important;
  }
  #playground [data-ds-strip].sig-fstrip .sig-field::placeholder, #playground [data-ds-strip] input[type="date"] { color: rgb(var(--ds-faint)) !important; }
  #playground [data-ds-strip].sig-fstrip input:focus {
    outline: none; border-color: rgb(var(--ds-primary)) !important; box-shadow: var(--ds-focus-field) !important;
  }
  /* prefills under a field: a quiet underlined link, the chosen one in the link blue (was amber) */
  #playground [data-ds-strip].sig-fstrip .pgw-prefill, #playground [data-ds-strip] .pgw-prefill {
    font-family: var(--ds-font-body); font-size: 13px; color: rgb(var(--ds-muted)); text-decoration-color: var(--ds-line);
  }
  #playground [data-ds-strip].sig-fstrip .pgw-prefill:hover, #playground [data-ds-strip] .pgw-prefill:hover { color: rgb(var(--ds-heading)); text-decoration-color: currentColor; }
  #playground [data-ds-strip].sig-fstrip .pgw-prefill.is-on, #playground [data-ds-strip] .pgw-prefill.is-on { color: rgb(var(--ds-link)); text-decoration-color: currentColor; }
  /* the blue ghost link into /playground (pane headers, strip footers) */
  #playground .fold-open-pg {
    font-family: var(--ds-font-body); font-size: 13px !important; font-weight: 600 !important; color: rgb(var(--ds-link)) !important;
  }
  #playground .fold-open-pg:hover { color: rgb(var(--ds-link)) !important; text-decoration: underline; text-underline-offset: 2px; }

  /* the autocomplete under a field: resources/css/playground-viz.css (x-ds.suggestions' look, both pages) */

  /* Hints under the row (guest lock, credit box): x-ds.gate since 2026-10-27 */

  /* (The output card's frame and its two panes: rules #4 and #20 above.) */
  @media (prefers-color-scheme: dark) {
    #playground [data-ds-strip] .pgw-prefill.is-guest-locked { color: rgb(var(--ds-muted)); }
    #playground [data-ds-strip].sig-fstrip .playground-input-shell .sig-field {
      border-color: var(--ds-line) !important; color: rgb(var(--ds-heading)) !important; }
    #playground [data-ds-strip].sig-fstrip .pgw-prefill { color: rgb(var(--ds-muted)); }
    #playground [data-ds-strip].sig-fstrip .pgw-prefill.is-on { color: rgb(var(--ds-link)); }
  }
    
