{"id":2287,"date":"2026-07-12T14:59:10","date_gmt":"2026-07-12T12:59:10","guid":{"rendered":"https:\/\/cad-kompass.de\/?p=2287"},"modified":"2026-07-12T14:59:11","modified_gmt":"2026-07-12T12:59:11","slug":"querschnittsaufbau-werkstatt","status":"publish","type":"post","link":"https:\/\/cad-kompass.de\/?p=2287","title":{"rendered":"Querschnittsaufbau-Werkstatt"},"content":{"rendered":"\n<style>\n    .qw-box {\n        --qw-primary: #3f5f75;\n        --qw-primary-dark: #2c4a5e;\n        --qw-primary-deep: #1e3548;\n        --qw-ink: #1e293b;\n        --qw-text: #334155;\n        --qw-muted: #64748b;\n        --qw-border: #c8d6e0;\n        --qw-surface: #f7f9fb;\n        --qw-good: #059669;\n        --qw-good-deep: #15803d;\n        --qw-warn: #d97706;\n        --qw-warn-deep: #92700c;\n        --qw-warn-border: #f4cf81;\n        --qw-warn-bg: #fffbeb;\n        --qw-error: #dc2626;\n        --qw-accent: #e8913a;\n        \/* tool-spezifische Codefarben: je Codeart eine eigene Farbe, damit man Punkt-, *\/\n        \/* Verknuepfungs- und Profilartcode im Querschnitt sofort auseinanderhaelt *\/\n        --qw-code-point: #7c3aed;\n        --qw-code-link: #0891b2;\n        --qw-code-shape: #e8913a;\n        background: var(--qw-surface);\n        border: 3px solid var(--qw-primary);\n        border-radius: 8px;\n        margin: 28px 0;\n        overflow: hidden;\n        position: relative;\n        font-family: inherit;\n        color: var(--qw-text);\n        line-height: 1.55;\n    }\n    .qw-box, .qw-box *, .qw-box *::before, .qw-box *::after { box-sizing: border-box; }\n\n    .qw-header {\n        background: linear-gradient(135deg, var(--qw-primary-deep) 0%, var(--qw-primary-dark) 100%);\n        padding: 20px 28px 18px;\n        position: relative;\n    }\n    .qw-header::after {\n        content: '';\n        position: absolute;\n        left: 0; right: 0; bottom: 0;\n        height: 3px;\n        background: repeating-linear-gradient(90deg, var(--qw-primary) 0px, var(--qw-primary) 8px, transparent 8px, transparent 12px);\n    }\n    .qw-header-top { display: flex; align-items: center; gap: 14px; }\n    .qw-header-icon { width: 36px; height: 36px; flex-shrink: 0; }\n    .qw-box-title { font-size: 1.15rem; color: #fff; font-weight: 700; margin: 0; letter-spacing: -0.01em; }\n    .qw-box-desc { font-size: 0.85rem; color: rgba(255,255,255,0.68); margin: 6px 0 0; line-height: 1.55; }\n\n    .qw-body { padding: 22px 28px 24px; }\n    .qw-privacy {\n        background: #f0fdf4;\n        border: 1px solid #bbf7d0;\n        border-radius: 3px;\n        padding: 9px 14px;\n        margin-bottom: 16px;\n        font-size: 0.8rem;\n        color: var(--qw-good-deep);\n        line-height: 1.5;\n        display: flex;\n        align-items: center;\n        gap: 8px;\n    }\n    .qw-privacy::before { content: '\\1F512'; flex-shrink: 0; font-size: 0.9rem; }\n    .qw-intro {\n        background: #f0f5fa;\n        border-left: 3px solid var(--qw-primary);\n        border-radius: 0 4px 4px 0;\n        padding: 11px 15px;\n        margin-bottom: 16px;\n        font-size: 0.86rem;\n        color: var(--qw-text);\n    }\n    .qw-intro strong { color: var(--qw-ink); }\n\n    .qw-focus-label {\n        font-size: 0.66rem;\n        font-weight: 800;\n        text-transform: uppercase;\n        letter-spacing: 0.1em;\n        color: var(--qw-muted);\n        margin-bottom: 6px;\n    }\n    .qw-focus { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }\n    .qw-box .qw-focus-btn {\n        -webkit-appearance: none !important;\n        appearance: none !important;\n        border: 1px solid var(--qw-border) !important;\n        border-radius: 3px !important;\n        background: #fff !important;\n        color: var(--qw-text) !important;\n        min-height: 36px !important;\n        padding: 7px 13px !important;\n        font: inherit !important;\n        font-size: 0.78rem !important;\n        font-weight: 800 !important;\n        cursor: pointer !important;\n        box-shadow: none !important;\n        text-transform: none !important;\n        transition: background-color 0.15s, border-color 0.15s, color 0.15s, transform 0.12s;\n    }\n    .qw-box .qw-focus-btn:hover { border-color: var(--qw-primary) !important; color: var(--qw-primary) !important; background: #fff !important; transform: translateY(-1px); }\n    .qw-box .qw-focus-btn:active { transform: translateY(1px); }\n    .qw-box .qw-focus-btn:focus-visible { outline: 2px solid var(--qw-primary) !important; outline-offset: 2px !important; border-color: var(--qw-primary) !important; color: var(--qw-primary) !important; }\n    .qw-box .qw-focus-btn.is-active { background: var(--qw-primary) !important; border-color: var(--qw-primary) !important; color: #fff !important; }\n    .qw-box .qw-focus-btn:disabled { opacity: 0.5 !important; cursor: not-allowed !important; }\n\n    .qw-topic { display: none; }\n    .qw-topic.is-active { display: block; }\n    .qw-topic-title {\n        font-size: 0.72rem;\n        font-weight: 800;\n        color: var(--qw-primary);\n        text-transform: uppercase;\n        letter-spacing: 0.08em;\n        margin: 0 0 9px;\n    }\n    .qw-stage-panel {\n        display: grid;\n        grid-template-columns: minmax(0, 1fr);\n        gap: 12px;\n        align-items: start;\n        margin-bottom: 14px;\n    }\n    .qw-svg-wrap, .qw-controls, .qw-verdict {\n        border: 1px solid var(--qw-border);\n        border-radius: 4px;\n        background: #fff;\n    }\n    .qw-svg-wrap { order: 2; padding: 12px 14px 10px; }\n    .qw-svg-wrap svg { width: 100%; height: auto; display: block; font-family: inherit; user-select: none; }\n    .qw-controls {\n        order: 1;\n        background: var(--qw-surface);\n        padding: 14px 16px 16px;\n        display: grid;\n        grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));\n        gap: 14px 16px;\n        align-items: start;\n    }\n    .qw-section-label {\n        font-size: 0.66rem;\n        font-weight: 800;\n        text-transform: uppercase;\n        letter-spacing: 0.1em;\n        color: var(--qw-muted);\n        margin: 0 0 8px;\n    }\n    .qw-control-block { min-width: 0; }\n    .qw-field { margin-bottom: 12px; padding-left: 9px; border-left: 3px solid var(--qw-border); }\n    .qw-field:last-child { margin-bottom: 0; }\n    .qw-field-label { display: flex; justify-content: space-between; gap: 8px; font-size: 0.76rem; font-weight: 800; color: var(--qw-ink); margin-bottom: 4px; }\n    .qw-field-unit { color: var(--qw-muted); font-size: 0.74rem; font-weight: 700; font-variant-numeric: tabular-nums; }\n\n    .qw-box .qw-range {\n        -webkit-appearance: none !important;\n        -moz-appearance: none !important;\n        appearance: none !important;\n        width: 100% !important;\n        height: 6px !important;\n        padding: 0 !important;\n        margin: 8px 0 2px !important;\n        background: #dbe4ec !important;\n        border: 0 !important;\n        border-radius: 3px !important;\n        outline: none !important;\n        box-shadow: none !important;\n        box-sizing: border-box !important;\n        accent-color: var(--qw-primary);\n    }\n    .qw-box .qw-range::-webkit-slider-runnable-track {\n        -webkit-appearance: none !important;\n        appearance: none !important;\n        height: 6px !important;\n        background: transparent !important;\n        border: 0 !important;\n        box-shadow: none !important;\n    }\n    .qw-box .qw-range::-webkit-slider-thumb {\n        -webkit-appearance: none !important;\n        appearance: none !important;\n        width: 18px !important;\n        height: 18px !important;\n        border-radius: 50% !important;\n        background: var(--qw-primary) !important;\n        border: 2px solid #fff !important;\n        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2) !important;\n        margin-top: -6px !important;\n        cursor: pointer !important;\n    }\n    .qw-box .qw-range::-moz-range-track {\n        height: 6px !important;\n        background: transparent !important;\n        border: 0 !important;\n        box-shadow: none !important;\n    }\n    .qw-box .qw-range::-moz-range-thumb {\n        -moz-appearance: none !important;\n        appearance: none !important;\n        width: 18px !important;\n        height: 18px !important;\n        border-radius: 50% !important;\n        background: var(--qw-primary) !important;\n        border: 2px solid #fff !important;\n        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2) !important;\n        cursor: pointer !important;\n    }\n    .qw-box .qw-range::-moz-focus-outer { border: 0 !important; }\n    .qw-box .qw-range:focus-visible { outline: 2px solid var(--qw-primary) !important; outline-offset: 4px !important; border-radius: 3px !important; }\n    .qw-box .qw-range:disabled { opacity: 0.42 !important; cursor: not-allowed !important; }\n    .qw-box .qw-range:disabled::-webkit-slider-thumb { background: #aab8c2 !important; }\n    .qw-box .qw-range:disabled::-moz-range-thumb { background: #aab8c2 !important; }\n\n    .qw-box .qw-btn {\n        -webkit-appearance: none !important;\n        appearance: none !important;\n        font-family: inherit !important;\n        font-size: 0.78rem !important;\n        font-weight: 800 !important;\n        line-height: 1.2 !important;\n        color: #fff !important;\n        background: var(--qw-primary) !important;\n        border: 1px solid var(--qw-primary) !important;\n        border-radius: 3px !important;\n        min-height: 36px !important;\n        padding: 7px 13px !important;\n        cursor: pointer !important;\n        box-shadow: none !important;\n        text-transform: none !important;\n        white-space: nowrap !important;\n        transition: background-color 0.15s, border-color 0.15s, color 0.15s;\n    }\n    .qw-box .qw-btn:hover { background: var(--qw-primary-dark) !important; border-color: var(--qw-primary-dark) !important; color: #fff !important; }\n    .qw-box .qw-btn:active { background: var(--qw-primary-deep) !important; }\n    .qw-box .qw-btn:focus-visible { outline: 2px solid var(--qw-primary) !important; outline-offset: 2px !important; }\n    .qw-box .qw-btn:disabled { background: #aab8c2 !important; border-color: #aab8c2 !important; cursor: not-allowed !important; }\n    .qw-box .qw-btn.is-ghost { background: #fff !important; color: var(--qw-primary) !important; }\n    .qw-box .qw-btn.is-ghost:hover { background: #eef4f8 !important; color: var(--qw-primary-dark) !important; }\n    .qw-box .qw-btn.is-ghost.is-active { background: var(--qw-primary) !important; color: #fff !important; border-color: var(--qw-primary) !important; }\n    .qw-box .qw-btn.is-ghost:focus-visible { outline: 2px solid var(--qw-primary) !important; outline-offset: 2px !important; }\n\n    .qw-part-row { display: flex; flex-wrap: wrap; gap: 6px; }\n    .qw-box .qw-part-btn {\n        -webkit-appearance: none !important;\n        appearance: none !important;\n        border: 1px solid var(--qw-border) !important;\n        border-radius: 3px !important;\n        background: #fff !important;\n        color: var(--qw-text) !important;\n        min-height: 34px !important;\n        padding: 6px 11px !important;\n        font: inherit !important;\n        font-size: 0.75rem !important;\n        font-weight: 800 !important;\n        cursor: pointer !important;\n        box-shadow: none !important;\n        text-transform: none !important;\n        transition: background-color 0.15s, border-color 0.15s, color 0.15s;\n    }\n    .qw-box .qw-part-btn:hover { border-color: var(--qw-primary) !important; color: var(--qw-primary) !important; }\n    .qw-box .qw-part-btn:active { background: #e2ecf2 !important; }\n    .qw-box .qw-part-btn:focus-visible { outline: 2px solid var(--qw-primary) !important; outline-offset: 2px !important; }\n    .qw-box .qw-part-btn.is-active { background: var(--qw-primary) !important; border-color: var(--qw-primary) !important; color: #fff !important; }\n\n    .qw-seg { display: inline-flex; flex-wrap: wrap; border: 1px solid var(--qw-border); border-radius: 3px; overflow: hidden; background: #fff; }\n    .qw-box .qw-seg button {\n        -webkit-appearance: none !important;\n        appearance: none !important;\n        font-family: inherit !important;\n        font-size: 0.73rem !important;\n        font-weight: 800 !important;\n        line-height: 1.2 !important;\n        color: var(--qw-text) !important;\n        background: #fff !important;\n        border: none !important;\n        border-radius: 0 !important;\n        min-height: 34px !important;\n        padding: 6px 12px !important;\n        cursor: pointer !important;\n        box-shadow: none !important;\n        text-transform: none !important;\n        transition: background-color 0.15s, color 0.15s;\n    }\n    .qw-box .qw-seg button + button { border-left: 1px solid var(--qw-border) !important; }\n    .qw-box .qw-seg button.is-active { background: var(--qw-primary) !important; color: #fff !important; }\n    .qw-box .qw-seg button:hover:not(.is-active) { background: #edf4f8 !important; color: var(--qw-primary) !important; }\n    .qw-box .qw-seg button:active { background: #e2ecf2 !important; }\n    .qw-box .qw-seg button:focus-visible { outline: 2px solid var(--qw-primary) !important; outline-offset: -2px !important; }\n    .qw-box .qw-seg button:disabled { opacity: 0.5 !important; cursor: not-allowed !important; }\n\n    .qw-mini-hint { font-size: 0.74rem; color: var(--qw-muted); line-height: 1.45; margin-top: 8px; }\n\n    .qw-verdict { padding: 12px 16px; margin-bottom: 14px; }\n    .qw-verdict.is-live { background: #fff; border-left: 3px solid var(--qw-primary); border-radius: 0 4px 4px 0; }\n    .qw-verdict-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }\n    .qw-verdict-title {\n        font-size: 0.66rem;\n        font-weight: 800;\n        text-transform: uppercase;\n        letter-spacing: 0.1em;\n        color: var(--qw-muted);\n    }\n    .qw-chip {\n        display: inline-flex;\n        align-items: center;\n        min-height: 22px;\n        padding: 2px 10px;\n        border-radius: 999px;\n        font-size: 0.72rem;\n        font-weight: 800;\n        background: #edf4f8;\n        border: 1px solid #cfe0ea;\n        color: var(--qw-primary-deep);\n        font-variant-numeric: tabular-nums;\n    }\n    .qw-chip.is-good { background: #f0fdf4; border-color: #bbf7d0; color: var(--qw-good-deep); }\n    .qw-chip.is-warn { background: #fffbeb; border-color: #f4cf81; color: var(--qw-warn-deep); }\n    .qw-chip.is-error { background: #fef2f2; border-color: #fac5c5; color: var(--qw-error); }\n    .qw-chip.is-point { background: #f5f3ff; border-color: #ddd6fe; color: #6d28d9; }\n    .qw-chip.is-link { background: #ecfeff; border-color: #a5f3fc; color: #0e7490; }\n    .qw-chip.is-shape { background: #fdf3e7; border-color: #f4cf81; color: #b45309; }\n    .qw-verdict-text { font-size: 0.85rem; line-height: 1.6; color: var(--qw-text); margin: 0; }\n    .qw-verdict-text strong { color: var(--qw-ink); }\n\n    .qw-tile-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 7px; }\n    .qw-tile {\n        background: #fff;\n        border: 1px solid #dde7ee;\n        border-radius: 3px;\n        padding: 8px 9px;\n        min-width: 0;\n    }\n    .qw-tile-label {\n        display: block;\n        color: var(--qw-muted);\n        font-size: 0.62rem;\n        font-weight: 800;\n        text-transform: uppercase;\n        letter-spacing: 0.05em;\n    }\n    .qw-tile-value {\n        display: block;\n        color: var(--qw-ink);\n        font-size: 0.9rem;\n        font-weight: 800;\n        font-variant-numeric: tabular-nums;\n        margin-top: 2px;\n    }\n\n    .qw-legend {\n        display: flex;\n        flex-wrap: wrap;\n        gap: 9px 14px;\n        align-items: center;\n        margin-top: 9px;\n        padding-top: 9px;\n        border-top: 1px solid #edf2f7;\n        font-size: 0.73rem;\n        color: var(--qw-muted);\n    }\n    .qw-legend-item { display: inline-flex; align-items: center; gap: 5px; }\n    .qw-line-swatch { width: 20px; height: 0; border-top: 3px solid currentColor; border-radius: 999px; }\n    .qw-line-swatch.is-dash {\n        height: 2px;\n        border-top: 0;\n        background: repeating-linear-gradient(90deg, currentColor 0 6px, transparent 6px 10px);\n    }\n    .qw-dot-swatch { width: 10px; height: 10px; border-radius: 50%; border: 2px solid currentColor; background: #fff; }\n    .qw-area-swatch { width: 16px; height: 11px; border-radius: 2px; border: 1px solid rgba(0,0,0,0.12); }\n\n    .qw-merksatz {\n        background: #f0fdf4;\n        border: 1px solid #bbf7d0;\n        border-left: 3px solid var(--qw-good);\n        border-radius: 0 4px 4px 0;\n        padding: 12px 16px;\n        margin-top: 14px;\n        font-size: 0.9rem;\n        color: var(--qw-text);\n    }\n    .qw-merksatz strong { color: var(--qw-good-deep); }\n\n    \/* SVG-Praesentation: Farben hartkodiert (Safari versteht keine CSS-Variablen in SVG-Attributen) *\/\n    .qw-svg-label { fill: #64748b; font-size: 10px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; }\n\n    @media (max-width: 940px) {\n        .qw-stage-panel { grid-template-columns: 1fr; }\n    }\n    @media (max-width: 700px) {\n        .qw-header { padding: 16px 20px 14px; }\n        .qw-body { padding: 18px 18px 20px; }\n        .qw-tile-grid { grid-template-columns: 1fr; }\n    }\n    @media (max-width: 480px) {\n        .qw-focus { flex-direction: column; align-items: stretch; }\n        .qw-box .qw-focus-btn { text-align: left !important; }\n        .qw-seg { display: flex; flex-direction: column; }\n        .qw-box .qw-seg button + button { border-left: 0 !important; border-top: 1px solid var(--qw-border) !important; }\n    }\n    @media (prefers-reduced-motion: reduce) {\n        \/* !important noetig: Accessibility-Override muss beliebige Spezifitaeten der CSS-Box schlagen. *\/\n        .qw-box * { transition: none !important; animation: none !important; }\n    }\n<\/style>\n\n<div class=\"qw-box\" data-qw-root>\n    <div class=\"qw-header\">\n        <div class=\"qw-header-top\">\n            <svg class=\"qw-header-icon\" viewBox=\"0 0 36 36\" fill=\"none\" aria-hidden=\"true\">\n                <line x1=\"18\" y1=\"4\" x2=\"18\" y2=\"32\" stroke=\"rgba(255,255,255,0.5)\" stroke-width=\"1.3\" stroke-dasharray=\"2 2\"\/>\n                <circle cx=\"18\" cy=\"14\" r=\"2.2\" fill=\"none\" stroke=\"rgba(255,255,255,0.85)\" stroke-width=\"1.4\"\/>\n                <path d=\"M18 14 L27 18 L31 27\" stroke=\"rgba(255,255,255,0.92)\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/>\n                <path d=\"M18 14 L9 18 L5 27\" stroke=\"rgba(255,255,255,0.55)\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/>\n                <circle cx=\"27\" cy=\"18\" r=\"1.6\" fill=\"rgba(255,255,255,0.92)\"\/>\n                <circle cx=\"9\" cy=\"18\" r=\"1.6\" fill=\"rgba(255,255,255,0.55)\"\/>\n            <\/svg>\n            <div>\n                <h2 class=\"qw-box-title\">Querschnitt-Werkstatt<\/h2>\n                <div class=\"qw-box-desc\">Die Codes eines Querschnitts und ihre Wirkung im Profilk&ouml;rper sichtbar machen und die DGM-Anbindung mit und ohne Ziel durchspielen &ndash; alles an einem Querschnitt.<\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <div class=\"qw-body\">\n        <div class=\"qw-privacy\">L&auml;uft komplett im Browser. Keine Daten verlassen deinen Rechner.<\/div>\n\n        <div class=\"qw-intro\">\n            Der <strong>Querschnitt (Assembly)<\/strong> ist die Eingabe f&uuml;r den Profilk&ouml;rper. Der Kern dieses Werkzeugs ist der Modus <strong>Codes &amp; Wirkung<\/strong>: Er zeigt, warum du jeden Bestandteil codierst und was der Code sp&auml;ter im Profilk&ouml;rper (08) erzeugt. Der Modus <strong>Anbindung<\/strong> spielt daneben durch, wie eine B&ouml;schung mit und ohne Ziel-DGM ausl&auml;uft.\n        <\/div>\n\n        <div class=\"qw-focus-label\">Modus<\/div>\n        <div class=\"qw-focus\" id=\"qwFocus\" role=\"group\" aria-label=\"Modus w&auml;hlen\">\n            <button type=\"button\" class=\"qw-focus-btn is-active\" data-qw-topic=\"codes\">1 &middot; Codes &amp; Wirkung<\/button>\n            <button type=\"button\" class=\"qw-focus-btn\" data-qw-topic=\"anbindung\">2 &middot; Anbindung<\/button>\n        <\/div>\n\n        <!-- MODUS 1: Codes und Wirkung -->\n        <div class=\"qw-topic is-active\" id=\"qwTopicCodes\" data-topic=\"codes\">\n            <div class=\"qw-topic-title\">Codes einblenden und ihre Wirkung zeigen<\/div>\n            <div class=\"qw-verdict is-live\">\n                <div class=\"qw-verdict-head\">\n                    <span class=\"qw-verdict-title\">Befund<\/span>\n                    <span class=\"qw-chip\" id=\"qwChipCodes\" aria-hidden=\"true\">l&auml;dt<\/span>\n                <\/div>\n                <p class=\"qw-verdict-text\" id=\"qwTextCodes\" aria-live=\"polite\"><\/p>\n            <\/div>\n            <div class=\"qw-stage-panel\">\n                <div class=\"qw-svg-wrap\">\n                    <svg id=\"qwSvgCodes\" viewBox=\"0 0 620 372\" preserveAspectRatio=\"xMidYMid meet\" role=\"img\" aria-labelledby=\"qwCodesTitle\">\n                        <title id=\"qwCodesTitle\">Links der Querschnitt quer zur Achse mit Codes, rechts ihre Wirkung l&auml;ngs entlang der Trasse<\/title>\n                        <g id=\"qwCodesDraw\"><\/g>\n                    <\/svg>\n                    <div class=\"qw-legend\">\n                        <span class=\"qw-legend-item\" style=\"color:#7c3aed;\"><span class=\"qw-dot-swatch\"><\/span> Punktcode<\/span>\n                        <span class=\"qw-legend-item\" style=\"color:#0891b2;\"><span class=\"qw-line-swatch\"><\/span> Verkn&uuml;pfungscode<\/span>\n                        <span class=\"qw-legend-item\"><span class=\"qw-area-swatch\" style=\"background:#f6dcc0;border-color:#e8913a;\"><\/span> Profilartcode<\/span>\n                        <span class=\"qw-legend-item\" style=\"color:#64748b;\"><span class=\"qw-line-swatch is-dash\"><\/span> l&auml;ngs (Trasse)<\/span>\n                    <\/div>\n                <\/div>\n                <div class=\"qw-controls\">\n                    <div class=\"qw-control-block\">\n                        <div class=\"qw-section-label\">Codeart einblenden<\/div>\n                        <span class=\"qw-seg\" id=\"qwCodeart\" role=\"group\" aria-label=\"Codeart w&auml;hlen\">\n                            <button type=\"button\" data-qw-codeart=\"punkt\" class=\"is-active\">Punktcode<\/button>\n                            <button type=\"button\" data-qw-codeart=\"verknuepfung\">Verkn&uuml;pfung<\/button>\n                            <button type=\"button\" data-qw-codeart=\"profilart\">Profilart<\/button>\n                            <button type=\"button\" data-qw-codeart=\"alle\">Alle<\/button>\n                        <\/span>\n                        <div style=\"margin-top:12px;\">\n                            <button type=\"button\" class=\"qw-btn is-ghost\" id=\"qwAusz\" data-qw-toggle=\"auszahlung\" aria-pressed=\"false\">Wirkung im Profilk&ouml;rper: aus<\/button>\n                        <\/div>\n                        <div class=\"qw-field\" style=\"margin-top:14px;\">\n                            <label class=\"qw-field-label\" for=\"qwStationen\">Stationen l&auml;ngs <span class=\"qw-field-unit\" id=\"qwStationenText\">3<\/span><\/label>\n                            <input class=\"qw-range\" id=\"qwStationen\" type=\"range\" min=\"2\" max=\"5\" step=\"1\" value=\"3\">\n                        <\/div>\n                    <\/div>\n                    <div class=\"qw-control-block\">\n                        <div class=\"qw-section-label\">Was der Code erzeugt<\/div>\n                        <div class=\"qw-tile-grid\">\n                            <div class=\"qw-tile\"><span class=\"qw-tile-label\">Sitzt an<\/span><span class=\"qw-tile-value\" id=\"qwCodeSitz\">&#8211;<\/span><\/div>\n                            <div class=\"qw-tile\"><span class=\"qw-tile-label\">Wird zu<\/span><span class=\"qw-tile-value\" id=\"qwCodeZiel\">&#8211;<\/span><\/div>\n                            <div class=\"qw-tile\"><span class=\"qw-tile-label\">Nutzen<\/span><span class=\"qw-tile-value\" id=\"qwCodeNutz\">&#8211;<\/span><\/div>\n                        <\/div>\n                        <div class=\"qw-mini-hint\">Der Querschnitt steht quer zur Achse (links). Im Profilk&ouml;rper wird er an vielen Stationen l&auml;ngs eingebaut (rechts) &ndash; erst dort zeigen die Codes ihre Wirkung.<\/div>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <!-- MODUS 3: Anbindung -->\n        <div class=\"qw-topic\" id=\"qwTopicAnbindung\" data-topic=\"anbindung\">\n            <div class=\"qw-topic-title\">B&ouml;schung ans DGM anbinden &ndash; mit und ohne Ziel<\/div>\n            <div class=\"qw-verdict is-live\">\n                <div class=\"qw-verdict-head\">\n                    <span class=\"qw-verdict-title\">Befund<\/span>\n                    <span class=\"qw-chip\" id=\"qwChipAnb\" aria-hidden=\"true\">l&auml;dt<\/span>\n                <\/div>\n                <p class=\"qw-verdict-text\" id=\"qwTextAnb\" aria-live=\"polite\"><\/p>\n            <\/div>\n            <div class=\"qw-stage-panel\">\n                <div class=\"qw-svg-wrap\">\n                    <svg id=\"qwSvgAnb\" viewBox=\"0 0 620 356\" preserveAspectRatio=\"xMidYMid meet\" role=\"img\" aria-labelledby=\"qwAnbTitle\">\n                        <title id=\"qwAnbTitle\">B&ouml;schungsbestandteil, der nur mit zugewiesenem Ziel-DGM anbindet<\/title>\n                        <g id=\"qwAnbDraw\"><\/g>\n                    <\/svg>\n                    <div class=\"qw-legend\">\n                        <span class=\"qw-legend-item\" style=\"color:#059669;\"><span class=\"qw-line-swatch\"><\/span> Planungskante<\/span>\n                        <span class=\"qw-legend-item\" style=\"color:#e8913a;\"><span class=\"qw-line-swatch\"><\/span> B&ouml;schung<\/span>\n                        <span class=\"qw-legend-item\" style=\"color:#3f5f75;\"><span class=\"qw-line-swatch\"><\/span> Ziel-DGM<\/span>\n                        <span class=\"qw-legend-item\" style=\"color:#dc2626;\"><span class=\"qw-line-swatch is-dash\"><\/span> kein Anschluss<\/span>\n                    <\/div>\n                <\/div>\n                <div class=\"qw-controls\">\n                    <div class=\"qw-control-block\">\n                        <div class=\"qw-section-label\">Ziel-DGM<\/div>\n                        <span class=\"qw-seg\" id=\"qwZiel\" role=\"group\" aria-label=\"Ziel zuweisen\">\n                            <button type=\"button\" data-qw-ziel=\"ohne\" class=\"is-active\">ohne Ziel<\/button>\n                            <button type=\"button\" data-qw-ziel=\"mit\">mit Ziel<\/button>\n                        <\/span>\n                        <div class=\"qw-field\" style=\"margin-top:14px;\">\n                            <label class=\"qw-field-label\" for=\"qwAnbNeig\">B&ouml;schungsneigung (H:V) <span class=\"qw-field-unit\" id=\"qwAnbNeigText\">2:1<\/span><\/label>\n                            <input class=\"qw-range\" id=\"qwAnbNeig\" type=\"range\" min=\"1\" max=\"4\" step=\"0.1\" value=\"2\">\n                        <\/div>\n                        <div class=\"qw-field\">\n                            <label class=\"qw-field-label\" for=\"qwAnbTiefe\">H&ouml;he zum Gel&auml;nde <span class=\"qw-field-unit\" id=\"qwAnbTiefeText\">2,0 m<\/span><\/label>\n                            <input class=\"qw-range\" id=\"qwAnbTiefe\" type=\"range\" min=\"0.5\" max=\"4\" step=\"0.1\" value=\"2\">\n                        <\/div>\n                    <\/div>\n                    <div class=\"qw-control-block\">\n                        <div class=\"qw-section-label\">Ergebnis<\/div>\n                        <div class=\"qw-tile-grid\">\n                            <div class=\"qw-tile\"><span class=\"qw-tile-label\">Status<\/span><span class=\"qw-tile-value\" id=\"qwAnbStatus\">&#8211;<\/span><\/div>\n                            <div class=\"qw-tile\"><span class=\"qw-tile-label\">Reichweite<\/span><span class=\"qw-tile-value\" id=\"qwAnbReach\">&#8211;<\/span><\/div>\n                            <div class=\"qw-tile\"><span class=\"qw-tile-label\">Neigung<\/span><span class=\"qw-tile-value\" id=\"qwAnbRatio\">&#8211;<\/span><\/div>\n                        <\/div>\n                        <div class=\"qw-mini-hint\">Das Ziel-DGM wird erst im Profilk&ouml;rper (08) zugewiesen. Im Querschnitt legst du nur den B&ouml;schungs-Bestandteil samt Ziel-Parameter an &ndash; er allein bindet noch nicht an.<\/div>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n\n    <\/div>\n<\/div>\n\n<script>\n    (function () {\n        \"use strict\";\n        var ROOT = document.querySelector(\"[data-qw-root]\");\n        if (!ROOT) { return; }\n\n        \/\/ Farbpalette als JS-Konstanten. Safari versteht keine CSS-Variablen in\n        \/\/ SVG-Attributwerten, deshalb hier hartkodierte Hex-Werte.\n        var COLORS = {\n            primary: \"#3f5f75\",\n            primaryDark: \"#2c4a5e\",\n            primaryDeep: \"#1e3548\",\n            ink: \"#1e293b\",\n            muted: \"#64748b\",\n            faint: \"#94a3b8\",\n            border: \"#d9e4ec\",\n            surface: \"#f4f7fa\",\n            ground: \"#3f5f75\",\n            groundFill: \"#eef2f5\",\n            plan: \"#059669\",\n            planDeep: \"#15803d\",\n            slope: \"#e8913a\",\n            slopeDeep: \"#b45309\",\n            error: \"#dc2626\",\n            warnDeep: \"#92700c\",\n            warnBg: \"#fffbeb\",\n            warnBorder: \"#f4cf81\",\n            codePoint: \"#7c3aed\",   \/\/ Punktcode violett\n            codePointDeep: \"#6d28d9\",\n            codeLink: \"#0891b2\",    \/\/ Verknuepfungscode cyan\n            codeLinkDeep: \"#0e7490\",\n            codeShape: \"#e8913a\",   \/\/ Profilartcode gold\n            shapeFill: \"#f6dcc0\",\n            paveFill: \"#e5edf3\",\n            linkFill: \"#d6f0f6\",\n            \/\/ Materialtoene fuer die realistische Querschnittsdarstellung:\n            \/\/ gedeckt gehalten, damit die Code-Farben (violett\/cyan\/gold) als\n            \/\/ Hervorhebung darueber lesbar bleiben\n            asphalt: \"#5d6a74\",\n            asphaltEdge: \"#46525c\",\n            gravel: \"#c9c2b2\",\n            gravelEdge: \"#a89f8c\",\n            frostFill: \"#ddd6c6\",\n            frostEdge: \"#c2b8a3\",\n            beton: \"#dfe4e8\",\n            betonEdge: \"#a9b8c2\",\n            earth: \"#ece5d8\",\n            earthEdge: \"#d4c9b4\",\n            groundTick: \"#c3cfd8\"\n        };\n\n        var SVGNS = \"http:\/\/www.w3.org\/2000\/svg\";\n        function $(id) { return ROOT.querySelector(\"#\" + id); }\n        function el(tag, attrs) {\n            var n = document.createElementNS(SVGNS, tag);\n            Object.keys(attrs || {}).forEach(function (k) { n.setAttribute(k, attrs[k]); });\n            return n;\n        }\n        function clear(node) { while (node.firstChild) { node.removeChild(node.firstChild); } }\n        function fmt(v, d) {\n            var digits = typeof d === \"number\" ? d : 2;\n            return (isFinite(v) ? v : 0).toLocaleString(\"de-DE\", { minimumFractionDigits: digits, maximumFractionDigits: digits });\n        }\n        function ratStr(nv) {\n            \/\/ Civil-3D-Parameter-Schreibweise H:V (\"n:1\"), konsistent mit T02 und Finder\n            var whole = Math.abs(nv - Math.round(nv)) < 0.05;\n            return fmt(nv, whole ? 0 : 1) + \":1\";\n        }\n        function ptStr(points) {\n            return points.map(function (p) { return p.x.toFixed(1) + \",\" + p.y.toFixed(1); }).join(\" \");\n        }\n        function poly(group, pts, attrs) {\n            group.appendChild(el(\"polyline\", Object.assign({ points: ptStr(pts) }, attrs || {})));\n        }\n        function line(group, x1, y1, x2, y2, attrs) {\n            group.appendChild(el(\"line\", Object.assign({ x1: x1, y1: y1, x2: x2, y2: y2 }, attrs || {})));\n        }\n        function text(group, x, y, content, attrs) {\n            \/\/ Safari erbt font-family im SVG nicht zuverlaessig, deshalb explizit.\n            var base = { x: x, y: y, \"font-family\": \"inherit\" };\n            var t = el(\"text\", Object.assign(base, attrs || {}));\n            t.textContent = content;\n            group.appendChild(t);\n            return t;\n        }\n        function rect(group, x, y, w, h, attrs) {\n            group.appendChild(el(\"rect\", Object.assign({ x: x, y: y, width: w, height: h }, attrs || {})));\n        }\n        function circle(group, x, y, r, attrs) {\n            group.appendChild(el(\"circle\", Object.assign({ cx: x, cy: y, r: r }, attrs || {})));\n        }\n        function card(group, x, y, w, h, title) {\n            rect(group, x, y, w, h, { fill: \"#fff\", stroke: \"#d9e4ec\", \"stroke-width\": 1.2, rx: 4 });\n            if (title) { text(group, x + 14, y + 22, title, { class: \"qw-svg-label\" }); }\n        }\n        function labelBox(group, x, y, label, opts) {\n            opts = opts || {};\n            var fs = opts.size || 9.5;\n            var pad = opts.pad || 6;\n            var w = opts.width || Math.max(30, label.length * fs * 0.6 + pad * 2);\n            var h = opts.height || 17;\n            rect(group, x - w \/ 2, y - h + 3, w, h, { fill: opts.fill || \"#fff\", stroke: opts.stroke || \"#d9e4ec\", \"stroke-width\": 1, rx: 3 });\n            text(group, x, y - 3, label, {\n                \"font-size\": fs,\n                fill: opts.color || \"#1e293b\",\n                \"text-anchor\": \"middle\",\n                \"font-weight\": opts.weight || 800\n            });\n        }\n        function dotMark(group, x, y, color, r) {\n            circle(group, x, y, r || 5, { fill: \"#fff\", stroke: color, \"stroke-width\": 2.4 });\n        }\n        function leader(group, ax, ay, lx, ly, color) {\n            line(group, ax, ay, lx, ly, { stroke: color, \"stroke-width\": 1, \"stroke-dasharray\": \"3 3\", opacity: 0.7 });\n        }\n        function syncSeg(containerId, attr, value) {\n            ROOT.querySelectorAll(\"#\" + containerId + \" button\").forEach(function (b) {\n                b.classList.toggle(\"is-active\", b.getAttribute(attr) === value);\n            });\n        }\n\n        var VERDICT = {\n            codes: { chip: \"qwChipCodes\", text: \"qwTextCodes\" },\n            anbindung: { chip: \"qwChipAnb\", text: \"qwTextAnb\" }\n        };\n        function setVerdict(kind, chip, html) {\n            var t = VERDICT[state.topic];\n            if (!t) { return; }\n            var c = $(t.chip);\n            c.className = \"qw-chip\" + (kind ? \" \" + kind : \"\");\n            c.textContent = chip;\n            $(t.text).innerHTML = html;\n        }\n\n        var state = {\n            topic: \"codes\",\n            codeart: \"punkt\",\n            auszahlung: false,\n            stationen: 3,\n            ziel: \"ohne\",\n            anbNeig: 2.0,\n            anbTiefe: 2.0\n        };\n\n        \/\/ ============ MODUS 1: CODES UND WIRKUNG ============\n        \/\/ Realer halber Strassenquerschnitt von der Achse bis zum Boeschungsfuss.\n        \/\/ Lokale Einheiten, y nach unten; Querneigung didaktisch leicht ueberhoeht.\n        var LP = {\n            crown:    { x: 0,   y: 0,   code: \"Crown\", de: \"Kronenpunkt\" },\n            etw:      { x: 100, y: 8,   code: \"ETW\", de: \"Fahrbahnrand\" },\n            rinne:    { x: 112, y: 10,  code: \"Flowline\", de: \"Rinne\" },\n            topcurb:  { x: 114, y: -8,  code: \"Top_Curb\", de: \"Bordoberkante\" },\n            backcurb: { x: 128, y: -9,  code: \"Back_Curb\", de: \"Bordr\u00fcckkante\" },\n            sidewalk: { x: 188, y: -13, code: \"Sidewalk\", de: \"Gehwegkante\" },\n            daylight: { x: 252, y: 58,  code: \"Daylight\", de: \"B\u00f6schungsfu\u00df\" }\n        };\n        var TOPCHAIN = [\"crown\", \"etw\", \"rinne\", \"topcurb\", \"backcurb\", \"sidewalk\", \"daylight\"];\n        \/\/ Planum (Datum-Verknuepfung): untere Begrenzung des Frostschutzes\n        var LD1 = { x: 0, y: 34 }, LD2 = { x: 120, y: 41 };\n\n        \/\/ Urgelaende unter dem Damm: leichte Welle, am Boeschungsfuss verankert\n        function groundLocalZ(x) { return 58 + 2.2 * Math.sin(x * 0.021 + 1.15); }\n        LP.daylight.y = groundLocalZ(LP.daylight.x);\n\n        function sp(p, o) { return { x: o.ox + p.x * o.s, y: o.oy + p.y * o.s }; }\n        function topChainPts(o) { return TOPCHAIN.map(function (k) { return sp(LP[k], o); }); }\n\n        function sectionShapes(o) {\n            function P(x, y) { return sp({ x: x, y: y }, o); }\n            var c = LP.crown, e = LP.etw, r = LP.rinne;\n            return {\n                \/\/ Fahrbahnaufbau: Belag \/ Tragschicht \/ Frostschutz, unter der Rinne endend\n                belag: [P(c.x, c.y), P(e.x, e.y), P(r.x, r.y), P(r.x, r.y + 7), P(e.x, e.y + 7), P(c.x, c.y + 8)],\n                trag:  [P(c.x, c.y + 8), P(e.x, e.y + 7), P(r.x, r.y + 7), P(r.x, r.y + 16), P(e.x, e.y + 16), P(c.x, c.y + 18)],\n                frost: [P(c.x, c.y + 18), P(e.x, e.y + 16), P(r.x, r.y + 16), sp(LD2, o), sp(LD1, o)],\n                \/\/ Hochbord als Betonkoerper mit Fundament, Gehwegplatte zur Strasse geneigt\n                bord: [P(112, 10), P(114, -8), P(128, -9), P(128, 18), P(112, 18)],\n                gehweg: [P(128, -9), P(188, -13), P(188, -5), P(128, -1)]\n            };\n        }\n\n        function drawSectionBase(g, o, emphasis) {\n            var pointOn = emphasis === \"punkt\" ? true : (emphasis === \"alle\");\n            var linkOn = emphasis === \"verknuepfung\" ? true : (emphasis === \"alle\");\n            var shapeOn = emphasis === \"profilart\" ? true : (emphasis === \"alle\");\n            var S = sectionShapes(o);\n            var x, i;\n\n            \/\/ Bodenkoerper: Band unter dem Urgelaende plus Erdschraffur-Ticks\n            var band = [];\n            for (x = -26; x <= 292.1; x += 6) { band.push(sp({ x: x, y: groundLocalZ(x) }, o)); }\n            var bandPoly = band.slice();\n            for (i = band.length - 1; i >= 0; i -= 1) { bandPoly.push({ x: band[i].x, y: band[i].y + 24 * o.s }); }\n            poly(g, bandPoly, { fill: \"#eef2f5\", stroke: \"none\" });\n            for (i = 1; i < band.length; i += 2) {\n                line(g, band[i].x, band[i].y + 2.5, band[i].x - 6 * o.s, band[i].y + 2.5 + 8 * o.s, { stroke: COLORS.groundTick, \"stroke-width\": 1 });\n            }\n\n            \/\/ Erdkoerper: alles unter der fertigen Oberflaeche bis zum Urgelaende.\n            \/\/ Die Materialschichten werden anschliessend deckend darueber gezeichnet,\n            \/\/ so bleibt keine Luecke zwischen Fuellung und Linien.\n            var dam = topChainPts(o);\n            for (x = LP.daylight.x; x >= -0.1; x -= 6) { dam.push(sp({ x: x, y: groundLocalZ(x) }, o)); }\n            poly(g, dam, { fill: COLORS.earth, stroke: \"none\" });\n            \/\/ Sparsame Diagonalschraffur im Damm (Erdbau-Signatur), per clipPath begrenzt\n            var cp = el(\"clipPath\", { id: \"qwDamClip\" });\n            cp.appendChild(el(\"polygon\", { points: ptStr(dam) }));\n            g.appendChild(cp);\n            var hg = el(\"g\", { \"clip-path\": \"url(#qwDamClip)\" });\n            g.appendChild(hg);\n            var hxx;\n            for (hxx = -20; hxx < 280; hxx += 26) {\n                var h1 = sp({ x: hxx, y: 72 }, o), h2 = sp({ x: hxx + 72, y: -18 }, o);\n                line(hg, h1.x, h1.y, h2.x, h2.y, { stroke: COLORS.earthEdge, \"stroke-width\": 0.8, opacity: 0.5 });\n            }\n\n            \/\/ Urgelaende: unter dem Damm gestrichelt (ueberschuettet), rechts durchgezogen\n            var gIn = [], gOut = [];\n            for (x = -26; x <= LP.daylight.x + 0.1; x += 6) { gIn.push(sp({ x: x, y: groundLocalZ(x) }, o)); }\n            for (x = LP.daylight.x; x <= 292.1; x += 6) { gOut.push(sp({ x: x, y: groundLocalZ(x) }, o)); }\n            poly(g, gIn, { fill: \"none\", stroke: COLORS.faint, \"stroke-width\": 1.3, \"stroke-dasharray\": \"5 4\", \"stroke-linejoin\": \"round\" });\n            poly(g, gOut, { fill: \"none\", stroke: COLORS.ground, \"stroke-width\": 2.2, \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\" });\n\n            \/\/ Materialkoerper in gedeckten Realtoenen. Fokusregel: Profilart hebt NUR den\n            \/\/ Belag hervor (klare Umfaerbung in Gold), alle anderen Schichten bleiben neutral.\n            poly(g, S.frost.concat([S.frost[0]]), { fill: COLORS.frostFill, stroke: COLORS.frostEdge, \"stroke-width\": 1 });\n            poly(g, S.trag.concat([S.trag[0]]), { fill: COLORS.gravel, stroke: COLORS.gravelEdge, \"stroke-width\": 1 });\n            poly(g, S.belag.concat([S.belag[0]]), { fill: shapeOn ? COLORS.shapeFill : COLORS.asphalt, stroke: shapeOn ? COLORS.codeShape : COLORS.asphaltEdge, \"stroke-width\": shapeOn ? 1.8 : 1, \"stroke-linejoin\": \"round\" });\n            poly(g, S.bord.concat([S.bord[0]]), { fill: COLORS.beton, stroke: COLORS.betonEdge, \"stroke-width\": 1 });\n            poly(g, S.gehweg.concat([S.gehweg[0]]), { fill: COLORS.beton, stroke: COLORS.betonEdge, \"stroke-width\": 1 });\n\n            \/\/ Achse: Strichpunktlinie am Schnittrand (halber Querschnitt)\n            var axTop = sp({ x: 0, y: -30 }, o), axBot = sp({ x: 0, y: 86 }, o);\n            line(g, axTop.x, axTop.y, axBot.x, axBot.y, { stroke: COLORS.faint, \"stroke-width\": 1.1, \"stroke-dasharray\": \"11 4 2 4\" });\n            var axLbl = sp({ x: 0, y: 98 }, o);\n            text(g, axLbl.x, axLbl.y, \"Achse\", { \"font-size\": 8, fill: COLORS.faint, \"text-anchor\": \"middle\", \"font-weight\": 700 });\n\n            \/\/ Masskette: die Zonen des Querschnitts als Ingenieur-Signatur an der Basis\n            var MK = [\n                { a: 0, b: 112, t: \"Fahrbahn\" },\n                { a: 112, b: 128, t: \"Bord\" },\n                { a: 128, b: 188, t: \"Gehweg\" },\n                { a: 188, b: 252, t: \"B\u00f6schung\" }\n            ];\n            var mkY = sp({ x: 0, y: 114 }, o).y;\n            line(g, sp({ x: 0, y: 0 }, o).x, mkY, sp({ x: 252, y: 0 }, o).x, mkY, { stroke: COLORS.faint, \"stroke-width\": 1 });\n            MK.forEach(function (z) {\n                var za = sp({ x: z.a, y: 0 }, o).x, zb = sp({ x: z.b, y: 0 }, o).x;\n                line(g, za, mkY - 4, za, mkY + 4, { stroke: COLORS.faint, \"stroke-width\": 1 });\n                line(g, zb, mkY - 4, zb, mkY + 4, { stroke: COLORS.faint, \"stroke-width\": 1 });\n                if (z.t === \"Bord\") {\n                    line(g, (za + zb) \/ 2, mkY + 5, (za + zb) \/ 2, mkY + 20, { stroke: COLORS.faint, \"stroke-width\": 0.8, \"stroke-dasharray\": \"2 2\" });\n                    text(g, (za + zb) \/ 2, mkY + 29, z.t, { \"font-size\": 7.5, fill: COLORS.muted, \"text-anchor\": \"middle\", \"font-weight\": 700 });\n                } else {\n                    text(g, (za + zb) \/ 2, mkY + 13, z.t, { \"font-size\": 7.5, fill: COLORS.muted, \"text-anchor\": \"middle\", \"font-weight\": 700 });\n                }\n            });\n\n            \/\/ Verknuepfungen: die Top-Kette (fertige Oberflaeche)\n            var top = topChainPts(o);\n            poly(g, top, { fill: \"none\", stroke: linkOn ? COLORS.codeLink : COLORS.primaryDark, \"stroke-width\": linkOn ? 3.4 : 2.2, \"stroke-linejoin\": \"round\", \"stroke-linecap\": \"round\" });\n\n            \/\/ Punkte. Fokusregel: der Punktcode hebt NUR die Gehwegkante hervor,\n            \/\/ die uebrigen Punkte bleiben kleine neutrale Marker.\n            TOPCHAIN.forEach(function (k) {\n                var pt = sp(LP[k], o);\n                if (pointOn ? k === \"sidewalk\" : false) {\n                    circle(g, pt.x, pt.y, 4.6, { fill: \"#fff\", stroke: COLORS.codePoint, \"stroke-width\": 2.4 });\n                } else {\n                    circle(g, pt.x, pt.y, 2.2, { fill: \"#fff\", stroke: COLORS.muted, \"stroke-width\": 1.2, opacity: 0.55 });\n                }\n            });\n\n            return { top: top };\n        }\n\n        function ribOrigin(i, st) {\n            \/\/ Stationen von vorn (i=0) nach hinten, mit leichter Perspektivverkleinerung\n            var t = st <= 1 ? 0 : i \/ (st - 1);\n            return { ox: 346 + t * 116, oy: 314 - t * 118, s: 0.40 - t * 0.10, t: t };\n        }\n\n        function renderCodes() {\n            var g = $(\"qwCodesDraw\");\n            clear(g);\n            syncSeg(\"qwCodeart\", \"data-qw-codeart\", state.codeart);\n            var auszBtn = $(\"qwAusz\");\n            auszBtn.classList.toggle(\"is-active\", state.auszahlung);\n            auszBtn.setAttribute(\"aria-pressed\", state.auszahlung ? \"true\" : \"false\");\n            auszBtn.textContent = state.auszahlung ? \"Wirkung im Profilk\u00f6rper: an\" : \"Wirkung im Profilk\u00f6rper: aus\";\n            $(\"qwStationenText\").textContent = String(state.stationen);\n\n            card(g, 24, 16, 572, 340, \"\");\n            line(g, 332, 34, 332, 348, { stroke: \"#e2e9ef\", \"stroke-width\": 1.2, \"stroke-dasharray\": \"4 4\" });\n            text(g, 40, 34, \"QUERSCHNITT (QUER ZUR ACHSE)\", { \"font-size\": 9, fill: COLORS.muted, \"font-weight\": 800, \"letter-spacing\": \"0.05em\" });\n            text(g, 344, 34, \"ENTLANG DER TRASSE (L\u00c4NGS)\", { \"font-size\": 9, fill: COLORS.muted, \"font-weight\": 800, \"letter-spacing\": \"0.05em\" });\n\n            var mainO = { ox: 52, oy: 186, s: 0.95 };\n            drawSectionBase(g, mainO, state.codeart);\n\n            \/\/ Beschriftungshelfer in lokalen Querschnittskoordinaten\n            function LB(lx, ly, label, opts) {\n                var p = sp({ x: lx, y: ly }, mainO);\n                labelBox(g, p.x, p.y, label, opts);\n            }\n            function LEAD(k, lx, ly, color) {\n                var a = sp(LP[k], mainO), b = sp({ x: lx, y: ly }, mainO);\n                leader(g, a.x, a.y, b.x, b.y, color);\n            }\n            function LEADP(px2, py2, lx, ly, color) {\n                var a = sp({ x: px2, y: py2 }, mainO), b = sp({ x: lx, y: ly }, mainO);\n                leader(g, a.x, a.y, b.x, b.y, color);\n            }\n            var PSTYLE = { fill: \"#f5f3ff\", stroke: \"#ddd6fe\", color: COLORS.codePointDeep };\n            var LSTYLE = { fill: \"#ecfeff\", stroke: \"#a5f3fc\", color: COLORS.codeLinkDeep };\n            var SSTYLE = { fill: \"#fdf3e7\", stroke: \"#f4cf81\", color: COLORS.slopeDeep };\n\n            var bst = sp({ x: 266, y: groundLocalZ(266) + 16 }, mainO);\n            text(g, bst.x, bst.y, \"Bestand\", { \"font-size\": 8, fill: COLORS.ground, \"text-anchor\": \"middle\", \"font-weight\": 700 });\n\n            var ca = state.codeart;\n            var caLabel = ca === \"punkt\" ? \"Punktcode\" : (ca === \"verknuepfung\" ? \"Verkn\u00fcpfungscode\" : (ca === \"profilart\" ? \"Profilartcode\" : \"Alle Codearten\"));\n\n            \/\/ Code-Beschriftungen im Querschnitt (per Leader, kein Text auf Linie)\n            \/\/ Fokusregel: genau EIN beschriftetes Element pro Codeart\n            if (ca === \"punkt\") {\n                LEAD(\"sidewalk\", 218, -38, COLORS.codePoint);\n                LB(218, -38, \"Gehwegkante\", Object.assign({ size: 8.6 }, PSTYLE));\n            } else if (ca === \"verknuepfung\") {\n                LEADP(58, 4.6, 44, -30, COLORS.codeLink);\n                LB(44, -30, \"Oberfl\u00e4che\", Object.assign({ size: 8.6 }, LSTYLE));\n            } else if (ca === \"profilart\") {\n                LEADP(46, 6, 34, -30, COLORS.codeShape);\n                LB(34, -30, \"Belag\", Object.assign({ size: 8.6 }, SSTYLE));\n            } else {\n                LEAD(\"sidewalk\", 214, -38, COLORS.codePoint);\n                LB(214, -38, \"Punkt: Gehwegkante\", Object.assign({ size: 8.4 }, PSTYLE));\n                LEADP(58, 4.6, 52, -30, COLORS.codeLink);\n                LB(52, -30, \"Verkn.: Oberfl\u00e4che\", Object.assign({ size: 8.4 }, LSTYLE));\n                LEADP(46, 6, 92, 78, COLORS.codeShape);\n                LB(92, 78, \"Profilart: Belag\", Object.assign({ size: 8.4 }, SSTYLE));\n            }\n\n            var st = state.stationen;\n            var frontO = ribOrigin(0, st);\n            function chainOf(i2) { return topChainPts(ribOrigin(i2, st)); }\n            var pi, sj, ei, ej;\n\n            if (!state.auszahlung) {\n                \/\/ Geister-Vorschau: der Profilkoerper ist noch nicht gebaut (Drahtgitter)\n                for (ej = 0; ej < TOPCHAIN.length; ej += 1) {\n                    var gedge = [];\n                    for (ei = 0; ei < st; ei += 1) { gedge.push(chainOf(ei)[ej]); }\n                    poly(g, gedge, { fill: \"none\", stroke: \"#e0e7ed\", \"stroke-width\": 0.9 });\n                }\n                for (pi = st - 1; pi >= 1; pi -= 1) {\n                    poly(g, chainOf(pi), { fill: \"none\", stroke: \"#d3dde4\", \"stroke-width\": 1.1, \"stroke-linejoin\": \"round\" });\n                }\n                poly(g, chainOf(0), { fill: \"none\", stroke: \"#b9c8d2\", \"stroke-width\": 1.6, \"stroke-linejoin\": \"round\" });\n                labelBox(g, 464, 200, \"Wirkung einblenden\", { width: 168, size: 9.5, fill: \"#f0f5fa\", stroke: \"#cfe0ea\", color: COLORS.primary });\n                text(g, 464, 226, \"Klick auf \u201eWirkung im\", { \"font-size\": 9, fill: COLORS.muted, \"text-anchor\": \"middle\" });\n                text(g, 464, 240, \"Profilk\u00f6rper\u201c\", { \"font-size\": 9, fill: COLORS.muted, \"text-anchor\": \"middle\" });\n            } else {\n                \/\/ Profilkoerper: Deckenband als Flaechenstreifen zwischen den Stationen.\n                \/\/ Farbfolge = Fahrbahn, Fahrbahn, Bordflanke, Bordkrone, Gehweg, Boeschung\n                var SEGFILL = [\"#aeb9c2\", \"#aeb9c2\", \"#d5dce1\", \"#e2e7ea\", \"#dbe1e5\", \"#e7dfcd\"];\n                for (pi = st - 1; pi >= 1; pi -= 1) {\n                    var cFar = chainOf(pi), cNear = chainOf(pi - 1);\n                    for (sj = 0; sj + 1 < cFar.length; sj += 1) {\n                        poly(g, [cNear[sj], cNear[sj + 1], cFar[sj + 1], cFar[sj], cNear[sj]], { fill: SEGFILL[sj], stroke: \"none\", opacity: 0.92 });\n                    }\n                    poly(g, cFar, { fill: \"none\", stroke: \"#94a7b4\", \"stroke-width\": 0.9, \"stroke-linejoin\": \"round\", opacity: 0.9 });\n                }\n                \/\/ Laengskanten: jeder Querschnittspunkt zieht seine Linie durch alle Stationen\n                for (ej = 0; ej < TOPCHAIN.length; ej += 1) {\n                    var edge = [];\n                    for (ei = 0; ei < st; ei += 1) { edge.push(chainOf(ei)[ej]); }\n                    poly(g, edge, { fill: \"none\", stroke: \"#8fa2b0\", \"stroke-width\": ej === 0 ? 1.2 : 0.8, opacity: 0.85 });\n                }\n                \/\/ Schnittflaeche vorn: Erdkoerper bis zur Oberflaeche, Materialaufbau deckend darueber\n                var damF = topChainPts(frontO);\n                var dx2;\n                for (dx2 = LP.daylight.x; dx2 >= -0.1; dx2 -= 12) { damF.push(sp({ x: dx2, y: groundLocalZ(dx2) }, frontO)); }\n                poly(g, damF, { fill: COLORS.earth, stroke: COLORS.earthEdge, \"stroke-width\": 0.9 });\n                var FS = sectionShapes(frontO);\n                poly(g, FS.frost.concat([FS.frost[0]]), { fill: COLORS.frostFill, stroke: COLORS.frostEdge, \"stroke-width\": 0.9 });\n                poly(g, FS.trag.concat([FS.trag[0]]), { fill: COLORS.gravel, stroke: COLORS.gravelEdge, \"stroke-width\": 0.9 });\n                poly(g, FS.belag.concat([FS.belag[0]]), { fill: COLORS.asphalt, stroke: COLORS.asphaltEdge, \"stroke-width\": 0.9 });\n                poly(g, FS.bord.concat([FS.bord[0]]), { fill: COLORS.beton, stroke: COLORS.betonEdge, \"stroke-width\": 0.9 });\n                poly(g, FS.gehweg.concat([FS.gehweg[0]]), { fill: COLORS.beton, stroke: COLORS.betonEdge, \"stroke-width\": 0.9 });\n                poly(g, chainOf(0), { fill: \"none\", stroke: COLORS.primaryDark, \"stroke-width\": 2, \"stroke-linejoin\": \"round\", \"stroke-linecap\": \"round\" });\n\n                \/\/ Stationierung an der Achskante\n                for (ei = 0; ei < st; ei += 1) {\n                    var cpt = sp(LP.crown, ribOrigin(ei, st));\n                    var stM = ei * 20;\n                    text(g, cpt.x - 7, cpt.y + 3, \"0+0\" + (stM < 100 ? \"0\" + stM : String(stM)).slice(-2), { \"font-size\": 7.2, fill: COLORS.faint, \"text-anchor\": \"end\", \"font-weight\": 700 });\n                }\n\n                if (ca === \"punkt\") {\n                    \/\/ EIN Element: die Gehwegkante wird laengs zur Elementkante\n                    var swPts = [];\n                    for (ei = 0; ei < st; ei += 1) { swPts.push(sp(LP.sidewalk, ribOrigin(ei, st))); }\n                    poly(g, swPts, { fill: \"none\", stroke: COLORS.slope, \"stroke-width\": 3.4, \"stroke-linecap\": \"round\" });\n                    swPts.forEach(function (p) { circle(g, p.x, p.y, 3.8, { fill: \"#fff\", stroke: COLORS.codePoint, \"stroke-width\": 2.2 }); });\n                    var lastP = swPts[swPts.length - 1];\n                    leader(g, lastP.x, lastP.y, lastP.x + 20, lastP.y - 30, COLORS.slopeDeep);\n                    labelBox(g, lastP.x + 20, lastP.y - 30, \"Elementkante\", Object.assign({ size: 8.8 }, SSTYLE));\n                } else if (ca === \"verknuepfung\") {\n                    \/\/ Die DGM-Flaeche folgt dem Oberflaechenverlauf jeder Station\n                    \/\/ (Fahrbahn, Bord, Gehweg, Boeschung), keine Sehne durch den Querschnitt\n                    var ri;\n                    for (ri = st - 1; ri >= 1; ri -= 1) {\n                        var sNear = chainOf(ri - 1), sFar = chainOf(ri);\n                        poly(g, sNear.concat(sFar.slice().reverse(), [sNear[0]]), { fill: COLORS.linkFill, \"fill-opacity\": 0.55, stroke: COLORS.codeLink, \"stroke-width\": 1, \"stroke-linejoin\": \"round\" });\n                    }\n                    poly(g, chainOf(0), { fill: \"none\", stroke: COLORS.codeLink, \"stroke-width\": 2, \"stroke-linejoin\": \"round\", \"stroke-linecap\": \"round\" });\n                    var bk = chainOf(st - 1)[0];\n                    leader(g, bk.x, bk.y, bk.x + 22, bk.y - 26, COLORS.codeLinkDeep);\n                    labelBox(g, bk.x + 22, bk.y - 26, \"DGM-Fl\u00e4che\", Object.assign({ size: 8.8 }, LSTYLE));\n                } else if (ca === \"profilart\") {\n                    \/\/ EIN Element: nur der Belag, als klare Gold-Umfaerbung\n                    poly(g, FS.belag.concat([FS.belag[0]]), { fill: COLORS.shapeFill, stroke: COLORS.codeShape, \"stroke-width\": 1.8, \"stroke-linejoin\": \"round\" });\n                    \/\/ Belagband laengs: Oberkante des Belags durch alle Stationen\n                    var t1 = [], t2 = [];\n                    for (ei = 0; ei < st; ei += 1) { t1.push(chainOf(ei)[0]); }\n                    for (ei = st - 1; ei >= 0; ei -= 1) { t2.push(chainOf(ei)[2]); }\n                    poly(g, t1.concat(t2, [t1[0]]), { fill: COLORS.codeShape, \"fill-opacity\": 0.28, stroke: COLORS.codeShape, \"stroke-width\": 1.2 });\n                    var fm = sp({ x: 50, y: 10 }, frontO);\n                    leader(g, fm.x, fm.y, fm.x + 14, fm.y + 36, COLORS.slopeDeep);\n                    labelBox(g, fm.x + 14, fm.y + 36, \"Materialfl\u00e4che (Belag)\", Object.assign({ size: 8.6 }, SSTYLE));\n                } else {\n                    \/\/ ALLE: ein Profilkoerper, pro Codeart das eine Fokus-Element\n                    var rj;\n                    for (rj = st - 1; rj >= 1; rj -= 1) {\n                        var aNear = chainOf(rj - 1), aFar = chainOf(rj);\n                        poly(g, aNear.concat(aFar.slice().reverse(), [aNear[0]]), { fill: COLORS.linkFill, \"fill-opacity\": 0.3, stroke: COLORS.codeLink, \"stroke-width\": 0.9, \"stroke-linejoin\": \"round\" });\n                    }\n                    poly(g, FS.belag.concat([FS.belag[0]]), { fill: COLORS.shapeFill, stroke: COLORS.codeShape, \"stroke-width\": 1.4, \"stroke-linejoin\": \"round\" });\n                    var swA = [];\n                    for (ei = 0; ei < st; ei += 1) { swA.push(sp(LP.sidewalk, ribOrigin(ei, st))); }\n                    poly(g, swA, { fill: \"none\", stroke: COLORS.slope, \"stroke-width\": 2.6, \"stroke-linecap\": \"round\" });\n                    swA.forEach(function (p) { circle(g, p.x, p.y, 3.2, { fill: \"#fff\", stroke: COLORS.codePoint, \"stroke-width\": 2 }); });\n                    var lA = swA[swA.length - 1];\n                    leader(g, lA.x, lA.y, lA.x + 20, lA.y - 28, COLORS.slopeDeep);\n                    labelBox(g, lA.x + 20, lA.y - 28, \"Elementkante\", Object.assign({ size: 8.4 }, SSTYLE));\n                    var mA = chainOf(st - 2 >= 0 ? st - 2 : 0)[0];\n                    leader(g, mA.x, mA.y, mA.x - 26, mA.y - 30, COLORS.codeLinkDeep);\n                    labelBox(g, mA.x - 26, mA.y - 30, \"DGM-Fl\u00e4che\", Object.assign({ size: 8.4 }, LSTYLE));\n                    var fA = sp({ x: 50, y: 10 }, frontO);\n                    leader(g, fA.x, fA.y, fA.x + 14, fA.y + 36, COLORS.slopeDeep);\n                    labelBox(g, fA.x + 14, fA.y + 36, \"Materialfl\u00e4che\", Object.assign({ size: 8.4 }, SSTYLE));\n                }\n            }\n\n            \/\/ Tiles + Verdict\n            var sitz, ziel, nutz, chipKind, sample, downstream, laengs;\n            var A = 1.30, L2 = st * 20, V = A * L2;\n            if (ca === \"punkt\") {\n                sitz = \"Punkte\";\n                ziel = \"Elementkante\";\n                nutz = \"Linien\/Modell\";\n                chipKind = \"is-point\";\n                sample = \"Crown, ETW, Top_Curb, Daylight\";\n                downstream = \"verbinden sich l\u00e4ngs zu 3D-Profilk\u00f6rper-Elementkanten\";\n                laengs = \"\u00dcber \" + st + \" Stationen wird aus dem gleichen Punktcode (hier der Gehwegkante) eine durchgehende Elementkante \u2013 dieselbe Objektklasse wie in 05, nutzbar als Bruchkante oder f\u00fcr Beschriftung.\";\n            } else if (ca === \"verknuepfung\") {\n                sitz = \"Linien\";\n                ziel = \"DGM-Fl\u00e4che\";\n                nutz = \"Profilk\u00f6rper-DGM\";\n                chipKind = \"is-link\";\n                sample = \"Top, Pave1\";\n                downstream = \"spannen l\u00e4ngs die Oberfl\u00e4che des Profilk\u00f6rper-DGM auf\";\n                laengs = \"Der gleiche Verkn\u00fcpfungscode (hier Top) spannt \u00fcber \" + st + \" Stationen eine Fl\u00e4che auf \u2013 daraus baut der Profilk\u00f6rper das DGM der fertigen Oberfl\u00e4che.\";\n            } else if (ca === \"profilart\") {\n                sitz = \"Fl\u00e4chen\";\n                ziel = \"Materialfl\u00e4che\";\n                nutz = \"Massen (m\u00b3)\";\n                chipKind = \"is-shape\";\n                sample = \"Pave1, Base, SubBase\";\n                downstream = \"werden zu Materialfl\u00e4chen f\u00fcr Schraffur und Massenermittlung\";\n                laengs = \"Der Profilartcode (hier Pave1) wird \u00fcber \" + st + \" Stationen zur Materialfl\u00e4che: A \u2248 \" + fmt(A, 2) + \" m\u00b2 \u00d7 \" + fmt(L2, 0) + \" m \u2248 \" + fmt(V, 0) + \" m\u00b3 Belag \u2013 so entstehen Schraffur und Massen.\";\n            } else {\n                sitz = \"alle drei\";\n                ziel = \"Kante \u00b7 DGM \u00b7 Masse\";\n                nutz = \"komplettes Modell\";\n                chipKind = \"\";\n                sample = \"Crown, Top, Pave1 \u2026\";\n                downstream = \"werden im Profilk\u00f6rper zu Elementkanten, DGM-Fl\u00e4chen und Materialmassen\";\n                laengs = \"Ein einziger, sauber codierter Querschnitt tr\u00e4gt alle drei Codearten \u2013 daraus entsteht \u00fcber \" + st + \" Stationen alles Weitere: Linien, Oberfl\u00e4chen und Massen.\";\n            }\n            $(\"qwCodeSitz\").textContent = sitz;\n            $(\"qwCodeZiel\").textContent = ziel;\n            $(\"qwCodeNutz\").textContent = nutz;\n\n            var head;\n            if (!state.auszahlung) {\n                if (ca === \"alle\") {\n                    head = \"<strong>Ein Querschnitt tr\u00e4gt alle drei Codearten gleichzeitig:<\/strong> Punktcodes an den Punkten (violett), Verkn\u00fcpfungscodes an den Linien (cyan), Profilartcodes an den Fl\u00e4chen (gold). Blende die <strong>Wirkung<\/strong> ein, um zu sehen, was daraus im Profilk\u00f6rper wird.\";\n                } else {\n                    head = \"<strong>\" + caLabel + \" markiert die \" + sitz + \" des Bestandteils<\/strong> (Beispiele: \" + sample + \"). Bisher ist das nur eine Kennzeichnung im Querschnitt. Blende die <strong>Wirkung<\/strong> ein, um zu sehen, was daraus im Profilk\u00f6rper wird.\";\n                }\n            } else {\n                if (ca === \"alle\") {\n                    head = \"<strong>Ein codierter Querschnitt, das komplette Modell.<\/strong> Dieselben Codes \" + downstream + \". \" + laengs;\n                } else {\n                    head = \"<strong>\" + caLabel + \" \u2192 \" + ziel + \".<\/strong> Gleich benannte Codes \" + downstream + \". \" + laengs;\n                }\n            }\n            setVerdict(chipKind, caLabel, head);\n        }\n\n        \/\/ ============ MODUS 3: ANBINDUNG ============\n        function groundZ(x) {\n            \/\/ leichtes Gefaelle nach rechts plus milde Welle, damit ein Boeschungsfuss real gefunden wird\n            return 100 - 0.06 * x + 0.3 * Math.sin(x * 0.5);\n        }\n        function renderAnbindung() {\n            var g = $(\"qwAnbDraw\");\n            clear(g);\n            syncSeg(\"qwZiel\", \"data-qw-ziel\", state.ziel);\n            var n = state.anbNeig, H = state.anbTiefe, mit = state.ziel === \"mit\";\n            $(\"qwAnbNeigText\").textContent = ratStr(n);\n            $(\"qwAnbTiefeText\").textContent = fmt(H, 1) + \" m\";\n\n            var xK = 0, xEnd = 8, xShow = 11, step = 0.04;\n            var niveau = groundZ(xK) + H;   \/\/ Boeschungskopf-Hoehe (Auftrag\/Damm)\n            var hit = false, xF = xEnd, zF = groundZ(xEnd);\n            var x;\n            for (x = xK + step; x <= xEnd + 0.0001; x += step) {\n                var ray = niveau - (x - xK) \/ n;\n                var gz = groundZ(x);\n                if (ray <= gz) { hit = true; xF = Math.round(x * 100) \/ 100; zF = Math.round(gz * 100) \/ 100; break; }\n            }\n            var reachM = xF - xK;\n\n            var zMin = 92, zMax = 106;\n            function mx(xx) { return 98 + (xx - 0) \/ (12 - 0) * 464; }\n            function mz(z) { return 40 + (zMax - z) \/ (zMax - zMin) * (300); }\n            function mzc(z) { return mz(Math.max(zMin + 0.3, Math.min(zMax - 0.3, z))); }\n\n            card(g, 24, 16, 572, 324, \"Anbindung: B\u00f6schungs-Bestandteil und Ziel-DGM\");\n\n            \/\/ Gelaende als Ingenieursdarstellung: Linie, heller Bodenkoerper, Erdschraffur.\n            \/\/ Das Gelaende laeuft links unter dem Strassenkoerper weiter (x ab -1.5).\n            var yBot = 318;\n            var roadX0 = 40;\n            var kopf = { x: mx(xK), y: mzc(niveau) };\n            var gpts = [];\n            for (x = -1.5; x <= xEnd + 0.0001; x += 0.2) { gpts.push({ x: mx(x), y: mz(groundZ(x)) }); }\n            var dgmColor = mit ? COLORS.ground : COLORS.faint;\n            var fillPts = gpts.slice();\n            fillPts.push({ x: mx(xEnd), y: yBot });\n            fillPts.push({ x: gpts[0].x, y: yBot });\n            poly(g, fillPts, { fill: mit ? \"#e6edf2\" : \"#edf0f3\", stroke: \"none\" });\n            \/\/ Sparsame Diagonalschraffur im Bodenkoerper, per clipPath begrenzt\n            var acp = el(\"clipPath\", { id: \"qwAnbClip\" });\n            acp.appendChild(el(\"polygon\", { points: ptStr(fillPts) }));\n            g.appendChild(acp);\n            var ahg = el(\"g\", { \"clip-path\": \"url(#qwAnbClip)\" });\n            g.appendChild(ahg);\n            var ahx;\n            for (ahx = gpts[0].x - 60; ahx < mx(xEnd); ahx += 42) {\n                line(ahg, ahx, yBot + 10, ahx + 130, mz(zMax) + 60, { stroke: mit ? \"#ccd7df\" : \"#d5dade\", \"stroke-width\": 0.8, opacity: 0.55 });\n            }\n            var ti;\n            for (ti = 2; ti < gpts.length - 1; ti += 3) {\n                line(g, gpts[ti].x, gpts[ti].y + 3, gpts[ti].x - 8, gpts[ti].y + 13, { stroke: COLORS.groundTick, \"stroke-width\": 1 });\n            }\n\n            \/\/ Erdkoerper der Planung: geschlossener Damm nur bei erreichtem Boeschungsfuss,\n            \/\/ sonst ein offener Sockel unter der Fahrbahn. Immer VOR der Gelaendelinie\n            \/\/ und den Fahrbahnschichten gezeichnet, damit die Fuellung ueberall anschliesst.\n            if (mit ? hit : false) {\n                var fussA = { x: mx(xF), y: mz(zF) };\n                var body = [{ x: roadX0, y: kopf.y }, { x: kopf.x, y: kopf.y }, { x: fussA.x, y: fussA.y }];\n                var bx2;\n                for (bx2 = xF; bx2 >= -1.5 - 0.001; bx2 -= 0.2) { body.push({ x: mx(bx2), y: mz(groundZ(bx2)) }); }\n                poly(g, body, { fill: COLORS.earth, stroke: \"none\" });\n                \/\/ Boeschungsschraffur: abwechselnd lange und kurze Striche in den Koerper\n                var dxs = fussA.x - kopf.x, dys = fussA.y - kopf.y;\n                var slen = Math.sqrt(dxs * dxs + dys * dys);\n                var nnx = -dys \/ slen, nny = dxs \/ slen;\n                var tt, hlen, hi = 0;\n                for (tt = 0.14; tt < 0.92; tt += 0.13) {\n                    hlen = hi % 2 === 0 ? 13 : 8;\n                    hi += 1;\n                    line(g, kopf.x + dxs * tt, kopf.y + dys * tt, kopf.x + dxs * tt + nnx * hlen, kopf.y + dys * tt + nny * hlen, { stroke: COLORS.earthEdge, \"stroke-width\": 1.1 });\n                }\n            } else {\n                poly(g, [{ x: roadX0, y: kopf.y }, { x: kopf.x, y: kopf.y }, { x: kopf.x, y: mz(groundZ(xK)) }, { x: roadX0, y: mz(groundZ(-1.5)) }], { fill: COLORS.earth, stroke: \"none\" });\n                line(g, kopf.x, kopf.y + 16, kopf.x, mz(groundZ(xK)) - 2, { stroke: COLORS.gravelEdge, \"stroke-width\": 1.2, \"stroke-dasharray\": \"4 3\" });\n            }\n\n            poly(g, gpts, { fill: \"none\", stroke: dgmColor, \"stroke-width\": 2.6, \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\", \"stroke-dasharray\": mit ? \"none\" : \"6 4\" });\n            text(g, mx(3.4), yBot - 22, mit ? \"Ziel-DGM (zugewiesen)\" : \"DGM vorhanden, aber nicht als Ziel\", { \"font-size\": 9.5, fill: mit ? COLORS.primaryDark : COLORS.muted, \"text-anchor\": \"middle\", \"font-weight\": 700 });\n\n            \/\/ Rechts der DGM-Grenze gibt es keine Zielflaeche: nur eine blasse Andeutung\n            var outPts = [];\n            for (x = xEnd; x <= 11.4; x += 0.2) { outPts.push({ x: mx(x), y: mz(groundZ(x)) }); }\n            poly(g, outPts, { fill: \"none\", stroke: \"#c9ced3\", \"stroke-width\": 1.3, \"stroke-dasharray\": \"5 5\" });\n            text(g, mx(9.7), mz(groundZ(9.7)) + 22, \"au\u00dferhalb des Ziel-DGM\", { \"font-size\": 8.4, fill: \"#a8b0b8\", \"text-anchor\": \"middle\" });\n\n            \/\/ DGM-Grenze\n            line(g, mx(xEnd), 60, mx(xEnd), yBot - 6, { stroke: \"#94a3b8\", \"stroke-width\": 1.3, \"stroke-dasharray\": \"4 4\" });\n            labelBox(g, mx(xEnd) - 44, 84, \"DGM-Grenze\", { width: 82, size: 8.4, color: COLORS.muted });\n\n            \/\/ Strassenkoerper links: Belag + Tragschicht, darauf die Planungskante\n            poly(g, [{ x: roadX0, y: kopf.y + 2 }, { x: kopf.x, y: kopf.y + 2 }, { x: kopf.x, y: kopf.y + 9 }, { x: roadX0, y: kopf.y + 9 }, { x: roadX0, y: kopf.y + 2 }], { fill: COLORS.asphalt, stroke: COLORS.asphaltEdge, \"stroke-width\": 1 });\n            poly(g, [{ x: roadX0, y: kopf.y + 9 }, { x: kopf.x, y: kopf.y + 9 }, { x: kopf.x, y: kopf.y + 15 }, { x: roadX0, y: kopf.y + 15 }, { x: roadX0, y: kopf.y + 9 }], { fill: COLORS.gravel, stroke: COLORS.gravelEdge, \"stroke-width\": 1 });\n            line(g, roadX0, kopf.y, kopf.x, kopf.y, { stroke: COLORS.plan, \"stroke-width\": 3.4, \"stroke-linecap\": \"round\" });\n            leader(g, kopf.x, kopf.y, kopf.x + 44, kopf.y - 24, COLORS.planDeep);\n            labelBox(g, kopf.x + 44, kopf.y - 24, \"Planungskante\", { width: 96, size: 8.6, color: COLORS.planDeep });\n            dotMark(g, kopf.x, kopf.y, COLORS.plan, 4.6);\n\n            var statusTxt, reachTxt, chipKind, chipTxt, head, rule;\n\n            if (!mit) {\n                \/\/ ohne Ziel: Link haengt in der Luft\n                var nomEnd = { x: mx(xShow * 0.62), y: mzc(niveau - (xShow * 0.62 - xK) \/ n) };\n                line(g, kopf.x, kopf.y, nomEnd.x, nomEnd.y, { stroke: COLORS.slope, \"stroke-width\": 3.4, \"stroke-linecap\": \"round\", \"stroke-dasharray\": \"2 3\", opacity: 0.85 });\n                circle(g, nomEnd.x, nomEnd.y, 5, { fill: \"#fff\", stroke: COLORS.error, \"stroke-width\": 2.2 });\n                line(g, nomEnd.x - 6, nomEnd.y - 6, nomEnd.x + 6, nomEnd.y + 6, { stroke: COLORS.error, \"stroke-width\": 1.8 });\n                line(g, nomEnd.x + 6, nomEnd.y - 6, nomEnd.x - 6, nomEnd.y + 6, { stroke: COLORS.error, \"stroke-width\": 1.8 });\n                leader(g, nomEnd.x, nomEnd.y, nomEnd.x + 10, nomEnd.y + 30, COLORS.error);\n                labelBox(g, nomEnd.x + 10, nomEnd.y + 30, \"kein Ziel \u2192 kein Fu\u00df\", { width: 128, size: 9, fill: \"#fef2f2\", stroke: \"#fac5c5\", color: COLORS.error });\n                statusTxt = \"kein Ziel\";\n                reachTxt = \"\u2013\";\n                chipKind = \"is-error\";\n                chipTxt = \"kein Anschluss\";\n                head = \"<strong>Ohne zugewiesenes Ziel-DGM bindet nichts an.<\/strong> Der B\u00f6schungs-Link ist im Querschnitt zwar vorhanden, hat aber keine Zielfl\u00e4che, an der er auslaufen k\u00f6nnte. Genau das ist die h\u00e4ufigste Entt\u00e4uschung: \u201ewarum passiert nichts?\u201c. Das Ziel wird erst im Profilk\u00f6rper (08) gesetzt, nicht hier.\";\n                rule = \"<strong>Merksatz:<\/strong> Der Querschnitt definiert die B\u00f6schung, das Ziel-DGM kommt im Profilk\u00f6rper dazu. Ohne Ziel kein B\u00f6schungsfu\u00df.\";\n            } else if (hit) {\n                var fuss = { x: mx(xF), y: mz(zF) };\n                line(g, kopf.x, kopf.y, fuss.x, fuss.y, { stroke: COLORS.slope, \"stroke-width\": 3.8, \"stroke-linecap\": \"round\" });\n                dotMark(g, fuss.x, fuss.y, COLORS.slope, 4.8);\n                leader(g, fuss.x, fuss.y, Math.min(fuss.x + 8, 470), fuss.y + 34, COLORS.slopeDeep);\n                labelBox(g, Math.min(fuss.x + 8, 470), fuss.y + 34, \"B\u00f6schungsfu\u00df\", { width: 104, size: 9, color: COLORS.slopeDeep });\n                statusTxt = \"trifft DGM\";\n                reachTxt = fmt(reachM, 1) + \" m\";\n                chipKind = \"is-good\";\n                chipTxt = \"bindet an\";\n                head = \"<strong>Mit Ziel-DGM l\u00e4uft die B\u00f6schung sauber aus.<\/strong> Der Link trifft die Zielfl\u00e4che rund \" + fmt(reachM, 1) + \" m von der Planungskante entfernt \u2013 dort sitzt der B\u00f6schungsfu\u00df (Daylight). Merke: Im Querschnitt legst du nur Bestandteil und Ziel-Parameter an; die Anbindung selbst rechnet der Profilk\u00f6rper an jeder Station.\";\n                rule = \"<strong>Merksatz:<\/strong> Steiler b\u00f6schen verk\u00fcrzt die Reichweite. Die B\u00f6schung l\u00e4uft nur aus, wenn das Ziel-DGM in Reichweite liegt.\";\n            } else {\n                var zEnd = niveau - (xEnd - xK) \/ n;\n                var zSh = niveau - (xShow - xK) \/ n;\n                line(g, kopf.x, kopf.y, mx(xEnd), mzc(zEnd), { stroke: COLORS.slope, \"stroke-width\": 3.8, \"stroke-linecap\": \"round\" });\n                line(g, mx(xEnd), mzc(zEnd), mx(xShow), mzc(zSh), { stroke: COLORS.error, \"stroke-width\": 2.6, \"stroke-dasharray\": \"6 5\", \"stroke-linecap\": \"round\" });\n                labelBox(g, mx(9.8), mzc((zEnd + zSh) \/ 2) + 22, \"trifft Gel\u00e4nde nicht\", { width: 132, size: 9.2, fill: \"#fef2f2\", stroke: \"#fac5c5\", color: COLORS.error });\n                statusTxt = \"verfehlt DGM\";\n                reachTxt = \"\u2013\";\n                chipKind = \"is-warn\";\n                chipTxt = \"l\u00e4uft nicht aus\";\n                head = \"<strong>Ziel ist gesetzt, aber die B\u00f6schung ist zu flach.<\/strong> Bei \" + ratStr(n) + \" (H:V) und \" + fmt(H, 1) + \" m H\u00f6he l\u00e4uft der Link \u00fcber die DGM-Grenze hinaus, bevor er die Zielfl\u00e4che trifft. Civil 3D meldet dann sinngem\u00e4\u00df \u201el\u00e4uft nicht aus\u201c. Steiler b\u00f6schen oder das Ziel-DGM weiter ausdehnen.\";\n                rule = \"<strong>Merksatz:<\/strong> Zu flach plus zu kleines Ziel-DGM, und die B\u00f6schung trifft den Bestand nicht \u2013 der Klassiker unter den Anbindungsfehlern.\";\n            }\n\n            $(\"qwAnbStatus\").textContent = statusTxt;\n            $(\"qwAnbReach\").textContent = reachTxt;\n            $(\"qwAnbRatio\").textContent = ratStr(n);\n            setVerdict(chipKind, chipTxt, head, rule);\n        }\n\n        \/\/ ============ Steuerung ============\n        function renderTopic() {\n            if (state.topic === \"codes\") { renderCodes(); }\n            else { renderAnbindung(); }\n        }\n        function setTopic(topic) {\n            state.topic = topic;\n            ROOT.querySelectorAll(\".qw-focus-btn\").forEach(function (btn) {\n                btn.classList.toggle(\"is-active\", btn.getAttribute(\"data-qw-topic\") === topic);\n            });\n            ROOT.querySelectorAll(\".qw-topic\").forEach(function (panel) {\n                panel.classList.toggle(\"is-active\", panel.getAttribute(\"data-topic\") === topic);\n            });\n            renderTopic();\n        }\n\n        ROOT.addEventListener(\"click\", function (e) {\n            var topicBtn = e.target.closest ? e.target.closest(\"[data-qw-topic]\") : null;\n            if (topicBtn ? ROOT.contains(topicBtn) : false) { setTopic(topicBtn.getAttribute(\"data-qw-topic\")); return; }\n\n            var toggleBtn = e.target.closest ? e.target.closest(\"[data-qw-toggle]\") : null;\n            if (toggleBtn ? ROOT.contains(toggleBtn) : false) {\n                var tk = toggleBtn.getAttribute(\"data-qw-toggle\");\n                if (tk === \"auszahlung\") { state.auszahlung = state.auszahlung !== true; renderCodes(); }\n                return;\n            }\n            var ca = e.target.closest ? e.target.closest(\"[data-qw-codeart]\") : null;\n            if (ca ? ROOT.contains(ca) : false) { state.codeart = ca.getAttribute(\"data-qw-codeart\"); renderCodes(); return; }\n            var zl = e.target.closest ? e.target.closest(\"[data-qw-ziel]\") : null;\n            if (zl ? ROOT.contains(zl) : false) { state.ziel = zl.getAttribute(\"data-qw-ziel\"); renderAnbindung(); return; }\n        });\n\n        ROOT.addEventListener(\"input\", function (e) {\n            var id = e.target.id;\n            var v = parseFloat(e.target.value);\n            if (isNaN(v)) { v = 0; }\n            if (id === \"qwStationen\") { state.stationen = Math.round(v); renderCodes(); }\n            else if (id === \"qwAnbNeig\") { state.anbNeig = v; renderAnbindung(); }\n            else if (id === \"qwAnbTiefe\") { state.anbTiefe = v; renderAnbindung(); }\n        });\n\n        renderTopic();\n    })();\n<\/script>\n\n","protected":false},"excerpt":{"rendered":"<p>Querschnitt-Werkstatt Die Codes eines Querschnitts und ihre Wirkung im Profilk&ouml;rper sichtbar machen und die DGM-Anbindung mit und ohne Ziel durchspielen [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"disabled","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[43],"tags":[],"class_list":["post-2287","post","type-post","status-publish","format-standard","hentry","category-querschnittsaufbau"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":false,"author_link":"https:\/\/cad-kompass.de\/?author=1"},"uagb_comment_info":0,"uagb_excerpt":"Querschnitt-Werkstatt Die Codes eines Querschnitts und ihre Wirkung im Profilk&ouml;rper sichtbar machen und die DGM-Anbindung mit und ohne Ziel durchspielen [&hellip;]","_links":{"self":[{"href":"https:\/\/cad-kompass.de\/index.php?rest_route=\/wp\/v2\/posts\/2287","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cad-kompass.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cad-kompass.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cad-kompass.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cad-kompass.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2287"}],"version-history":[{"count":1,"href":"https:\/\/cad-kompass.de\/index.php?rest_route=\/wp\/v2\/posts\/2287\/revisions"}],"predecessor-version":[{"id":2288,"href":"https:\/\/cad-kompass.de\/index.php?rest_route=\/wp\/v2\/posts\/2287\/revisions\/2288"}],"wp:attachment":[{"href":"https:\/\/cad-kompass.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2287"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cad-kompass.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2287"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cad-kompass.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2287"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}