{"id":5339,"date":"2026-03-16T12:07:35","date_gmt":"2026-03-16T11:07:35","guid":{"rendered":"https:\/\/assemblico.com\/roi-lighting-calculator\/"},"modified":"2026-05-25T13:56:36","modified_gmt":"2026-05-25T11:56:36","slug":"roi-kalkulator-oswietlenie","status":"publish","type":"page","link":"https:\/\/assemblico.com\/pl\/roi-kalkulator-oswietlenie\/","title":{"rendered":"ROI Kalkulator O\u015bwietlenia"},"content":{"rendered":"<div class=\"et_pb_section_0 et_pb_section et_section_regular et_flex_section\">\n<div class=\"et_pb_row_0 et_pb_row et_flex_row\">\n<div class=\"et_pb_column_0 et_pb_column et-last-child et_flex_column et_pb_css_mix_blend_mode_passthrough et_flex_column_24_24 et_flex_column_24_24_tablet et_flex_column_24_24_phone\">\n<div class=\"et_pb_code_0 et_pb_code et_pb_module\"><div class=\"et_pb_code_inner\"><!-- Zale\u017cno\u015bci kalkulatora (czcionki, biblioteki Tailwind, React, Recharts) -->\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Montserrat:wght@400;500;600;700;800;900&display=swap\" rel=\"stylesheet\">\n\n<script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\n<script src=\"https:\/\/unpkg.com\/react@18\/umd\/react.production.min.js\"><\/script>\n<script src=\"https:\/\/unpkg.com\/react-dom@18\/umd\/react-dom.production.min.js\"><\/script>\n<script src=\"https:\/\/unpkg.com\/prop-types@15.8.1\/prop-types.min.js\"><\/script>\n<script src=\"https:\/\/unpkg.com\/recharts@2.12.7\/umd\/Recharts.js\"><\/script>\n<script src=\"https:\/\/unpkg.com\/@babel\/standalone\/babel.min.js\"><\/script>\n\n<style>\n    :root { --main-bg: #050810; }\n    #lighting-calc-root { \n        font-family: 'Montserrat', sans-serif;\n        -webkit-font-smoothing: antialiased;\n        color: #f8fafc;\n        background-color: var(--main-bg);\n        border-radius: 17px;\n    }\n    #lighting-calc-root input[type=\"text\"] { \n        color-scheme: dark; \n        font-family: 'Montserrat', sans-serif;\n        background-color: #1e293b !important;\n        border: 1px solid #334155 !important;\n        color: #f8fafc !important;\n        padding: 0 1rem !important;\n        box-shadow: none !important;\n    }\n    \n    #lighting-calc-root table, \n    #lighting-calc-root th, \n    #lighting-calc-root td, \n    #lighting-calc-root tr,\n    #lighting-calc-root tbody,\n    #lighting-calc-root thead {\n        border: none !important;\n        background: transparent;\n    }\n\n    .recharts-responsive-container { min-height: 320px; }\n    .table-container::-webkit-scrollbar { height: 6px; }\n    .table-container::-webkit-scrollbar-thumb { background: #334155; border-radius: 10px; }\n\n    \/* ==============================================================\n       PERFEKCYJNY WYDRUK - PODEJ\u015aCIE PIONOWE (DOCUMENT FLOW)\n       Brak zoomu, brak fixed. Tabela naturalnie nad wykresem.\n       ============================================================== *\/\n    @media print {\n        @page { size: A4 portrait; margin: 10mm; }\n        \n        body { \n            background-color: white !important; \n            margin: 0 !important; \n            padding: 0 !important;\n            -webkit-print-color-adjust: exact !important; \n            print-color-adjust: exact !important; \n        }\n\n        body * { visibility: hidden !important; }\n        \n        #lighting-calc-root, #lighting-calc-root * { \n            visibility: visible !important; \n        }\n        \n        #lighting-calc-root {\n            position: absolute !important;\n            left: 0 !important;\n            top: 0 !important;\n            width: 100% !important; \n            background-color: white !important;\n            color: #0f172a !important;\n            box-sizing: border-box !important;\n            \/* ZERO ZOOMU. Ca\u0142kowite oddanie kontroli przegl\u0105darce *\/\n            zoom: 1 !important; \n        }\n\n        \/* Pancerne przywr\u00f3cenie zaokr\u0105gle\u0144 w blokach na wydruku *\/\n        .print-card {\n            border-radius: 12px !important;\n            overflow: hidden !important;\n            border: 1px solid #e2e8f0 !important;\n        }\n\n        \/* Recharts musi by\u0107 w 100% zamkni\u0119ty w swoim pojemniku *\/\n        .recharts-wrapper, .recharts-surface {\n            width: 100% !important;\n            height: 100% !important;\n        }\n\n        .recharts-tooltip-wrapper, .recharts-active-dot, .recharts-dot { display: none !important; }\n        .no-print { display: none !important; }\n    }\n<\/style>\n\n<div id=\"lighting-calc-root\"><\/div>\n\n<script type=\"text\/babel\">\n    const { useState, useMemo, useEffect, memo, useCallback } = React;\n    const { \n        LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer \n    } = window.Recharts;\n\n    const InputField = memo(({ label, value, onChange, unit }) => (\n        <div className=\"flex flex-col h-full justify-end group\">\n            <label className=\"text-[9px] md:text-[10px] font-bold text-slate-500 uppercase tracking-widest mb-1.5 min-h-[26px] flex items-end leading-tight print:text-slate-700 print:text-[8px] print:mb-0 print:min-h-0\">\n                {label} {unit && `[${unit}]`}\n            <\/label>\n            <input \n                type=\"text\" \n                value={value} \n                onChange={(e) => onChange(e.target.value)}\n                \/* Mniejsze i cie\u0144sze na wydruku, by zyska\u0107 miejsce w pionie *\/\n                className=\"rounded-[10px] print:rounded-md text-sm w-full h-11 print:h-6 print:px-2 print:text-[10px] font-semibold transition-all border border-[#334155] print:bg-white print:border-slate-300 print:text-slate-900\"\n            \/>\n        <\/div>\n    ));\n\n    const App = () => {\n        const [isMobile, setIsMobile] = useState(window.innerWidth < 768);\n\n        useEffect(() => {\n            const handleResize = () => setIsMobile(window.innerWidth < 768);\n            window.addEventListener('resize', handleResize);\n            return () => window.removeEventListener('resize', handleResize);\n        }, []);\n\n        const [common, setCommon] = useState({\n            dailyHours: \"16\", activePrice: \"0,90\", reactivePrice: \"1,40\",\n            periodYears: \"10\", installCostPerUnit: \"40,00\", sourceCount: \"20\"\n        });\n\n        const [p1, setP1] = useState({ power: \"8,0\", pf: \"0,50\", price: \"50,00\", lifespan: \"20000\" });\n        const [p2, setP2] = useState({ power: \"10,0\", pf: \"0,90\", price: \"140,00\", lifespan: \"50000\" });\n\n        const parse = useCallback((v) => parseFloat(v.toString().replace(\/\\s\/g, '').replace(',', '.')) || 0, []);\n        const fmt = useCallback((v, dec = 0) => {\n            const val = Number(v).toFixed(dec);\n            const parts = val.split('.');\n            parts[0] = parts[0].replace(\/\\B(?=(\\d{3})+(?!\\d))\/g, \" \");\n            return parts.length > 1 ? parts.join(',') : parts[0];\n        }, []);\n        const fmtCur = useCallback((v) => `${fmt(v, 2)} z\u0142`, [fmt]);\n\n        const results = useMemo(() => {\n            const calc = (p) => {\n                const count = parse(common.sourceCount);\n                const power = parse(p.power);\n                const pf = parse(p.pf);\n                const years = parse(common.periodYears);\n                const installUnit = parse(common.installCostPerUnit);\n                const pPrice = parse(p.price);\n                \n                const totalP = count * power;\n                const tanPhi = pf > 0 && pf < 1 ? Math.sqrt(1 - pf**2) \/ pf : 0;\n                const totalQ = totalP * tanPhi;\n                const annHours = parse(common.dailyHours) * 365;\n                const annActiveCost = (totalP \/ 1000) * annHours * parse(common.activePrice);\n                const annReactiveCost = (totalQ \/ 1000) * annHours * parse(common.reactivePrice);\n                const annTotalEnergy = annActiveCost + annReactiveCost;\n                const onceSourceCost = count * pPrice;\n                const onceInstallCost = count * installUnit;\n                const totalUsageHours = years * annHours;\n                const repl = Math.floor(totalUsageHours \/ parse(p.lifespan));\n                const totalEnergyPeriod = annTotalEnergy * years;\n                const totalSourcesPeriod = (repl + 1) * onceSourceCost;\n                const totalInstallPeriod = (repl + 1) * onceInstallCost;\n                const finalCost = totalEnergyPeriod + totalSourcesPeriod + totalInstallPeriod;\n\n                return { \n                    totalP, totalQ, annHours, annActiveCost, annReactiveCost, annTotalEnergy,\n                    onceSourceCost, onceInstallCost, repl, \n                    totalEnergyPeriod, totalSourcesPeriod, totalInstallPeriod, finalCost \n                };\n            };\n\n            const r1 = calc(p1);\n            const r2 = calc(p2);\n            const savings = r1.finalCost - r2.finalCost;\n            const savingsPct = r1.finalCost > 0 ? (savings \/ r1.finalCost) * 100 : 0;\n            \n            let roiMonth = 0;\n            const monthHours = parse(common.dailyHours) * 30.42;\n            let simC1 = r1.onceSourceCost + r1.onceInstallCost;\n            let simC2 = r2.onceSourceCost + r2.onceInstallCost;\n            \n            if (simC2 <= simC1 && r2.annTotalEnergy <= r1.annTotalEnergy) {\n                roiMonth = 0;\n            } else {\n                let found = false;\n                for (let m = 1; m <= 1200; m++) {\n                    simC1 += r1.annTotalEnergy \/ 12;\n                    simC2 += r2.annTotalEnergy \/ 12;\n                    const h = m * monthHours;\n                    const isRepl1 = Math.floor(h \/ parse(p1.lifespan)) > Math.floor((h - monthHours) \/ parse(p1.lifespan));\n                    const isRepl2 = Math.floor(h \/ parse(p2.lifespan)) > Math.floor((h - monthHours) \/ parse(p2.lifespan));\n                    if (isRepl1) simC1 += r1.onceSourceCost + r1.onceInstallCost;\n                    if (isRepl2) simC2 += r2.onceSourceCost + r2.onceInstallCost;\n                    if (simC2 < simC1) { roiMonth = m; found = true; break; }\n                }\n                if (!found) roiMonth = \"Brak zwrotu\";\n            }\n            return { r1, r2, savings, savingsPct, roi: roiMonth };\n        }, [common, p1, p2, parse]);\n\n        const chartData = useMemo(() => {\n            const data = [];\n            const months = parse(common.periodYears) * 12;\n            const monthHours = parse(common.dailyHours) * 30.42;\n            let c1 = results.r1.onceSourceCost + results.r1.onceInstallCost;\n            let c2 = results.r2.onceSourceCost + results.r2.onceInstallCost;\n            for (let m = 0; m <= months; m++) {\n                if (m > 0) {\n                    c1 += results.r1.annTotalEnergy \/ 12;\n                    c2 += results.r2.annTotalEnergy \/ 12;\n                    const h = m * monthHours;\n                    const isRepl = (p, currH) => Math.floor(currH \/ parse(p.lifespan)) > Math.floor((currH - monthHours) \/ parse(p.lifespan));\n                    if (isRepl(p1, h)) c1 += results.r1.onceSourceCost + results.r1.onceInstallCost;\n                    if (isRepl(p2, h)) c2 += results.r2.onceSourceCost + results.r2.onceInstallCost;\n                }\n                data.push({ m, p1: Math.round(c1), p2: Math.round(c2) });\n            }\n            return data;\n        }, [results, common, p1, p2, parse]);\n\n        const handlePrint = () => {\n            window.print();\n        };\n\n        return (\n            <div className=\"bg-[#050810] text-slate-200 p-4 md:p-8 lg:p-12 border border-slate-800 rounded-[17px] shadow-2xl print:bg-white print:border-none print:shadow-none print:p-0\">\n                <div className=\"max-w-7xl mx-auto print:max-w-none print:w-full print:mx-0\">\n                    \n                    {\/* KPI Cards - Odchudzone paddingi w druku, wymuszony Grid *\/}\n                    <div className=\"grid grid-cols-1 md:grid-cols-3 print:grid-cols-3 gap-6 print:gap-3 mb-10 print:mb-4\">\n                        <div className=\"bg-gradient-to-br from-blue-600 to-blue-800 p-8 rounded-[17px] shadow-xl relative group print:bg-none print:bg-blue-50 print-card print:p-3\">\n                            <div className=\"text-blue-100\/70 text-[10px] font-extrabold uppercase tracking-[0.2em] mb-3 print:text-blue-800 print:mb-1 print:text-[8px]\">Oszcz\u0119dno\u015b\u0107 \u0142\u0105czna<\/div>\n                            <div className=\"text-4xl font-black text-white leading-none print:text-blue-700 print:text-xl\">{fmtCur(results.savings)}<\/div>\n                            <div className=\"text-blue-100\/60 text-[11px] mt-4 font-bold tracking-wider print:text-blue-600 print:text-[8px] print:mt-1\">OKRES {common.periodYears} LAT<\/div>\n                        <\/div>\n                        <div className=\"bg-[#111827] border border-slate-800 p-8 rounded-[17px] shadow-lg print:bg-emerald-50 print-card print:p-3\">\n                            <div className=\"text-slate-500 text-[10px] font-extrabold uppercase tracking-[0.2em] mb-3 text-emerald-500\/80 print:text-emerald-700 print:mb-1 print:text-[8px]\">Czas zwrotu<\/div>\n                            <div className=\"text-4xl font-black text-emerald-400 leading-none print:text-emerald-600 print:text-xl\">\n                                {typeof results.roi === 'number' ? `${results.roi} mies.` : results.roi}\n                            <\/div>\n                            <div className=\"text-slate-500 text-[11px] mt-4 font-bold uppercase tracking-wider print:text-emerald-700\/70 print:text-[8px] print:mt-1\">Amortyzacja koszt\u00f3w<\/div>\n                        <\/div>\n                        <div className=\"bg-[#111827] border border-slate-800 p-8 rounded-[17px] shadow-lg print:bg-slate-50 print-card print:p-3\">\n                            <div className=\"text-slate-500 text-[10px] font-extrabold uppercase tracking-[0.2em] mb-3 print:text-slate-500 print:mb-1 print:text-[8px]\">Redukcja koszt\u00f3w<\/div>\n                            <div className=\"text-4xl font-black text-white leading-none print:text-slate-800 print:text-xl\">{Math.round(results.savingsPct)}%<\/div>\n                            <div className=\"text-slate-500 text-[11px] mt-4 font-bold uppercase tracking-wider print:text-slate-500 print:text-[8px] print:mt-1\">Wydajno\u015b\u0107 finansowa<\/div>\n                        <\/div>\n                    <\/div>\n\n                    {\/* Form Section *\/}\n                    <div className=\"grid grid-cols-1 md:grid-cols-2 print:grid-cols-2 gap-6 print:gap-3 mb-10 print:mb-4\">\n                        <div className=\"md:col-span-2 bg-[#111827] border border-slate-800 rounded-[17px] p-6 md:p-8 print:col-span-2 print:bg-white print:p-0 print:border-none\">\n                            <h3 className=\"text-[10px] font-black text-slate-500 uppercase tracking-[0.2em] mb-6 print:text-slate-800 print:mb-2 print:text-[9px]\">Parametry wsp\u00f3lne<\/h3>\n                            <div className=\"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-6 print:grid-cols-6 gap-6 print:gap-2\">\n                                <InputField label=\"Liczba \u017ar\u00f3de\u0142\" unit=\"szt\" value={common.sourceCount} onChange={(v) => setCommon({...common, sourceCount: v})} \/>\n                                <InputField label=\"Czas pracy\" unit=\"h\/d\" value={common.dailyHours} onChange={(v) => setCommon({...common, dailyHours: v})} \/>\n                                <InputField label=\"Cena czynna\" unit=\"z\u0142\/kWh\" value={common.activePrice} onChange={(v) => setCommon({...common, activePrice: v})} \/>\n                                <InputField label=\"Cena bierna\" unit=\"z\u0142\/kVarh\" value={common.reactivePrice} onChange={(v) => setCommon({...common, reactivePrice: v})} \/>\n                                <InputField label=\"Okres rozliczenia\" unit=\"lat\" value={common.periodYears} onChange={(v) => setCommon({...common, periodYears: v})} \/>\n                                <InputField label=\"Koszt monta\u017cu\" unit=\"z\u0142\/szt\" value={common.installCostPerUnit} onChange={(v) => setCommon({...common, installCostPerUnit: v})} \/>\n                            <\/div>\n                        <\/div>\n\n                        <div className=\"bg-[#111827] border border-slate-800 rounded-[17px] p-6 md:p-8 relative print:bg-white print-card print:p-3\">\n                            <div className=\"absolute top-0 left-0 w-full h-1 bg-red-500\/80 print:bg-red-500\"><\/div>\n                            <div className=\"mb-8 font-black text-red-500 text-[12px] uppercase tracking-[0.25em] print:mb-2 print:text-[10px] mt-1 print:mt-0\">Produkt 1 (Obecne)<\/div>\n                            <div className=\"grid grid-cols-2 print:grid-cols-2 gap-8 print:gap-2\">\n                                <InputField label=\"Moc \u017ar\u00f3d\u0142a\" unit=\"W\" value={p1.power} onChange={(v) => setP1({...p1, power: v})} \/>\n                                <InputField label=\"Wsp\u00f3\u0142czynnik PF\" value={p1.pf} onChange={(v) => setP1({...p1, pf: v})} \/>\n                                <InputField label=\"Koszt \u017ar\u00f3d\u0142a\" unit=\"z\u0142\" value={p1.price} onChange={(v) => setP1({...p1, price: v})} \/>\n                                <InputField label=\"Trwa\u0142o\u015b\u0107\" unit=\"h\" value={p1.lifespan} onChange={(v) => setP1({...p1, lifespan: v})} \/>\n                            <\/div>\n                        <\/div>\n\n                        <div className=\"bg-[#111827] border border-slate-800 rounded-[17px] p-6 md:p-8 relative print:bg-white print-card print:p-3\">\n                            <div className=\"absolute top-0 left-0 w-full h-1 bg-emerald-500\/80 print:bg-emerald-500\"><\/div>\n                            <div className=\"mb-8 font-black text-emerald-500 text-[12px] uppercase tracking-[0.25em] print:mb-2 print:text-[10px] mt-1 print:mt-0\">Produkt 2 (Nowe)<\/div>\n                            <div className=\"grid grid-cols-2 print:grid-cols-2 gap-8 print:gap-2\">\n                                <InputField label=\"Moc \u017ar\u00f3d\u0142a\" unit=\"W\" value={p2.power} onChange={(v) => setP2({...p2, power: v})} \/>\n                                <InputField label=\"Wsp\u00f3\u0142czynnik PF\" value={p2.pf} onChange={(v) => setP2({...p2, pf: v})} \/>\n                                <InputField label=\"Koszt \u017ar\u00f3d\u0142a\" unit=\"z\u0142\" value={p2.price} onChange={(v) => setP2({...p2, price: v})} \/>\n                                <InputField label=\"Trwa\u0142o\u015b\u0107\" unit=\"h\" value={p2.lifespan} onChange={(v) => setP2({...p2, lifespan: v})} \/>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n\n                    {\/* Chart & Summary - Z\u0141OTY KLUCZ: W DRUKU ZMIENIAMY NA PION! TABELA G\u00d3RA (ORDER-1), WYKRES D\u00d3\u0141 (ORDER-2) *\/}\n                    <div className=\"grid grid-cols-1 lg:grid-cols-12 gap-8 print:flex print:flex-col print:gap-4 print:mb-2\">\n                        \n                        {\/* TABELA - Na druku leci na g\u00f3r\u0119 nad wykres (print:order-1) i bierze 100% szeroko\u015bci *\/}\n                        <div className=\"lg:col-span-5 print:w-full print:order-1 bg-[#111827] border border-slate-800 rounded-[17px] overflow-hidden flex flex-col shadow-2xl print:bg-white print-card\">\n                            <div className=\"p-5 bg-slate-800\/30 border-none text-center uppercase tracking-[0.2em] text-[10px] font-black text-slate-500 print:bg-slate-50 print:text-slate-800 print:border-b print:border-slate-200 print:p-2\">Podsumowanie referencyjne<\/div>\n                            <div className=\"overflow-x-auto table-container\">\n                                <table className=\"w-full text-left text-[11px] print:text-[9px] font-medium border-collapse\">\n                                    <tbody>\n                                        {\/* Ekstremalnie odchudzone paddingi w trybie druku by zaoszcz\u0119dzi\u0107 cenne centymetry *\/}\n                                        <tr className=\"hover:bg-white\/[0.02] print:hover:bg-transparent\"><td className=\"p-4 print:py-1 print:px-2 text-slate-400 print:text-slate-600\">Ca\u0142kowita moc czynna [W]<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900\">{fmt(results.r1.totalP, 1)}<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900\">{fmt(results.r2.totalP, 1)}<\/td><\/tr>\n                                        <tr className=\"hover:bg-white\/[0.02] print:hover:bg-transparent\"><td className=\"p-4 print:py-1 print:px-2 text-slate-400 print:text-slate-600\">Ca\u0142kowita moc bierna [Var]<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900\">{fmt(results.r1.totalQ, 1)}<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900\">{fmt(results.r2.totalQ, 1)}<\/td><\/tr>\n                                        <tr className=\"hover:bg-white\/[0.02] print:hover:bg-transparent\"><td className=\"p-4 print:py-1 print:px-2 text-slate-400 print:text-slate-600\">Roczny czas u\u017cytkowania [h]<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900\">{fmt(results.r1.annHours, 0)}<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900\">{fmt(results.r2.annHours, 0)}<\/td><\/tr>\n                                        <tr className=\"hover:bg-white\/[0.02] print:hover:bg-transparent\"><td className=\"p-4 print:py-1 print:px-2 text-slate-400 print:text-slate-600\">Roczny koszt energii czynnej [PLN]<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900 whitespace-nowrap\">{fmt(results.r1.annActiveCost, 2)}<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900 whitespace-nowrap\">{fmt(results.r2.annActiveCost, 2)}<\/td><\/tr>\n                                        <tr className=\"hover:bg-white\/[0.02] print:hover:bg-transparent\"><td className=\"p-4 print:py-1 print:px-2 text-slate-400 print:text-slate-600\">Roczny koszt energii biernej [PLN]<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900 whitespace-nowrap\">{fmt(results.r1.annReactiveCost, 2)}<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900 whitespace-nowrap\">{fmt(results.r2.annReactiveCost, 2)}<\/td><\/tr>\n                                        <tr className=\"hover:bg-white\/[0.02] print:hover:bg-transparent\"><td className=\"p-4 print:py-1 print:px-2 text-slate-400 print:text-slate-600\">Jednorazowy koszt \u017ar\u00f3de\u0142 \u015bwiat\u0142a [PLN]<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900 whitespace-nowrap\">{fmt(results.r1.onceSourceCost, 2)}<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900 whitespace-nowrap\">{fmt(results.r2.onceSourceCost, 2)}<\/td><\/tr>\n                                        <tr className=\"hover:bg-white\/[0.02] print:hover:bg-transparent\"><td className=\"p-4 print:py-1 print:px-2 text-slate-400 print:text-slate-600\">Jednorazowy koszt wymiany [PLN]<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900 whitespace-nowrap\">{fmt(results.r1.onceInstallCost, 2)}<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900 whitespace-nowrap\">{fmt(results.r2.onceInstallCost, 2)}<\/td><\/tr>\n                                        <tr className=\"hover:bg-white\/[0.02] print:hover:bg-transparent\"><td className=\"p-4 print:py-1 print:px-2 text-slate-400 print:text-slate-600\">Liczba wymian w okresie<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900\">{results.r1.repl}<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900\">{results.r2.repl}<\/td><\/tr>\n                                        \n                                        <tr className=\"bg-slate-800\/10 print:bg-slate-50\"><td className=\"p-4 print:py-1 print:px-2 text-slate-400 print:text-slate-700\">\u0141\u0105czny koszt energii (okres) [PLN]<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900 whitespace-nowrap\">{fmt(results.r1.totalEnergyPeriod, 2)}<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900 whitespace-nowrap\">{fmt(results.r2.totalEnergyPeriod, 2)}<\/td><\/tr>\n                                        <tr className=\"bg-slate-800\/10 print:bg-slate-50\"><td className=\"p-4 print:py-1 print:px-2 text-slate-400 print:text-slate-700\">\u0141\u0105czny koszt \u017ar\u00f3de\u0142 (okres) [PLN]<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900 whitespace-nowrap\">{fmt(results.r1.totalSourcesPeriod, 2)}<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900 whitespace-nowrap\">{fmt(results.r2.totalSourcesPeriod, 2)}<\/td><\/tr>\n                                        <tr className=\"bg-slate-800\/10 print:bg-slate-50\"><td className=\"p-4 print:py-1 print:px-2 text-slate-400 print:text-slate-700\">\u0141\u0105czny koszt monta\u017cu (okres) [PLN]<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900 whitespace-nowrap\">{fmt(results.r1.totalInstallPeriod, 2)}<\/td><td className=\"p-4 print:py-1 print:px-2 text-right font-bold text-slate-300 print:text-slate-900 whitespace-nowrap\">{fmt(results.r2.totalInstallPeriod, 2)}<\/td><\/tr>\n                                        \n                                        <tr className=\"bg-slate-800\/50 print:bg-slate-100 border-none\">\n                                            <td className=\"p-5 print:py-2 print:px-2 font-black text-white uppercase tracking-widest print:text-slate-900\">\u0141\u0105czny koszt u\u017cytkowania<\/td>\n                                            <td className=\"p-5 print:py-2 print:px-2 text-right text-red-500 font-black text-xs whitespace-nowrap print:text-red-600\">{fmtCur(results.r1.finalCost)}<\/td>\n                                            <td className=\"p-5 print:py-2 print:px-2 text-right text-emerald-500 font-black text-xs whitespace-nowrap print:text-emerald-600\">{fmtCur(results.r2.finalCost)}<\/td>\n                                        <\/tr>\n                                    <\/tbody>\n                                <\/table>\n                            <\/div>\n                        <\/div>\n\n                        {\/* WYKRES - L\u0105duje pod tabel\u0105 w druku (order-2), dostaje sztywn\u0105 wysoko\u015b\u0107, \u017ceby nigdy niczego nie zakry\u0142! *\/}\n                        <div className=\"lg:col-span-7 print:w-full print:order-2 bg-[#111827] border border-slate-800 rounded-[17px] p-6 md:p-10 shadow-xl print:bg-white print-card print:p-4\">\n                            <h4 className=\"text-[11px] font-black text-slate-500 uppercase mb-8 tracking-[0.2em] text-center print:text-slate-800 print:mb-2 print:text-[10px]\">Symulacja koszt\u00f3w ca\u0142kowitych<\/h4>\n                            <div className=\"h-[340px] w-full print:h-[230px]\"> \n                                <ResponsiveContainer width=\"100%\" height=\"100%\">\n                                    <LineChart data={chartData} margin={{ top: 10, right: 20, left: isMobile ? -10 : 15, bottom: 5 }}>\n                                        <CartesianGrid strokeDasharray=\"3 3\" stroke=\"#1e293b\" vertical={false} \/>\n                                        <XAxis dataKey=\"m\" stroke=\"#475569\" tickFormatter={(v) => v % 12 === 0 ? `ROK ${v\/12}` : ''} interval={isMobile ? 23 : 11} dy={10} \/>\n                                        <YAxis stroke=\"#475569\" width={isMobile ? 70 : 90} tickFormatter={(v) => `${fmt(v)} z\u0142`} \/>\n                                        <Tooltip formatter={(val) => [`${fmt(val)} z\u0142`]} labelFormatter={(l) => `Miesi\u0105c: ${l}`} contentStyle={{backgroundColor:'#0f172a', border:'1px solid #334155', borderRadius:'16px', fontFamily: 'Montserrat', fontSize: '12px', fontWeight: 600}} \/>\n                                        <Legend verticalAlign=\"top\" align=\"right\" iconType=\"plainline\" wrapperStyle={{paddingBottom: '10px', fontSize: '11px', fontWeight: 800}}\/>\n                                        <Line isAnimationActive={false} activeDot={false} type=\"monotone\" name=\"Produkt 1\" dataKey=\"p1\" stroke=\"#ef4444\" strokeWidth={3} dot={false} \/>\n                                        <Line isAnimationActive={false} activeDot={false} type=\"monotone\" name=\"Produkt 2\" dataKey=\"p2\" stroke=\"#10b981\" strokeWidth={3} dot={false} \/>\n                                    <\/LineChart>\n                                <\/ResponsiveContainer>\n                            <\/div>\n                        <\/div>\n\n                    <\/div>\n\n                    {\/* Przyciski operacyjne ukrywane w druku *\/}\n                    <div className=\"mt-10 flex justify-center no-print\">\n                        <button \n                            onClick={handlePrint}\n                            className=\"flex items-center gap-3 font-bold py-4 px-10 rounded-[17px] transition-all duration-300 bg-blue-600 hover:bg-blue-500 text-white shadow-[0_0_20px_rgba(37,99,235,0.4)] hover:shadow-[0_0_30px_rgba(37,99,235,0.6)] transform hover:-translate-y-1\"\n                        >\n                            <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n                                <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"><\/path>\n                                <polyline points=\"7 10 12 15 17 10\"><\/polyline>\n                                <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\"><\/line>\n                            <\/svg>\n                            DRUKUJ \/ ZAPISZ PDF\n                        <\/button>\n                    <\/div>\n\n                    {\/* STOPKA - Zwyk\u0142y blok tekstu z zachowanym flex order. Naturalnie le\u017cy na samym dole kartki. *\/}\n                    <div className=\"mt-10 pt-6 border-t border-slate-800 flex justify-center print:border-slate-300 print:order-3 print:mt-4 print:pt-2\">\n                        <p className=\"text-[10px] text-blue-400\/60 font-black uppercase tracking-[0.2em] text-center print:text-slate-400\">\n                            Powered by Assemblico.com\n                        <\/p>\n                    <\/div>\n\n                <\/div>\n            <\/div>\n        );\n    };\n\n    const root = ReactDOM.createRoot(document.getElementById('lighting-calc-root'));\n    root.render(<App \/>);\n<\/script><\/div><\/div>\n<\/div>\n<\/div>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-5339","page","type-page","status-publish","hentry"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>ROI Kalkulator O\u015bwietlenia - Assemblico \u2013 The Future of Electricians &amp; Builders<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/assemblico.com\/pl\/roi-kalkulator-oswietlenie\/\" \/>\n<meta property=\"og:locale\" content=\"pl_PL\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"ROI Kalkulator O\u015bwietlenia - Assemblico \u2013 The Future of Electricians &amp; Builders\" \/>\n<meta property=\"og:url\" content=\"https:\/\/assemblico.com\/pl\/roi-kalkulator-oswietlenie\/\" \/>\n<meta property=\"og:site_name\" content=\"Assemblico \u2013 The Future of Electricians &amp; Builders\" \/>\n<meta property=\"article:modified_time\" content=\"2026-05-25T11:56:36+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/assemblico.com\\\/pl\\\/roi-kalkulator-oswietlenie\\\/\",\"url\":\"https:\\\/\\\/assemblico.com\\\/pl\\\/roi-kalkulator-oswietlenie\\\/\",\"name\":\"ROI Kalkulator O\u015bwietlenia - Assemblico \u2013 The Future of Electricians &amp; Builders\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/assemblico.com\\\/#website\"},\"datePublished\":\"2026-03-16T11:07:35+00:00\",\"dateModified\":\"2026-05-25T11:56:36+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/assemblico.com\\\/pl\\\/roi-kalkulator-oswietlenie\\\/#breadcrumb\"},\"inLanguage\":\"pl-PL\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/assemblico.com\\\/pl\\\/roi-kalkulator-oswietlenie\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/assemblico.com\\\/pl\\\/roi-kalkulator-oswietlenie\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Strona g\u0142\u00f3wna\",\"item\":\"https:\\\/\\\/assemblico.com\\\/pl\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"ROI Kalkulator O\u015bwietlenia\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/assemblico.com\\\/#website\",\"url\":\"https:\\\/\\\/assemblico.com\\\/\",\"name\":\"Assemblico \u2013 The Future of Electricians &amp; Builders\",\"description\":\"One platform. One brain. Endless efficiency.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/assemblico.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pl-PL\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"ROI Kalkulator O\u015bwietlenia - Assemblico \u2013 The Future of Electricians &amp; Builders","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/assemblico.com\/pl\/roi-kalkulator-oswietlenie\/","og_locale":"pl_PL","og_type":"article","og_title":"ROI Kalkulator O\u015bwietlenia - Assemblico \u2013 The Future of Electricians &amp; Builders","og_url":"https:\/\/assemblico.com\/pl\/roi-kalkulator-oswietlenie\/","og_site_name":"Assemblico \u2013 The Future of Electricians &amp; Builders","article_modified_time":"2026-05-25T11:56:36+00:00","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/assemblico.com\/pl\/roi-kalkulator-oswietlenie\/","url":"https:\/\/assemblico.com\/pl\/roi-kalkulator-oswietlenie\/","name":"ROI Kalkulator O\u015bwietlenia - Assemblico \u2013 The Future of Electricians &amp; Builders","isPartOf":{"@id":"https:\/\/assemblico.com\/#website"},"datePublished":"2026-03-16T11:07:35+00:00","dateModified":"2026-05-25T11:56:36+00:00","breadcrumb":{"@id":"https:\/\/assemblico.com\/pl\/roi-kalkulator-oswietlenie\/#breadcrumb"},"inLanguage":"pl-PL","potentialAction":[{"@type":"ReadAction","target":["https:\/\/assemblico.com\/pl\/roi-kalkulator-oswietlenie\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/assemblico.com\/pl\/roi-kalkulator-oswietlenie\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Strona g\u0142\u00f3wna","item":"https:\/\/assemblico.com\/pl\/"},{"@type":"ListItem","position":2,"name":"ROI Kalkulator O\u015bwietlenia"}]},{"@type":"WebSite","@id":"https:\/\/assemblico.com\/#website","url":"https:\/\/assemblico.com\/","name":"Assemblico \u2013 The Future of Electricians &amp; Builders","description":"One platform. One brain. Endless efficiency.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/assemblico.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pl-PL"}]}},"_links":{"self":[{"href":"https:\/\/assemblico.com\/pl\/wp-json\/wp\/v2\/pages\/5339","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/assemblico.com\/pl\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/assemblico.com\/pl\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/assemblico.com\/pl\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/assemblico.com\/pl\/wp-json\/wp\/v2\/comments?post=5339"}],"version-history":[{"count":4,"href":"https:\/\/assemblico.com\/pl\/wp-json\/wp\/v2\/pages\/5339\/revisions"}],"predecessor-version":[{"id":8693,"href":"https:\/\/assemblico.com\/pl\/wp-json\/wp\/v2\/pages\/5339\/revisions\/8693"}],"wp:attachment":[{"href":"https:\/\/assemblico.com\/pl\/wp-json\/wp\/v2\/media?parent=5339"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}