d718c5a372
CI / windows_test (push) Waiting to run
CI / compile_and_lint (push) Failing after 0s
CI / docker_build (linux/amd64, -linux-amd64-duckdb, duckdb) (push) Failing after 0s
CI / docker_build (linux/arm64, -linux-arm64, minimal) (push) Failing after 2s
CI / docker_build (linux/arm64, -linux-arm64-duckdb, duckdb) (push) Failing after 1s
CI / docker_build (linux/amd64, minimal) (push) Failing after 1s
CI / test (, sqlite, sqlite::memory:) (push) Has been skipped
CI / test (mssql, mssql, mssql://root:Password123!@127.0.0.1/sqlpage) (push) Has been skipped
CI / test (mysql, mysql, mysql://root:Password123!@127.0.0.1/sqlpage) (push) Has been skipped
CI / test (oracle, oracle, Driver=Oracle 21 ODBC driver;Dbq=//127.0.0.1:1521/FREEPDB1;Uid=root;Pwd=Password123!) (push) Has been skipped
CI / test (postgres, odbc, Driver=PostgreSQL Unicode;Server=127.0.0.1;Port=5432;Database=sqlpage;UID=root;PWD=Password123!, true) (push) Has been skipped
CI / test (postgres, postgres, postgres://root:Password123!@127.0.0.1/sqlpage) (push) Has been skipped
CI / playwright (push) Has been skipped
CI / docker_build (linux/arm/v7, -linux-arm-v7, minimal) (push) Failing after 0s
CI / hurl_examples (push) Failing after 8s
deploy website / deploy_official_site (push) Failing after 1s
CI / docker_push (duckdb) (push) Waiting to run
CI / docker_push (minimal) (push) Waiting to run
CI / hurl (${{ matrix.example }}) (push) Has been skipped
1517 lines
48 KiB
Handlebars
1517 lines
48 KiB
Handlebars
<!doctype html>
|
||
<html lang="en">
|
||
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
||
<title>SQLPage - SQL websites</title>
|
||
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<meta property="og:title" content="SQLPage: SQL websites" />
|
||
<meta name="description"
|
||
content="Build interactive websites and apps with only SQL queries. SQLPage is an open-source tool to generate nice user interfaces on top of traditional databases. Maps, charts, tables, forms, and dashboards - without traditional web programming." />
|
||
<meta property="og:description" content="Build interactive websites with only SQL queries." />
|
||
<meta property="og:image" content="/sqlpage_social_preview.webp" />
|
||
<meta name="twitter:image" content="/sqlpage_social_preview.webp" />
|
||
<meta name="generator" content="SQLPage" />
|
||
|
||
<style>
|
||
/* ROOT VARIABLES
|
||
===============
|
||
Color system based on SQLPage visual identity.
|
||
|
||
BRAND COLORS (from visual-identity.sql):
|
||
- Primary Cyan: #37E5EF - bright accent, use sparingly
|
||
- Teal: #2A9FAF - secondary accent
|
||
- Dark Navy: #0a0f1a - primary background
|
||
|
||
DESIGN PRINCIPLE:
|
||
Bright cyan is an ACCENT color for small elements (buttons, borders, hovers).
|
||
Gradients and large areas use darker, desaturated tones for readability.
|
||
*/
|
||
:root {
|
||
/* === BRAND COLORS === */
|
||
--brand-cyan: #37E5EF;
|
||
--brand-teal: #2A9FAF;
|
||
--brand-navy: #0a0f1a;
|
||
|
||
/* === BACKGROUNDS ===
|
||
Dark navy family - slight teal undertone for cohesion */
|
||
--bg-primary: #0a0f1a;
|
||
--bg-secondary: #0c1520;
|
||
--bg-tertiary: #101c28;
|
||
--bg-elevated: #142430;
|
||
|
||
/* === TEXT === */
|
||
--text-primary: #f0f4f7;
|
||
--text-secondary: #8a9baa;
|
||
--text-muted: rgba(255, 255, 255, 0.6);
|
||
|
||
/* === ACCENT COLORS ===
|
||
For buttons, links, highlights - the bright brand colors */
|
||
--accent-primary: var(--brand-cyan);
|
||
--accent-secondary: var(--brand-teal);
|
||
|
||
/* === GRADIENT COLORS ===
|
||
Darker, desaturated versions for large area gradients.
|
||
These blend smoothly without harsh contrast. */
|
||
--gradient-dark: #0d1a24;
|
||
--gradient-mid: #153040;
|
||
--gradient-light: #1a4055;
|
||
|
||
/* === GLOW COLORS ===
|
||
Semi-transparent brand colors for subtle atmospheric effects */
|
||
--glow-cyan: rgba(55, 229, 239, 0.15);
|
||
--glow-teal: rgba(42, 159, 175, 0.12);
|
||
--glow-subtle: rgba(55, 229, 239, 0.06);
|
||
|
||
/* === OVERLAYS === */
|
||
--overlay-light: rgba(255, 255, 255, 0.03);
|
||
--overlay-lighter: rgba(255, 255, 255, 0.05);
|
||
--overlay-lightest: rgba(255, 255, 255, 0.12);
|
||
|
||
/* === BORDERS === */
|
||
--border-subtle: rgba(55, 229, 239, 0.08);
|
||
--border-light: rgba(55, 229, 239, 0.15);
|
||
--border-medium: rgba(55, 229, 239, 0.25);
|
||
|
||
/* === GRADIENTS ===
|
||
Primary: for buttons and interactive elements
|
||
Atmospheric: for background decoration */
|
||
--gradient-primary: linear-gradient(135deg,
|
||
var(--brand-teal) 0%,
|
||
var(--brand-cyan) 100%);
|
||
--gradient-atmospheric: linear-gradient(135deg,
|
||
var(--gradient-dark) 0%,
|
||
var(--gradient-mid) 100%);
|
||
|
||
/* === SHADOWS === */
|
||
--shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.25);
|
||
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.3);
|
||
--shadow-glow: 0 0 20px var(--glow-cyan);
|
||
|
||
/* === SPACING === */
|
||
--container-padding: 40px;
|
||
--container-width: 1000px;
|
||
--gap-sm: 20px;
|
||
--gap-md: 40px;
|
||
--gap-lg: 60px;
|
||
|
||
/* === TRANSITIONS === */
|
||
--transition-fast: 0.3s ease;
|
||
--transition-medium: 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||
--transition-slow: 0.6s cubic-bezier(0.22, 1, 0.36, 1);
|
||
}
|
||
|
||
/* Firefox scrollbar styles */
|
||
* {
|
||
scrollbar-width: thin;
|
||
scrollbar-color: var(--border-medium) var(--bg-primary);
|
||
}
|
||
|
||
/* RESET */
|
||
* {
|
||
margin: 0;
|
||
padding: 0;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
html,
|
||
body {
|
||
width: 100%;
|
||
height: 100%;
|
||
font-family: sans-serif;
|
||
display: block;
|
||
background-color: var(--bg-primary);
|
||
color: var(--text-primary);
|
||
background-image:
|
||
radial-gradient(ellipse 80% 60% at 100% 0%,
|
||
var(--glow-cyan) 0%,
|
||
transparent 70%),
|
||
radial-gradient(ellipse 70% 50% at 0% 100%,
|
||
var(--glow-teal) 0%,
|
||
transparent 70%),
|
||
linear-gradient(160deg,
|
||
var(--bg-primary) 0%,
|
||
var(--bg-secondary) 100%);
|
||
backface-visibility: hidden;
|
||
-webkit-backface-visibility: hidden;
|
||
-moz-backface-visibility: hidden;
|
||
transform: translate3d(0, 0, 0);
|
||
-webkit-transform: translate3d(0, 0, 0);
|
||
-moz-transform: translate3d(0, 0, 0);
|
||
overflow-x: hidden;
|
||
scroll-behavior: smooth;
|
||
}
|
||
|
||
.container:first-of-type {
|
||
min-height: 100vh;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
position: relative;
|
||
}
|
||
|
||
/* CONTAINER */
|
||
.container {
|
||
text-align: left;
|
||
max-width: var(--container-width);
|
||
width: 90%;
|
||
margin: 0 auto;
|
||
padding: var(--container-padding);
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--gap-lg);
|
||
}
|
||
|
||
/* LOGO WRAPPER */
|
||
.logo {
|
||
width: 300px;
|
||
height: 300px;
|
||
flex-shrink: 0;
|
||
animation: floatWaves 6s ease-in-out infinite;
|
||
margin-bottom: .5rem;
|
||
}
|
||
|
||
@keyframes floatWaves {
|
||
|
||
0%,
|
||
100% {
|
||
transform: rotate(-15deg) translateY(0px) scale(1);
|
||
|
||
}
|
||
|
||
50% {
|
||
transform: rotate(-15deg) translateY(-10px) scale(1.01);
|
||
}
|
||
}
|
||
|
||
/* TEXT WRAPPER */
|
||
.text-content {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--gap-sm);
|
||
animation: fadeIn 1s ease-out;
|
||
}
|
||
|
||
@keyframes fadeIn {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(20px);
|
||
}
|
||
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
/* LOGO WRAPPER - ENHANCED STYLING */
|
||
.logo {
|
||
display: inline-block;
|
||
width: 220px;
|
||
height: 220px;
|
||
transform: rotate(-15deg);
|
||
position: relative;
|
||
transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||
box-shadow:
|
||
inset 0 0 20px rgba(0, 0, 0, 0.7),
|
||
0 5px 15px rgba(0, 0, 0, 0.6);
|
||
border-radius: 12px;
|
||
overflow: hidden;
|
||
background: linear-gradient(135deg, var(--glow-teal), var(--glow-subtle));
|
||
margin-right: 30px;
|
||
animation: floatWaves 6s ease-in-out infinite;
|
||
}
|
||
|
||
.logo:hover {
|
||
transform: rotate(-5deg) scale(1.08) translateY(-5px);
|
||
box-shadow:
|
||
inset 0 0 25px rgba(0, 0, 0, 0.8),
|
||
0 12px 30px rgba(0, 0, 0, 0.4),
|
||
0 4px 8px rgba(0, 0, 0, 0.3);
|
||
animation: buzz 0.6s;
|
||
}
|
||
|
||
@keyframes buzz {
|
||
|
||
0%,
|
||
100% {
|
||
transform: rotate(-5deg) scale(1.08) translateY(-5px);
|
||
}
|
||
|
||
20% {
|
||
transform: rotate(-3deg) scale(1.08) translateY(-5px);
|
||
}
|
||
|
||
40% {
|
||
transform: rotate(-7deg) scale(1.08) translateY(-5px);
|
||
}
|
||
|
||
60% {
|
||
transform: rotate(-3deg) scale(1.08) translateY(-5px);
|
||
}
|
||
|
||
80% {
|
||
transform: rotate(-7deg) scale(1.08) translateY(-5px);
|
||
}
|
||
}
|
||
|
||
.logo svg {
|
||
transition: transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||
}
|
||
|
||
.logo:hover svg {
|
||
transform: scale(0.95) translateY(2px);
|
||
}
|
||
|
||
/* TITLE & TAGLINE - ENHANCED */
|
||
h1 {
|
||
font-size: 4rem;
|
||
margin-bottom: 15px;
|
||
font-weight: 800;
|
||
letter-spacing: -1px;
|
||
transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||
transform: scale(1) translateX(0) translateY(0) translateZ(0);
|
||
}
|
||
|
||
h1:hover {
|
||
color: white;
|
||
background: none;
|
||
transform: scale(1.02) translateX(8px) translateY(-8px) translateZ(2px);
|
||
}
|
||
|
||
h1 span:first-child {
|
||
margin-right: 0;
|
||
transition: margin-right 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||
}
|
||
|
||
h1:hover span:first-child {
|
||
margin-right: 0.5em;
|
||
}
|
||
|
||
h1 .words {
|
||
position: relative;
|
||
}
|
||
|
||
h1 .words span {
|
||
position: absolute;
|
||
left: 0;
|
||
opacity: 0;
|
||
}
|
||
|
||
h1 .words span:first-child {
|
||
opacity: 1;
|
||
position: relative;
|
||
transform: translateX(0);
|
||
}
|
||
|
||
h1:hover .words span {
|
||
text-shadow: 0 0 3px rgba(255, 255, 255, 0.5);
|
||
/* Total animation time: 8 words × 2s per word = 16s total cycle */
|
||
animation: rotateWords 16s ease-in-out infinite;
|
||
}
|
||
|
||
|
||
/* Delays: each word starts at 2s intervals
|
||
2s × (n-1) -1s where n is the word position */
|
||
h1:hover .words span:nth-child(1) {
|
||
animation-delay: -1s;
|
||
}
|
||
|
||
h1:hover .words span:nth-child(2) {
|
||
animation-delay: 1s;
|
||
}
|
||
|
||
h1:hover .words span:nth-child(3) {
|
||
animation-delay: 3s;
|
||
}
|
||
|
||
h1:hover .words span:nth-child(4) {
|
||
animation-delay: 5s;
|
||
}
|
||
|
||
h1:hover .words span:nth-child(5) {
|
||
animation-delay: 7s;
|
||
}
|
||
|
||
h1:hover .words span:nth-child(6) {
|
||
animation-delay: 9s;
|
||
}
|
||
|
||
h1:hover .words span:nth-child(7) {
|
||
animation-delay: 11s;
|
||
}
|
||
|
||
h1:hover .words span:nth-child(8) {
|
||
animation-delay: 13s;
|
||
}
|
||
|
||
/** Each word needs to appear for 2s, then disappear for the rest of the animation.
|
||
2s / 16s = 12.5% of the animation time.
|
||
**/
|
||
@keyframes rotateWords {
|
||
0% {
|
||
opacity: 0;
|
||
}
|
||
|
||
3%,
|
||
9.5% {
|
||
opacity: 1;
|
||
}
|
||
|
||
12%,
|
||
100% {
|
||
opacity: 0;
|
||
}
|
||
}
|
||
|
||
@keyframes shimmer {
|
||
0% {
|
||
background-position: 400% 0;
|
||
}
|
||
|
||
100% {
|
||
background-position: -400% 0;
|
||
}
|
||
}
|
||
|
||
p {
|
||
font-size: 2rem;
|
||
color: var(--text-secondary);
|
||
line-height: 1.4;
|
||
transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||
}
|
||
|
||
/* RESPONSIVE ADJUSTMENTS */
|
||
@media (max-width: 900px) {
|
||
:root {
|
||
--container-padding: 30px;
|
||
--gap-lg: 40px;
|
||
}
|
||
|
||
.container {
|
||
gap: var(--gap-lg);
|
||
padding: var(--container-padding);
|
||
}
|
||
|
||
.logo {
|
||
width: 250px;
|
||
height: 250px;
|
||
}
|
||
|
||
h1 {
|
||
font-size: 3.5rem;
|
||
}
|
||
|
||
p {
|
||
font-size: 1.8rem;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
:root {
|
||
--container-padding: 20px;
|
||
--gap-lg: 30px;
|
||
}
|
||
|
||
.container {
|
||
flex-direction: column;
|
||
text-align: center;
|
||
gap: var(--gap-lg);
|
||
}
|
||
|
||
.text-content {
|
||
align-items: center;
|
||
}
|
||
|
||
.logo {
|
||
width: 200px;
|
||
height: 200px;
|
||
margin-right: 0;
|
||
}
|
||
|
||
h1 {
|
||
font-size: 3rem;
|
||
}
|
||
|
||
p {
|
||
font-size: 1.6rem;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 480px) {
|
||
.container {
|
||
padding: var(--container-padding);
|
||
gap: var(--gap-lg);
|
||
}
|
||
|
||
.logo {
|
||
width: 150px;
|
||
height: 150px;
|
||
}
|
||
|
||
h1 {
|
||
font-size: 2.5rem;
|
||
}
|
||
|
||
p {
|
||
font-size: 1.4rem;
|
||
}
|
||
}
|
||
|
||
/* MENU STYLES */
|
||
.menu {
|
||
position: fixed;
|
||
top: 2rem;
|
||
right: 2rem;
|
||
display: flex;
|
||
gap: 0.5rem;
|
||
z-index: 1000;
|
||
background: rgba(10, 15, 26, 0.85);
|
||
backdrop-filter: blur(12px);
|
||
padding: 0.6rem 1rem;
|
||
border-radius: 8px;
|
||
border: 1px solid var(--border-subtle);
|
||
}
|
||
|
||
.menu a {
|
||
color: var(--text-secondary);
|
||
text-decoration: none;
|
||
font-size: 0.85rem;
|
||
padding: 0.4rem 0.8rem;
|
||
border-radius: 6px;
|
||
position: relative;
|
||
transition: all 0.2s ease;
|
||
}
|
||
|
||
.menu a:hover {
|
||
color: var(--text-primary);
|
||
background: var(--overlay-lighter);
|
||
text-decoration: none;
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.menu {
|
||
top: 1rem;
|
||
right: 1rem;
|
||
gap: 0.25rem;
|
||
padding: 0.4rem 0.6rem;
|
||
}
|
||
|
||
.menu a {
|
||
font-size: 0.8rem;
|
||
padding: 0.3rem 0.5rem;
|
||
}
|
||
}
|
||
|
||
/* CTA BUTTON - Minimal, transparent base */
|
||
.cta-button {
|
||
display: inline-block;
|
||
text-align: center;
|
||
padding: .8rem 2rem;
|
||
min-width: 200px;
|
||
max-width: 300px;
|
||
font-size: 1.2rem;
|
||
font-weight: 600;
|
||
background: transparent;
|
||
color: var(--text-primary);
|
||
text-decoration: none !important;
|
||
border-radius: 8px;
|
||
transition: all var(--transition-fast);
|
||
border: 1px solid var(--border-medium);
|
||
cursor: pointer;
|
||
margin-top: 1.5rem;
|
||
}
|
||
|
||
.cta-button:hover {
|
||
color: var(--brand-cyan);
|
||
border-color: var(--brand-cyan);
|
||
background: rgba(55, 229, 239, 0.05);
|
||
text-decoration: none !important;
|
||
}
|
||
|
||
.cta-button:active {
|
||
background: rgba(55, 229, 239, 0.1);
|
||
transition-duration: 0.1s;
|
||
}
|
||
|
||
.cta-button:focus {
|
||
outline: none;
|
||
border-color: var(--brand-cyan);
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.cta-button {
|
||
font-size: 1.1rem;
|
||
padding: 0.7rem 1.8rem;
|
||
min-width: 180px;
|
||
}
|
||
}
|
||
|
||
.scroll-link {
|
||
position: fixed;
|
||
bottom: 1.5rem;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
color: var(--text-secondary);
|
||
opacity: 0.5;
|
||
transition: all 0.3s ease;
|
||
animation: bounce 3s infinite;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.scroll-link svg {
|
||
width: 32px;
|
||
height: 32px;
|
||
}
|
||
|
||
.scroll-link:hover {
|
||
color: var(--text-primary);
|
||
opacity: 0.8;
|
||
transform: translateX(-50%) scale(1.05);
|
||
}
|
||
|
||
@keyframes bounce {
|
||
|
||
0%,
|
||
20%,
|
||
50%,
|
||
80%,
|
||
100% {
|
||
transform: translateX(-50%) translateY(0);
|
||
}
|
||
|
||
40% {
|
||
transform: translateX(-50%) translateY(-6px);
|
||
}
|
||
|
||
60% {
|
||
transform: translateX(-50%) translateY(-3px);
|
||
}
|
||
}
|
||
|
||
#features {
|
||
min-height: 100vh;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: linear-gradient(135deg,
|
||
var(--bg-secondary) 0%,
|
||
var(--bg-tertiary) 100%);
|
||
}
|
||
|
||
#features .container {
|
||
flex-direction: column;
|
||
gap: 3rem;
|
||
}
|
||
|
||
#features h2 {
|
||
font-size: 3.5rem;
|
||
margin-bottom: 1rem;
|
||
color: var(--text-primary);
|
||
}
|
||
|
||
.features-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
gap: 2.5rem;
|
||
perspective: 1000px;
|
||
}
|
||
|
||
.feature-card {
|
||
background: var(--overlay-light);
|
||
border: 1px solid var(--border-subtle);
|
||
border-radius: 16px;
|
||
padding: 2.5rem;
|
||
transform-style: preserve-3d;
|
||
transform: perspective(1000px) rotateX(10deg);
|
||
transition: all var(--transition-slow);
|
||
backdrop-filter: blur(10px);
|
||
box-shadow: var(--shadow-lg);
|
||
}
|
||
|
||
.feature-card:hover {
|
||
transform: perspective(1000px) rotateX(0deg) translateY(-10px);
|
||
background: var(--overlay-lighter);
|
||
border-color: var(--border-light);
|
||
}
|
||
|
||
.feature-card h3 {
|
||
font-size: 1.5rem;
|
||
margin-bottom: 1rem;
|
||
color: var(--text-primary);
|
||
position: relative;
|
||
}
|
||
|
||
.feature-card h3::before {
|
||
content: '';
|
||
position: absolute;
|
||
width: 30px;
|
||
height: 2px;
|
||
background: var(--gradient-primary);
|
||
bottom: -8px;
|
||
left: 0;
|
||
transform: scaleX(0);
|
||
transform-origin: left;
|
||
transition: transform 0.3s ease;
|
||
}
|
||
|
||
.feature-card:hover h3::before {
|
||
transform: scaleX(1);
|
||
}
|
||
|
||
.feature-card p {
|
||
font-size: 1rem;
|
||
line-height: 1.6;
|
||
color: var(--text-secondary);
|
||
margin-top: 1rem;
|
||
}
|
||
|
||
.feature-icon {
|
||
font-size: 2rem;
|
||
margin-bottom: 1.5rem;
|
||
opacity: 0.8;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.feature-card:hover .feature-icon {
|
||
opacity: 1;
|
||
transform: translateY(-5px);
|
||
}
|
||
|
||
@media (max-width: 968px) {
|
||
.features-grid {
|
||
grid-template-columns: repeat(2, 1fr);
|
||
}
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.features-grid {
|
||
grid-template-columns: 1fr;
|
||
gap: 1.5rem;
|
||
}
|
||
|
||
#features .container {
|
||
gap: 3rem;
|
||
}
|
||
|
||
.feature-card {
|
||
padding: 2rem;
|
||
}
|
||
}
|
||
|
||
.feature-section {
|
||
min-height: 100vh;
|
||
display: flex;
|
||
align-items: center;
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.feature-section:nth-child(odd) {
|
||
background: linear-gradient(135deg,
|
||
var(--bg-secondary) 0%,
|
||
var(--bg-tertiary) 100%);
|
||
}
|
||
|
||
.feature-section .container {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 4rem;
|
||
align-items: center;
|
||
}
|
||
|
||
.feature-section:nth-child(even) .container {
|
||
direction: rtl;
|
||
}
|
||
|
||
.feature-section:nth-child(even) .feature-content {
|
||
direction: ltr;
|
||
}
|
||
|
||
.feature-content {
|
||
max-width: 500px;
|
||
}
|
||
|
||
.feature-content .gradient-title {
|
||
font-size: 2.5rem;
|
||
margin-bottom: 1.5rem;
|
||
background: var(--gradient-primary);
|
||
-webkit-background-clip: text;
|
||
background-clip: text;
|
||
color: transparent;
|
||
}
|
||
|
||
.feature-content p {
|
||
font-size: 1.2rem;
|
||
margin-bottom: 2rem;
|
||
}
|
||
|
||
.feature-image {
|
||
position: relative;
|
||
border-radius: 12px;
|
||
overflow: hidden;
|
||
box-shadow: var(--shadow-lg);
|
||
transition: transform var(--transition-medium);
|
||
}
|
||
|
||
.feature-image:hover {
|
||
transform: translateY(-10px);
|
||
}
|
||
|
||
.feature-image img,
|
||
.feature-image video {
|
||
width: 100%;
|
||
object-fit: cover;
|
||
object-position: left;
|
||
display: block;
|
||
}
|
||
|
||
@media (max-width: 968px) {
|
||
.feature-section .container {
|
||
grid-template-columns: 1fr;
|
||
text-align: center;
|
||
}
|
||
|
||
.feature-content {
|
||
max-width: 100%;
|
||
}
|
||
}
|
||
|
||
.compat-section {
|
||
position: relative;
|
||
background:
|
||
radial-gradient(ellipse 60% 50% at 20% 20%, var(--glow-teal), transparent 60%),
|
||
radial-gradient(ellipse 50% 40% at 80% 10%, var(--glow-subtle), transparent 60%),
|
||
linear-gradient(160deg, var(--bg-secondary), var(--bg-primary));
|
||
overflow: hidden;
|
||
isolation: isolate;
|
||
}
|
||
|
||
.compat-section::before,
|
||
.compat-section::after {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 0;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.compat-section::before {
|
||
background-image: radial-gradient(2px 2px at 25px 35px, rgba(255, 255, 255, 0.6), transparent), radial-gradient(1px 1px at 120px 80px, rgba(255, 255, 255, 0.4), transparent), radial-gradient(1.5px 1.5px at 220px 140px, rgba(255, 255, 255, 0.55), transparent), radial-gradient(2px 2px at 320px 60px, rgba(255, 255, 255, 0.5), transparent), radial-gradient(1px 1px at 420px 180px, rgba(255, 255, 255, 0.4), transparent), radial-gradient(1.5px 1.5px at 520px 90px, rgba(255, 255, 255, 0.5), transparent);
|
||
background-size: 240px 220px;
|
||
opacity: 0.45;
|
||
animation: twinkle 14s linear infinite;
|
||
}
|
||
|
||
.compat-section::after {
|
||
background: radial-gradient(450px 450px at 80% 110%, var(--glow-teal), transparent 70%);
|
||
}
|
||
|
||
.compat-layout {
|
||
display: grid;
|
||
grid-template-columns: minmax(400px, 1fr) minmax(450px, 1.2fr);
|
||
gap: var(--gap-lg);
|
||
padding-top: calc(var(--container-padding) * 1.5);
|
||
padding-bottom: calc(var(--container-padding) * 1.5);
|
||
position: relative;
|
||
z-index: 1;
|
||
}
|
||
|
||
.compat-intro {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 1.5rem;
|
||
}
|
||
|
||
.compat-eyebrow {
|
||
font-size: 0.85rem;
|
||
letter-spacing: 0.3em;
|
||
text-transform: uppercase;
|
||
color: var(--brand-cyan);
|
||
opacity: 0.7;
|
||
}
|
||
|
||
.compat-intro h2 {
|
||
font-size: 3.2rem;
|
||
line-height: 1.1;
|
||
color: var(--text-primary);
|
||
}
|
||
|
||
.compat-intro p {
|
||
font-size: 1.15rem;
|
||
color: var(--text-secondary);
|
||
max-width: 90%;
|
||
}
|
||
|
||
.compat-highlights {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 0.75rem;
|
||
}
|
||
|
||
.compat-pill {
|
||
padding: 0.45rem 0.9rem;
|
||
border-radius: 999px;
|
||
background: var(--overlay-lighter);
|
||
border: 1px solid var(--border-light);
|
||
color: var(--text-primary);
|
||
font-size: 0.85rem;
|
||
backdrop-filter: blur(6px);
|
||
}
|
||
|
||
.compat-showcase {
|
||
position: relative;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 2rem;
|
||
width: 100%;
|
||
min-width: 0;
|
||
}
|
||
|
||
.compat-orbit {
|
||
position: relative;
|
||
width: 320px;
|
||
height: 320px;
|
||
margin: 0 auto;
|
||
border-radius: 50%;
|
||
background: radial-gradient(circle, var(--gradient-mid), var(--bg-tertiary));
|
||
box-shadow: inset 0 0 40px var(--glow-subtle), 0 20px 60px rgba(0, 0, 0, 0.5);
|
||
}
|
||
|
||
.compat-orbit::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 14px;
|
||
border-radius: 50%;
|
||
border: 1px dashed var(--border-medium);
|
||
animation: orbitSpin 26s linear infinite;
|
||
}
|
||
|
||
.compat-orbit::after {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 44px;
|
||
border-radius: 50%;
|
||
border: 1px solid var(--border-subtle);
|
||
filter: blur(0.3px);
|
||
}
|
||
|
||
.compat-core {
|
||
position: absolute;
|
||
width: 160px;
|
||
height: 160px;
|
||
border-radius: 50%;
|
||
background: radial-gradient(circle at 30% 30%, var(--bg-elevated), var(--bg-tertiary));
|
||
box-shadow: var(--shadow-glow);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
text-align: center;
|
||
padding: 1rem;
|
||
color: var(--text-primary);
|
||
font-size: 0.9rem;
|
||
line-height: 1.3;
|
||
backdrop-filter: blur(6px);
|
||
margin: auto;
|
||
top: 50%;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%);
|
||
}
|
||
|
||
.compat-node {
|
||
position: absolute;
|
||
width: 84px;
|
||
height: 84px;
|
||
border-radius: 18px;
|
||
background: var(--bg-secondary);
|
||
box-shadow: var(--shadow-lg), inset 0 0 24px var(--glow-subtle);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
backdrop-filter: blur(10px);
|
||
border: 1px solid var(--border-light);
|
||
outline: 1px solid rgba(0, 0, 0, 0.3);
|
||
outline-offset: -4px;
|
||
}
|
||
|
||
.compat-node img {
|
||
width: 54px;
|
||
height: 54px;
|
||
}
|
||
|
||
.compat-node:nth-child(2) {
|
||
top: 6%;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%);
|
||
animation: floatNode 7s ease-in-out infinite;
|
||
}
|
||
|
||
.compat-node:nth-child(3) {
|
||
top: 50%;
|
||
right: 2%;
|
||
transform: translate(50%, -50%);
|
||
animation: floatNode 9s ease-in-out infinite;
|
||
}
|
||
|
||
.compat-node:nth-child(4) {
|
||
bottom: 4%;
|
||
left: 50%;
|
||
transform: translate(-50%, 50%);
|
||
animation: floatNode 8s ease-in-out infinite;
|
||
}
|
||
|
||
.compat-node:nth-child(5) {
|
||
top: 50%;
|
||
left: 2%;
|
||
transform: translate(-50%, -50%);
|
||
animation: floatNode 10s ease-in-out infinite;
|
||
}
|
||
|
||
.compat-card {
|
||
background: rgba(10, 15, 26, 0.8);
|
||
border-radius: 18px;
|
||
padding: 1.8rem;
|
||
border: 1px solid var(--border-subtle);
|
||
box-shadow: var(--shadow-lg);
|
||
backdrop-filter: blur(12px);
|
||
display: grid;
|
||
gap: 1.2rem;
|
||
width: 100%;
|
||
max-width: 500px;
|
||
min-width: 380px;
|
||
}
|
||
|
||
.compat-card h3 {
|
||
font-size: 1.35rem;
|
||
color: var(--text-primary);
|
||
}
|
||
|
||
.compat-card p {
|
||
font-size: 0.98rem;
|
||
color: var(--text-secondary);
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.compat-logos {
|
||
display: grid;
|
||
grid-template-columns: repeat(4, 1fr);
|
||
gap: 0.75rem;
|
||
}
|
||
|
||
.compat-logos .db-logo {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border-radius: 12px;
|
||
padding: 0.7rem;
|
||
background: var(--bg-tertiary);
|
||
border: 1px solid var(--border-subtle);
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.compat-logos img {
|
||
width: 44px;
|
||
height: 44px;
|
||
}
|
||
|
||
.compat-badges {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 0.6rem 0.75rem;
|
||
}
|
||
|
||
.compat-badge {
|
||
padding: 0.35rem 0.75rem;
|
||
border-radius: 999px;
|
||
background: var(--glow-teal);
|
||
color: var(--text-primary);
|
||
font-size: 0.82rem;
|
||
}
|
||
|
||
@keyframes twinkle {
|
||
0% {
|
||
opacity: 0.4;
|
||
transform: scale(1) translate3d(0, 0, 0);
|
||
}
|
||
|
||
50% {
|
||
opacity: 0.75;
|
||
transform: scale(1.05) translate3d(-2%, -3%, 0);
|
||
}
|
||
|
||
100% {
|
||
opacity: 0.4;
|
||
transform: scale(1) translate3d(0, 0, 0);
|
||
}
|
||
}
|
||
|
||
@keyframes orbitSpin {
|
||
0% {
|
||
transform: rotate(0deg);
|
||
}
|
||
|
||
100% {
|
||
transform: rotate(360deg);
|
||
}
|
||
}
|
||
|
||
@keyframes floatNode {
|
||
0% {
|
||
transform: translate3d(0, 0, 0);
|
||
}
|
||
|
||
50% {
|
||
transform: translate3d(0, -10px, 0);
|
||
}
|
||
|
||
100% {
|
||
transform: translate3d(0, 0, 0);
|
||
}
|
||
}
|
||
|
||
@media (max-width: 968px) {
|
||
.compat-layout {
|
||
grid-template-columns: 1fr;
|
||
text-align: center;
|
||
}
|
||
|
||
.compat-intro p {
|
||
max-width: 100%;
|
||
}
|
||
|
||
.compat-highlights {
|
||
justify-content: center;
|
||
}
|
||
|
||
.compat-orbit {
|
||
width: 260px;
|
||
height: 260px;
|
||
}
|
||
|
||
.compat-node {
|
||
width: 74px;
|
||
height: 74px;
|
||
}
|
||
|
||
.compat-node img {
|
||
width: 46px;
|
||
height: 46px;
|
||
}
|
||
|
||
.compat-logos {
|
||
grid-template-columns: repeat(3, 1fr);
|
||
}
|
||
}
|
||
|
||
@media (max-width: 640px) {
|
||
.compat-intro h2 {
|
||
font-size: 2.6rem;
|
||
}
|
||
|
||
.compat-logos {
|
||
grid-template-columns: repeat(2, 1fr);
|
||
}
|
||
|
||
.compat-card {
|
||
padding: 1.4rem;
|
||
}
|
||
}
|
||
|
||
/* FOOTER STYLES */
|
||
footer {
|
||
background:
|
||
radial-gradient(ellipse 60% 40% at 0% 100%, var(--glow-subtle), transparent 70%),
|
||
radial-gradient(ellipse 50% 30% at 100% 0%, var(--glow-subtle), transparent 70%),
|
||
linear-gradient(180deg, var(--bg-secondary) 0%, var(--bg-tertiary) 100%);
|
||
padding: 5rem 0 1rem 0;
|
||
border-top: 1px solid var(--border-subtle);
|
||
}
|
||
|
||
footer .container {
|
||
padding: 0;
|
||
min-height: auto !important;
|
||
}
|
||
|
||
.footer-content {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 5rem;
|
||
}
|
||
|
||
.footer-links {
|
||
display: grid;
|
||
grid-template-columns: repeat(4, 1fr);
|
||
gap: 5rem;
|
||
}
|
||
|
||
.link-category {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 0.8rem;
|
||
}
|
||
|
||
.link-category h4 {
|
||
color: var(--text-primary);
|
||
font-size: 1.1rem;
|
||
margin-bottom: 0.5rem;
|
||
}
|
||
|
||
.link-category a {
|
||
color: var(--text-secondary);
|
||
text-decoration: none;
|
||
font-size: 0.9rem;
|
||
transition: color var(--transition-fast);
|
||
}
|
||
|
||
.link-category a:hover {
|
||
color: var(--brand-cyan);
|
||
}
|
||
|
||
.social-links {
|
||
display: flex;
|
||
gap: 1rem;
|
||
justify-content: center;
|
||
}
|
||
|
||
.social-links a {
|
||
color: var(--text-secondary);
|
||
transition: all var(--transition-fast);
|
||
}
|
||
|
||
.social-links a:hover {
|
||
color: var(--brand-cyan);
|
||
transform: translateY(-2px);
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.footer-links {
|
||
grid-template-columns: repeat(2, 1fr);
|
||
}
|
||
}
|
||
|
||
@media (max-width: 480px) {
|
||
.footer-links {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
}
|
||
|
||
/* SWORD METAL EFFECT */
|
||
.sword {
|
||
color: transparent;
|
||
background:
|
||
linear-gradient(180deg,
|
||
rgba(255, 255, 255, .8) 0%,
|
||
rgba(172, 179, 211, 0.9) 100%),
|
||
linear-gradient(135deg,
|
||
#ccc 0%,
|
||
#ccc 45%,
|
||
#fff 50%,
|
||
#ccc 55%,
|
||
#ccc 100%);
|
||
background-blend-mode: multiply;
|
||
background-size: 100% 100%, 400% 100%;
|
||
background-clip: text;
|
||
-webkit-background-clip: text;
|
||
animation: shimmer 25s linear infinite;
|
||
}
|
||
|
||
@keyframes shimmer {
|
||
0% {
|
||
background-position: 400% 0;
|
||
}
|
||
|
||
100% {
|
||
background-position: -400% 0;
|
||
}
|
||
}
|
||
|
||
.dynamic-title {
|
||
font-size: 2.5rem;
|
||
background: var(--gradient-primary);
|
||
-webkit-background-clip: text;
|
||
background-clip: text;
|
||
color: transparent;
|
||
text-shadow:
|
||
0 1px 1px rgba(0, 0, 0, 0.2),
|
||
0 -1px 1px rgba(255, 255, 255, 0.1);
|
||
position: relative;
|
||
margin-bottom: 1rem;
|
||
}
|
||
|
||
.footer-attribution {
|
||
text-align: center;
|
||
padding: 2rem 0 1rem 0;
|
||
font-size: 0.7rem;
|
||
opacity: 0.8;
|
||
transition: .2s;
|
||
}
|
||
|
||
.footer-attribution:hover {
|
||
opacity: 1;
|
||
}
|
||
|
||
.footer-attribution a {
|
||
color: inherit;
|
||
text-decoration: none;
|
||
border-bottom: 1px dotted currentColor;
|
||
}
|
||
|
||
a {
|
||
color: var(--text-primary);
|
||
text-decoration: none;
|
||
font-weight: 500;
|
||
transition: color var(--transition-fast), text-decoration var(--transition-fast);
|
||
}
|
||
|
||
a:hover {
|
||
color: var(--brand-cyan);
|
||
text-decoration: underline;
|
||
text-underline-offset: 2px;
|
||
text-decoration-thickness: 1.5px;
|
||
}
|
||
</style>
|
||
</head>
|
||
|
||
<body>
|
||
<nav class="menu">
|
||
<a href="/your-first-sql-website/">Download</a>
|
||
<a href="/documentation.sql">Documentation</a>
|
||
<a href="/examples/tabs">Examples</a>
|
||
<a href="https://github.com/sqlpage/SQLPage">Github</a>
|
||
<a href="https://datapage.app">Hosting</a>
|
||
</nav>
|
||
<div class="container">
|
||
<div class="logo">
|
||
<img src="/assets/icon.webp" alt="SQLPage Logo" width="220" height="248"
|
||
style="position: relative; bottom: 13%; object-fit: contain; width: 100%; height: 100%;">
|
||
</div>
|
||
|
||
<div class="text-content">
|
||
<h1 class="sword"><span>SQL</span><span class="words"><span class="sword">Page</span><span>
|
||
Website</span><span>
|
||
App</span><span>
|
||
Tools</span><span>
|
||
Forms</span><span>
|
||
Maps</span><span>
|
||
Plots</span><span>
|
||
APIs</span></span>
|
||
</h1>
|
||
<p>Instant web interfaces for your database. Free and open-source.</p>
|
||
<a href="/your-first-sql-website/" class="cta-button">Get Started</a>
|
||
</div>
|
||
</div>
|
||
<a href="#features" class="scroll-link">
|
||
<svg width="40" height="40" viewBox="0 0 24 24" fill="none">
|
||
<path d="M7 13l5 5 5-5M7 6l5 5 5-5" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||
stroke-linejoin="round" />
|
||
</svg>
|
||
</a>
|
||
|
||
<section id="features">
|
||
<div class="container">
|
||
<div class="text-content">
|
||
<h2>Build sophisticated tools, easily</h2>
|
||
<p>Turn simple SQL queries into beautiful, dynamic web applications.</p>
|
||
</div>
|
||
<div class="features-grid">
|
||
<div class="feature-card">
|
||
<div class="feature-icon">📈</div>
|
||
<h3>Complete</h3>
|
||
<p>Create navigatable interfaces with
|
||
<a href="/component.sql?component=map">maps</a>,
|
||
<a href="/component.sql?component=chart">charts</a>,
|
||
<a href="/component.sql?component=table">tables</a>,
|
||
<a href="/component.sql?component=form">forms</a>,
|
||
<a href="/component.sql?component=card">grids</a>,
|
||
<a href="/component.sql?component=big_number">dashboards</a>, and more.
|
||
Batteries included.
|
||
</p>
|
||
</div>
|
||
<div class="feature-card">
|
||
<div class="feature-icon">⚡</div>
|
||
<h3>Fast</h3>
|
||
<p>Build fast applications, quickly. You spend one afternoon building your first app. Then it
|
||
<a href="/performance">loads instantly</a> for everyone forever.
|
||
</p>
|
||
</div>
|
||
<div class="feature-card">
|
||
<div class="feature-icon">🎯</div>
|
||
<h3>Easy</h3>
|
||
<p>You can teach yourself enough <i>SQL</i> to query and edit a database through SQLPage in a
|
||
weekend. Focus on your data, we'll handle <a href="/performance">optimizations</a> and <a
|
||
href="/safety">security</a>.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="feature-section" id="scalable">
|
||
<div class="container">
|
||
<div class="feature-content">
|
||
<h2 class="dynamic-title">More scalable than a spreadsheet</h2>
|
||
<p>SQL queries sort, filter, and aggregate millions of rows in milliseconds. No more slow spreadsheet
|
||
formulas or memory limitations. Your app remains <a href="/performance">smooth and responsive</a>
|
||
even
|
||
as your data grows.</p>
|
||
</div>
|
||
<div class="feature-image">
|
||
<video src="/assets/screenshots/big_tables.webm" alt="SQLPage displaying large tables" width="600"
|
||
height="400" autoplay loop muted playsinline></video>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="feature-section" id="dynamic">
|
||
<div class="container">
|
||
<div class="feature-content">
|
||
<h2 class="dynamic-title">More dynamic than a dashboard</h2>
|
||
<p>Create multi-page interactive websites with drill-down capabilities. Navigate from summaries to
|
||
detailed records.
|
||
<p>
|
||
You should be able to comment, edit, and dive into your data instead of just looking at aggregated
|
||
statistics.
|
||
<p>
|
||
Build apps, not dashboards.
|
||
</div>
|
||
<div class="feature-image">
|
||
<img src="/assets/screenshots/user-creation-form.png"
|
||
alt="User creation form, illustrating the ability to create, edit, and delete individual data points, to go beyond simple static dashboards."
|
||
width="600" height="400">
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="compat-section" id="compatibility">
|
||
<div class="container compat-layout">
|
||
<div class="compat-intro">
|
||
<div class="compat-eyebrow">Database Compatibility</div>
|
||
<h2>Works with <em>your</em> database</h2>
|
||
<p>SQLPage connects to the database engine you already rely on today.
|
||
Keep your data in place and surface it through a
|
||
friendly interface that stays in sync.
|
||
If you don't have a DB yet, SQLPage comes with a built-in query engine.
|
||
</p>
|
||
<div class="compat-highlights">
|
||
<div class="compat-pill">SQLite built-in</div>
|
||
<div class="compat-pill">MySQL & MariaDB</div>
|
||
<div class="compat-pill">PostgreSQL family</div>
|
||
<div class="compat-pill">Microsoft SQL Server</div>
|
||
<div class="compat-pill">ODBC bridge</div>
|
||
</div>
|
||
</div>
|
||
<div class="compat-showcase">
|
||
<div class="compat-orbit">
|
||
<div class="compat-core" title="Native connectors for SQLite, MySQL, PostgreSQL, and SQL Server">
|
||
Native connectors
|
||
</div>
|
||
<div class="compat-node" title="SQLite"><img src="/assets/db-sqlite.svg" alt="SQLite"></div>
|
||
<div class="compat-node" title="MySQL"><img src="/assets/db-mysql.svg" alt="MySQL"></div>
|
||
<div class="compat-node" title="PostgreSQL"><img src="/assets/db-postgres.svg" alt="PostgreSQL"></div>
|
||
<div class="compat-node" title="Microsoft SQL Server"><img src="/assets/db-sqlserver.svg" alt="Microsoft SQL Server"></div>
|
||
</div>
|
||
<div class="compat-card">
|
||
<h3>Wherever your data lives</h3>
|
||
<p>Through ODBC you can plug SQLPage into any warehouses and enterprise engines.</p>
|
||
<div class="compat-logos">
|
||
<div class="db-logo" title="Open Database Connectivity"><img src="/assets/db-odbc.svg" alt="ODBC"></div>
|
||
<div class="db-logo" title="DuckDB: fast portable in-process analytical SQL database"><img src="/assets/db-duckdb.svg" alt="DuckDB"></div>
|
||
<div class="db-logo" title="ClickHouse: fast columnar database for OLAP"><img src="/assets/db-clickhouse.svg" alt="ClickHouse"></div>
|
||
<div class="db-logo" title="Databricks: cloud-native data warehouse"><img src="/assets/db-databricks.svg" alt="Databricks"></div>
|
||
<div class="db-logo" title="Snowflake: cloud-native data warehouse"><img src="/assets/db-snowflake.svg" alt="Snowflake"></div>
|
||
<div class="db-logo" title="BigQuery: cloud-native data warehouse"><img src="/assets/db-bigquery.svg" alt="BigQuery"></div>
|
||
<div class="db-logo" title="Oracle: enterprise database"><img src="/assets/db-oracle.svg" alt="Oracle"></div>
|
||
<div class="db-logo" title="IBM Db2: enterprise database"><img src="/assets/db-db2.svg" alt="Db2"></div>
|
||
</div>
|
||
<div class="compat-badges">
|
||
<span class="compat-badge">No data copy</span>
|
||
<span class="compat-badge">Streams query results</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="feature-section">
|
||
<div class="container">
|
||
<div class="feature-content">
|
||
<h2 class="gradient-title">The power of the web, without the complexity</h2>
|
||
<p>Do not code, <i>query</i>. Write SQL, get a web app.
|
||
<p>Traditional web programming languages are powerful, but complex.
|
||
Using smart opinionated defaults, SQLPage requires 10x less code.
|
||
<p>
|
||
For advanced customization, you can still optionally use HTML/CSS/JS, and
|
||
integrate with external programs and APIs.</p>
|
||
</div>
|
||
<img src="/assets/screenshots/plot.svg" alt="Simple Web Development. Just SQL" width="380"
|
||
style="width: 100%;">
|
||
</div>
|
||
</section>
|
||
|
||
<footer>
|
||
<div class="container footer-content">
|
||
<div class="footer-links">
|
||
<div class="link-category">
|
||
<h4>Product</h4>
|
||
<a href="/your-first-sql-website/">Get Started</a>
|
||
<a href="/documentation.sql">Documentation</a>
|
||
<a href="/examples/tabs">Examples</a>
|
||
<a href="/safety.sql">Security</a>
|
||
<a href="/performance.sql">Performance</a>
|
||
</div>
|
||
<div class="link-category">
|
||
<h4>Hosting</h4>
|
||
<a href="https://editor.datapage.app">Online Editor</a>
|
||
<a href="https://datapage.app">SFTP + Postgres</a>
|
||
<a href="https://editor.datapage.app/privacy">Privacy Policy</a>
|
||
<a href="https://editor.datapage.app/terms">Terms of Service</a>
|
||
<a href="/your-first-sql-website/nginx.sql">Self Hosting</a>
|
||
</div>
|
||
<div class="link-category">
|
||
<h4>Community</h4>
|
||
<a href="https://github.com/sqlpage/sqlpage">GitHub</a>
|
||
<a href="https://github.com/sqlpage/sqlpage/discussions">Discussions</a>
|
||
<a href="https://github.com/sqlpage/sqlpage/issues">Report a Bug</a>
|
||
<a href="/blog.sql">Blog</a>
|
||
</div>
|
||
<div class="link-category">
|
||
<h4>Components</h4>
|
||
<a href="/component.sql?component=form">SQL Forms</a>
|
||
<a href="/component.sql?component=chart">SQL Plots</a>
|
||
<a href="/component.sql?component=map">SQL Maps</a>
|
||
<a href="/component.sql?component=authentication">Authentication</a>
|
||
<a href="/component.sql?component=json">JSON APIs</a>
|
||
<a href="/documentation.sql">More...</a>
|
||
</div>
|
||
</div>
|
||
<div class="social-links">
|
||
<a href="https://x.com/sqlpage" aria-label="Twitter">
|
||
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
|
||
<path
|
||
d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />
|
||
</svg>
|
||
</a>
|
||
<a href="https://github.com/sqlpage/sqlpage" aria-label="GitHub">
|
||
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
|
||
<path
|
||
d="M12 2C6.477 2 2 6.477 2 12c0 4.42 2.865 8.17 6.839 9.49.5.092.682-.217.682-.482 0-.237-.008-.866-.013-1.7-2.782.604-3.369-1.34-3.369-1.34-.454-1.156-1.11-1.464-1.11-1.464-.908-.62.069-.608.069-.608 1.003.07 1.531 1.03 1.531 1.03.892 1.529 2.341 1.087 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.11-4.555-4.943 0-1.091.39-1.984 1.029-2.683-.103-.253-.446-1.27.098-2.647 0 0 .84-.269 2.75 1.025A9.578 9.578 0 0112 6.836c.85.004 1.705.114 2.504.336 1.909-1.294 2.747-1.025 2.747-1.025.546 1.377.203 2.394.1 2.647.64.699 1.028 1.592 1.028 2.683 0 3.842-2.339 4.687-4.566 4.935.359.309.678.919.678 1.852 0 1.336-.012 2.415-.012 2.743 0 .267.18.578.688.48C19.138 20.167 22 16.418 22 12c0-5.523-4.477-10-10-10z" />
|
||
</svg>
|
||
</a>
|
||
<a href="https://youtube.com/@sqlpage" aria-label="YouTube">
|
||
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
|
||
<path
|
||
d="M19.615 3.184c-3.604-.246-11.631-.245-15.23 0-3.897.266-4.356 2.62-4.385 8.816.029 6.185.484 8.549 4.385 8.816 3.6.245 11.626.246 15.23 0 3.897-.266 4.356-2.62 4.385-8.816-.029-6.185-.484-8.549-4.385-8.816zm-10.615 12.816v-8l8 3.993-8 4.007z" />
|
||
</svg>
|
||
</a>
|
||
</div>
|
||
</div>
|
||
<div class="footer-attribution">
|
||
Built <a href="https://github.com/sqlpage/SQLPage/tree/main/examples/official-site">with SQLPage</a>
|
||
</div>
|
||
</footer>
|
||
</body>
|
||
|
||
</html> |