{"id":2167,"date":"2026-06-15T07:08:29","date_gmt":"2026-06-15T05:08:29","guid":{"rendered":"https:\/\/cad-kompass.de\/?p=2167"},"modified":"2026-06-26T17:59:04","modified_gmt":"2026-06-26T15:59:04","slug":"dialog-versenken","status":"publish","type":"post","link":"https:\/\/cad-kompass.de\/?p=2167","title":{"rendered":"Dialog-Versenken"},"content":{"rendered":"\n<!--\n    (c) CAD-Kompass. Alle Rechte vorbehalten.\n    Dieses Tool einschliesslich Quellcode, Design und Logik ist geistiges\n    Eigentum von CAD-Kompass. Jegliche Vervielfaeltigung, Weitergabe oder\n    Einbindung auf fremden Webseiten ist ohne ausdrueckliche schriftliche\n    Genehmigung untersagt.\n-->\n<style>\n    .zz-box {\n        --zz-primary: #3f5f75;\n        --zz-primary-dark: #2c4a5e;\n        --zz-primary-deep: #1e3548;\n        --zz-accent: #e8913a;\n        --zz-ink: #1e293b;\n        --zz-text: #334155;\n        --zz-muted: #64748b;\n        --zz-faint: #94a3b8;\n        --zz-border: #c8d6e0;\n        --zz-surface: #f7f9fb;\n        background: var(--zz-surface);\n        border: 2px solid var(--zz-primary);\n        border-radius: 2px;\n        margin: 28px 0;\n        overflow: hidden;\n        position: relative;\n        font-family: inherit;\n        color: var(--zz-text);\n        line-height: 1.6;\n    }\n\n    \/* Top bar (Tool-Lab-Standard) *\/\n    .zz-header {\n        background: linear-gradient(135deg, var(--zz-primary-deep) 0%, var(--zz-primary-dark) 100%);\n        padding: 20px 28px 18px;\n        position: relative;\n        overflow: hidden;\n    }\n    .zz-header::after {\n        content: '';\n        position: absolute;\n        bottom: 0;\n        left: 0;\n        right: 0;\n        height: 3px;\n        background: repeating-linear-gradient(\n                90deg,\n                var(--zz-primary) 0px,\n                var(--zz-primary) 8px,\n                transparent 8px,\n                transparent 12px\n        );\n    }\n    .zz-header-top {\n        display: flex;\n        align-items: center;\n        gap: 12px;\n        margin-bottom: 6px;\n    }\n    .zz-header-icon {\n        width: 36px;\n        height: 36px;\n        flex-shrink: 0;\n        opacity: 0.85;\n    }\n    .zz-box .zz-box-title {\n        font-size: 1.15rem;\n        font-weight: 700;\n        color: #fff;\n        margin: 0;\n        padding: 0;\n        letter-spacing: 0.02em;\n        display: inline;\n    }\n    .zz-box .zz-box-desc {\n        font-size: 0.85rem;\n        color: rgba(255,255,255,0.65);\n        margin: 0;\n        padding: 0;\n        line-height: 1.5;\n        display: block;\n    }\n\n    \/* Body *\/\n    .zz-body {\n        padding: 22px 28px 24px;\n    }\n\n    \/* Privacy *\/\n    .zz-privacy {\n        background: #f0fdf4;\n        border: 1px solid #bbf7d0;\n        border-radius: 3px;\n        padding: 9px 14px;\n        margin-bottom: 20px;\n        font-size: 0.8rem;\n        color: #15803d;\n        line-height: 1.5;\n        display: flex;\n        align-items: center;\n        gap: 8px;\n    }\n    .zz-privacy::before {\n        content: '\\1F512';\n        flex-shrink: 0;\n        font-size: 0.9rem;\n    }\n\n    \/* Section label *\/\n    .zz-section-label {\n        display: flex;\n        align-items: center;\n        gap: 10px;\n        margin-bottom: 14px;\n        font-size: 0.72rem;\n        font-weight: 700;\n        text-transform: uppercase;\n        letter-spacing: 0.1em;\n        color: var(--zz-muted);\n    }\n    .zz-section-label::before,\n    .zz-section-label::after {\n        content: '';\n        height: 1px;\n        background: var(--zz-border);\n        flex: 1;\n    }\n    .zz-section-label::before {\n        max-width: 20px;\n    }\n\n    \/* Buttons (Tool-Lab-Standard) *\/\n    .zz-btn {\n        padding: 10px 24px;\n        font-size: 0.9rem;\n        font-family: inherit;\n        background: var(--zz-primary);\n        color: #fff;\n        border: none;\n        border-radius: 2px;\n        cursor: pointer;\n        white-space: nowrap;\n        font-weight: 600;\n        letter-spacing: 0.02em;\n        transition: background 0.15s;\n        position: relative;\n    }\n    .zz-btn:hover {\n        background: var(--zz-primary-dark);\n        color: #fff;\n    }\n    .zz-btn:disabled {\n        background: var(--zz-faint);\n        cursor: not-allowed;\n    }\n    .zz-btn::before {\n        content: '';\n        position: absolute;\n        left: 0;\n        top: 0;\n        bottom: 0;\n        width: 3px;\n        background: rgba(255,255,255,0.25);\n        border-radius: 2px 0 0 2px;\n    }\n    .zz-btn:focus-visible {\n        outline: 2px solid var(--zz-primary);\n        outline-offset: 2px;\n    }\n\n    \/* ====== Spielfl\u00e4che: Seekarte ====== *\/\n    .zz-stage {\n        position: relative;\n        background-color: #fdfdfd;\n        background-image: linear-gradient(#eef2f6 1px, transparent 1px), linear-gradient(90deg, #eef2f6 1px, transparent 1px);\n        background-size: 28px 28px;\n        border: 1px solid var(--zz-border);\n        border-radius: 2px;\n        padding: 18px;\n        margin-bottom: 18px;\n    }\n\n    \/* Legende *\/\n    .zz-legend {\n        display: flex;\n        gap: 10px;\n        flex-wrap: wrap;\n        margin-bottom: 14px;\n    }\n    .zz-legend-chip {\n        display: flex;\n        align-items: center;\n        gap: 7px;\n        background: #fff;\n        border: 1px solid var(--zz-border);\n        border-radius: 2px;\n        padding: 5px 10px;\n        font-size: 0.74rem;\n        font-weight: 600;\n        color: var(--zz-text);\n    }\n    .zz-legend-chip svg {\n        width: 14px;\n        height: 14px;\n        flex-shrink: 0;\n    }\n\n    \/* Raster *\/\n    .zz-grid {\n        display: grid;\n        grid-template-columns: repeat(4, 1fr);\n        gap: 10px;\n    }\n    .zz-cell {\n        position: relative;\n        min-height: 84px;\n        background: rgba(255,255,255,0.45);\n        border: 1px dashed #d7e0e7;\n        border-radius: 2px;\n    }\n    .zz-cell::before {\n        content: attr(data-coord);\n        position: absolute;\n        top: 3px;\n        left: 6px;\n        font-size: 0.6rem;\n        font-weight: 700;\n        color: #c5d2db;\n        letter-spacing: 0.05em;\n    }\n\n    \/* Auftauchende Meldung *\/\n    .zz-mole {\n        position: absolute;\n        inset: 6px;\n        background: #fff;\n        border: 1px solid #9aa6af;\n        border-radius: 2px;\n        box-shadow: 0 5px 14px rgba(30,53,72,0.22);\n        display: flex;\n        flex-direction: column;\n        overflow: hidden;\n        cursor: pointer;\n        opacity: 0;\n        transform: translateY(10px) scale(0.92);\n        transition: opacity 0.16s ease, transform 0.16s ease;\n        pointer-events: none;\n        user-select: none;\n        -webkit-user-select: none;\n    }\n    .zz-mole.zz-up {\n        opacity: 1;\n        transform: none;\n        pointer-events: auto;\n    }\n    .zz-mole.zz-sunk {\n        transition: opacity 0.4s ease, transform 0.4s ease;\n        opacity: 0;\n        transform: translateY(22px) rotate(5deg) scale(0.85);\n        pointer-events: none;\n    }\n    .zz-mole.zz-wrong {\n        animation: zzWrong 0.4s ease;\n        pointer-events: none;\n    }\n    @keyframes zzWrong {\n        0%, 100% { transform: translateX(0); }\n        25% { transform: translateX(-5px); }\n        50% { transform: translateX(5px); }\n        75% { transform: translateX(-3px); }\n    }\n    .zz-mole-titlebar {\n        display: flex;\n        align-items: center;\n        justify-content: space-between;\n        gap: 6px;\n        background: linear-gradient(180deg, var(--zz-primary), var(--zz-primary-dark));\n        color: #fff;\n        font-size: 0.58rem;\n        font-weight: 600;\n        padding: 3px 7px;\n        flex-shrink: 0;\n    }\n    .zz-mole-x {\n        opacity: 0.75;\n        font-size: 0.55rem;\n    }\n    .zz-mole-body {\n        display: flex;\n        align-items: center;\n        gap: 7px;\n        padding: 7px 8px;\n        flex: 1;\n    }\n    .zz-mole-icon {\n        width: 18px;\n        height: 18px;\n        flex-shrink: 0;\n    }\n    .zz-mole-icon svg {\n        width: 18px;\n        height: 18px;\n        display: none;\n    }\n    .zz-mole-text {\n        font-size: 0.64rem;\n        font-weight: 600;\n        color: var(--zz-ink);\n        line-height: 1.35;\n    }\n    .zz-mole .zz-ico-warn { display: block; }\n    .zz-mole.zz-mole--good .zz-ico-warn { display: none; }\n    .zz-mole.zz-mole--good .zz-ico-ok { display: block; }\n\n    \/* Splash beim Versenken *\/\n    .zz-splash {\n        position: absolute;\n        width: 34px;\n        height: 34px;\n        border: 2px solid var(--zz-primary);\n        border-radius: 50%;\n        pointer-events: none;\n        animation: zzSplash 0.5s ease-out forwards;\n    }\n    @keyframes zzSplash {\n        0% { transform: scale(0.4); opacity: 0.9; }\n        100% { transform: scale(1.9); opacity: 0; }\n    }\n    .zz-stage.zz-ouch {\n        animation: zzOuch 0.3s ease;\n    }\n    @keyframes zzOuch {\n        0%, 100% { box-shadow: none; }\n        50% { box-shadow: inset 0 0 0 3px rgba(220,38,38,0.45); }\n    }\n\n    \/* Freigabe-Schleier + Pille (wie Klick-Wut) *\/\n    .zz-veil {\n        position: absolute;\n        inset: 0;\n        z-index: 2;\n        background: rgba(247,249,251,0.65);\n        border-radius: 2px;\n        cursor: pointer;\n    }\n    .zz-veil.zz-gone {\n        display: none;\n    }\n    .zz-cta {\n        position: absolute;\n        top: 50%;\n        left: 50%;\n        z-index: 3;\n        display: flex;\n        flex-direction: column;\n        align-items: center;\n        justify-content: center;\n        gap: 5px;\n        background: var(--zz-primary);\n        color: #fff;\n        font-size: 0.78rem;\n        font-weight: 700;\n        letter-spacing: 0.02em;\n        line-height: 1.45;\n        padding: 11px 18px 10px;\n        border-radius: 2px;\n        box-shadow: 0 4px 14px rgba(30,53,72,0.35);\n        cursor: pointer;\n        white-space: normal;\n        text-align: center;\n        max-width: 96%;\n        animation: zzPulse 1.6s ease-in-out infinite;\n    }\n    .zz-cta svg {\n        width: 16px;\n        height: 16px;\n        flex-shrink: 0;\n    }\n    .zz-cta.zz-gone {\n        display: none;\n    }\n    @keyframes zzPulse {\n        0%, 100% { transform: translate(-50%, -50%) scale(1); }\n        50% { transform: translate(-50%, -50%) scale(1.05); }\n    }\n\n    \/* HUD *\/\n    .zz-hud {\n        display: flex;\n        align-items: stretch;\n        gap: 12px;\n        margin-top: 16px;\n        flex-wrap: wrap;\n    }\n    .zz-hud-cell {\n        background: #fff;\n        border: 1px solid var(--zz-border);\n        border-left: 3px solid var(--zz-primary);\n        border-radius: 0 2px 2px 0;\n        padding: 8px 14px;\n        min-width: 96px;\n    }\n    .zz-hud-label {\n        font-size: 0.66rem;\n        font-weight: 700;\n        color: var(--zz-muted);\n        text-transform: uppercase;\n        letter-spacing: 0.08em;\n    }\n    .zz-hud-value {\n        font-size: 1.25rem;\n        font-weight: 700;\n        color: var(--zz-ink);\n        font-variant-numeric: tabular-nums;\n    }\n\n    .zz-hint {\n        font-size: 0.8rem;\n        color: var(--zz-muted);\n        line-height: 1.5;\n        margin: 14px 2px 0;\n    }\n\n    \/* Ergebnis *\/\n    .zz-result {\n        display: none;\n        background: #fff;\n        border: 1px solid var(--zz-border);\n        border-left: 3px solid var(--zz-primary);\n        border-radius: 0 2px 2px 0;\n        padding: 18px 22px;\n        margin-top: 18px;\n        margin-bottom: 18px;\n    }\n    .zz-result.zz-open {\n        display: block;\n        animation: zzRise 0.35s ease;\n    }\n    @keyframes zzRise {\n        from { opacity: 0; transform: translateY(8px); }\n        to { opacity: 1; transform: none; }\n    }\n    .zz-result-num {\n        font-size: 1.7rem;\n        font-weight: 700;\n        color: var(--zz-ink);\n        line-height: 1.2;\n    }\n    .zz-result-num small {\n        font-size: 0.85rem;\n        font-weight: 600;\n        color: var(--zz-muted);\n    }\n    .zz-result-rank {\n        font-size: 1rem;\n        font-weight: 700;\n        color: var(--zz-primary-dark);\n        margin: 10px 0 4px;\n    }\n    .zz-result-spruch {\n        font-size: 0.88rem;\n        color: var(--zz-text);\n        margin: 0 0 14px;\n    }\n\n    \/* ====== Bordbuch ====== *\/\n    .zz-board {\n        background: #fff;\n        border: 1px solid var(--zz-border);\n        border-radius: 2px;\n        padding: 16px 20px;\n    }\n    .zz-board-list {\n        list-style: none;\n        margin: 0;\n        padding: 0;\n    }\n    .zz-board-list li {\n        display: flex;\n        align-items: baseline;\n        gap: 10px;\n        padding: 5px 4px;\n        border-bottom: 1px solid #eef2f6;\n        font-size: 0.85rem;\n    }\n    .zz-board-list li:last-child {\n        border-bottom: none;\n    }\n    .zz-board-list li.zz-me {\n        background: #f0f7ff;\n    }\n    .zz-board-rank {\n        width: 24px;\n        text-align: right;\n        color: var(--zz-muted);\n        font-variant-numeric: tabular-nums;\n        flex-shrink: 0;\n    }\n    .zz-board-name {\n        flex: 1;\n        color: var(--zz-ink);\n        font-weight: 600;\n        overflow: hidden;\n        text-overflow: ellipsis;\n        white-space: nowrap;\n    }\n    .zz-board-score {\n        font-weight: 700;\n        color: var(--zz-primary-dark);\n        font-variant-numeric: tabular-nums;\n    }\n    .zz-board-empty {\n        font-size: 0.82rem;\n        color: var(--zz-muted);\n        margin: 0;\n    }\n    .zz-board-form {\n        display: none;\n        margin-top: 14px;\n        padding-top: 14px;\n        border-top: 1px solid #eef2f6;\n    }\n    .zz-board-form.zz-open {\n        display: block;\n    }\n    .zz-board-form-label {\n        font-size: 0.82rem;\n        color: var(--zz-text);\n        margin: 0 0 8px;\n    }\n    .zz-board-row {\n        display: flex;\n        gap: 8px;\n        flex-wrap: wrap;\n    }\n    .zz-board-row input {\n        flex: 1;\n        min-width: 160px;\n        padding: 10px 12px;\n        font-size: 0.92rem;\n        border: 1px solid var(--zz-border);\n        border-radius: 2px;\n        font-family: inherit;\n        color: var(--zz-ink);\n        background: #fff;\n        transition: border-color 0.15s, box-shadow 0.15s;\n        -webkit-appearance: none;\n    }\n    .zz-board-row input:focus {\n        outline: none;\n        border-color: var(--zz-primary);\n        box-shadow: 0 0 0 2px rgba(63,95,117,0.12);\n    }\n    .zz-board-row input::placeholder {\n        color: var(--zz-faint);\n    }\n    .zz-board-status {\n        font-size: 0.78rem;\n        color: var(--zz-muted);\n        margin: 10px 0 0;\n        line-height: 1.5;\n    }\n    .zz-board-status:empty {\n        display: none;\n    }\n\n    \/* Disclaimer *\/\n    .zz-disclaimer {\n        font-size: 0.76rem;\n        color: var(--zz-faint);\n        font-style: italic;\n        margin: 20px 0 0;\n        line-height: 1.5;\n        padding-top: 14px;\n        border-top: 1px solid #eef2f6;\n    }\n\n    \/* Vorlage f\u00fcr die Meldungen (bleibt unsichtbar) *\/\n    .zz-tpl {\n        display: none;\n    }\n\n    @media (prefers-reduced-motion: reduce) {\n        .zz-cta { animation: none; transform: translate(-50%, -50%); }\n        .zz-mole, .zz-result.zz-open { transition: none; animation: none; }\n        .zz-splash { animation-duration: 0.01s; }\n    }\n    @media (max-width: 600px) {\n        .zz-header { padding: 16px 20px 14px; }\n        .zz-body { padding: 18px 20px 20px; }\n        .zz-stage { padding: 12px; }\n        .zz-grid { grid-template-columns: repeat(3, 1fr); gap: 8px; }\n        .zz-cell { min-height: 92px; }\n    }\n<\/style>\n\n<div class=\"zz-box\">\n    <div class=\"zz-header\">\n        <div class=\"zz-header-top\">\n            <svg class=\"zz-header-icon\" viewBox=\"0 0 36 36\" fill=\"none\">\n                <circle cx=\"18\" cy=\"16\" r=\"10\" stroke=\"rgba(255,255,255,0.55)\" stroke-width=\"1\"\/>\n                <line x1=\"18\" y1=\"3\" x2=\"18\" y2=\"9\" stroke=\"rgba(255,255,255,0.85)\" stroke-width=\"1.3\"\/>\n                <line x1=\"18\" y1=\"23\" x2=\"18\" y2=\"29\" stroke=\"rgba(255,255,255,0.85)\" stroke-width=\"1.3\"\/>\n                <line x1=\"5\" y1=\"16\" x2=\"11\" y2=\"16\" stroke=\"rgba(255,255,255,0.85)\" stroke-width=\"1.3\"\/>\n                <line x1=\"25\" y1=\"16\" x2=\"31\" y2=\"16\" stroke=\"rgba(255,255,255,0.85)\" stroke-width=\"1.3\"\/>\n                <circle cx=\"18\" cy=\"16\" r=\"2\" fill=\"rgba(255,255,255,0.9)\"\/>\n                <path d=\"M4 32 Q 8 29, 12 32 T 20 32 T 28 32 T 34 32\" stroke=\"rgba(255,255,255,0.5)\" stroke-width=\"1\" fill=\"none\"\/>\n            <\/svg>\n            <span class=\"zz-box-title\">Dialog-Versenken<\/span>\n        <\/div>\n        <span class=\"zz-box-desc\">Auf der Seekarte tauchen Meldungen auf, die du aus Civil 3D kennst. Versenk die St\u00f6renfriede per Klick. Nur die gr\u00fcnen Erfolgsmeldungen bleiben unangetastet, die sind selten genug.<\/span>\n    <\/div>\n\n    <div class=\"zz-body\">\n        <div class=\"zz-privacy\">Das Spiel l\u00e4uft komplett in deinem Browser. Erst wenn du dich ins Bordbuch eintr\u00e4gst, werden Rufzeichen und Punktzahl gespeichert und \u00f6ffentlich gelistet.<\/div>\n\n        <div class=\"zz-section-label\">Seekarte<\/div>\n        <div class=\"zz-stage\" id=\"zzStage\">\n            <div class=\"zz-legend\">\n                <span class=\"zz-legend-chip\">\n                    <svg viewBox=\"0 0 18 18\" aria-hidden=\"true\"><path d=\"M9 2 L17 16 L1 16 Z\" fill=\"#e8913a\"\/><rect x=\"8.2\" y=\"7\" width=\"1.6\" height=\"4.5\" fill=\"#fff\"\/><rect x=\"8.2\" y=\"12.6\" width=\"1.6\" height=\"1.6\" fill=\"#fff\"\/><\/svg>\n                    Versenken: +10\n                <\/span>\n                <span class=\"zz-legend-chip\">\n                    <svg viewBox=\"0 0 18 18\" aria-hidden=\"true\"><circle cx=\"9\" cy=\"9\" r=\"8\" fill=\"#15803d\"\/><path d=\"M5 9.5 L8 12.5 L13 6\" stroke=\"#fff\" stroke-width=\"1.8\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg>\n                    Verschonen: &minus;15 bei Klick\n                <\/span>\n            <\/div>\n\n            <div class=\"zz-grid\" id=\"zzGrid\">\n                <div class=\"zz-cell\" data-coord=\"A1\"><\/div>\n                <div class=\"zz-cell\" data-coord=\"B1\"><\/div>\n                <div class=\"zz-cell\" data-coord=\"C1\"><\/div>\n                <div class=\"zz-cell\" data-coord=\"D1\"><\/div>\n                <div class=\"zz-cell\" data-coord=\"A2\"><\/div>\n                <div class=\"zz-cell\" data-coord=\"B2\"><\/div>\n                <div class=\"zz-cell\" data-coord=\"C2\"><\/div>\n                <div class=\"zz-cell\" data-coord=\"D2\"><\/div>\n                <div class=\"zz-cell\" data-coord=\"A3\"><\/div>\n                <div class=\"zz-cell\" data-coord=\"B3\"><\/div>\n                <div class=\"zz-cell\" data-coord=\"C3\"><\/div>\n                <div class=\"zz-cell\" data-coord=\"D3\"><\/div>\n            <\/div>\n\n            <div class=\"zz-veil\" id=\"zzVeil\"><\/div>\n            <div class=\"zz-cta\" id=\"zzCta\" role=\"button\" aria-label=\"Spiel starten\">\n                <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n                    <path d=\"M5 3 L5 17 L9 13.5 L11.5 19 L14 18 L11.5 12.5 L17 12.5 Z\" fill=\"currentColor\" stroke=\"none\"\/>\n                <\/svg>\n                <span>Klick zum Start. 30 Sekunden Wache.<\/span>\n            <\/div>\n        <\/div>\n\n        <div class=\"zz-hud\">\n            <div class=\"zz-hud-cell\">\n                <div class=\"zz-hud-label\">Zeit<\/div>\n                <div class=\"zz-hud-value\"><span id=\"zzTime\">30,0<\/span>&thinsp;s<\/div>\n            <\/div>\n            <div class=\"zz-hud-cell\">\n                <div class=\"zz-hud-label\">Punkte<\/div>\n                <div class=\"zz-hud-value\" id=\"zzScore\">0<\/div>\n            <\/div>\n            <div class=\"zz-hud-cell\">\n                <div class=\"zz-hud-label\">Versenkt<\/div>\n                <div class=\"zz-hud-value\" id=\"zzHits\">0<\/div>\n            <\/div>\n            <div class=\"zz-hud-cell\">\n                <div class=\"zz-hud-label\">Fehlgriffe<\/div>\n                <div class=\"zz-hud-value\" id=\"zzMisses\">0<\/div>\n            <\/div>\n        <\/div>\n\n        <p class=\"zz-hint\">Die Meldungen tauchen immer schneller auf und verschwinden von selbst. Versenken bringt 10 Punkte, ein Klick auf eine gr\u00fcne Erfolgsmeldung kostet 15. Entwischte St\u00f6renfriede kosten nichts, au\u00dfer Stolz.<\/p>\n\n        <div class=\"zz-result\" id=\"zzResult\">\n            <div class=\"zz-result-num\"><span id=\"zzResScore\">0<\/span> Punkte <small>(<span id=\"zzResHits\">0<\/span> versenkt &middot; <span id=\"zzResMisses\">0<\/span> Fehlgriffe)<\/small><\/div>\n            <div class=\"zz-result-rank\" id=\"zzResRank\"><\/div>\n            <p class=\"zz-result-spruch\" id=\"zzResSpruch\"><\/p>\n            <button type=\"button\" class=\"zz-btn\" id=\"zzAgain\">Noch eine Wache<\/button>\n        <\/div>\n\n        <div class=\"zz-section-label\">Bordbuch<\/div>\n        <div class=\"zz-board\">\n            <ol class=\"zz-board-list\" id=\"zzBoardList\"><\/ol>\n            <p class=\"zz-board-empty\" id=\"zzBoardEmpty\">Noch keine Eintr\u00e4ge. Die erste Wache geh\u00f6rt dir.<\/p>\n            <div class=\"zz-board-form\" id=\"zzBoardForm\">\n                <p class=\"zz-board-form-label\" id=\"zzBoardFormLabel\">Trag dein Ergebnis ein:<\/p>\n                <div class=\"zz-board-row\">\n                    <input type=\"text\" id=\"zzName\" maxlength=\"12\" placeholder=\"Dein Rufzeichen (3&ndash;12 Zeichen)\" autocomplete=\"off\">\n                    <button type=\"button\" class=\"zz-btn\" id=\"zzSubmit\">Eintragen<\/button>\n                <\/div>\n            <\/div>\n            <p class=\"zz-board-status\" id=\"zzBoardStatus\"><\/p>\n        <\/div>\n\n        <p class=\"zz-disclaimer\">Versenkte Dialoge tauchen in Civil 3D leider trotzdem wieder auf. Wir arbeiten dran.<\/p>\n    <\/div>\n\n    <!-- Vorlage einer Meldung, wird per JS in die Zellen geklont -->\n    <div class=\"zz-tpl\" id=\"zzMoleTpl\">\n        <div class=\"zz-mole\">\n            <div class=\"zz-mole-titlebar\"><span class=\"zz-mole-app\">Civil 3D 2026<\/span><span class=\"zz-mole-x\">&#10005;<\/span><\/div>\n            <div class=\"zz-mole-body\">\n                <span class=\"zz-mole-icon\">\n                    <svg class=\"zz-ico-warn\" viewBox=\"0 0 18 18\" aria-hidden=\"true\"><path d=\"M9 2 L17 16 L1 16 Z\" fill=\"#e8913a\"\/><rect x=\"8.2\" y=\"7\" width=\"1.6\" height=\"4.5\" fill=\"#fff\"\/><rect x=\"8.2\" y=\"12.6\" width=\"1.6\" height=\"1.6\" fill=\"#fff\"\/><\/svg>\n                    <svg class=\"zz-ico-ok\" viewBox=\"0 0 18 18\" aria-hidden=\"true\"><circle cx=\"9\" cy=\"9\" r=\"8\" fill=\"#15803d\"\/><path d=\"M5 9.5 L8 12.5 L13 6\" stroke=\"#fff\" stroke-width=\"1.8\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg>\n                <\/span>\n                <span class=\"zz-mole-text\"><\/span>\n            <\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<script>\n(function () {\n    'use strict';\n\n    var ROUND_MS = 30000;\n\n    \/* St\u00f6renfriede: versenken (+10) *\/\n    var TARGETS = [\n        'DGM ist nicht aktuell.',\n        'Proxy-Grafiken anzeigen?',\n        'Ereignisanzeige: 132 neue Eintr\u00e4ge',\n        'Verweis nicht gefunden: xref_Bestand.dwg',\n        'Lizenz wird \u00fcberpr\u00fcft \u2026',\n        'Zeichnung muss wiederhergestellt werden.',\n        'Objekt geh\u00f6rt zu einer Verschneidung.',\n        'Synchronisierung fehlgeschlagen.',\n        'Unerwarteter Fehler. Neustart empfohlen.',\n        'Beschriftungsma\u00dfstab fehlt.'\n    ];\n    \/* Gute Nachrichten: verschonen (\u221215 bei Klick) *\/\n    var FRIENDS = [\n        'Speichern erfolgreich.',\n        'Alle Verweise gefunden.',\n        'DGM ist aktuell.',\n        'Pr\u00fcfung abgeschlossen: keine Fehler.'\n    ];\n\n    var RANKS = [\n        { min: -9999, name: 'Seekrank',      text: 'Du hast vor allem die guten Nachrichten versenkt. Mutig.' },\n        { min: 1,     name: 'Leichtmatrose', text: 'Ein Anfang. Die Dialoge haben noch keinen Respekt vor dir.' },\n        { min: 71,    name: 'Matrose',       text: 'Solide Wache. Ein paar St\u00f6renfriede sind trotzdem durchgerutscht.' },\n        { min: 141,   name: 'Bootsmann',     text: 'Ruhige Hand. Auf deiner Seekarte herrscht Ordnung.' },\n        { min: 201,   name: 'Steuermann',    text: 'Sehr sauber. Du erkennst \u00c4rger, bevor er andockt.' },\n        { min: 261,   name: 'K\u00e4pt\u2019n',        text: 'Die See ist leer, die Crew applaudiert. Mehr versenkt man nicht.' }\n    ];\n\n    var stage = document.getElementById('zzStage');\n    var gridEl = document.getElementById('zzGrid');\n    var veil = document.getElementById('zzVeil');\n    var cta = document.getElementById('zzCta');\n    var timeEl = document.getElementById('zzTime');\n    var scoreEl = document.getElementById('zzScore');\n    var hitsEl = document.getElementById('zzHits');\n    var missesEl = document.getElementById('zzMisses');\n    var resultEl = document.getElementById('zzResult');\n    var resScore = document.getElementById('zzResScore');\n    var resHits = document.getElementById('zzResHits');\n    var resMisses = document.getElementById('zzResMisses');\n    var resRank = document.getElementById('zzResRank');\n    var resSpruch = document.getElementById('zzResSpruch');\n    var againBtn = document.getElementById('zzAgain');\n\n    \/* Zellen aufbauen: Vorlage in jede Zelle klonen *\/\n    var tpl = document.querySelector('#zzMoleTpl .zz-mole');\n    var cellNodes = gridEl.querySelectorAll('.zz-cell');\n    var cells = [];\n    var ci;\n    for (ci = 0; ci < cellNodes.length; ci++) {\n        var moleEl = tpl.cloneNode(true);\n        cellNodes[ci].appendChild(moleEl);\n        cells.push({\n            cell: cellNodes[ci],\n            mole: moleEl,\n            text: moleEl.querySelector('.zz-mole-text'),\n            busy: false,\n            good: false,\n            hideTimer: null,\n            clearTimer: null\n        });\n    }\n\n    function freshState() {\n        return { running: false, ended: false, score: 0, hits: 0, misses: 0, t0: 0, tick: null, spawn: null };\n    }\n    var state = freshState();\n\n    function fmt1(n) {\n        return n.toFixed(1).replace('.', ',');\n    }\n\n    function updateHud() {\n        scoreEl.textContent = state.score;\n        hitsEl.textContent = state.hits;\n        missesEl.textContent = state.misses;\n    }\n\n    function despawn(c) {\n        clearTimeout(c.hideTimer);\n        clearTimeout(c.clearTimer);\n        c.mole.classList.remove('zz-up');\n        c.clearTimer = setTimeout(function () {\n            c.mole.classList.remove('zz-sunk');\n            c.mole.classList.remove('zz-wrong');\n            c.busy = false;\n        }, 220);\n    }\n\n    function spawn() {\n        var free = [];\n        var i;\n        for (i = 0; i < cells.length; i++) {\n            if (!cells[i].busy) { free.push(cells[i]); }\n        }\n        if (free.length === 0) { return; }\n        var c = free[Math.floor(Math.random() * free.length)];\n        var isTarget = Math.random() < 0.72;\n        var pool = isTarget ? TARGETS : FRIENDS;\n        c.good = !isTarget; \/* good = gute Nachricht = verschonen *\/\n        c.text.textContent = pool[Math.floor(Math.random() * pool.length)];\n        if (c.good) { c.mole.classList.add('zz-mole--good'); } else { c.mole.classList.remove('zz-mole--good'); }\n        c.busy = true;\n        c.mole.classList.remove('zz-sunk');\n        c.mole.classList.remove('zz-wrong');\n        c.mole.classList.add('zz-up');\n\n        var elapsed = Date.now() - state.t0;\n        var lifetime = Math.max(950, 1600 - elapsed * 0.02);\n        c.hideTimer = setTimeout(function () { despawn(c); }, lifetime);\n    }\n\n    function spawnLoop() {\n        if (!state.running) { return; }\n        spawn();\n        var elapsed = Date.now() - state.t0;\n        var interval = Math.max(620, 1150 - elapsed * 0.016);\n        state.spawn = setTimeout(spawnLoop, interval);\n    }\n\n    function splashAt(c) {\n        var r = c.cell.getBoundingClientRect();\n        var sr = stage.getBoundingClientRect();\n        var s = document.createElement('span');\n        s.className = 'zz-splash';\n        s.style.left = (r.left - sr.left + r.width \/ 2 - 17) + 'px';\n        s.style.top = (r.top - sr.top + r.height \/ 2 - 17) + 'px';\n        stage.appendChild(s);\n        s.addEventListener('animationend', function () { s.remove(); });\n    }\n\n    function onMoleClick(c) {\n        if (!state.running) { return; }\n        if (!c.busy) { return; }\n        clearTimeout(c.hideTimer);\n        if (c.good) {\n            state.score -= 15;\n            state.misses += 1;\n            c.mole.classList.add('zz-wrong');\n            stage.classList.remove('zz-ouch');\n            void stage.offsetWidth;\n            stage.classList.add('zz-ouch');\n            c.hideTimer = setTimeout(function () { despawn(c); }, 420);\n        } else {\n            state.score += 10;\n            state.hits += 1;\n            c.mole.classList.add('zz-sunk');\n            splashAt(c);\n            c.hideTimer = setTimeout(function () { despawn(c); }, 60);\n        }\n        updateHud();\n    }\n\n    (function bindMoles() {\n        var i;\n        for (i = 0; i < cells.length; i++) {\n            (function (c) {\n                c.mole.addEventListener('click', function () { onMoleClick(c); });\n            })(cells[i]);\n        }\n    })();\n\n    function tick() {\n        var left = ROUND_MS - (Date.now() - state.t0);\n        if (left <= 0) { end(); return; }\n        timeEl.textContent = fmt1(left \/ 1000);\n    }\n\n    function start() {\n        state = freshState();\n        state.running = true;\n        state.t0 = Date.now();\n        updateHud();\n        timeEl.textContent = '30,0';\n        resultEl.classList.remove('zz-open');\n        veil.classList.add('zz-gone');\n        cta.classList.add('zz-gone');\n        state.tick = setInterval(tick, 100);\n        spawnLoop();\n    }\n\n    function rankFor(score) {\n        var i, idx = 0;\n        for (i = 0; i < RANKS.length; i++) {\n            if (score >= RANKS[i].min) { idx = i; }\n        }\n        return RANKS[idx];\n    }\n\n    function end() {\n        state.running = false;\n        state.ended = true;\n        clearInterval(state.tick);\n        clearTimeout(state.spawn);\n        var i;\n        for (i = 0; i < cells.length; i++) {\n            if (cells[i].busy) { despawn(cells[i]); }\n        }\n        timeEl.textContent = '0,0';\n\n        var rank = rankFor(state.score);\n        resScore.textContent = state.score;\n        resHits.textContent = state.hits;\n        resMisses.textContent = state.misses;\n        resRank.textContent = 'Dienstgrad: ' + rank.name;\n        resSpruch.textContent = rank.text;\n        resultEl.classList.add('zz-open');\n\n        lastScore = state.score;\n        submitted = false;\n        submitBtn.disabled = false;\n        if (lastScore > 0) {\n            boardFormLabel.textContent = 'Dein Ergebnis: ' + lastScore + ' Punkte. Trag dich ins Bordbuch ein:';\n            if (!nameInput.value) {\n                var saved = '';\n                try { saved = localStorage.getItem(NAME_KEY) || ''; } catch (err) { saved = ''; }\n                nameInput.value = saved;\n            }\n            boardForm.classList.add('zz-open');\n        } else {\n            boardForm.classList.remove('zz-open');\n        }\n        loadBoard(null);\n    }\n\n    stage.addEventListener('click', function (e) {\n        var gate = e.target.closest ? e.target.closest('#zzCta, #zzVeil') : null;\n        if (gate) {\n            if (!state.running) { start(); }\n        }\n    });\n\n    againBtn.addEventListener('click', function () {\n        boardForm.classList.remove('zz-open');\n        boardStatus.textContent = '';\n        start();\n    });\n\n    \/* ====== Bordbuch: global \u00fcber REST, lokaler Fallback ====== *\/\n    var API_URL = '\/?rest_route=\/zenzorn\/v1\/scores\/dialog-versenken';\n    var LOCAL_BOARD_KEY = 'zz-board-dialog-versenken';\n    var NAME_KEY = 'zz-bordname';\n    var NAME_RE = \/^[A-Za-z0-9\u00c4\u00d6\u00dc\u00e4\u00f6\u00fc\u00df._\\- ]{3,12}$\/;\n\n    var boardList = document.getElementById('zzBoardList');\n    var boardEmpty = document.getElementById('zzBoardEmpty');\n    var boardForm = document.getElementById('zzBoardForm');\n    var boardFormLabel = document.getElementById('zzBoardFormLabel');\n    var boardStatus = document.getElementById('zzBoardStatus');\n    var nameInput = document.getElementById('zzName');\n    var submitBtn = document.getElementById('zzSubmit');\n\n    var boardToken = null;\n    var remoteMode = true;\n    var submitted = false;\n    var lastScore = 0;\n\n    function localRead() {\n        var raw = null;\n        try { raw = localStorage.getItem(LOCAL_BOARD_KEY); } catch (err) { raw = null; }\n        if (!raw) { return []; }\n        var list = [];\n        try { list = JSON.parse(raw); } catch (err) { list = []; }\n        return Array.isArray(list) ? list : [];\n    }\n\n    function localAdd(name, score) {\n        var list = localRead();\n        list.push({ name: name, score: score });\n        list.sort(function (a, b) { return b.score - a.score; });\n        list = list.slice(0, 10);\n        try { localStorage.setItem(LOCAL_BOARD_KEY, JSON.stringify(list)); } catch (err) { \/* localStorage gesperrt *\/ }\n        return list;\n    }\n\n    function renderBoard(list, own) {\n        boardList.textContent = '';\n        var shown = list.slice(0, 10);\n        boardEmpty.style.display = shown.length === 0 ? '' : 'none';\n        var ownMarked = false;\n        var i;\n        for (i = 0; i < shown.length; i++) {\n            var li = document.createElement('li');\n            var rank = document.createElement('span');\n            rank.className = 'zz-board-rank';\n            rank.textContent = (i + 1) + '.';\n            var nm = document.createElement('span');\n            nm.className = 'zz-board-name';\n            nm.textContent = shown[i].name;\n            var sc = document.createElement('span');\n            sc.className = 'zz-board-score';\n            sc.textContent = shown[i].score;\n            li.appendChild(rank);\n            li.appendChild(nm);\n            li.appendChild(sc);\n            if (own) {\n                if (!ownMarked) {\n                    if (shown[i].name === own.name) {\n                        if (shown[i].score === own.score) {\n                            li.classList.add('zz-me');\n                            ownMarked = true;\n                        }\n                    }\n                }\n            }\n            boardList.appendChild(li);\n        }\n    }\n\n    function loadBoard(own) {\n        fetch(API_URL, { cache: 'no-store' })\n            .then(function (r) {\n                if (!r.ok) { throw new Error('http'); }\n                return r.json();\n            })\n            .then(function (data) {\n                remoteMode = true;\n                boardToken = data.token;\n                renderBoard(data.scores || [], own || null);\n                boardStatus.textContent = '';\n            })\n            .catch(function () {\n                remoteMode = false;\n                boardToken = null;\n                renderBoard(localRead(), own || null);\n                boardStatus.textContent = 'Keine Verbindung zum Server. Das Bordbuch l\u00e4uft gerade nur lokal auf diesem Ger\u00e4t.';\n            });\n    }\n\n    function submitScore() {\n        if (submitted) { return; }\n        var name = nameInput.value.trim();\n        if (!NAME_RE.test(name)) {\n            boardStatus.textContent = 'Rufzeichen bitte 3 bis 12 Zeichen: Buchstaben, Zahlen, Punkt, Strich.';\n            return;\n        }\n        try { localStorage.setItem(NAME_KEY, name); } catch (err) { \/* localStorage gesperrt *\/ }\n        if (!remoteMode) {\n            var list = localAdd(name, lastScore);\n            submitted = true;\n            boardForm.classList.remove('zz-open');\n            renderBoard(list, { name: name, score: lastScore });\n            boardStatus.textContent = 'Lokal eingetragen (nur auf diesem Ger\u00e4t sichtbar).';\n            return;\n        }\n        submitBtn.disabled = true;\n        boardStatus.textContent = 'Wird eingetragen \u2026';\n        fetch(API_URL, {\n            method: 'POST',\n            headers: { 'Content-Type': 'application\/json' },\n            body: JSON.stringify({ name: name, score: lastScore, token: boardToken, website: '' })\n        })\n            .then(function (r) {\n                return r.json().then(function (d) { return { ok: r.ok, data: d }; });\n            })\n            .then(function (res) {\n                if (res.ok) {\n                    submitted = true;\n                    boardForm.classList.remove('zz-open');\n                    renderBoard(res.data.scores || [], { name: name, score: lastScore });\n                    boardStatus.textContent = 'Eingetragen. Willkommen im Bordbuch, ' + name + '.';\n                } else {\n                    submitBtn.disabled = false;\n                    var msg = res.data ? res.data.message : '';\n                    boardStatus.textContent = msg ? msg : 'Der Eintrag wurde abgelehnt.';\n                    loadBoard(null);\n                }\n            })\n            .catch(function () {\n                submitBtn.disabled = false;\n                boardStatus.textContent = 'Verbindung fehlgeschlagen. Versuch es gleich nochmal.';\n            });\n    }\n\n    submitBtn.addEventListener('click', submitScore);\n    nameInput.addEventListener('keydown', function (e) {\n        if (e.key === 'Enter') { submitScore(); }\n    });\n\n    loadBoard(null);\n})();\n<\/script>\n\n","protected":false},"excerpt":{"rendered":"<p>Dialog-Versenken Auf der Seekarte tauchen Meldungen auf, die du aus Civil 3D kennst. Versenk die St\u00f6renfriede per Klick. Nur die [&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":[41],"tags":[],"class_list":["post-2167","post","type-post","status-publish","format-standard","hentry","category-zen-zorn"],"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":"Dialog-Versenken Auf der Seekarte tauchen Meldungen auf, die du aus Civil 3D kennst. Versenk die St\u00f6renfriede per Klick. Nur die [&hellip;]","_links":{"self":[{"href":"https:\/\/cad-kompass.de\/index.php?rest_route=\/wp\/v2\/posts\/2167","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=2167"}],"version-history":[{"count":2,"href":"https:\/\/cad-kompass.de\/index.php?rest_route=\/wp\/v2\/posts\/2167\/revisions"}],"predecessor-version":[{"id":2170,"href":"https:\/\/cad-kompass.de\/index.php?rest_route=\/wp\/v2\/posts\/2167\/revisions\/2170"}],"wp:attachment":[{"href":"https:\/\/cad-kompass.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2167"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cad-kompass.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2167"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cad-kompass.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2167"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}