<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Garis Lurus — Kontraktor & Desain Bangunan</title>
<meta name="description" content="Kontraktor & desain bangunan area Indonesia: kanopi, desain ritel, masjid, klinik, rumah, cafe, hingga renovasi.">
<link rel="canonical" href="https://kontraktorgarislurus.xyz/">

<!-- Open Graph -->
<meta property="og:type" content="website">
<meta property="og:url" content="https://kontraktorgarislurus.xyz/">
<meta property="og:title" content="Garis Lurus — Kontraktor & Desain Bangunan">
<meta property="og:description" content="Kontraktor & desain bangunan area Indonesia: kanopi, desain ritel, masjid, klinik, rumah, cafe, hingga renovasi.">
<meta property="og:image" content="https://kontraktorgarislurus.xyz/logo.jpg">
<meta property="og:locale" content="id_ID">

<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Garis Lurus — Kontraktor & Desain Bangunan">
<meta name="twitter:description" content="Kontraktor & desain bangunan area Indonesia: kanopi, desain ritel, masjid, klinik, rumah, cafe, hingga renovasi.">
<meta name="twitter:image" content="https://kontraktorgarislurus.xyz/logo.jpg">

<!-- Structured Data -->
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "GeneralContractor",
  "name": "Garis Lurus",
  "url": "https://kontraktorgarislurus.xyz/",
  "image": "https://kontraktorgarislurus.xyz/logo.jpg",
  "description": "Kontraktor & desain bangunan: kanopi, desain ritel, masjid, klinik, rumah, cafe, hingga renovasi.",
  "areaServed": "Indonesia",
  "telephone": "+6281717240995"
}
</script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=Work+Sans:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
  :root{
    --bg:#121210;
    --ink:#ECE7DD;
    --ink-soft:#9C968A;
    --line:#2B2924;
    --panel:#1B1A16;
    --accent:#C97C52;
  }
  *{box-sizing:border-box; margin:0; padding:0;}
  html{scroll-behavior:smooth;}
  body{background:var(--bg); color:var(--ink); font-family:'Work Sans', sans-serif; line-height:1.55;}
  img{display:block; max-width:100%;}
  h1,h2,h3,h4{font-family:'Plus Jakarta Sans', sans-serif; letter-spacing:-0.01em; color:var(--ink);}
  a{color:inherit;}
  .mono{font-family:'IBM Plex Mono', monospace;}
  .eyebrow{
    font-family:'IBM Plex Mono', monospace; font-size:.7rem; letter-spacing:.14em;
    text-transform:uppercase; color:var(--ink-soft); display:flex; align-items:center; gap:8px; margin-bottom:12px;
  }
  .eyebrow::before{content:''; width:16px; height:1px; background:var(--ink-soft);}
  .wrap{max-width:1320px; margin:0 auto; padding:0 clamp(24px, 5vw, 80px);}

  /* ===== PRELOADER ===== */
  #preloader{
    position:fixed; inset:0; z-index:9999; background:var(--bg); display:flex; flex-direction:column;
    align-items:center; justify-content:center; transition:opacity .6s ease, visibility .6s ease;
  }
  #preloader.hide{opacity:0; visibility:hidden; pointer-events:none;}
  .pl-line-wrap{position:relative; width:min(60vw, 320px); height:2px;}
  .pl-line{position:absolute; top:0; height:2px; background:var(--ink);}
  .pl-line.left{left:0; width:50%; transform-origin:left center; transform:scaleX(0); animation:plGrowLeft .8s cubic-bezier(.65,0,.35,1) forwards;}
  .pl-line.right{right:0; width:50%; transform-origin:right center; transform:scaleX(0); animation:plGrowRight .8s cubic-bezier(.65,0,.35,1) forwards;}
  @keyframes plGrowLeft{ to{transform:scaleX(1);} }
  @keyframes plGrowRight{ to{transform:scaleX(1);} }
  .pl-text{
    margin-top:22px; font-family:'Plus Jakarta Sans',sans-serif; font-weight:800; font-size:1.05rem;
    letter-spacing:.32em; color:var(--ink); text-transform:uppercase; opacity:0; transform:translateY(8px);
    animation:plTextIn .6s ease forwards .8s;
  }
  @keyframes plTextIn{ to{opacity:1; transform:none;} }
  @media(prefers-reduced-motion:reduce){
    .pl-line.left, .pl-line.right{animation:none; transform:scaleX(1);}
    .pl-text{animation:none; opacity:1; transform:none;}
  }

  /* ===== NAV ===== */
  header{border-bottom:1px solid var(--line);}
  nav{display:flex; align-items:center; justify-content:space-between; padding:24px 5vw;}
  .brand{font-family:'Plus Jakarta Sans',sans-serif; font-weight:800; font-size:1.02rem; letter-spacing:.06em; display:flex; align-items:center; gap:14px; text-transform:uppercase;}
  .brand .mark{width:150px; height:42px; overflow:hidden; display:flex; align-items:center; justify-content:center; flex-shrink:0;}
  .brand .mark img{width:100%; height:100%; object-fit:cover; object-position:center 44%;}
  .navlinks{display:flex; gap:32px; font-size:.86rem; font-weight:500;}
  .navlinks a{text-decoration:none; color:var(--ink-soft); transition:color .2s;}
  .navlinks a:hover{color:var(--ink);}
  @media(max-width:860px){.navlinks{display:none;}}

  .btn-dark{
    background:var(--ink); color:var(--bg); padding:15px 30px; border-radius:6px; text-decoration:none;
    font-weight:600; font-size:.88rem; display:inline-block; transition:background .25s, transform .25s;
  }
  .btn-dark:hover{background:var(--accent); color:#fff; transform:translateY(-2px);}
  .btn-accent{
    background:var(--accent); color:#fff; padding:15px 30px; border-radius:6px; text-decoration:none;
    font-weight:600; font-size:.88rem; display:inline-block; transition:background .25s, transform .25s;
  }
  .btn-accent:hover{background:#9A4A30; transform:translateY(-2px);}

  /* ===== HERO — full-bleed background photo ===== */
  .hero{
    position:relative; min-height:82vh; display:flex; align-items:flex-end;
    background:
      linear-gradient(180deg, rgba(12,12,10,.35) 0%, rgba(12,12,10,.72) 78%, rgba(12,12,10,.82) 100%),
      url('images/bg/background.jpg') center/cover no-repeat;
  }
  .hero-inner{padding:10vh 0 9vh; position:relative; z-index:1;}
  .hero-eyebrow{color:#E7C9A9;}
  .hero-eyebrow::before{background:#E7C9A9;}
  .hero h1{font-size:clamp(2.3rem,4.4vw,3.7rem); font-weight:700; line-height:1.08; max-width:16ch; margin-bottom:20px; color:#fff;}
  .hero-desc{color:#D8D4CB; font-size:1rem; max-width:52ch; margin-bottom:32px; line-height:1.65;}
  .hero-actions{display:flex; align-items:center; gap:20px; flex-wrap:wrap;}
  .hero-phone{font-family:'IBM Plex Mono',monospace; font-size:.82rem; color:#D8D4CB;}
  @media(max-width:640px){.hero{min-height:72vh;}}

  /* ===== ABOUT / WHY-US (shared split-section style) ===== */
  .split-section{padding:9vh 0; border-top:1px solid var(--line); display:grid; grid-template-columns:.9fr 1.1fr; gap:50px; align-items:center;}
  .split-section.reverse{grid-template-columns:1.1fr .9fr;}
  .split-section.reverse .split-photo{order:2;}
  @media(max-width:760px){.split-section, .split-section.reverse{grid-template-columns:1fr;} .split-section.reverse .split-photo{order:0;}}
  .split-photo{aspect-ratio:4/3.4; border-radius:4px; overflow:hidden;}
  .split-photo img{width:100%; height:100%; object-fit:cover;}
  .split-section h2{font-size:clamp(1.7rem,2.8vw,2.3rem); font-weight:700; margin-bottom:18px; max-width:18ch;}
  .split-section p{color:var(--ink-soft); margin-bottom:14px; font-size:.98rem;}

  /* ===== LAYANAN (chips) ===== */
  .services-section{padding:8vh 0; border-top:1px solid var(--line);}
  .services-section .head{max-width:56ch; margin-bottom:32px;}
  .services-section h2{font-size:clamp(1.6rem,2.6vw,2.1rem); font-weight:700;}
  .chip-row{display:flex; flex-wrap:wrap; gap:12px;}
  .chip{
    font-family:'IBM Plex Mono',monospace; font-size:.82rem; padding:12px 20px; border:1px solid var(--line);
    border-radius:100px; color:var(--ink); transition:border-color .2s, background .2s;
  }
  .chip:hover{border-color:var(--ink); background:var(--panel);}

  /* ===== REKAM JEJAK (stat strip) ===== */
  .stat-strip{border-top:1px solid var(--line); border-bottom:1px solid var(--line); padding:5vh 0; display:flex; flex-wrap:wrap;}
  .stat-strip .stat{flex:1; min-width:160px; padding:10px 24px; border-left:1px solid var(--line);}
  .stat-strip .stat:first-child{border-left:none; padding-left:0;}
  .stat-strip .n{font-family:'Plus Jakarta Sans',sans-serif; font-weight:800; font-size:2rem;}
  .stat-strip .l{font-size:.76rem; color:var(--ink-soft); font-family:'IBM Plex Mono',monospace; text-transform:uppercase; letter-spacing:.04em; margin-top:4px;}

  /* ===== PROJECTS ===== */
  .projects{padding:9vh 0 10vh; border-top:1px solid var(--line);}
  .proj-head{display:flex; justify-content:space-between; align-items:flex-end; flex-wrap:wrap; gap:20px; margin-bottom:36px;}
  .proj-head h2{font-size:clamp(1.7rem,2.8vw,2.3rem); font-weight:700;}
  .filter-row{display:flex; gap:22px; font-family:'IBM Plex Mono',monospace; font-size:.78rem; flex-wrap:wrap;}
  .filter-btn{background:none; border:none; color:var(--ink-soft); cursor:pointer; padding:0; text-transform:uppercase; letter-spacing:.03em; border-bottom:1.5px solid transparent; padding-bottom:4px; transition:all .2s;}
  .filter-btn.active, .filter-btn:hover{color:var(--ink); border-color:var(--ink);}

  .proj-grid{display:grid; grid-template-columns:repeat(4,1fr); gap:18px;}
  @media(max-width:920px){.proj-grid{grid-template-columns:1fr 1fr;}}
  @media(max-width:520px){.proj-grid{grid-template-columns:1fr;}}
  .proj-card{cursor:pointer;}
  .proj-thumb{position:relative; aspect-ratio:3/3.6; overflow:hidden; border-radius:4px; background:var(--panel);}
  .proj-thumb img{width:100%; height:100%; object-fit:cover; transition:transform .5s;}
  .proj-card:hover .proj-thumb img{transform:scale(1.05);}
  .proj-count{position:absolute; top:10px; right:10px; background:rgba(22,22,22,.7); color:#fff; font-family:'IBM Plex Mono',monospace; font-size:.64rem; padding:4px 9px; border-radius:100px;}
  .proj-info{padding-top:14px;}
  .proj-info .loc{font-family:'IBM Plex Mono',monospace; font-size:.66rem; text-transform:uppercase; color:var(--ink-soft); letter-spacing:.04em; margin-bottom:5px;}
  .proj-info h3{font-size:.98rem; font-weight:700; margin-bottom:6px; line-height:1.3;}
  .proj-info .view{font-size:.8rem; color:var(--accent); font-weight:600;}

  /* ===== TIPE RUMAH ===== */
  .house-grid{display:grid; grid-template-columns:repeat(3,1fr); gap:18px;}
  @media(max-width:920px){.house-grid{grid-template-columns:1fr 1fr;}}
  @media(max-width:520px){.house-grid{grid-template-columns:1fr;}}

  /* ===== CTA STRIP ===== */
  .cta-strip{
    padding:12vh 5vw; text-align:center; position:relative;
    background:
      linear-gradient(180deg, rgba(10,10,10,.68) 0%, rgba(10,10,10,.82) 100%),
      url('images/bg/cta.jpg') center/cover no-repeat;
  }
  .cta-strip .eyebrow{color:#E7C9A9;}
  .cta-strip .eyebrow::before{background:#E7C9A9;}
  .cta-strip h2{color:#fff; font-size:clamp(1.8rem,3.4vw,2.6rem); max-width:22ch; margin:0 auto 16px; font-weight:700;}
  .cta-strip p{color:#D8D4CB; max-width:44ch; margin:0 auto 28px; font-size:.98rem;}

  /* ===== FOOTER ===== */
  footer{border-top:1px solid var(--line); padding:5vh 5vw;}
  .footer-row{display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:16px;}
  .footer-left{display:flex; align-items:center; gap:14px; font-size:.84rem; color:var(--ink-soft);}
  .social-row{display:flex; gap:10px;}
  .social-row a{
    width:34px; height:34px; border:1px solid var(--line); border-radius:50%; display:flex; align-items:center; justify-content:center;
    text-decoration:none; color:var(--ink); transition:all .2s;
  }
  .social-row a:hover{background:var(--ink); color:var(--bg); border-color:var(--ink);}

  /* ===== FLOATING ===== */
  .wa-float{
    position:fixed; right:20px; bottom:20px; z-index:45; background:#25D366; color:#fff; width:52px; height:52px;
    border-radius:50%; display:flex; align-items:center; justify-content:center; text-decoration:none;
    box-shadow:0 8px 22px rgba(37,211,102,.4); transition:transform .25s;
  }
  .wa-float:hover{transform:translateY(-4px) scale(1.05);}

  /* ===== LIGHTBOX ===== */
  .lightbox{position:fixed; inset:0; z-index:100; background:rgba(10,10,10,.96); display:none; align-items:center; justify-content:center; padding:5vh 4vw;}
  .lightbox.open{display:flex;}
  .lightbox .lb-grid-view, .lightbox .lb-single-view{display:none;}
  .lightbox.mode-grid .lb-grid-view{display:block;}
  .lightbox.mode-single .lb-single-view{display:block;}

  /* -- grid gallery view -- */
  .lb-grid-view{width:100%; max-width:1140px; max-height:88vh; overflow-y:auto; color:#fff; padding-right:4px;}
  .lb-grid-header{display:flex; justify-content:space-between; align-items:center; padding-bottom:20px; padding-right:110px; border-bottom:1px solid rgba(255,255,255,.15); margin-bottom:24px; position:sticky; top:0; background:rgba(10,10,10,.96);}
  .lb-grid-title{font-family:'Plus Jakarta Sans',sans-serif; font-weight:700; font-size:1.5rem;}
  .lb-grid{display:grid; grid-template-columns:repeat(4,1fr); gap:14px;}
  @media(max-width:760px){.lb-grid{grid-template-columns:repeat(2,1fr);}}
  .lb-grid-item{position:relative; aspect-ratio:1/1; overflow:hidden; border-radius:6px; cursor:pointer;}
  .lb-grid-item img{width:100%; height:100%; object-fit:cover; transition:transform .3s;}
  .lb-grid-item:hover img{transform:scale(1.06);}
  .lb-grid-num{position:absolute; bottom:8px; right:8px; background:rgba(0,0,0,.6); color:#fff; font-family:'IBM Plex Mono',monospace; font-size:.7rem; padding:3px 9px; border-radius:4px;}

  /* -- single photo view -- */
  .lb-single-view{max-width:900px; width:100%;}
  .lb-imgwrap{position:relative; background:#000; border-radius:8px; overflow:hidden; aspect-ratio:16/10; display:flex; align-items:center; justify-content:center;}
  .lb-imgwrap img{width:100%; height:100%; object-fit:contain; background:#0d0d0d;}
  .lb-meta{display:flex; justify-content:space-between; align-items:center; margin-top:16px; color:#EDEAE2; flex-wrap:wrap; gap:10px;}
  .lb-title{font-family:'Plus Jakarta Sans',sans-serif; font-weight:700; font-size:1.05rem;}
  .lb-counter{font-family:'IBM Plex Mono',monospace; font-size:.78rem; color:#B0B0B0;}
  .lb-nav{position:absolute; top:0; bottom:0; width:60px; display:flex; align-items:center; justify-content:center; cursor:pointer; color:#fff; font-size:1.6rem; background:transparent; border:none;}
  .lb-prev{left:0;} .lb-next{right:0;}
  .lb-nav:hover{background:rgba(255,255,255,.08);}
  .lb-close{position:fixed; top:20px; right:24px; z-index:150; background:rgba(0,0,0,.78); color:#fff; border:1px solid rgba(255,255,255,.28); padding:12px 24px; border-radius:999px; font-family:'Plus Jakarta Sans',sans-serif; font-weight:600; font-size:.85rem; cursor:pointer; backdrop-filter:blur(4px); display:none;}
  .lb-close:hover{background:rgba(0,0,0,.92); border-color:rgba(255,255,255,.45);}
  .lightbox.mode-grid .lb-close-grid{display:block;}
  .lightbox.mode-single .lb-close-single{display:block;}
  @media(max-width:600px){.lb-close{top:14px; right:14px; padding:11px 20px; font-size:.8rem;}}

  .reveal{opacity:0; transform:translateY(20px); transition:opacity .6s ease, transform .6s ease;}
  .reveal.show{opacity:1; transform:none;}
  @media(prefers-reduced-motion:reduce){.reveal{opacity:1; transform:none; transition:none;}}
</style>
</head>
<body>

<div id="preloader">
  <div class="pl-line-wrap">
    <div class="pl-line left"></div>
    <div class="pl-line right"></div>
  </div>
  <div class="pl-text">Garis Lurus</div>
</div>

<header>
  <nav class="wrap" style="padding-top:24px; padding-bottom:24px;">
    <div class="brand"><div class="mark"><img src="logo.jpg" alt="Garis Lurus"></div>Garis Lurus</div>
    <div class="navlinks">
      <a href="#beranda">Home</a>
      <a href="#tentang">About</a>
      <a href="#proyek">Projects</a>
      <a href="#tipe-rumah">Type Rumah</a>
      <a href="#kontak">Contact</a>
    </div>
  </nav>
</header>

<section class="hero" id="beranda">
  <div class="wrap hero-inner">
    <div class="eyebrow hero-eyebrow">Kontraktor &amp; Desain Bangunan</div>
    <h1>Kontraktor dengan pendekatan yang berbeda.</h1>
    <p class="hero-desc">Desain dan konstruksi ditangani satu tim yang sama — dari sketsa awal sampai serah terima kunci, didokumentasikan penuh di setiap tahap.</p>
    <div class="hero-actions">
      <a class="btn-accent" href="#proyek">Our Projects</a>
      <span class="hero-phone">(+62) 817-1724-0995</span>
    </div>
  </div>
</section>

<div class="wrap">

  <section class="projects" id="tipe-rumah">
    <div class="proj-head">
      <div>
        <div class="eyebrow">Type Rumah</div>
        <h2>Pilihan Type Rumah</h2>
        <p style="margin-top:14px; max-width:56ch; color:#8a8a8a;">Beberapa type rumah yang telah kami kerjakan, siap disesuaikan dengan kebutuhan Anda.</p>
      </div>
      <a class="btn-dark" href="#proyek">Lihat Hasil Kerja Kami ↓</a>
    </div>
    <div class="house-grid" id="houseGrid"></div>
  </section>

</div>

<div class="wrap">

  <section class="split-section" id="tentang">
    <div class="split-photo">
      <img src="https://images.unsplash.com/photo-1449844908441-8829872d2607?w=900&q=80&auto=format&fit=crop" alt="Desain bangunan" loading="lazy">
    </div>
    <div class="reveal">
      <div class="eyebrow">About Us</div>
      <h2>Sebuah pendekatan berbeda dalam desain dan konstruksi.</h2>
      <p>Kami menangani desain dan pengerjaan berbagai jenis bangunan — dari kanopi rumah, ruang usaha, tempat ibadah, klinik, sampai renovasi kamar — untuk seluruh Indonesia.</p>
      <p>Setiap proyek didokumentasikan dari awal sampai selesai, supaya calon klien bisa melihat sendiri bagaimana proses pengerjaannya berjalan di lapangan.</p>
    </div>
  </section>

  <section class="split-section reverse">
    <div class="split-photo">
      <img src="https://images.unsplash.com/photo-1518005020951-eccb494ad742?w=900&q=80&auto=format&fit=crop" alt="Kenapa pilih kami" loading="lazy">
    </div>
    <div class="reveal">
      <div class="eyebrow">Why Choose Us</div>
      <h2>Satu tim untuk desain dan pelaksanaan.</h2>
      <p>Desain dan pengerjaan lapangan ditangani tim yang sama, jadi gambar yang disepakati adalah yang benar-benar dibangun — bukan lempar tanggung jawab ke pihak lain.</p>
    </div>
  </section>

  <div class="stat-strip reveal">
    <div class="stat"><div class="n">13</div><div class="l">Jenis Proyek</div></div>
    <div class="stat"><div class="n">111</div><div class="l">Dokumentasi Foto</div></div>
    <div class="stat"><div class="n">Indonesia</div><div class="l">Area Kerja</div></div>
  </div>

  <section class="projects" id="proyek">
    <div class="proj-head">
      <div>
        <div class="eyebrow">Portfolio</div>
        <h2>Our Projects</h2>
      </div>
      <div class="filter-row" id="filterRow"></div>
    </div>
    <div class="proj-grid" id="projGrid"></div>
  </section>

</div>

<section class="cta-strip" id="kontak">
  <div class="eyebrow" style="justify-content:center;">Konsultasi Gratis</div>
  <h2>Ada rencana bangun atau renovasi? Ceritakan ke kami.</h2>
  <p>Ceritakan lokasi dan rencana bangun lo, kami balas via WhatsApp.</p>
  <a class="btn-accent" href="https://wa.me/6281717240995" target="_blank" rel="noopener">Chat via WhatsApp</a>
</section>

<footer>
  <div class="wrap footer-row">
    <div class="footer-left">
      <div class="brand"><div class="mark"><img src="logo.jpg" alt="Garis Lurus"></div>Garis Lurus</div>
      <span>© 2026</span>
    </div>
    <div class="social-row">
      <a href="#" target="_blank" rel="noopener" aria-label="Instagram">
        <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="2" width="20" height="20" rx="5"/><circle cx="12" cy="12" r="4"/><circle cx="17.5" cy="6.5" r="1"/></svg>
      </a>
    </div>
  </div>
</footer>

<a class="wa-float" href="https://wa.me/6281717240995?text=Halo%2C%20saya%20ingin%20konsultasi" target="_blank" rel="noopener" aria-label="Chat WhatsApp">
  <svg width="24" height="24" viewBox="0 0 24 24" fill="#fff"><path d="M17.5 14.4c-.3-.1-1.7-.8-2-.9-.3-.1-.5-.1-.7.1-.2.3-.8.9-.9 1.1-.2.2-.3.2-.6.1-.3-.1-1.3-.5-2.4-1.5-.9-.8-1.5-1.8-1.7-2.1-.2-.3 0-.5.1-.6.1-.1.3-.3.4-.5.1-.1.2-.3.3-.4.1-.2 0-.3 0-.5s-.7-1.7-1-2.3c-.2-.6-.5-.5-.7-.5h-.6c-.2 0-.5.1-.8.3-.3.3-1 1-1 2.4s1 2.8 1.2 3c.1.2 2 3.1 4.9 4.3.7.3 1.2.5 1.6.6.7.2 1.3.2 1.8.1.5-.1 1.7-.7 1.9-1.3.2-.7.2-1.2.2-1.3-.1-.1-.3-.2-.6-.3z"/><path d="M12 2C6.5 2 2 6.5 2 12c0 1.9.5 3.6 1.5 5.1L2 22l5-1.5c1.4.8 3.1 1.2 5 1.2 5.5 0 10-4.5 10-10S17.5 2 12 2zm0 18c-1.7 0-3.3-.5-4.6-1.3l-.3-.2-3 .9.9-2.9-.2-.3C4 15 3.5 13.5 3.5 12c0-4.7 3.8-8.5 8.5-8.5s8.5 3.8 8.5 8.5-3.8 8.5-8.5 8.5z"/></svg>
</a>

<div class="lightbox" id="lightbox">
  <button class="lb-close lb-close-grid" id="lbGridClose" aria-label="Tutup">Tutup</button>
  <button class="lb-close lb-close-single" id="lbSingleClose" aria-label="Kembali ke galeri">Kembali</button>
  <div class="lb-grid-view">
    <div class="lb-grid-header">
      <div class="lb-grid-title" id="lbGridTitle"></div>
    </div>
    <div class="lb-grid" id="lbGrid"></div>
  </div>
  <div class="lb-single-view">
    <div class="lb-imgwrap">
      <button class="lb-nav lb-prev" id="lbPrev">‹</button>
      <img id="lbImg" src="" alt="">
      <button class="lb-nav lb-next" id="lbNext">›</button>
    </div>
    <div class="lb-meta">
      <div class="lb-title" id="lbTitle"></div>
      <div class="lb-counter" id="lbCounter"></div>
    </div>
  </div>
</div>

<script>
  const PROJECTS = [
    { slug:'kanopi-brebes', title:'Pemasangan Kanopi Brebes', tag:'Kanopi', location:'Brebes', count:7, ext:'jpeg', folder:'Kanopi parkiran brebes 2023' },
    { slug:'indomaret-brebes', title:'Desain Indomaret Brebes', tag:'Ritel', location:'Brebes', count:5, ext:'jpg', folder:'Indomaret brebes 2024' },
    { slug:'masjid-lebaksiu', title:'Desain Masjid Lebaksiu', tag:'Ibadah', location:'Tegal', count:9, ext:'jpg', folder:'Desain masjid lebaksiu 2024' },
    { slug:'klinik-sidapurna', title:'Desain Klinik Sidapurna', tag:'Klinik', location:'Tegal', count:5, ext:'jpg', folder:'Desain klinik sidapurna 2025' },
    { slug:'desain-talang', title:'Desain Rumah Talang', tag:'Residensial', location:'Talang', count:4, ext:'jpg', folder:'Desain Rumah Talang 2025' },
    { slug:'cafe-adw', title:'Pembangunan Caffe Adiwerna', tag:'Bangun Baru', location:'Adiwerna, Tegal', count:17, ext:'jpeg', folder:'Pembangunan caffe adiwerna 2025' },
    { slug:'kamartdr-adiwerna', title:'Renovasi Kamar Tidur Adiwerna', tag:'Renovasi', location:'Adiwerna, Tegal', count:9, ext:'jpeg', folder:'Renovasi kamar tidur adiwerna 2025' },
    { slug:'smp', title:'Renovasi SMP Ketanggungan', tag:'Renovasi', location:'Brebes', count:10, ext:'jpg', folder:'Renovasi SMP ketanggunan brebes 2021' },
    { slug:'sengon', title:'Pasar Sengon', tag:'Pasar', location:'Brebes', count:12, ext:'jpeg', folder:'Pasar sengon brebes 2022' },
    { slug:'pasar', title:'Pasar Kersana', tag:'Pasar', location:'Brebes', count:6, ext:'jpeg', folder:'Pasar Kersana brebes 2022' },
    { slug:'musholla', title:'Renovasi Musholla & Toilet Sengon', tag:'Renovasi', location:'Sengon, Brebes', count:6, ext:'jpeg', folder:'Renovasi musholla dan toilet sengon brebes' },
    { slug:'tembok', title:'Desain Rumah Tembok', tag:'Residensial', location:'Adiwerna, Tegal', count:3, ext:'jpeg', folder:'Desain rumah tembok adiwerna tegal' },
    { slug:'pager', title:'Pager Panel Warureja', tag:'Pagar', location:'Warureja, Tegal', count:18, ext:'jpeg', folder:'Pager panel warureja tegal 2026' },
  ];

  const HOUSE_TYPES = [
    { slug:'scan', title:'Scandinavian', spec:'Ganti sesuai spesifikasi', count:11, ext:'jpg', folder:'type rumah' },
    { slug:'clas', title:'Classic', spec:'Ganti sesuai spesifikasi', count:11, ext:'jpg', folder:'type rumah' },
    { slug:'min', title:'Minimalis', spec:'Ganti sesuai spesifikasi', count:18, ext:'jpg', folder:'type rumah' },
    { slug:'japan', title:'Japandi', spec:'Ganti sesuai spesifikasi', count:11, ext:'jpg', folder:'type rumah' },
    { slug:'indus', title:'Industrial', spec:'Ganti sesuai spesifikasi', count:14, ext:'jpg', folder:'type rumah' },
  ];

  function photoUrl(p, i){ return 'images/' + encodeURIComponent(p.folder) + '/' + p.slug + i + '.' + p.ext; }

  const filterRow = document.getElementById('filterRow');
  filterRow.innerHTML = '<button class="filter-btn active" data-filter="all">All</button>' +
    [...new Set(PROJECTS.map(p=>p.tag))].map(tag => `<button class="filter-btn" data-filter="${tag}">${tag}</button>`).join('');

  const projGrid = document.getElementById('projGrid');
  function renderProjects(filter){
    const list = filter === 'all' ? PROJECTS : PROJECTS.filter(p => p.tag === filter);
    projGrid.innerHTML = list.map(p => `
      <div class="proj-card reveal show" data-slug="${p.slug}">
        <div class="proj-thumb">
          <span class="proj-count">${p.count} Foto</span>
          <img src="${photoUrl(p,1)}" alt="${p.title}" loading="lazy">
        </div>
        <div class="proj-info">
          <div class="loc">${p.location}</div>
          <h3>${p.title}</h3>
          <div class="view">View the Project →</div>
        </div>
      </div>
    `).join('');
    document.querySelectorAll('.proj-card').forEach(card => {
      card.addEventListener('click', () => openLightbox(card.dataset.slug));
    });
  }
  renderProjects('all');

  const houseGrid = document.getElementById('houseGrid');
  houseGrid.innerHTML = HOUSE_TYPES.map(h => `
    <div class="proj-card reveal show" data-slug="${h.slug}">
      <div class="proj-thumb">
        <span class="proj-count">${h.count} Foto</span>
        <img src="${photoUrl(h,1)}" alt="${h.title}" loading="lazy">
      </div>
      <div class="proj-info">
        <h3>${h.title}</h3>
        <div class="view">Lihat Foto →</div>
      </div>
    </div>
  `).join('');
  document.querySelectorAll('#houseGrid .proj-card').forEach(card => {
    card.addEventListener('click', () => openLightbox(card.dataset.slug, HOUSE_TYPES));
  });

  filterRow.addEventListener('click', (e) => {
    if(!e.target.matches('.filter-btn')) return;
    document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
    e.target.classList.add('active');
    renderProjects(e.target.dataset.filter);
  });

  const lightbox = document.getElementById('lightbox');
  const lbGridTitle = document.getElementById('lbGridTitle');
  const lbGrid = document.getElementById('lbGrid');
  const lbImg = document.getElementById('lbImg');
  const lbTitle = document.getElementById('lbTitle');
  const lbCounter = document.getElementById('lbCounter');
  let currentProject = null, currentIndex = 1;

  function openLightbox(slug, list){
    currentProject = (list || PROJECTS).find(p => p.slug === slug);
    renderGrid();
    lightbox.classList.add('open', 'mode-grid');
    lightbox.classList.remove('mode-single');
    document.body.style.overflow = 'hidden';
  }
  function renderGrid(){
    lbGridTitle.textContent = 'Galeri — ' + currentProject.title;
    const indices = Array.from({length: currentProject.count}, (_, i) => i + 1);
    lbGrid.innerHTML = indices.map(i => `
      <div class="lb-grid-item" data-index="${i}">
        <img src="${photoUrl(currentProject, i)}" alt="${currentProject.title} - foto ${i}" loading="lazy">
        <span class="lb-grid-num">${i}</span>
      </div>
    `).join('');
    document.querySelectorAll('.lb-grid-item').forEach(item => {
      item.addEventListener('click', () => openSingle(parseInt(item.dataset.index, 10)));
    });
  }
  function openSingle(index){
    currentIndex = index;
    updateSingle();
    lightbox.classList.remove('mode-grid');
    lightbox.classList.add('mode-single');
  }
  function backToGrid(){
    lightbox.classList.remove('mode-single');
    lightbox.classList.add('mode-grid');
  }
  function closeLightbox(){ lightbox.classList.remove('open'); document.body.style.overflow = ''; }
  function updateSingle(){
    lbImg.src = photoUrl(currentProject, currentIndex);
    lbImg.alt = currentProject.title + ' - foto ' + currentIndex;
    lbTitle.textContent = currentProject.title;
    lbCounter.textContent = currentIndex + ' / ' + currentProject.count;
  }
  function nextPhoto(){ currentIndex = currentIndex >= currentProject.count ? 1 : currentIndex + 1; updateSingle(); }
  function prevPhoto(){ currentIndex = currentIndex <= 1 ? currentProject.count : currentIndex - 1; updateSingle(); }

  document.getElementById('lbGridClose').addEventListener('click', closeLightbox);
  document.getElementById('lbSingleClose').addEventListener('click', backToGrid);
  document.getElementById('lbNext').addEventListener('click', nextPhoto);
  document.getElementById('lbPrev').addEventListener('click', prevPhoto);
  lightbox.addEventListener('click', (e) => { if(e.target === lightbox) closeLightbox(); });
  document.addEventListener('keydown', (e) => {
    if(!lightbox.classList.contains('open')) return;
    if(e.key === 'Escape'){
      if(lightbox.classList.contains('mode-single')) backToGrid();
      else closeLightbox();
    }
    if(lightbox.classList.contains('mode-single')){
      if(e.key === 'ArrowRight') nextPhoto();
      if(e.key === 'ArrowLeft') prevPhoto();
    }
  });

  const io = new IntersectionObserver((entries) => {
    entries.forEach(e => { if(e.isIntersecting){ e.target.classList.add('show'); io.unobserve(e.target); } });
  }, {threshold:.12});
  document.querySelectorAll('.reveal').forEach(el => io.observe(el));

  // ====== PRELOADER ======
  const preloader = document.getElementById('preloader');
  const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  document.body.style.overflow = 'hidden';
  const holdTime = reduceMotion ? 200 : 1900; // total waktu sebelum preloader mulai fade out
  setTimeout(() => {
    preloader.classList.add('hide');
    document.body.style.overflow = '';
  }, holdTime);
</script>
</body>
</html>
