{"id":2375,"date":"2026-08-03T07:08:22","date_gmt":"2026-08-03T05:08:22","guid":{"rendered":"https:\/\/cad-kompass.de\/?p=2375"},"modified":"2026-08-03T07:08:42","modified_gmt":"2026-08-03T05:08:42","slug":"spalten-dekoder-fuer-haltungen","status":"publish","type":"post","link":"https:\/\/cad-kompass.de\/?p=2375","title":{"rendered":"Spalten Dekoder f\u00fcr Haltungen"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<style>\n    .ksd-box {\n        --ksd-primary: #3f5f75;\n        --ksd-primary-dark: #2c4a5e;\n        --ksd-primary-deep: #1e3548;\n        --ksd-ink: #1e293b;\n        --ksd-text: #334155;\n        --ksd-muted: #64748b;\n        --ksd-border: #c8d6e0;\n        --ksd-surface: #f7f9fb;\n        --ksd-good: #059669;\n        --ksd-good-deep: #15803d;\n        --ksd-warn: #d97706;\n        --ksd-warn-deep: #92700c;\n        --ksd-warn-border: #f4cf81;\n        --ksd-error: #dc2626;\n        --ksd-accent: #e8913a;\n        --ksd-accent-deep: #a25c14;\n        background: var(--ksd-surface);\n        border: 3px solid var(--ksd-primary);\n        border-radius: 8px;\n        margin: 28px 0;\n        overflow: hidden;\n        position: relative;\n        font-family: inherit;\n        color: var(--ksd-text);\n        line-height: 1.55;\n    }\n    .ksd-box, .ksd-box *, .ksd-box *::before, .ksd-box *::after { box-sizing: border-box; }\n    .ksd-box [hidden] { display: none !important; }\n\n    .ksd-header {\n        background: linear-gradient(135deg, var(--ksd-primary-deep) 0%, var(--ksd-primary-dark) 100%);\n        padding: 20px 28px 18px;\n        position: relative;\n    }\n    .ksd-header::after {\n        content: '';\n        position: absolute;\n        left: 0; right: 0; bottom: 0;\n        height: 3px;\n        background: repeating-linear-gradient(90deg, var(--ksd-primary) 0px, var(--ksd-primary) 8px, transparent 8px, transparent 12px);\n    }\n    .ksd-header-top { display: flex; align-items: center; gap: 14px; }\n    .ksd-header-icon { width: 36px; height: 36px; flex-shrink: 0; }\n    .ksd-box-title { font-size: 1.15rem; color: #fff; font-weight: 700; margin: 0; letter-spacing: -0.01em; }\n    .ksd-box-desc { font-size: 0.85rem; color: rgba(255,255,255,0.68); margin: 6px 0 0; line-height: 1.55; }\n\n    .ksd-body { padding: 22px 28px 24px; }\n    .ksd-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(--ksd-good-deep);\n        line-height: 1.5;\n        display: flex;\n        align-items: center;\n        gap: 8px;\n    }\n    .ksd-privacy::before { content: '\\1F512'; flex-shrink: 0; font-size: 0.9rem; }\n    .ksd-intro {\n        background: #f0f5fa;\n        border-left: 3px solid var(--ksd-primary);\n        border-radius: 0 4px 4px 0;\n        padding: 11px 15px;\n        margin-bottom: 16px;\n        font-size: 0.86rem;\n        color: var(--ksd-text);\n    }\n    .ksd-intro strong { color: var(--ksd-ink); }\n\n    .ksd-section-label {\n        font-size: 0.66rem;\n        font-weight: 800;\n        text-transform: uppercase;\n        letter-spacing: 0.1em;\n        color: var(--ksd-muted);\n        margin: 0 0 8px;\n    }\n    .ksd-sub-title {\n        font-size: 0.72rem;\n        font-weight: 800;\n        color: var(--ksd-primary);\n        text-transform: uppercase;\n        letter-spacing: 0.08em;\n        margin: 22px 0 9px;\n        padding-top: 16px;\n        border-top: 1px solid #e4ebf1;\n    }\n    .ksd-sub-title.is-plain { border-top: 0; padding-top: 0; margin-top: 16px; }\n\n    \/* --- Steuerung --- *\/\n    .ksd-controls {\n        border: 1px solid var(--ksd-border);\n        border-radius: 4px;\n        background: var(--ksd-surface);\n        padding: 14px 16px 16px;\n        display: grid;\n        grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n        gap: 14px 20px;\n        align-items: start;\n        margin-bottom: 14px;\n    }\n    .ksd-control-block { min-width: 0; }\n    .ksd-field { margin-bottom: 12px; padding-left: 9px; border-left: 3px solid var(--ksd-border); }\n    .ksd-field:last-child { margin-bottom: 0; }\n    .ksd-field-label { display: flex; justify-content: space-between; gap: 8px; font-size: 0.76rem; font-weight: 800; color: var(--ksd-ink); margin-bottom: 4px; }\n    .ksd-field-unit { color: var(--ksd-muted); font-size: 0.74rem; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }\n\n    .ksd-box .ksd-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(--ksd-primary);\n    }\n    .ksd-box .ksd-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    .ksd-box .ksd-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(--ksd-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    .ksd-box .ksd-range::-moz-range-track {\n        height: 6px !important;\n        background: transparent !important;\n        border: 0 !important;\n        box-shadow: none !important;\n    }\n    .ksd-box .ksd-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(--ksd-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    .ksd-box .ksd-range::-moz-focus-outer { border: 0 !important; }\n    .ksd-box .ksd-range:focus-visible { outline: 2px solid var(--ksd-primary) !important; outline-offset: 4px !important; border-radius: 3px !important; }\n    .ksd-box .ksd-range:disabled { opacity: 0.42 !important; cursor: not-allowed !important; }\n    .ksd-box .ksd-range:disabled::-webkit-slider-thumb { background: #aab8c2 !important; }\n    .ksd-box .ksd-range:disabled::-moz-range-thumb { background: #aab8c2 !important; }\n\n    .ksd-box .ksd-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(--ksd-primary) !important;\n        border: 1px solid var(--ksd-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    .ksd-box .ksd-btn:hover { background: var(--ksd-primary-dark) !important; border-color: var(--ksd-primary-dark) !important; color: #fff !important; }\n    .ksd-box .ksd-btn:active { background: var(--ksd-primary-deep) !important; }\n    .ksd-box .ksd-btn:focus-visible { outline: 2px solid var(--ksd-primary) !important; outline-offset: 2px !important; }\n    .ksd-box .ksd-btn:disabled { background: #aab8c2 !important; border-color: #aab8c2 !important; cursor: not-allowed !important; }\n    .ksd-box .ksd-btn.ksd-btn-ghost {\n        background: #fff !important;\n        color: var(--ksd-primary) !important;\n        border: 1px solid var(--ksd-border) !important;\n        font-size: 0.74rem !important;\n        min-height: 32px !important;\n        padding: 5px 11px !important;\n    }\n    .ksd-box .ksd-btn.ksd-btn-ghost:hover { background: #edf4f8 !important; border-color: var(--ksd-primary) !important; color: var(--ksd-primary-dark) !important; }\n    .ksd-box .ksd-btn.ksd-btn-ghost:active { background: #e2ecf2 !important; }\n\n    .ksd-seg { display: inline-flex; flex-wrap: wrap; border: 1px solid var(--ksd-border); border-radius: 3px; overflow: hidden; background: #fff; width: 100%; }\n    .ksd-box .ksd-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(--ksd-text) !important;\n        background: #fff !important;\n        border: none !important;\n        border-radius: 0 !important;\n        min-height: 34px !important;\n        padding: 6px 10px !important;\n        cursor: pointer !important;\n        box-shadow: none !important;\n        text-transform: none !important;\n        flex: 1 1 auto !important;\n        transition: background-color 0.15s, color 0.15s;\n    }\n    .ksd-box .ksd-seg button + button { border-left: 1px solid var(--ksd-border) !important; }\n    .ksd-box .ksd-seg button.is-active { background: var(--ksd-primary) !important; color: #fff !important; }\n    .ksd-box .ksd-seg button:hover:not(.is-active) { background: #edf4f8 !important; color: var(--ksd-primary) !important; }\n    .ksd-box .ksd-seg button:active { background: #e2ecf2 !important; }\n    .ksd-box .ksd-seg button:focus-visible { outline: 2px solid var(--ksd-primary) !important; outline-offset: -2px !important; }\n    .ksd-box .ksd-seg button:disabled { opacity: 0.5 !important; cursor: not-allowed !important; }\n    .ksd-seg.ksd-seg-col { flex-direction: column; }\n    .ksd-box .ksd-seg.ksd-seg-col button { text-align: left !important; }\n    .ksd-box .ksd-seg.ksd-seg-col button + button { border-left: 0 !important; border-top: 1px solid var(--ksd-border) !important; }\n\n    .ksd-mini-hint { font-size: 0.74rem; color: var(--ksd-muted); line-height: 1.45; margin-top: 8px; }\n    .ksd-mini-hint strong { color: var(--ksd-ink); }\n\n    \/* --- Zeichnung --- *\/\n    .ksd-svg-wrap {\n        border: 1px solid var(--ksd-border);\n        border-radius: 4px;\n        background: #fff;\n        padding: 12px 14px 10px;\n        margin-bottom: 14px;\n    }\n    .ksd-svg-wrap svg { width: 100%; height: auto; display: block; font-family: inherit; user-select: none; }\n    .ksd-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(--ksd-muted);\n    }\n    .ksd-legend-item { display: inline-flex; align-items: center; gap: 5px; }\n    .ksd-line-swatch { width: 20px; height: 0; border-top: 3px solid currentColor; border-radius: 999px; }\n    .ksd-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\n    \/* --- Erklaer-Panel --- *\/\n    .ksd-panel {\n        border: 1px solid var(--ksd-border);\n        border-left: 3px solid var(--ksd-accent);\n        border-radius: 0 4px 4px 0;\n        background: #fff;\n        padding: 12px 16px;\n        margin-bottom: 14px;\n    }\n    .ksd-panel-head { display: flex; align-items: center; gap: 10px; margin-bottom: 7px; flex-wrap: wrap; }\n    .ksd-panel-kicker {\n        font-size: 0.66rem;\n        font-weight: 800;\n        text-transform: uppercase;\n        letter-spacing: 0.1em;\n        color: var(--ksd-muted);\n    }\n    .ksd-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(--ksd-primary-deep);\n        font-variant-numeric: tabular-nums;\n    }\n    .ksd-chip.is-accent { background: #fdf1da; border-color: #f0c894; color: var(--ksd-accent-deep); }\n    .ksd-chip.is-good { background: #f0fdf4; border-color: #bbf7d0; color: var(--ksd-good-deep); }\n    .ksd-chip.is-warn { background: #fffbeb; border-color: var(--ksd-warn-border); color: var(--ksd-warn-deep); }\n    .ksd-panel-title { font-size: 0.92rem; font-weight: 800; color: var(--ksd-ink); margin: 0 0 5px; line-height: 1.4; }\n    .ksd-panel-formula {\n        font-family: 'SF Mono', 'Fira Code', Consolas, monospace;\n        font-size: 0.76rem;\n        color: var(--ksd-primary-deep);\n        background: #f2f7fa;\n        border-radius: 3px;\n        padding: 5px 9px;\n        margin: 0 0 7px;\n        display: inline-block;\n        font-variant-numeric: tabular-nums;\n    }\n    .ksd-panel-text { font-size: 0.85rem; line-height: 1.65; color: var(--ksd-text); margin: 0; }\n    .ksd-panel-note { font-size: 0.78rem; line-height: 1.55; color: var(--ksd-muted); margin: 7px 0 0; }\n\n    \/* --- Vorhersagefrage --- *\/\n    .ksd-quiz { border: 1px solid var(--ksd-border); border-radius: 4px; background: #fff; padding: 13px 16px 15px; }\n    .ksd-quiz-text { font-size: 0.86rem; color: var(--ksd-text); margin: 0 0 11px; line-height: 1.6; }\n    .ksd-quiz-text strong { color: var(--ksd-ink); }\n    .ksd-quiz-opts { display: flex; flex-direction: column; gap: 7px; }\n    .ksd-box .ksd-opt {\n        -webkit-appearance: none !important;\n        appearance: none !important;\n        display: block !important;\n        width: 100% !important;\n        text-align: left !important;\n        font-family: inherit !important;\n        font-size: 0.82rem !important;\n        font-weight: 700 !important;\n        line-height: 1.4 !important;\n        color: var(--ksd-text) !important;\n        background: #fff !important;\n        border: 1px solid var(--ksd-border) !important;\n        border-radius: 3px !important;\n        min-height: 40px !important;\n        padding: 9px 13px !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    .ksd-box .ksd-opt:hover { background: #edf4f8 !important; border-color: var(--ksd-primary) !important; color: var(--ksd-primary-dark) !important; }\n    .ksd-box .ksd-opt:active { background: #e2ecf2 !important; }\n    .ksd-box .ksd-opt:focus-visible { outline: 2px solid var(--ksd-primary) !important; outline-offset: 2px !important; }\n    .ksd-box .ksd-opt:disabled { opacity: 0.55 !important; cursor: not-allowed !important; }\n    .ksd-box .ksd-opt.is-active { background: #f2f7fa !important; border-color: var(--ksd-primary) !important; color: var(--ksd-primary-deep) !important; }\n    .ksd-quiz-fb {\n        margin-top: 11px;\n        font-size: 0.84rem;\n        line-height: 1.6;\n        border-radius: 3px;\n        padding: 9px 13px;\n        background: #f0fdf4;\n        border: 1px solid #bbf7d0;\n        color: var(--ksd-good-deep);\n    }\n    .ksd-quiz-fb.is-off { background: #fffbeb; border-color: var(--ksd-warn-border); color: var(--ksd-warn-deep); }\n\n    \/* --- Tabellen --- *\/\n    .ksd-table { border: 1px solid var(--ksd-border); border-radius: 4px; background: #fff; overflow: hidden; }\n    .ksd-thead {\n        display: flex;\n        align-items: center;\n        gap: 10px;\n        padding: 7px 13px;\n        background: #f2f7fa;\n        border-bottom: 1px solid var(--ksd-border);\n        font-size: 0.62rem;\n        font-weight: 800;\n        text-transform: uppercase;\n        letter-spacing: 0.07em;\n        color: var(--ksd-muted);\n    }\n    .ksd-th-name { flex: 1 1 auto; min-width: 0; }\n    .ksd-th-val { width: 104px; text-align: right; flex: 0 0 auto; }\n    .ksd-th-src { width: 148px; flex: 0 0 auto; }\n    .ksd-box .ksd-row {\n        -webkit-appearance: none !important;\n        appearance: none !important;\n        display: flex !important;\n        align-items: center;\n        gap: 10px;\n        flex-wrap: wrap;\n        width: 100% !important;\n        text-align: left !important;\n        font-family: inherit !important;\n        font-size: 0.82rem !important;\n        font-weight: 600 !important;\n        line-height: 1.4 !important;\n        color: var(--ksd-text) !important;\n        background: #fff !important;\n        border: 0 !important;\n        border-top: 1px solid #edf2f7 !important;\n        border-left: 3px solid transparent !important;\n        border-radius: 0 !important;\n        min-height: 44px !important;\n        padding: 8px 13px !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;\n    }\n    .ksd-box .ksd-row:first-child { border-top: 0 !important; }\n    .ksd-box .ksd-row:hover { background: #f6fafc !important; }\n    .ksd-box .ksd-row:focus-visible { outline: 2px solid var(--ksd-primary) !important; outline-offset: -2px !important; }\n    .ksd-box .ksd-row.is-active { background: #fdf9f2 !important; border-left-color: var(--ksd-accent) !important; }\n    .ksd-row-name { flex: 1 1 200px; min-width: 0; color: var(--ksd-ink); font-weight: 700; }\n    .ksd-row.is-active .ksd-row-name { font-weight: 800; }\n    .ksd-row-val {\n        width: 104px;\n        flex: 0 0 auto;\n        text-align: right;\n        font-weight: 800;\n        color: var(--ksd-primary-deep);\n        font-variant-numeric: tabular-nums;\n    }\n    .ksd-row-src { width: 148px; flex: 0 0 auto; font-size: 0.72rem; font-weight: 700; color: var(--ksd-muted); }\n    .ksd-row-sub { width: 148px; flex: 0 0 auto; font-size: 0.74rem; color: var(--ksd-muted); font-variant-numeric: tabular-nums; }\n\n    .ksd-tile-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 7px; margin-top: 14px; }\n    .ksd-tile { background: #fff; border: 1px solid #dde7ee; border-radius: 3px; padding: 8px 9px; min-width: 0; }\n    .ksd-tile-label {\n        display: block;\n        color: var(--ksd-muted);\n        font-size: 0.62rem;\n        font-weight: 800;\n        text-transform: uppercase;\n        letter-spacing: 0.05em;\n    }\n    .ksd-tile-value {\n        display: block;\n        color: var(--ksd-ink);\n        font-size: 0.9rem;\n        font-weight: 800;\n        font-variant-numeric: tabular-nums;\n        margin-top: 2px;\n    }\n    .ksd-tile-value.is-accent { color: var(--ksd-accent-deep); }\n    .ksd-tile-value.is-warn { color: var(--ksd-warn-deep); }\n\n    .ksd-note {\n        margin-top: 18px;\n        background: #fffdf7;\n        border: 1px solid #f0e2c8;\n        border-left: 3px solid var(--ksd-accent);\n        border-radius: 0 4px 4px 0;\n        padding: 12px 16px;\n        font-size: 0.84rem;\n        line-height: 1.65;\n        color: var(--ksd-text);\n    }\n    .ksd-note strong { color: var(--ksd-ink); }\n    .ksd-note p { margin: 0; }\n    .ksd-note p + p { margin-top: 8px; }\n\n    .ksd-row-tools { display: flex; justify-content: flex-end; margin-bottom: 9px; }\n\n    @media (max-width: 700px) {\n        .ksd-header { padding: 16px 20px 14px; }\n        .ksd-body { padding: 18px 18px 20px; }\n        .ksd-tile-grid { grid-template-columns: 1fr; }\n        .ksd-th-src, .ksd-th-val { width: auto; }\n        .ksd-row-val { width: auto; text-align: left; }\n        .ksd-row-src, .ksd-row-sub { width: auto; }\n        .ksd-thead { display: none; }\n    }\n    @media (max-width: 480px) {\n        .ksd-seg { display: flex; flex-direction: column; }\n        .ksd-box .ksd-seg button + button { border-left: 0 !important; border-top: 1px solid var(--ksd-border) !important; }\n    }\n    @media (prefers-reduced-motion: reduce) {\n        \/* !important noetig: Accessibility-Override muss beliebige Spezifitaeten der CSS-Box schlagen. *\/\n        .ksd-box * { transition: none !important; animation: none !important; }\n    }\n<\/style>\n\n<div class=\"ksd-box\" data-ksd-root>\n    <div class=\"ksd-header\">\n        <div class=\"ksd-header-top\">\n            <svg class=\"ksd-header-icon\" viewBox=\"0 0 36 36\" fill=\"none\" aria-hidden=\"true\">\n                <rect x=\"4\" y=\"9\" width=\"6\" height=\"15\" rx=\"1\" fill=\"none\" stroke=\"rgba(255,255,255,0.9)\" stroke-width=\"1.6\"\/>\n                <rect x=\"26\" y=\"12\" width=\"6\" height=\"12\" rx=\"1\" fill=\"none\" stroke=\"rgba(255,255,255,0.9)\" stroke-width=\"1.6\"\/>\n                <line x1=\"7\" y1=\"19\" x2=\"29\" y2=\"22\" stroke=\"rgba(255,255,255,0.9)\" stroke-width=\"2\" stroke-linecap=\"round\"\/>\n                <line x1=\"7\" y1=\"29\" x2=\"29\" y2=\"29\" stroke=\"rgba(255,255,255,0.55)\" stroke-width=\"1.3\"\/>\n                <path d=\"M7 26.5 L7 31.5 M29 26.5 L29 31.5\" stroke=\"rgba(255,255,255,0.55)\" stroke-width=\"1.3\" stroke-linecap=\"round\"\/>\n                <path d=\"M10 27.4 L7 29 L10 30.6 M26 27.4 L29 29 L26 30.6\" fill=\"none\" stroke=\"rgba(255,255,255,0.55)\" stroke-width=\"1.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/>\n            <\/svg>\n            <div>\n                <h2 class=\"ksd-box-title\">Spalten-Dekoder f&uuml;r Haltungen<\/h2>\n                <div class=\"ksd-box-desc\">Sechs L&auml;ngen f&uuml;r dieselbe Haltung. Welche Spalte misst welche Strecke?<\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <div class=\"ksd-body\">\n        <div class=\"ksd-privacy\">L&auml;uft komplett im Browser. Keine Daten verlassen deinen Rechner.<\/div>\n\n        <div class=\"ksd-intro\">\n            Civil 3D f&uuml;hrt mehrere L&auml;ngen- und Neigungsspalten nebeneinander, keine hei&szlig;t einfach nur <strong>L&auml;nge<\/strong>. Alle Werte stimmen, niemand widerspricht dir: Eine falsche Spalte in der Mengenermittlung f&auml;llt nicht auf.\n        <\/div>\n\n        <div class=\"ksd-section-label\">Die Haltung, die du vermisst<\/div>\n        <div class=\"ksd-controls\">\n            <div class=\"ksd-control-block\">\n                <div class=\"ksd-field\">\n                    <label class=\"ksd-field-label\" for=\"ksdL\">Schachtmitte zu Schachtmitte <span class=\"ksd-field-unit\" id=\"ksdLTxt\">40 m<\/span><\/label>\n                    <input class=\"ksd-range\" id=\"ksdL\" type=\"range\" min=\"20\" max=\"60\" step=\"1\" value=\"40\">\n                <\/div>\n                <div class=\"ksd-field\">\n                    <label class=\"ksd-field-label\" for=\"ksdZ1\">Sohlh&ouml;he oben (S1) <span class=\"ksd-field-unit\" id=\"ksdZ1Txt\">97,80 m<\/span><\/label>\n                    <input class=\"ksd-range\" id=\"ksdZ1\" type=\"range\" min=\"97.50\" max=\"98.10\" step=\"0.05\" value=\"97.80\">\n                <\/div>\n                <div class=\"ksd-field\">\n                    <label class=\"ksd-field-label\" for=\"ksdZ2\">Sohlh&ouml;he unten (S2) <span class=\"ksd-field-unit\" id=\"ksdZ2Txt\">97,30 m<\/span><\/label>\n                    <input class=\"ksd-range\" id=\"ksdZ2\" type=\"range\" min=\"96.90\" max=\"97.40\" step=\"0.05\" value=\"97.30\">\n                <\/div>\n            <\/div>\n            <div class=\"ksd-control-block\">\n                <div class=\"ksd-field\">\n                    <label class=\"ksd-field-label\" for=\"ksdD1\">Innendurchmesser S1 <span class=\"ksd-field-unit\" id=\"ksdD1Txt\">1000 mm<\/span><\/label>\n                    <input class=\"ksd-range\" id=\"ksdD1\" type=\"range\" min=\"800\" max=\"1500\" step=\"100\" value=\"1000\">\n                <\/div>\n                <div class=\"ksd-field\">\n                    <label class=\"ksd-field-label\" for=\"ksdD2\">Innendurchmesser S2 <span class=\"ksd-field-unit\" id=\"ksdD2Txt\">1000 mm<\/span><\/label>\n                    <input class=\"ksd-range\" id=\"ksdD2\" type=\"range\" min=\"800\" max=\"1500\" step=\"100\" value=\"1000\">\n                <\/div>\n                <div class=\"ksd-section-label\" style=\"margin-top:12px;\">Nennweite der Haltung<\/div>\n                <span class=\"ksd-seg\" id=\"ksdDN\" role=\"group\" aria-label=\"Nennweite w&auml;hlen\">\n                    <button type=\"button\" data-ksd-dn=\"200\">DN 200<\/button>\n                    <button type=\"button\" data-ksd-dn=\"300\" class=\"is-active\">DN 300<\/button>\n                    <button type=\"button\" data-ksd-dn=\"400\">DN 400<\/button>\n                <\/span>\n                <div class=\"ksd-mini-hint\" id=\"ksdDNHint\"><\/div>\n            <\/div>\n            <div class=\"ksd-control-block\">\n                <div class=\"ksd-section-label\">Zeichenrichtung der Haltung<\/div>\n                <span class=\"ksd-seg ksd-seg-col\" id=\"ksdDir\" role=\"group\" aria-label=\"Zeichenrichtung w&auml;hlen\">\n                    <button type=\"button\" data-ksd-dir=\"mit\" class=\"is-active\">mit der Flie&szlig;richtung gezeichnet<\/button>\n                    <button type=\"button\" data-ksd-dir=\"gegen\">gegen die Flie&szlig;richtung gezeichnet<\/button>\n                <\/span>\n                <div class=\"ksd-mini-hint\">Das Wasser flie&szlig;t in beiden F&auml;llen gleich, von S1 nach S2. Nur der Anfangspunkt der Haltung wandert ans andere Ende. Zwei der drei Neigungsspalten h&auml;ngen genau daran.<\/div>\n            <\/div>\n        <\/div>\n\n        <div class=\"ksd-svg-wrap\">\n            <svg id=\"ksdSvgMain\" viewBox=\"0 0 620 380\" preserveAspectRatio=\"xMidYMid meet\" role=\"img\" aria-labelledby=\"ksdSvgTitle\">\n                <title id=\"ksdSvgTitle\">Zwei Sch&auml;chte im Schnitt mit einer Haltung dazwischen, darunter die Ma&szlig;ketten f&uuml;r die verschiedenen L&auml;ngenspalten<\/title>\n                <g id=\"ksdDraw\"><\/g>\n            <\/svg>\n            <div class=\"ksd-legend\">\n                <span class=\"ksd-legend-item\" style=\"color:#e8913a;\"><span class=\"ksd-line-swatch\"><\/span> gew&auml;hlte Messstrecke<\/span>\n                <span class=\"ksd-legend-item\" style=\"color:#3f5f75;\"><span class=\"ksd-line-swatch\"><\/span> Bauwerk und Rohr<\/span>\n                <span class=\"ksd-legend-item\" style=\"color:#059669;\"><span class=\"ksd-line-swatch\"><\/span> Flie&szlig;richtung des Wassers<\/span>\n                <span class=\"ksd-legend-item\" style=\"color:#a9b7c4;\"><span class=\"ksd-line-swatch is-dash\"><\/span> &uuml;brige Ma&szlig;ketten<\/span>\n            <\/div>\n        <\/div>\n\n        <div class=\"ksd-panel\">\n            <div class=\"ksd-panel-head\">\n                <span class=\"ksd-panel-kicker\">Was misst diese Spalte?<\/span>\n                <span class=\"ksd-chip is-accent\" id=\"ksdPanelChip\">l&auml;dt<\/span>\n            <\/div>\n            <p class=\"ksd-panel-title\" id=\"ksdPanelTitle\">&#8211;<\/p>\n            <p class=\"ksd-panel-formula\" id=\"ksdPanelFormula\">&#8211;<\/p>\n            <p class=\"ksd-panel-text\" id=\"ksdPanelText\" aria-live=\"polite\"><\/p>\n            <p class=\"ksd-panel-note\" id=\"ksdPanelNote\"><\/p>\n        <\/div>\n\n        <div id=\"ksdQuiz\">\n            <div class=\"ksd-sub-title\">Kurz vorher: was sch&auml;tzt du?<\/div>\n            <div class=\"ksd-quiz\">\n                <p class=\"ksd-quiz-text\" id=\"ksdQuizText\">&#8211;<\/p>\n                <div class=\"ksd-quiz-opts\" id=\"ksdQuizOpts\"><\/div>\n            <\/div>\n        <\/div>\n\n        <div id=\"ksdTables\" hidden>\n            <div class=\"ksd-quiz-fb\" id=\"ksdQuizFb\" hidden><\/div>\n            <div class=\"ksd-sub-title\">Sechs L&auml;ngen f&uuml;r eine Haltung<\/div>\n            <div class=\"ksd-row-tools\">\n                <button type=\"button\" class=\"ksd-btn ksd-btn-ghost\" id=\"ksdAgain\">Frage erneut<\/button>\n            <\/div>\n            <div class=\"ksd-table\">\n                <div class=\"ksd-thead\">\n                    <span class=\"ksd-th-name\">Spalte in Civil 3D<\/span>\n                    <span class=\"ksd-th-val\">Wert<\/span>\n                    <span class=\"ksd-th-src\">zu finden in<\/span>\n                <\/div>\n                <div id=\"ksdLenRows\"><\/div>\n            <\/div>\n            <div class=\"ksd-mini-hint\" id=\"ksdLenHint\"><\/div>\n\n            <div class=\"ksd-sub-title\">Drei Neigungen, zwei davon rechnen in Zeichenrichtung<\/div>\n            <p class=\"ksd-quiz-text\" id=\"ksdSlopeIntro\" style=\"margin-bottom:10px;\">&#8211;<\/p>\n            <div class=\"ksd-table\">\n                <div class=\"ksd-thead\">\n                    <span class=\"ksd-th-name\">Spalte in Civil 3D<\/span>\n                    <span class=\"ksd-th-val\">Wert<\/span>\n                    <span class=\"ksd-th-sub ksd-th-src\">weitere Einheiten<\/span>\n                <\/div>\n                <div id=\"ksdSlopeRows\"><\/div>\n            <\/div>\n            <div class=\"ksd-mini-hint\" id=\"ksdSlopeHint\"><\/div>\n\n            <div class=\"ksd-tile-grid\">\n                <div class=\"ksd-tile\"><span class=\"ksd-tile-label\">Sprung durch die Bezugsart<\/span><span class=\"ksd-tile-value is-accent\" id=\"ksdTileBez\">&#8211;<\/span><\/div>\n                <div class=\"ksd-tile\"><span class=\"ksd-tile-label\">Sprung von 2D auf 3D<\/span><span class=\"ksd-tile-value\" id=\"ksdTile3D\">&#8211;<\/span><\/div>\n                <div class=\"ksd-tile\"><span class=\"ksd-tile-label\">Neigung in Flie&szlig;richtung<\/span><span class=\"ksd-tile-value\" id=\"ksdTileNeig\">&#8211;<\/span><\/div>\n            <\/div>\n            <div class=\"ksd-mini-hint\" id=\"ksdTileHint\"><\/div>\n        <\/div>\n\n        <div class=\"ksd-note\">\n            <p><strong>Welche dieser L&auml;ngen dein Leistungsverzeichnis meint, steht nicht in Civil 3D.<\/strong> Das Tool zeigt nur, welche Strecke jede Spalte misst; abgerechnet wird nach deiner Abrechnungsvorgabe.<\/p>\n            <p>Dazu kommt die Haltungsregel <strong>Kanalendposition festlegen<\/strong>. Sie bestimmt, wo Rohranfang und Rohrende sitzen, und verschiebt damit die beiden schlichten Spalten &bdquo;2D-L&auml;nge&ldquo; und &bdquo;3D-L&auml;nge&ldquo;.<\/p>\n        <\/div>\n    <\/div>\n<\/div>\n\n<script>\n    (function () {\n        \"use strict\";\n        var ROOT = document.querySelector(\"[data-ksd-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 C = {\n            primary: \"#3f5f75\",\n            primaryDark: \"#2c4a5e\",\n            primaryDeep: \"#1e3548\",\n            ink: \"#1e293b\",\n            muted: \"#64748b\",\n            faint: \"#94a3b8\",\n            pale: \"#a9b7c4\",\n            border: \"#c8d6e0\",\n            soil: \"#eef2f5\",\n            soilTick: \"#c3cfd8\",\n            wall: \"#dbe4ec\",\n            pipe: \"#e2ecf3\",\n            pipeGhost: \"#f0f4f7\",\n            accent: \"#e8913a\",\n            accentSoft: \"#fdf1da\",\n            accentDeep: \"#a25c14\",\n            good: \"#059669\",\n            warn: \"#d97706\",\n            error: \"#dc2626\"\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 line(g, x1, y1, x2, y2, attrs) {\n            g.appendChild(el(\"line\", Object.assign({ x1: x1, y1: y1, x2: x2, y2: y2 }, attrs || {})));\n        }\n        function rect(g, x, y, w, h, attrs) {\n            g.appendChild(el(\"rect\", Object.assign({ x: x, y: y, width: Math.max(0.4, w), height: Math.max(0.4, h) }, attrs || {})));\n        }\n        function text(g, x, y, content, attrs) {\n            var t = el(\"text\", Object.assign({ x: x, y: y, \"font-family\": \"inherit\" }, attrs || {}));\n            t.textContent = content;\n            g.appendChild(t);\n            return t;\n        }\n        function pathD(g, d, attrs) {\n            g.appendChild(el(\"path\", Object.assign({ d: d }, attrs || {})));\n        }\n        function labelBox(g, x, y, label, opts) {\n            opts = opts || {};\n            var fs = opts.size || 9.2;\n            var w = opts.width || Math.max(28, label.length * fs * 0.58 + 12);\n            var h = opts.height || 16;\n            rect(g, x - w \/ 2, y - h + 3, w, h, {\n                fill: opts.fill || \"#ffffff\",\n                stroke: opts.stroke || \"#d9e4ec\",\n                \"stroke-width\": 1,\n                rx: 3\n            });\n            text(g, x, y - 3, label, {\n                \"font-size\": fs,\n                fill: opts.color || C.ink,\n                \"text-anchor\": \"middle\",\n                \"font-weight\": opts.weight || 800\n            });\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        \/\/ ---------- Zahlen-Formate ----------\n        function num(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 mStr(v) { return num(v, 3) + \" m\"; }\n        function mmStr(v) { return num(v * 1000, 0) + \" mm\"; }\n        \/\/ Nennweiten ohne Tausenderpunkt, sonst liest sich DN 1000 als \"1.000\"\n        function dnStr(v) { return String(Math.round(v)) + \" mm\"; }\n        function permil(v, d) { return num(v * 1000, typeof d === \"number\" ? d : 2) + \" \u2030\"; }\n        function permilS(v) {\n            var s = v >= 0 ? \"+\" : \"\u2212\";\n            return s + num(Math.abs(v) * 1000, 2) + \" \u2030\";\n        }\n        function pctS(v) {\n            var s = v >= 0 ? \"+\" : \"\u2212\";\n            return s + num(Math.abs(v) * 100, 2) + \" %\";\n        }\n        function ratioStr(v) {\n            var a = Math.abs(v);\n            if (a < 1e-9) { return \"waagerecht\"; }\n            return \"1:\" + num(1 \/ a, 0);\n        }\n\n        \/\/ ============ MODELL ============\n        \/\/ Eine Haltung zwischen zwei Schaechten. Alle Laengen leiten sich aus\n        \/\/ elementarer Geometrie ab, keine Iteration.\n        var state = {\n            L: 40,        \/\/ Schachtmitte zu Schachtmitte, m\n            z1: 97.80,    \/\/ Sohlhoehe oben, m\n            z2: 97.30,    \/\/ Sohlhoehe unten, m\n            d1: 1000,     \/\/ Innendurchmesser S1, mm\n            d2: 1000,     \/\/ Innendurchmesser S2, mm\n            dn: 300,      \/\/ Nennweite der Haltung, mm\n            dir: \"mit\",   \/\/ Zeichenrichtung: \"mit\" oder \"gegen\" die Fliessrichtung\n            sel: \"l2dmm\",\n            answered: false,\n            picked: null\n        };\n\n        function calc() {\n            var L = state.L;\n            var d1m = state.d1 \/ 1000;\n            var d2m = state.d2 \/ 1000;\n            var abzug = (d1m + d2m) \/ 2;          \/\/ je Schacht der halbe Innendurchmesser\n            var Lin = L - abzug;\n            var dh = state.z1 - state.z2;         \/\/ Sohldifferenz, positiv = faellt zu S2\n            var dhIn = dh * (Lin \/ L);            \/\/ anteilige Hoehendifferenz auf der kurzen Strecke\n            var L3 = Math.sqrt(L * L + dh * dh);\n            var L3in = Math.sqrt(Lin * Lin + dhIn * dhIn);\n            var nFlow = dh \/ L;                   \/\/ auf die Fliessrichtung bezogen\n            var nStart = state.dir === \"mit\" ? nFlow : -nFlow;   \/\/ ab Anfangspunkt in Zeichenrichtung\n            var nEnd = -nStart;                                  \/\/ ab Endpunkt, also Gegenrichtung\n            return {\n                L: L, Lin: Lin, abzug: abzug, dh: dh, dhIn: dhIn,\n                L3: L3, L3in: L3in,\n                d1m: d1m, d2m: d2m, dnm: state.dn \/ 1000,\n                z1: state.z1, z2: state.z2,\n                nFlow: nFlow, nStart: nStart, nEnd: nEnd,\n                minGef: 1 \/ state.dn,\n                val: {\n                    l2dmm: L, l3dmm: L3, l2din: Lin, l3din: L3in, l2dobj: L, l3dobj: L3,\n                    sStart: nStart, sEnd: nEnd, sFlow: nFlow\n                }\n            };\n        }\n\n        \/\/ ---------- Zeilen-Definitionen ----------\n        var LEN_ROWS = [\n            { id: \"l2dmm\", name: \"2D-L\u00e4nge (Mitte zu Mitte)\", src: \"Kanalnetzansichten\" },\n            { id: \"l3dmm\", name: \"3D-L\u00e4nge - Mitte zu Mitte\", src: \"Kanalnetzansichten\" },\n            { id: \"l2din\", name: \"2D-L\u00e4nge - Zu Innenr\u00e4ndern\", src: \"Kanalnetzansichten\" },\n            { id: \"l3din\", name: \"3D-L\u00e4nge - Zu Innenr\u00e4ndern\", src: \"Kanalnetzansichten\" },\n            { id: \"l2dobj\", name: \"2D-L\u00e4nge\", src: \"Haltungseigenschaften\" },\n            { id: \"l3dobj\", name: \"3D-L\u00e4nge\", src: \"Haltungseigenschaften\" }\n        ];\n        var SLOPE_ROWS = [\n            { id: \"sStart\", name: \"Gef\u00e4lle in Flie\u00dfrichtung (Anfang fest)\" },\n            { id: \"sEnd\", name: \"Gef\u00e4lle gegen Flie\u00dfrichtung (Ende fest)\" },\n            { id: \"sFlow\", name: \"Neigung\" }\n        ];\n\n        \/\/ Was wird bei welcher Auswahl hervorgehoben?\n        \/\/ span: \"mm\" = Mitte zu Mitte, \"in\" = zwischen den Innenraendern\n        \/\/ chain: welche Masskette unten gehoert dazu (0 = keine)\n        \/\/ kind: \"2d\" | \"3d\" | \"slope\"\n        var SPEC = {\n            l2dmm: { span: \"mm\", chain: 1, kind: \"2d\" },\n            l3dmm: { span: \"mm\", chain: 1, kind: \"3d\" },\n            l2din: { span: \"in\", chain: 2, kind: \"2d\" },\n            l3din: { span: \"in\", chain: 2, kind: \"3d\" },\n            l2dobj: { span: \"mm\", chain: 3, kind: \"2d\" },\n            l3dobj: { span: \"mm\", chain: 3, kind: \"3d\" },\n            sStart: { span: \"mm\", chain: 0, kind: \"slope\", ref: \"start\" },\n            sEnd: { span: \"mm\", chain: 0, kind: \"slope\", ref: \"end\" },\n            sFlow: { span: \"mm\", chain: 0, kind: \"slope\", ref: \"flow\" }\n        };\n\n        \/\/ ============ SVG-KOORDINATEN ============\n        var XC1 = 112, XC2 = 536;          \/\/ Schachtmitten in Pixeln, fest\n        var Z_TOP = 100.80, Z_BOT = 96.60; \/\/ dargestellter Hoehenbereich\n        var Y_TOP_PX = 64, Y_SPAN_PX = 150;\n        var VS = Y_SPAN_PX \/ (Z_TOP - Z_BOT);   \/\/ Pixel je Hoehenmeter\n        var DECKEL = 100.50;\n        var YD1 = 250, YD2 = 290, YD3 = 330;    \/\/ die drei Masskettenzeilen\n        var Y_SEC_BOT = 222;\n        function yz(z) { return Y_TOP_PX + (Z_TOP - z) * VS; }\n\n        function arrow(g, x1, y1, x2, y2, col, w) {\n            line(g, x1, y1, x2, y2, { stroke: col, \"stroke-width\": w, \"stroke-linecap\": \"round\" });\n            var a = Math.atan2(y2 - y1, x2 - x1);\n            var s = 6 + w;\n            var p1x = x2 - s * Math.cos(a - 0.42), p1y = y2 - s * Math.sin(a - 0.42);\n            var p2x = x2 - s * Math.cos(a + 0.42), p2y = y2 - s * Math.sin(a + 0.42);\n            pathD(g, \"M \" + x2.toFixed(1) + \" \" + y2.toFixed(1) + \" L \" + p1x.toFixed(1) + \" \" + p1y.toFixed(1) + \" L \" + p2x.toFixed(1) + \" \" + p2y.toFixed(1) + \" Z\", { fill: col });\n        }\n\n        \/\/ Eine Masskette: Linie mit Endpfeilen, Name darueber, Wert darunter.\n        \/\/ Vor der Vorhersagefrage wird val als leerer String uebergeben, dann steht\n        \/\/ nur die Bezeichnung mittig auf der Masslinie und die Zahl bleibt verdeckt.\n        function chain(g, xA, xB, y, name, val, mode) {\n            var on = mode === \"on\";\n            var mid = mode === \"mid\";\n            var showVal = typeof val === \"string\" ? val.length > 0 : false;\n            var col = on ? C.accent : (mid ? C.primary : C.pale);\n            var wid = on ? 2.2 : (mid ? 1.6 : 1.1);\n            var op = on ? 1 : (mid ? 0.85 : 0.45);\n            var dash = on ? \"none\" : (mid ? \"none\" : \"5 4\");\n            \/\/ Hilfslinien von der Zeichnung herunter\n            line(g, xA, Y_SEC_BOT + 2, xA, y + 7, { stroke: col, \"stroke-width\": 1, \"stroke-dasharray\": \"3 3\", opacity: op * 0.8 });\n            line(g, xB, Y_SEC_BOT + 2, xB, y + 7, { stroke: col, \"stroke-width\": 1, \"stroke-dasharray\": \"3 3\", opacity: op * 0.8 });\n            \/\/ Masslinie\n            line(g, xA, y, xB, y, { stroke: col, \"stroke-width\": wid, \"stroke-dasharray\": dash, opacity: op });\n            line(g, xA, y - 6, xA, y + 6, { stroke: col, \"stroke-width\": wid, opacity: op });\n            line(g, xB, y - 6, xB, y + 6, { stroke: col, \"stroke-width\": wid, opacity: op });\n            arrow(g, xA + 22, y, xA + 2, y, col, wid);\n            arrow(g, xB - 22, y, xB - 2, y, col, wid);\n            \/\/ Text mit weisser Unterlage, damit die Masslinie den Text nicht kreuzt\n            var mx = (xA + xB) \/ 2;\n            var fsN = on ? 9.6 : 8.8;\n            var wName = name.length * fsN * 0.56;\n            var wVal = showVal ? val.length * 11 * 0.62 : 0;\n            var w = Math.max(wName, wVal) + 16;\n            \/\/ Ohne Wert schrumpft die Unterlage auf eine Zeile, sonst klafft eine\n            \/\/ weisse Luecke unter der Bezeichnung.\n            rect(g, mx - w \/ 2, showVal ? y - 13 : y - 9, w, showVal ? 28 : 18, { fill: \"#ffffff\", stroke: \"none\" });\n            text(g, mx, showVal ? y - 2 : y + 3.2, name, {\n                \"font-size\": fsN,\n                fill: on ? C.accentDeep : (mid ? C.primaryDeep : C.muted),\n                \"text-anchor\": \"middle\",\n                \"font-weight\": on ? 800 : 700,\n                opacity: on ? 1 : (mid ? 0.95 : 0.75)\n            });\n            if (showVal) {\n                text(g, mx, y + 12, val, {\n                    \"font-size\": on ? 11 : 9.6,\n                    fill: on ? C.accentDeep : (mid ? C.primaryDeep : C.faint),\n                    \"text-anchor\": \"middle\",\n                    \"font-weight\": 800,\n                    opacity: on ? 1 : (mid ? 0.95 : 0.7)\n                });\n            }\n        }\n\n        function renderScene(m) {\n            var g = $(\"ksdDraw\");\n            clear(g);\n            var spec = SPEC[state.sel];\n            var sx = (XC2 - XC1) \/ m.L;                 \/\/ Pixel je Meter, waagerecht\n            var xI1 = XC1 + (m.d1m \/ 2) * sx;\n            var xI2 = XC2 - (m.d2m \/ 2) * sx;\n            var wpx = Math.max(1.2, 0.15 * sx);         \/\/ Schachtwand, 15 cm\n            var r1 = (m.d1m \/ 2) * sx, r2 = (m.d2m \/ 2) * sx;\n            var za1 = m.z1 + m.dnm \/ 2, za2 = m.z2 + m.dnm \/ 2;   \/\/ Rohrachse\n            var yA1 = yz(za1), yA2 = yz(za2);\n            var xSpanA = spec.span === \"in\" ? xI1 : XC1;\n            var xSpanB = spec.span === \"in\" ? xI2 : XC2;\n            function zAxisAtX(x) { return za1 + (za2 - za1) * (x - XC1) \/ (XC2 - XC1); }\n\n            \/\/ Rahmen und Titel\n            rect(g, 8, 8, 604, 364, { fill: \"#ffffff\", stroke: \"#d9e4ec\", \"stroke-width\": 1.2, rx: 4 });\n            text(g, 22, 27, \"DIESELBE HALTUNG, VERSCHIEDENE MESSSTRECKEN\", {\n                \"font-size\": 10, fill: C.muted, \"font-weight\": 800, \"letter-spacing\": \"0.06em\"\n            });\n            var ueb = VS \/ sx;\n            text(g, 598, 27, \"H\u00f6hen \" + num(ueb, 1) + \"-fach \u00fcberh\u00f6ht\", {\n                \"font-size\": 8.4, fill: C.faint, \"text-anchor\": \"end\", \"font-style\": \"italic\"\n            });\n\n            \/\/ Erdreich und Gelaende\n            var yD = yz(DECKEL);\n            rect(g, 16, yD, 588, Y_SEC_BOT - yD, { fill: C.soil, stroke: \"none\" });\n            line(g, 16, yD, 604, yD, { stroke: C.primary, \"stroke-width\": 2, \"stroke-linecap\": \"round\" });\n            var tx;\n            for (tx = 26; tx < 600; tx += 26) {\n                line(g, tx, yD + 2, tx - 6, yD + 9, { stroke: C.soilTick, \"stroke-width\": 1 });\n            }\n\n            \/\/ Schaechte (Rechtecke mit erkennbarer Wandstaerke)\n            function shaft(xc, rr, zSohle, label, role) {\n                var yTop = yz(DECKEL);\n                var yBot = yz(zSohle - 0.25);\n                rect(g, xc - rr - wpx, yTop, (rr + wpx) * 2, yBot - yTop, { fill: C.wall, stroke: C.primary, \"stroke-width\": 1.3, rx: 1.5 });\n                rect(g, xc - rr, yTop + 1, rr * 2, yBot - yTop - 1 - wpx, { fill: \"#ffffff\", stroke: \"none\" });\n                line(g, xc - rr - wpx - 4, yTop, xc + rr + wpx + 4, yTop, { stroke: C.primaryDeep, \"stroke-width\": 3, \"stroke-linecap\": \"round\" });\n                labelBox(g, xc, yTop - 8, label, { width: 28, size: 9, color: C.primaryDeep });\n                var isRef = spec.kind === \"slope\" ? role === spec.ref : false;\n                labelBox(g, xc, yTop - 26, role === \"start\" ? \"Anfang\" : \"Ende\", {\n                    width: 46, size: 8,\n                    fill: isRef ? C.accentSoft : \"#ffffff\",\n                    stroke: isRef ? C.accent : \"#d9e4ec\",\n                    color: isRef ? C.accentDeep : C.muted\n                });\n            }\n            var role1 = state.dir === \"mit\" ? \"start\" : \"end\";\n            var role2 = state.dir === \"mit\" ? \"end\" : \"start\";\n            shaft(XC1, r1, m.z1, \"S1\", role1);\n            shaft(XC2, r2, m.z2, \"S2\", role2);\n\n            \/\/ Haltung: Vollteil zwischen den Innenraendern, blasse Stummel bis zur Schachtmitte\n            function pipeSeg(xa, xb, solid) {\n                var zS = function (x) { return m.z1 + (m.z2 - m.z1) * (x - XC1) \/ (XC2 - XC1); };\n                var pts = [\n                    [xa, yz(zS(xa))], [xb, yz(zS(xb))],\n                    [xb, yz(zS(xb) + m.dnm)], [xa, yz(zS(xa) + m.dnm)]\n                ];\n                var d = \"M \" + pts.map(function (p) { return p[0].toFixed(1) + \" \" + p[1].toFixed(1); }).join(\" L \") + \" Z\";\n                pathD(g, d, {\n                    fill: solid ? C.pipe : C.pipeGhost,\n                    stroke: solid ? C.primary : C.faint,\n                    \"stroke-width\": solid ? 1.6 : 1,\n                    \"stroke-dasharray\": solid ? \"none\" : \"4 3\"\n                });\n            }\n            pipeSeg(xI1, xI2, true);\n            pipeSeg(XC1, xI1, false);\n            pipeSeg(xI2, XC2, false);\n            \/\/ Rohrachse, die Bezugslinie der 3D-Laengen\n            line(g, XC1, yA1, XC2, yA2, { stroke: C.muted, \"stroke-width\": 1, \"stroke-dasharray\": \"7 3 2 3\", opacity: 0.8 });\n\n            \/\/ Sohlhoehen beschriften\n            text(g, XC1 - r1 - wpx - 8, yz(m.z1) + 3, \"Sohle \" + num(m.z1, 2), {\n                \"font-size\": 8.4, fill: C.primaryDeep, \"text-anchor\": \"end\", \"font-weight\": 700\n            });\n            text(g, XC2 + r2 + wpx + 8, yz(m.z2) + 3, \"Sohle \" + num(m.z2, 2), {\n                \"font-size\": 8.4, fill: C.primaryDeep, \"font-weight\": 700\n            });\n\n            \/\/ Zeichenrichtung im Erdreich, Fliessrichtung direkt ueber dem Rohr\n            var zdY = 104;\n            var zdCol = state.dir === \"mit\" ? C.primary : C.accent;\n            if (state.dir === \"mit\") {\n                arrow(g, XC1 + 70, zdY, XC2 - 70, zdY, zdCol, 1.8);\n            } else {\n                arrow(g, XC2 - 70, zdY, XC1 + 70, zdY, zdCol, 1.8);\n            }\n            labelBox(g, (XC1 + XC2) \/ 2, zdY - 8, \"Zeichenrichtung: Anfang \u2192 Ende\", {\n                width: 176, size: 8.4,\n                fill: state.dir === \"mit\" ? \"#ffffff\" : C.accentSoft,\n                stroke: state.dir === \"mit\" ? \"#d9e4ec\" : C.accent,\n                color: state.dir === \"mit\" ? C.muted : C.accentDeep\n            });\n\n            \/\/ Ueber der hoechsten Achslage, damit der Pfeil weder das Rohr noch die\n            \/\/ waagerechte Kathete des Steigungsdreiecks kreuzt.\n            var yFlow = yz(za1) - 22;\n            var flowCol = spec.ref === \"flow\" ? C.accent : C.good;\n            arrow(g, (XC1 + XC2) \/ 2 - 34, yFlow, (XC1 + XC2) \/ 2 + 34, yFlow, flowCol, 2);\n            labelBox(g, (XC1 + XC2) \/ 2 - 108, yFlow + 4, \"Flie\u00dfrichtung\", {\n                width: 76, size: 8.4,\n                fill: spec.ref === \"flow\" ? C.accentSoft : \"#ffffff\",\n                stroke: spec.ref === \"flow\" ? C.accent : \"#d9e4ec\",\n                color: spec.ref === \"flow\" ? C.accentDeep : C.muted\n            });\n\n            \/\/ Hervorhebung je nach gewaehlter Spalte\n            if (spec.kind === \"2d\") {\n                \/\/ Senkrechte Marken an den beiden Messpunkten\n                [xSpanA, xSpanB].forEach(function (x) {\n                    line(g, x, yz(DECKEL) + 6, x, Y_SEC_BOT - 4, { stroke: C.accent, \"stroke-width\": 2, \"stroke-dasharray\": \"5 4\" });\n                });\n                if (spec.chain === 3) {\n                    [[XC1, yA1], [XC2, yA2]].forEach(function (p) {\n                        rect(g, p[0] - 4, p[1] - 4, 8, 8, { fill: C.accent, stroke: \"#ffffff\", \"stroke-width\": 1.4, rx: 1 });\n                    });\n                    line(g, XC1 + 4, yA1 - 4, XC1 + 40, yA1 - 34, { stroke: C.accent, \"stroke-width\": 1, \"stroke-dasharray\": \"3 2\" });\n                    labelBox(g, XC1 + 74, yA1 - 34, \"Rohranfang\", { width: 68, size: 8, fill: C.accentSoft, stroke: C.accent, color: C.accentDeep });\n                    line(g, XC2 - 4, yA2 + 4, XC2 - 40, yA2 + 26, { stroke: C.accent, \"stroke-width\": 1, \"stroke-dasharray\": \"3 2\" });\n                    labelBox(g, XC2 - 70, yA2 + 32, \"Rohrende\", { width: 60, size: 8, fill: C.accentSoft, stroke: C.accent, color: C.accentDeep });\n                }\n            }\n            if (spec.kind !== \"2d\") {\n                \/\/ Steigungsdreieck: waagerechte Kathete, senkrechte Kathete, Achse als Hypotenuse\n                var zA = zAxisAtX(xSpanA), zB = zAxisAtX(xSpanB);\n                var yAa = yz(zA), yBb = yz(zB);\n                line(g, xSpanA, yAa, xSpanB, yAa, { stroke: C.faint, \"stroke-width\": 1.2, \"stroke-dasharray\": \"5 4\" });\n                line(g, xSpanB, yAa, xSpanB, yBb, { stroke: C.accent, \"stroke-width\": 2 });\n                line(g, xSpanB - 5, yAa, xSpanB + 5, yAa, { stroke: C.accent, \"stroke-width\": 2 });\n                line(g, xSpanB - 5, yBb, xSpanB + 5, yBb, { stroke: C.accent, \"stroke-width\": 2 });\n                line(g, xSpanA, yAa, xSpanB, yBb, { stroke: C.accent, \"stroke-width\": 3, \"stroke-linecap\": \"round\" });\n                var dhShown = spec.span === \"in\" ? m.dhIn : m.dh;\n                labelBox(g, xSpanB - 46, yAa - 6, \"\u0394h \" + num(dhShown, 3) + \" m\", {\n                    width: 78, size: 8.4, fill: C.accentSoft, stroke: C.accent, color: C.accentDeep\n                });\n                line(g, xSpanB - 8, yAa - 9, xSpanB - 1, (yAa + yBb) \/ 2, { stroke: C.accent, \"stroke-width\": 1, \"stroke-dasharray\": \"3 2\" });\n                if (spec.kind === \"slope\") {\n                    \/\/ Bezugspunkt und Messrichtung folgen der Zeichenrichtung:\n                    \/\/ Bei \"gegen\" liegt der Anfang der Haltung rechts, nicht links.\n                    var startLinks = state.dir === \"mit\";\n                    var refLinks = true;\n                    if (spec.ref === \"start\") { refLinks = startLinks; }\n                    if (spec.ref === \"end\") { refLinks = !startLinks; }\n                    \/\/ Messpfeil unter dem Rohr, damit er das Delta-h-Schild nicht kreuzt\n                    var mA = xSpanA + 40, mB = xSpanB - 40;\n                    var yMa = yz(zAxisAtX(mA)) + 26, yMb = yz(zAxisAtX(mB)) + 26;\n                    if (refLinks) {\n                        arrow(g, mA, yMa, mB, yMb, C.accent, 2);\n                    } else {\n                        arrow(g, mB, yMb, mA, yMa, C.accent, 2);\n                    }\n                    var refX = refLinks ? xSpanA : xSpanB;\n                    var refY = yz(zAxisAtX(refX));\n                    g.appendChild(el(\"circle\", { cx: refX, cy: refY, r: 5, fill: \"#ffffff\", stroke: C.accent, \"stroke-width\": 2.6 }));\n                }\n            }\n\n            \/\/ Masskettenzeilen. Solange die Vorhersagefrage offen ist, zeigen sie nur\n            \/\/ ihre Bezeichnung, damit die Zahl nicht schon ueber der Frage steht.\n            var mm1 = spec.chain === 1 ? (spec.kind === \"3d\" ? \"mid\" : \"on\") : \"off\";\n            var mm2 = spec.chain === 2 ? (spec.kind === \"3d\" ? \"mid\" : \"on\") : \"off\";\n            var mm3 = spec.chain === 3 ? (spec.kind === \"3d\" ? \"mid\" : \"on\") : \"off\";\n            var zeigeWert = state.answered;\n            chain(g, XC1, XC2, YD1, \"Mitte zu Mitte\", zeigeWert ? mStr(m.L) : \"\", mm1);\n            chain(g, xI1, xI2, YD2, \"Zu Innenr\u00e4ndern\", zeigeWert ? mStr(m.Lin) : \"\", mm2);\n            chain(g, XC1, XC2, YD3, \"Rohranfang bis Rohrende (ohne Regel)\", zeigeWert ? mStr(m.L) : \"\", mm3);\n            if (!zeigeWert) {\n                text(g, (XC1 + XC2) \/ 2, 358, \"Die Zahlen zu diesen Ma\u00dfketten erscheinen, sobald du unten gesch\u00e4tzt hast.\", {\n                    \"font-size\": 8.6, fill: C.faint, \"text-anchor\": \"middle\", \"font-style\": \"italic\"\n                });\n            }\n\n            \/\/ Abzugsstummel an der Innenrand-Kette sichtbar machen\n            if (spec.span === \"in\") {\n                [[XC1, xI1], [xI2, XC2]].forEach(function (p) {\n                    line(g, p[0], YD2, p[1], YD2, { stroke: C.accent, \"stroke-width\": 3.4, \"stroke-linecap\": \"butt\" });\n                });\n                text(g, XC1 - 14, YD2 + 3, \"je Schacht-D\/2 ab\", { \"font-size\": 8.4, fill: C.accentDeep, \"text-anchor\": \"end\", \"font-weight\": 800 });\n                line(g, XC1 - 12, YD2, XC1 - 2, YD2, { stroke: C.accent, \"stroke-width\": 1, \"stroke-dasharray\": \"3 2\" });\n            }\n        }\n\n        \/\/ ============ ERKLAER-PANEL ============\n        function explain(m) {\n            var id = state.sel;\n            var gegen = state.dir === \"gegen\";\n            if (id === \"l2dmm\") {\n                return {\n                    chip: mStr(m.L),\n                    title: \"\u201e2D-L\u00e4nge (Mitte zu Mitte)\u201c\",\n                    formula: \"L = \" + mStr(m.L),\n                    text: \"Der waagerechte Abstand von Schachtmitte zu Schachtmitte. Die Bauwerke selbst spielen dabei keine Rolle, das ist die reine Grundrissl\u00e4nge der Haltungsachse.\",\n                    note: \"Dieselbe Zahl bekommst du, wenn du im Lageplan von Schachtpunkt zu Schachtpunkt misst.\"\n                };\n            }\n            if (id === \"l3dmm\") {\n                return {\n                    chip: mStr(m.L3),\n                    title: \"\u201e3D-L\u00e4nge - Mitte zu Mitte\u201c\",\n                    formula: \"\u221a(\" + num(m.L, 3) + \"\u00b2 + \" + num(m.dh, 3) + \"\u00b2) = \" + mStr(m.L3),\n                    text: \"Dieselbe Strecke, aber schr\u00e4g gemessen: die Rohrachse von Mitte zu Mitte, samt H\u00f6henunterschied. Pythagoras aus der 2D-L\u00e4nge und der Sohldifferenz.\",\n                    note: \"Bei \u00fcblichem Kanalgef\u00e4lle bringt der H\u00f6henunterschied fast nichts, hier \" + mmStr(m.L3 - m.L) + \" mehr als die 2D-L\u00e4nge. Die H\u00f6hen sind in der Zeichnung \u00fcberh\u00f6ht, deshalb sieht der Unterschied dort gr\u00f6\u00dfer aus, als er rechnerisch ist.\"\n                };\n            }\n            if (id === \"l2din\") {\n                return {\n                    chip: mStr(m.Lin),\n                    title: \"\u201e2D-L\u00e4nge - Zu Innenr\u00e4ndern\u201c\",\n                    formula: num(m.L, 3) + \" \u2212 (\" + num(m.d1m, 3) + \" + \" + num(m.d2m, 3) + \") \/ 2 = \" + mStr(m.Lin),\n                    text: \"Waagerecht, aber erst ab der Schachtinnenwand. Von jeder Schachtmitte geht der halbe Schacht-Innendurchmesser ab, zusammen also \" + mStr(m.abzug) + \".\",\n                    note: \"Das ist die Strecke, die frei zwischen den beiden Bauwerken liegt. Gegen\u00fcber Mitte zu Mitte fehlen \" + mStr(m.L - m.Lin) + \" je Haltung.\"\n                };\n            }\n            if (id === \"l3din\") {\n                return {\n                    chip: mStr(m.L3in),\n                    title: \"\u201e3D-L\u00e4nge - Zu Innenr\u00e4ndern\u201c\",\n                    formula: \"\u221a(\" + num(m.Lin, 3) + \"\u00b2 + \" + num(m.dhIn, 3) + \"\u00b2) = \" + mStr(m.L3in),\n                    text: \"Die kurze Strecke, schr\u00e4g gemessen. Weil die Strecke innerhalb der Schachtw\u00e4nde endet, z\u00e4hlt auch nur der anteilige H\u00f6henunterschied von \" + num(m.dhIn, 3) + \" m mit.\",\n                    note: \"Zur 2D-Variante derselben Bezugsart sind es \" + mmStr(m.L3in - m.Lin) + \" Unterschied, zur Mitte-zu-Mitte-Welt dagegen \" + mStr(m.L3 - m.L3in) + \".\"\n                };\n            }\n            if (id === \"l2dobj\") {\n                return {\n                    chip: mStr(m.L),\n                    title: \"\u201e2D-L\u00e4nge\u201c in den Haltungseigenschaften\",\n                    formula: \"ohne Regel: Anfang und Ende in Schachtmitte \u2192 \" + mStr(m.L),\n                    text: \"Die Objektl\u00e4nge im Grundriss, laut Hilfe gemessen ab dem Beginn der Haltung bis zum Ende der Haltung. Wo diese beiden Punkte sitzen, entscheidet die Haltungsregel Kanalendposition festlegen.\",\n                    note: \"Ohne diese Regel sitzen Anfang und Ende in der Schachtmitte, dann liegt der Wert praktisch auf Mitte zu Mitte. Genau dieser Zustand ist oben gezeichnet. Sobald die Regel die Rohrenden verschiebt, wandert diese Spalte mit, die vier anderen nicht.\"\n                };\n            }\n            if (id === \"l3dobj\") {\n                return {\n                    chip: mStr(m.L3),\n                    title: \"\u201e3D-L\u00e4nge\u201c in den Haltungseigenschaften\",\n                    formula: \"\u221a(\" + num(m.L, 3) + \"\u00b2 + \" + num(m.dh, 3) + \"\u00b2) = \" + mStr(m.L3),\n                    text: \"Dieselbe Objektl\u00e4nge, schr\u00e4g gemessen. Sie h\u00e4ngt an denselben beiden Punkten wie die 2D-L\u00e4nge und damit an derselben Regel.\",\n                    note: \"Diese beiden schlichten Felder stehen in den Haltungseigenschaften unter Komponenteneigenschaften, Gruppe Geometrie. Ob dein Panorama sie zus\u00e4tzlich als Spalte anbietet, pr\u00fcfst du in der Spaltenauswahl.\"\n                };\n            }\n            if (id === \"sStart\") {\n                return {\n                    chip: permilS(m.nStart),\n                    title: \"\u201eGef\u00e4lle in Flie\u00dfrichtung (Anfang fest)\u201c\",\n                    formula: permilS(m.nStart) + \"  \u00b7  \" + pctS(m.nStart) + \"  \u00b7  \" + ratioStr(m.nStart),\n                    text: \"Gerechnet wird ab dem Anfangspunkt der Haltung, also ab der Stelle, an der du beim Zeichnen begonnen hast. Die Hilfe schreibt dazu ausdr\u00fccklich: Die Flussrichtung wird nicht ber\u00fccksichtigt.\",\n                    note: gegen\n                        ? \"Diese Haltung ist gegen die Flie\u00dfrichtung gezeichnet. Vom Anfangspunkt aus steigt sie, deshalb steht hier das Vorzeichen, das du nicht erwartest, obwohl das Wasser v\u00f6llig normal von S1 nach S2 l\u00e4uft.\"\n                        : \"Diese Haltung ist mit der Flie\u00dfrichtung gezeichnet, deshalb passt das Vorzeichen hier zuf\u00e4llig zum Wasser. Schalte oben die Zeichenrichtung um, dann kippt es.\"\n                };\n            }\n            if (id === \"sEnd\") {\n                return {\n                    chip: permilS(m.nEnd),\n                    title: \"\u201eGef\u00e4lle gegen Flie\u00dfrichtung (Ende fest)\u201c\",\n                    formula: permilS(m.nEnd) + \"  \u00b7  \" + pctS(m.nEnd) + \"  \u00b7  \" + ratioStr(m.nEnd),\n                    text: \"Dasselbe von der anderen Seite: Bezugspunkt ist das Ende der Haltung, gerechnet wird in die Gegenrichtung. Auch hier bleibt die Flussrichtung laut Hilfe au\u00dfen vor.\",\n                    note: \"Der Wert kippt also mit der Zeichenrichtung, nicht mit dem Wasser. Der Zusatz in Klammern deutet zugleich auf den Punkt, der beim \u00c4ndern des Wertes stehen bleibt. Probiere das einmal an einer Testhaltung aus, dann wei\u00dft du f\u00fcr dein Projekt, wie herum es steht.\"\n                };\n            }\n            return {\n                chip: permilS(m.nFlow),\n                title: \"\u201eNeigung\u201c\",\n                formula: permilS(m.nFlow) + \"  \u00b7  \" + pctS(m.nFlow) + \"  \u00b7  \" + ratioStr(m.nFlow),\n                text: \"Die einzige der drei Angaben, die sich auf die Flie\u00dfrichtung bezieht. Sie bleibt gleich, egal in welcher Richtung die Haltung gezeichnet ist.\",\n                note: \"Wenn du eine Zahl brauchst, die zum Wasser passt, ist das diese. Schalte oben die Zeichenrichtung um: Die beiden Werte dar\u00fcber kippen, dieser bleibt stehen.\"\n            };\n        }\n\n        function renderPanel(m) {\n            var e = explain(m);\n            $(\"ksdPanelChip\").textContent = e.chip;\n            $(\"ksdPanelTitle\").textContent = e.title;\n            $(\"ksdPanelFormula\").textContent = e.formula;\n            $(\"ksdPanelText\").textContent = e.text;\n            $(\"ksdPanelNote\").textContent = e.note;\n        }\n\n        \/\/ ============ TABELLEN ============\n        var rowRefs = {};\n        function buildRows() {\n            var lenWrap = $(\"ksdLenRows\");\n            clear(lenWrap);\n            LEN_ROWS.forEach(function (r) {\n                var b = document.createElement(\"button\");\n                b.type = \"button\";\n                b.className = \"ksd-row\";\n                b.setAttribute(\"data-ksd-sel\", r.id);\n                var n = document.createElement(\"span\");\n                n.className = \"ksd-row-name\";\n                n.textContent = \"\u201e\" + r.name + \"\u201c\";\n                var v = document.createElement(\"span\");\n                v.className = \"ksd-row-val\";\n                var s = document.createElement(\"span\");\n                s.className = \"ksd-row-src\";\n                s.textContent = r.src;\n                b.appendChild(n);\n                b.appendChild(v);\n                b.appendChild(s);\n                lenWrap.appendChild(b);\n                rowRefs[r.id] = { btn: b, val: v, sub: null };\n            });\n            var slopeWrap = $(\"ksdSlopeRows\");\n            clear(slopeWrap);\n            SLOPE_ROWS.forEach(function (r) {\n                var b = document.createElement(\"button\");\n                b.type = \"button\";\n                b.className = \"ksd-row\";\n                b.setAttribute(\"data-ksd-sel\", r.id);\n                var n = document.createElement(\"span\");\n                n.className = \"ksd-row-name\";\n                n.textContent = \"\u201e\" + r.name + \"\u201c\";\n                var v = document.createElement(\"span\");\n                v.className = \"ksd-row-val\";\n                var sub = document.createElement(\"span\");\n                sub.className = \"ksd-row-sub\";\n                var chip = document.createElement(\"span\");\n                chip.className = \"ksd-chip\";\n                b.appendChild(n);\n                b.appendChild(v);\n                b.appendChild(sub);\n                b.appendChild(chip);\n                slopeWrap.appendChild(b);\n                rowRefs[r.id] = { btn: b, val: v, sub: sub, chip: chip };\n            });\n        }\n\n        function renderRows(m) {\n            LEN_ROWS.forEach(function (r) {\n                var ref = rowRefs[r.id];\n                ref.val.textContent = mStr(m.val[r.id]);\n                ref.btn.classList.toggle(\"is-active\", state.sel === r.id);\n                ref.btn.setAttribute(\"aria-pressed\", state.sel === r.id ? \"true\" : \"false\");\n            });\n            SLOPE_ROWS.forEach(function (r) {\n                var ref = rowRefs[r.id];\n                var v = m.val[r.id];\n                ref.val.textContent = permilS(v);\n                ref.sub.textContent = pctS(v) + \"  \u00b7  \" + ratioStr(v);\n                ref.btn.classList.toggle(\"is-active\", state.sel === r.id);\n                ref.btn.setAttribute(\"aria-pressed\", state.sel === r.id ? \"true\" : \"false\");\n                if (r.id === \"sFlow\") {\n                    ref.chip.className = \"ksd-chip is-good\";\n                    ref.chip.textContent = \"Bezug Flie\u00dfrichtung\";\n                } else if (state.dir === \"gegen\") {\n                    ref.chip.className = \"ksd-chip is-warn\";\n                    ref.chip.textContent = \"Bezug Zeichenrichtung, kippt\";\n                } else {\n                    ref.chip.className = \"ksd-chip\";\n                    ref.chip.textContent = \"Bezug Zeichenrichtung\";\n                }\n            });\n        }\n\n        \/\/ ============ VORHERSAGEFRAGE ============\n        var LSKEY = \"cadk_ksd_frage_v1\";\n        function loadAnswered() {\n            try {\n                var ls = window.localStorage;\n                return ls ? ls.getItem(LSKEY) === \"1\" : false;\n            } catch (err) { return false; }\n        }\n        function saveAnswered(on) {\n            try {\n                var ls = window.localStorage;\n                if (!ls) { return; }\n                if (on) { ls.setItem(LSKEY, \"1\"); } else { ls.removeItem(LSKEY); }\n            } catch (err) { return; }\n        }\n\n        function buildQuiz(m) {\n            var wrap = $(\"ksdQuizOpts\");\n            clear(wrap);\n            var dText = state.d1 === state.d2\n                ? \"beide Sch\u00e4chte haben \" + dnStr(state.d1) + \" Innendurchmesser\"\n                : \"die Sch\u00e4chte haben \" + dnStr(state.d1) + \" und \" + dnStr(state.d2) + \" Innendurchmesser\";\n            $(\"ksdQuizText\").textContent = \"Zwischen S1 und S2 liegen \" + num(m.L, 0)\n                + \" m von Schachtmitte zu Schachtmitte, \" + dText\n                + \". Wie weit liegen die Spalten \u201eMitte zu Mitte\u201c und \u201eZu Innenr\u00e4ndern\u201c auseinander?\";\n            var diff = m.L - m.Lin;\n            var opts = [\n                { id: \"a\", label: \"Ein paar Millimeter, das f\u00e4llt nicht ins Gewicht.\" },\n                { id: \"b\", label: \"Rund \" + mStr(diff) + \" je Haltung.\" },\n                { id: \"c\", label: \"Rund \" + mStr(diff * 2) + \" je Haltung.\" }\n            ];\n            opts.forEach(function (o) {\n                var b = document.createElement(\"button\");\n                b.type = \"button\";\n                b.className = \"ksd-opt\";\n                b.setAttribute(\"data-ksd-opt\", o.id);\n                b.textContent = o.label;\n                wrap.appendChild(b);\n            });\n        }\n\n        function answerQuiz(pick, m) {\n            var diff = m.L - m.Lin;\n            var fb = $(\"ksdQuizFb\");\n            fb.hidden = false;\n            if (pick === \"b\") {\n                fb.className = \"ksd-quiz-fb\";\n                fb.textContent = \"Richtig. Von jeder Schachtmitte geht der halbe Schacht-Innendurchmesser ab, zusammen \"\n                    + mStr(diff) + \". Auf 20 Haltungen sind das \" + mStr(diff * 20) + \".\";\n            } else if (pick === \"a\") {\n                fb.className = \"ksd-quiz-fb is-off\";\n                fb.textContent = \"Das ist der Unterschied zwischen 2D und 3D, hier gerade \" + mmStr(m.L3 - m.L)\n                    + \". Zwischen Mitte zu Mitte und Zu Innenr\u00e4ndern liegen dagegen \" + mStr(diff) + \" je Haltung.\";\n            } else {\n                fb.className = \"ksd-quiz-fb is-off\";\n                fb.textContent = \"Das w\u00e4re der volle Innendurchmesser beider Sch\u00e4chte. Abgezogen wird aber nur der halbe je Schacht, zusammen \"\n                    + mStr(diff) + \" je Haltung.\";\n            }\n            ROOT.querySelectorAll(\"[data-ksd-opt]\").forEach(function (b) {\n                b.disabled = true;\n                b.classList.toggle(\"is-active\", b.getAttribute(\"data-ksd-opt\") === pick);\n            });\n            state.answered = true;\n            state.picked = pick;\n            state.sel = \"l2din\";\n            saveAnswered(true);\n            $(\"ksdTables\").hidden = false;\n        }\n\n        function resetQuiz() {\n            state.answered = false;\n            state.picked = null;\n            \/\/ Zurueck auf die neutrale Auswahl, sonst stuende im Erklaerpanel die\n            \/\/ Zahl der Innenrand-Spalte ueber der gerade erneut gestellten Frage.\n            state.sel = \"l2dmm\";\n            saveAnswered(false);\n            $(\"ksdQuiz\").hidden = false;\n            $(\"ksdQuizFb\").hidden = true;\n            $(\"ksdTables\").hidden = true;\n            renderAll();\n        }\n\n        \/\/ ============ HAUPT-RENDER ============\n        function renderAll() {\n            var m = calc();\n\n            $(\"ksdLTxt\").textContent = num(m.L, 0) + \" m\";\n            $(\"ksdZ1Txt\").textContent = num(m.z1, 2) + \" m\";\n            $(\"ksdZ2Txt\").textContent = num(m.z2, 2) + \" m\";\n            $(\"ksdD1Txt\").textContent = dnStr(state.d1);\n            $(\"ksdD2Txt\").textContent = dnStr(state.d2);\n            syncSeg(\"ksdDN\", \"data-ksd-dn\", String(state.dn));\n            syncSeg(\"ksdDir\", \"data-ksd-dir\", state.dir);\n            $(\"ksdDNHint\").textContent = \"DN \" + state.dn\n                + \" \u00e4ndert die L\u00e4ngen hier nicht, weil beide Rohrenden dieselbe Nennweite haben. Es \u00e4ndert nur, wie dick die Haltung liegt und ab wann das Mindestgef\u00e4lle 1:DN (\"\n                + permil(m.minGef) + \") unterschritten ist.\";\n\n            renderScene(m);\n            renderPanel(m);\n\n            if (state.answered) {\n                $(\"ksdQuiz\").hidden = true;\n                $(\"ksdTables\").hidden = false;\n            } else {\n                $(\"ksdQuiz\").hidden = false;\n                $(\"ksdTables\").hidden = true;\n                buildQuiz(m);\n            }\n\n            renderRows(m);\n\n            $(\"ksdLenHint\").textContent = \"Dazu kommt \u201eSehnenl\u00e4nge\u201c, die nur bei gekr\u00fcmmten Haltungen einen Wert liefert. \"\n                + \"Diese Haltung hier ist gerade, deshalb steht sie nicht in der Tabelle.\";\n\n            $(\"ksdSlopeIntro\").textContent = \"Bei den beiden oberen Angaben steht in der Hilfe ausdr\u00fccklich: Die Flussrichtung wird nicht ber\u00fccksichtigt. \"\n                + \"Sie sagen nur, ob vom Anfangs- oder vom Endpunkt der Haltung aus gerechnet wird, also in Zeichenrichtung. \"\n                + \"Nur \u201eNeigung\u201c ist auf die Flie\u00dfrichtung bezogen. Schalte oben die Zeichenrichtung um und sieh zu, was kippt.\";\n\n            var slopeHint = \"Als Bezugsl\u00e4nge ist hier die 2D-L\u00e4nge Mitte zu Mitte gerechnet. \"\n                + \"Wie das Vorzeichen in deiner Version angezeigt wird, h\u00e4ngt an der Anzeigekonvention. \"\n                + \"Fest steht: Die beiden \u201efest\u201c-Angaben h\u00e4ngen am Anfangs- und Endpunkt in Zeichenrichtung, nicht am Wasser.\";\n            if (m.nFlow < m.minGef - 1e-9) {\n                slopeHint = slopeHint + \" Nebenbei: Mit \" + permil(m.nFlow) + \" liegt diese Haltung unter der Faustregel 1:DN (\"\n                    + permil(m.minGef) + \"). F\u00fcr die Spaltenfrage \u00e4ndert das nichts, f\u00fcrs Projekt schon.\";\n            }\n            $(\"ksdSlopeHint\").textContent = slopeHint;\n\n            var diff = m.L - m.Lin;\n            $(\"ksdTileBez\").textContent = mStr(diff);\n            $(\"ksdTile3D\").textContent = mmStr(m.L3 - m.L);\n            var tN = $(\"ksdTileNeig\");\n            tN.textContent = permil(m.nFlow);\n            tN.className = \"ksd-tile-value \" + (m.nFlow < m.minGef - 1e-9 ? \"is-warn\" : \"\");\n            $(\"ksdTileHint\").textContent = \"Auf 20 Haltungen gerechnet sind das \" + mStr(diff * 20)\n                + \" Unterschied allein aus der Bezugsart, gegen\u00fcber \" + mmStr((m.L3 - m.L) * 20)\n                + \" aus dem Sprung von 2D auf 3D.\";\n        }\n\n        \/\/ ============ STEUERUNG ============\n        var SLIDERS = {\n            ksdL: { key: \"L\", step: 1 },\n            ksdZ1: { key: \"z1\", step: 0.05 },\n            ksdZ2: { key: \"z2\", step: 0.05 },\n            ksdD1: { key: \"d1\", step: 100 },\n            ksdD2: { key: \"d2\", step: 100 }\n        };\n\n        ROOT.addEventListener(\"input\", function (e) {\n            var conf = SLIDERS[e.target.id];\n            if (!conf) { return; }\n            var v = parseFloat(e.target.value);\n            if (isNaN(v)) { return; }\n            state[conf.key] = Math.round(v * 100) \/ 100;\n            renderAll();\n        });\n\n        ROOT.addEventListener(\"click\", function (e) {\n            var t = e.target;\n            if (!t.closest) { return; }\n\n            var dnBtn = t.closest(\"[data-ksd-dn]\");\n            if (dnBtn ? ROOT.contains(dnBtn) : false) {\n                state.dn = parseInt(dnBtn.getAttribute(\"data-ksd-dn\"), 10);\n                renderAll();\n                return;\n            }\n            var dirBtn = t.closest(\"[data-ksd-dir]\");\n            if (dirBtn ? ROOT.contains(dirBtn) : false) {\n                state.dir = dirBtn.getAttribute(\"data-ksd-dir\");\n                if (SPEC[state.sel].kind !== \"slope\") { state.sel = \"sStart\"; }\n                renderAll();\n                return;\n            }\n            var rowBtn = t.closest(\"[data-ksd-sel]\");\n            if (rowBtn ? ROOT.contains(rowBtn) : false) {\n                state.sel = rowBtn.getAttribute(\"data-ksd-sel\");\n                renderAll();\n                return;\n            }\n            var optBtn = t.closest(\"[data-ksd-opt]\");\n            if (optBtn ? ROOT.contains(optBtn) : false) {\n                answerQuiz(optBtn.getAttribute(\"data-ksd-opt\"), calc());\n                renderAll();\n                return;\n            }\n            if (t.closest(\"#ksdAgain\")) {\n                resetQuiz();\n            }\n        });\n\n        buildRows();\n        state.answered = loadAnswered();\n        renderAll();\n    })();\n<\/script>\n\n","protected":false},"excerpt":{"rendered":"<p>Spalten-Dekoder f&uuml;r Haltungen Sechs L&auml;ngen f&uuml;r dieselbe Haltung. Welche Spalte misst welche Strecke? L&auml;uft komplett im Browser. Keine Daten verlassen [&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":[47],"tags":[],"class_list":["post-2375","post","type-post","status-publish","format-standard","hentry","category-kanalnetz"],"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":"Spalten-Dekoder f&uuml;r Haltungen Sechs L&auml;ngen f&uuml;r dieselbe Haltung. Welche Spalte misst welche Strecke? L&auml;uft komplett im Browser. Keine Daten verlassen [&hellip;]","_links":{"self":[{"href":"https:\/\/cad-kompass.de\/index.php?rest_route=\/wp\/v2\/posts\/2375","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=2375"}],"version-history":[{"count":1,"href":"https:\/\/cad-kompass.de\/index.php?rest_route=\/wp\/v2\/posts\/2375\/revisions"}],"predecessor-version":[{"id":2376,"href":"https:\/\/cad-kompass.de\/index.php?rest_route=\/wp\/v2\/posts\/2375\/revisions\/2376"}],"wp:attachment":[{"href":"https:\/\/cad-kompass.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2375"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cad-kompass.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2375"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cad-kompass.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2375"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}