Files
D1041231077-webgis/landing/index.html
T
2026-06-10 00:49:56 +07:00

869 lines
38 KiB
HTML

<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebGIS Pontianak — Portfolio Proyek</title>
<meta name="description" content="Kumpulan proyek WebGIS Kota Pontianak — Kepadatan Penduduk, SPBU, dan Distribusi Bantuan Sosial.">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg-primary: #f8fafc;
--bg-card: #ffffff;
--bg-card-hover: #ffffff;
--border: #e2e8f0;
--border-hover: #cbd5e1;
--text: #0f172a;
--text-muted: #475569;
--text-dim: #64748b;
--accent-1: #0891b2;
--accent-2: #7c3aed;
--accent-3: #d97706;
--accent-4: #059669;
--font: 'Inter', -apple-system, system-ui, sans-serif;
--mono: 'DM Mono', monospace;
}
html { scroll-behavior: smooth; }
body {
font-family: var(--font);
background: var(--bg-primary);
color: var(--text);
min-height: 100vh;
overflow-x: hidden;
}
/* =========================================
AMBIENT BACKGROUND
========================================= */
.bg-ambient {
position: fixed; inset: 0; z-index: 0; pointer-events: none;
overflow: hidden;
}
.bg-orb {
position: absolute;
border-radius: 50%;
filter: blur(120px);
opacity: 0.08;
animation: orbFloat 20s ease-in-out infinite;
}
.bg-orb:nth-child(1) {
width: 600px; height: 600px;
background: var(--accent-1);
top: -10%; left: -10%;
animation-delay: 0s;
}
.bg-orb:nth-child(2) {
width: 500px; height: 500px;
background: var(--accent-2);
bottom: -10%; right: -5%;
animation-delay: -7s;
}
.bg-orb:nth-child(3) {
width: 400px; height: 400px;
background: var(--accent-3);
top: 40%; left: 50%;
animation-delay: -14s;
}
@keyframes orbFloat {
0%, 100% { transform: translate(0, 0) scale(1); }
33% { transform: translate(30px, -40px) scale(1.05); }
66% { transform: translate(-20px, 30px) scale(0.95); }
}
/* Grid pattern overlay */
.bg-grid {
position: fixed; inset: 0; z-index: 0; pointer-events: none;
background-image:
linear-gradient(rgba(15, 23, 42, 0.03) 1px, transparent 1px),
linear-gradient(90deg, rgba(15, 23, 42, 0.03) 1px, transparent 1px);
background-size: 60px 60px;
}
/* =========================================
NAVBAR
========================================= */
.navbar {
position: fixed; top: 0; left: 0; right: 0;
z-index: 100;
padding: 16px 40px;
display: flex; align-items: center; justify-content: space-between;
background: rgba(248, 250, 252, 0.8);
backdrop-filter: blur(20px) saturate(1.4);
border-bottom: 1px solid var(--border);
transition: all 0.3s;
}
.navbar.scrolled {
padding: 12px 40px;
background: rgba(255, 255, 255, 0.95);
box-shadow: 0 4px 20px rgba(15, 23, 42, 0.03);
}
.nav-brand {
display: flex; align-items: center; gap: 12px;
}
.nav-logo {
width: 36px; height: 36px;
background: linear-gradient(135deg, var(--accent-1), var(--accent-2));
border-radius: 10px;
display: flex; align-items: center; justify-content: center;
font-size: 18px;
box-shadow: 0 4px 20px rgba(6, 182, 212, 0.3);
}
.nav-title {
font-size: 16px; font-weight: 700;
letter-spacing: -0.3px;
}
.nav-title span {
background: linear-gradient(135deg, var(--accent-1), var(--accent-2));
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
background-clip: text;
}
.nav-links {
display: flex; gap: 8px;
}
.nav-link {
padding: 8px 16px;
font-size: 13px; font-weight: 500;
color: var(--text-muted);
text-decoration: none;
border-radius: 8px;
transition: all 0.2s;
}
.nav-link:hover {
color: var(--text);
background: rgba(15, 23, 42, 0.05);
}
/* =========================================
HERO SECTION
========================================= */
.hero {
position: relative; z-index: 1;
display: flex; flex-direction: column;
align-items: center; justify-content: center;
text-align: center;
padding: 160px 40px 80px;
min-height: 70vh;
}
.hero-badge {
display: inline-flex; align-items: center; gap: 8px;
padding: 6px 16px 6px 8px;
background: rgba(139, 92, 246, 0.12);
border: 1px solid rgba(139, 92, 246, 0.2);
border-radius: 100px;
font-size: 12px; font-weight: 600; color: var(--accent-2);
margin-bottom: 24px;
animation: fadeInUp 0.6s ease;
}
.hero-badge-dot {
width: 8px; height: 8px;
background: var(--accent-2);
border-radius: 50%;
animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
0%,100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.5; transform: scale(1.3); }
}
.hero h1 {
font-size: clamp(36px, 6vw, 64px);
font-weight: 800;
line-height: 1.1;
letter-spacing: -1.5px;
margin-bottom: 20px;
animation: fadeInUp 0.6s ease 0.1s both;
}
.hero h1 .gradient-text {
background: linear-gradient(135deg, var(--accent-1) 0%, var(--accent-2) 50%, var(--accent-3) 100%);
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
background-clip: text;
}
.hero-desc {
font-size: 17px; color: var(--text-muted);
max-width: 560px; line-height: 1.7;
margin-bottom: 36px;
animation: fadeInUp 0.6s ease 0.2s both;
}
.hero-stats {
display: flex; gap: 40px;
animation: fadeInUp 0.6s ease 0.3s both;
}
.hero-stat {
text-align: center;
}
.hero-stat-num {
font-size: 28px; font-weight: 800;
font-family: var(--mono);
background: linear-gradient(135deg, var(--accent-1), var(--accent-4));
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
background-clip: text;
}
.hero-stat-label {
font-size: 11px; font-weight: 600;
color: var(--text-dim);
text-transform: uppercase;
letter-spacing: 1px;
margin-top: 4px;
}
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
/* =========================================
PROJECTS SECTION
========================================= */
.projects {
position: relative; z-index: 1;
padding: 40px 40px 100px;
max-width: 1200px;
margin: 0 auto;
}
.section-label {
display: flex; align-items: center; gap: 10px;
font-size: 11px; font-weight: 700;
text-transform: uppercase;
letter-spacing: 2px;
color: var(--accent-1);
margin-bottom: 12px;
}
.section-label::before {
content: '';
width: 24px; height: 2px;
background: var(--accent-1);
border-radius: 2px;
}
.section-title {
font-size: 32px; font-weight: 800;
letter-spacing: -0.8px;
margin-bottom: 48px;
}
.project-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
gap: 24px;
}
/* =========================================
PROJECT CARD
========================================= */
.project-card {
position: relative;
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 20px;
overflow: hidden;
cursor: pointer;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
text-decoration: none;
color: inherit;
display: flex; flex-direction: column;
box-shadow: 0 4px 20px rgba(15, 23, 42, 0.02);
}
.project-card:hover {
transform: translateY(-6px);
background: var(--bg-card-hover);
border-color: var(--border-hover);
box-shadow:
0 20px 45px rgba(15, 23, 42, 0.06),
0 0 0 1px rgba(15, 23, 42, 0.03);
}
.project-card:hover .card-icon-glow {
opacity: 0.25;
}
.project-card:hover .card-arrow {
transform: translate(3px, -3px);
opacity: 1;
}
.project-card:hover .card-preview {
transform: scale(1.03);
}
/* Card top: preview area */
.card-preview-wrap {
position: relative;
height: 200px;
overflow: hidden;
background: linear-gradient(135deg, rgba(15, 23, 42, 0.02), rgba(15, 23, 42, 0.04));
}
.card-preview {
width: 100%; height: 100%;
display: flex; align-items: center; justify-content: center;
transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}
.card-icon-glow {
position: absolute;
width: 200px; height: 200px;
border-radius: 50%;
filter: blur(60px);
opacity: 0.12;
transition: opacity 0.4s;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
}
/* SVG icons */
.card-icon-svg {
position: relative; z-index: 1;
width: 100px; height: 100px;
}
/* Card number badge */
.card-number {
position: absolute; top: 16px; left: 16px;
font-family: var(--mono);
font-size: 11px; font-weight: 600;
color: var(--text-dim);
padding: 4px 10px;
background: rgba(15, 23, 42, 0.04);
border: 1px solid var(--border);
border-radius: 6px;
}
/* Card arrow */
.card-arrow {
position: absolute; top: 16px; right: 16px;
width: 32px; height: 32px;
background: rgba(15, 23, 42, 0.04);
border: 1px solid var(--border);
border-radius: 8px;
display: flex; align-items: center; justify-content: center;
opacity: 0.5;
transition: all 0.3s;
}
.card-arrow svg {
width: 14px; height: 14px;
stroke: var(--text-muted);
fill: none;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
}
/* Card body */
.card-body {
padding: 24px 24px 28px;
flex: 1;
display: flex; flex-direction: column;
}
.card-tag {
display: inline-flex;
align-self: flex-start;
padding: 3px 10px;
font-size: 10px; font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.8px;
border-radius: 6px;
margin-bottom: 12px;
}
.card-tag.choropleth {
background: rgba(245, 158, 11, 0.12);
color: var(--accent-3);
border: 1px solid rgba(245, 158, 11, 0.2);
}
.card-tag.crud {
background: rgba(6, 182, 212, 0.12);
color: var(--accent-1);
border: 1px solid rgba(6, 182, 212, 0.2);
}
.card-tag.fullstack {
background: rgba(16, 185, 129, 0.12);
color: var(--accent-4);
border: 1px solid rgba(16, 185, 129, 0.2);
}
.card-title {
font-size: 20px; font-weight: 700;
letter-spacing: -0.3px;
margin-bottom: 8px;
line-height: 1.3;
}
.card-desc {
font-size: 13px; color: var(--text-muted);
line-height: 1.7;
flex: 1;
}
/* Card tech tags */
.card-techs {
display: flex; flex-wrap: wrap; gap: 6px;
margin-top: 16px; padding-top: 16px;
border-top: 1px solid var(--border);
}
.card-tech {
padding: 3px 8px;
font-size: 10px; font-weight: 600;
color: var(--text-muted);
background: rgba(15, 23, 42, 0.03);
border: 1px solid var(--border);
border-radius: 5px;
font-family: var(--mono);
}
/* =========================================
FOOTER
========================================= */
.footer {
position: relative; z-index: 1;
text-align: center;
padding: 40px;
border-top: 1px solid var(--border);
}
.footer-text {
font-size: 12px; color: var(--text-dim);
}
.footer-text a {
color: var(--accent-1);
text-decoration: none;
}
/* =========================================
RESPONSIVE
========================================= */
@media (max-width: 768px) {
.navbar { padding: 12px 20px; }
.nav-links { display: none; }
.hero { padding: 120px 20px 60px; }
.hero-stats { gap: 24px; }
.projects { padding: 20px 20px 60px; }
.project-grid { grid-template-columns: 1fr; }
.card-preview-wrap { height: 160px; }
}
/* =========================================
SCROLL ANIMATIONS
========================================= */
.reveal {
opacity: 0;
transform: translateY(30px);
transition: all 0.7s cubic-bezier(0.4, 0, 0.2, 1);
}
.reveal.visible {
opacity: 1;
transform: translateY(0);
}
</style>
</head>
<body>
<!-- Ambient Background -->
<div class="bg-ambient">
<div class="bg-orb"></div>
<div class="bg-orb"></div>
<div class="bg-orb"></div>
</div>
<div class="bg-grid"></div>
<!-- Navbar -->
<nav class="navbar" id="navbar">
<div class="nav-brand">
<div class="nav-logo">🌍</div>
<div class="nav-title"><span>WebGIS</span> Pontianak</div>
</div>
<div class="nav-links">
<a href="#projects" class="nav-link">Proyek</a>
<a href="https://github.com" class="nav-link" target="_blank">GitHub</a>
</div>
</nav>
<!-- Hero -->
<section class="hero">
<div class="hero-badge">
<div class="hero-badge-dot"></div>
Sistem Informasi Geografis Berbasis Web
</div>
<h1>
Eksplorasi <span class="gradient-text">WebGIS</span><br>
Kota Pontianak
</h1>
<p class="hero-desc">
Kumpulan proyek WebGIS interaktif yang mencakup analisis kepadatan penduduk,
pemetaan SPBU, hingga distribusi bantuan sosial berbasis peta digital.
</p>
<div class="hero-stats">
<div class="hero-stat">
<div class="hero-stat-num">3</div>
<div class="hero-stat-label">Proyek</div>
</div>
<div class="hero-stat">
<div class="hero-stat-num">Leaflet</div>
<div class="hero-stat-label">Map Engine</div>
</div>
<div class="hero-stat">
<div class="hero-stat-num">PHP</div>
<div class="hero-stat-label">Backend</div>
</div>
</div>
</section>
<!-- Projects -->
<section class="projects" id="projects">
<div class="section-label">Portfolio</div>
<h2 class="section-title">Proyek yang Telah Dibuat</h2>
<div class="project-grid">
<!-- Card 1: WebGIS SPBU -->
<a href="http://localhost/webgis/03/index.html" class="project-card reveal" id="card-03">
<div class="card-preview-wrap">
<div class="card-icon-glow" style="background: var(--accent-1);"></div>
<div class="card-number">03</div>
<div class="card-arrow">
<svg viewBox="0 0 24 24"><path d="M7 17L17 7M17 7H7M17 7V17"/></svg>
</div>
<div class="card-preview">
<!-- SPBU / Gas Station Icon -->
<svg class="card-icon-svg" viewBox="0 0 120 120" fill="none">
<!-- Gas pump body -->
<rect x="25" y="35" width="40" height="55" rx="6" fill="#06b6d4" opacity="0.8"/>
<rect x="30" y="42" width="30" height="20" rx="3" fill="#0e7490" opacity="0.6"/>
<!-- Display -->
<rect x="33" y="45" width="24" height="14" rx="2" fill="#164e63"/>
<text x="38" y="55" font-family="monospace" font-size="8" fill="#22d3ee">24H</text>
<!-- Nozzle -->
<path d="M65 45 L75 40 L78 50 L80 75" stroke="#06b6d4" stroke-width="3" fill="none" stroke-linecap="round"/>
<circle cx="80" cy="78" r="4" fill="#06b6d4" opacity="0.7"/>
<!-- Base -->
<rect x="20" y="88" width="50" height="6" rx="3" fill="#06b6d4" opacity="0.3"/>
<!-- Map pin markers -->
<circle cx="95" cy="35" r="6" fill="#10b981" opacity="0.8"/>
<circle cx="95" cy="35" r="2.5" fill="white"/>
<circle cx="100" cy="55" r="5" fill="#ef4444" opacity="0.8"/>
<circle cx="100" cy="55" r="2" fill="white"/>
<!-- Lines / roads -->
<path d="M85 45 L105 45" stroke="#334155" stroke-width="2" stroke-dasharray="4 3" opacity="0.4"/>
<path d="M88 65 L108 65" stroke="#334155" stroke-width="2" stroke-dasharray="4 3" opacity="0.4"/>
<!-- Polygon hint -->
<path d="M88 75 L105 72 L108 85 L90 88 Z" fill="#8b5cf6" opacity="0.15" stroke="#8b5cf6" stroke-width="1"/>
</svg>
</div>
</div>
<div class="card-body">
<div class="card-tag crud">CRUD + Draw Tools</div>
<div class="card-title">WebGIS SPBU Kota Pontianak</div>
<div class="card-desc">
Sistem pemetaan SPBU interaktif dengan fitur CRUD lengkap — tambah, edit, hapus
titik SPBU. Dilengkapi draw tools untuk menggambar jalan (polyline) dan kavling (polygon)
langsung di peta, serta filter status operasional 24 jam.
</div>
<div class="card-techs">
<span class="card-tech">Leaflet.js</span>
<span class="card-tech">Leaflet Draw</span>
<span class="card-tech">PHP + MySQL</span>
<span class="card-tech">CRUD</span>
</div>
</div>
</a>
<!-- Card 2: Kepadatan Penduduk -->
<a href="http://localhost/webgis/02/index.html" class="project-card reveal" id="card-02" style="animation-delay: 0.1s">
<div class="card-preview-wrap">
<div class="card-icon-glow" style="background: var(--accent-3);"></div>
<div class="card-number">02</div>
<div class="card-arrow">
<svg viewBox="0 0 24 24"><path d="M7 17L17 7M17 7H7M17 7V17"/></svg>
</div>
<div class="card-preview">
<!-- Choropleth Map Icon -->
<svg class="card-icon-svg" viewBox="0 0 120 120" fill="none">
<!-- Map regions -->
<path d="M20 30 L55 20 L60 50 L35 60 Z" fill="#f59e0b" opacity="0.8" rx="4"/>
<path d="M55 20 L95 25 L90 55 L60 50 Z" fill="#d97706" opacity="0.7" rx="4"/>
<path d="M35 60 L60 50 L65 85 L25 90 Z" fill="#fbbf24" opacity="0.6" rx="4"/>
<path d="M60 50 L90 55 L95 80 L65 85 Z" fill="#b45309" opacity="0.9" rx="4"/>
<!-- Map outline glow -->
<path d="M20 30 L55 20 L95 25 L90 55 L95 80 L65 85 L25 90 L35 60 Z"
stroke="#f59e0b" stroke-width="1.5" fill="none" opacity="0.4"/>
<!-- People dots -->
<circle cx="45" cy="40" r="3" fill="white" opacity="0.7"/>
<circle cx="75" cy="38" r="4" fill="white" opacity="0.8"/>
<circle cx="50" cy="68" r="2.5" fill="white" opacity="0.6"/>
<circle cx="78" cy="65" r="5" fill="white" opacity="0.9"/>
<!-- Legend bar -->
<rect x="30" y="98" width="60" height="6" rx="3" fill="url(#grad-heat)" opacity="0.7"/>
<defs>
<linearGradient id="grad-heat" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#fef3c7"/>
<stop offset="50%" stop-color="#f59e0b"/>
<stop offset="100%" stop-color="#7c2d12"/>
</linearGradient>
</defs>
</svg>
</div>
</div>
<div class="card-body">
<div class="card-tag choropleth">Choropleth Map</div>
<div class="card-title">Kepadatan Penduduk Kota Pontianak</div>
<div class="card-desc">
Visualisasi peta tematik kepadatan penduduk per kelurahan di Kota Pontianak
menggunakan teknik choropleth dengan gradasi warna berdasarkan jumlah jiwa.
Dilengkapi hover interaktif dan legenda dinamis.
</div>
<div class="card-techs">
<span class="card-tech">Leaflet.js</span>
<span class="card-tech">GeoJSON</span>
<span class="card-tech">Choropleth</span>
<span class="card-tech">Interactive</span>
</div>
</div>
</a>
<!-- Card 3: BantSOSial GIS -->
<a href="http://localhost/webgis/04/index.html" class="project-card reveal" id="card-04" style="animation-delay: 0.2s">
<div class="card-preview-wrap">
<div class="card-icon-glow" style="background: var(--accent-4);"></div>
<div class="card-number">04</div>
<div class="card-arrow">
<svg viewBox="0 0 24 24"><path d="M7 17L17 7M17 7H7M17 7V17"/></svg>
</div>
<div class="card-preview">
<!-- Social Aid / Distribution Icon -->
<svg class="card-icon-svg" viewBox="0 0 120 120" fill="none">
<!-- Central mosque/worship icon -->
<path d="M60 25 Q60 15 60 15 Q65 20 65 25" fill="#10b981" opacity="0.8"/>
<rect x="45" y="25" width="30" height="35" rx="4" fill="#10b981" opacity="0.7"/>
<path d="M40 60 L80 60 L80 65 L40 65 Z" fill="#10b981" opacity="0.5"/>
<!-- Dome -->
<ellipse cx="60" cy="28" rx="12" ry="8" fill="#059669" opacity="0.6"/>
<!-- Radius circle -->
<circle cx="60" cy="50" r="35" fill="none" stroke="#10b981" stroke-width="1.5"
stroke-dasharray="6 4" opacity="0.35"/>
<!-- Houses around -->
<rect x="20" y="40" width="10" height="10" rx="2" fill="#ef4444" opacity="0.7"/>
<rect x="90" y="45" width="10" height="10" rx="2" fill="#f59e0b" opacity="0.7"/>
<rect x="30" y="75" width="10" height="10" rx="2" fill="#22c55e" opacity="0.7"/>
<rect x="80" y="70" width="10" height="10" rx="2" fill="#ef4444" opacity="0.7"/>
<rect x="55" y="80" width="10" height="10" rx="2" fill="#f59e0b" opacity="0.7"/>
<!-- Connection lines -->
<line x1="25" y1="45" x2="45" y2="45" stroke="#ef4444" stroke-width="0.8" opacity="0.4" stroke-dasharray="3 2"/>
<line x1="80" y1="50" x2="95" y2="50" stroke="#f59e0b" stroke-width="0.8" opacity="0.4" stroke-dasharray="3 2"/>
<!-- Legend dots -->
<circle cx="25" cy="100" r="4" fill="#ef4444" opacity="0.7"/>
<circle cx="50" cy="100" r="4" fill="#f59e0b" opacity="0.7"/>
<circle cx="75" cy="100" r="4" fill="#22c55e" opacity="0.7"/>
<text x="32" y="103" font-size="7" fill="#64748b" font-family="sans-serif">Belum</text>
<text x="57" y="103" font-size="7" fill="#64748b" font-family="sans-serif">Sudah</text>
<text x="82" y="103" font-size="7" fill="#64748b" font-family="sans-serif">Luar</text>
</svg>
</div>
</div>
<div class="card-body">
<div class="card-tag fullstack">Full-Stack WebGIS</div>
<div class="card-title">Distribusi Bantuan Sosial Pontianak</div>
<div class="card-desc">
Aplikasi WebGIS lengkap untuk memetakan distribusi bantuan sosial berbasis rumah ibadah.
Fitur meliputi role system (Admin, Surveyer, Viewer), radius jangkauan,
input data keluarga miskin, status bantuan, dan sistem pelaporan masyarakat.
</div>
<div class="card-techs">
<span class="card-tech">Leaflet.js</span>
<span class="card-tech">PHP + MySQL</span>
<span class="card-tech">Role System</span>
<span class="card-tech">Pelaporan</span>
</div>
</div>
</a>
</div>
</section>
<div class="card-arrow">
<svg viewBox="0 0 24 24"><path d="M7 17L17 7M17 7H7M17 7V17"/></svg>
</div>
<div class="card-preview">
<!-- Choropleth Map Icon -->
<svg class="card-icon-svg" viewBox="0 0 120 120" fill="none">
<!-- Map regions -->
<path d="M20 30 L55 20 L60 50 L35 60 Z" fill="#f59e0b" opacity="0.8" rx="4"/>
<path d="M55 20 L95 25 L90 55 L60 50 Z" fill="#d97706" opacity="0.7" rx="4"/>
<path d="M35 60 L60 50 L65 85 L25 90 Z" fill="#fbbf24" opacity="0.6" rx="4"/>
<path d="M60 50 L90 55 L95 80 L65 85 Z" fill="#b45309" opacity="0.9" rx="4"/>
<!-- Map outline glow -->
<path d="M20 30 L55 20 L95 25 L90 55 L95 80 L65 85 L25 90 L35 60 Z"
stroke="#f59e0b" stroke-width="1.5" fill="none" opacity="0.4"/>
<!-- People dots -->
<circle cx="45" cy="40" r="3" fill="white" opacity="0.7"/>
<circle cx="75" cy="38" r="4" fill="white" opacity="0.8"/>
<circle cx="50" cy="68" r="2.5" fill="white" opacity="0.6"/>
<circle cx="78" cy="65" r="5" fill="white" opacity="0.9"/>
<!-- Legend bar -->
<rect x="30" y="98" width="60" height="6" rx="3" fill="url(#grad-heat)" opacity="0.7"/>
<defs>
<linearGradient id="grad-heat" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#fef3c7"/>
<stop offset="50%" stop-color="#f59e0b"/>
<stop offset="100%" stop-color="#7c2d12"/>
</linearGradient>
</defs>
</svg>
</div>
</div>
<div class="card-body">
<div class="card-tag choropleth">Choropleth Map</div>
<div class="card-title">Kepadatan Penduduk Kota Pontianak</div>
<div class="card-desc">
Visualisasi peta tematik kepadatan penduduk per kelurahan di Kota Pontianak
menggunakan teknik choropleth dengan gradasi warna berdasarkan jumlah jiwa.
Dilengkapi hover interaktif dan legenda dinamis.
</div>
<div class="card-techs">
<span class="card-tech">Leaflet.js</span>
<span class="card-tech">GeoJSON</span>
<span class="card-tech">Choropleth</span>
<span class="card-tech">Interactive</span>
</div>
</div>
</a>
<div class="card-preview-wrap">
<div class="card-icon-glow" style="background: var(--accent-1);"></div>
<div class="card-number">03</div>
<div class="card-arrow">
<svg viewBox="0 0 24 24"><path d="M7 17L17 7M17 7H7M17 7V17"/></svg>
</div>
<div class="card-preview">
<!-- SPBU / Gas Station Icon -->
<svg class="card-icon-svg" viewBox="0 0 120 120" fill="none">
<!-- Gas pump body -->
<rect x="25" y="35" width="40" height="55" rx="6" fill="#06b6d4" opacity="0.8"/>
<rect x="30" y="42" width="30" height="20" rx="3" fill="#0e7490" opacity="0.6"/>
<!-- Display -->
<rect x="33" y="45" width="24" height="14" rx="2" fill="#164e63"/>
<text x="38" y="55" font-family="monospace" font-size="8" fill="#22d3ee">24H</text>
<!-- Nozzle -->
<path d="M65 45 L75 40 L78 50 L80 75" stroke="#06b6d4" stroke-width="3" fill="none" stroke-linecap="round"/>
<circle cx="80" cy="78" r="4" fill="#06b6d4" opacity="0.7"/>
<!-- Base -->
<rect x="20" y="88" width="50" height="6" rx="3" fill="#06b6d4" opacity="0.3"/>
<!-- Map pin markers -->
<circle cx="95" cy="35" r="6" fill="#10b981" opacity="0.8"/>
<circle cx="95" cy="35" r="2.5" fill="white"/>
<circle cx="100" cy="55" r="5" fill="#ef4444" opacity="0.8"/>
<circle cx="100" cy="55" r="2" fill="white"/>
<!-- Lines / roads -->
<path d="M85 45 L105 45" stroke="#334155" stroke-width="2" stroke-dasharray="4 3" opacity="0.4"/>
<path d="M88 65 L108 65" stroke="#334155" stroke-width="2" stroke-dasharray="4 3" opacity="0.4"/>
<!-- Polygon hint -->
<path d="M88 75 L105 72 L108 85 L90 88 Z" fill="#8b5cf6" opacity="0.15" stroke="#8b5cf6" stroke-width="1" opacity="0.3"/>
</svg>
</div>
</div>
<div class="card-body">
<div class="card-tag crud">CRUD + Draw Tools</div>
<div class="card-title">WebGIS SPBU Kota Pontianak</div>
<div class="card-desc">
Sistem pemetaan SPBU interaktif dengan fitur CRUD lengkap — tambah, edit, hapus
titik SPBU. Dilengkapi draw tools untuk menggambar jalan (polyline) dan kavling (polygon)
langsung di peta, serta filter status operasional 24 jam.
</div>
<div class="card-techs">
<span class="card-tech">Leaflet.js</span>
<span class="card-tech">Leaflet Draw</span>
<span class="card-tech">PHP + MySQL</span>
<span class="card-tech">CRUD</span>
</div>
</div>
</a>
<!-- Card 3: BantSOSial GIS -->
<a href="http://localhost/webgis/04/index.html" class="project-card reveal" id="card-04" style="animation-delay: 0.2s">
<div class="card-preview-wrap">
<div class="card-icon-glow" style="background: var(--accent-4);"></div>
<div class="card-number">04</div>
<div class="card-arrow">
<svg viewBox="0 0 24 24"><path d="M7 17L17 7M17 7H7M17 7V17"/></svg>
</div>
<div class="card-preview">
<!-- Social Aid / Distribution Icon -->
<svg class="card-icon-svg" viewBox="0 0 120 120" fill="none">
<!-- Central mosque/worship icon -->
<path d="M60 25 Q60 15 60 15 Q65 20 65 25" fill="#10b981" opacity="0.8"/>
<rect x="45" y="25" width="30" height="35" rx="4" fill="#10b981" opacity="0.7"/>
<path d="M40 60 L80 60 L80 65 L40 65 Z" fill="#10b981" opacity="0.5"/>
<!-- Dome -->
<ellipse cx="60" cy="28" rx="12" ry="8" fill="#059669" opacity="0.6"/>
<!-- Radius circle -->
<circle cx="60" cy="50" r="35" fill="none" stroke="#10b981" stroke-width="1.5"
stroke-dasharray="6 4" opacity="0.35"/>
<!-- Houses around -->
<rect x="20" y="40" width="10" height="10" rx="2" fill="#ef4444" opacity="0.7"/>
<rect x="90" y="45" width="10" height="10" rx="2" fill="#f59e0b" opacity="0.7"/>
<rect x="30" y="75" width="10" height="10" rx="2" fill="#22c55e" opacity="0.7"/>
<rect x="80" y="70" width="10" height="10" rx="2" fill="#ef4444" opacity="0.7"/>
<rect x="55" y="80" width="10" height="10" rx="2" fill="#f59e0b" opacity="0.7"/>
<!-- Connection lines -->
<line x1="25" y1="45" x2="45" y2="45" stroke="#ef4444" stroke-width="0.8" opacity="0.4" stroke-dasharray="3 2"/>
<line x1="80" y1="50" x2="95" y2="50" stroke="#f59e0b" stroke-width="0.8" opacity="0.4" stroke-dasharray="3 2"/>
<!-- Legend dots -->
<circle cx="25" cy="100" r="4" fill="#ef4444" opacity="0.7"/>
<circle cx="50" cy="100" r="4" fill="#f59e0b" opacity="0.7"/>
<circle cx="75" cy="100" r="4" fill="#22c55e" opacity="0.7"/>
<text x="32" y="103" font-size="7" fill="#64748b" font-family="sans-serif">Belum</text>
<text x="57" y="103" font-size="7" fill="#64748b" font-family="sans-serif">Sudah</text>
<text x="82" y="103" font-size="7" fill="#64748b" font-family="sans-serif">Luar</text>
</svg>
</div>
</div>
<div class="card-body">
<div class="card-tag fullstack">Full-Stack WebGIS</div>
<div class="card-title">Distribusi Bantuan Sosial Pontianak</div>
<div class="card-desc">
Aplikasi WebGIS lengkap untuk memetakan distribusi bantuan sosial berbasis rumah ibadah.
Fitur meliputi role system (Admin, Surveyer, Viewer), radius jangkauan,
input data keluarga miskin, status bantuan, dan sistem pelaporan masyarakat.
</div>
<div class="card-techs">
<span class="card-tech">Leaflet.js</span>
<span class="card-tech">PHP + MySQL</span>
<span class="card-tech">Role System</span>
<span class="card-tech">Pelaporan</span>
</div>
</div>
</a>
</div>
</section>
<!-- Footer -->
<footer class="footer">
<div class="footer-text">
&copy; 2026 WebGIS Pontianak — Dibuat dengan
<a href="https://leafletjs.com" target="_blank">Leaflet.js</a> & ❤️
</div>
</footer>
<script>
// Navbar scroll effect
const navbar = document.getElementById('navbar');
window.addEventListener('scroll', () => {
navbar.classList.toggle('scrolled', window.scrollY > 40);
});
// Scroll reveal animation
const revealEls = document.querySelectorAll('.reveal');
const revealObserver = new IntersectionObserver((entries) => {
entries.forEach((entry, i) => {
if (entry.isIntersecting) {
setTimeout(() => {
entry.target.classList.add('visible');
}, i * 120);
revealObserver.unobserve(entry.target);
}
});
}, { threshold: 0.15 });
revealEls.forEach(el => revealObserver.observe(el));
</script>
</body>
</html>