{"id":2215,"date":"2025-12-04T22:41:34","date_gmt":"2025-12-04T21:41:34","guid":{"rendered":"https:\/\/kemiformler.dk\/?page_id=2215"},"modified":"2025-12-05T10:28:52","modified_gmt":"2025-12-05T09:28:52","slug":"elementor-2215","status":"publish","type":"page","link":"https:\/\/kemiformler.dk\/index.php\/elementor-2215\/","title":{"rendered":"Animationer KemiB"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"2215\" class=\"elementor elementor-2215\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-d8134e6 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"d8134e6\" data-element_type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-faffd18\" data-id=\"faffd18\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-fe1725a elementor-widget elementor-widget-html\" data-id=\"fe1725a\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"da\">\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n    <title>Alkan-Simulatoren V8 (Komplet)<\/title>\r\n    <style>\r\n        body {\r\n            font-family: 'Segoe UI', Roboto, sans-serif;\r\n            background-color: #f0f2f5;\r\n            display: flex;\r\n            flex-direction: column;\r\n            align-items: center;\r\n            padding: 20px;\r\n            color: #333;\r\n        }\r\n\r\n        h1 { margin-bottom: 5px; color: #2c3e50; }\r\n        p { margin-bottom: 20px; color: #555; max-width: 650px; text-align: center; }\r\n\r\n        .main-container {\r\n            display: flex;\r\n            gap: 25px;\r\n            background: white;\r\n            padding: 25px;\r\n            border-radius: 16px;\r\n            box-shadow: 0 10px 25px rgba(0,0,0,0.08);\r\n            flex-wrap: wrap;\r\n            justify-content: center;\r\n        }\r\n\r\n        .canvas-wrapper {\r\n            position: relative;\r\n            width: 420px;\r\n            height: 540px;\r\n            border: 3px solid #546E7A;\r\n            background: linear-gradient(to bottom, #e3f2fd 0%, #ffffff 70%, #cfd8dc 100%);\r\n            border-radius: 8px;\r\n            overflow: hidden;\r\n        }\r\n\r\n        canvas { display: block; width: 100%; height: 100%; }\r\n        \r\n        \/* Eksplosions-effekt klasse *\/\r\n        .flash-anim {\r\n            animation: flash 0.5s ease-out;\r\n        }\r\n        @keyframes flash {\r\n            0% { background: #ffff00; }\r\n            50% { background: #ff9800; }\r\n            100% { background: linear-gradient(to bottom, #e3f2fd 0%, #ffffff 70%, #cfd8dc 100%); }\r\n        }\r\n\r\n        .zone-label {\r\n            position: absolute;\r\n            font-weight: 800;\r\n            color: #90a4ae;\r\n            font-size: 14px;\r\n            letter-spacing: 1px;\r\n            text-transform: uppercase;\r\n            pointer-events: none;\r\n            left: 15px;\r\n        }\r\n        .top-label { top: 15px; }\r\n        .bot-label { bottom: 15px; color: #78909c; }\r\n\r\n        .controls-panel {\r\n            width: 340px;\r\n            display: flex;\r\n            flex-direction: column;\r\n            gap: 10px;\r\n        }\r\n\r\n        .slider-card {\r\n            background: #fff3e0;\r\n            padding: 15px 20px;\r\n            border-radius: 10px;\r\n            border: 1px solid #ffe0b2;\r\n            text-align: center;\r\n            margin-bottom: 5px;\r\n        }\r\n\r\n        .temp-display { font-size: 32px; font-weight: 900; color: #d32f2f; margin: 5px 0; font-family: monospace;}\r\n        \r\n        input[type=range] { width: 100%; cursor: pointer; margin: 10px 0; }\r\n\r\n        .state-badge {\r\n            font-weight: 700;\r\n            font-size: 15px;\r\n            padding: 8px 12px;\r\n            border-radius: 6px;\r\n            background: rgba(255,255,255,0.9);\r\n            margin-top: 10px;\r\n            border: 1px solid #ddd;\r\n            display: inline-block;\r\n            min-width: 180px;\r\n        }\r\n\r\n        .btn-styled {\r\n            width: 100%;\r\n            padding: 10px 12px;\r\n            margin-bottom: 4px;\r\n            border: 1px solid #cfd8dc;\r\n            background: #f8f9fa;\r\n            cursor: pointer;\r\n            border-radius: 8px;\r\n            text-align: left;\r\n            font-size: 14px;\r\n            display: flex;\r\n            justify-content: space-between;\r\n            align-items: center;\r\n            transition: all 0.2s ease;\r\n            color: #455A64;\r\n        }\r\n        \r\n        .btn-styled:hover { background: #eceff1; }\r\n        \r\n        .btn-styled.active {\r\n            background: #e3f2fd;\r\n            border-color: #2196F3;\r\n            color: #0d47a1;\r\n            font-weight: 700;\r\n            transform: translateY(-1px);\r\n        }\r\n\r\n        \/* Mix knap *\/\r\n        .btn-mix {\r\n            border: 2px solid #673AB7;\r\n            background: #EDE7F6;\r\n            margin-top: 5px;\r\n            padding: 12px;\r\n        }\r\n        .btn-mix.active { background: #D1C4E9; border-color: #512DA8; color: #311B92; }\r\n\r\n        \/* Forbr\u00e6ndings knap *\/\r\n        .btn-burn {\r\n            border: 2px solid #d32f2f;\r\n            background: #ffebee;\r\n            color: #b71c1c;\r\n            font-weight: bold;\r\n            margin-top: 15px;\r\n            padding: 14px;\r\n            text-align: center;\r\n            justify-content: center;\r\n        }\r\n        .btn-burn:hover { background: #ffcdd2; box-shadow: 0 0 10px rgba(211, 47, 47, 0.3); }\r\n        .btn-burn:active { transform: scale(0.98); }\r\n\r\n        .kp-badge { font-size: 11px; color: #555; background: #eceff1; padding: 2px 6px; border-radius: 4px; font-weight: 600; }\r\n\r\n        .section-separator {\r\n            border-top: 1px solid #e0e0e0;\r\n            margin: 10px 0 5px 0;\r\n            position: relative;\r\n            text-align: center;\r\n        }\r\n        .section-separator span {\r\n            position: relative;\r\n            top: -10px;\r\n            background: white;\r\n            padding: 0 12px;\r\n            font-size: 11px;\r\n            font-weight: 700;\r\n            color: #90a4ae;\r\n            text-transform: uppercase;\r\n        }\r\n        \r\n        .info-box {\r\n            font-size: 13px; color: #546E7A; background: #eceff1; padding: 10px; border-radius: 8px; border-left: 4px solid #90a4ae;\r\n            line-height: 1.4; min-height: 40px;\r\n        }\r\n        \r\n        .flex-row { display: flex; gap: 8px; }\r\n        .flex-fill { flex: 1; }\r\n\r\n    <\/style>\r\n<\/head>\r\n<body>\r\n\r\n    <h1>Alkan-Simulatoren (Komplet)<\/h1>\r\n    <p>Unders\u00f8g fysiske egenskaber, destillation og slut af med en forbr\u00e6nding!<\/p>\r\n\r\n    <div class=\"main-container\">\r\n        <div class=\"canvas-wrapper\" id=\"canvasWrap\">\r\n            <canvas id=\"simCanvas\" width=\"420\" height=\"540\"><\/canvas>\r\n            <div class=\"zone-label top-label\">Gasfase<\/div>\r\n            <div class=\"zone-label bot-label\">V\u00e6ske \/ Fast Stof<\/div>\r\n        <\/div>\r\n\r\n        <div class=\"controls-panel\">\r\n            <div class=\"slider-card\">\r\n                <label style=\"font-weight:600; color:#d84315;\">Temperatur (\u00b0C)<\/label>\r\n                <input type=\"range\" id=\"tempSlider\" min=\"-200\" max=\"150\" value=\"20\">\r\n                <div class=\"temp-display\"><span id=\"tempValue\">20<\/span> \u00b0C<\/div>\r\n                <div id=\"stateText\" class=\"state-badge\">Tilstand: ...<\/div>\r\n            <\/div>\r\n\r\n            <div class=\"section-separator\"><span>Alkaner (St\u00f8rrelse)<\/span><\/div>\r\n            \r\n            <button onclick=\"changeAlkane('metan')\" id=\"btn-metan\" class=\"btn-styled active\">\r\n                <span>Metan (C\u2081)<\/span>\r\n                <span class=\"kp-badge\">Kp: -162\u00b0<\/span>\r\n            <\/button>\r\n            \r\n            <button onclick=\"changeAlkane('octan')\" id=\"btn-octan\" class=\"btn-styled\">\r\n                <span>Octan (C\u2088)<\/span>\r\n                <span class=\"kp-badge\">Kp: 126\u00b0<\/span>\r\n            <\/button>\r\n\r\n            <div class=\"section-separator\"><span>Isomeri (Form)<\/span><\/div>\r\n            \r\n            <div class=\"flex-row\">\r\n                <button onclick=\"changeAlkane('pentan')\" id=\"btn-pentan\" class=\"btn-styled flex-fill\">\r\n                    <span>n-Pentan<\/span>\r\n                     <span class=\"kp-badge\">Kp: 36\u00b0<\/span>\r\n                <\/button>\r\n                <button onclick=\"changeAlkane('neopentan')\" id=\"btn-neopentan\" class=\"btn-styled flex-fill\" style=\"background:#fce4ec; border-color:#f8bbd0; color:#880e4f;\">\r\n                    <span>Neopentan<\/span>\r\n                    <span class=\"kp-badge\" style=\"background:#f8bbd0; color:#880e4f;\">Kp: 10\u00b0<\/span>\r\n                <\/button>\r\n            <\/div>\r\n\r\n            <div class=\"section-separator\"><span>Avanceret<\/span><\/div>\r\n            \r\n            <button onclick=\"startMix()\" id=\"btn-mix\" class=\"btn-styled btn-mix\">\r\n                <span>\ud83e\uddea Bland: Metan & Octan<\/span>\r\n            <\/button>\r\n\r\n            <button onclick=\"triggerCombustion()\" id=\"btn-burn\" class=\"btn-burn\">\r\n                \ud83d\udd25 ANT\u00c6ND DAMP\r\n            <\/button>\r\n\r\n            <div id=\"infoText\" class=\"info-box\">\r\n                Indl\u00e6ser data...\r\n            <\/div>\r\n        <\/div>\r\n    <\/div>\r\n\r\n<script>\r\nwindow.onload = function() {\r\n\r\n    \/\/ --- Ops\u00e6tning ---\r\n    const canvas = document.getElementById('simCanvas');\r\n    const ctx = canvas.getContext('2d');\r\n    const width = canvas.width;\r\n    const height = canvas.height;\r\n\r\n    \/\/ Data definitioner\r\n    const alkanes = {\r\n        metan:  { name: \"Metan\", carbons: 1, melt: -182, boil: -162, col: \"#2196F3\", isBranched: false, txt: \"Metan (C\u2081) er lille. Den koger allerede ved -162\u00b0C.\" },\r\n        pentan: { name: \"n-Pentan\", carbons: 5, melt: -130, boil: 36, col: \"#FF9800\", isBranched: false, txt: \"n-Pentan (C\u2085) er en lang k\u00e6de. Koger ved 36\u00b0C.\" },\r\n        neopentan:{ name: \"Neopentan\", carbons: 5, melt: -17, boil: 10, col: \"#E91E63\", isBranched: true,  txt: \"Neopentan (C\u2085) er kugleformet. Koger ved 10\u00b0C.\" },\r\n        octan:  { name: \"Octan\", carbons: 8, melt: -57, boil: 126, col: \"#9C27B0\", isBranched: false, txt: \"Octan (C\u2088) er en tung k\u00e6de. Koger ved 126\u00b0C.\" }\r\n    };\r\n\r\n    let currentTemp = 20;\r\n    let particles = [];\r\n    let isMixMode = false;\r\n    let isCombustionMode = false;\r\n\r\n    \/\/ --- Partikel Klasser ---\r\n    \r\n    \/\/ 1. Alkan Partikel (De normale)\r\n    class AlkaneParticle {\r\n        constructor(alkaneType) {\r\n            this.type = alkaneType; \r\n            this.reset(true);\r\n        }\r\n\r\n        reset(randomY = false) {\r\n            this.atomRadius = 5; \r\n            let sizeFactor = this.type.isBranched ? 1.0 : 1.5;\r\n            this.physRadius = this.atomRadius + (this.type.carbons * sizeFactor);\r\n\r\n            this.x = Math.random() * (width - 40) + 20;\r\n            this.y = randomY ? Math.random() * height : height - 20;\r\n            this.vx = (Math.random() - 0.5) * 0.8; \r\n            this.vy = 0;\r\n            this.angle = Math.random() * Math.PI * 2;\r\n            this.spin = 0;\r\n        }\r\n\r\n        update() {\r\n            const isSolid = currentTemp < this.type.melt;\r\n            const isGas = currentTemp > this.type.boil;\r\n            const isLiquid = !isSolid && !isGas;\r\n\r\n            if (isSolid) {\r\n                this.vy += 0.3; this.vx *= 0.8; this.spin *= 0.9; \r\n                if (this.y > height - this.physRadius) {\r\n                    this.y = height - this.physRadius; this.vy = 0;\r\n                    this.x += (Math.random() - 0.5) * 0.5; this.y += (Math.random() - 0.5) * 0.5;\r\n                }\r\n            } else if (isLiquid) {\r\n                this.vy += 0.15; this.spin = (this.vx * 0.05);\r\n                if (this.y > height - this.physRadius) {\r\n                    this.y = height - this.physRadius; this.vy *= -0.2; this.vx *= 0.96;\r\n                    this.vx += (Math.random() - 0.5) * 0.2;\r\n                    if(Math.random() < 0.02) this.vy -= 0.5;\r\n                }\r\n            } else { \/\/ GAS\r\n                let energy = ((currentTemp - this.type.boil) * 0.005) + 0.05;\r\n                this.vy += 0.02; \r\n                if (Math.random() < 0.1) this.vy -= (energy + Math.random() * 0.4);\r\n                this.spin = (Math.random() - 0.5) * 0.1;\r\n\r\n                if (this.y < 0) { this.y = 0; this.vy *= -0.5; }\r\n                if (this.y > height - this.physRadius) { this.y = height - this.physRadius; this.vy *= -0.5; }\r\n            }\r\n\r\n            this.x += this.vx; this.y += this.vy; this.angle += this.spin;\r\n            if (this.x < 10) { this.x = 10; this.vx *= -1; }\r\n            if (this.x > width - 10) { this.x = width - 10; this.vx *= -1; }\r\n        }\r\n\r\n        draw(ctx) {\r\n            ctx.save();\r\n            ctx.translate(this.x, this.y);\r\n            ctx.rotate(this.angle);\r\n\r\n            let drawColor = this.type.col;\r\n            if (currentTemp < this.type.melt) drawColor = \"#90A4AE\";\r\n\r\n            \/\/ Tegn Neopentan eller K\u00e6de\r\n            if (this.type.isBranched && this.type.carbons === 5) {\r\n                this.drawAtom(ctx, 0, 0, drawColor);\r\n                const dist = this.atomRadius * 1.8;\r\n                this.drawAtom(ctx, dist, 0, drawColor); this.drawAtom(ctx, -dist, 0, drawColor);\r\n                this.drawAtom(ctx, 0, dist, drawColor); this.drawAtom(ctx, 0, -dist, drawColor);\r\n            } else {\r\n                const count = this.type.carbons;\r\n                const spacing = 8;\r\n                const totalLen = (count - 1) * spacing;\r\n                const startX = -totalLen \/ 2;\r\n                \r\n                ctx.strokeStyle = \"rgba(0,0,0,0.3)\";\r\n                if (count > 1) {\r\n                    ctx.beginPath(); ctx.moveTo(startX, 0); ctx.lineTo(startX + totalLen, 0);\r\n                    ctx.lineWidth = 4; ctx.stroke();\r\n                }\r\n                for (let i = 0; i < count; i++) this.drawAtom(ctx, startX + (i * spacing), 0, drawColor);\r\n            }\r\n            ctx.restore();\r\n        }\r\n\r\n        drawAtom(ctx, x, y, color) {\r\n            ctx.beginPath(); ctx.arc(x, y, this.atomRadius, 0, Math.PI * 2);\r\n            ctx.fillStyle = color; ctx.fill();\r\n            ctx.lineWidth = 1; ctx.strokeStyle = \"rgba(0,0,0,0.2)\"; ctx.stroke();\r\n        }\r\n    }\r\n\r\n    \/\/ 2. Produkt Partikel (CO2 og H2O til forbr\u00e6nding)\r\n    class ProductParticle {\r\n        constructor(type) {\r\n            this.type = type; \/\/ 'co2' eller 'h2o'\r\n            this.x = Math.random() * width;\r\n            this.y = Math.random() * (height\/2); \/\/ Start i luften\r\n            this.vx = (Math.random() - 0.5) * 8; \/\/ Meget hurtige! (H\u00f8j energi)\r\n            this.vy = (Math.random() - 0.5) * 8;\r\n            this.angle = Math.random();\r\n            this.spin = (Math.random() - 0.5) * 0.5;\r\n        }\r\n\r\n        update() {\r\n            this.x += this.vx; this.y += this.vy; this.angle += this.spin;\r\n            \r\n            \/\/ Bounce vildt rundt\r\n            if (this.x < 0 || this.x > width) this.vx *= -1;\r\n            if (this.y < 0 || this.y > height) this.vy *= -1;\r\n        }\r\n\r\n        draw(ctx) {\r\n            ctx.save();\r\n            ctx.translate(this.x, this.y);\r\n            ctx.rotate(this.angle);\r\n\r\n            if (this.type === 'co2') {\r\n                \/\/ CO2: Sort (C) i midten, to R\u00f8de (O) p\u00e5 siderne\r\n                \/\/ C\r\n                ctx.beginPath(); ctx.arc(0, 0, 6, 0, Math.PI*2); ctx.fillStyle = \"#333\"; ctx.fill();\r\n                \/\/ O'er\r\n                ctx.beginPath(); ctx.arc(-8, 0, 5, 0, Math.PI*2); ctx.fillStyle = \"#f44336\"; ctx.fill();\r\n                ctx.beginPath(); ctx.arc(8, 0, 5, 0, Math.PI*2); ctx.fillStyle = \"#f44336\"; ctx.fill();\r\n            } else {\r\n                \/\/ H2O: R\u00f8d (O) i midten, to Hvide (H) (Mickey Mouse)\r\n                \/\/ O\r\n                ctx.beginPath(); ctx.arc(0, 0, 6, 0, Math.PI*2); ctx.fillStyle = \"#f44336\"; ctx.fill();\r\n                \/\/ H'er (Mickey \u00f8rer)\r\n                ctx.beginPath(); ctx.arc(-5, -6, 4, 0, Math.PI*2); ctx.fillStyle = \"#fff\"; ctx.fill(); ctx.stroke();\r\n                ctx.beginPath(); ctx.arc(5, -6, 4, 0, Math.PI*2); ctx.fillStyle = \"#fff\"; ctx.fill(); ctx.stroke();\r\n            }\r\n            ctx.restore();\r\n        }\r\n    }\r\n\r\n    \/\/ --- Logik og Events ---\r\n    \r\n    window.triggerCombustion = function() {\r\n        \/\/ Tjek om vi er i gas-tilstand\r\n        \/\/ Vi tager en pr\u00f8ve fra den f\u00f8rste partikel\r\n        if (particles.length === 0 || isCombustionMode) return;\r\n        \r\n        \/\/ Find ud af om det koger\r\n        let sample = particles[0];\r\n        \/\/ Hvis mix-mode, tjek om metan koger (hvis den er der)\r\n        let boilPoint = sample.type.boil;\r\n        \r\n        \/\/ Sikkerhedsregel: Skal v\u00e6re varmere end kogepunktet for at ant\u00e6nde\r\n        if (currentTemp <= boilPoint) {\r\n            alert(\"\u26a0\ufe0f Du kan ikke ant\u00e6nde v\u00e6sken! Varm op indtil det er damp (gas).\");\r\n            return;\r\n        }\r\n\r\n        \/\/ START FORBR\u00c6NDING\r\n        isCombustionMode = true;\r\n        \r\n        \/\/ Visuel effekt\r\n        document.getElementById('canvasWrap').classList.add('flash-anim');\r\n        setTimeout(() => document.getElementById('canvasWrap').classList.remove('flash-anim'), 500);\r\n\r\n        \/\/ Skift tekst\r\n        document.getElementById('infoText').innerHTML = \"<b>BOOM! \ud83d\udca5<\/b> Kemisk reaktion! <br>Alkan + Ilt \u2192 CO\u2082 + Vand. <br>Reaktionen udvikler masser af varme!\";\r\n        document.getElementById('infoText').style.background = \"#fff3cd\";\r\n        document.getElementById('infoText').style.borderColor = \"#ffc107\";\r\n\r\n        \/\/ S\u00e6t temperatur til MAX (Exoterm reaktion)\r\n        currentTemp = 500; \r\n        document.getElementById('tempValue').innerText = \"MAX\";\r\n        document.getElementById('stateText').innerText = \"PLASMA \/ ILD \ud83d\udd25\";\r\n        document.getElementById('stateText').style.color = \"red\";\r\n\r\n        \/\/ Erstat partikler med Produkter (CO2 og H2O)\r\n        let count = particles.length;\r\n        particles = [];\r\n        for(let i=0; i<count; i++) {\r\n            \/\/ 50\/50 chance for CO2 eller H2O for simpel visualisering\r\n            let type = Math.random() > 0.5 ? 'co2' : 'h2o';\r\n            particles.push(new ProductParticle(type));\r\n        }\r\n    }\r\n\r\n    function animate() {\r\n        ctx.clearRect(0, 0, width, height);\r\n        \r\n        \/\/ V\u00e6ske linje (kun hvis ikke eksplosion)\r\n        if (!isCombustionMode) {\r\n            ctx.beginPath(); ctx.moveTo(0, height-100); ctx.lineTo(width, height-100); \r\n            ctx.strokeStyle = \"rgba(255,255,255,0.3)\"; ctx.stroke();\r\n        }\r\n\r\n        particles.forEach(p => {\r\n            p.update();\r\n            p.draw(ctx);\r\n        });\r\n        requestAnimationFrame(animate);\r\n    }\r\n\r\n    window.changeAlkane = function(key) {\r\n        resetMode();\r\n        let selected = alkanes[key];\r\n        \r\n        document.querySelectorAll('.btn-styled').forEach(b => b.classList.remove('active'));\r\n        document.getElementById('btn-' + key).classList.add('active');\r\n        document.getElementById('infoText').innerText = selected.txt;\r\n\r\n        particles = [];\r\n        const n = selected.carbons > 5 ? 60 : 100;\r\n        for(let i=0; i<n; i++) particles.push(new AlkaneParticle(selected));\r\n        updateUI();\r\n    };\r\n\r\n    window.startMix = function() {\r\n        resetMode();\r\n        isMixMode = true;\r\n        document.querySelectorAll('.btn-styled').forEach(b => b.classList.remove('active'));\r\n        document.getElementById('btn-mix').classList.add('active');\r\n        document.getElementById('infoText').innerText = \"BLANDING: Metan & Octan. Varm op og se forskellen.\";\r\n\r\n        currentTemp = -200;\r\n        document.getElementById('tempSlider').value = -200;\r\n        \r\n        particles = [];\r\n        for(let i=0; i<50; i++) particles.push(new AlkaneParticle(alkanes.metan));\r\n        for(let i=0; i<40; i++) particles.push(new AlkaneParticle(alkanes.octan));\r\n        updateUI();\r\n    };\r\n\r\n    function resetMode() {\r\n        isCombustionMode = false;\r\n        isMixMode = false;\r\n        document.getElementById('infoText').style.background = \"#eceff1\"; \/\/ Reset farve\r\n        document.getElementById('infoText').style.borderColor = \"#90a4ae\";\r\n        \/\/ Reset knap styles hvis n\u00f8dvendigt\r\n    }\r\n\r\n    function updateUI() {\r\n        if(isCombustionMode) return; \/\/ UI opdateres ikke under eksplosion\r\n\r\n        document.getElementById('tempValue').innerText = currentTemp;\r\n        let sText = document.getElementById('stateText');\r\n\r\n        if(isMixMode) {\r\n            if (currentTemp < -162) {\r\n                sText.innerText = \"Frossen \/ V\u00e6ske \u2744\ufe0f\"; sText.style.color = \"#1565C0\";\r\n            } else if (currentTemp < 126) {\r\n                sText.innerText = \"Metan fordamper! \ud83d\udd25\"; sText.style.color = \"#673AB7\";\r\n            } else {\r\n                sText.innerText = \"Alt fordamper \u2601\ufe0f\"; sText.style.color = \"#d84315\";\r\n            }\r\n        } else {\r\n            let type = particles[0].type;\r\n            if (currentTemp < type.melt) {\r\n                sText.innerText = \"Fast Stof \ud83e\uddca\"; sText.style.color = \"#37474F\";\r\n            } else if (currentTemp >= type.melt && currentTemp < type.boil) {\r\n                sText.innerText = \"V\u00e6ske \ud83d\udca7\"; sText.style.color = \"#0277bd\";\r\n            } else {\r\n                sText.innerText = \"Gas (Damp) \u2601\ufe0f\"; sText.style.color = \"#d84315\";\r\n            }\r\n        }\r\n    }\r\n\r\n    document.getElementById('tempSlider').oninput = function() {\r\n        if (isCombustionMode) {\r\n            \/\/ Hvis man r\u00f8rer slideren efter eksplosion, resetter vi til det valgte stof\r\n            let activeBtn = document.querySelector('.btn-styled.active');\r\n            if (activeBtn) activeBtn.click();\r\n            else if (document.getElementById('btn-mix').classList.contains('active')) startMix();\r\n        }\r\n        currentTemp = parseInt(this.value);\r\n        updateUI();\r\n    };\r\n\r\n    \/\/ Start\r\n    changeAlkane('metan'); \r\n    animate();\r\n};\r\n<\/script>\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-e39b02a elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"e39b02a\" data-element_type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-39642e9\" data-id=\"39642e9\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-e4e48f1 elementor-widget-divider--view-line elementor-widget elementor-widget-divider\" data-id=\"e4e48f1\" data-element_type=\"widget\" data-widget_type=\"divider.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-divider\">\n\t\t\t<span class=\"elementor-divider-separator\">\n\t\t\t\t\t\t<\/span>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-51c3c14 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"51c3c14\" data-element_type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-b5547e6\" data-id=\"b5547e6\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-26cda72 elementor-widget elementor-widget-html\" data-id=\"26cda72\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\r\n    \/* --- CSS variabler --- *\/\r\n    :root {\r\n        --bg-color: #f4f6f9;\r\n        --primary: #2c3e50;\r\n        --accent: #3498db;\r\n        --success: #27ae60;\r\n        --warning: #f39c12;\r\n        --danger: #c0392b;\r\n        --text: #34495e;\r\n        --panel-bg: #ffffff;\r\n    }\r\n\r\n    \/* --- GAME CONTAINER (Erstatter BODY) --- *\/\r\n    .game-container {\r\n        \/* Dette er den nye container, som kun p\u00e5virker dit spil *\/\r\n        font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;\r\n        background-color: var(--bg-color);\r\n        color: var(--text);\r\n        margin: 0;\r\n        display: flex;\r\n        flex-direction: column;\r\n        \r\n        \/* Sat til 900px, s\u00e5 det ikke fylder hele sk\u00e6rmen (100vh) *\/\r\n        height: 900px; \r\n        \/* Giver scrolling inde i spillet, hvis det fylder mere end 900px *\/\r\n        overflow: auto; \r\n    }\r\n\r\n    \/* --- HEADER --- *\/\r\n    .game-container header { \r\n        background: var(--primary);\r\n        color: white;\r\n        padding: 15px 25px;\r\n        display: flex;\r\n        justify-content: space-between;\r\n        align-items: center;\r\n        box-shadow: 0 4px 6px rgba(0,0,0,0.1);\r\n        z-index: 10;\r\n    }\r\n    \r\n    .header-title { font-size: 20px; font-weight: bold; display: flex; align-items: center; gap: 10px; }\r\n    .game-stats { display: flex; gap: 25px; font-size: 18px; font-weight: 500; }\r\n    .money-val { color: #f1c40f; font-weight: bold; text-shadow: 1px 1px 0 rgba(0,0,0,0.5); }\r\n    \r\n    .shop-btn {\r\n        background: var(--warning); border: none; padding: 10px 20px; \r\n        border-radius: 6px; font-weight: bold; cursor: pointer; color: #fff;\r\n        box-shadow: 0 4px 0 #d35400; transition: transform 0.1s;\r\n    }\r\n    .shop-btn:active { transform: translateY(4px); box-shadow: 0 0 0; }\r\n    \r\n    \/* Anti-Softlock knap *\/\r\n    .grant-btn {\r\n        background: none; border: 1px solid rgba(255,255,255,0.3); color: #aaa;\r\n        padding: 5px 10px; font-size: 10px; cursor: pointer; margin-left: 20px;\r\n    }\r\n\r\n    \/* --- LAYOUT --- *\/\r\n    .main-layout {\r\n        display: flex;\r\n        flex: 1;\r\n        padding: 20px;\r\n        gap: 20px;\r\n        \/* Tillader spillet at scrolle internt, hvis content fylder mere end 900px *\/\r\n        overflow: hidden; \r\n        height: 100%; \/* S\u00f8rger for at layoutet fylder containeren *\/\r\n    }\r\n\r\n    .panel {\r\n        background: var(--panel-bg);\r\n        border-radius: 12px;\r\n        box-shadow: 0 5px 15px rgba(0,0,0,0.05);\r\n        display: flex;\r\n        flex-direction: column;\r\n        overflow: hidden;\r\n    }\r\n    .panel-header {\r\n        padding: 15px; background: #ecf0f1; border-bottom: 1px solid #bdc3c7;\r\n        font-weight: bold; color: var(--primary); display: flex; justify-content: space-between; align-items: center;\r\n    }\r\n\r\n    \/* --- LAGER --- *\/\r\n    .inventory-panel { flex: 1; min-width: 250px; }\r\n    .inventory-grid {\r\n        padding: 15px; overflow-y: auto; display: grid; grid-template-columns: repeat(auto-fill, minmax(90px, 1fr)); gap: 12px;\r\n    }\r\n    .chem-card {\r\n        background: #fff; border: 2px solid #e0e0e0; border-radius: 8px; padding: 10px;\r\n        text-align: center; cursor: pointer; position: relative; transition: all 0.2s;\r\n    }\r\n    .chem-card:hover { border-color: var(--accent); transform: translateY(-3px); box-shadow: 0 5px 10px rgba(0,0,0,0.1); }\r\n    .chem-icon { font-size: 28px; display: block; margin-bottom: 5px; }\r\n    .chem-name { font-size: 12px; font-weight: bold; line-height: 1.3; display: block; }\r\n    .chem-formula { font-size: 10px; color: #7f8c8d; font-family: monospace; }\r\n    .chem-badge {\r\n        position: absolute; top: -8px; right: -8px; background: var(--primary); color: white;\r\n        font-size: 11px; font-weight: bold; width: 24px; height: 24px; line-height: 24px;\r\n        border-radius: 50%; box-shadow: 0 2px 5px rgba(0,0,0,0.2);\r\n    }\r\n\r\n    \/* --- REAKTOR --- *\/\r\n    .reactor-panel { flex: 2; display: flex; flex-direction: column; }\r\n    .reactor-visual {\r\n        flex: 1; display: flex; justify-content: center; align-items: center;\r\n        background: radial-gradient(circle at center, #fdfdfd, #ecf0f1); position: relative; border-bottom: 1px solid #ddd;\r\n    }\r\n    .flask-container { width: 180px; height: 240px; position: relative; }\r\n    .flask-neck {\r\n        width: 50px; height: 80px; background: rgba(255,255,255,0.4); border: 3px solid #7f8c8d; border-bottom: none;\r\n        position: absolute; top: 0; left: 65px; z-index: 2;\r\n    }\r\n    .flask-body {\r\n        width: 180px; height: 160px; background: rgba(255,255,255,0.4); border: 3px solid #7f8c8d; border-radius: 50% 50% 10px 10px;\r\n        position: absolute; top: 70px; left: 0; z-index: 1; overflow: hidden;\r\n    }\r\n    .flask-liquid {\r\n        width: 100%; height: 0%; background: var(--accent); position: absolute; bottom: 0; \r\n        transition: height 0.5s, background-color 1s; opacity: 0.8;\r\n    }\r\n    .bubbles {\r\n        width: 100%; height: 100%; position: absolute; bottom: 0; opacity: 0;\r\n        background-image: radial-gradient(rgba(255,255,255,0.5) 20%, transparent 20%);\r\n        background-size: 15px 15px; animation: bubbleAnim 1s infinite linear;\r\n    }\r\n    @keyframes bubbleAnim { from {background-position: 0 0;} to {background-position: 0 -30px;} }\r\n\r\n    .slots-overlay {\r\n        position: absolute; top: 20px; width: 100%; display: flex; justify-content: center; gap: 150px; pointer-events: none;\r\n    }\r\n    .slot-box {\r\n        width: 90px; height: 90px; background: white; border: 2px dashed #bdc3c7; border-radius: 10px;\r\n        display: flex; flex-direction: column; align-items: center; justify-content: center;\r\n        font-size: 11px; color: #95a5a6; pointer-events: auto; cursor: pointer; box-shadow: 0 5px 15px rgba(0,0,0,0.1);\r\n    }\r\n    .slot-box.filled { border-style: solid; border-color: var(--accent); color: var(--text); }\r\n\r\n    .reactor-controls {\r\n        padding: 20px; background: white; display: grid; grid-template-columns: 1fr 1fr; gap: 20px;\r\n    }\r\n    .control-group label { display: block; font-weight: bold; margin-bottom: 8px; font-size: 14px; }\r\n    .cat-buttons { display: flex; background: #ecf0f1; border-radius: 8px; padding: 4px; }\r\n    .cat-btn {\r\n        flex: 1; border: none; background: transparent; padding: 8px; border-radius: 6px; cursor: pointer; font-size: 12px; font-weight: bold;\r\n    }\r\n    .cat-btn.active { background: white; box-shadow: 0 2px 5px rgba(0,0,0,0.1); color: var(--accent); }\r\n    .temp-control { display: flex; align-items: center; gap: 10px; }\r\n    input[type=range] { flex: 1; }\r\n    .synthesize-btn {\r\n        grid-column: span 2; background: var(--success); color: white; border: none; padding: 15px;\r\n        border-radius: 8px; font-size: 18px; font-weight: bold; cursor: pointer; box-shadow: 0 4px 0 #219150; transition: all 0.1s;\r\n    }\r\n    .synthesize-btn:active { transform: translateY(4px); box-shadow: none; }\r\n\r\n    \/* --- QUEST BOX (NY) --- *\/\r\n    .info-panel { flex: 1; min-width: 250px; display: flex; flex-direction: column; }\r\n    \r\n    .quest-box {\r\n        background: #fff8e1; border: 2px solid #ffecb3; padding: 20px; margin: 15px; border-radius: 10px;\r\n        box-shadow: 0 4px 10px rgba(0,0,0,0.05); position: relative;\r\n    }\r\n    .quest-title { font-weight: bold; color: #f39c12; font-size: 12px; text-transform: uppercase; margin-bottom: 5px; letter-spacing: 1px;}\r\n    .quest-name { font-size: 18px; font-weight: bold; color: #2c3e50; margin-bottom: 10px; }\r\n    .quest-desc { font-size: 13px; color: #555; line-height: 1.5; }\r\n    .quest-progress { margin-top: 10px; background: #ddd; height: 6px; border-radius: 3px; overflow: hidden; }\r\n    .quest-bar { height: 100%; width: 0%; background: #f39c12; transition: width 0.5s; }\r\n\r\n    .log-list {\r\n        flex: 1; padding: 15px; overflow-y: auto; font-family: monospace; font-size: 12px; background: #2c3e50; color: #ecf0f1;\r\n    }\r\n    .log-entry { margin-bottom: 8px; border-bottom: 1px solid #34495e; padding-bottom: 4px; }\r\n    .log-success { color: #2ecc71; }\r\n    .log-error { color: #e74c3c; }\r\n\r\n    \/* --- MODALS --- *\/\r\n    \/* Modals skal ligge fast over hele sk\u00e6rmen, s\u00e5 de har stadig 'position: fixed' *\/\r\n    .modal {\r\n        position: fixed; top: 0; left: 0; width: 100%; height: 100%;\r\n        background: rgba(0,0,0,0.6); backdrop-filter: blur(3px);\r\n        display: flex; justify-content: center; align-items: center; z-index: 100;\r\n    }\r\n    .hidden { display: none; }\r\n    \r\n    \/* SHOP *\/\r\n    .shop-container {\r\n        background: white; width: 800px; height: 80%; border-radius: 12px; display: flex; flex-direction: column; overflow: hidden;\r\n        box-shadow: 0 20px 50px rgba(0,0,0,0.3);\r\n    }\r\n    .shop-header { padding: 20px; background: var(--primary); color: white; display: flex; justify-content: space-between; align-items: center; }\r\n    .shop-tabs { display: flex; background: #ecf0f1; padding: 10px 20px 0 20px; gap: 5px; }\r\n    .tab { padding: 10px 20px; background: #bdc3c7; border-radius: 8px 8px 0 0; cursor: pointer; font-weight: bold; color: #555; }\r\n    .tab.active { background: white; color: var(--primary); }\r\n    .shop-content { padding: 20px; overflow-y: auto; flex: 1; background: white; }\r\n    .shop-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 15px; }\r\n    .shop-item {\r\n        border: 1px solid #eee; border-radius: 8px; padding: 15px; display: flex; flex-direction: column; align-items: center; text-align: center;\r\n    }\r\n    .shop-item:hover { border-color: var(--accent); }\r\n    .buy-btn { background: var(--accent); color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer; width: 100%; margin-top: 10px;}\r\n    \r\n    \/* VICTORY \/ MESSAGE *\/\r\n    .msg-box {\r\n        background: white; width: 400px; padding: 30px; border-radius: 15px; text-align: center;\r\n        box-shadow: 0 10px 40px rgba(0,0,0,0.4); animation: popIn 0.3s;\r\n    }\r\n    @keyframes popIn { from {transform: scale(0.8); opacity:0;} to {transform: scale(1); opacity:1;} }\r\n    .msg-icon { font-size: 60px; margin-bottom: 20px; display: block; }\r\n    .msg-title { font-size: 24px; font-weight: bold; margin-bottom: 10px; color: var(--primary); }\r\n    .msg-body { color: #555; margin-bottom: 25px; line-height: 1.5; }\r\n    .msg-btn {\r\n        background: var(--success); color: white; border: none; padding: 12px 30px;\r\n        border-radius: 50px; font-size: 16px; font-weight: bold; cursor: pointer;\r\n    }\r\n<\/style>\r\n\r\n<div class=\"game-container\"> \r\n\r\n    <header>\r\n        <div class=\"header-title\">\r\n            <span style=\"font-size:24px\">\u2697\ufe0f<\/span>\r\n            <div>\r\n                <div>Syntese-Tycoon<\/div>\r\n                <div style=\"font-size:12px; opacity:0.8;\">QUEST MODE<\/div>\r\n            <\/div>\r\n        <\/div>\r\n        \r\n        <div class=\"game-stats\">\r\n            <span class=\"money-val\"><span id=\"moneyVal\">250<\/span> kr.<\/span>\r\n            <button class=\"grant-btn\" onclick=\"grantMoney()\" title=\"N\u00f8d-midler hvis du sidder fast\">S\u00f8g Fondsmidler<\/button>\r\n        <\/div>\r\n\r\n        <button class=\"shop-btn\" onclick=\"toggleShop()\">\ud83d\uded2 VAREHUS<\/button>\r\n    <\/header>\r\n\r\n    <div class=\"main-layout\">\r\n        \r\n        <div class=\"panel inventory-panel\">\r\n            <div class=\"panel-header\">\r\n                Lager\r\n                <button onclick=\"sellAll()\" style=\"font-size:11px; padding:4px 8px; cursor:pointer;\">S\u00e6lg F\u00e6rdigvarer<\/button>\r\n            <\/div>\r\n            <div id=\"inventoryGrid\" class=\"inventory-grid\"><\/div>\r\n        <\/div>\r\n\r\n        <div class=\"panel reactor-panel\">\r\n            <div class=\"panel-header\">Reaktionskolbe<\/div>\r\n            \r\n            <div class=\"reactor-visual\">\r\n                <div class=\"slots-overlay\">\r\n                    <div class=\"slot-box\" id=\"slotA\" onclick=\"clearSlot('A')\">\r\n                        <div style=\"font-size:20px; margin-bottom:5px;\">\u2795<\/div>\r\n                        Klik i lager<br>for at tilf\u00f8je\r\n                    <\/div>\r\n                    <div class=\"slot-box\" id=\"slotB\" onclick=\"clearSlot('B')\">\r\n                        <div style=\"font-size:20px; margin-bottom:5px;\">\u2795<\/div>\r\n                        Klik i lager<br>for at tilf\u00f8je\r\n                    <\/div>\r\n                <\/div>\r\n\r\n                <div class=\"flask-container\">\r\n                    <div class=\"flask-neck\"><\/div>\r\n                    <div class=\"flask-body\">\r\n                        <div class=\"flask-liquid\" id=\"liquid\"><\/div>\r\n                        <div class=\"bubbles\" id=\"bubbles\"><\/div>\r\n                    <\/div>\r\n                <\/div>\r\n            <\/div>\r\n\r\n            <div class=\"reactor-controls\">\r\n                <div class=\"control-group\">\r\n                    <label>Katalysator:<\/label>\r\n                    <div class=\"cat-buttons\">\r\n                        <button class=\"cat-btn active\" id=\"catNone\" onclick=\"setCat('none')\">Ingen<\/button>\r\n                        <button class=\"cat-btn\" id=\"catAcid\" onclick=\"setCat('H+')\">Syre (H\u207a)<\/button>\r\n                    <\/div>\r\n                <\/div>\r\n                <div class=\"control-group\">\r\n                    <label>Temperatur: <span id=\"tempDisplay\" style=\"color:var(--danger)\">20\u00b0C<\/span><\/label>\r\n                    <div class=\"temp-control\">\r\n                        <span style=\"font-size:12px\">Kold<\/span>\r\n                        <input type=\"range\" min=\"20\" max=\"150\" value=\"20\" oninput=\"updateTemp(this.value)\">\r\n                        <span style=\"font-size:12px\">Varm<\/span>\r\n                    <\/div>\r\n                <\/div>\r\n                <button class=\"synthesize-btn\" onclick=\"synthesize()\">START SYNTESE<\/button>\r\n            <\/div>\r\n        <\/div>\r\n\r\n        <div class=\"panel info-panel\">\r\n            \r\n            <div class=\"quest-box\" id=\"questBox\">\r\n                <div class=\"quest-title\">NUV\u00c6RENDE MISSION (1\/5)<\/div>\r\n                <div class=\"quest-name\" id=\"questName\">Opstarten<\/div>\r\n                <div class=\"quest-desc\" id=\"questDesc\">Velkommen til fabrikken. F\u00f8r vi kan producere, skal vi have r\u00e5varer. G\u00e5 i Varehuset og k\u00f8b Ethanol og Oxidationsmiddel.<\/div>\r\n                <div class=\"quest-progress\"><div class=\"quest-bar\" id=\"questBar\"><\/div><\/div>\r\n            <\/div>\r\n\r\n            <div class=\"panel-header\" style=\"border-top:1px solid #ddd;\">Log<\/div>\r\n            <div class=\"log-list\" id=\"gameLog\">\r\n                <div class=\"log-entry\">> Velkommen, Laborant.<\/div>\r\n                <div class=\"log-entry\">> F\u00f8lg missionen \u00f8verst til h\u00f8jre.<\/div>\r\n            <\/div>\r\n        <\/div>\r\n\r\n    <\/div>\r\n\r\n<\/div> \r\n<div id=\"shopModal\" class=\"modal hidden\">\r\n    <div class=\"shop-container\">\r\n        <div class=\"shop-header\">\r\n            <span style=\"font-size:22px; font-weight:bold;\">Kemikalie Grossisten<\/span>\r\n            <button class=\"close-shop\" onclick=\"toggleShop()\">\u00d7<\/button>\r\n        <\/div>\r\n        <div class=\"shop-tabs\">\r\n            <div class=\"tab active\" onclick=\"setShopTab('alcohol')\">Alkoholer<\/div>\r\n            <div class=\"tab\" onclick=\"setShopTab('acid')\">Syrer & Aromater<\/div>\r\n            <div class=\"tab\" onclick=\"setShopTab('reagent')\">Reagenser<\/div>\r\n        <\/div>\r\n        <div class=\"shop-content\">\r\n            <div class=\"shop-grid\" id=\"shopGrid\"><\/div>\r\n        <\/div>\r\n    <\/div>\r\n<\/div>\r\n\r\n<div id=\"msgModal\" class=\"modal hidden\">\r\n    <div class=\"msg-box\">\r\n        <div class=\"msg-icon\" id=\"msgIcon\">\ud83c\udfc6<\/div>\r\n        <div class=\"msg-title\" id=\"msgTitle\">Titel<\/div>\r\n        <div class=\"msg-body\" id=\"msgBody\">Indhold<\/div>\r\n        <button class=\"msg-btn\" onclick=\"closeMsg()\">FORTS\u00c6T<\/button>\r\n    <\/div>\r\n<\/div>\r\n\r\n<script>\r\n    \/\/ --- QUEST DATA ---\r\n    const quests = [\r\n        {\r\n            id: 1,\r\n            title: \"Indk\u00f8b\",\r\n            desc: \"For at lave kemi skal vi bruge stoffer. K\u00f8b 1x Ethanol og 1x Oxidationsmiddel i shoppen.\",\r\n            check: () => (inventory['ethanol'] >= 1 && inventory['oxidizer'] >= 1),\r\n            reward: 50,\r\n            msg: \"Godt! Du har nu ingredienserne til din f\u00f8rste reaktion.\"\r\n        },\r\n        {\r\n            id: 2,\r\n            title: \"Oxidation\",\r\n            desc: \"Vi skal lave Ethansyre. Bland Ethanol og Oxidationsmiddel i kolben. Brug varme (>60\u00b0C).\",\r\n            check: () => (inventory['ethansyre'] >= 1),\r\n            reward: 100,\r\n            msg: \"Succes! Ethanol blev oxideret til Ethansyre. Du har nu en carboxylsyre.\"\r\n        },\r\n        {\r\n            id: 3,\r\n            title: \"Kondensation\",\r\n            desc: \"Lad os lave duftstof (Ester). K\u00f8b Pentanol og reag\u00e9r det med din Ethansyre. HUSK: Dette kr\u00e6ver H+ katalysator!\",\r\n            check: () => (inventory['pentylethanoat'] >= 1),\r\n            reward: 300,\r\n            msg: \"Fantastisk! Du har lavet Banan-duft (Pentylethanoat). Estere dufter godt og kan s\u00e6lges dyrt.\"\r\n        },\r\n        {\r\n            id: 4,\r\n            title: \"Kapitalisme\",\r\n            desc: \"Vi skal bruge penge til det store projekt. Tjen 1000 kr ved at producere og s\u00e6lge stoffer (f.eks. mere banan-duft).\",\r\n            check: () => (money >= 1000),\r\n            reward: 0,\r\n            msg: \"Du har nu kapital nok til at k\u00f8be de dyre aromatiske stoffer.\"\r\n        },\r\n        {\r\n            id: 5,\r\n            title: \"Svendestykket\",\r\n            desc: \"Den ultimative test: Producer ASPIRIN. Du skal bruge Salicylsyre (k\u00f8b) og Ethansyre (lav selv).\",\r\n            check: () => (inventory['aspirin'] >= 1),\r\n            reward: 1000,\r\n            msg: \"DU GJORDE DET! Du har syntetiseret medicin fra bunden.\"\r\n        }\r\n    ];\r\n    let currentQuestIdx = 0;\r\n\r\n    \/\/ --- DATABASE ---\r\n    const chemicals = {\r\n        'ethanol': { name: 'Ethanol', formula: 'C2H5OH', type: 'alcohol', price: 20, icon: '\ud83e\uddea' },\r\n        'pentanol': { name: 'Pentan-1-ol', formula: 'C5H11OH', type: 'alcohol', price: 40, icon: '\ud83e\uddea' },\r\n        'salicylsyre': { name: 'Salicylsyre', formula: 'C7H6O3', type: 'acid', price: 150, icon: '\ud83d\udc8a' },\r\n        'ethansyre': { name: 'Ethansyre', formula: 'CH3COOH', type: 'acid', price: 0, sell: 40, icon: '\ud83c\udf4b' },\r\n        'pentylethanoat': { name: 'Pentyl-ethanoat', formula: 'Ester', type: 'ester', price: 0, sell: 350, icon: '\ud83c\udf4c' },\r\n        'aspirin': { name: 'Acetylsalicylsyre', formula: 'Aspirin', type: 'pharma', price: 0, sell: 800, icon: '\u2695\ufe0f' },\r\n        'oxidizer': { name: 'KMnO4 (Ox)', formula: 'Oxidationsmiddel', type: 'reagent', price: 50, icon: '\ud83d\udd25' },\r\n    };\r\n\r\n    const recipes = [\r\n        { in: ['ethanol', 'oxidizer'], out: 'ethansyre', temp: 60, cat: 'any', msg: 'Oxidation: Ethanol -> Ethansyre' },\r\n        { in: ['pentanol', 'oxidizer'], out: 'pentansyre', temp: 60, cat: 'any', msg: 'Oxidation: Pentanol -> Pentansyre' },\r\n        { in: ['ethanol', 'ethansyre'], out: 'ethylethanoat', temp: 50, cat: 'H+', msg: 'Kondensation: P\u00e6re-duft dannet!' },\r\n        { in: ['pentanol', 'ethansyre'], out: 'pentylethanoat', temp: 50, cat: 'H+', msg: 'Kondensation: Banan-duft dannet!' },\r\n        { in: ['salicylsyre', 'ethansyre'], out: 'aspirin', temp: 70, cat: 'H+', msg: 'SUCCESS! ASPIRIN FREMSTILLET!' }\r\n    ];\r\n\r\n    \/\/ --- STATE ---\r\n    let money = 250;\r\n    let inventory = {};\r\n    let slots = { A: null, B: null };\r\n    let currentTemp = 20;\r\n    let currentCat = 'none';\r\n    let currentShopTab = 'alcohol';\r\n\r\n    \/\/ --- INIT ---\r\n    function init() {\r\n        updateUI();\r\n        updateQuestUI();\r\n    }\r\n\r\n    \/\/ --- QUEST LOGIC ---\r\n    function checkQuests() {\r\n        if(currentQuestIdx >= quests.length) return; \/\/ F\u00e6rdig\r\n\r\n        const q = quests[currentQuestIdx];\r\n        if (q.check()) {\r\n            \/\/ Quest complete!\r\n            money += q.reward;\r\n            showMsg(\"MISSION FULDF\u00d8RT!\", q.msg + (q.reward > 0 ? `<br><br><b>Bel\u00f8nning: ${q.reward} kr.<\/b>` : \"\"));\r\n            \r\n            currentQuestIdx++;\r\n            if (currentQuestIdx >= quests.length) {\r\n                \/\/ VICTORY\r\n                setTimeout(() => showVictory(), 2000);\r\n            }\r\n            updateQuestUI();\r\n            updateUI();\r\n        }\r\n    }\r\n\r\n    function updateQuestUI() {\r\n        const box = document.getElementById('questBox');\r\n        if(currentQuestIdx >= quests.length) {\r\n            box.style.background = \"#d4edda\";\r\n            box.style.borderColor = \"#c3e6cb\";\r\n            document.getElementById('questName').innerText = \"SPILLET ER GENNEMF\u00d8RT\";\r\n            document.getElementById('questDesc').innerText = \"Du er nu en mester i organisk syntese!\";\r\n            return;\r\n        }\r\n\r\n        const q = quests[currentQuestIdx];\r\n        box.querySelector('.quest-title').innerText = `NUV\u00c6RENDE MISSION (${currentQuestIdx+1}\/${quests.length})`;\r\n        document.getElementById('questName').innerText = q.title;\r\n        document.getElementById('questDesc').innerText = q.desc;\r\n        \r\n        \/\/ Progress bar (simpel 0 eller 100 for nu, da logikken er bin\u00e6r)\r\n        document.getElementById('questBar').style.width = \"0%\";\r\n    }\r\n\r\n    \/\/ --- UI UPDATES ---\r\n    function updateUI() {\r\n        document.getElementById('moneyVal').innerText = money;\r\n        renderInventory();\r\n        renderShop();\r\n    }\r\n\r\n    function renderInventory() {\r\n        const grid = document.getElementById('inventoryGrid');\r\n        grid.innerHTML = '';\r\n        for (let [key, count] of Object.entries(inventory)) {\r\n            if (count > 0) {\r\n                let item = chemicals[key];\r\n                let card = document.createElement('div');\r\n                card.className = 'chem-card';\r\n                card.innerHTML = `\r\n                    <div class=\"chem-badge\">${count}<\/div>\r\n                    <span class=\"chem-icon\">${item.icon}<\/span>\r\n                    <span class=\"chem-name\">${item.name}<\/span>\r\n                `;\r\n                card.onclick = () => addToSlot(key);\r\n                grid.appendChild(card);\r\n            }\r\n        }\r\n    }\r\n\r\n    function renderShop() {\r\n        const grid = document.getElementById('shopGrid');\r\n        grid.innerHTML = '';\r\n        let filtered = Object.keys(chemicals).filter(k => {\r\n            let type = chemicals[k].type;\r\n            if (currentShopTab === 'alcohol') return type === 'alcohol';\r\n            if (currentShopTab === 'acid') return type === 'acid' || type === 'pharma';\r\n            if (currentShopTab === 'reagent') return type === 'reagent';\r\n            return false;\r\n        });\r\n\r\n        filtered.forEach(key => {\r\n            let item = chemicals[key];\r\n            if (item.price > 0) { \r\n                let card = document.createElement('div');\r\n                card.className = 'shop-item';\r\n                card.innerHTML = `\r\n                    <div style=\"font-size:30px; margin-bottom:10px;\">${item.icon}<\/div>\r\n                    <div style=\"font-weight:bold; margin-bottom:5px;\">${item.name}<\/div>\r\n                    <div class=\"shop-price\">${item.price} kr<\/div>\r\n                    <button class=\"buy-btn\" onclick=\"buy('${key}')\">K\u00f8b<\/button>\r\n                `;\r\n                grid.appendChild(card);\r\n            }\r\n        });\r\n    }\r\n\r\n    function updateTemp(val) {\r\n        currentTemp = parseInt(val);\r\n        document.getElementById('tempDisplay').innerText = val + \"\u00b0C\";\r\n        let liquid = document.getElementById('liquid');\r\n        if(currentTemp > 80) {\r\n            liquid.style.backgroundColor = \"#e74c3c\"; \r\n            document.getElementById('bubbles').style.opacity = 1;\r\n        } else {\r\n            liquid.style.backgroundColor = \"#3498db\"; \r\n            document.getElementById('bubbles').style.opacity = 0;\r\n        }\r\n    }\r\n\r\n    function setCat(cat) {\r\n        currentCat = cat;\r\n        document.getElementById('catNone').classList.remove('active');\r\n        document.getElementById('catAcid').classList.remove('active');\r\n        if(cat === 'none') document.getElementById('catNone').classList.add('active');\r\n        else document.getElementById('catAcid').classList.add('active');\r\n    }\r\n\r\n    \/\/ --- ACTIONS ---\r\n    function addToSlot(key) {\r\n        if (!slots.A) { slots.A = key; updateSlotUI('A'); }\r\n        else if (!slots.B) { slots.B = key; updateSlotUI('B'); }\r\n        else { log(\"Kolben er fuld!\", 'err'); }\r\n    }\r\n    function clearSlot(slotName) {\r\n        slots[slotName] = null;\r\n        updateSlotUI(slotName);\r\n    }\r\n    function updateSlotUI(slotName) {\r\n        let key = slots[slotName];\r\n        let el = document.getElementById('slot' + slotName);\r\n        if (key) {\r\n            let item = chemicals[key];\r\n            el.innerHTML = `<span style=\"font-size:24px\">${item.icon}<\/span><br>${item.name}`;\r\n            el.classList.add('filled');\r\n        } else {\r\n            el.innerHTML = `<div style=\"font-size:20px; margin-bottom:5px;\">\u2795<\/div>Klik i lager<br>for at tilf\u00f8je`;\r\n            el.classList.remove('filled');\r\n        }\r\n    }\r\n\r\n    function buy(key) {\r\n        let item = chemicals[key];\r\n        if (money >= item.price) {\r\n            money -= item.price;\r\n            inventory[key] = (inventory[key] || 0) + 1;\r\n            updateUI();\r\n            log(`K\u00f8bte ${item.name}`, 'succ');\r\n            checkQuests(); \/\/ Check if quest complete\r\n        } else {\r\n            log(\"Ikke nok penge!\", 'err');\r\n        }\r\n    }\r\n\r\n    function synthesize() {\r\n        if (!slots.A || !slots.B) { log(\"Mangler reaktanter!\", 'err'); return; }\r\n        if ((inventory[slots.A] || 0) > 0 && (inventory[slots.B] || 0) > 0) {\r\n            inventory[slots.A]--; inventory[slots.B]--;\r\n        } else {\r\n            log(\"Lager tomt!\", 'err'); return;\r\n        }\r\n        updateUI();\r\n\r\n        let liq = document.getElementById('liquid');\r\n        liq.style.height = \"80%\";\r\n        log(\"Reaktion i gang...\");\r\n\r\n        setTimeout(() => {\r\n            liq.style.height = \"0%\";\r\n            checkReactionResult();\r\n        }, 1500);\r\n    }\r\n\r\n    function checkReactionResult() {\r\n        let inputs = [slots.A, slots.B].sort();\r\n        let match = null;\r\n\r\n        for (let r of recipes) {\r\n            let rInputs = r.in.sort();\r\n            if (JSON.stringify(inputs) === JSON.stringify(rInputs)) {\r\n                let tempOK = currentTemp >= r.temp;\r\n                let catOK = (r.cat === 'any') || (r.cat === currentCat);\r\n                if (tempOK && catOK) match = r;\r\n                else {\r\n                    if(!tempOK) log(`Fejl: Temperatur for lav!`, 'err');\r\n                    if(!catOK) log(`Fejl: Forkert katalysator!`, 'err');\r\n                    clearSlot('A'); clearSlot('B'); return;\r\n                }\r\n            }\r\n        }\r\n\r\n        if (match) {\r\n            inventory[match.out] = (inventory[match.out] || 0) + 1;\r\n            log(match.msg, 'succ');\r\n            checkQuests(); \/\/ Check quests on success\r\n        } else {\r\n            log(\"Reaktionen fejlede.\", 'err');\r\n        }\r\n\r\n        clearSlot('A'); clearSlot('B');\r\n        updateUI();\r\n    }\r\n\r\n    function sellAll() {\r\n        let earned = 0;\r\n        for (let [key, count] of Object.entries(inventory)) {\r\n            let item = chemicals[key];\r\n            if (count > 0 && item.sell && item.sell > 0) {\r\n                let total = count * item.sell;\r\n                money += total; earned += total;\r\n                inventory[key] = 0;\r\n            }\r\n        }\r\n        if(earned > 0) { \r\n            log(`Solgte varer for ${earned} kr.`, 'succ'); \r\n            checkQuests(); \/\/ Check if money quest complete\r\n        }\r\n        else log(\"Intet salgbart p\u00e5 lager.\");\r\n        updateUI();\r\n    }\r\n    \r\n    function grantMoney() {\r\n        money += 100;\r\n        log(\"Fondsmidler modtaget (+100 kr)\", 'succ');\r\n        updateUI();\r\n        checkQuests();\r\n    }\r\n\r\n    \/\/ --- MODALS ---\r\n    function showMsg(title, body) {\r\n        document.getElementById('msgIcon').innerText = \"\ud83d\udcdc\";\r\n        document.getElementById('msgTitle').innerText = title;\r\n        document.getElementById('msgBody').innerHTML = body;\r\n        document.getElementById('msgModal').classList.remove('hidden');\r\n    }\r\n    \r\n    function showVictory() {\r\n        document.getElementById('msgIcon').innerText = \"\ud83c\udf93\";\r\n        document.getElementById('msgTitle').innerText = \"CERTIFIKAT\";\r\n        document.getElementById('msgBody').innerHTML = \"Tillykke! Du har gennemf\u00f8rt kurset i Organisk Syntese.<br>Du har bevist at du kan fremstille komplekse stoffer, styre \u00f8konomien og forst\u00e5 kemien.\";\r\n        document.getElementById('msgModal').classList.remove('hidden');\r\n    }\r\n\r\n    function closeMsg() { document.getElementById('msgModal').classList.add('hidden'); }\r\n    function toggleShop() { document.getElementById('shopModal').classList.toggle('hidden'); }\r\n    function setShopTab(tab) {\r\n        currentShopTab = tab;\r\n        document.querySelectorAll('.shop-tabs .tab').forEach(t => t.classList.remove('active'));\r\n        \/\/ Find den rigtige knap og aktiv\u00e9r den\r\n        document.querySelector(`.shop-tabs .tab[onclick*='${tab}']`).classList.add('active'); \r\n        renderShop();\r\n    }\r\n    function log(msg, type) {\r\n        let div = document.createElement('div'); div.className = 'log-entry';\r\n        if(type === 'succ') div.classList.add('log-success');\r\n        if(type === 'err') div.classList.add('log-error');\r\n        div.innerText = \"> \" + msg;\r\n        document.getElementById('gameLog').prepend(div);\r\n    }\r\n\r\n    init();\r\n\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-2552267 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"2552267\" data-element_type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-bf2cf1d\" data-id=\"bf2cf1d\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-cf62a47 elementor-widget-divider--view-line elementor-widget elementor-widget-divider\" data-id=\"cf62a47\" data-element_type=\"widget\" data-widget_type=\"divider.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-divider\">\n\t\t\t<span class=\"elementor-divider-separator\">\n\t\t\t\t\t\t<\/span>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e6d6dc9 elementor-widget elementor-widget-html\" data-id=\"e6d6dc9\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"da\">\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n    <title>Ethanol: St\u00e6rkere London-kr\u00e6fter<\/title>\r\n    <style>\r\n        body {\r\n            font-family: 'Segoe UI', Roboto, sans-serif;\r\n            background-color: #f0f2f5;\r\n            display: flex;\r\n            flex-direction: column;\r\n            align-items: center;\r\n            padding: 20px;\r\n            color: #333;\r\n        }\r\n\r\n        h1 { margin-bottom: 5px; color: #2c3e50; }\r\n        p { margin-bottom: 20px; color: #555; max-width: 700px; text-align: center; line-height:1.5; }\r\n\r\n        .main-container {\r\n            display: flex;\r\n            gap: 25px;\r\n            background: white;\r\n            padding: 30px;\r\n            border-radius: 16px;\r\n            box-shadow: 0 10px 25px rgba(0,0,0,0.08);\r\n            flex-wrap: wrap;\r\n            justify-content: center;\r\n        }\r\n\r\n        .canvas-wrapper {\r\n            position: relative;\r\n            width: 500px;\r\n            height: 500px;\r\n            border-radius: 50%;\r\n            border: 8px solid #607D8B;\r\n            background: radial-gradient(circle, #ffffff 40%, #eceff1 100%);\r\n            overflow: hidden;\r\n            box-shadow: inset 0 0 20px rgba(0,0,0,0.1);\r\n        }\r\n\r\n        canvas { display: block; width: 100%; height: 100%; }\r\n\r\n        .controls-panel {\r\n            width: 300px;\r\n            display: flex;\r\n            flex-direction: column;\r\n            gap: 15px;\r\n            justify-content: center;\r\n        }\r\n\r\n        .slider-card {\r\n            background: #fff3e0;\r\n            padding: 15px;\r\n            border-radius: 12px;\r\n            border: 1px solid #ffe0b2;\r\n            text-align: center;\r\n        }\r\n\r\n        .temp-display { font-size: 24px; font-weight: 900; color: #d32f2f; margin: 10px 0; }\r\n        input[type=range] { width: 100%; cursor: pointer; }\r\n\r\n        .legend {\r\n            background: #fafafa; padding: 15px; border-radius: 10px; font-size: 13px; border: 1px solid #eee;\r\n        }\r\n        .legend-item { display: flex; align-items: center; margin-bottom: 8px; }\r\n        \r\n        .line-h { width: 25px; height: 0; border-top: 3px dashed red; margin-right: 8px; }\r\n        .line-london { width: 25px; height: 0; border-top: 3px dotted #555; margin-right: 8px; } \/* Gjort m\u00f8rkere\/tykkere *\/\r\n\r\n        .toggles { display: flex; gap: 10px; flex-direction: column; }\r\n        .checkbox-label { display: flex; align-items: center; cursor: pointer; font-weight: 500; font-size: 14px;}\r\n        .checkbox-label input { margin-right: 10px; width: 18px; height: 18px; }\r\n\r\n    <\/style>\r\n<\/head>\r\n<body>\r\n\r\n    <h1>Ethanol: Bindinger i Balance<\/h1>\r\n    <p>Nu er London-kr\u00e6fterne (mellem halerne) st\u00e6rkere, s\u00e5 du tydeligt kan se, at de upol\u00e6re ender ogs\u00e5 s\u00f8ger sammen.<\/p>\r\n\r\n    <div class=\"main-container\">\r\n        <div class=\"canvas-wrapper\">\r\n            <canvas id=\"simCanvas\" width=\"500\" height=\"500\"><\/canvas>\r\n        <\/div>\r\n\r\n        <div class=\"controls-panel\">\r\n            <div class=\"slider-card\">\r\n                <label style=\"font-weight:600; color:#d84315;\">Temperatur<\/label>\r\n                <input type=\"range\" id=\"tempSlider\" min=\"0\" max=\"100\" value=\"20\">\r\n                <div class=\"temp-display\"><span id=\"tempValue\">Lav (V\u00e6ske)<\/span><\/div>\r\n            <\/div>\r\n\r\n            <div class=\"toggles\">\r\n                <label class=\"checkbox-label\">\r\n                    <input type=\"checkbox\" id=\"checkH\" checked>\r\n                    Vis Hydrogenbindinger (R\u00f8d)\r\n                <\/label>\r\n                <label class=\"checkbox-label\">\r\n                    <input type=\"checkbox\" id=\"checkL\" checked>\r\n                    Vis London-kr\u00e6fter (Gr\u00e5)\r\n                <\/label>\r\n            <\/div>\r\n\r\n            <div class=\"legend\">\r\n                <strong>Signaturforklaring:<\/strong>\r\n                <div class=\"legend-item\" style=\"margin-top:8px;\">\r\n                    <div class=\"line-h\"><\/div>\r\n                    <div>\r\n                        <strong>Hydrogenbinding<\/strong><br>\r\n                        <span style=\"color:#d32f2f; font-size:11px;\">St\u00e6rk tiltr\u00e6kning (O \u2194 H)<\/span>\r\n                    <\/div>\r\n                <\/div>\r\n                <div class=\"legend-item\">\r\n                    <div class=\"line-london\"><\/div>\r\n                    <div>\r\n                        <strong>London-kraft<\/strong><br>\r\n                        <span style=\"color:#555; font-size:11px;\">Mellem-st\u00e6rk (Hale \u2194 Hale)<\/span>\r\n                    <\/div>\r\n                <\/div>\r\n            <\/div>\r\n        <\/div>\r\n    <\/div>\r\n\r\n<script>\r\nwindow.onload = function() {\r\n    const canvas = document.getElementById('simCanvas');\r\n    const ctx = canvas.getContext('2d');\r\n    const width = canvas.width;\r\n    const height = canvas.height;\r\n\r\n    let currentTemp = 20;\r\n    let showHBonds = true;\r\n    let showLondon = true;\r\n    \r\n    \/\/ Antal molekyler\r\n    const numMolecules = 10; \r\n    let molecules = [];\r\n\r\n    \/\/ Ethanol struktur\r\n    const ethanolStructure = [\r\n        { t: 'C_Tail', x: -20, y: 2, r: 10, col: '#37474F' }, \r\n        { t: 'C', x: 0, y: 0, r: 10, col: '#37474F' },   \r\n        { t: 'H_C', x: -28, y: -8, r: 6, col: '#f5f5f5' }, \r\n        { t: 'H_C', x: -28, y: 12, r: 6, col: '#f5f5f5' },\r\n        { t: 'H_C', x: -10, y: 20, r: 6, col: '#f5f5f5' }, \r\n        { t: 'H_C', x: 10, y: 18, r: 6, col: '#f5f5f5' },\r\n        { t: 'H_C', x: -10, y: -18, r: 6, col: '#f5f5f5' },\r\n        { t: 'O', x: 22, y: -8, r: 11, col: '#ff5252' }, \r\n        { t: 'H_O', x: 32, y: 4, r: 7, col: '#ffffff', border: '#ff5252' } \r\n    ];\r\n\r\n    class Molecule {\r\n        constructor() {\r\n            this.x = Math.random() * (width - 100) + 50;\r\n            this.y = Math.random() * (height - 100) + 50;\r\n            \r\n            \/\/ Lav hastighed\r\n            this.vx = (Math.random() - 0.5) * 0.2; \r\n            this.vy = (Math.random() - 0.5) * 0.2;\r\n            \r\n            this.angle = Math.random() * Math.PI * 2;\r\n            this.spin = (Math.random() - 0.5) * 0.01; \r\n            this.radius = 45; \r\n        }\r\n\r\n        update() {\r\n            \/\/ Slow motion logic\r\n            let speedFactor = currentTemp \/ 45; \r\n            if(speedFactor < 0.15) speedFactor = 0.15; \r\n\r\n            this.x += this.vx * speedFactor;\r\n            this.y += this.vy * speedFactor;\r\n            this.angle += this.spin * Math.sqrt(speedFactor);\r\n\r\n            \/\/ Bounce\r\n            let dx = this.x - width\/2;\r\n            let dy = this.y - height\/2;\r\n            let distFromCenter = Math.sqrt(dx*dx + dy*dy);\r\n            if (distFromCenter + this.radius > width\/2) {\r\n                let angleToCenter = Math.atan2(dy, dx);\r\n                this.vx = -Math.cos(angleToCenter) * Math.abs(this.vx);\r\n                this.vy = -Math.sin(angleToCenter) * Math.abs(this.vy);\r\n                this.x -= Math.cos(angleToCenter) * 2;\r\n                this.y -= Math.sin(angleToCenter) * 2;\r\n            }\r\n            \r\n            this.x += (Math.random()-0.5)*speedFactor*0.3;\r\n            this.y += (Math.random()-0.5)*speedFactor*0.3;\r\n        }\r\n\r\n        getAtomAbsPos(atomDef) {\r\n            let rotatedX = atomDef.x * Math.cos(this.angle) - atomDef.y * Math.sin(this.angle);\r\n            let rotatedY = atomDef.x * Math.sin(this.angle) + atomDef.y * Math.cos(this.angle);\r\n            return { x: this.x + rotatedX, y: this.y + rotatedY };\r\n        }\r\n\r\n        draw() {\r\n            ctx.save();\r\n            ctx.translate(this.x, this.y);\r\n            ctx.rotate(this.angle);\r\n\r\n            ctx.strokeStyle = \"rgba(0,0,0,0.4)\";\r\n            ctx.lineWidth = 3;\r\n            ctx.beginPath();\r\n            ctx.moveTo(ethanolStructure[0].x, ethanolStructure[0].y);\r\n            ctx.lineTo(ethanolStructure[1].x, ethanolStructure[1].y);\r\n            ctx.lineTo(ethanolStructure[7].x, ethanolStructure[7].y);\r\n            ctx.lineTo(ethanolStructure[8].x, ethanolStructure[8].y);\r\n            ctx.stroke();\r\n\r\n            ethanolStructure.forEach(atom => {\r\n                ctx.beginPath();\r\n                ctx.arc(atom.x, atom.y, atom.r, 0, Math.PI*2);\r\n                ctx.fillStyle = atom.col;\r\n                ctx.fill();\r\n                if(atom.border) { ctx.strokeStyle = atom.border; ctx.lineWidth = 2; ctx.stroke(); } \r\n                else { ctx.strokeStyle = \"rgba(0,0,0,0.2)\"; ctx.lineWidth = 1; ctx.stroke(); }\r\n            });\r\n            ctx.restore();\r\n        }\r\n    }\r\n\r\n    function animate() {\r\n        ctx.clearRect(0, 0, width, height);\r\n        \r\n        molecules.forEach(m => m.update());\r\n\r\n        for (let i = 0; i < molecules.length; i++) {\r\n            for (let j = i + 1; j < molecules.length; j++) {\r\n                let molA = molecules[i];\r\n                let molB = molecules[j];\r\n\r\n                \/\/ HYDROGEN BINDINGER (R\u00f8d)\r\n                \/\/ STYRKE: 2.5 (Op fra 2.0)\r\n                \/\/ RANGE: 85 (Lidt mere tolerant)\r\n                if (showHBonds) {\r\n                    let O_A = molA.getAtomAbsPos(ethanolStructure[7]);\r\n                    let H_A = molA.getAtomAbsPos(ethanolStructure[8]);\r\n                    let O_B = molB.getAtomAbsPos(ethanolStructure[7]);\r\n                    let H_B = molB.getAtomAbsPos(ethanolStructure[8]);\r\n                    \r\n                    applyForceAndDraw(O_A, H_B, molA, molB, 'red', 2.5, 85); \r\n                    applyForceAndDraw(O_B, H_A, molB, molA, 'red', 2.5, 85); \r\n                }\r\n\r\n                \/\/ LONDON BINDINGER (Gr\u00e5)\r\n                \/\/ STYRKE: 1.4 (Op fra 0.6 - K\u00e6mpe boost)\r\n                \/\/ RANGE: 115 (Op fra 100 - Griber tidligere fat)\r\n                if (showLondon) {\r\n                    let C_A = molA.getAtomAbsPos(ethanolStructure[0]);\r\n                    let C_B = molB.getAtomAbsPos(ethanolStructure[0]);\r\n                    \r\n                    applyForceAndDraw(C_A, C_B, molA, molB, 'london', 1.4, 115); \r\n                }\r\n            }\r\n        }\r\n\r\n        molecules.forEach(m => m.draw());\r\n        requestAnimationFrame(animate);\r\n    }\r\n\r\n    \/\/ Funktion med variabel Range og Styrke\r\n    function applyForceAndDraw(pos1, pos2, mol1, mol2, type, strengthFactor, baseRange) {\r\n        let dx = pos1.x - pos2.x;\r\n        let dy = pos1.y - pos2.y;\r\n        let distSq = dx*dx + dy*dy;\r\n        \r\n        \/\/ Temp modifikation: H\u00f8j varme reducerer r\u00e6kkevidden (bliver sv\u00e6rere at binde)\r\n        let tempMod = currentTemp * 0.5;\r\n        let threshold = baseRange - tempMod; \r\n\r\n        if (distSq < threshold * threshold && distSq > 100) {\r\n            \r\n            if (type === 'red') {\r\n                ctx.strokeStyle = \"rgba(255, 0, 0, 0.8)\"; \r\n                ctx.lineWidth = 3; \r\n                ctx.setLineDash([5, 5]);\r\n            } else {\r\n                \/\/ Gjort linjen m\u00f8rkere og mere tydelig\r\n                ctx.strokeStyle = \"rgba(80, 80, 80, 0.6)\"; \r\n                ctx.lineWidth = 3; \r\n                ctx.setLineDash([3, 5]); \r\n            }\r\n            \r\n            ctx.beginPath();\r\n            ctx.moveTo(pos1.x, pos1.y);\r\n            ctx.lineTo(pos2.x, pos2.y);\r\n            ctx.stroke();\r\n            ctx.setLineDash([]);\r\n\r\n            \/\/ Physics: Tiltr\u00e6kning\r\n            \/\/ Jo lavere temp, jo st\u00e6rkere tr\u00e6k\r\n            let forceStrength = (100 - currentTemp) * 0.00003 * strengthFactor;\r\n            let angle = Math.atan2(dy, dx);\r\n            \r\n            mol1.vx -= Math.cos(angle) * forceStrength;\r\n            mol1.vy -= Math.sin(angle) * forceStrength;\r\n            mol2.vx += Math.cos(angle) * forceStrength;\r\n            mol2.vy += Math.sin(angle) * forceStrength;\r\n        }\r\n    }\r\n\r\n    document.getElementById('checkH').onchange = function() { showHBonds = this.checked; };\r\n    document.getElementById('checkL').onchange = function() { showLondon = this.checked; };\r\n\r\n    const slider = document.getElementById('tempSlider');\r\n    const tempVal = document.getElementById('tempValue');\r\n    slider.oninput = function() {\r\n        currentTemp = parseInt(this.value);\r\n        if(currentTemp < 30) tempVal.innerText = \"Lav (V\u00e6ske)\";\r\n        else if(currentTemp < 70) tempVal.innerText = \"Mellem (Koger)\";\r\n        else tempVal.innerText = \"H\u00f8j (Damp)\";\r\n    };\r\n\r\n    for(let i=0; i<numMolecules; i++) molecules.push(new Molecule());\r\n    animate();\r\n};\r\n<\/script>\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-5f24dab elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"5f24dab\" data-element_type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-d70204d\" data-id=\"d70204d\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap\">\n\t\t\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Alkan-Simulatoren V8 (Komplet) Alkan-Simulatoren (Komplet) Unders\u00f8g fysiske egenskaber, destillation og slut af med en forbr\u00e6nding! Gasfase V\u00e6ske \/ Fast Stof Temperatur (\u00b0C) 20 \u00b0C Tilstand: &#8230; Alkaner (St\u00f8rrelse) Metan (C\u2081) Kp: -162\u00b0 Octan (C\u2088) Kp: 126\u00b0 Isomeri (Form) n-Pentan Kp: 36\u00b0 Neopentan Kp: 10\u00b0 Avanceret \ud83e\uddea Bland: Metan &#038; Octan \ud83d\udd25 ANT\u00c6ND DAMP Indl\u00e6ser data&#8230;&hellip;&nbsp;<a href=\"https:\/\/kemiformler.dk\/index.php\/elementor-2215\/\" class=\"\" rel=\"bookmark\">Read More &raquo;<span class=\"screen-reader-text\">Animationer KemiB<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"page-templates\/template-pagebuilder-full-width.php","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","footnotes":""},"class_list":["post-2215","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/kemiformler.dk\/index.php\/wp-json\/wp\/v2\/pages\/2215","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kemiformler.dk\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/kemiformler.dk\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/kemiformler.dk\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kemiformler.dk\/index.php\/wp-json\/wp\/v2\/comments?post=2215"}],"version-history":[{"count":10,"href":"https:\/\/kemiformler.dk\/index.php\/wp-json\/wp\/v2\/pages\/2215\/revisions"}],"predecessor-version":[{"id":2227,"href":"https:\/\/kemiformler.dk\/index.php\/wp-json\/wp\/v2\/pages\/2215\/revisions\/2227"}],"wp:attachment":[{"href":"https:\/\/kemiformler.dk\/index.php\/wp-json\/wp\/v2\/media?parent=2215"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}