#iph2, #iph2 *, #iph2 *::before, #iph2 *::after { box-sizing: border-box; } #iph2 .iph-track *, #iph2 .iph-track *::before, #iph2 .iph-track *::after, #iph2 .iph-dots, #iph2 .iph-arrow, #iph2 .iph-dot { margin: 0; padding: 0; } #iph2 a { text-decoration: none; } #iph2 button { cursor: pointer; font-family: inherit; border: none; background: none; } #iph2 { --blue: #0052CC; --blue-hover: #003D99; --white: #ffffff; --dark: #0d1b2a; --gray: #4a5568; --muted: #64748b; --radius: 6px; /* Layout: height follows the screen width, but never taller than the visible window (minus the site header), from 460px up to 1200px on TVs */ --slide-h: clamp(460px, min(40vw, calc(100vh - 170px)), 1200px); --left-w: clamp(340px, 32%, 1300px); --pad-y: clamp(2rem, 3.6vw, 6.5rem); --pad-x: clamp(1.6rem, 3.2vw, 5.5rem); --ctrl: clamp(40px, 2.5vw, 76px); --dot: clamp(7px, .42vw, 14px); font-family: 'Poppins', system-ui, -apple-system, 'Segoe UI', sans-serif; -webkit-font-smoothing: antialiased; position: relative; width: 100%; overflow: hidden; border-radius: 2px; box-shadow: 0 4px 40px rgba(0,0,0,.08); -webkit-tap-highlight-color: transparent; outline: none; } @supports (height: 100svh) { #iph2 { --slide-h: clamp(460px, min(40vw, calc(100svh - 170px)), 1200px); } } #iph2:focus-visible { box-shadow: inset 0 0 0 3px rgba(0,82,204,.45); } /* ── Track & slides ─────────────────────────────────────────── */ #iph2 .iph-track { display: flex; height: var(--slide-h); transform: translate3d(0,0,0); will-change: transform; touch-action: pan-y; /* vertical scroll stays native */ } #iph2 .iph-track.animated { transition: transform .7s cubic-bezier(.4,0,.2,1); } #iph2 .iph-slide { flex: 0 0 100%; min-width: 0; height: 100%; display: flex; position: relative; } /* ── Text panel ─────────────────────────────────────────────── */ #iph2 .iph-left { flex: 0 0 var(--left-w); min-width: 0; height: 100%; background: var(--white); display: flex; flex-direction: column; justify-content: center; padding: var(--pad-y) var(--pad-x); position: relative; z-index: 2; box-shadow: 8px 0 40px rgba(0,0,0,.09); overflow: hidden; } /* ── Image panel ────────────────────────────────────────────── */ #iph2 .iph-right { flex: 1 1 auto; min-width: 0; height: 100%; position: relative; z-index: 1; overflow: hidden; background: #d1c9bd; } #iph2 .iph-right::before { content: ''; position: absolute; inset: 0; z-index: 1; background: linear-gradient(to right, rgba(0,0,0,.18) 0%, rgba(0,0,0,.04) 8%, transparent 20%); pointer-events: none; } #iph2 .iph-right img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center; display: block; opacity: 1; transition: opacity .5s ease; -webkit-user-drag: none; user-select: none; } #iph2 .iph-right img[data-src] { opacity: 0; } /* ── Typography (fluid: phone → TV) ─────────────────────────── */ #iph2 .iph-eye { display: inline-flex; align-items: center; gap: .7em; font-size: clamp(.64rem, .62vw, 1.25rem); font-weight: 600; letter-spacing: .18em; text-transform: uppercase; color: var(--muted); margin-bottom: 1.45em; } #iph2 .iph-eye::before { content: ''; flex: 0 0 auto; width: 2.1em; height: 2px; border-radius: 1px; background: var(--blue); } #iph2 .iph-h { font-size: clamp(1.9rem, 3.1vw, 7rem); font-weight: 700; line-height: 1.1; letter-spacing: -.02em; color: var(--dark); margin-bottom: .38em; text-wrap: balance; overflow-wrap: break-word; } #iph2 .iph-h span { color: var(--blue); } #iph2 .iph-body { font-size: clamp(.82rem, .95vw, 1.85rem); font-weight: 300; line-height: 1.7; color: var(--gray); max-width: 34ch; margin-bottom: 2.2em; } /* ── Button ─────────────────────────────────────────────────── */ #iph2 .iph-btn { display: inline-flex; align-items: center; gap: .55em; width: fit-content; max-width: 100%; padding: .9em 1.75em; border-radius: var(--radius); font-size: clamp(.8rem, .85vw, 1.65rem); font-weight: 600; letter-spacing: .02em; line-height: 1.2; background: var(--blue); color: var(--white); border: 2px solid var(--blue); box-shadow: 0 2px 12px rgba(0,82,204,.25); transition: background .2s ease, border-color .2s ease, box-shadow .2s ease; } #iph2 .iph-btn svg { width: 1.1em; height: 1.1em; flex: 0 0 auto; stroke: currentColor; transition: transform .2s; } #iph2 .iph-btn:hover { background: var(--blue-hover); border-color: var(--blue-hover); box-shadow: 0 4px 18px rgba(0,61,153,.35); color: var(--white); } #iph2 .iph-btn:hover svg { transform: translateX(3px); } #iph2 .iph-btn:focus-visible { outline: 3px solid rgba(0,82,204,.45); outline-offset: 3px; } /* ── Text entrance: the current slide animates in; the slide that is leaving keeps its text visible while it slides away ───────── */ #iph2 .iph-eye, #iph2 .iph-h, #iph2 .iph-body, #iph2 .iph-btn-wrap { opacity: 0; transform: translateY(14px); } #iph2 .iph-slide.active .iph-eye { opacity: 1; transform: none; transition: opacity .5s .12s ease, transform .5s .12s ease; } #iph2 .iph-slide.active .iph-h { opacity: 1; transform: none; transition: opacity .55s .22s ease, transform .55s .22s ease; } #iph2 .iph-slide.active .iph-body { opacity: 1; transform: none; transition: opacity .5s .32s ease, transform .5s .32s ease; } #iph2 .iph-slide.active .iph-btn-wrap { opacity: 1; transform: none; transition: opacity .45s .42s ease, transform .45s .42s ease; } #iph2 .iph-slide.leaving .iph-eye, #iph2 .iph-slide.leaving .iph-h, #iph2 .iph-slide.leaving .iph-body, #iph2 .iph-slide.leaving .iph-btn-wrap { opacity: 1; transform: none; transition: none; } #iph2.is-static .iph-eye, #iph2.is-static .iph-h, #iph2.is-static .iph-body, #iph2.is-static .iph-btn-wrap { transition: none !important; } /* ── Arrows ─────────────────────────────────────────────────── */ #iph2 .iph-arrow { position: absolute; top: 50%; z-index: 30; width: var(--ctrl); height: var(--ctrl); border-radius: 50%; display: flex; align-items: center; justify-content: center; background: var(--white); border: 1.5px solid rgba(0,0,0,.08); box-shadow: 0 3px 14px rgba(0,0,0,.10); transform: translateY(-50%); transition: background .2s, transform .2s, box-shadow .2s; outline: none; } #iph2 .iph-arrow:hover { background: #f8fafc; transform: translateY(calc(-50% - 2px)); box-shadow: 0 6px 20px rgba(0,0,0,.15); } #iph2 .iph-arrow:focus-visible { box-shadow: 0 0 0 3px rgba(0,82,204,.45); } #iph2 .iph-arrow svg { width: 40%; height: 40%; stroke: var(--blue); pointer-events: none; } #iph2 .iph-prev { left: calc(var(--left-w) + clamp(.6rem, 1.4vw, 2.5rem)); } #iph2 .iph-next { right: clamp(.6rem, 1.4vw, 2.5rem); } /* ── Dots + pause button (centred under the photo) ──────────── */ #iph2 .iph-dots { position: absolute; z-index: 30; bottom: clamp(.6rem, 1.1vw, 2rem); left: calc(var(--left-w) + (100% - var(--left-w)) / 2); transform: translateX(-50%); display: flex; align-items: center; padding: 0 calc(var(--dot) * .9); border-radius: 999px; background: rgba(13,27,42,.26); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); } #iph2 .iph-dot, #iph2 .iph-play { width: max(28px, calc(var(--dot) * 4)); height: max(40px, calc(var(--dot) * 5.6)); display: flex; align-items: center; justify-content: center; border: none; background: transparent; padding: 0; outline: none; } #iph2 .iph-dot::before { content: ''; display: block; width: var(--dot); height: var(--dot); border-radius: 99px; background: rgba(255,255,255,.62); transition: width .35s ease, background .35s ease; } #iph2 .iph-dot.active::before { width: calc(var(--dot) * 3.2); background: var(--white); } #iph2 .iph-dot:hover::before { background: var(--white); } #iph2 .iph-dot:focus-visible::before, #iph2 .iph-play:focus-visible svg { outline: 2px solid var(--white); outline-offset: 3px; } #iph2 .iph-play svg { width: calc(var(--dot) * 1.8); height: calc(var(--dot) * 1.8); fill: var(--white); } #iph2 .iph-play .i-play { display: none; } #iph2.is-paused .iph-play .i-play { display: block; } #iph2.is-paused .iph-play .i-pause { display: none; } /* ── Progress bar (GPU transform, no layout work) ───────────── */ #iph2 .iph-progress { position: absolute; left: 0; bottom: 0; z-index: 30; width: 100%; height: clamp(3px, .18vw, 6px); background: var(--blue); transform: scaleX(0); transform-origin: 0 50%; } #iph2 .iph-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; } /* ── Tablet & small laptop ≤1024px ──────────────────────────── */ @media (max-width: 1024px) { #iph2 { --slide-h: clamp(400px, 54vw, 540px); --left-w: 42%; --pad-y: clamp(1.4rem, 3.4vw, 2.6rem); --pad-x: clamp(1.1rem, 2.8vw, 2.2rem); } #iph2 .iph-h { font-size: clamp(1.35rem, 2.9vw, 2rem); } #iph2 .iph-body { font-size: clamp(.78rem, 1.15vw, .88rem); max-width: 32ch; margin-bottom: 1.6em; } #iph2 .iph-btn { font-size: .8rem; } } /* ── Phones (portrait) & small tablets: photo on top, text below ── */ @media (max-width: 1024px) and (orientation: portrait), (max-width: 768px) and (min-height: 541px) { #iph2 { --img-h: min(62.5vw, 640px); /* 16:10 photo */ --left-w: 0px; } #iph2 .iph-track { height: auto; } #iph2 .iph-slide { flex-direction: column; height: auto; } #iph2 .iph-right { order: 1; flex: 0 0 auto; width: 100%; height: var(--img-h); } #iph2 .iph-right::before { background: linear-gradient(to bottom, rgba(0,0,0,.12) 0%, transparent 55%, rgba(0,0,0,.18) 100%); } #iph2 .iph-left { order: 2; flex: 1 1 auto; width: 100%; height: auto; justify-content: flex-start; padding: clamp(1.25rem, 5vw, 2rem) clamp(1.1rem, 5.5vw, 2.25rem) clamp(1.6rem, 6vw, 2.4rem); box-shadow: none; } #iph2 .iph-eye { font-size: .64rem; margin-bottom: 1.1em; } #iph2 .iph-h { font-size: clamp(1.4rem, 5.6vw, 2.1rem); } #iph2 .iph-body { font-size: clamp(.8rem, 2.3vw, .9rem); max-width: 42ch; margin-bottom: 1.4em; } #iph2 .iph-btn { font-size: clamp(.78rem, 2.2vw, .86rem); } #iph2 .iph-arrow { display: none; } /* dots sit at the very bottom of the slider, under the button */ #iph2 .iph-left { padding-bottom: calc(clamp(1.6rem, 6vw, 2.4rem) + 40px); } #iph2 .iph-dots { left: 50%; top: auto; bottom: 4px; background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; } #iph2 .iph-dot::before { background: rgba(13,27,42,.2); } #iph2 .iph-dot.active::before { background: var(--blue); } #iph2 .iph-dot:hover::before { background: rgba(13,27,42,.4); } #iph2 .iph-dot.active:hover::before { background: var(--blue); } #iph2 .iph-play svg { fill: var(--muted); } #iph2 .iph-dot:focus-visible::before, #iph2 .iph-play:focus-visible svg { outline-color: var(--blue); } } /* larger portrait screens (big phones turned tablet, iPads): arrows on the photo */ @media (min-width: 600px) and (max-width: 1024px) and (orientation: portrait) { #iph2 .iph-arrow { display: flex; top: calc(var(--img-h) / 2); } #iph2 .iph-prev { left: 1rem; } #iph2 .iph-left { padding: clamp(1.8rem, 4vw, 2.8rem) clamp(1.6rem, 5vw, 3rem) calc(clamp(2.2rem, 5vw, 3.2rem) + 40px); } #iph2 .iph-h { font-size: clamp(1.9rem, 4.6vw, 2.8rem); } #iph2 .iph-body { font-size: clamp(.9rem, 1.9vw, 1.05rem); max-width: 48ch; } #iph2 .iph-eye { font-size: .72rem; } #iph2 .iph-btn { font-size: .9rem; } } @media (max-width: 480px) and (orientation: portrait), (max-width: 480px) and (min-height: 541px) { #iph2 { --img-h: min(75vw, 380px); } /* 4:3 photo */ } @media (max-width: 360px) { #iph2 .iph-eye { letter-spacing: .14em; } #iph2 .iph-btn { padding: .85em 1.35em; } #iph2 .iph-dot, #iph2 .iph-play { width: 26px; } } /* ── Phones held sideways: keep side-by-side, fit the screen ── */ @media (max-width: 1024px) and (max-height: 540px) and (orientation: landscape) { #iph2 { --slide-h: clamp(260px, calc(100vh - 64px), 440px); --left-w: 46%; --pad-y: 1rem; --pad-x: clamp(1rem, 3vw, 1.8rem); } #iph2 .iph-eye { font-size: .6rem; margin-bottom: .8em; } #iph2 .iph-h { font-size: clamp(1.15rem, 3.2vw, 1.6rem); margin-bottom: .3em; } #iph2 .iph-body { font-size: .76rem; line-height: 1.55; margin-bottom: 1em; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; } #iph2 .iph-btn { font-size: .74rem; padding: .7em 1.3em; } #iph2 .iph-arrow { display: none; } } @supports (height: 100svh) { @media (max-width: 1024px) and (max-height: 540px) and (orientation: landscape) { #iph2 { --slide-h: clamp(260px, calc(100svh - 64px), 440px); } } } /* ── Reduced motion ─────────────────────────────────────────── */ @media (prefers-reduced-motion: reduce) { #iph2 .iph-track.animated, #iph2 .iph-arrow, #iph2 .iph-dot::before, #iph2 .iph-right img { transition: none !important; } #iph2 .iph-eye, #iph2 .iph-h, #iph2 .iph-body, #iph2 .iph-btn-wrap { opacity: 1 !important; transform: none !important; transition: none !important; } }

iPanel – The Original

No.1
Ceiling Solution in Sri Lanka

Premium ceiling designs with lasting durability, elegant finishes, and trusted quality.

Modern interior with iPanel PVC ceiling panels

F-10 Wall Panel Collection

Black Marble
Statement Walls

Bold black slat panels with subtle marble veining for dramatic dining, lounge, and hospitality interiors.

Black marble slat wall panels in a modern dining room

Choose Your Finish

Four Signature
Wood Finishes

Jack Wood, Burma Teak, Rich Teak, and Kaluwara — curated tones to match every interior style.

F-10 wall panel colour swatches: Jack Wood, Burma Teak, Rich Teak and Kaluwara

Texture You Can Feel

Rich Teak
Wall Panels

Vertical slat profiling with a warm teak grain that adds depth, warmth, and acoustic comfort to any wall.

Rich Teak F-10 slat wall panel feature wall

Built for Long-Lasting Performance

Up to
15 Years Warranty

Water resistant, fire retardant, warp resistant, and low maintenance.

Burma teak wood pattern PVC ceiling panels
(function () { 'use strict'; var root = document.getElementById('iph2'); if (!root || root.getAttribute('data-ready')) return; root.setAttribute('data-ready', '1'); var track = root.querySelector('.iph-track'); var slides = Array.prototype.slice.call(root.querySelectorAll('.iph-slide')); var dotList = root.querySelector('.iph-dot-list'); var playBtn = root.querySelector('.iph-play'); var progress = root.querySelector('.iph-progress'); var live = root.querySelector('.iph-sr'); var TOTAL = slides.length; var DELAY = 5200; var reduce = window.matchMedia && matchMedia('(prefers-reduced-motion: reduce)').matches; var cur = 0, dots = [], leaveTimer = null; /* Why autoplay may be stopped; it runs only when every flag is clear */ var hold = { offscreen: false, hover: false, focus: false, tabHidden: document.hidden, drag: false, user: reduce }; /* ── Images: only slide 1 loads with the page; the rest load just before they are needed, so they don't compete with the hero ── */ function load(i) { var img = slides[(i + TOTAL) % TOTAL].querySelector('img[data-src]'); if (!img) return; img.addEventListener('load', function () { img.removeAttribute('data-src'); }, { once: true }); img.addEventListener('error', function () { img.removeAttribute('data-src'); }, { once: true }); img.src = img.getAttribute('data-src'); } function loadAround(i) { load(i); load(i + 1); load(i - 1); } function warmUp() { var idle = window.requestIdleCallback || function (fn) { return setTimeout(fn, 600); }; idle(function () { load(1); load(TOTAL - 1); }); } if (document.readyState === 'complete') warmUp(); else window.addEventListener('load', warmUp, { once: true }); /* ── Accessibility state for slides ── */ function setActiveA11y(slide, on) { if (on) slide.removeAttribute('aria-hidden'); else slide.setAttribute('aria-hidden', 'true'); var f = slide.querySelectorAll('a, button'); for (var k = 0; k 8 && Math.abs(mx) > Math.abs(my) * 1.2) { dragging = true; hold.drag = true; sync(); try { root.setPointerCapture(pid); } catch (x) {} } else if (Math.abs(my) > 10) { pid = null; return; } else return; } dx = mx; var edge = (cur === 0 && dx > 0) || (cur === TOTAL - 1 && dx 0.45; if (dx < -w * 0.18 || (fast && dx w * 0.18 || (fast && dx > 30)) goTo(cur - 1, true); else { setTrack(-100 * cur, 0, true); sync(); } } root.addEventListener('pointerup', endDrag); root.addEventListener('pointercancel', endDrag); root.addEventListener('click', function (e) { if (blockClick) { e.preventDefault(); e.stopPropagation(); } }, true); if (reduce) root.classList.add('is-static'); sync(); })();

Best ceiling panel sri lanka

Three Signature Series.
One Premium Standard.

Engineered to perform beautifully for decades in Sri Lanka’s tropical climate. Discover the perfect system for your space.

Almost every operator runs a points programme, usually presented as a tier ladder with escalating perks. What matters is arithmetic rather than badges, specifically how many points a stake earns and what those points are worth in cash.

Reading a Rewards Programme Honestly

Slots usually earn points at full rate while table games earn at a fraction, mirroring the way bonus weighting works. Anyone judging whether a club is worth concentrating play at one operator may Slotlair casino first. Watch for point expiry too, because dormant balances are commonly cleared after a few months of inactivity.

ElementWhat to Check
Conversion ratePoints needed for one unit of credit
Tier speedHow much play each level demands
ExpiryHow long unused points survive
  • Convert points into a cash percentage before judging a scheme
  • Check which games earn at the full rate
  • Note whether points expire during inactive periods

A loyalty scheme is a modest rebate on money already staked, not a source of profit, and it never offsets the house edge. Its correct use is choosing between operators you would have played at anyway. Set your budget independently of any tier target, and never extend a session to chase points.

Podczas gdy bonus powitalny sluzy pozyskaniu gracza, reload ma go zatrzymac. Pojawia sie regularnie, czesto co tydzien, i wlasnie ta powtarzalnosc sprawia, ze warto przyjrzec sie jego warunkom raz, a stosowac wielokrotnie.

Warunki powtarzalnej oferty

Powtarzalny bonus kusi do czestszych wplat, dlatego warto oddzielic go od wlasnego planu gry. Zeby ocenic warunki, mozna bison casino online i przeczytac wymog obrotu oraz limit czasu przed skorzystaniem. Reload objety krotkim terminem czesto wymusza szybsza gre.

PunktDlaczego wazny
CzestotliwoscZacheca do czestszych wplat
Limit czasuWymusza tempo gry
  • Zobacz limit czasu na spelnienie warunkow
  • Nie zwiekszaj czestotliwosci wplat pod oferte

Regularny bonus najlatwiej popycha do czestszych depozytow, niz sam by chcial. Traktuj go jak drobny dodatek do zaplanowanej gry, sprawdzaj warunki za kazdym razem i nie pozwol, by kalendarz ofert dyktowal Twoje wplaty.

Lightweight, stylish, and easy to install, I-PANEL LITE is a popular ceiling solution for modern homes. 

Designed for strength and seamless performance, the i-Panel HEAVY range is ideal for offices and commercial spaces. 

Precision-engineered cornices, beadings, and edge trims for a flawless, gapless transition and perfect architectural detailing.

Marble & wood-look wall panels that create elegant feature walls for TV lounges, bedrooms, boardrooms, and reception areas.

Easy Maintenance

Simple cleaning and minimal upkeep required.

Water Resist

Excellent water resistance properties

Zero Toxicity

All materials are safe for indoor use

Light Weight

Reduces structural load requirements

trees 1
100% recyclable UPVC. Zero timber. Zero formaldehyde. A documented commitment to preserving Sri Lanka’s natural heritage.

Environmental Commitment

i Panel Protecting
Sri Lanka's Forests.

0 Trees saved in 2026
0 Kg of O₂ released
0 Kg of CO₂ absorbed

LIVE Based on i Panel factory output ≈ 84,000 trees · 7,560 t O₂ · 1,848 t CO₂ per year, oxygen for 55,000 people

.ipl-env { color: #fff; position: relative; z-index: 3; /* keeps text above overlapping cards */ padding: 1rem 0 0; min-width: 0; } .ipl-env-eye { color: #2563eb; letter-spacing: .35em; text-transform: uppercase; font-size: .68rem; font-weight: 600; margin: 0 0 1rem; } .ipl-env-h { font-size: clamp(2rem, 3.6vw, 3.2rem); line-height: 1.1; font-weight: 600; margin: 0 0 2.2rem; letter-spacing: -0.01em; } /* ── Stats: compact rows (safe inside narrow columns) ── */ .ipl-env-stats { display: flex; flex-direction: column; border-top: 1px solid rgba(255,255,255,.16); } .ipl-env-stat { display: flex; align-items: baseline; justify-content: space-between; gap: 1.2rem; padding: 1.05rem 0; min-width: 0; border-bottom: 1px solid rgba(255,255,255,.16); } .ipl-env-num { font-size: clamp(1.65rem, 2.4vw, 2.5rem); font-weight: 600; line-height: 1; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; white-space: nowrap; } .ipl-env-lab { font-size: .62rem; letter-spacing: .26em; text-transform: uppercase; color: rgba(255,255,255,.55); text-align: right; } /* ── Note + LIVE badge ── */ .ipl-env-note { display: flex; align-items: flex-start; gap: .7rem; margin: 1.7rem 0 0; font-size: .72rem; line-height: 1.65; color: rgba(255,255,255,.45); max-width: 54ch; } .ipl-env-live { display: inline-flex; align-items: center; gap: .38rem; flex-shrink: 0; font-size: .56rem; font-weight: 700; letter-spacing: .22em; color: #22c55e; border: 1px solid rgba(34,197,94,.35); border-radius: 999px; padding: .3rem .6rem .3rem .5rem; margin-top: .1rem; } .ipl-env-dot { width: 6px; height: 6px; border-radius: 50%; background: #22c55e; animation: iplPulse 2s infinite; } @keyframes iplPulse { 0% { box-shadow: 0 0 0 0 rgba(34,197,94,.5); } 70% { box-shadow: 0 0 0 8px rgba(34,197,94,0); } 100% { box-shadow: 0 0 0 0 rgba(34,197,94,0); } } /* ── Optional: horizontal band when widget sits in a FULL-WIDTH container ── Add class "ipl-env--wide" to the wrapper div to activate. */ .ipl-env--wide .ipl-env-stats { flex-direction: row; border-top: 0; } .ipl-env--wide .ipl-env-stat { flex: 1; flex-direction: column; align-items: flex-start; justify-content: flex-start; gap: .55rem; padding: 1.3rem 2rem .3rem; border-bottom: 0; border-left: 1px solid rgba(255,255,255,.16); } .ipl-env--wide .ipl-env-stat:first-child { border-left: 0; padding-left: 0; } .ipl-env--wide .ipl-env-lab { text-align: left; } .ipl-env--wide .ipl-env-num { font-size: clamp(2rem, 3.2vw, 3rem); } /* ── Responsive ── */ @media (max-width: 1024px) { .ipl-env-stat { flex-direction: column; align-items: flex-start; gap: .4rem; } .ipl-env-lab { text-align: left; } } @media (max-width: 768px) { .ipl-env--wide .ipl-env-stats { flex-direction: column; } .ipl-env--wide .ipl-env-stat { border-left: 0; padding: 1.05rem 0; border-bottom: 1px solid rgba(255,255,255,.16); } .ipl-env-h { margin-bottom: 1.6rem; } } @media (prefers-reduced-motion: reduce) { .ipl-env-dot { animation: none; } } (function () { 'use strict'; /* ── Production calculation (edit here if figures change) ── */ var TREES_PER_YEAR = 84000; // i-Panel factory figure: 84,000 trees saved a year var O2_KG_PER_YEAR = 7560000; // 84,000 × 90 kg = 7,560 tons var CO2_KG_PER_YEAR = 1848000; // 84,000 × 22 kg = 1,848 tons var TZ_OFFSET_MIN = 330; // count the year in Sri Lanka time (UTC+05:30) var DEC = { trees: 2, o2: 1, co2: 1 }; var wrap = document.getElementById('iplEnv'); var elTrees = document.getElementById('iplTrees'); var elO2 = document.getElementById('iplO2'); var elCo2 = document.getElementById('iplCo2'); if (!wrap || !elTrees || !elO2 || !elCo2) return; var reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches; var yr = wrap.querySelector('.ipl-env-yr'); if (yr) yr.textContent = new Date(Date.now() + TZ_OFFSET_MIN * 60000).getUTCFullYear(); /* Same clock as the hero badge, so every visitor sees the same numbers */ function yearFraction(now) { var off = TZ_OFFSET_MIN * 60000; var y = new Date(now.getTime() + off).getUTCFullYear(); var start = Date.UTC(y, 0, 1) - off; var end = Date.UTC(y + 1, 0, 1) - off; return (now - start) / (end - start); } function values(now) { var f = yearFraction(now); return { trees: TREES_PER_YEAR * f, o2: O2_KG_PER_YEAR * f, co2: CO2_KG_PER_YEAR * f }; } function fmt(n, d) { return n.toLocaleString('en-US', { minimumFractionDigits: d, maximumFractionDigits: d }); } function render(v) { elTrees.textContent = fmt(v.trees, DEC.trees); elO2.textContent = fmt(v.o2, DEC.o2); elCo2.textContent = fmt(v.co2, DEC.co2); } function tickLoop() { var last = 0; function frame(ts) { if (ts - last >= 100) { last = ts; render(values(new Date())); } requestAnimationFrame(frame); } requestAnimationFrame(frame); } var started = false; function start() { if (started) return; started = true; if (reduced) { render(values(new Date())); setInterval(function () { render(values(new Date())); }, 1000); return; } var target = values(new Date()); var dur = 1800, t0 = null; function ease(t) { return 1 - Math.pow(1 - t, 3); } function step(ts) { if (t0 === null) t0 = ts; var p = Math.min((ts - t0) / dur, 1), e = ease(p); render({ trees: target.trees * e, o2: target.o2 * e, co2: target.co2 * e }); if (p < 1) requestAnimationFrame(step); else tickLoop(); } requestAnimationFrame(step); } if ('IntersectionObserver' in window) { var io = new IntersectionObserver(function (entries) { entries.forEach(function (en) { if (en.isIntersecting) { start(); io.disconnect(); } }); }, { threshold: 0.3 }); io.observe(wrap); } else { start(); } })();

Featured Finishes

Most Popular Products

Elevate your interiors with our most popular textures. Each panel combines architectural beauty with unmatched durability for a truly refined space.

Our Showrooms

Islandwide Coverage & Trust

i‑panel’s island‑wide network of authorised dealers brings our premium solutions within reach of every Sri Lankan home and project. It is how we deliver quality, trust, and service – wherever you are.

150+

Authorized Dealers

400+

Sivilima Showrooms

500k+

Customers

Banner

Performance Validation

Built for Sri Lanka.
Proven to Last.

While imitation panels warp, crack, and discolor within two years of exposure to humidity and heat, the original i-Panel maintains its form and finish for decades.
Raw Slab

Exposed Concrete

Unfinished structural ceilings leave wiring and uneven concrete surfaces visible to residents.

Elevated Living

Seamless Integration

A flawless matte finish conceals utilities while instantly brightening the residential space.

Apartment with i-Panel PVC Ceiling
Apartment Without Ceiling
:root { --ipanel-blue: #0066ff; --text-shadow: 0 2px 4px rgba(0,0,0,0.9); } .luxury-validation { display: flow-root !important; position: relative !important; width: 100% !important; max-width: 1100px; margin: 30px auto 40px auto !important; padding: 0 !important; font-family: 'Poppins', sans-serif !important; isolation: isolate; clear: both; } .elementor-widget-html:has(.luxury-validation) { display: block !important; width: 100% !important; position: relative !important; clear: both !important; margin-bottom: 0px !important; } .luxury-stage { display: block; position: relative; width: 100%; aspect-ratio: 16 / 9; min-height: 200px; border-radius: 8px; overflow: hidden; background: #000; box-shadow: 0 20px 60px -10px rgba(0,0,0,0.25); isolation: isolate; transform: translateZ(0); /* GPU layer */ } .scrim-overlay, .img-wrap, .luxury-input, .luxury-handle { position: absolute; top: 0; left: 0; right: 0; bottom: 0; } .scrim-overlay { z-index: 4; pointer-events: none; background: linear-gradient(to top, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0.2) 35%, transparent 100%); } .overlay-content { position: absolute; bottom: 36px; width: 300px; transition: opacity 0.4s ease, transform 0.4s ease; pointer-events: none; will-change: opacity, transform; } .left-content { left: 36px; text-align: left; } .right-content { right: 36px; text-align: right; } .luxury-tag { display: block; font-size: 10px; font-weight: 800 !important; text-transform: uppercase; letter-spacing: 3px; color: #fff; margin-bottom: 6px; } .luxury-tag.blue { color: var(--ipanel-blue); } .overlay-content h3 { font-family: 'Poppins', sans-serif !important; font-size: 24px; font-weight: 700 !important; color: #fff; margin: 0; text-shadow: var(--text-shadow); line-height: 1.2; } .overlay-content p { font-family: 'Poppins', sans-serif !important; font-size: 13px; font-weight: 400 !important; color: rgba(255,255,255,0.9); margin: 6px 0 0; line-height: 1.5; text-shadow: var(--text-shadow); } .hidden-state { opacity: 0 !important; pointer-events: none; } .left-content.hidden-state { transform: translateX(-12px); } .right-content.hidden-state { transform: translateX(12px); } .img-wrap { pointer-events: none; z-index: 1; } .img-wrap img { width: 100%; height: 100%; object-fit: cover; display: block; } .img-before { width: 50%; right: auto; z-index: 2; overflow: hidden; border-right: 1.5px solid rgba(255,255,255,0.85); will-change: width; } .luxury-input { width: 100%; height: 100%; appearance: none; -webkit-appearance: none; background: transparent; z-index: 6; cursor: ew-resize; margin: 0; padding: 0; touch-action: pan-y; } .luxury-input:focus { outline: 2px solid var(--ipanel-blue); outline-offset: -2px; } .luxury-input::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 60px; height: 100%; background: transparent; cursor: ew-resize; } .luxury-input::-moz-range-thumb { width: 60px; height: 100%; background: transparent; border: none; cursor: ew-resize; } .luxury-handle { width: 2px; left: 50%; right: auto; z-index: 5; pointer-events: none; display: flex; flex-direction: column; align-items: center; justify-content: center; transform: translateX(-50%); will-change: left; } .handle-core { flex-shrink: 0; width: 44px; height: 44px; background: var(--ipanel-blue); border: 2.5px solid #fff; border-radius: 50%; display: flex; align-items: center; justify-content: center; } .line-top, .line-bottom { flex: 1; width: 1.5px; background: rgba(255,255,255,0.85); } @media (max-width: 1024px) { .luxury-validation { margin: 30px auto 40px auto !important; } .luxury-stage { aspect-ratio: 4 / 3; border-radius: 6px; } .overlay-content { width: 240px; bottom: 24px; } .left-content { left: 20px; } .right-content { right: 20px; } .overlay-content h3 { font-size: 20px; } .overlay-content p { font-size: 12px; } } @media (max-width: 768px) { .luxury-validation { margin: 20px auto 40px auto !important; } .luxury-validation::after { content: ''; display: table; clear: both; } .luxury-stage { aspect-ratio: 3 / 4; border-radius: 4px; min-height: 380px !important; } .scrim-overlay { background: linear-gradient(to bottom, transparent 50%, rgba(0,0,0,0.75) 100%); } .overlay-content { width: calc(50% - 24px); bottom: 24px; top: auto; text-align: center; left: auto; right: auto; } .left-content { left: 8px; right: auto; display: flex; flex-direction: column; align-items: center; } .right-content { right: 8px; left: auto; display: flex; flex-direction: column; align-items: center; } .left-content.hidden-state { transform: translateY(10px) !important; } .right-content.hidden-state { transform: translateY(10px) !important; } .overlay-content h3 { font-size: 18px; } .overlay-content p { font-size: 12px; } .luxury-tag { font-size: 9px; margin-bottom: 4px; } .handle-core { width: 48px; height: 48px; } .luxury-input::-webkit-slider-thumb { width: 80px; } } @media (max-width: 480px) { .luxury-stage { min-height: 320px !important; } .overlay-content h3 { font-size: 16px; } .overlay-content p { font-size: 11px; } } (function () { var slider = document.getElementById('lux-slider-apartments'); var clipBox = document.getElementById('clip-box-apartments'); var handle = document.getElementById('lux-handle-apartments'); var textBefore = document.getElementById('content-before-apartments'); var textAfter = document.getElementById('content-after-apartments'); var ticking = false; function isMobileTablet() { return window.innerWidth <= 1024; } function updateDOM(val) { var pct = val + '%'; clipBox.style.width = pct; handle.style.left = pct; if (isMobileTablet()) { if (val = 65) { textAfter.classList.remove('hidden-state'); textBefore.classList.add('hidden-state'); } else { textBefore.classList.add('hidden-state'); textAfter.classList.add('hidden-state'); } } else { if (val > 80) { textAfter.classList.add('hidden-state'); textBefore.classList.remove('hidden-state'); } else if (val < 20) { textBefore.classList.add('hidden-state'); textAfter.classList.remove('hidden-state'); } else { textBefore.classList.remove('hidden-state'); textAfter.classList.remove('hidden-state'); } } ticking = false; } function requestUpdate(val) { if (!ticking) { window.requestAnimationFrame(function() { updateDOM(val); }); ticking = true; } } slider.addEventListener('input', function (e) { requestUpdate(parseInt(e.target.value, 10)); }); function init() { if (isMobileTablet()) { textBefore.classList.add('hidden-state'); textAfter.classList.add('hidden-state'); } else { textBefore.classList.remove('hidden-state'); textAfter.classList.remove('hidden-state'); } } var resizeTimer; window.addEventListener('resize', function () { clearTimeout(resizeTimer); resizeTimer = setTimeout(function() { requestUpdate(parseInt(slider.value, 10)); }, 100); }); if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();
Structural Frame

Heavy Beams

Deep concrete beams create harsh shadows and visual clutter in primary living areas.

Architectural Warmth

Premium Wood Grain

Rich teak textures and integrated ambient lighting transform the room into a luxury retreat.

Living Room with i-Panel PVC Ceiling
Living Room Without Ceiling
:root { --ipanel-blue: #0066ff; --text-shadow: 0 2px 4px rgba(0,0,0,0.9); } .luxury-validation { display: flow-root !important; position: relative !important; width: 100% !important; max-width: 1100px; margin: 30px auto 40px auto !important; padding: 0 !important; font-family: 'Poppins', sans-serif !important; isolation: isolate; clear: both; } .elementor-widget-html:has(.luxury-validation) { display: block !important; width: 100% !important; position: relative !important; clear: both !important; margin-bottom: 0px !important; } .luxury-stage { display: block; position: relative; width: 100%; aspect-ratio: 16 / 9; min-height: 200px; border-radius: 8px; overflow: hidden; background: #000; box-shadow: 0 20px 60px -10px rgba(0,0,0,0.25); isolation: isolate; transform: translateZ(0); /* GPU compositing layer */ } .scrim-overlay, .img-wrap, .luxury-input, .luxury-handle { position: absolute; top: 0; left: 0; right: 0; bottom: 0; } .scrim-overlay { z-index: 4; pointer-events: none; background: linear-gradient(to top, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0.2) 35%, transparent 100%); } .overlay-content { position: absolute; bottom: 36px; width: 300px; transition: opacity 0.4s ease, transform 0.4s ease; pointer-events: none; will-change: opacity, transform; } .left-content { left: 36px; text-align: left; } .right-content { right: 36px; text-align: right; } .luxury-tag { display: block; font-size: 10px; font-weight: 800 !important; text-transform: uppercase; letter-spacing: 3px; color: #fff; margin-bottom: 6px; } .luxury-tag.blue { color: var(--ipanel-blue); } .overlay-content h3 { font-family: 'Poppins', sans-serif !important; font-size: 24px; font-weight: 700 !important; color: #fff; margin: 0; text-shadow: var(--text-shadow); line-height: 1.2; } .overlay-content p { font-family: 'Poppins', sans-serif !important; font-size: 13px; font-weight: 400 !important; color: rgba(255,255,255,0.9); margin: 6px 0 0; line-height: 1.5; text-shadow: var(--text-shadow); } .hidden-state { opacity: 0 !important; pointer-events: none; } .left-content.hidden-state { transform: translateX(-12px); } .right-content.hidden-state { transform: translateX(12px); } .img-wrap { pointer-events: none; z-index: 1; } .img-wrap img { width: 100%; height: 100%; object-fit: cover; display: block; } .img-before { width: 50%; right: auto; z-index: 2; overflow: hidden; border-right: 1.5px solid rgba(255,255,255,0.85); will-change: width; } .luxury-input { width: 100%; height: 100%; appearance: none; -webkit-appearance: none; background: transparent; z-index: 6; cursor: ew-resize; margin: 0; padding: 0; touch-action: pan-y; } .luxury-input:focus { outline: 2px solid var(--ipanel-blue); outline-offset: -2px; } .luxury-input::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 60px; height: 100%; background: transparent; cursor: ew-resize; } .luxury-input::-moz-range-thumb { width: 60px; height: 100%; background: transparent; border: none; cursor: ew-resize; } .luxury-handle { width: 2px; left: 50%; right: auto; z-index: 5; pointer-events: none; display: flex; flex-direction: column; align-items: center; justify-content: center; transform: translateX(-50%); will-change: left; } .handle-core { flex-shrink: 0; width: 44px; height: 44px; background: var(--ipanel-blue); border: 2.5px solid #fff; border-radius: 50%; display: flex; align-items: center; justify-content: center; } .line-top, .line-bottom { flex: 1; width: 1.5px; background: rgba(255,255,255,0.85); } @media (max-width: 1024px) { .luxury-validation { margin: 30px auto 40px auto !important; } .luxury-stage { aspect-ratio: 4 / 3; border-radius: 6px; } .overlay-content { width: 240px; bottom: 24px; } .left-content { left: 20px; } .right-content { right: 20px; } .overlay-content h3 { font-size: 20px; } .overlay-content p { font-size: 12px; } } @media (max-width: 768px) { .luxury-validation { margin: 20px auto 40px auto !important; } .luxury-validation::after { content: ''; display: table; clear: both; } .luxury-stage { aspect-ratio: 3 / 4; border-radius: 4px; min-height: 380px !important; } .scrim-overlay { background: linear-gradient(to bottom, transparent 50%, rgba(0,0,0,0.75) 100%); } .overlay-content { width: calc(50% - 24px); bottom: 24px; top: auto; text-align: center; left: auto; right: auto; } .left-content { left: 8px; right: auto; display: flex; flex-direction: column; align-items: center; } .right-content { right: 8px; left: auto; display: flex; flex-direction: column; align-items: center; } .left-content.hidden-state { transform: translateY(10px) !important; } .right-content.hidden-state { transform: translateY(10px) !important; } .overlay-content h3 { font-size: 18px; } .overlay-content p { font-size: 12px; } .luxury-tag { font-size: 9px; margin-bottom: 4px; } .handle-core { width: 48px; height: 48px; } .luxury-input::-webkit-slider-thumb { width: 80px; } } @media (max-width: 480px) { .luxury-stage { min-height: 320px !important; } .overlay-content h3 { font-size: 16px; } .overlay-content p { font-size: 11px; } } (function () { var slider = document.getElementById('lux-slider-livingroom'); var clipBox = document.getElementById('clip-box-livingroom'); var handle = document.getElementById('lux-handle-livingroom'); var textBefore = document.getElementById('content-before-livingroom'); var textAfter = document.getElementById('content-after-livingroom'); var ticking = false; function isMobileTablet() { return window.innerWidth <= 1024; } function updateDOM(val) { var pct = val + '%'; clipBox.style.width = pct; handle.style.left = pct; if (isMobileTablet()) { if (val = 65) { textAfter.classList.remove('hidden-state'); textBefore.classList.add('hidden-state'); } else { textBefore.classList.add('hidden-state'); textAfter.classList.add('hidden-state'); } } else { if (val > 80) { textAfter.classList.add('hidden-state'); textBefore.classList.remove('hidden-state'); } else if (val < 20) { textBefore.classList.add('hidden-state'); textAfter.classList.remove('hidden-state'); } else { textBefore.classList.remove('hidden-state'); textAfter.classList.remove('hidden-state'); } } ticking = false; } function requestUpdate(val) { if (!ticking) { window.requestAnimationFrame(function() { updateDOM(val); }); ticking = true; } } slider.addEventListener('input', function (e) { requestUpdate(parseInt(e.target.value, 10)); }); function init() { if (isMobileTablet()) { textBefore.classList.add('hidden-state'); textAfter.classList.add('hidden-state'); } else { textBefore.classList.remove('hidden-state'); textAfter.classList.remove('hidden-state'); } } var resizeTimer; window.addEventListener('resize', function () { clearTimeout(resizeTimer); resizeTimer = setTimeout(function() { requestUpdate(parseInt(slider.value, 10)); }, 100); }); if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();
Unfinished Shell

Bare Services

Exposed commercial roofing lacks the visual refinement required for high end client interactions.

Corporate Identity

Professional Refinement

Clean architectural lines and sophisticated tones deliver an authoritative corporate atmosphere.

Commercial Space with i-Panel PVC Ceiling
Commercial Space Without Ceiling
:root { --ipanel-blue: #0066ff; --text-shadow: 0 2px 4px rgba(0,0,0,0.9); } .luxury-validation { display: flow-root !important; position: relative !important; width: 100% !important; max-width: 1100px; margin: 30px auto 40px auto !important; padding: 0 !important; font-family: 'Poppins', sans-serif !important; isolation: isolate; clear: both; } .elementor-widget-html:has(.luxury-validation) { display: block !important; width: 100% !important; position: relative !important; clear: both !important; margin-bottom: 0px !important; } .luxury-stage { display: block; position: relative; width: 100%; aspect-ratio: 16 / 9; min-height: 200px; border-radius: 8px; overflow: hidden; background: #000; box-shadow: 0 20px 60px -10px rgba(0,0,0,0.25); isolation: isolate; transform: translateZ(0); /* GPU compositing layer */ } .scrim-overlay, .img-wrap, .luxury-input, .luxury-handle { position: absolute; top: 0; left: 0; right: 0; bottom: 0; } .scrim-overlay { z-index: 4; pointer-events: none; background: linear-gradient(to top, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0.2) 35%, transparent 100%); } .overlay-content { position: absolute; bottom: 36px; width: 300px; transition: opacity 0.4s ease, transform 0.4s ease; pointer-events: none; will-change: opacity, transform; } .left-content { left: 36px; text-align: left; } .right-content { right: 36px; text-align: right; } .luxury-tag { display: block; font-size: 10px; font-weight: 800 !important; text-transform: uppercase; letter-spacing: 3px; color: #fff; margin-bottom: 6px; } .luxury-tag.blue { color: var(--ipanel-blue); } .overlay-content h3 { font-family: 'Poppins', sans-serif !important; font-size: 24px; font-weight: 700 !important; color: #fff; margin: 0; text-shadow: var(--text-shadow); line-height: 1.2; } .overlay-content p { font-family: 'Poppins', sans-serif !important; font-size: 13px; font-weight: 400 !important; color: rgba(255,255,255,0.9); margin: 6px 0 0; line-height: 1.5; text-shadow: var(--text-shadow); } .hidden-state { opacity: 0 !important; pointer-events: none; } .left-content.hidden-state { transform: translateX(-12px); } .right-content.hidden-state { transform: translateX(12px); } .img-wrap { pointer-events: none; z-index: 1; } .img-wrap img { width: 100%; height: 100%; object-fit: cover; display: block; } .img-before { width: 50%; right: auto; z-index: 2; overflow: hidden; border-right: 1.5px solid rgba(255,255,255,0.85); will-change: width; } .luxury-input { width: 100%; height: 100%; appearance: none; -webkit-appearance: none; background: transparent; z-index: 6; cursor: ew-resize; margin: 0; padding: 0; touch-action: pan-y; } .luxury-input:focus { outline: 2px solid var(--ipanel-blue); outline-offset: -2px; } .luxury-input::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 60px; height: 100%; background: transparent; cursor: ew-resize; } .luxury-input::-moz-range-thumb { width: 60px; height: 100%; background: transparent; border: none; cursor: ew-resize; } .luxury-handle { width: 2px; left: 50%; right: auto; z-index: 5; pointer-events: none; display: flex; flex-direction: column; align-items: center; justify-content: center; transform: translateX(-50%); will-change: left; } .handle-core { flex-shrink: 0; width: 44px; height: 44px; background: var(--ipanel-blue); border: 2.5px solid #fff; border-radius: 50%; display: flex; align-items: center; justify-content: center; } .line-top, .line-bottom { flex: 1; width: 1.5px; background: rgba(255,255,255,0.85); } @media (max-width: 1024px) { .luxury-validation { margin: 30px auto 40px auto !important; } .luxury-stage { aspect-ratio: 4 / 3; border-radius: 6px; } .overlay-content { width: 240px; bottom: 24px; } .left-content { left: 20px; } .right-content { right: 20px; } .overlay-content h3 { font-size: 20px; } .overlay-content p { font-size: 12px; } } @media (max-width: 768px) { .luxury-validation { margin: 20px auto 40px auto !important; } .luxury-validation::after { content: ''; display: table; clear: both; } .luxury-stage { aspect-ratio: 3 / 4; border-radius: 4px; min-height: 380px !important; } .scrim-overlay { background: linear-gradient(to bottom, transparent 50%, rgba(0,0,0,0.75) 100%); } .overlay-content { width: calc(50% - 24px); bottom: 24px; top: auto; text-align: center; left: auto; right: auto; } .left-content { left: 8px; right: auto; display: flex; flex-direction: column; align-items: center; } .right-content { right: 8px; left: auto; display: flex; flex-direction: column; align-items: center; } .left-content.hidden-state { transform: translateY(10px) !important; } .right-content.hidden-state { transform: translateY(10px) !important; } .overlay-content h3 { font-size: 18px; } .overlay-content p { font-size: 12px; } .luxury-tag { font-size: 9px; margin-bottom: 4px; } .handle-core { width: 48px; height: 48px; } .luxury-input::-webkit-slider-thumb { width: 80px; } } @media (max-width: 480px) { .luxury-stage { min-height: 320px !important; } .overlay-content h3 { font-size: 16px; } .overlay-content p { font-size: 11px; } } (function () { var slider = document.getElementById('lux-slider-commercial'); var clipBox = document.getElementById('clip-box-commercial'); var handle = document.getElementById('lux-handle-commercial'); var textBefore = document.getElementById('content-before-commercial'); var textAfter = document.getElementById('content-after-commercial'); var ticking = false; function isMobileTablet() { return window.innerWidth <= 1024; } function updateDOM(val) { var pct = val + '%'; clipBox.style.width = pct; handle.style.left = pct; if (isMobileTablet()) { if (val = 65) { textAfter.classList.remove('hidden-state'); textBefore.classList.add('hidden-state'); } else { textBefore.classList.add('hidden-state'); textAfter.classList.add('hidden-state'); } } else { if (val > 80) { textAfter.classList.add('hidden-state'); textBefore.classList.remove('hidden-state'); } else if (val < 20) { textBefore.classList.add('hidden-state'); textAfter.classList.remove('hidden-state'); } else { textBefore.classList.remove('hidden-state'); textAfter.classList.remove('hidden-state'); } } ticking = false; } function requestUpdate(val) { if (!ticking) { window.requestAnimationFrame(function() { updateDOM(val); }); ticking = true; } } slider.addEventListener('input', function (e) { requestUpdate(parseInt(e.target.value, 10)); }); function init() { if (isMobileTablet()) { textBefore.classList.add('hidden-state'); textAfter.classList.add('hidden-state'); } else { textBefore.classList.remove('hidden-state'); textAfter.classList.remove('hidden-state'); } } var resizeTimer; window.addEventListener('resize', function () { clearTimeout(resizeTimer); resizeTimer = setTimeout(function() { requestUpdate(parseInt(slider.value, 10)); }, 100); }); if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();
Industrial Roof

Exposed Trusses

Bare metal frameworks increase thermal transfer and create distracting overhead clutter.

Creative Focus

Optimized Illumination

Crisp white panels maximize natural light reflection and provide a clean aesthetic baseline.

Modern Studio with i-Panel PVC Ceiling
Modern Studio Without Ceiling
:root { --ipanel-blue: #0066ff; --text-shadow: 0 2px 4px rgba(0,0,0,0.9); } .luxury-validation { display: flow-root !important; position: relative !important; width: 100% !important; max-width: 1100px; margin: 30px auto 40px auto !important; padding: 0 !important; font-family: 'Poppins', sans-serif !important; isolation: isolate; clear: both; } .elementor-widget-html:has(.luxury-validation) { display: block !important; width: 100% !important; position: relative !important; clear: both !important; margin-bottom: 0px !important; } .luxury-stage { display: block; position: relative; width: 100%; aspect-ratio: 16 / 9; min-height: 200px; border-radius: 8px; overflow: hidden; background: #000; box-shadow: 0 20px 60px -10px rgba(0,0,0,0.25); isolation: isolate; transform: translateZ(0); /* GPU compositing layer */ } .scrim-overlay, .img-wrap, .luxury-input, .luxury-handle { position: absolute; top: 0; left: 0; right: 0; bottom: 0; } .scrim-overlay { z-index: 4; pointer-events: none; background: linear-gradient(to top, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0.2) 35%, transparent 100%); } .overlay-content { position: absolute; bottom: 36px; width: 300px; transition: opacity 0.4s ease, transform 0.4s ease; pointer-events: none; will-change: opacity, transform; } .left-content { left: 36px; text-align: left; } .right-content { right: 36px; text-align: right; } .luxury-tag { display: block; font-size: 10px; font-weight: 800 !important; text-transform: uppercase; letter-spacing: 3px; color: #fff; margin-bottom: 6px; } .luxury-tag.blue { color: var(--ipanel-blue); } .overlay-content h3 { font-family: 'Poppins', sans-serif !important; font-size: 24px; font-weight: 700 !important; color: #fff; margin: 0; text-shadow: var(--text-shadow); line-height: 1.2; } .overlay-content p { font-family: 'Poppins', sans-serif !important; font-size: 13px; font-weight: 400 !important; color: rgba(255,255,255,0.9); margin: 6px 0 0; line-height: 1.5; text-shadow: var(--text-shadow); } .hidden-state { opacity: 0 !important; pointer-events: none; } .left-content.hidden-state { transform: translateX(-12px); } .right-content.hidden-state { transform: translateX(12px); } .img-wrap { pointer-events: none; z-index: 1; } .img-wrap img { width: 100%; height: 100%; object-fit: cover; display: block; } .img-before { width: 50%; right: auto; z-index: 2; overflow: hidden; border-right: 1.5px solid rgba(255,255,255,0.85); will-change: width; } .luxury-input { width: 100%; height: 100%; appearance: none; -webkit-appearance: none; background: transparent; z-index: 6; cursor: ew-resize; margin: 0; padding: 0; touch-action: pan-y; } .luxury-input:focus { outline: 2px solid var(--ipanel-blue); outline-offset: -2px; } .luxury-input::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 60px; height: 100%; background: transparent; cursor: ew-resize; } .luxury-input::-moz-range-thumb { width: 60px; height: 100%; background: transparent; border: none; cursor: ew-resize; } .luxury-handle { width: 2px; left: 50%; right: auto; z-index: 5; pointer-events: none; display: flex; flex-direction: column; align-items: center; justify-content: center; transform: translateX(-50%); will-change: left; } .handle-core { flex-shrink: 0; width: 44px; height: 44px; background: var(--ipanel-blue); border: 2.5px solid #fff; border-radius: 50%; display: flex; align-items: center; justify-content: center; } .line-top, .line-bottom { flex: 1; width: 1.5px; background: rgba(255,255,255,0.85); } @media (max-width: 1024px) { .luxury-validation { margin: 30px auto 40px auto !important; } .luxury-stage { aspect-ratio: 4 / 3; border-radius: 6px; } .overlay-content { width: 240px; bottom: 24px; } .left-content { left: 20px; } .right-content { right: 20px; } .overlay-content h3 { font-size: 20px; } .overlay-content p { font-size: 12px; } } @media (max-width: 768px) { .luxury-validation { margin: 20px auto 40px auto !important; } .luxury-validation::after { content: ''; display: table; clear: both; } .luxury-stage { aspect-ratio: 3 / 4; border-radius: 4px; min-height: 380px !important; } .scrim-overlay { background: linear-gradient(to bottom, transparent 50%, rgba(0,0,0,0.75) 100%); } .overlay-content { width: calc(50% - 24px); bottom: 24px; top: auto; text-align: center; left: auto; right: auto; } .left-content { left: 8px; right: auto; display: flex; flex-direction: column; align-items: center; } .right-content { right: 8px; left: auto; display: flex; flex-direction: column; align-items: center; } .left-content.hidden-state { transform: translateY(10px) !important; } .right-content.hidden-state { transform: translateY(10px) !important; } .overlay-content h3 { font-size: 18px; } .overlay-content p { font-size: 12px; } .luxury-tag { font-size: 9px; margin-bottom: 4px; } .handle-core { width: 48px; height: 48px; } .luxury-input::-webkit-slider-thumb { width: 80px; } } @media (max-width: 480px) { .luxury-stage { min-height: 320px !important; } .overlay-content h3 { font-size: 16px; } .overlay-content p { font-size: 11px; } } (function () { var slider = document.getElementById('lux-slider-studio'); var clipBox = document.getElementById('clip-box-studio'); var handle = document.getElementById('lux-handle-studio'); var textBefore = document.getElementById('content-before-studio'); var textAfter = document.getElementById('content-after-studio'); var ticking = false; function isMobileTablet() { return window.innerWidth <= 1024; } function updateDOM(val) { var pct = val + '%'; clipBox.style.width = pct; handle.style.left = pct; if (isMobileTablet()) { if (val = 65) { textAfter.classList.remove('hidden-state'); textBefore.classList.add('hidden-state'); } else { textBefore.classList.add('hidden-state'); textAfter.classList.add('hidden-state'); } } else { if (val > 80) { textAfter.classList.add('hidden-state'); textBefore.classList.remove('hidden-state'); } else if (val < 20) { textBefore.classList.add('hidden-state'); textAfter.classList.remove('hidden-state'); } else { textBefore.classList.remove('hidden-state'); textAfter.classList.remove('hidden-state'); } } ticking = false; } function requestUpdate(val) { if (!ticking) { window.requestAnimationFrame(function() { updateDOM(val); }); ticking = true; } } slider.addEventListener('input', function (e) { requestUpdate(parseInt(e.target.value, 10)); }); function init() { if (isMobileTablet()) { textBefore.classList.add('hidden-state'); textAfter.classList.add('hidden-state'); } else { textBefore.classList.remove('hidden-state'); textAfter.classList.remove('hidden-state'); } } var resizeTimer; window.addEventListener('resize', function () { clearTimeout(resizeTimer); resizeTimer = setTimeout(function() { requestUpdate(parseInt(slider.value, 10)); }, 100); }); if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();
#ipag *,#ipag *::before,#ipag *::after{box-sizing:border-box;margin:0;padding:0} #ipag{ --text: #0A0A14; --muted: #4A4A5A; --border: #E8E8F0; --hover: #F5F7FF; --blue: #0052CC; font-family:'Poppins',sans-serif; -webkit-font-smoothing:antialiased; width:100%; } /* ── Grid ── */ #ipag .ag-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:0; border-top:1px solid var(--border); border-left:1px solid var(--border); } /* ── Card ── */ #ipag .ag-card{ display:flex; flex-direction:column; align-items:flex-start; padding:36px 32px 40px; border-right:1px solid var(--border); border-bottom:1px solid var(--border); background:#fff; transition:background .25s ease; position:relative; overflow:hidden; } #ipag .ag-card::after{ content:''; position:absolute; bottom:0;left:0;right:0; height:3px; background:var(--blue); transform:scaleX(0); transform-origin:left; transition:transform .3s ease; } #ipag .ag-card:hover{background:var(--hover)} #ipag .ag-card:hover::after{transform:scaleX(1)} /* ── Icon ── */ #ipag .ag-icon{ width:64px; height:64px; margin-bottom:22px; flex-shrink:0; } #ipag .ag-icon img{ width:100%; height:100%; object-fit:contain; display:block; } /* ── Title ── */ #ipag .ag-title{ font-size:1.05rem; font-weight:700; color:var(--text); line-height:1.3; margin-bottom:12px; letter-spacing:-.01em; } /* ── Description ── */ #ipag .ag-desc{ font-size:.825rem; font-weight:400; color:var(--muted); line-height:1.75; } /* ── Responsive ── */ @media(max-width:1024px){ #ipag .ag-grid{grid-template-columns:repeat(2,1fr)} #ipag .ag-card{padding:28px 24px 32px} } @media(max-width:600px){ #ipag .ag-grid{grid-template-columns:repeat(2,1fr)} #ipag .ag-card{padding:22px 18px 26px} #ipag .ag-icon{width:52px;height:52px;margin-bottom:16px} #ipag .ag-title{font-size:.95rem} #ipag .ag-desc{font-size:.78rem} } @media(max-width:380px){ #ipag .ag-grid{grid-template-columns:1fr} }
Fire Retardant icon

Fire Retardant

Advanced fire-resistant materials that meet safety standards and provide excellent protection against fire hazards in construction applications.

No Need to Paint icon

No Need to Paint

Pre-finished surface eliminates the need for painting, saving time and maintenance costs while maintaining aesthetic appeal.

Easy Maintenance icon

Easy Maintenance

Simple cleaning and minimal upkeep required. Resistant to stains and dirt, making maintenance effortless and cost-effective.

Saves Labour icon

Saves Labor

Cut labor costs with our fast, simple, and innovative ceiling installation.

Water Resistant icon

Water Resist

Excellent water resistance properties prevent moisture damage, mold growth, and structural deterioration over time.

Zero Toxicity icon

Zero Toxicity

Non-toxic materials that are safe for indoor use, containing no harmful chemicals or volatile organic compounds (VOCs).

Any Climate Tolerant icon

Any Climate Tolerant

Performs excellently in various weather conditions — from extreme heat to cold, humidity, and changing seasonal conditions.

Saves Time icon

Saves Time

Streamlined installation process and reduced preparation time leads to faster project completion and quicker occupancy.

Free from Insects icon

Free from Insect

Naturally resistant to termites, ants, and other insects, eliminating the need for chemical treatments and pest control.

Non-Carcinogenic icon

Non-Carcinogenic

Completely safe and non-carcinogenic materials that pose no health risks to occupants or construction workers.

Less Wastage icon

Less Wastage

Precise manufacturing and easy cutting reduce material waste, making it an environmentally friendly and cost-effective choice.

Light Weighted icon

Light Weighted

Lightweight design reduces structural load requirements and makes handling and installation easier without compromising strength.

i-Panel CATALOG

Sri Lanka's #1 Interior Panel

For over 15 years, i-Panel has shaped the interiors of Sri Lanka’s most distinguished spaces. Proudly manufactured to international standards, our premium solutions are distributed through a strong, islandwide network covering all major districts—delivering architectural precision and enduring performance wherever you are.

15+ Years

Shaping Sri Lankan interiors.

Islandwide

Available across all major districts.

15-Year Warranty

Engineered for structural performance.

I Panel product catalogue 1

DESIGN INSPIRATION

Follow Us on Pinterest

Explore our latest ceiling design ideas, interior inspirations, and real project showcases curated just for you.

/* ── i-Panel Pinterest Feed · every rule is scoped to .ipf-wrap / .ipf-lb ── */ /* Design tokens live on the widget, not :root, so they can't clash with the host theme. The lightbox is appended to , so it gets its own copy. */ .ipf-wrap,.ipf-lb{ --ipf-text:#2D2D2D; --ipf-text-2:#6E6E6E; /* was #8C8C8C (3.4:1) — now passes WCAG AA for small text */ --ipf-border:#E8E5DF; --ipf-border-hover:#D1CFC9; --ipf-bg:#FFFFFF; --ipf-bg-2:#F7F5F0; --ipf-accent:#1C38FF; --ipf-accent-soft:#E8F0FE; font-family:'Outfit',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif; color:var(--ipf-text); line-height:1.4; -webkit-font-smoothing:antialiased; } /* Scoped reset + light hardening against host-page element styles */ .ipf-wrap,.ipf-wrap *,.ipf-wrap *::before,.ipf-wrap *::after, .ipf-lb,.ipf-lb *,.ipf-lb *::before,.ipf-lb *::after{box-sizing:border-box;margin:0;padding:0} .ipf-wrap [hidden],.ipf-lb [hidden]{display:none!important} .ipf-wrap button,.ipf-lb button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;-webkit-appearance:none;appearance:none;text-transform:none;letter-spacing:normal} .ipf-wrap a,.ipf-lb a{color:inherit;text-decoration:none} .ipf-wrap ul{list-style:none} .ipf-wrap img,.ipf-lb img{border:0} .ipf-wrap :focus-visible,.ipf-lb :focus-visible{outline:2px solid var(--ipf-accent);outline-offset:2px} .ipf-icon{width:16px;height:16px;display:inline-block;flex-shrink:0;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;vertical-align:-.15em} /* Shell */ .ipf-wrap{ width:100%;display:flex;gap:32px;align-items:flex-start;padding:32px; background:var(--ipf-bg);border:1px solid var(--ipf-border);border-radius:24px; box-shadow:0 4px 20px rgba(0,0,0,.03); } /* Sidebar */ .ipf-wrap .ipf-sidebar{flex:0 0 220px;display:flex;flex-direction:column;gap:18px} .ipf-wrap .ipf-brand{display:flex;align-items:center;gap:12px} .ipf-wrap .ipf-avatar{width:44px;height:44px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;background:var(--ipf-accent-soft);color:var(--ipf-accent)} .ipf-wrap .ipf-avatar .ipf-icon{width:22px;height:22px} .ipf-wrap .ipf-brand-name{font-size:16px;font-weight:600;line-height:1.3} .ipf-wrap .ipf-brand-handle{font-size:12px;color:var(--ipf-text-2);margin-top:2px} .ipf-wrap .ipf-desc{font-size:13px;line-height:1.6;color:var(--ipf-text-2);border-left:2px solid var(--ipf-border);padding-left:10px} .ipf-wrap .ipf-stats{display:grid;grid-template-columns:1fr 1fr;gap:8px} .ipf-wrap .ipf-stat{background:var(--ipf-bg-2);border-radius:10px;padding:10px 12px;text-align:center} .ipf-wrap .ipf-stat-num{font-size:18px;font-weight:600} .ipf-wrap .ipf-stat-lbl{font-size:11px;color:var(--ipf-text-2);margin-top:2px} .ipf-wrap .ipf-follow-btn{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;padding:11px 16px;border-radius:10px;background:var(--ipf-accent);color:#fff;font-size:13px;font-weight:600;transition:opacity .15s} .ipf-wrap .ipf-follow-btn:hover{opacity:.88} .ipf-wrap .ipf-tags{display:flex;flex-wrap:wrap;gap:6px} .ipf-wrap .ipf-tag{font-size:11px;color:var(--ipf-text-2);background:var(--ipf-bg-2);border:1px solid var(--ipf-border);border-radius:999px;padding:3px 10px} /* Main panel */ .ipf-wrap .ipf-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:20px} .ipf-wrap .ipf-filters{display:flex;flex-wrap:wrap;gap:8px} .ipf-wrap .ipf-chip{font-size:12px;padding:5px 12px;border-radius:999px;border:1px solid var(--ipf-border);color:var(--ipf-text);transition:background-color .15s,color .15s,border-color .15s} .ipf-wrap .ipf-chip:hover{background:var(--ipf-bg-2)} .ipf-wrap .ipf-chip.is-active{background:var(--ipf-accent);border-color:var(--ipf-accent);color:#fff} /* Grid — fade-in only: content swaps instantly, then animates from 0 → 1 */ .ipf-wrap .ipf-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px;align-items:start;min-height:320px;opacity:1;transition:opacity .2s ease} .ipf-wrap .ipf-grid.is-entering{opacity:0;transition:none} /* Pin card */ .ipf-wrap .ipf-pin{display:flex;flex-direction:column;overflow:hidden;border-radius:16px;background:var(--ipf-bg);border:1px solid var(--ipf-border);box-shadow:0 4px 12px rgba(0,0,0,.03);transition:transform .25s,box-shadow .25s,border-color .25s} .ipf-wrap .ipf-pin:hover,.ipf-wrap .ipf-pin:focus-within{transform:translateY(-4px);box-shadow:0 12px 24px rgba(0,0,0,.06);border-color:var(--ipf-border-hover)} .ipf-wrap .ipf-pin-open{display:block;width:100%;text-align:left} .ipf-wrap .ipf-pin-open:focus-visible{outline-offset:-3px;border-radius:16px 16px 0 0} /* Image area: skeleton and image are stacked, so the fade-in can actually animate */ .ipf-wrap .ipf-pin-media{position:relative;display:block;aspect-ratio:3/4;overflow:hidden;background:var(--ipf-bg-2)} .ipf-wrap .ipf-pin-skel{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;overflow:hidden} .ipf-wrap .ipf-pin-skel::after{content:'';position:absolute;inset:0;background:linear-gradient(90deg,transparent 20%,rgba(255,255,255,.55) 50%,transparent 80%);background-size:200% 100%;animation:ipfShimmer 1.6s ease-in-out infinite} .ipf-wrap .ipf-pin-skel .ipf-icon{display:none;width:24px;height:24px;color:var(--ipf-text-2);opacity:.4} .ipf-wrap .ipf-pin-media.is-error .ipf-pin-skel::after{display:none} .ipf-wrap .ipf-pin-media.is-error .ipf-pin-skel .ipf-icon{display:inline-block} .ipf-wrap .ipf-pin-img{position:absolute;inset:0;display:block;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .3s ease,transform .45s ease} .ipf-wrap .ipf-pin-media.is-loaded .ipf-pin-img{opacity:1} .ipf-wrap .ipf-pin-media.is-error .ipf-pin-img{display:none} .ipf-wrap .ipf-pin-open:hover .ipf-pin-img{transform:scale(1.045)} .ipf-wrap .ipf-pin-title{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;padding:12px 14px 0;font-size:13px;font-weight:500;line-height:1.45} .ipf-wrap .ipf-pin-footer{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:12px 14px 14px} .ipf-wrap .ipf-pin-view{display:inline-flex;align-items:center;gap:4px;font-size:12px;color:var(--ipf-text-2);transition:color .15s} .ipf-wrap .ipf-pin-view .ipf-icon{width:13px;height:13px} .ipf-wrap .ipf-pin-view:hover{color:var(--ipf-accent)} .ipf-wrap .ipf-pin-save{display:inline-flex;align-items:center;gap:5px;height:28px;padding:0 10px;border-radius:14px;background:var(--ipf-accent);color:#fff;font-size:12px;font-weight:600;transition:transform .15s} .ipf-wrap .ipf-pin-save .ipf-icon{width:13px;height:13px} .ipf-wrap .ipf-pin-save:hover{transform:scale(1.05)} /* Loading placeholders (shown while pins are fetched) */ .ipf-wrap .ipf-pin.is-skeleton{pointer-events:none;box-shadow:none} .ipf-wrap .ipf-skel-line{position:relative;display:block;height:10px;margin:14px 14px 0;border-radius:5px;background:var(--ipf-bg-2);overflow:hidden} .ipf-wrap .ipf-skel-line.is-short{width:45%;margin-bottom:18px} /* Empty state */ .ipf-wrap .ipf-empty{grid-column:1/-1;display:flex;flex-direction:column;align-items:center;gap:12px;padding:48px 24px;text-align:center;font-size:14px;color:var(--ipf-text-2)} .ipf-wrap .ipf-empty .ipf-icon{width:32px;height:32px;opacity:.5} .ipf-wrap .ipf-empty-action{font-size:13px;font-weight:600;color:var(--ipf-accent);padding:6px 12px;border-radius:8px;transition:background-color .15s} .ipf-wrap .ipf-empty-action:hover{background:var(--ipf-accent-soft)} /* Pagination */ .ipf-wrap .ipf-pag-row{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;padding-top:18px;border-top:1px solid var(--ipf-border)} .ipf-wrap .ipf-pag-info{font-size:12px;color:var(--ipf-text-2);min-height:1.2em} .ipf-wrap .ipf-pag-btns{display:flex;align-items:center;gap:4px} .ipf-wrap .ipf-pag-btn{min-width:36px;height:36px;padding:0 6px;display:flex;align-items:center;justify-content:center;border-radius:10px;border:1px solid var(--ipf-border);color:var(--ipf-text-2);font-size:13px;font-weight:500;transition:background-color .15s,color .15s} .ipf-wrap .ipf-pag-btn:not(.is-active):not(:disabled):hover{background:var(--ipf-bg-2);color:var(--ipf-text)} .ipf-wrap .ipf-pag-btn.is-active{background:var(--ipf-accent);border-color:var(--ipf-accent);color:#fff} .ipf-wrap .ipf-pag-btn:disabled{opacity:.35;cursor:not-allowed} .ipf-wrap .ipf-pag-gap{padding:0 4px;font-size:13px;color:var(--ipf-text-2)} /* ── Lightbox (appended to by the script) ── visibility is delayed on close so the fade-out actually plays */ .ipf-lb{position:fixed;inset:0;z-index:99999;display:flex;align-items:center;justify-content:center;padding:24px;background:rgba(0,0,0,0);opacity:0;visibility:hidden;transition:opacity .2s ease,background-color .2s ease,visibility 0s linear .2s} .ipf-lb.is-open{opacity:1;visibility:visible;background:rgba(0,0,0,.75);transition:opacity .2s ease,background-color .2s ease,visibility 0s} .ipf-lb .ipf-lb-panel{position:relative;display:flex;flex-direction:column;width:100%;max-width:680px;max-height:calc(100vh - 48px);overflow:hidden;background:var(--ipf-bg);border:1px solid var(--ipf-border);border-radius:24px;transform:scale(.96);transition:transform .2s ease} .ipf-lb.is-open .ipf-lb-panel{transform:scale(1)} /* Fixed-height media area: no layout jump when switching between tall and wide images */ .ipf-lb .ipf-lb-media{position:relative;flex:0 0 auto;height:min(60vh,520px);background:var(--ipf-bg-2)} .ipf-lb .ipf-lb-img{display:block;width:100%;height:100%;object-fit:contain;opacity:0;transition:opacity .25s ease} .ipf-lb .ipf-lb-media.is-loaded .ipf-lb-img{opacity:1} .ipf-lb .ipf-lb-spinner{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none;transition:opacity .2s} .ipf-lb .ipf-lb-spinner::after{content:'';width:32px;height:32px;border:3px solid var(--ipf-border);border-top-color:var(--ipf-accent);border-radius:50%;animation:ipfSpin .8s linear infinite} .ipf-lb .ipf-lb-media.is-loaded .ipf-lb-spinner,.ipf-lb .ipf-lb-media.is-error .ipf-lb-spinner{opacity:0} .ipf-lb .ipf-lb-error{position:absolute;inset:0;display:none;flex-direction:column;align-items:center;justify-content:center;gap:8px;font-size:13px;color:var(--ipf-text-2)} .ipf-lb .ipf-lb-error .ipf-icon{width:28px;height:28px;opacity:.5} .ipf-lb .ipf-lb-media.is-error .ipf-lb-error{display:flex} .ipf-lb .ipf-lb-close{position:absolute;top:12px;right:12px;z-index:2;width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.55);border:1px solid rgba(255,255,255,.15);color:#fff;transition:background-color .2s} .ipf-lb .ipf-lb-close:hover{background:rgba(0,0,0,.8)} /* Dark buttons: the old white-on-cream arrows were nearly invisible */ .ipf-lb .ipf-lb-nav{position:absolute;top:50%;z-index:1;width:40px;height:40px;transform:translateY(-50%);border-radius:50%;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.45);border:1px solid rgba(255,255,255,.2);color:#fff;transition:background-color .2s} .ipf-lb .ipf-lb-nav:hover{background:rgba(0,0,0,.7)} .ipf-lb .ipf-lb-nav .ipf-icon{width:18px;height:18px} .ipf-lb .ipf-lb-prev{left:16px} .ipf-lb .ipf-lb-next{right:16px} .ipf-lb .ipf-lb-body{flex:1 1 auto;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:10px;padding:20px 24px 24px} .ipf-lb .ipf-lb-counter{font-size:12px;color:var(--ipf-text-2)} .ipf-lb .ipf-lb-title{font-family:inherit;font-size:15px;font-weight:600;line-height:1.4;color:var(--ipf-text);letter-spacing:normal;text-transform:none;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden} .ipf-lb .ipf-lb-desc{font-size:13px;line-height:1.6;color:var(--ipf-text-2)} .ipf-lb .ipf-lb-actions{display:flex;gap:8px;margin-top:4px} .ipf-lb .ipf-lb-link{flex:1;display:flex;align-items:center;justify-content:center;gap:8px;padding:10px;border-radius:10px;background:var(--ipf-accent);color:#fff;font-size:13px;font-weight:500} .ipf-lb .ipf-lb-closebtn{padding:10px 14px;border-radius:10px;border:1px solid var(--ipf-border);color:var(--ipf-text-2);font-size:13px;transition:background-color .15s} .ipf-lb .ipf-lb-closebtn:hover{background:var(--ipf-bg-2)} @keyframes ipfShimmer{0%{background-position:200% 0}100%{background-position:-200% 0}} @keyframes ipfSpin{to{transform:rotate(360deg)}} @media (prefers-reduced-motion:reduce){ .ipf-wrap *,.ipf-wrap *::after,.ipf-lb,.ipf-lb *,.ipf-lb *::after{transition:none!important;animation:none!important} .ipf-wrap .ipf-pin:hover,.ipf-wrap .ipf-pin:focus-within,.ipf-wrap .ipf-pin-open:hover .ipf-pin-img{transform:none} } @media (max-width:680px){ .ipf-wrap{flex-direction:column;gap:24px;padding:20px} .ipf-wrap .ipf-sidebar{flex:none;width:100%} .ipf-wrap .ipf-grid{grid-template-columns:repeat(2,minmax(0,1fr))} } @media (max-width:480px){ .ipf-lb{padding:12px} .ipf-lb .ipf-lb-panel{border-radius:16px;max-height:calc(100vh - 24px)} .ipf-lb .ipf-lb-media{height:min(50vh,420px)} } @media (max-width:420px){ .ipf-wrap .ipf-grid{grid-template-columns:1fr} }

    (function () { 'use strict'; // Included twice (e.g. two embeds)? Reuse the first copy and just pick up any new roots. if (window.IPanelFeed && typeof window.IPanelFeed.autoInit === 'function') { window.IPanelFeed.autoInit(); return; } const SVG_NS = 'http://www.w3.org/2000/svg'; const DEFAULT_PROFILE_URL = 'https://www.pinterest.com/ipanelceiling/'; const reducedMotion = window.matchMedia ? window.matchMedia('(prefers-reduced-motion: reduce)') : { matches: false }; // Keyword fallback for pins without tags. Whole-word match (plus plurals / -ing), // so "led" no longer matches "instal-led" and "tiled". const FILTER_KEYWORDS = { wood: ['wood', 'wooden', 'timber', 'kithul', 'teak', 'oak', 'beam', 'plank'], modern: ['modern', 'minimalist', 'contemporary', 'slim', 'open-plan'], luxury: ['luxury', 'hotel', 'premium', 'elegant', 'high-end'], lighting: ['light', 'lighting', 'pendant', 'lamp', 'recessed', 'ambient', 'led', 'glow'] }; const FILTER_PATTERNS = {}; Object.keys(FILTER_KEYWORDS).forEach((key) => { FILTER_PATTERNS[key] = new RegExp('\\b(?:' + FILTER_KEYWORDS[key].join('|') + ')(?:s|es|ing)?\\b', 'i'); }); // Demo data — only used on localhost / file:// or with data-ipf-demo (see header comment). const DEMO_PINS = [ { title: 'Gray Wood luxury ceiling panel', description: 'Waterproof finish, perfect for bathrooms and kitchens.', img: 'https://images.unsplash.com/photo-1631889993959-41b4e9c6e3c5?w=400&q=80', imgFull: 'https://images.unsplash.com/photo-1631889993959-41b4e9c6e3c5?w=1200&q=90', link: 'https://www.pinterest.com/ipanelceiling/', tags: ['wood', 'luxury'] }, { title: 'Kithul dark wood ceiling — built to last', description: 'Authentic Sri Lankan kithul timber, naturally termite-resistant.', img: 'https://images.unsplash.com/photo-1600585154526-990dced4db0d?w=400&q=80', imgFull: 'https://images.unsplash.com/photo-1600585154526-990dced4db0d?w=1200&q=90', link: 'https://www.pinterest.com/ipanelceiling/', tags: ['wood', 'luxury'] }, { title: 'Minimalist white panel living room', description: 'Seamless, modern finish for any ceiling.', img: 'https://images.unsplash.com/photo-1555041469-a586c61ea9bc?w=400&q=80', imgFull: 'https://images.unsplash.com/photo-1555041469-a586c61ea9bc?w=1200&q=90', link: 'https://www.pinterest.com/ipanelceiling/', tags: ['modern'] }, { title: 'Recessed lighting with slim ceiling panels', description: 'Ambient lighting integrated perfectly with i‑Panel boards.', img: 'https://images.unsplash.com/photo-1565538810643-b5bdb714032a?w=400&q=80', imgFull: 'https://images.unsplash.com/photo-1565538810643-b5bdb714032a?w=1200&q=90', link: 'https://www.pinterest.com/ipanelceiling/', tags: ['lighting', 'modern'] }, { title: 'Open-plan dining ceiling design', description: 'Inspiration for spacious, light-filled interiors.', img: 'https://images.unsplash.com/photo-1556909114-f6e7ad7d3136?w=400&q=80', imgFull: 'https://images.unsplash.com/photo-1556909114-f6e7ad7d3136?w=1200&q=90', link: 'https://www.pinterest.com/ipanelceiling/', tags: ['modern', 'luxury'] }, { title: 'Natural wood ceiling with beam detailing', description: 'Rustic yet refined – adds character to any room.', img: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&q=80', imgFull: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=1200&q=90', link: 'https://www.pinterest.com/ipanelceiling/', tags: ['wood'] }, { title: 'Contemporary bedroom ceiling panel install', description: 'Fast, clean installation – no mess, no stress.', img: 'https://images.unsplash.com/photo-1616594039964-ae9021a400a0?w=400&q=80', imgFull: 'https://images.unsplash.com/photo-1616594039964-ae9021a400a0?w=1200&q=90', link: 'https://www.pinterest.com/ipanelceiling/', tags: ['modern'] }, { title: 'Luxury hotel lobby ceiling inspiration', description: 'Premium finishes for high‑end commercial projects.', img: 'https://images.unsplash.com/photo-1578683010236-d716f9a3f461?w=400&q=80', imgFull: 'https://images.unsplash.com/photo-1578683010236-d716f9a3f461?w=1200&q=90', link: 'https://www.pinterest.com/ipanelceiling/', tags: ['luxury'] }, { title: 'Pendant light + wood panel combination', description: 'Warm, inviting atmosphere with wooden ceilings and soft lighting.', img: 'https://images.unsplash.com/photo-1513694203232-719a280e022f?w=400&q=80', imgFull: 'https://images.unsplash.com/photo-1513694203232-719a280e022f?w=1200&q=90', link: 'https://www.pinterest.com/ipanelceiling/', tags: ['lighting', 'wood'] }, { title: 'Waterproof bathroom ceiling panel', description: 'No mould, no warping – perfect for high‑humidity areas.', img: 'https://images.unsplash.com/photo-1552321554-5fefe8c9ef14?w=400&q=80', imgFull: 'https://images.unsplash.com/photo-1552321554-5fefe8c9ef14?w=1200&q=90', link: 'https://www.pinterest.com/ipanelceiling/', tags: ['modern'] }, { title: 'Fast-install ceiling panels for offices', description: 'Transform your workspace in hours, not days.', img: 'https://images.unsplash.com/photo-1497366216548-37526070297c?w=400&q=80', imgFull: 'https://images.unsplash.com/photo-1497366216548-37526070297c?w=1200&q=90', link: 'https://www.pinterest.com/ipanelceiling/', tags: ['modern'] }, { title: 'Sri Lanka No 1 ceiling solution showroom', description: 'Visit our showroom to experience the i‑Panel difference.', img: 'https://images.unsplash.com/photo-1600607687939-ce8a6c25118c?w=400&q=80', imgFull: 'https://images.unsplash.com/photo-1600607687939-ce8a6c25118c?w=1200&q=90', link: 'https://www.pinterest.com/ipanelceiling/', tags: ['luxury'] } ]; /* ── Helpers ─────────────────────────────────────────────── */ // Tiny DOM builder. Strings become text nodes, so pin data can never inject markup. function h(tag, props, ...children) { const node = document.createElement(tag); Object.keys(props || {}).forEach((key) => { const value = props[key]; if (value == null || value === false) return; if (key === 'class') node.className = value; else if (key === 'text') node.textContent = value; else if (key.slice(0, 2) === 'on') node.addEventListener(key.slice(2), value); else node.setAttribute(key, value === true ? '' : String(value)); }); children.flat().forEach((child) => { if (child != null) node.append(child); }); return node; } function icon(name) { const svg = document.createElementNS(SVG_NS, 'svg'); svg.setAttribute('class', 'ipf-icon'); svg.setAttribute('aria-hidden', 'true'); svg.setAttribute('focusable', 'false'); const use = document.createElementNS(SVG_NS, 'use'); use.setAttribute('href', '#ipf-i-' + name); svg.appendChild(use); return svg; } // Only http(s) URLs get through — blocks javascript:, data: and other schemes. function safeUrl(url, fallback) { if (typeof url !== 'string' || !url.trim()) return fallback || ''; try { const parsed = new URL(url, window.location.href); return parsed.protocol === 'https:' || parsed.protocol === 'http:' ? parsed.href : (fallback || ''); } catch (e) { return fallback || ''; } } // Swap the size segment of a Pinterest CDN URL (e.g. /236x/ → /736x/). function upgradePinUrl(url, size) { if (!url || url.indexOf('pinimg.com') === -1) return url; return url.replace(/\/\d+x\//, '/' + size + '/'); } function normalizePins(list, profileUrl) { if (!Array.isArray(list)) { if (list != null) console.warn('[i-Panel feed] Pin data must be an array; got', typeof list); return []; } const pins = list.map((raw) => { if (!raw || typeof raw !== 'object') return null; const img = safeUrl(raw.img); if (!img) return null; return { title: String(raw.title || '').trim(), description: String(raw.description || '').trim(), img: img, imgFull: safeUrl(raw.imgFull) || img, link: safeUrl(raw.link, profileUrl), tags: Array.isArray(raw.tags) ? raw.tags.map((t) => String(t).toLowerCase()) : [] }; }).filter(Boolean); if (pins.length c.classList.contains('is-active')); let activeFilter = initialChip ? initialChip.getAttribute('data-filter') : 'all'; let allPins = []; let filtered = []; let currentPage = 0; let loadState = 'ready'; // 'loading' | 'ready' | 'error' /* Lightbox (one per feed, appended to so no ancestor can clip it) */ const lbTitleId = 'ipf-lb-title-' + uid; const lbImg = h('img', { class: 'ipf-lb-img', alt: '' }); const lbClose = h('button', { class: 'ipf-lb-close', type: 'button', 'aria-label': 'Close' }, icon('close')); const lbPrev = h('button', { class: 'ipf-lb-nav ipf-lb-prev', type: 'button', 'aria-label': 'Previous pin' }, icon('chevron-left')); const lbNext = h('button', { class: 'ipf-lb-nav ipf-lb-next', type: 'button', 'aria-label': 'Next pin' }, icon('chevron-right')); const lbMedia = h('div', { class: 'ipf-lb-media' }, h('div', { class: 'ipf-lb-spinner', 'aria-hidden': 'true' }), h('div', { class: 'ipf-lb-error' }, icon('photo-off'), h('span', { text: 'Image unavailable' })), lbImg, lbPrev, lbNext); const lbCounter = h('p', { class: 'ipf-lb-counter' }); const lbTitle = h('h2', { class: 'ipf-lb-title', id: lbTitleId }); const lbDesc = h('p', { class: 'ipf-lb-desc' }); const lbLink = h('a', { class: 'ipf-lb-link', target: '_blank', rel: 'noopener noreferrer' }, icon('pinterest'), 'View on Pinterest'); const lbCloseBtn = h('button', { class: 'ipf-lb-closebtn', type: 'button' }, 'Close'); const lbEl = h('div', { class: 'ipf-lb', role: 'dialog', 'aria-modal': 'true', 'aria-labelledby': lbTitleId, 'aria-hidden': 'true' }, h('div', { class: 'ipf-lb-panel' }, lbClose, lbMedia, h('div', { class: 'ipf-lb-body' }, lbCounter, lbTitle, lbDesc, h('div', { class: 'ipf-lb-actions' }, lbLink, lbCloseBtn)))); document.body.appendChild(lbEl); let lbPos = 0; let lbLoadId = 0; let lastFocused = null; let savedScroll = null; const isOpen = () => lbEl.classList.contains('is-open'); function lockScroll() { const docEl = document.documentElement; const body = document.body; const scrollbar = window.innerWidth - docEl.clientWidth; savedScroll = { overflow: docEl.style.overflow, paddingRight: body.style.paddingRight }; docEl.style.overflow = 'hidden'; if (scrollbar > 0) { const current = parseFloat(window.getComputedStyle(body).paddingRight) || 0; body.style.paddingRight = (current + scrollbar) + 'px'; } } function unlockScroll() { if (!savedScroll) return; document.documentElement.style.overflow = savedScroll.overflow; document.body.style.paddingRight = savedScroll.paddingRight; savedScroll = null; } function showLightboxPin(pin) { const loadId = ++lbLoadId; const many = filtered.length > 1; lbMedia.classList.remove('is-loaded', 'is-error'); lbTitle.textContent = pin.title || 'Untitled pin'; lbDesc.textContent = pin.description; lbDesc.hidden = !pin.description; lbLink.href = pin.link; lbCounter.textContent = (lbPos + 1) + ' / ' + filtered.length; lbCounter.hidden = !many; lbPrev.hidden = !many; lbNext.hidden = !many; lbImg.alt = pin.title; // Try the full-size image first, then the thumbnail. Every handler checks loadId, // so a late event from a previous pin can never affect the current one. const full = upgradePinUrl(pin.imgFull, '736x'); const sources = full === pin.img ? [full] : [full, pin.img]; let attempt = 0; lbImg.onload = () => { if (loadId === lbLoadId) lbMedia.classList.add('is-loaded'); }; lbImg.onerror = () => { if (loadId !== lbLoadId) return; attempt += 1; if (attempt !el.hidden && !el.disabled && el.getClientRects().length > 0); if (!focusable.length) return; const first = focusable[0]; const last = focusable[focusable.length - 1]; if (!lbEl.contains(document.activeElement)) { e.preventDefault(); first.focus(); } else if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); } else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); } } lbClose.addEventListener('click', () => closeLightbox()); lbCloseBtn.addEventListener('click', () => closeLightbox()); lbPrev.addEventListener('click', () => openLightbox(lbPos - 1)); lbNext.addEventListener('click', () => openLightbox(lbPos + 1)); lbEl.addEventListener('click', (e) => { if (e.target === lbEl) closeLightbox(); }); document.addEventListener('keydown', (e) => { if (!isOpen()) return; switch (e.key) { case 'Escape': e.preventDefault(); closeLightbox(); break; case 'ArrowLeft': if (filtered.length > 1) { e.preventDefault(); openLightbox(lbPos - 1); } break; case 'ArrowRight': if (filtered.length > 1) { e.preventDefault(); openLightbox(lbPos + 1); } break; case 'Tab': trapFocus(e); break; default: break; } }); /* Cards */ function buildCard(pin, pos) { const media = h('span', { class: 'ipf-pin-media' }, h('span', { class: 'ipf-pin-skel' }, icon('photo-off'))); // alt="" because the title is right below; a duplicate alt would be read twice. const img = h('img', { class: 'ipf-pin-img', alt: '', decoding: 'async', width: 474, height: 632 }); img.addEventListener('load', () => media.classList.add('is-loaded'), { once: true }); img.addEventListener('error', () => media.classList.add('is-error'), { once: true }); media.append(img); img.src = upgradePinUrl(pin.img, '474x'); const label = pin.title || 'Untitled pin'; const openBtn = h('button', { class: 'ipf-pin-open', type: 'button', 'aria-haspopup': 'dialog', onclick: () => openLightbox(pos) }, media, h('span', { class: 'ipf-pin-title', text: label })); const viewLink = h('a', { class: 'ipf-pin-view', href: pin.link, target: '_blank', rel: 'noopener noreferrer', 'aria-label': 'View pin: ' + label }, icon('external'), 'View pin'); // A real link, so it still works if popups are blocked or JS fails. const saveLink = h('a', { class: 'ipf-pin-save', href: saveUrlFor(pin), target: '_blank', rel: 'noopener noreferrer', 'aria-label': 'Save: ' + label + ' to Pinterest' }, icon('bookmark'), 'Save'); saveLink.addEventListener('click', (e) => { const popup = window.open(saveLink.href, '_blank', 'width=750,height=550'); if (popup) { popup.opener = null; // the Pinterest page gets no handle back to this one e.preventDefault(); } // if blocked, the normal new-tab link behaviour takes over }); return h('li', { class: 'ipf-pin', 'data-pos': pos }, openBtn, h('div', { class: 'ipf-pin-footer' }, viewLink, saveLink)); } function activeChipLabel() { const chip = chips.find((c) => c.getAttribute('data-filter') === activeFilter); return chip ? chip.textContent.trim() : activeFilter; } function buildSkeletonCard() { return h('li', { class: 'ipf-pin is-skeleton', 'aria-hidden': 'true' }, h('span', { class: 'ipf-pin-media' }, h('span', { class: 'ipf-pin-skel' })), h('span', { class: 'ipf-skel-line' }), h('span', { class: 'ipf-skel-line is-short' })); } function buildEmpty() { if (loadState === 'error') { return h('li', { class: 'ipf-empty' }, icon('photo-off'), h('p', { text: 'We couldn’t load our latest pins right now.' }), h('a', { class: 'ipf-empty-action', href: opts.profileUrl, target: '_blank', rel: 'noopener noreferrer' }, 'See them on Pinterest')); } if (!allPins.length) { return h('li', { class: 'ipf-empty' }, icon('empty'), h('p', { text: 'New pins are on their way — check back soon.' }), h('a', { class: 'ipf-empty-action', href: opts.profileUrl, target: '_blank', rel: 'noopener noreferrer' }, 'See our boards on Pinterest')); } return h('li', { class: 'ipf-empty' }, icon('empty'), h('p', { text: 'No ' + activeChipLabel().toLowerCase() + ' pins yet.' }), h('button', { class: 'ipf-empty-action', type: 'button', onclick: () => setFilter('all', { focusChip: true }) }, 'Show all pins')); } /* Rendering */ function renderPage(page, settings) { const cfg = Object.assign({ animate: true, focus: null }, settings || {}); if (loadState === 'loading') { grid.setAttribute('aria-busy', 'true'); grid.replaceChildren(...Array.from({ length: opts.pageSize }, buildSkeletonCard)); pagInfo.textContent = 'Loading pins…'; pagBtns.replaceChildren(); return; } grid.removeAttribute('aria-busy'); const total = filtered.length; const totalPages = Math.ceil(total / opts.pageSize); currentPage = Math.min(Math.max(0, page), Math.max(0, totalPages - 1)); const start = currentPage * opts.pageSize; const slice = filtered.slice(start, start + opts.pageSize); grid.replaceChildren(...(total ? slice.map((pin, i) => buildCard(pin, start + i)) : [buildEmpty()])); if (cfg.animate && !reducedMotion.matches) { grid.classList.add('is-entering'); void grid.offsetWidth; // commit opacity:0 before transitioning back to 1 grid.classList.remove('is-entering'); } if (total) { pagInfo.textContent = 'Showing ' + (start + 1) + '–' + (start + slice.length) + ' of ' + total + (totalPages > 1 ? ' · page ' + (currentPage + 1) + ' of ' + totalPages : ''); } else { pagInfo.textContent = allPins.length ? 'No pins in this filter' : ''; } renderPagination(totalPages); if (cfg.focus) focusPaginationControl(cfg.focus); } function pagesToShow(cur, total) { if (total i); const pages = [0]; if (cur > 2) pages.push('gap'); for (let i = Math.max(1, cur - 1); i <= Math.min(total - 2, cur + 1); i++) pages.push(i); if (cur < total - 3) pages.push('gap'); pages.push(total - 1); return pages; } function renderPagination(totalPages) { pagBtns.replaceChildren(); if (totalPages h('button', { class: 'ipf-pag-btn' + (state.current ? ' is-active' : ''), type: 'button', 'aria-label': label, 'aria-current': state.current ? 'page' : null, 'data-role': role, disabled: !!state.disabled, onclick: onClick }, content); pagBtns.append(makeBtn(icon('chevron-left'), 'Previous page', 'prev', () => renderPage(currentPage - 1, { focus: 'prev' }), { disabled: currentPage === 0 })); pagesToShow(currentPage, totalPages).forEach((p) => { if (p === 'gap') { pagBtns.append(h('span', { class: 'ipf-pag-gap', 'aria-hidden': 'true' }, '…')); } else { pagBtns.append(makeBtn(String(p + 1), 'Page ' + (p + 1), 'page', () => renderPage(p, { focus: 'page' }), { current: p === currentPage })); } }); pagBtns.append(makeBtn(icon('chevron-right'), 'Next page', 'next', () => renderPage(currentPage + 1, { focus: 'next' }), { disabled: currentPage === totalPages - 1 })); } // Buttons are rebuilt on every page change, so put focus back on the matching control. function focusPaginationControl(which) { let target = which === 'page' ? null : pagBtns.querySelector('[data-role="' + which + '"]:not(:disabled)'); if (!target) target = pagBtns.querySelector('[aria-current="page"]'); if (target) target.focus(); } function setFilter(filter, settings) { const cfg = settings || {}; activeFilter = filter; chips.forEach((chip) => { const on = chip.getAttribute('data-filter') === filter; chip.classList.toggle('is-active', on); chip.setAttribute('aria-pressed', String(on)); if (on && cfg.focusChip) chip.focus(); }); filtered = allPins.filter((pin) => matchesFilter(pin, filter)); renderPage(0); } function setPins(pins) { if (isOpen()) closeLightbox(false); loadState = 'ready'; allPins = normalizePins(pins, opts.profileUrl); if (pinCountEl) pinCountEl.textContent = String(allPins.length); // total, not the filtered count // Real pins won't cover every category: hide filter chips that would match nothing. let visibleFilters = 0; chips.forEach((chip) => { const filter = chip.getAttribute('data-filter'); const hasPins = filter === 'all' || allPins.some((pin) => matchesFilter(pin, filter)); chip.hidden = !hasPins; if (hasPins && filter !== 'all') visibleFilters += 1; }); const filterBar = root.querySelector('.ipf-filters'); if (filterBar) filterBar.hidden = visibleFilters === 0; // "All" on its own is pointless const activeChip = chips.find((c) => c.getAttribute('data-filter') === activeFilter); if (!activeChip || activeChip.hidden) activeFilter = 'all'; setFilter(activeFilter); } function showLoadError() { loadState = 'error'; allPins = []; filtered = []; if (pinCountEl) pinCountEl.textContent = '—'; const filterBar = root.querySelector('.ipf-filters'); if (filterBar) filterBar.hidden = true; renderPage(0); } // Fetch pins from the server endpoint (ipanel-pins.php), which reads the Pinterest feed. async function loadPins() { loadState = 'loading'; renderPage(0); const controller = typeof AbortController === 'function' ? new AbortController() : null; const timer = controller ? setTimeout(() => controller.abort(), 15000) : null; try { const res = await fetch(opts.pinsUrl, { headers: { Accept: 'application/json' }, credentials: 'same-origin', signal: controller ? controller.signal : undefined }); const data = await res.json().catch(() => null); if (!res.ok || !data || !Array.isArray(data.pins)) { throw new Error((data && data.error) || 'HTTP ' + res.status); } if (data.stale) console.info('[i-Panel feed] Pinterest is unreachable; showing pins cached at ' + data.updated + '.'); setPins(data.pins); } catch (err) { if (opts.demo) { console.info('[i-Panel feed] ' + opts.pinsUrl + ' unavailable here (' + err.message + ') — showing demo pins (dev/demo mode only).'); setPins(DEMO_PINS); } else { console.error('[i-Panel feed] Could not load pins from ' + opts.pinsUrl + ':', err); showLoadError(); } } finally { if (timer) clearTimeout(timer); } } chips.forEach((chip) => { chip.addEventListener('click', () => setFilter(chip.getAttribute('data-filter'))); }); /* Initial data */ const initial = opts.pins !== undefined ? opts.pins : window.ipnlPins; if (initial != null) { setPins(initial); } else if (opts.pinsUrl) { loadPins(); } else if (opts.demo) { console.info('[i-Panel feed] No pin data — showing demo pins (dev/demo mode only).'); setPins(DEMO_PINS); } else { console.warn('[i-Panel feed] No pin data yet. Define window.ipnlPins or call IPanelFeed.setPins([...]).'); setPins([]); } return { root: root, setPins: setPins, reload: () => (opts.pinsUrl ? loadPins() : undefined), setFilter: (filter) => setFilter(filter), goToPage: (page) => renderPage(page), open: (pos) => openLightbox(pos), close: () => closeLightbox() }; } /* ── Public API ──────────────────────────────────────────── */ const registry = new WeakMap(); const instances = []; function init(root, options) { if (!root) return null; if (registry.has(root)) return registry.get(root); const instance = createFeed(root, options); if (instance) { registry.set(root, instance); instances.push(instance); } return instance; } function autoInit() { document.querySelectorAll('[data-ipf-feed]').forEach((el) => init(el)); } window.IPanelFeed = { init: init, autoInit: autoInit, instances: instances, // Convenience for the common single-feed case: IPanelFeed.setPins(data) setPins: (pins) => instances.forEach((instance) => instance.setPins(pins)) }; if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', autoInit); else autoInit(); })();

    Visual Showcase

    Inspiring Interior
    Gallery Collection

    Explore our collection of stunning visuals that showcase our work. Each image tells a unique story and represents our creative vision in transforming interior spaces.

    Hall of Excellence

    A Legacy of
    Innovation & Trust.

    Recognized globally and locally for pushing the boundaries of sustainable design and mobile user experience.

    2025

    Best Mobile User Experience

    iPanel Wins Best Mobile User Experience Website at BestWeb.LK 2025, recognized for delivering an outstanding and intuitive digital experience.

    2024

    Green Brand of the Year

    Named ‘Green Brand of the Year’ at SLIM Brand Excellence 2024 for our unwavering commitment to sustainable and eco-friendly practices.

    2023

    Green Labeled Product

    Recognized by the Green Building Council of Sri Lanka for outstanding eco-friendly building solutions.

    2016

    ISO 9001

    German Technology certification ensuring international quality standards.

    2015

    Best Innovative Product

    UPVC ceiling and wall panels awarded at the Kadella Exhibition for revolutionary design.

    Begin Your Project with the Original.

    Tell us about your space and our specialists will handle the rest. Whether it’s a private estate, luxury hotel, or commercial development, our team provides tailored material guidance and precision quotations.