{"id":16607,"date":"2026-05-19T07:57:48","date_gmt":"2026-05-19T07:57:48","guid":{"rendered":"https:\/\/boreal-plus.ro\/?page_id=16607"},"modified":"2026-09-10T12:18:20","modified_gmt":"2026-09-10T12:18:20","slug":"blog","status":"publish","type":"page","link":"https:\/\/boreal-plus.ro\/en\/blog\/","title":{"rendered":"Blog"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"16607\" class=\"elementor elementor-16607\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-d6818e9 e-con-full e-flex e-con e-parent\" data-id=\"d6818e9\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-32d3f12 elementor-widget elementor-widget-html\" data-id=\"32d3f12\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!-- BOREAL PLUS - Blog Listing (fragment Elementor) -->\n<!-- NU lipi <!DOCTYPE>, <html>, <head>, <body> \u2014 WordPress le adaug\u0103 singur. Fonturile + style.css se \u00eencarc\u0103 global din tem\u0103. -->\n<style>\n.blog-hero {\n    position: relative;\n    background-image: linear-gradient(180deg, rgba(0, 45, 61, 0.92) 0%, rgba(0, 45, 61, 0.72) 48%, rgba(0, 45, 61, 0.94) 100%), url('https:\/\/boreal-plus.ro\/wp-content\/uploads\/2025\/08\/noul-boreal-plus.jpg');\n    background-size: cover;\n    background-position: center;\n    min-height: 680px;\n    padding: clamp(100px, 14vw, 140px) var(--container-px) 80px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    overflow: hidden;\n    color: #ffffff;\n}\n.blog-hero::before {\n    content: '';\n    position: absolute;\n    inset: 0;\n    background: radial-gradient(circle at top right, rgba(180,144,121,0.22), transparent 30%);\n    pointer-events: none;\n    z-index: 0;\n}\n.blog-hero::after {\n    content: '';\n    position: absolute;\n    inset: 0;\n    background: linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.0) 60%);\n    pointer-events: none;\n    z-index: 0;\n}\n.blog-hero-inner {\n    position: relative;\n    z-index: 2;\n    max-width: 820px;\n    margin: 0 auto;\n    padding: 0 var(--container-px);\n    text-align: center;\n    color: #ffffff;\n    text-shadow: 0 18px 45px rgba(0, 0, 0, 0.22);\n}\n.blog-hero-inner .label {\n    display: inline-flex;\n    align-items: center;\n    color: var(--secondary);\n    font-family: 'Inter', sans-serif;\n    font-size: 0.82rem;\n    font-weight: 700;\n    letter-spacing: 1.8px;\n    text-transform: uppercase;\n    margin-bottom: 20px;\n    padding: 10px 20px;\n    border: 1px solid rgba(255, 255, 255, 0.24);\n    border-radius: 999px;\n    background: rgba(255, 255, 255, 0.08);\n    max-width: fit-content;\n}\n.blog-hero-inner h1 {\n    font-family: 'Outfit', sans-serif;\n    font-size: clamp(2.2rem, 3.6vw, 3.2rem);\n    color: #ffffff;\n    font-weight: 500;\n    margin: 0 auto 18px;\n    line-height: 1.1;\n    letter-spacing: -0.025em;\n    max-width: 100%;\n}\n.blog-hero-inner p {\n    color: rgba(255, 255, 255, 0.9);\n    font-size: 1.03rem;\n    line-height: 1.9;\n    max-width: 690px;\n    margin: 0 auto;\n}\n@media (max-width: 980px) {\n    .blog-hero {\n        min-height: auto;\n        padding: 80px 0 60px;\n    }\n    .blog-hero-inner {\n        padding: 0 24px;\n    }\n    .blog-hero-inner h1 {\n        font-size: clamp(1.9rem, 5.5vw, 2.6rem);\n    }\n}\n@media (max-width: 640px) {\n    .blog-hero-inner {\n        padding: 0 16px;\n    }\n    .blog-hero-inner .label {\n        margin-bottom: 16px;\n        padding: 9px 16px;\n    }\n    .blog-hero-inner h1 {\n        font-size: 1.85rem;\n    }\n    .blog-hero-inner p {\n        font-size: 0.98rem;\n        line-height: 1.75;\n    }\n}\n\n\/* Page title above the category filters *\/\n.blog-filters-title {\n    display: block;\n    font-family: 'Outfit', sans-serif;\n    font-size: var(--fs-h2);\n    color: var(--primary-dark);\n    margin: 0 0 48px;\n    font-weight: 500;\n    letter-spacing: 1px;\n    text-transform: uppercase;\n    text-align: center;\n    position: relative;\n}\n.blog-filters-title::after {\n    content: '';\n    position: absolute;\n    bottom: -18px;\n    left: 50%;\n    transform: translateX(-50%);\n    width: 50px;\n    height: 2px;\n    background: var(--secondary);\n}\n<\/style>\n\n<!-- BLOG HERO -->\n<section class=\"blog-hero\">\n    <div class=\"blog-hero-inner\">\n        <span class=\"label\">Articole & Nout\u0103\u021bi<\/span>\n        <h1>Blog & Stil de Via\u021b\u0103<\/h1>\n    <\/div>\n<\/section>\n\n<!-- CATEGORY FILTERS -->\n<section class=\"blog-filters-section\">\n    <div class=\"container\">\n        <h2 class=\"blog-filters-title\">Blog &amp; Nout\u0103\u021bi<\/h2>\n        <div class=\"blog-filters-row\" id=\"blog-filters-row\">\n            <button class=\"blog-filter-btn active\" data-filter=\"toate\">Toate articolele<\/button>\n            <!-- Restul filtrelor se genereaz\u0103 dinamic din categoriile WordPress -->\n        <\/div>\n    <\/div>\n<\/section>\n\n<!-- BLOG LISTING -->\n<section class=\"blog-list-section\">\n    <div class=\"container\">\n        <div class=\"blog-list-grid\" id=\"blog-listing-grid\">\n            \n            <!-- Articol 1 -->\n            <article class=\"blog-card-modern\" data-category=\"comunitate\">\n                <div class=\"blog-card-media\">\n                    <img src=\"https:\/\/boreal-plus.ro\/wp-content\/uploads\/2024\/08\/apartamente-finalizate.png\" alt=\"Evolu\u021bia lucr\u0103rilor \u00een complexul reziden\u021bial Boreal Plus\" loading=\"lazy\" decoding=\"async\">\n                <\/div>\n                <div class=\"blog-card-body\">\n                    <div class=\"blog-card-meta\">\n                        <span class=\"blog-card-category\">Comunitate<\/span>\n                        <span class=\"blog-card-date\">15 Mai 2026<\/span>\n                    <\/div>\n                    <h3>Evolu\u021bia lucr\u0103rilor \u00een complexul reziden\u021bial Boreal Plus<\/h3>\n                    <p>Afl\u0103 stadiul actual al construc\u021biei, finisajele interioare realizate \u0219i ce urmeaz\u0103 \u00een urm\u0103toarele luni pentru noul t\u0103u acas\u0103 premium \u00een Constan\u021ba.<\/p>\n                    <a href=\"#\" class=\"blog-card-link\">Cite\u0219te mai mult <span>&rarr;<\/span><\/a>\n                <\/div>\n            <\/article>\n\n            <!-- Articol 2 -->\n            <article class=\"blog-card-modern\" data-category=\"design-interior\">\n                <div class=\"blog-card-media\">\n                    <img src=\"https:\/\/boreal-plus.ro\/wp-content\/uploads\/2026\/06\/living.jpg\" alt=\"Sfaturi practice pentru amenajarea unui living generos \u0219i luminos\" loading=\"lazy\" decoding=\"async\">\n                <\/div>\n                <div class=\"blog-card-body\">\n                    <div class=\"blog-card-meta\">\n                        <span class=\"blog-card-category\">Design Interior<\/span>\n                        <span class=\"blog-card-date\">10 Mai 2026<\/span>\n                    <\/div>\n                    <h3>Sfaturi practice pentru amenajarea unui living generos \u0219i luminos<\/h3>\n                    <p>Descoper\u0103 cum s\u0103 profi\u021bi la maximum de suprafe\u021bele vitrate mari, s\u0103 alegi culorile calde potrivite \u0219i s\u0103 creezi un spa\u021biu elegant \u0219i aerisit.<\/p>\n                    <a href=\"#\" class=\"blog-card-link\">Cite\u0219te mai mult <span>&rarr;<\/span><\/a>\n                <\/div>\n            <\/article>\n\n            <!-- Articol 3 -->\n            <article class=\"blog-card-modern\" data-category=\"lifestyle\">\n                <div class=\"blog-card-media\">\n                    <img src=\"https:\/\/boreal-plus.ro\/wp-content\/uploads\/2026\/06\/ansamblu2.jpg\" alt=\"10 atrac\u021bii \u0219i locuri premium de vizitat \u00een apropierea casei tale\" loading=\"lazy\" decoding=\"async\">\n                <\/div>\n                <div class=\"blog-card-body\">\n                    <div class=\"blog-card-meta\">\n                        <span class=\"blog-card-category\">Lifestyle<\/span>\n                        <span class=\"blog-card-date\">05 Mai 2026<\/span>\n                    <\/div>\n                    <h3>10 atrac\u021bii \u0219i locuri premium de vizitat \u00een apropierea casei tale<\/h3>\n                    <p>De la plimb\u0103ri relaxante pe malul lacului Siutghiol, la cele mai bune restaurante cu specific marin \u0219i plaje premium din nordul Constan\u021bei.<\/p>\n                    <a href=\"#\" class=\"blog-card-link\">Cite\u0219te mai mult <span>&rarr;<\/span><\/a>\n                <\/div>\n            <\/article>\n\n            <!-- Articol 4 -->\n            <article class=\"blog-card-modern\" data-category=\"evolutie-santier\">\n                <div class=\"blog-card-media\">\n                    <img src=\"https:\/\/boreal-plus.ro\/wp-content\/uploads\/2025\/08\/noul-boreal-plus.jpg\" alt=\"Sustenabilitatea \u00een Boreal Plus: Eficien\u021b\u0103 energetic\u0103 ridicat\u0103\" loading=\"lazy\" decoding=\"async\">\n                <\/div>\n                <div class=\"blog-card-body\">\n                    <div class=\"blog-card-meta\">\n                        <span class=\"blog-card-category\">Evolu\u021bie \u0218antier<\/span>\n                        <span class=\"blog-card-date\">28 Aprilie 2026<\/span>\n                    <\/div>\n                    <h3>Sustenabilitatea \u00een Boreal Plus: Eficien\u021b\u0103 energetic\u0103 ridicat\u0103<\/h3>\n                    <p>Cum contribuie panourile solare, izola\u021bia acustic\u0103 \u0219i confortul termic la reducerea costurilor de \u00eentre\u021binere cu 15% \u00een noul t\u0103u apartament.<\/p>\n                    <a href=\"#\" class=\"blog-card-link\">Cite\u0219te mai mult <span>&rarr;<\/span><\/a>\n                <\/div>\n            <\/article>\n\n            <!-- Articol 5 -->\n            <article class=\"blog-card-modern\" data-category=\"design-interior\">\n                <div class=\"blog-card-media\">\n                    <img src=\"https:\/\/boreal-plus.ro\/wp-content\/uploads\/2026\/06\/living.jpg\" alt=\"Amenajarea terasei: O extensie a livingului t\u0103u pe tot parcursul anului\" loading=\"lazy\" decoding=\"async\">\n                <\/div>\n                <div class=\"blog-card-body\">\n                    <div class=\"blog-card-meta\">\n                        <span class=\"blog-card-category\">Design Interior<\/span>\n                        <span class=\"blog-card-date\">20 Aprilie 2026<\/span>\n                    <\/div>\n                    <h3>Amenajarea terasei: O extensie a livingului t\u0103u pe tot parcursul anului<\/h3>\n                    <p>Ghid complet de design interior pentru mobilarea \u0219i decorarea teraselor mari din Boreal Plus, cre\u00e2nd o zon\u0103 perfect\u0103 de relaxare cu vedere panoramic\u0103.<\/p>\n                    <a href=\"#\" class=\"blog-card-link\">Cite\u0219te mai mult <span>&rarr;<\/span><\/a>\n                <\/div>\n            <\/article>\n\n            <!-- Articol 6 -->\n            <article class=\"blog-card-modern\" data-category=\"comunitate\">\n                <div class=\"blog-card-media\">\n                    <img src=\"https:\/\/boreal-plus.ro\/wp-content\/uploads\/2026\/06\/ansamblu1.jpg\" alt=\"Cum se construie\u0219te o comunitate vibrant\u0103 \u00een Constan\u021ba de Nord\" loading=\"lazy\" decoding=\"async\">\n                <\/div>\n                <div class=\"blog-card-body\">\n                    <div class=\"blog-card-meta\">\n                        <span class=\"blog-card-category\">Comunitate<\/span>\n                        <span class=\"blog-card-date\">12 Aprilie 2026<\/span>\n                    <\/div>\n                    <h3>Cum se construie\u0219te o comunitate vibrant\u0103 \u00een Constan\u021ba de Nord<\/h3>\n                    <p>Spa\u021bii verzi ample, locuri de joac\u0103 pentru copii \u0219i o gr\u0103dini\u021b\u0103 privat\u0103 \u2014 descoper\u0103 cum Boreal Plus creeaz\u0103 premisele unui stil de via\u021b\u0103 unit.<\/p>\n                    <a href=\"#\" class=\"blog-card-link\">Cite\u0219te mai mult <span>&rarr;<\/span><\/a>\n                <\/div>\n            <\/article>\n\n        <\/div>\n        <!-- PAGINATION -->\n        <div class=\"blog-pagination\" id=\"blog-pagination\"><\/div>\n    <\/div>\n<\/section>\n\n<!-- CONTACT SECTION -->\n<section class=\"contact-section\" id=\"contact\" style=\"padding: var(--section-py) 0; background: var(--bg-cream);\">\n    <div class=\"container\">\n                <!-- Contact Info Cards -->\n        <!-- CONTACT JOS \u2014 split bleumarin \/ crem (artboard \"Site \u2014 10 \u00b7 Contact jos\", f\u0103r\u0103 subsol) -->\n<div class=\"bp-contact\">\n\n    <div class=\"bp-contact-main reveal\">\n        <span class=\"bp-contact-eyebrow\">Contact<\/span>\n        <h2 class=\"bp-contact-title\">\u00cencepe povestea ta \u00een BOREAL Plus<\/h2>\n\n        <div class=\"bp-contact-grid\">\n            <div class=\"bp-contact-block\">\n                <span class=\"bp-contact-lbl\">Birou v\u00e2nz\u0103ri Constan\u021ba<\/span>\n                <span class=\"bp-contact-val\">Strada Amsterdam nr. 5,<br>Bloc M1, Constan\u021ba<\/span>\n                <a href=\"https:\/\/maps.google.com\/?q=Strada+Amsterdam+Nr.+5,+Bloc+M1,+Constan%C8%9Ba\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"bp-contact-link\">Deschide harta <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.7\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M5 12h14\"\/><path d=\"M13 6l6 6-6 6\"\/><\/svg><\/a>\n            <\/div>\n\n            <div class=\"bp-contact-block\">\n                <span class=\"bp-contact-lbl\">Program<\/span>\n                <div class=\"bp-contact-hours\"><span class=\"bp-contact-day\">Luni \u2013 Vineri<\/span><span class=\"bp-contact-dots\"><\/span><span class=\"bp-contact-time\">08:30 \u2013 18:00<\/span><\/div>\n                <div class=\"bp-contact-hours\"><span class=\"bp-contact-day\">S\u00e2mb\u0103t\u0103<\/span><span class=\"bp-contact-dots\"><\/span><span class=\"bp-contact-time\">10:00 \u2013 15:30<\/span><\/div>\n                <div class=\"bp-contact-hours\"><span class=\"bp-contact-day\">Duminic\u0103<\/span><span class=\"bp-contact-dots\"><\/span><span class=\"bp-contact-time\">10:00 \u2013 14:00<\/span><\/div>\n            <\/div>\n\n            <div class=\"bp-contact-block\">\n                <span class=\"bp-contact-lbl\">Contact v\u00e2nz\u0103ri<\/span>\n                <a href=\"tel:+40735509700\" class=\"bp-contact-tel\">+40 735 509 700<\/a>\n                <a href=\"mailto:hello@boreal-plus.ro\" class=\"bp-contact-mail\">hello@boreal-plus.ro<\/a>\n            <\/div>\n\n            <div class=\"bp-contact-block\">\n                <span class=\"bp-contact-lbl\">Sediu central<\/span>\n                <span class=\"bp-contact-addr\">Greenfield B\u0103neasa, Drumul P\u0103durea Mogo\u0219oaia 31\u201341, Sector 1, Bucure\u0219ti<\/span>\n                <a href=\"tel:+40212307570\" class=\"bp-contact-mail\">+40 21 230 75 70<\/a>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <div class=\"bp-contact-side reveal\">\n        <span class=\"bp-contact-eyebrow\">Sun\u0103 un consultant<\/span>\n        <p class=\"bp-contact-side-desc\">\u00ce\u021bi r\u0103spund direct, f\u0103r\u0103 call center.<\/p>\n            <div class=\"bp-contact-people\">\n                <div class=\"bp-contact-person\">\n                    <img src=\"https:\/\/boreal-plus.ro\/wp-content\/uploads\/2024\/08\/Elena-Neagu.png\" alt=\"Elena Neagu\" loading=\"lazy\" decoding=\"async\">\n                    <span class=\"bp-contact-person-name\">Elena Neagu<\/span>\n                    <span class=\"bp-contact-person-role\">Consultant v\u00e2nz\u0103ri<\/span>\n                    <a href=\"tel:+40729100577\" class=\"bp-contact-person-tel\">0729 100 577<\/a>\n                <\/div>\n                <div class=\"bp-contact-person\">\n                    <img src=\"https:\/\/boreal-plus.ro\/wp-content\/uploads\/2024\/08\/Filiz-Ismail.png\" alt=\"Filiz Ismail\" loading=\"lazy\" decoding=\"async\">\n                    <span class=\"bp-contact-person-name\">Filiz Ismail<\/span>\n                    <span class=\"bp-contact-person-role\">Consultant v\u00e2nz\u0103ri<\/span>\n                    <a href=\"tel:+40747100341\" class=\"bp-contact-person-tel\">0747 100 341<\/a>\n                <\/div>\n            <\/div>\n        <a href=\"#contact-form-component\" class=\"bp-contact-cta\">Preferi s\u0103 te sun\u0103m noi <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.7\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M5 12h14\"\/><path d=\"M13 6l6 6-6 6\"\/><\/svg><\/a>\n    <\/div>\n\n<\/div>\n\n        <!-- Dynamic Form \/ Elementor Shortcode Wrapper -->\n        <div class=\"contact-form-large reveal\" style=\"margin: 0 auto;\">\n            <div id=\"contact-form-component\">\n                <!-- Elementor shortcode template for WordPress insertion -->\n                \t\t<div data-elementor-type=\"container\" data-elementor-id=\"16282\" class=\"elementor elementor-16282\" data-elementor-post-type=\"elementor_library\">\n\t\t\t\t<div class=\"elementor-element elementor-element-2363c9d e-flex e-con-boxed e-con e-parent\" data-id=\"2363c9d\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-b970a7d elementor-widget elementor-widget-html\" data-id=\"b970a7d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\n\/* ============================================================================\n   FORMULAR BOREAL PLUS \u2014 split bleumarin \/ alb, artboard \"Site \u2014 09 \u00b7 Formular\"\n   Stilurile stau aici, nu \u00een style.css, pentru c\u0103 formularul e o singur\u0103 bucat\u0103:\n   se lipe\u0219te \u00een template-ul Elementor 16282 \u0219i apare la fel pe toate paginile.\n   ============================================================================ *\/\n\n\/* F\u00e2\u0219iile de culoare merg p\u00e2n\u0103 la marginile ecranului. Pe fiecare pagin\u0103\n   formularul st\u0103 \u00eentr-un .container centrat, deci ie\u0219im din el: l\u0103\u021bime c\u00e2t\n   fereastra plus marginile negative care anuleaz\u0103 centrarea. *\/\n.bp-form-split {\n    \/* Unde \u00eencepe con\u021binutul din .container, ca panourile s\u0103 se alinieze cu\n       restul paginii chiar dac\u0103 fundalul lor curge p\u00e2n\u0103 la margine. *\/\n    --bp-edge: calc(max(0px, (100vw - var(--max-width, 1280px)) \/ 2) + var(--container-px, 20px));\n\n    width: 100vw;\n    margin-left: calc(50% - 50vw);\n    margin-right: calc(50% - 50vw);\n\n    display: grid;\n    grid-template-columns: 0.86fr 1.14fr;\n    align-items: stretch;\n    font-family: 'Inter', sans-serif;\n    text-align: left;\n}\n\n\/* Sec\u021biunea gazd\u0103 \u00ee\u0219i pierde padding-ul vertical: f\u00e2\u0219iile de culoare trebuie s\u0103\n   ating\u0103 sec\u021biunile vecine, iar spa\u021bierea o dau panourile pe din\u0103untru.\n   :has() pe str\u0103mo\u0219 \u2014 singurul mod de a ajunge la el dintr-un fragment lipit. *\/\n.contact-section:has(.bp-form-split),\n.camp-consultant:has(.bp-form-split) { padding-bottom: 0 !important; }\n\n\/* Spa\u021biul de SUS dispare doar c\u00e2nd formularul deschide sec\u021biunea. Pe\n   apartamente.html sec\u021biunea \u00eencepe cu un antet care introduce formularul, iar\n   acolo <section> poart\u0103 clasa .has-intro, deci padding-ul de sus r\u0103m\u00e2ne. *\/\n.contact-section:has(.bp-form-split):not(.has-intro),\n.camp-consultant:has(.bp-form-split):not(.has-intro) { padding-top: 0 !important; }\n.contact-form-large:has(.bp-form-split) { margin: 0 !important; }\n\n\/* Elementor randeaz\u0103 template-ul 16282 \u00een containerele lui\n   (.elementor > .e-con > .e-con-inner), iar .e-con are padding vertical din set\u0103rile\n   proprii \u2014 40px sus \u0219i jos \u00een mod obi\u0219nuit. \u0102la e spa\u021biul care \u021binea formularul\n   nelipit de sec\u021biunea urm\u0103toare; nu se vede local, doar \u00een WordPress.\n\n   \u021ainta e #contact-form-component, wrapperul nostru din jurul shortcode-ului, prezent\n   pe toate paginile. NU un :has(.bp-form-split) pe .e-con: :has() se potrive\u0219te pe\n   descenden\u021bi, deci ar prinde \u0219i containerele exterioare ale paginii \u0219i le-ar \u0219terge\n   spa\u021bierea. *\/\n#contact-form-component,\n#contact-form-component .elementor,\n#contact-form-component .e-con,\n#contact-form-component .e-con-inner,\n#contact-form-component .elementor-widget,\n#contact-form-component .elementor-widget-container {\n    padding-block-start: 0 !important;\n    padding-block-end: 0 !important;\n    margin-block-start: 0 !important;\n    margin-block-end: 0 !important;\n}\n\n\/* 100vw include l\u0103\u021bimea barei de scroll clasice (Windows, Linux), deci f\u00e2\u0219ia ar fi\n   cu ~15px mai lat\u0103 dec\u00e2t zona vizibil\u0103 \u0219i ar ap\u0103rea o bar\u0103 orizontal\u0103 pe toat\u0103\n   pagina. clip, NU hidden: hidden ar for\u021ba \u0219i axa vertical\u0103 \u00eentr-un scroll\n   container, clip las\u0103 overflow-y vizibil, deci pagina scroleaz\u0103 normal. Meniul\n   mobil e position: fixed, deci nu e afectat de clipping. *\/\nbody:has(.bp-form-split) { overflow-x: clip; }\n\n\/* ---------- panoul bleumarin ---------- *\/\n.bp-form-aside {\n    background-color: var(--bp-dark-bg-color, #001F2B);\n    background-image: var(--bp-dark-bg-image,\n        radial-gradient(1100px 620px at 84% 6%, rgba(196, 154, 110, 0.085), rgba(196, 154, 110, 0) 58%),\n        radial-gradient(900px 640px at 6% 100%, rgba(0, 0, 0, 0.28), rgba(0, 0, 0, 0) 64%),\n        linear-gradient(158deg, #002B3B 0%, #001F2B 52%, #00151E 100%));\n    padding: clamp(40px, 4.6vw, 64px) clamp(24px, 3.6vw, 52px) clamp(40px, 4.6vw, 64px) var(--bp-edge);\n    display: flex;\n    flex-direction: column;\n}\n\n.bp-form-aside-eyebrow {\n    font-size: 0.64rem;\n    font-weight: 500;\n    letter-spacing: 0.3em;\n    text-transform: uppercase;\n    color: #B49079;\n    margin-bottom: 20px;\n}\n\n\/* !important pe font\/dimensiune\/greutate\/culoare: kit-ul global Elementor are\n   `.elementor-kit-XXXX h2` (0,1,1), care bate o clas\u0103 simpl\u0103 (0,1,0). *\/\n.bp-form-aside-title {\n    font-family: 'Playfair Display', Georgia, serif !important;\n    font-size: var(--bp-cta-title-size, clamp(1.6rem, 3vw, 2.4rem)) !important;\n    font-weight: 600 !important;\n    line-height: 1.16 !important;\n    letter-spacing: -0.3px;\n    color: #ffffff !important;\n    margin: 0 0 18px 0 !important;\n}\n\n.bp-form-aside-desc {\n    font-size: 0.96rem;\n    line-height: 1.85;\n    color: rgba(255, 255, 255, 0.7);\n    margin: 0 0 clamp(28px, 3.4vw, 44px) 0;\n}\n\n.bp-form-aside-list { display: flex; flex-direction: column; }\n\n.bp-form-aside-row {\n    display: flex;\n    align-items: baseline;\n    gap: 20px;\n    padding: clamp(13px, 1.4vw, 18px) 0;\n    border-top: 1px solid rgba(255, 255, 255, 0.14);\n}\n.bp-form-aside-row:last-child { border-bottom: 1px solid rgba(255, 255, 255, 0.14); }\n\n.bp-form-aside-num {\n    font-family: 'Playfair Display', Georgia, serif;\n    font-size: 1rem;\n    color: #B49079;\n    min-width: 26px;\n    flex-shrink: 0;\n}\n\n.bp-form-aside-txt {\n    font-size: 0.94rem;\n    line-height: 1.7;\n    color: rgba(255, 255, 255, 0.86);\n}\n\n\/* margin-top: auto lipe\u0219te blocul de telefon de baza panoului, ca \u00een machet\u0103. *\/\n.bp-form-aside-call {\n    display: flex;\n    flex-direction: column;\n    gap: 8px;\n    margin-top: auto;\n    padding-top: clamp(28px, 3.6vw, 46px);\n}\n\n.bp-form-aside-call-lbl {\n    font-size: 0.6rem;\n    font-weight: 500;\n    letter-spacing: 0.28em;\n    text-transform: uppercase;\n    color: rgba(255, 255, 255, 0.45);\n}\n\n\/* !important pe color: kit-ul Elementor are `.elementor-kit-XXXX a` cu culoarea de link a\n   sitului (teal), care pe bleumarin e practic invizibil\u0103 \u2014 de-aia \u201enu se vedea\" pe live.\n   Greutate 400, nu 300: la 2rem sub\u021bire, albul pe fundal \u00eenchis se citea slab. *\/\n.bp-form-aside-tel {\n    font-family: 'Outfit', sans-serif !important;\n    font-size: clamp(1.5rem, 2.2vw, 2rem) !important;\n    font-weight: 400 !important;\n    color: #ffffff !important;\n    line-height: 1.2;\n    text-decoration: none !important;\n}\n.bp-form-aside-tel:hover,\n.bp-form-aside-tel:focus-visible { color: #d4b8a0 !important; }\n\n.bp-form-aside-addr {\n    font-size: 0.9rem;\n    line-height: 1.7;\n    color: rgba(255, 255, 255, 0.6);\n}\n\n\/* ---------- panoul crem, cu formularul ---------- *\/\n.bp-form-panel {\n    background: #F4F1EB;\n    padding: clamp(40px, 4.6vw, 64px) var(--bp-edge) clamp(40px, 4.6vw, 64px) clamp(24px, 3.8vw, 56px);\n    display: flex;\n    flex-direction: column;\n    justify-content: center;\n    min-width: 0;\n}\n\n\/* position\/overflow r\u0103m\u00e2n: honeypot-ul e absolut \u0219i se sprijin\u0103 pe ele. *\/\n.bp-form-container {\n    position: relative;\n    overflow: hidden;\n}\n\n.bp-form-row {\n    display: grid;\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n    gap: clamp(22px, 2.6vw, 34px);\n    margin-bottom: clamp(22px, 2.4vw, 32px);\n}\n\n.bp-form-group {\n    display: flex;\n    flex-direction: column;\n    gap: 12px;\n    margin-bottom: clamp(22px, 2.4vw, 32px);\n}\n\n\/* Eticheta mic\u0103, foarte spa\u021biat\u0103 \u2014 exact ca \u00een artboard. *\/\n.bp-form-group label {\n    font-size: 0.6rem;\n    font-weight: 500;\n    letter-spacing: 0.26em;\n    text-transform: uppercase;\n    color: #96A0A6;\n    transition: color 0.3s ease;\n}\n.bp-form-group:focus-within label { color: #B49079; }\n\n\/* C\u00e2mpul e o linie, nu o caset\u0103. *\/\n\/* !important pe fiecare proprietate pe care o d\u0103 \u0219i kit-ul global Elementor. Regula\n   lui e:\n       .elementor-kit-XXXX input:not([type=\"button\"]):not([type=\"submit\"]), \u2026 textarea\n   adic\u0103 specificitate (0,3,1) \u2014 bate (0,1,1) c\u00e2t are selectorul de aici. F\u0103r\u0103\n   !important, kit-ul impune border-width: 1px pe TOATE laturile (de-aia ap\u0103reau\n   casete \u00een loc de linii), plus fontul, greutatea \u0219i culoarea textului.\n   Kit-ul NU atinge padding \u0219i nici <select>, deci alea r\u0103m\u00e2n f\u0103r\u0103. *\/\n.bp-form-group input,\n.bp-form-group select,\n.bp-form-group textarea {\n    width: 100%;\n    padding: 0 0 14px 0;\n    border: 0 !important;\n    border-bottom: 1px solid #C9C2B7 !important;\n    border-radius: 0 !important;\n    \/* background-color, NU shorthand-ul background: acesta ar \u0219terge\n       background-image, adic\u0103 s\u0103geata select-ului de mai jos. *\/\n    background-color: transparent;\n    font-family: 'Inter', sans-serif !important;\n    font-size: 1rem !important;\n    font-weight: 400 !important;\n    color: #001F2B !important;\n    outline: none;\n    transition: border-color 0.3s ease;\n}\n\n\/* Textul-fantom\u0103 e mai deschis \u0219i mai sub\u021bire dec\u00e2t o valoare completat\u0103. *\/\n.bp-form-group input::placeholder,\n.bp-form-group textarea::placeholder {\n    color: #B3BBC0;\n    font-weight: 300;\n}\n\n.bp-form-group input:focus,\n.bp-form-group select:focus,\n.bp-form-group textarea:focus {\n    border-bottom-color: #001F2B !important;\n}\n\n\/* ---------- validare: starea invalid\u0103 + mesajul de sub c\u00e2mp ----------\n   .is-invalid se pune de script pe c\u00e2mp; (0,2,1) bate (0,1,1) al regulii de baz\u0103, deci\n   !important-ul de acolo nu ne \u00eencurc\u0103. Mesajul st\u0103 \u00een .bp-form-group cu gap 12px, deci\n   \u00eel tragem pu\u021bin \u00een sus ca s\u0103 se lipeasc\u0103 de linie. *\/\n.bp-form-group input.is-invalid,\n.bp-form-group select.is-invalid,\n.bp-form-group textarea.is-invalid {\n    border-bottom-color: #B4423A !important;\n}\n.bp-form-group.is-invalid label { color: #B4423A; }\n\n.bp-form-field-error {\n    display: none;\n    margin-top: -4px;\n    font-size: 0.78rem;\n    font-weight: 400;\n    line-height: 1.4;\n    color: #B4423A;\n}\n.bp-form-field-error.is-visible { display: block; }\n\n.bp-form-group textarea {\n    resize: vertical;\n    min-height: 76px;\n    padding-bottom: 40px;\n    line-height: 1.6;\n}\n\n.bp-form-group select {\n    appearance: none;\n    -webkit-appearance: none;\n    cursor: pointer;\n    background-image: url(\"data:image\/svg+xml,%3Csvg width='12' height='8' viewBox='0 0 12 8' fill='none' xmlns='http:\/\/www.w3.org\/2000\/svg'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%23B49079' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'\/%3E%3C\/svg%3E\");\n    background-repeat: no-repeat;\n    \/* C\u00e2mpul are 14px padding jos, deci centrul cutiei e cu 7px sub linia\n       textului; f\u0103r\u0103 corec\u021bie s\u0103geata at\u00e2rn\u0103 sub cuv\u00e2nt. *\/\n    \/* Forma cu 4 valori: cuv\u00e2nt-cheie + offset pe FIECARE ax\u0103. Varianta cu trei\n       valori (right 2px calc(...)) e invalid\u0103, browserul o arunc\u0103 \u0219i cade pe 0% 0%,\n       adic\u0103 s\u0103geata ajunge \u00een col\u021bul din st\u00e2nga sus. *\/\n    background-position: right 2px top calc(50% - 7px);\n    padding-right: 28px;\n}\n\n\/* Varianta blocat\u0103 a c\u00e2mpului de apartament, construit\u0103 de lockTo() mai jos:\n   acelea\u0219i linii, ca s\u0103 nu reapar\u0103 o caset\u0103. *\/\n.bp-form-static {\n    width: 100%;\n    padding: 0 0 14px 0;\n    border-bottom: 1px solid #C9C2B7;\n    font-size: 1rem;\n    font-weight: 400;\n    color: #001F2B;\n    line-height: 1.35;\n}\n\n\/* ---------- bifele (deocamdat\u0103 doar GDPR) ----------\n   .bp-form-checks = grupul (poart\u0103 spa\u021biul de sub el), .bp-form-check = un r\u00e2nd; alte\n   consim\u021b\u0103minte (newsletter, marketing) se adaug\u0103 ca r\u00e2nduri noi, f\u0103r\u0103 CSS \u00een plus. *\/\n.bp-form-checks {\n    display: flex;\n    flex-direction: column;\n    gap: 12px;\n    margin-bottom: clamp(26px, 3vw, 36px);\n}\n.bp-form-check {\n    display: flex;\n    align-items: flex-start;\n    gap: 14px;\n}\n\/* Sub r\u00e2ndul GDPR, nu sub tot grupul: gap-ul de 12px al coloanei ar l\u0103sa-o prea departe. *\/\n.bp-form-checks .bp-form-field-error { margin: -6px 0 0 30px; }\n\n\/* P\u0103trat cu contur bronz, ca \u00een machet\u0103. appearance:none schimb\u0103 doar aspectul \u2014\n   r\u0103m\u00e2ne un checkbox adev\u0103rat, deci atributul required \u0219i FormData func\u021bioneaz\u0103 la fel. *\/\n.bp-form-check input[type=\"checkbox\"] {\n    appearance: none;\n    -webkit-appearance: none;\n    width: 16px;\n    height: 16px;\n    margin: 3px 0 0 0;\n    \/* Kit-ul prinde \u0219i checkbox-ul cu regula de mai sus \u0219i \u00eei impune culoarea lui\n       de bordur\u0103; f\u0103r\u0103 !important p\u0103tratul iese gri, nu bronz. *\/\n    border: 1px solid #B49079 !important;\n    border-radius: 0 !important;\n    background: transparent;\n    flex-shrink: 0;\n    cursor: pointer;\n    display: grid;\n    place-content: center;\n}\n.bp-form-check input[type=\"checkbox\"]::before {\n    content: '';\n    width: 8px;\n    height: 8px;\n    background: #B49079;\n    transform: scale(0);\n    transition: transform 0.15s ease;\n}\n.bp-form-check input[type=\"checkbox\"]:checked::before { transform: scale(1); }\n.bp-form-check input[type=\"checkbox\"]:focus-visible {\n    outline: 2px solid #001F2B;\n    outline-offset: 2px;\n}\n.bp-form-check input[type=\"checkbox\"].is-invalid { border-color: #B4423A !important; }\n\n.bp-form-check label {\n    font-size: 0.85rem;\n    font-weight: 300;\n    line-height: 1.7;\n    color: #7D888F;\n    cursor: pointer;\n}\n.bp-form-check label a {\n    color: #001F2B;\n    text-decoration: none;\n    border-bottom: 1px solid #C9C2B7;\n}\n.bp-form-check label a:hover { border-bottom-color: #B49079; }\n\n\/* ---------- buton + not\u0103 ---------- *\/\n.bp-form-actions {\n    display: flex;\n    align-items: center;\n    flex-wrap: wrap;\n    gap: clamp(14px, 2vw, 26px);\n}\n\n.bp-form-submit {\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    gap: 14px;\n    \/* Kit-ul are `.elementor-kit-XXXX button` (0,1,1) > .bp-form-submit (0,1,0) \u0219i\n       impune padding: 18px 24px, font-size, greutate, spa\u021biere \u00eentre litere,\n       text-transform \u0219i border-radius: 0. Toate cele de mai jos sunt exact\n       propriet\u0103\u021bile din acea regul\u0103. *\/\n    padding: 19px 40px !important;\n    background: #001F2B !important;\n    border: 1px solid #001F2B !important;\n    color: #ffffff !important;\n    font-family: 'Inter', sans-serif !important;\n    font-size: 0.68rem !important;\n    font-weight: 600 !important;\n    letter-spacing: 0.22em !important;\n    text-transform: uppercase !important;\n    cursor: pointer;\n    \/* Raza de 4px a tuturor butoanelor sitului; macheta le are cu col\u021b drept. *\/\n    border-radius: 4px !important;\n    transition: background 0.3s ease, border-color 0.3s ease, color 0.3s ease;\n}\n\n\/* S\u0103geata e pus\u0103 din CSS, nu ca <svg> \u00een markup: scriptul de trimitere scrie\n   butonului textContent (\"Se trimite...\" \u0219i \u00eenapoi), ceea ce ar \u0219terge un copil. *\/\n.bp-form-submit::after {\n    content: '';\n    width: 15px;\n    height: 15px;\n    flex-shrink: 0;\n    background: url(\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'\/%3E%3Cpath d='M13 6l6 6-6 6'\/%3E%3C\/svg%3E\") no-repeat center \/ contain;\n    transition: transform 0.35s ease;\n}\n.bp-form-submit:hover { background: #B49079 !important; border-color: #B49079 !important; }\n.bp-form-submit:hover::after { transform: translateX(4px); }\n.bp-form-submit:disabled { opacity: 0.7; cursor: wait; }\n.bp-form-submit:disabled::after { display: none; }\n\n.bp-form-note {\n    \/* flex-basis mic + shrink: nota st\u0103 l\u00e2ng\u0103 buton \u0219i \u00ee\u0219i rupe textul intern,\n       \u00een loc s\u0103 treac\u0103 \u00eentreag\u0103 pe r\u00e2ndul urm\u0103tor. *\/\n    flex: 1 1 200px;\n    margin: 0;\n    font-size: 0.82rem;\n    font-weight: 300;\n    color: #7D888F;\n}\n\n\/* ---------- mesaje de eroare ---------- *\/\n.bp-form-alert {\n    display: none;\n    margin-bottom: 24px;\n    padding: 14px 18px;\n    border-radius: 4px;\n    font-size: 0.92rem;\n    line-height: 1.5;\n}\n.bp-form-alert.is-visible { display: block; }\n.bp-form-alert--error {\n    background: #fff5f5;\n    border: 1px solid #f5b5b5;\n    color: #8b2e2e;\n}\n\n.bp-form-honeypot {\n    position: absolute;\n    left: -9999px;\n    width: 1px;\n    height: 1px;\n    overflow: hidden;\n}\n\n\/* ---------- pe telefon panourile se stivuiesc ---------- *\/\n@media (max-width: 900px) {\n    .bp-form-split { grid-template-columns: 1fr; }\n    .bp-form-aside,\n    .bp-form-panel { padding-left: var(--bp-edge); padding-right: var(--bp-edge); }\n    .bp-form-row { grid-template-columns: 1fr; gap: 0; }\n    .bp-form-submit { width: 100%; }\n    .bp-form-actions { gap: 14px; }\n}\n<\/style>\n\n<div class=\"bp-form-split\">\n\n    <div class=\"bp-form-aside\">\n        <span class=\"bp-form-aside-eyebrow\">Programare vizionare<\/span>\n        <h2 class=\"bp-form-aside-title\">Vino s\u0103 vezi apartamentul \u00eenainte s\u0103 decizi<\/h2>\n        <p class=\"bp-form-aside-desc\">Un consultant dedicat te \u00eenso\u021be\u0219te la vizionare \u0219i \u00ee\u021bi explic\u0103 pas cu pas pre\u021bul, plata \u0219i termenele.<\/p>\n\n        <div class=\"bp-form-aside-list\">\n            <div class=\"bp-form-aside-row\">\n                <span class=\"bp-form-aside-num\">01<\/span>\n                <span class=\"bp-form-aside-txt\">Vizionare la fa\u021ba locului, f\u0103r\u0103 costuri<\/span>\n            <\/div>\n            <div class=\"bp-form-aside-row\">\n                <span class=\"bp-form-aside-num\">02<\/span>\n                <span class=\"bp-form-aside-txt\">Apartamente Faza 1, gata de mutare<\/span>\n            <\/div>\n            <div class=\"bp-form-aside-row\">\n                <span class=\"bp-form-aside-num\">03<\/span>\n                <span class=\"bp-form-aside-txt\">Acela\u0219i consultant, de la prima vizionare p\u00e2n\u0103 la semnare<\/span>\n            <\/div>\n        <\/div>\n\n        <div class=\"bp-form-aside-call\">\n            <span class=\"bp-form-aside-call-lbl\">Sun\u0103 direct<\/span>\n            <a href=\"tel:+40735509700\" class=\"bp-form-aside-tel\">+40 735 509 700<\/a>\n            <span class=\"bp-form-aside-addr\">Strada Amsterdam nr. 5, Bloc M1, Constan\u021ba<\/span>\n        <\/div>\n    <\/div>\n\n    <div class=\"bp-form-panel\">\n        <div class=\"bp-form-container\" id=\"contact-form\">\n\n            <div class=\"bp-form-alert bp-form-alert--error\" id=\"bp-form-error\" role=\"alert\" aria-live=\"assertive\"><\/div>\n\n            <form id=\"bp-lead-form\" novalidate>\n                <div class=\"bp-form-honeypot\" aria-hidden=\"true\">\n                    <label for=\"bp-website\">Website<\/label>\n                    <input type=\"text\" id=\"bp-website\" name=\"bp_website\" tabindex=\"-1\" autocomplete=\"off\">\n                <\/div>\n\n                <div class=\"bp-form-row\">\n                    <div class=\"bp-form-group\">\n                        <label for=\"bp-name\">Nume complet *<\/label>\n                        <input type=\"text\" id=\"bp-name\" name=\"name\" placeholder=\"Numele t\u0103u\" autocomplete=\"name\" maxlength=\"80\" required aria-describedby=\"bp-name-error\">\n                        <span class=\"bp-form-field-error\" id=\"bp-name-error\" aria-live=\"polite\"><\/span>\n                    <\/div>\n                    <div class=\"bp-form-group\">\n                        <label for=\"bp-phone\">Telefon *<\/label>\n                        <input type=\"tel\" id=\"bp-phone\" name=\"phone\" placeholder=\"+40 7XX XXX XXX\" autocomplete=\"tel\" inputmode=\"tel\" maxlength=\"20\" required aria-describedby=\"bp-phone-error\">\n                        <span class=\"bp-form-field-error\" id=\"bp-phone-error\" aria-live=\"polite\"><\/span>\n                    <\/div>\n                <\/div>\n\n                <div class=\"bp-form-row\">\n                    <div class=\"bp-form-group\">\n                        <label for=\"bp-email\">Email *<\/label>\n                        <input type=\"email\" id=\"bp-email\" name=\"email\" placeholder=\"email@exemplu.ro\" autocomplete=\"email\" inputmode=\"email\" maxlength=\"120\" required aria-describedby=\"bp-email-error\">\n                        <span class=\"bp-form-field-error\" id=\"bp-email-error\" aria-live=\"polite\"><\/span>\n                    <\/div>\n                    <div class=\"bp-form-group\">\n                        <label for=\"bp-apt-type\">Te intereseaz\u0103<\/label>\n                        <!-- Op\u021biunile de mai jos sunt doar FALLBACK. La \u00eenc\u0103rcare sunt \u00eenlocuite cu\n                             lista complet\u0103 de apartamente, citit\u0103 din REST (vezi scriptul de jos).\n                             Dac\u0103 fetch-ul e\u0219ueaz\u0103, formularul r\u0103m\u00e2ne func\u021bional cu aceste 3 op\u021biuni. -->\n                        <select id=\"bp-apt-type\" name=\"apartment_type\">\n                            <option value=\"\">Selecteaz\u0103 apartamentul<\/option>\n                            <option value=\"Garsonier\u0103\">Garsonier\u0103<\/option>\n                            <option value=\"2 camere\">2 Camere<\/option>\n                            <option value=\"3 camere\">3 Camere<\/option>\n                        <\/select>\n                        <span class=\"bp-form-field-error\" id=\"bp-apt-type-error\" aria-live=\"polite\"><\/span>\n                    <\/div>\n                <\/div>\n\n                <div class=\"bp-form-group\">\n                    <label for=\"bp-message\">Mesaj (op\u021bional)<\/label>\n                    <textarea id=\"bp-message\" name=\"message\" placeholder=\"Spune-ne ce cau\u021bi...\" maxlength=\"1000\" aria-describedby=\"bp-message-error\"><\/textarea>\n                    <span class=\"bp-form-field-error\" id=\"bp-message-error\" aria-live=\"polite\"><\/span>\n                <\/div>\n\n                <div class=\"bp-form-checks\">\n                    <div class=\"bp-form-check\">\n                        <input type=\"checkbox\" id=\"bp-gdpr\" name=\"gdpr\" value=\"1\" required aria-describedby=\"bp-gdpr-error\">\n                        <label for=\"bp-gdpr\">Sunt de acord cu <a href=\"https:\/\/boreal-plus.ro\/politica-de-protectie-a-datelor\/\" target=\"_blank\" rel=\"noopener noreferrer\">Politica de protec\u021bie a datelor<\/a> \u0219i cu <a href=\"https:\/\/boreal-plus.ro\/nota-de-informare\/\" target=\"_blank\" rel=\"noopener noreferrer\">Nota de informare<\/a>. *<\/label>\n                    <\/div>\n                    <span class=\"bp-form-field-error\" id=\"bp-gdpr-error\" aria-live=\"polite\"><\/span>\n                <\/div>\n\n                <!-- Wrapper pur de a\u0219ezare: butonul \u0219i nota pe un r\u00e2nd.\n                     Butonul r\u0103m\u00e2ne descendent al formularului, deci\n                     form.querySelector('.bp-form-submit') din script \u00eel g\u0103se\u0219te la fel. -->\n                <div class=\"bp-form-actions\">\n                    <button type=\"submit\" class=\"bp-form-submit\">Programeaz\u0103 o vizionare<\/button>\n                    <p class=\"bp-form-note\">Garant\u0103m confiden\u021bialitatea datelor dumneavoastr\u0103.<\/p>\n                <\/div>\n            <\/form>\n        <\/div>\n    <\/div>\n\n<\/div>\n\n<!-- \u2500\u2500 Lista de apartamente \u00een c\u00e2mpul \u201eInteres\" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n     Op\u021biunile se construiesc din REST (\/wp-json\/wp\/v2\/apartamente), deci selectul se\n     actualizeaz\u0103 singur c\u00e2nd se adaug\u0103 apartamente noi \u2014 nu trebuie atins codul.\n     Pe pagina unui apartament se preselecteaz\u0103 EXACT acel apartament, iar \u00een lead pleac\u0103\n     numele complet (ex. \u201e2 camere 70 mp tip 3\"), nu doar num\u0103rul de camere.\n     Carrier-ul Pods d\u0103 slug-ul apartamentului curent; pe alte pagini r\u0103m\u00e2ne gol. -->\n<div id=\"bp-cf-apt\"\n     data-post-name=\"&lt;div  class=&quot;pods-ui-notice pods-ui-notice-notice pods-ui-notice-notice-error pods-ui-notice-is-dismissible pods-ui-notice-front&quot;&gt;&lt;p&gt;&lt;strong&gt;Pods Embed Error:&lt;\/strong&gt; Pod not found.&lt;\/p&gt;&lt;\/div&gt;\"\n     data-camere=\"&lt;div  class=&quot;pods-ui-notice pods-ui-notice-notice pods-ui-notice-notice-error pods-ui-notice-is-dismissible pods-ui-notice-front&quot;&gt;&lt;p&gt;&lt;strong&gt;Pods Embed Error:&lt;\/strong&gt; Pod not found.&lt;\/p&gt;&lt;\/div&gt;\"\n     style=\"display:none\"><\/div>\n<script>\n(function () {\n    var API = 'https:\/\/boreal-plus.ro\/wp-json\/wp\/v2\/apartamente?per_page=100&_fields=slug,title';\n    var GROUPS = [\n        { rooms: 1, label: 'Garsoniere' },\n        { rooms: 2, label: '2 camere' },\n        { rooms: 3, label: '3 camere' },\n        { rooms: 0, label: 'Alte apartamente' }\n    ];\n\n    \/\/ Slug-ul apartamentului pe care se afl\u0103 vizitatorul (sau null pe orice alt\u0103 pagin\u0103).\n    function currentSlug() {\n        \/\/ 1) carrier-ul Pods \u2014 autoritar, se completeaz\u0103 doar pe pagina unui apartament\n        var ids = ['bp-cf-apt', 'bp-apt-preselect'];\n        for (var i = 0; i < ids.length; i++) {\n            var el = document.getElementById(ids[i]);\n            if (!el) continue;\n            var v = (el.getAttribute('data-post-name') || '').trim();\n            if (v && v.indexOf('[pods') === -1) return v; \/\/ shortcode nerandat \u2192 ignor\u0103m\n        }\n        \/\/ 2) fallback pe URL: \/apartamente\/<slug>\n        var m = window.location.pathname.match(\/\\\/apartamente\\\/([^\\\/]+)\\\/?$\/);\n        return m ? decodeURIComponent(m[1]) : null;\n    }\n\n    \/\/ Pe landing (campaign.html) wrapperul #contact-form-component poart\u0103\n    \/\/ data-bp-apt-scope=\"listed\": selectul arat\u0103 DOAR apartamentele listate \u00een pagin\u0103, adic\u0103\n    \/\/ cardurile .lux-card r\u0103mase vizibile dup\u0103 filtrul de Faza 1 al campaniei \u2014 nu toat\u0103\n    \/\/ lista din REST. Slug-ul se ia din linkul cardului (\/apartamente\/<slug>), acela\u0219i cu\n    \/\/ cel din REST. Pe orice alt\u0103 pagin\u0103 \u00eentoarce null = f\u0103r\u0103 restric\u021bie.\n    function listedSlugs() {\n        var wrap = document.getElementById('contact-form-component');\n        if (!wrap || wrap.getAttribute('data-bp-apt-scope') !== 'listed') return null;\n\n        var slugs = {};\n        var found = 0;\n        document.querySelectorAll('.lux-card').forEach(function (card) {\n            \/\/ \u00cen WP cardul st\u0103 \u00eentr-o celul\u0103 .e-loop-item; filtrul campaniei ascunde celula.\n            var cell = card.closest('.e-loop-item') || card;\n            if (getComputedStyle(cell).display === 'none' || getComputedStyle(card).display === 'none') return;\n            var a = card.querySelector('a[href*=\"\/apartamente\/\"]');\n            var m = a && (a.getAttribute('href') || '').match(\/\\\/apartamente\\\/([^\\\/?#]+)\/);\n            if (!m) return;\n            slugs[decodeURIComponent(m[1])] = true;\n            found++;\n        });\n\n        if (!found) {\n            \/\/ Loop Grid-ul lipse\u0219te sau nu s-a filtrat \u00eenc\u0103: mai bine toat\u0103 lista dec\u00e2t un select gol.\n            console.warn('[bp-form] scope \"listed\", dar nu am g\u0103sit carduri vizibile \u2014 afi\u0219ez toat\u0103 lista');\n            return null;\n        }\n        return slugs;\n    }\n\n    \/\/ Titlurile WP vin cu entit\u0103\u021bi HTML (&#8211;, &amp;) \u2014 le transform\u0103m \u00een text curat.\n    function decodeEntities(html) {\n        var ta = document.createElement('textarea');\n        ta.innerHTML = html || '';\n        return (ta.value || '').trim();\n    }\n\n    function roomsOf(title) {\n        var t = title.toLowerCase();\n        if (\/garsonier|studio\/.test(t)) return 1;\n        var m = t.match(\/(\\d+)\\s*camer\/);\n        return m ? parseInt(m[1], 10) : 0;\n    }\n\n    function buildOptions(select, items) {\n        var placeholder = select.querySelector('option[value=\"\"]');\n        select.innerHTML = '';\n        select.appendChild(placeholder || new Option('Selecteaz\u0103 apartamentul', ''));\n\n        GROUPS.forEach(function (g) {\n            var inGroup = items.filter(function (it) { return it.rooms === g.rooms; });\n            if (!inGroup.length) return;\n            var og = document.createElement('optgroup');\n            og.label = g.label;\n            inGroup.forEach(function (it) {\n                var opt = new Option(it.name, it.name); \/\/ value = numele complet \u2192 pleac\u0103 a\u0219a \u00een lead\n                opt.setAttribute('data-slug', it.slug);\n                og.appendChild(opt);\n            });\n            select.appendChild(og);\n        });\n    }\n\n    \/\/ Pe pagina unui apartament \u00eenlocuim <select>-ul cu textul apartamentului + un hidden\n    \/\/ input care duce mai departe aceea\u0219i valoare, sub acela\u0219i name (apartment_type).\n    function lockTo(select, name) {\n        var label = document.querySelector('label[for=\"' + select.id + '\"]');\n\n        var box = document.createElement('div');\n        box.className = 'bp-form-static';\n        box.id = 'bp-apt-type-static';\n        box.textContent = name;\n\n        var hidden = document.createElement('input');\n        hidden.type = 'hidden';\n        hidden.name = select.name || 'apartment_type';\n        hidden.value = name;\n\n        var parent = select.parentNode;\n        parent.replaceChild(box, select);\n        parent.appendChild(hidden);\n\n        \/\/ eticheta nu mai are un control de asociat \u2192 scoatem for, ca s\u0103 r\u0103m\u00e2n\u0103 HTML valid\n        if (label) label.removeAttribute('for');\n    }\n\n    function preselect(select, slug) {\n        if (!slug) return;\n        var opt = select.querySelector('option[data-slug=\"' + slug.replace(\/\"\/g, '\\\\\"') + '\"]');\n        if (!opt) return;              \/\/ slug necunoscut \u2192 l\u0103s\u0103m select-ul, e mai util dec\u00e2t un text gre\u0219it\n        lockTo(select, opt.value);\n    }\n\n    function init(select) {\n        fetch(API, { credentials: 'same-origin' })\n            .then(function (r) {\n                if (!r.ok) throw new Error('REST ' + r.status);\n                return r.json();\n            })\n            .then(function (data) {\n                if (!Array.isArray(data) || !data.length) throw new Error('list\u0103 goal\u0103');\n                var items = data.map(function (p) {\n                    var name = decodeEntities(p.title && p.title.rendered);\n                    return { slug: p.slug, name: name, rooms: roomsOf(name) };\n                }).filter(function (it) { return it.name; });\n                if (!items.length) throw new Error('f\u0103r\u0103 titluri');\n\n                var allowed = listedSlugs();\n                if (allowed) {\n                    var listed = items.filter(function (it) { return allowed[it.slug]; });\n                    \/\/ Dac\u0103 niciun slug nu se potrive\u0219te (ex. link-urile cardurilor s-au schimbat),\n                    \/\/ p\u0103str\u0103m lista \u00eentreag\u0103 \u2014 un select gol ar bloca formularul.\n                    if (listed.length) items = listed;\n                    else console.warn('[bp-form] niciun apartament din REST nu corespunde cardurilor din pagin\u0103');\n                }\n\n                items.sort(function (a, b) { return a.name.localeCompare(b.name, 'ro'); });\n                buildOptions(select, items);\n                preselect(select, currentSlug());\n            })\n            .catch(function (err) {\n                \/\/ Fallback: r\u0103m\u00e2n cele 3 op\u021biuni generice din markup, formularul e func\u021bional.\n                console.warn('[bp-form] nu am putut \u00eenc\u0103rca lista de apartamente:', err.message);\n            });\n    }\n\n    \/\/ Formularul e randat de Elementor, uneori pu\u021bin dup\u0103 DOMContentLoaded \u2192 mai \u00eencerc\u0103m.\n    \/\/ A\u0219tept\u0103m \u0219i ie\u0219irea din 'loading': filtrul de carduri al campaniei ruleaz\u0103 pe\n    \/\/ DOMContentLoaded, iar listedSlugs() trebuie s\u0103 vad\u0103 cardurile deja filtrate.\n    var tries = 0;\n    var timer = setInterval(function () {\n        var select = document.getElementById('bp-apt-type');\n        if (select && document.readyState !== 'loading') { clearInterval(timer); init(select); return; }\n        if (++tries > 20) clearInterval(timer);\n    }, 300);\n})();\n<\/script>\n\n<script>\n(function () {\n    var FALLBACK = {\n        ajaxUrl: 'https:\/\/boreal-plus.ro\/wp-admin\/admin-ajax.php',\n        action: 'boreal_plus_lead_submit',\n        thankYouUrl: 'https:\/\/boreal-plus.ro\/thank-you-2026\/',\n        nonce: ''\n    };\n\n    var form = document.getElementById('bp-lead-form');\n    if (!form) {\n        return;\n    }\n\n    var submitBtn = form.querySelector('.bp-form-submit');\n    var errorAlert = document.getElementById('bp-form-error');\n\n    function getConfig() {\n        return window.borealPlusLeadForm || FALLBACK;\n    }\n\n    function hideError() {\n        if (errorAlert) {\n            errorAlert.classList.remove('is-visible');\n            errorAlert.textContent = '';\n        }\n    }\n\n    function showError(message) {\n        if (!errorAlert) {\n            return;\n        }\n        errorAlert.textContent = message;\n        errorAlert.classList.add('is-visible');\n    }\n\n    function getUtmSource() {\n        return new URLSearchParams(window.location.search).get('utm_source') || 'SiteBoreal';\n    }\n\n    \/\/ ---------- validare pe c\u00e2mp ----------\n    \/\/ Fiecare regul\u0103 prime\u0219te valoarea (trim-uit\u0103) \u0219i \u00eentoarce '' dac\u0103 e valid\u0103 sau mesajul\n    \/\/ de eroare. Cheia = atributul name al c\u00e2mpului; mesajul se afi\u0219eaz\u0103 \u00een\n    \/\/ <span id=\"<id c\u00e2mp>-error\"> de sub c\u00e2mp (conven\u021bia din markup).\n\n    \/\/ Litere latine (inclusiv \u0103 \u00e2 \u00ee \u0219 \u021b, cu virgul\u0103 sau sedil\u0103), spa\u021bii, cratim\u0103, apostrof, punct.\n    \/\/ Intervale explicite, nu \\p{L}: un browser f\u0103r\u0103 suport pentru \\p{} ar arunca eroare de\n    \/\/ sintax\u0103 la parsarea scriptului \u0219i formularul n-ar mai trimite deloc.\n    var NAME_RE = \/^[A-Za-z\u00c0-\u024f\u1e00-\u1eff][A-Za-z\u00c0-\u024f\u1e00-\u1eff\\s'\u2019.\\-]*$\/;\n    var EMAIL_RE = \/^[A-Za-z0-9._%+\\-]+@[A-Za-z0-9\\-]+(\\.[A-Za-z0-9\\-]+)*\\.[A-Za-z]{2,}$\/;\n\n    \/\/ \"+40 (735) 509-700\", \"0040735509700\", \"0735.509.700\" \u2192 \"+40735509700\" \/ \"0735509700\".\n    \/\/ \u00centoarce '' dac\u0103 r\u0103m\u00e2n caractere care nu au ce c\u0103uta \u00eentr-un num\u0103r.\n    function normalizePhone(raw) {\n        var v = raw.replace(\/[\\s().\\-]\/g, '');\n        if (!\/^\\+?\\d+$\/.test(v)) return '';\n        if (v.indexOf('00') === 0) v = '+' + v.slice(2);\n        return v;\n    }\n\n    var RULES = {\n        name: function (v) {\n            if (!v) return 'Te rug\u0103m s\u0103 scrii numele complet.';\n            if (v.length < 3) return 'Numele trebuie s\u0103 aib\u0103 cel pu\u021bin 3 litere.';\n            if (v.length > 80) return 'Numele e prea lung (maxim 80 de caractere).';\n            if (!NAME_RE.test(v)) return 'Numele poate con\u021bine doar litere, spa\u021bii, cratim\u0103 \u0219i apostrof.';\n            return '';\n        },\n        phone: function (v) {\n            if (!v) return 'Te rug\u0103m s\u0103 scrii un num\u0103r de telefon.';\n            var p = normalizePhone(v);\n            if (!p) return 'Telefonul poate con\u021bine doar cifre, spa\u021bii, +, paranteze, punct sau cratim\u0103.';\n            \/\/ Na\u021bional rom\u00e2nesc: 0 + 9 cifre, a doua cifr\u0103 2\/3 (fix) sau 7 (mobil).\n            if (p.charAt(0) === '0') {\n                return \/^0[237]\\d{8}$\/.test(p) ? '' : 'Num\u0103rul din Rom\u00e2nia are 10 cifre \u0219i \u00eencepe cu 07, 02 sau 03.';\n            }\n            \/\/ Interna\u021bional: +40 urmat de 9 cifre, sau alt prefix + 8\u201315 cifre (E.164).\n            if (p.indexOf('+40') === 0) {\n                return \/^\\+40[237]\\d{8}$\/.test(p) ? '' : 'Dup\u0103 +40 urmeaz\u0103 9 cifre, ex. +40 7XX XXX XXX.';\n            }\n            if (p.charAt(0) === '+') {\n                return \/^\\+\\d{8,15}$\/.test(p) ? '' : 'Num\u0103rul interna\u021bional trebuie s\u0103 aib\u0103 \u00eentre 8 \u0219i 15 cifre dup\u0103 +.';\n            }\n            return 'Scrie num\u0103rul cu 0 \u00een fa\u021b\u0103 (07XX XXX XXX) sau cu prefixul \u021b\u0103rii (+40 7XX XXX XXX).';\n        },\n        email: function (v) {\n            if (!v) return 'Te rug\u0103m s\u0103 scrii adresa de email.';\n            if (v.length > 120) return 'Adresa de email e prea lung\u0103 (maxim 120 de caractere).';\n            if (!EMAIL_RE.test(v)) return 'Introdu o adres\u0103 de email valid\u0103, ex. nume@exemplu.ro.';\n            return '';\n        },\n        \/\/ Op\u021bional. C\u00e2nd e <select>, valoarea trebuie s\u0103 fie una din op\u021biuni (o valoare\n        \/\/ str\u0103in\u0103 ar \u00eensemna markup manipulat). C\u00e2nd lockTo() l-a \u00eenlocuit cu un hidden, e\n        \/\/ deja valoarea exact\u0103 a apartamentului.\n        apartment_type: function (v, el) {\n            if (!v || !el || el.tagName !== 'SELECT') return '';\n            for (var i = 0; i < el.options.length; i++) {\n                if (el.options[i].value === v) return '';\n            }\n            return 'Alege un apartament din list\u0103.';\n        },\n        message: function (v) {\n            if (v.length > 1000) return 'Mesajul e prea lung (maxim 1000 de caractere).';\n            return '';\n        },\n        gdpr: function (v) {\n            return v === '1' ? '' : 'Pentru a trimite cererea trebuie s\u0103 accep\u021bi Politica de protec\u021bie a datelor.';\n        }\n    };\n\n    function fieldByName(name) {\n        return form.querySelector('[name=\"' + name + '\"]');\n    }\n\n    \/\/ Valoarea \u201elogic\u0103\" a c\u00e2mpului: pentru checkbox '1'\/'' (ca \u00een FormData), altfel textul trim-uit.\n    function valueOf(el) {\n        if (!el) return '';\n        if (el.type === 'checkbox') return el.checked ? '1' : '';\n        return (el.value || '').trim();\n    }\n\n    function setFieldError(el, msg) {\n        if (!el) return;\n        var group = el.closest('.bp-form-group, .bp-form-checks');\n        var box = el.id ? document.getElementById(el.id + '-error') : null;\n        if (msg) {\n            el.classList.add('is-invalid');\n            el.setAttribute('aria-invalid', 'true');\n            if (group) group.classList.add('is-invalid');\n            if (box) { box.textContent = msg; box.classList.add('is-visible'); }\n        } else {\n            el.classList.remove('is-invalid');\n            el.removeAttribute('aria-invalid');\n            if (group) group.classList.remove('is-invalid');\n            if (box) { box.textContent = ''; box.classList.remove('is-visible'); }\n        }\n    }\n\n    \/\/ Valideaz\u0103 un c\u00e2mp \u0219i \u00eei afi\u0219eaz\u0103\/\u0219terge eroarea. \u00centoarce true dac\u0103 e valid.\n    function validateField(name) {\n        var rule = RULES[name];\n        var el = fieldByName(name);\n        if (!rule || !el) return true;\n        var msg = rule(valueOf(el), el);\n        setFieldError(el, msg);\n        return !msg;\n    }\n\n    \/\/ Valideaz\u0103 tot formularul; \u00eentoarce primul c\u00e2mp invalid (pentru focus) sau null.\n    function validateForm() {\n        var firstInvalid = null;\n        Object.keys(RULES).forEach(function (name) {\n            if (!validateField(name) && !firstInvalid) firstInvalid = fieldByName(name);\n        });\n        return firstInvalid;\n    }\n\n    \/\/ Eroarea apare la blur (nu \u00een timp ce omul \u00eenc\u0103 scrie) \u0219i dispare imediat ce c\u00e2mpul\n    \/\/ devine valid; la bife reac\u021bion\u0103m la change.\n    Object.keys(RULES).forEach(function (name) {\n        var el = fieldByName(name);\n        if (!el) return;\n        if (el.type === 'checkbox') {\n            el.addEventListener('change', function () { validateField(name); });\n            return;\n        }\n        el.addEventListener('blur', function () {\n            if (valueOf(el)) validateField(name);\n        });\n        el.addEventListener('input', function () {\n            if (el.classList.contains('is-invalid')) validateField(name);\n        });\n        el.addEventListener('change', function () {\n            if (el.classList.contains('is-invalid')) validateField(name);\n        });\n    });\n\n    form.addEventListener('submit', function (event) {\n        event.preventDefault();\n        hideError();\n\n        var config = getConfig();\n        var formData = new FormData(form);\n\n        var firstInvalid = validateForm();\n        if (firstInvalid) {\n            showError('Verific\u0103 c\u00e2mpurile marcate cu ro\u0219u.');\n            if (typeof firstInvalid.focus === 'function') firstInvalid.focus();\n            return;\n        }\n\n        if (submitBtn) {\n            submitBtn.disabled = true;\n            submitBtn.textContent = 'Se trimite...';\n        }\n\n        var payload = new FormData();\n        payload.append('action', config.action || FALLBACK.action);\n        if (config.nonce) {\n            payload.append('nonce', config.nonce);\n        }\n        payload.append('name', (formData.get('name') || '').trim());\n        payload.append('email', (formData.get('email') || '').trim());\n        \/\/ Telefonul pleac\u0103 normalizat (+40735509700 \/ 0735509700), nu cum l-a tastat omul.\n        payload.append('phone', normalizePhone((formData.get('phone') || '').trim()));\n        payload.append('apartment_type', (formData.get('apartment_type') || '').trim());\n        payload.append('message', (formData.get('message') || '').trim());\n        payload.append('gdpr', formData.get('gdpr') === '1' ? '1' : '');\n        payload.append('utm_source', getUtmSource());\n        payload.append('page_url', window.location.href);\n        payload.append('bp_website', (formData.get('bp_website') || '').trim());\n\n        fetch(config.ajaxUrl || FALLBACK.ajaxUrl, {\n            method: 'POST',\n            credentials: 'same-origin',\n            body: payload\n        })\n            .then(function (response) {\n                return response.json().then(function (data) {\n                    return { ok: response.ok, data: data };\n                });\n            })\n            .then(function (result) {\n                if (!result.ok || !result.data || !result.data.success) {\n                    var message = (result.data && result.data.data && result.data.data.message)\n                        ? result.data.data.message\n                        : 'Nu am putut trimite cererea. Te rug\u0103m s\u0103 \u00eencerci din nou.';\n                    throw new Error(message);\n                }\n\n                var redirectUrl = (result.data.data && result.data.data.redirect)\n                    ? result.data.data.redirect\n                    : (config.thankYouUrl || FALLBACK.thankYouUrl);\n\n                window.location.href = redirectUrl;\n            })\n            .catch(function (error) {\n                showError(error && error.message ? error.message : 'Nu am putut trimite cererea. Te rug\u0103m s\u0103 \u00eencerci din nou.');\n                if (submitBtn) {\n                    submitBtn.disabled = false;\n                    submitBtn.textContent = 'Programeaz\u0103 o vizionare';\n                }\n            });\n    });\n})();\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\n\n            <\/div>\n        <\/div>\n    <\/div>\n<\/section>\n\n\n\n<script>\ndocument.addEventListener(\"DOMContentLoaded\", function() {\n\n    const POSTS_PER_PAGE = 18;\n    let allPosts = [];        \/\/ all fetched & processed posts\n    let filteredPosts = [];   \/\/ posts after category filter\n    let currentPage = 1;\n    let currentFilter = 'toate';\n    const categoriesMap = {};\n    let filtersBuilt = false;  \/\/ so the heavy posts fetch doesn't rebuild filters already shown\n\n    \/\/ Normalize WP \"uncategorized\" \u2192 \"Generale\"\n    function normalizeCategory(slug, name) {\n        slug = slug || '';\n        name = name || '';\n        if (slug === 'uncategorized' || slug === 'fara-categorie' ||\n            name.toLowerCase() === 'uncategorized' || name.toLowerCase() === 'f\u0103r\u0103 categorie') {\n            return { slug: 'generale', name: 'Generale' };\n        }\n        return { slug, name };\n    }\n\n    \/\/ --- Render cards for current page ---\n    function renderPage() {\n        const grid = document.getElementById('blog-listing-grid');\n        const start = (currentPage - 1) * POSTS_PER_PAGE;\n        const end = start + POSTS_PER_PAGE;\n        const pagePosts = filteredPosts.slice(start, end);\n\n        let html = '';\n        pagePosts.forEach((post, index) => {\n            html += `\n            <article class=\"blog-card-modern\" data-category=\"${post.categorySlug}\" onclick=\"window.location.href='${post.link}'\" style=\"cursor:pointer;\">\n                <div class=\"blog-card-media\">\n                    <img decoding=\"async\" src=\"${post.imgUrl}\" alt=\"${post.title}\" loading=\"lazy\">\n                <\/div>\n                <div class=\"blog-card-body\">\n                    <div class=\"blog-card-meta\">\n                        <span class=\"blog-card-category\">${post.categoryName}<\/span>\n                        <span class=\"blog-card-date\">${post.formattedDate}<\/span>\n                    <\/div>\n                    <h3>${post.title}<\/h3>\n                    <p>${post.excerpt}<\/p>\n                    <a href=\"${post.link}\" class=\"blog-card-link\">Cite\u0219te mai mult <span>&rarr;<\/span><\/a>\n                <\/div>\n            <\/article>\n            `;\n        });\n\n        grid.innerHTML = html;\n\n        \/\/ Animate cards\n        const cards = grid.querySelectorAll('.blog-card-modern');\n        cards.forEach((card, i) => {\n            card.style.animation = 'none';\n            card.offsetHeight;\n            card.style.animation = `luxFadeIn 0.4s ease both`;\n            card.style.animationDelay = `${i * 0.04}s`;\n        });\n\n        renderPagination();\n    }\n\n    \/\/ --- Render pagination buttons ---\n    function renderPagination() {\n        const container = document.getElementById('blog-pagination');\n        if (!container) return;\n\n        const totalPages = Math.ceil(filteredPosts.length \/ POSTS_PER_PAGE);\n        if (totalPages <= 1) {\n            container.innerHTML = '';\n            return;\n        }\n\n        let html = '';\n\n        \/\/ Prev button\n        html += `<button class=\"blog-page-btn blog-page-prev ${currentPage === 1 ? 'disabled' : ''}\" data-page=\"prev\">&larr; Anterior<\/button>`;\n\n        \/\/ Page numbers\n        for (let i = 1; i <= totalPages; i++) {\n            if (totalPages > 7) {\n                \/\/ Show: 1, ..., current-1, current, current+1, ..., last\n                if (i === 1 || i === totalPages || (i >= currentPage - 1 && i <= currentPage + 1)) {\n                    html += `<button class=\"blog-page-btn ${i === currentPage ? 'active' : ''}\" data-page=\"${i}\">${i}<\/button>`;\n                } else if (i === currentPage - 2 || i === currentPage + 2) {\n                    html += `<span class=\"blog-page-dots\">&hellip;<\/span>`;\n                }\n            } else {\n                html += `<button class=\"blog-page-btn ${i === currentPage ? 'active' : ''}\" data-page=\"${i}\">${i}<\/button>`;\n            }\n        }\n\n        \/\/ Next button\n        html += `<button class=\"blog-page-btn blog-page-next ${currentPage === totalPages ? 'disabled' : ''}\" data-page=\"next\">Urm\u0103tor &rarr;<\/button>`;\n\n        container.innerHTML = html;\n\n        \/\/ Bind pagination clicks\n        container.querySelectorAll('.blog-page-btn').forEach(btn => {\n            btn.addEventListener('click', function() {\n                if (this.classList.contains('disabled')) return;\n                const page = this.dataset.page;\n                if (page === 'prev') {\n                    currentPage = Math.max(1, currentPage - 1);\n                } else if (page === 'next') {\n                    currentPage = Math.min(totalPages, currentPage + 1);\n                } else {\n                    currentPage = parseInt(page);\n                }\n                renderPage();\n                \/\/ Scroll to top of blog grid\n                const gridSection = document.querySelector('.blog-list-section');\n                if (gridSection) {\n                    gridSection.scrollIntoView({ behavior: 'smooth', block: 'start' });\n                }\n            });\n        });\n    }\n\n    \/\/ --- Filter Logic ---\n    function applyFilter(category) {\n        currentFilter = category;\n        currentPage = 1;\n        if (category === 'toate') {\n            filteredPosts = [...allPosts];\n        } else {\n            filteredPosts = allPosts.filter(p => p.categorySlug === category);\n        }\n        renderPage();\n    }\n\n    \/\/ --- Bind filter buttons ---\n    function bindFilterButtons() {\n        const filterBtns = document.querySelectorAll('.blog-filter-btn');\n        filterBtns.forEach(btn => {\n            btn.addEventListener('click', function() {\n                filterBtns.forEach(b => b.classList.remove('active'));\n                this.classList.add('active');\n                applyFilter(this.dataset.filter);\n            });\n        });\n    }\n\n    \/\/ --- Build Dynamic Filter Buttons ---\n    function buildFilterButtons(categories) {\n        const filtersRow = document.getElementById('blog-filters-row');\n        if (!filtersRow) return;\n\n        filtersRow.innerHTML = '<button class=\"blog-filter-btn active\" data-filter=\"toate\">Toate articolele<\/button>';\n\n        const sorted = Object.entries(categories).sort((a, b) => a[1].localeCompare(b[1]));\n        sorted.forEach(([slug, name]) => {\n            const btn = document.createElement('button');\n            btn.className = 'blog-filter-btn';\n            btn.dataset.filter = slug;\n            btn.textContent = name;\n            filtersRow.appendChild(btn);\n        });\n\n        bindFilterButtons();\n        filtersBuilt = true;\n    }\n\n    \/\/ --- Fetch category list (lightweight) so filters show FAST, ---\n    \/\/ --- independent of the heavy posts fetch. ---\n    async function fetchCategories() {\n        try {\n            const res = await fetch('\/wp-json\/wp\/v2\/categories?per_page=100&hide_empty=true&orderby=name&order=asc');\n            if (!res.ok) return;\n            const cats = await res.json();\n            if (!Array.isArray(cats) || cats.length === 0) return;\n            cats.forEach(c => {\n                const norm = normalizeCategory(c.slug, c.name);\n                if (norm.slug && !categoriesMap[norm.slug]) categoriesMap[norm.slug] = norm.name;\n            });\n            if (Object.keys(categoriesMap).length > 0) {\n                buildFilterButtons(categoriesMap);\n            }\n        } catch (e) {\n            \/\/ keep the static \"Toate articolele\" fallback; posts fetch will still build filters\n            console.log('Blog: categories fetch failed, will build filters from posts instead:', e);\n        }\n    }\n\n    \/\/ --- Turn one WP REST post into our card model ---\n    function processPost(post) {\n        const title = post.title?.rendered || 'Articol Boreal Plus';\n        const link = post.link || '#';\n\n        \/\/ Excerpt\n        let excerpt = post.excerpt?.rendered || post.content?.rendered || '';\n        const tempEl = document.createElement('div');\n        tempEl.innerHTML = excerpt;\n        excerpt = tempEl.textContent || tempEl.innerText || '';\n        if (excerpt.length > 140) {\n            excerpt = excerpt.substring(0, 140).trim() + '...';\n        }\n\n        \/\/ Featured Image\n        let imgUrl = 'https:\/\/boreal-plus.ro\/wp-content\/uploads\/2025\/08\/noul-boreal-plus.jpg';\n        if (post._embedded && post._embedded['wp:featuredmedia'] && post._embedded['wp:featuredmedia'][0]) {\n            imgUrl = post._embedded['wp:featuredmedia'][0].source_url || imgUrl;\n        }\n\n        \/\/ Category\n        let categoryName = 'Generale';\n        let categorySlug = 'generale';\n        if (post._embedded && post._embedded['wp:term'] && post._embedded['wp:term'][0] && post._embedded['wp:term'][0][0]) {\n            const norm = normalizeCategory(post._embedded['wp:term'][0][0].slug, post._embedded['wp:term'][0][0].name);\n            categoryName = norm.name;\n            categorySlug = norm.slug;\n        }\n        if (!categoriesMap[categorySlug]) {\n            categoriesMap[categorySlug] = categoryName;\n        }\n\n        \/\/ Formatted Date\n        let formattedDate = '';\n        if (post.date) {\n            const dateObj = new Date(post.date);\n            const options = { day: 'numeric', month: 'long', year: 'numeric' };\n            formattedDate = dateObj.toLocaleDateString('ro-RO', options);\n        }\n\n        return { title, link, excerpt, imgUrl, categoryName, categorySlug, formattedDate };\n    }\n\n    \/\/ --- Fetch posts progressively ---\n    \/\/ We request only POSTS_PER_PAGE per call (light, fast) and render the FIRST\n    \/\/ batch as soon as it arrives, instead of waiting for one huge `_embed` request\n    \/\/ of 100 posts (which delayed all cards by several seconds).\n    async function fetchAllPosts() {\n        let page = 1;\n        let totalPages = 1;\n        let firstRendered = false;\n\n        while (page <= totalPages) {\n            let response;\n            try {\n                response = await fetch(`\/wp-json\/wp\/v2\/posts?per_page=${POSTS_PER_PAGE}&page=${page}&_embed`);\n                if (!response.ok) break;\n            } catch (netErr) {\n                console.log('Blog: posts page', page, 'request failed:', netErr);\n                break;\n            }\n\n            const wpTotalPages = response.headers.get('X-WP-TotalPages');\n            if (wpTotalPages) totalPages = parseInt(wpTotalPages);\n\n            let posts;\n            try {\n                posts = await response.json();\n            } catch (parseErr) {\n                break;\n            }\n            if (!Array.isArray(posts) || posts.length === 0) break;\n\n            posts.forEach(post => allPosts.push(processPost(post)));\n\n            \/\/ Only refresh the visible list while the user is still on page 1 and\n            \/\/ hasn't picked a category \u2014 so background loading never disrupts them.\n            if (currentFilter === 'toate') {\n                filteredPosts = [...allPosts];\n            }\n\n            if (!firstRendered) {\n                if (!filtersBuilt) buildFilterButtons(categoriesMap);\n                renderPage();        \/\/ show the first batch immediately\n                firstRendered = true;\n            } else if (currentPage === 1 && currentFilter === 'toate') {\n                renderPagination();  \/\/ grow the pager as more pages stream in\n            }\n\n            page++;\n        }\n\n        if (!firstRendered) {\n            \/\/ Nothing loaded from the API \u2192 keep the static fallback cards visible.\n            bindFilterButtons();\n        }\n    }\n\n    \/\/ Start\n    bindFilterButtons();\n    fetchCategories();  \/\/ fast: filters appear immediately\n    fetchAllPosts();    \/\/ heavier: fills in the article cards\n});\n<\/script>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Articole &#038; Nout\u0103\u021bi Blog &#038; Stil de Via\u021b\u0103 Blog &amp; Nout\u0103\u021bi Toate articolele Comunitate 15 Mai 2026 Evolu\u021bia lucr\u0103rilor \u00een complexul reziden\u021bial Boreal Plus Afl\u0103 stadiul actual al construc\u021biei, finisajele interioare realizate \u0219i ce urmeaz\u0103 \u00een urm\u0103toarele luni pentru noul t\u0103u acas\u0103 premium \u00een Constan\u021ba. Cite\u0219te mai mult &rarr; Design Interior 10 Mai 2026 Sfaturi [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"footnotes":""},"class_list":["post-16607","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Blog - Boreal Plus<\/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:\/\/boreal-plus.ro\/en\/blog\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Blog - Boreal Plus\" \/>\n<meta property=\"og:description\" content=\"Articole &#038; Nout\u0103\u021bi Blog &#038; Stil de Via\u021b\u0103 Blog &amp; Nout\u0103\u021bi Toate articolele Comunitate 15 Mai 2026 Evolu\u021bia lucr\u0103rilor \u00een complexul reziden\u021bial Boreal Plus Afl\u0103 stadiul actual al construc\u021biei, finisajele interioare realizate \u0219i ce urmeaz\u0103 \u00een urm\u0103toarele luni pentru noul t\u0103u acas\u0103 premium \u00een Constan\u021ba. Cite\u0219te mai mult &rarr; Design Interior 10 Mai 2026 Sfaturi [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/boreal-plus.ro\/en\/blog\/\" \/>\n<meta property=\"og:site_name\" content=\"Boreal Plus\" \/>\n<meta property=\"article:modified_time\" content=\"2026-09-10T12:18:20+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/boreal-plus.ro\/wp-content\/uploads\/2024\/08\/apartamente-finalizate.png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/boreal-plus.ro\\\/blog\\\/\",\"url\":\"https:\\\/\\\/boreal-plus.ro\\\/blog\\\/\",\"name\":\"Blog - Boreal Plus\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/boreal-plus.ro\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/boreal-plus.ro\\\/blog\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/boreal-plus.ro\\\/blog\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/boreal-plus.ro\\\/wp-content\\\/uploads\\\/2024\\\/08\\\/apartamente-finalizate.png\",\"datePublished\":\"2026-05-19T07:57:48+00:00\",\"dateModified\":\"2026-09-10T12:18:20+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/boreal-plus.ro\\\/blog\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/boreal-plus.ro\\\/blog\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/boreal-plus.ro\\\/blog\\\/#primaryimage\",\"url\":\"https:\\\/\\\/boreal-plus.ro\\\/wp-content\\\/uploads\\\/2024\\\/08\\\/apartamente-finalizate.png\",\"contentUrl\":\"https:\\\/\\\/boreal-plus.ro\\\/wp-content\\\/uploads\\\/2024\\\/08\\\/apartamente-finalizate.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/boreal-plus.ro\\\/blog\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/boreal-plus.ro\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Blog\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/boreal-plus.ro\\\/#website\",\"url\":\"https:\\\/\\\/boreal-plus.ro\\\/\",\"name\":\"Boreal Plus\",\"description\":\"Apartamente \u0219i case de v\u00e2nzare BOREAL Constan\u021ba\",\"publisher\":{\"@id\":\"https:\\\/\\\/boreal-plus.ro\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/boreal-plus.ro\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/boreal-plus.ro\\\/#organization\",\"name\":\"Boreal Plus\",\"url\":\"https:\\\/\\\/boreal-plus.ro\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/boreal-plus.ro\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"\",\"contentUrl\":\"\",\"caption\":\"Boreal Plus\"},\"image\":{\"@id\":\"https:\\\/\\\/boreal-plus.ro\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Blog - Boreal Plus","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:\/\/boreal-plus.ro\/en\/blog\/","og_locale":"en_US","og_type":"article","og_title":"Blog - Boreal Plus","og_description":"Articole &#038; Nout\u0103\u021bi Blog &#038; Stil de Via\u021b\u0103 Blog &amp; Nout\u0103\u021bi Toate articolele Comunitate 15 Mai 2026 Evolu\u021bia lucr\u0103rilor \u00een complexul reziden\u021bial Boreal Plus Afl\u0103 stadiul actual al construc\u021biei, finisajele interioare realizate \u0219i ce urmeaz\u0103 \u00een urm\u0103toarele luni pentru noul t\u0103u acas\u0103 premium \u00een Constan\u021ba. Cite\u0219te mai mult &rarr; Design Interior 10 Mai 2026 Sfaturi [&hellip;]","og_url":"https:\/\/boreal-plus.ro\/en\/blog\/","og_site_name":"Boreal Plus","article_modified_time":"2026-09-10T12:18:20+00:00","og_image":[{"url":"https:\/\/boreal-plus.ro\/wp-content\/uploads\/2024\/08\/apartamente-finalizate.png","type":"","width":"","height":""}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/boreal-plus.ro\/blog\/","url":"https:\/\/boreal-plus.ro\/blog\/","name":"Blog - Boreal Plus","isPartOf":{"@id":"https:\/\/boreal-plus.ro\/#website"},"primaryImageOfPage":{"@id":"https:\/\/boreal-plus.ro\/blog\/#primaryimage"},"image":{"@id":"https:\/\/boreal-plus.ro\/blog\/#primaryimage"},"thumbnailUrl":"https:\/\/boreal-plus.ro\/wp-content\/uploads\/2024\/08\/apartamente-finalizate.png","datePublished":"2026-05-19T07:57:48+00:00","dateModified":"2026-09-10T12:18:20+00:00","breadcrumb":{"@id":"https:\/\/boreal-plus.ro\/blog\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/boreal-plus.ro\/blog\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/boreal-plus.ro\/blog\/#primaryimage","url":"https:\/\/boreal-plus.ro\/wp-content\/uploads\/2024\/08\/apartamente-finalizate.png","contentUrl":"https:\/\/boreal-plus.ro\/wp-content\/uploads\/2024\/08\/apartamente-finalizate.png"},{"@type":"BreadcrumbList","@id":"https:\/\/boreal-plus.ro\/blog\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/boreal-plus.ro\/"},{"@type":"ListItem","position":2,"name":"Blog"}]},{"@type":"WebSite","@id":"https:\/\/boreal-plus.ro\/#website","url":"https:\/\/boreal-plus.ro\/","name":"Boreal Plus","description":"Apartments and houses for sale BOREAL Constan\u021ba","publisher":{"@id":"https:\/\/boreal-plus.ro\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/boreal-plus.ro\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/boreal-plus.ro\/#organization","name":"Boreal Plus","url":"https:\/\/boreal-plus.ro\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/boreal-plus.ro\/#\/schema\/logo\/image\/","url":"","contentUrl":"","caption":"Boreal Plus"},"image":{"@id":"https:\/\/boreal-plus.ro\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/boreal-plus.ro\/en\/wp-json\/wp\/v2\/pages\/16607","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/boreal-plus.ro\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/boreal-plus.ro\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/boreal-plus.ro\/en\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/boreal-plus.ro\/en\/wp-json\/wp\/v2\/comments?post=16607"}],"version-history":[{"count":53,"href":"https:\/\/boreal-plus.ro\/en\/wp-json\/wp\/v2\/pages\/16607\/revisions"}],"predecessor-version":[{"id":18053,"href":"https:\/\/boreal-plus.ro\/en\/wp-json\/wp\/v2\/pages\/16607\/revisions\/18053"}],"wp:attachment":[{"href":"https:\/\/boreal-plus.ro\/en\/wp-json\/wp\/v2\/media?parent=16607"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}