Skip to content

Instantly share code, notes, and snippets.

@davekennewell
Created February 21, 2026 06:15
Show Gist options
  • Select an option

  • Save davekennewell/cf3930d9409d76d3358c63f34c4dfdd3 to your computer and use it in GitHub Desktop.

Select an option

Save davekennewell/cf3930d9409d76d3358c63f34c4dfdd3 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hydrata - See Your Water Data</title>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700;1,9..40,400&display=swap" rel="stylesheet">
<style>
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--water-deep: #1a5276;
--water-mid: #2980b9;
--water-light: #85c1e9;
--water-pale: #d4e6f1;
--land-dark: #1e4d2b;
--land-mid: #27ae60;
--land-light: #82e0aa;
--earth-dark: #6e4b3a;
--earth-mid: #af8c6e;
--earth-light: #dcc9b6;
--earth-pale: #f5f0eb;
--topo-cream: #faf8f5;
--topo-line: rgba(26, 82, 118, 0.12);
--text-primary: #1a2332;
--text-secondary: #4a5568;
--text-muted: #8896a6;
--white: #ffffff;
--shadow-sm: 0 1px 3px rgba(0,0,0,0.08);
--shadow-md: 0 4px 12px rgba(0,0,0,0.1);
--shadow-lg: 0 8px 30px rgba(0,0,0,0.12);
--shadow-xl: 0 20px 60px rgba(0,0,0,0.15);
}
html {
scroll-behavior: smooth;
}
body {
font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, sans-serif;
color: var(--text-primary);
background: var(--topo-cream);
line-height: 1.6;
overflow-x: hidden;
-webkit-font-smoothing: antialiased;
}
/* ---- NAV ---- */
nav {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
padding: 0 2rem;
height: 64px;
display: flex;
align-items: center;
justify-content: space-between;
background: rgba(250, 248, 245, 0.85);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border-bottom: 1px solid rgba(26, 82, 118, 0.08);
transition: background 0.3s;
}
.nav-logo {
font-size: 1.35rem;
font-weight: 700;
color: var(--water-deep);
text-decoration: none;
letter-spacing: -0.5px;
display: flex;
align-items: center;
gap: 0.5rem;
}
.nav-logo-icon {
width: 28px;
height: 28px;
border-radius: 8px;
background: linear-gradient(135deg, var(--water-mid), var(--water-deep));
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
}
.nav-logo-icon::after {
content: '';
position: absolute;
width: 18px;
height: 18px;
border-radius: 50%;
border: 2px solid rgba(255,255,255,0.5);
top: 8px;
left: 5px;
}
.nav-links {
display: flex;
align-items: center;
gap: 1.5rem;
}
.nav-links a {
text-decoration: none;
color: var(--text-secondary);
font-size: 0.9rem;
font-weight: 500;
transition: color 0.2s;
}
.nav-links a:hover {
color: var(--water-deep);
}
.nav-cta {
background: var(--water-deep) !important;
color: var(--white) !important;
padding: 0.5rem 1.25rem;
border-radius: 8px;
font-weight: 600 !important;
transition: background 0.2s, transform 0.15s !important;
}
.nav-cta:hover {
background: var(--water-mid) !important;
transform: translateY(-1px);
}
/* ---- HERO ---- */
.hero {
position: relative;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
padding: 64px 2rem 2rem;
}
/* Topographic map background */
.topo-bg {
position: absolute;
inset: 0;
background:
/* water body - lower right */
radial-gradient(ellipse 60% 50% at 75% 70%, rgba(41, 128, 185, 0.25) 0%, transparent 70%),
/* water body - upper area */
radial-gradient(ellipse 40% 35% at 25% 25%, rgba(133, 193, 233, 0.2) 0%, transparent 60%),
/* land elevation warm */
radial-gradient(ellipse 50% 45% at 40% 55%, rgba(175, 140, 110, 0.15) 0%, transparent 60%),
/* overall wash */
linear-gradient(175deg, #f0ebe4 0%, #e8eef4 40%, #dde8e4 70%, #e4e0d8 100%);
}
/* Contour lines layer */
.contour-lines {
position: absolute;
inset: 0;
opacity: 0.6;
}
.contour-lines::before {
content: '';
position: absolute;
inset: 0;
background:
/* Concentric contours - mountain 1 */
radial-gradient(ellipse 320px 280px at 30% 40%, transparent 58%, var(--topo-line) 59%, var(--topo-line) 60%, transparent 61%),
radial-gradient(ellipse 260px 220px at 30% 40%, transparent 58%, var(--topo-line) 59%, var(--topo-line) 60%, transparent 61%),
radial-gradient(ellipse 200px 170px at 30% 40%, transparent 58%, var(--topo-line) 59%, var(--topo-line) 60%, transparent 61%),
radial-gradient(ellipse 150px 125px at 30% 40%, transparent 58%, var(--topo-line) 59%, var(--topo-line) 60%, transparent 61%),
radial-gradient(ellipse 100px 85px at 30% 40%, transparent 58%, rgba(30,77,43,0.15) 59%, rgba(30,77,43,0.15) 60%, transparent 61%),
radial-gradient(ellipse 55px 45px at 30% 40%, transparent 50%, rgba(30,77,43,0.2) 51%, rgba(30,77,43,0.2) 53%, transparent 54%),
/* Concentric contours - mountain 2 */
radial-gradient(ellipse 280px 350px at 72% 55%, transparent 58%, var(--topo-line) 59%, var(--topo-line) 60%, transparent 61%),
radial-gradient(ellipse 220px 280px at 72% 55%, transparent 58%, var(--topo-line) 59%, var(--topo-line) 60%, transparent 61%),
radial-gradient(ellipse 160px 210px at 72% 55%, transparent 58%, var(--topo-line) 59%, var(--topo-line) 60%, transparent 61%),
radial-gradient(ellipse 110px 145px at 72% 55%, transparent 58%, var(--topo-line) 59%, var(--topo-line) 60%, transparent 61%),
radial-gradient(ellipse 65px 85px at 72% 55%, transparent 50%, rgba(26,82,118,0.15) 51%, rgba(26,82,118,0.15) 53%, transparent 54%);
}
.contour-lines::after {
content: '';
position: absolute;
inset: 0;
background:
/* Ridge / saddle contours */
radial-gradient(ellipse 400px 200px at 50% 65%, transparent 58%, var(--topo-line) 59%, var(--topo-line) 60%, transparent 61%),
radial-gradient(ellipse 500px 260px at 50% 65%, transparent 58%, rgba(26,82,118,0.06) 59%, rgba(26,82,118,0.06) 60%, transparent 61%),
/* Small hill */
radial-gradient(ellipse 90px 70px at 55% 25%, transparent 55%, var(--topo-line) 56%, var(--topo-line) 58%, transparent 59%),
radial-gradient(ellipse 55px 40px at 55% 25%, transparent 50%, rgba(110,75,58,0.12) 51%, rgba(110,75,58,0.12) 54%, transparent 55%),
/* Another small feature */
radial-gradient(ellipse 120px 100px at 85% 20%, transparent 55%, var(--topo-line) 56%, var(--topo-line) 58%, transparent 59%),
radial-gradient(ellipse 70px 55px at 85% 20%, transparent 50%, var(--topo-line) 51%, var(--topo-line) 54%, transparent 55%);
}
/* Water flow lines (rivers/streams) */
.water-flow {
position: absolute;
inset: 0;
overflow: hidden;
}
.river {
position: absolute;
background: transparent;
border: none;
}
.river-1 {
width: 300px;
height: 600px;
top: 5%;
left: 20%;
border-right: 2.5px solid rgba(41, 128, 185, 0.3);
border-radius: 0 0 200px 0;
transform: rotate(-15deg);
}
.river-1::after {
content: '';
position: absolute;
width: 200px;
height: 400px;
bottom: -200px;
right: -100px;
border-left: 2px solid rgba(41, 128, 185, 0.25);
border-radius: 0 0 0 180px;
transform: rotate(10deg);
}
.river-2 {
width: 150px;
height: 400px;
top: 20%;
left: 35%;
border-left: 2px solid rgba(41, 128, 185, 0.2);
border-radius: 0 0 0 120px;
transform: rotate(5deg);
}
.river-3 {
width: 250px;
height: 500px;
top: 10%;
right: 20%;
border-right: 2px solid rgba(41, 128, 185, 0.2);
border-radius: 0 0 150px 0;
transform: rotate(-8deg);
}
/* Animated subtle shimmer on water areas */
.water-shimmer {
position: absolute;
inset: 0;
background:
radial-gradient(ellipse 200px 150px at 75% 72%, rgba(133,193,233,0.08) 0%, transparent 70%),
radial-gradient(ellipse 150px 120px at 25% 28%, rgba(133,193,233,0.06) 0%, transparent 70%);
animation: shimmer 8s ease-in-out infinite alternate;
}
@keyframes shimmer {
0% { opacity: 0.5; }
50% { opacity: 1; }
100% { opacity: 0.6; }
}
/* Grid overlay - subtle map grid */
.map-grid {
position: absolute;
inset: 0;
background-image:
linear-gradient(rgba(26,82,118,0.03) 1px, transparent 1px),
linear-gradient(90deg, rgba(26,82,118,0.03) 1px, transparent 1px);
background-size: 80px 80px;
}
/* Elevation markers */
.elev-marker {
position: absolute;
font-size: 0.65rem;
color: var(--earth-mid);
opacity: 0.5;
font-weight: 500;
letter-spacing: 0.5px;
pointer-events: none;
}
.elev-1 { top: 38%; left: 28%; transform: rotate(-5deg); }
.elev-2 { top: 52%; right: 26%; transform: rotate(3deg); }
.elev-3 { top: 22%; left: 53%; }
.elev-4 { bottom: 30%; left: 45%; transform: rotate(-2deg); }
/* Hero content */
.hero-content {
position: relative;
z-index: 10;
text-align: center;
max-width: 720px;
}
.hero-badge {
display: inline-flex;
align-items: center;
gap: 0.4rem;
background: rgba(255,255,255,0.8);
backdrop-filter: blur(10px);
border: 1px solid rgba(26,82,118,0.1);
border-radius: 100px;
padding: 0.4rem 1rem;
font-size: 0.8rem;
font-weight: 500;
color: var(--water-deep);
margin-bottom: 1.5rem;
}
.hero-badge-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--land-mid);
animation: pulse-dot 2s ease-in-out infinite;
}
@keyframes pulse-dot {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.5; transform: scale(1.3); }
}
.hero h1 {
font-size: clamp(2.5rem, 6vw, 4.5rem);
font-weight: 700;
line-height: 1.08;
letter-spacing: -2px;
color: var(--text-primary);
margin-bottom: 1rem;
}
.hero h1 span {
background: linear-gradient(135deg, var(--water-deep), var(--water-mid));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.hero-tagline {
font-size: clamp(1.05rem, 2.2vw, 1.35rem);
color: var(--text-secondary);
margin-bottom: 2.5rem;
font-weight: 400;
max-width: 520px;
margin-left: auto;
margin-right: auto;
line-height: 1.5;
}
.hero-actions {
display: flex;
align-items: center;
justify-content: center;
gap: 1rem;
flex-wrap: wrap;
}
.btn-primary {
display: inline-flex;
align-items: center;
gap: 0.5rem;
background: var(--water-deep);
color: var(--white);
padding: 0.9rem 2rem;
border-radius: 12px;
font-size: 1rem;
font-weight: 600;
text-decoration: none;
transition: all 0.25s;
box-shadow: var(--shadow-md), 0 0 0 0 rgba(26,82,118,0);
border: none;
cursor: pointer;
}
.btn-primary:hover {
background: var(--water-mid);
transform: translateY(-2px);
box-shadow: var(--shadow-lg), 0 0 0 4px rgba(41,128,185,0.15);
}
.btn-primary .arrow {
transition: transform 0.2s;
}
.btn-primary:hover .arrow {
transform: translateX(3px);
}
.btn-secondary {
display: inline-flex;
align-items: center;
gap: 0.5rem;
background: rgba(255,255,255,0.7);
backdrop-filter: blur(10px);
color: var(--text-primary);
padding: 0.9rem 1.75rem;
border-radius: 12px;
font-size: 1rem;
font-weight: 500;
text-decoration: none;
border: 1px solid rgba(26,82,118,0.12);
transition: all 0.25s;
cursor: pointer;
}
.btn-secondary:hover {
background: rgba(255,255,255,0.95);
border-color: rgba(26,82,118,0.25);
transform: translateY(-1px);
}
/* Scroll hint */
.scroll-hint {
position: absolute;
bottom: 2rem;
left: 50%;
transform: translateX(-50%);
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
color: var(--text-muted);
font-size: 0.75rem;
font-weight: 500;
letter-spacing: 1px;
text-transform: uppercase;
animation: float 3s ease-in-out infinite;
}
.scroll-line {
width: 1px;
height: 32px;
background: linear-gradient(to bottom, var(--text-muted), transparent);
}
@keyframes float {
0%, 100% { transform: translateX(-50%) translateY(0); }
50% { transform: translateX(-50%) translateY(6px); }
}
/* ---- SECTION SHARED ---- */
section {
padding: 6rem 2rem;
}
.section-label {
display: inline-block;
font-size: 0.75rem;
font-weight: 600;
letter-spacing: 2px;
text-transform: uppercase;
color: var(--water-mid);
margin-bottom: 1rem;
}
.section-title {
font-size: clamp(1.75rem, 4vw, 2.5rem);
font-weight: 700;
letter-spacing: -1px;
color: var(--text-primary);
margin-bottom: 1rem;
line-height: 1.15;
}
.section-subtitle {
font-size: 1.1rem;
color: var(--text-secondary);
max-width: 560px;
line-height: 1.6;
}
/* ---- WHAT YOU CAN MODEL ---- */
.model-section {
background: var(--white);
position: relative;
}
.model-section::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px;
background: linear-gradient(90deg, transparent, var(--topo-line), transparent);
}
.model-header {
text-align: center;
margin-bottom: 3.5rem;
}
.model-header .section-subtitle {
margin: 0 auto;
}
.model-cards {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.5rem;
max-width: 1100px;
margin: 0 auto;
}
.model-card {
border-radius: 20px;
overflow: hidden;
position: relative;
min-height: 380px;
display: flex;
flex-direction: column;
justify-content: flex-end;
padding: 2rem;
cursor: default;
transition: transform 0.3s, box-shadow 0.3s;
}
.model-card:hover {
transform: translateY(-4px);
box-shadow: var(--shadow-xl);
}
/* Flood card */
.card-flood {
background:
/* Wave pattern */
radial-gradient(ellipse 100% 40px at 50% 100%, rgba(255,255,255,0.15) 0%, transparent 100%),
radial-gradient(ellipse 100% 40px at 50% 88%, rgba(255,255,255,0.1) 0%, transparent 100%),
radial-gradient(ellipse 100% 40px at 50% 76%, rgba(255,255,255,0.07) 0%, transparent 100%),
/* Concentric flood zones */
radial-gradient(ellipse 70% 60% at 50% 40%, rgba(133,193,233,0.4) 0%, rgba(133,193,233,0.2) 30%, rgba(41,128,185,0.3) 60%, transparent 70%),
radial-gradient(ellipse 90% 80% at 50% 40%, rgba(41,128,185,0.15) 0%, transparent 70%),
/* Water ripple rings */
radial-gradient(circle 40px at 35% 30%, transparent 50%, rgba(255,255,255,0.12) 51%, rgba(255,255,255,0.12) 53%, transparent 54%),
radial-gradient(circle 60px at 35% 30%, transparent 50%, rgba(255,255,255,0.08) 51%, rgba(255,255,255,0.08) 53%, transparent 54%),
radial-gradient(circle 80px at 35% 30%, transparent 50%, rgba(255,255,255,0.05) 51%, rgba(255,255,255,0.05) 53%, transparent 54%),
radial-gradient(circle 30px at 65% 50%, transparent 50%, rgba(255,255,255,0.1) 51%, rgba(255,255,255,0.1) 53%, transparent 54%),
radial-gradient(circle 50px at 65% 50%, transparent 50%, rgba(255,255,255,0.06) 51%, rgba(255,255,255,0.06) 53%, transparent 54%),
linear-gradient(170deg, #2471a3 0%, #1a5276 40%, #154360 100%);
color: var(--white);
}
/* Stormwater card */
.card-storm {
background:
/* Rain drops - scattered dots */
radial-gradient(circle 2px at 15% 10%, rgba(255,255,255,0.25) 0%, transparent 100%),
radial-gradient(circle 2px at 25% 18%, rgba(255,255,255,0.2) 0%, transparent 100%),
radial-gradient(circle 2px at 40% 8%, rgba(255,255,255,0.3) 0%, transparent 100%),
radial-gradient(circle 2px at 55% 22%, rgba(255,255,255,0.2) 0%, transparent 100%),
radial-gradient(circle 2px at 70% 12%, rgba(255,255,255,0.25) 0%, transparent 100%),
radial-gradient(circle 2px at 85% 20%, rgba(255,255,255,0.2) 0%, transparent 100%),
radial-gradient(circle 2px at 10% 35%, rgba(255,255,255,0.15) 0%, transparent 100%),
radial-gradient(circle 2px at 30% 40%, rgba(255,255,255,0.2) 0%, transparent 100%),
radial-gradient(circle 2px at 50% 32%, rgba(255,255,255,0.25) 0%, transparent 100%),
radial-gradient(circle 2px at 65% 38%, rgba(255,255,255,0.15) 0%, transparent 100%),
radial-gradient(circle 2px at 80% 30%, rgba(255,255,255,0.2) 0%, transparent 100%),
radial-gradient(circle 1.5px at 20% 28%, rgba(255,255,255,0.15) 0%, transparent 100%),
radial-gradient(circle 1.5px at 45% 15%, rgba(255,255,255,0.2) 0%, transparent 100%),
radial-gradient(circle 1.5px at 75% 25%, rgba(255,255,255,0.15) 0%, transparent 100%),
/* Ground/vegetation gradient */
radial-gradient(ellipse 80% 40% at 50% 90%, rgba(130,224,170,0.3) 0%, transparent 70%),
radial-gradient(ellipse 60% 50% at 30% 70%, rgba(39,174,96,0.2) 0%, transparent 60%),
linear-gradient(175deg, #1e8449 0%, #1e6f3e 30%, #1a5632 100%);
color: var(--white);
}
/* Watershed card */
.card-watershed {
background:
/* Terrain contour lines */
radial-gradient(ellipse 80% 70% at 40% 35%, transparent 30%, rgba(255,255,255,0.08) 31%, rgba(255,255,255,0.08) 32%, transparent 33%),
radial-gradient(ellipse 65% 55% at 40% 35%, transparent 30%, rgba(255,255,255,0.1) 31%, rgba(255,255,255,0.1) 32%, transparent 33%),
radial-gradient(ellipse 50% 40% at 40% 35%, transparent 30%, rgba(255,255,255,0.12) 31%, rgba(255,255,255,0.12) 32%, transparent 33%),
radial-gradient(ellipse 35% 25% at 40% 35%, transparent 30%, rgba(255,255,255,0.15) 31%, rgba(255,255,255,0.15) 33%, transparent 34%),
/* Ridge line */
radial-gradient(ellipse 90% 60% at 60% 60%, transparent 35%, rgba(255,255,255,0.06) 36%, rgba(255,255,255,0.06) 37%, transparent 38%),
radial-gradient(ellipse 75% 45% at 60% 60%, transparent 35%, rgba(255,255,255,0.08) 36%, rgba(255,255,255,0.08) 37%, transparent 38%),
/* Drainage channel */
radial-gradient(ellipse 8px 120px at 50% 65%, rgba(41,128,185,0.2) 0%, transparent 100%),
linear-gradient(170deg, #935116 0%, #7d6544 30%, #6e5b3a 60%, #5a4a30 100%);
color: var(--white);
}
.model-card-icon {
width: 48px;
height: 48px;
border-radius: 14px;
background: rgba(255,255,255,0.15);
backdrop-filter: blur(8px);
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 1rem;
font-size: 1.4rem;
border: 1px solid rgba(255,255,255,0.15);
}
.model-card h3 {
font-size: 1.35rem;
font-weight: 700;
margin-bottom: 0.5rem;
letter-spacing: -0.3px;
}
.model-card p {
font-size: 0.95rem;
opacity: 0.85;
line-height: 1.5;
}
/* ---- HOW IT WORKS ---- */
.how-section {
background: var(--topo-cream);
position: relative;
overflow: hidden;
}
/* Subtle background contour decoration */
.how-section::before {
content: '';
position: absolute;
width: 600px;
height: 600px;
top: -200px;
right: -200px;
border-radius: 50%;
border: 1px solid rgba(26,82,118,0.05);
pointer-events: none;
}
.how-section::after {
content: '';
position: absolute;
width: 400px;
height: 400px;
bottom: -150px;
left: -100px;
border-radius: 50%;
border: 1px solid rgba(26,82,118,0.04);
pointer-events: none;
}
.how-header {
text-align: center;
margin-bottom: 4rem;
}
.how-header .section-subtitle {
margin: 0 auto;
}
.how-steps {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
max-width: 960px;
margin: 0 auto;
position: relative;
}
/* Connecting line */
.how-steps::before {
content: '';
position: absolute;
top: 40px;
left: calc(16.67% + 24px);
right: calc(16.67% + 24px);
height: 2px;
background: linear-gradient(90deg, var(--water-light), var(--water-mid), var(--water-light));
z-index: 0;
}
.step {
text-align: center;
position: relative;
z-index: 1;
}
.step-number {
width: 56px;
height: 56px;
border-radius: 16px;
background: var(--white);
border: 2px solid var(--water-light);
display: flex;
align-items: center;
justify-content: center;
font-size: 1.1rem;
font-weight: 700;
color: var(--water-deep);
margin: 0 auto 1.25rem;
position: relative;
transition: all 0.3s;
box-shadow: var(--shadow-sm);
}
.step:hover .step-number {
background: var(--water-deep);
color: var(--white);
border-color: var(--water-deep);
transform: scale(1.08);
box-shadow: var(--shadow-md);
}
.step-icon {
font-size: 1.3rem;
}
.step h3 {
font-size: 1.1rem;
font-weight: 700;
margin-bottom: 0.5rem;
color: var(--text-primary);
letter-spacing: -0.3px;
}
.step p {
font-size: 0.92rem;
color: var(--text-secondary);
line-height: 1.55;
max-width: 240px;
margin: 0 auto;
}
/* ---- OPEN SOURCE ---- */
.open-section {
background: var(--white);
position: relative;
}
.open-section::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px;
background: linear-gradient(90deg, transparent, var(--topo-line), transparent);
}
.open-inner {
max-width: 1100px;
margin: 0 auto;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 4rem;
align-items: center;
}
.open-text .section-title {
margin-bottom: 1.5rem;
}
.open-text p {
font-size: 1.05rem;
color: var(--text-secondary);
line-height: 1.7;
margin-bottom: 1rem;
}
.open-text p:last-of-type {
margin-bottom: 2rem;
}
.open-features {
display: flex;
flex-direction: column;
gap: 0.75rem;
margin-top: 1.5rem;
}
.open-feature {
display: flex;
align-items: center;
gap: 0.75rem;
font-size: 0.95rem;
color: var(--text-secondary);
}
.open-feature-check {
width: 22px;
height: 22px;
border-radius: 6px;
background: rgba(39,174,96,0.1);
color: var(--land-mid);
display: flex;
align-items: center;
justify-content: center;
font-size: 0.75rem;
font-weight: 700;
flex-shrink: 0;
}
/* Tech grid */
.tech-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
.tech-item {
background: var(--topo-cream);
border-radius: 16px;
padding: 1.5rem;
text-align: center;
border: 1px solid rgba(26,82,118,0.06);
transition: all 0.25s;
position: relative;
overflow: hidden;
}
.tech-item::before {
content: '';
position: absolute;
inset: 0;
opacity: 0;
transition: opacity 0.25s;
}
.tech-item:hover {
border-color: rgba(26,82,118,0.15);
transform: translateY(-2px);
box-shadow: var(--shadow-md);
}
.tech-name {
font-size: 0.85rem;
font-weight: 700;
color: var(--text-primary);
letter-spacing: 0.5px;
margin-top: 0.5rem;
}
.tech-icon {
font-size: 1.8rem;
margin-bottom: 0.25rem;
display: block;
}
.tech-desc {
font-size: 0.72rem;
color: var(--text-muted);
margin-top: 0.25rem;
}
/* ---- CTA SECTION ---- */
.cta-section {
background: var(--topo-cream);
padding: 5rem 2rem 6rem;
position: relative;
overflow: hidden;
}
.cta-inner {
max-width: 680px;
margin: 0 auto;
text-align: center;
position: relative;
z-index: 2;
}
/* Topo decoration behind CTA */
.cta-section::before {
content: '';
position: absolute;
inset: 0;
background:
radial-gradient(ellipse 300px 250px at 20% 50%, rgba(41,128,185,0.04) 0%, transparent 70%),
radial-gradient(ellipse 250px 300px at 80% 50%, rgba(39,174,96,0.04) 0%, transparent 70%),
radial-gradient(circle 180px at 20% 50%, transparent 55%, rgba(26,82,118,0.03) 56%, rgba(26,82,118,0.03) 57%, transparent 58%),
radial-gradient(circle 120px at 20% 50%, transparent 55%, rgba(26,82,118,0.03) 56%, rgba(26,82,118,0.03) 57%, transparent 58%),
radial-gradient(circle 160px at 80% 50%, transparent 55%, rgba(26,82,118,0.03) 56%, rgba(26,82,118,0.03) 57%, transparent 58%),
radial-gradient(circle 100px at 80% 50%, transparent 55%, rgba(26,82,118,0.03) 56%, rgba(26,82,118,0.03) 57%, transparent 58%);
pointer-events: none;
}
.cta-section .section-title {
margin-bottom: 1rem;
}
.cta-subtitle {
font-size: 1.05rem;
color: var(--text-secondary);
margin-bottom: 2.5rem;
line-height: 1.6;
}
.search-bar {
display: flex;
align-items: center;
background: var(--white);
border-radius: 16px;
padding: 0.5rem;
border: 2px solid rgba(26,82,118,0.1);
box-shadow: var(--shadow-md);
max-width: 520px;
margin: 0 auto 2rem;
transition: border-color 0.3s, box-shadow 0.3s;
}
.search-bar:focus-within {
border-color: var(--water-mid);
box-shadow: var(--shadow-lg), 0 0 0 4px rgba(41,128,185,0.1);
}
.search-icon {
padding: 0 0.75rem 0 0.75rem;
color: var(--text-muted);
font-size: 1.1rem;
flex-shrink: 0;
display: flex;
align-items: center;
}
.search-bar input {
flex: 1;
border: none;
outline: none;
font-size: 1rem;
font-family: inherit;
color: var(--text-primary);
background: transparent;
padding: 0.6rem 0;
}
.search-bar input::placeholder {
color: var(--text-muted);
}
.search-bar .btn-primary {
padding: 0.7rem 1.5rem;
border-radius: 12px;
font-size: 0.9rem;
white-space: nowrap;
}
.cta-or {
color: var(--text-muted);
font-size: 0.85rem;
margin-bottom: 1rem;
}
.cta-links {
display: flex;
align-items: center;
justify-content: center;
gap: 2rem;
flex-wrap: wrap;
}
.cta-links a {
color: var(--water-deep);
text-decoration: none;
font-weight: 600;
font-size: 0.95rem;
transition: color 0.2s;
display: inline-flex;
align-items: center;
gap: 0.3rem;
}
.cta-links a:hover {
color: var(--water-mid);
}
/* ---- FOOTER ---- */
footer {
background: var(--text-primary);
color: rgba(255,255,255,0.6);
padding: 3rem 2rem;
}
.footer-inner {
max-width: 1100px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 1.5rem;
}
.footer-brand {
font-size: 1.15rem;
font-weight: 700;
color: rgba(255,255,255,0.9);
letter-spacing: -0.3px;
}
.footer-links {
display: flex;
gap: 2rem;
flex-wrap: wrap;
}
.footer-links a {
color: rgba(255,255,255,0.5);
text-decoration: none;
font-size: 0.85rem;
transition: color 0.2s;
}
.footer-links a:hover {
color: rgba(255,255,255,0.9);
}
.footer-copy {
font-size: 0.8rem;
width: 100%;
text-align: center;
margin-top: 1.5rem;
padding-top: 1.5rem;
border-top: 1px solid rgba(255,255,255,0.08);
}
/* ---- RESPONSIVE ---- */
@media (max-width: 900px) {
.model-cards {
grid-template-columns: 1fr;
max-width: 420px;
}
.model-card {
min-height: 280px;
}
.how-steps {
grid-template-columns: 1fr;
gap: 2.5rem;
max-width: 320px;
}
.how-steps::before {
display: none;
}
.open-inner {
grid-template-columns: 1fr;
gap: 2.5rem;
}
.tech-grid {
grid-template-columns: repeat(3, 1fr);
}
.hero h1 {
letter-spacing: -1px;
}
}
@media (max-width: 600px) {
nav {
padding: 0 1rem;
}
.nav-links a:not(.nav-cta) {
display: none;
}
section {
padding: 4rem 1.25rem;
}
.hero {
padding: 64px 1.25rem 3rem;
}
.hero-actions {
flex-direction: column;
}
.btn-primary, .btn-secondary {
width: 100%;
justify-content: center;
}
.search-bar {
flex-direction: column;
gap: 0.5rem;
padding: 0.75rem;
}
.search-bar input {
width: 100%;
text-align: center;
}
.search-bar .btn-primary {
width: 100%;
justify-content: center;
}
.search-icon {
display: none;
}
.tech-grid {
grid-template-columns: repeat(2, 1fr);
}
.footer-inner {
flex-direction: column;
text-align: center;
}
.footer-links {
justify-content: center;
}
.scroll-hint {
display: none;
}
.elev-marker {
display: none;
}
.cta-links {
flex-direction: column;
gap: 1rem;
}
}
/* Subtle entrance animations */
@media (prefers-reduced-motion: no-preference) {
.hero-content {
animation: fadeUp 0.8s ease-out both;
}
@keyframes fadeUp {
from {
opacity: 0;
transform: translateY(24px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.model-card {
animation: fadeUp 0.6s ease-out both;
}
.model-card:nth-child(2) { animation-delay: 0.1s; }
.model-card:nth-child(3) { animation-delay: 0.2s; }
}
</style>
</head>
<body>
<!-- Navigation -->
<nav>
<a href="/" class="nav-logo">
<span class="nav-logo-icon"></span>
Hydrata
</a>
<div class="nav-links">
<a href="/catalogue/#/?f=map">Maps</a>
<a href="/about/">About</a>
<a href="/account/signup/" class="nav-cta">Sign Up</a>
</div>
</nav>
<!-- Hero -->
<section class="hero">
<!-- Topographic map background layers -->
<div class="topo-bg"></div>
<div class="contour-lines"></div>
<div class="water-flow">
<div class="river river-1"></div>
<div class="river river-2"></div>
<div class="river river-3"></div>
</div>
<div class="water-shimmer"></div>
<div class="map-grid"></div>
<!-- Elevation markers -->
<span class="elev-marker elev-1">580m</span>
<span class="elev-marker elev-2">320m</span>
<span class="elev-marker elev-3">410m</span>
<span class="elev-marker elev-4">260m</span>
<div class="hero-content">
<div class="hero-badge">
<span class="hero-badge-dot"></span>
Open-source hydraulic modeling
</div>
<h1>See Your <span>Water Data</span></h1>
<p class="hero-tagline">Upload terrain. Run flood simulations. Visualize results on interactive maps. Powered by ANUGA, in your browser.</p>
<div class="hero-actions">
<a href="/catalogue/#/?f=map" class="btn-primary">
Explore Maps <span class="arrow">&rarr;</span>
</a>
<a href="/account/signup/" class="btn-secondary">
Create Free Account
</a>
</div>
</div>
<div class="scroll-hint">
<span>Scroll</span>
<div class="scroll-line"></div>
</div>
</section>
<!-- What You Can Model -->
<section class="model-section">
<div class="model-header">
<span class="section-label">Capabilities</span>
<h2 class="section-title">What You Can Model</h2>
<p class="section-subtitle">From flash floods to long-term watershed management, simulate real-world hydrology on real terrain.</p>
</div>
<div class="model-cards">
<div class="model-card card-flood">
<div class="model-card-icon">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 15c6.667-6 13.333 0 20-6"/><path d="M2 19c6.667-6 13.333 0 20-6"/></svg>
</div>
<h3>Flood Risk Assessment</h3>
<p>Model inundation depths, flow velocities, and flood extents across complex terrain to identify vulnerable areas before events occur.</p>
</div>
<div class="model-card card-storm">
<div class="model-card-icon">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242"/><path d="M16 14v6"/><path d="M8 14v6"/><path d="M12 16v6"/></svg>
</div>
<h3>Stormwater Management</h3>
<p>Evaluate best management practices, design retention systems, and quantify runoff reduction across urban and peri-urban landscapes.</p>
</div>
<div class="model-card card-watershed">
<div class="model-card-icon">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>
</div>
<h3>Watershed Planning</h3>
<p>Delineate catchments, trace flow paths, and assess cumulative impacts of land use changes on downstream hydrology.</p>
</div>
</div>
</section>
<!-- How It Works -->
<section class="how-section">
<div class="how-header">
<span class="section-label">Workflow</span>
<h2 class="section-title">Three Steps to Results</h2>
<p class="section-subtitle">From raw terrain data to actionable flood maps in minutes, not months.</p>
</div>
<div class="how-steps">
<div class="step">
<div class="step-number">
<span class="step-icon">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
</span>
</div>
<h3>Upload Terrain</h3>
<p>Drag in your DEM, elevation raster, or point cloud. We handle the projection and meshing.</p>
</div>
<div class="step">
<div class="step-number">
<span class="step-icon">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>
</span>
</div>
<h3>Configure &amp; Run</h3>
<p>Set boundary conditions, inflow hydrographs, and friction. Hit run. ANUGA does the physics.</p>
</div>
<div class="step">
<div class="step-number">
<span class="step-icon">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6"/><line x1="8" y1="2" x2="8" y2="18"/><line x1="16" y1="6" x2="16" y2="22"/></svg>
</span>
</div>
<h3>Map the Results</h3>
<p>Visualize flood depths, velocities, and hazard zones as interactive map layers you can share.</p>
</div>
</div>
</section>
<!-- Open Data, Open Source -->
<section class="open-section">
<div class="open-inner">
<div class="open-text">
<span class="section-label">Principles</span>
<h2 class="section-title">Open Data,<br>Open Source</h2>
<p>Hydrata is built on the belief that water modeling should be transparent, reproducible, and accessible. Every simulation runs on open-source solvers. Every dataset uses open standards.</p>
<p>No vendor lock-in. No proprietary formats. Your data stays yours, served through OGC-compliant APIs that integrate with any GIS platform.</p>
<div class="open-features">
<div class="open-feature">
<span class="open-feature-check">&#10003;</span>
<span>Full simulation reproducibility</span>
</div>
<div class="open-feature">
<span class="open-feature-check">&#10003;</span>
<span>OGC WMS/WFS/WCS compliant</span>
</div>
<div class="open-feature">
<span class="open-feature-check">&#10003;</span>
<span>Download raw results anytime</span>
</div>
<div class="open-feature">
<span class="open-feature-check">&#10003;</span>
<span>Community-driven development</span>
</div>
</div>
</div>
<div class="tech-grid">
<div class="tech-item">
<span class="tech-icon">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#2980b9" stroke-width="1.5"><path d="M2 15c6.667-6 13.333 0 20-6"/><path d="M2 19c6.667-6 13.333 0 20-6"/><path d="M2 11c6.667-6 13.333 0 20-6"/></svg>
</span>
<div class="tech-name">ANUGA</div>
<div class="tech-desc">Hydrodynamic solver</div>
</div>
<div class="tech-item">
<span class="tech-icon">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#27ae60" stroke-width="1.5"><circle cx="12" cy="12" r="9"/><path d="M12 3v18"/><path d="M3 12h18"/><ellipse cx="12" cy="12" rx="4" ry="9"/></svg>
</span>
<div class="tech-name">PostGIS</div>
<div class="tech-desc">Spatial database</div>
</div>
<div class="tech-item">
<span class="tech-icon">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#6e4b3a" stroke-width="1.5"><rect x="3" y="3" width="18" height="18" rx="3"/><path d="M3 9h18"/><path d="M9 3v18"/></svg>
</span>
<div class="tech-name">GeoServer</div>
<div class="tech-desc">Map services</div>
</div>
<div class="tech-item">
<span class="tech-icon">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#935116" stroke-width="1.5"><polygon points="12 2 22 8.5 22 15.5 12 22 2 15.5 2 8.5 12 2"/><line x1="12" y1="22" x2="12" y2="8.5"/><line x1="22" y1="8.5" x2="2" y2="8.5"/></svg>
</span>
<div class="tech-name">OGC</div>
<div class="tech-desc">Open standards</div>
</div>
<div class="tech-item">
<span class="tech-icon">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#1a5276" stroke-width="1.5"><path d="M12 18.5c-4.136 0-7.5-2.91-7.5-6.5S7.864 5.5 12 5.5s7.5 2.91 7.5 6.5c0 1.68-.75 3.22-2 4.38"/><circle cx="9" cy="11" r="1.25" fill="#1a5276"/><circle cx="15" cy="11" r="1.25" fill="#1a5276"/><path d="M9 14.5c1 1 5 1 6 0"/></svg>
</span>
<div class="tech-name">Python</div>
<div class="tech-desc">Backend engine</div>
</div>
<div class="tech-item">
<span class="tech-icon">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#2471a3" stroke-width="1.5"><polygon points="1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6"/><line x1="8" y1="2" x2="8" y2="18"/><line x1="16" y1="6" x2="16" y2="22"/></svg>
</span>
<div class="tech-name">MapStore</div>
<div class="tech-desc">Web mapping</div>
</div>
</div>
</div>
</section>
<!-- CTA -->
<section class="cta-section">
<div class="cta-inner">
<span class="section-label">Get started</span>
<h2 class="section-title">Start Exploring</h2>
<p class="cta-subtitle">Search for a location or browse existing flood models and geospatial datasets shared by the community.</p>
<div class="search-bar">
<span class="search-icon">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
</span>
<input type="text" placeholder="Search locations, models, datasets..." />
<a href="/catalogue/#/?f=map" class="btn-primary">Search</a>
</div>
<p class="cta-or">or</p>
<div class="cta-links">
<a href="/catalogue/#/?f=map">
Browse all maps
<span>&rarr;</span>
</a>
<a href="/account/signup/">
Create an account
<span>&rarr;</span>
</a>
</div>
</div>
</section>
<!-- Footer -->
<footer>
<div class="footer-inner">
<div class="footer-brand">Hydrata</div>
<div class="footer-links">
<a href="/catalogue/#/?f=map">Maps</a>
<a href="/about/">About</a>
<a href="https://github.com/Hydrata">GitHub</a>
<a href="/account/signup/">Sign Up</a>
</div>
<div class="footer-copy">
Built on open-source technology. Powered by ANUGA, GeoNode, and the open geospatial community.
</div>
</div>
</footer>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment