diff --git a/doc/_quarto.yml b/doc/_quarto.yml
index 27ec54dc..1fa1bfd4 100644
--- a/doc/_quarto.yml
+++ b/doc/_quarto.yml
@@ -7,8 +7,8 @@ website:
The home of ggsql. A declarative visualisation language build on top of SQL
and the grammar of graphics.
site-url: https://ggsql.org
- repo-url: https://github.com/ggsql-dev/ggsql
- issue-url: https://github.com/ggsql-dev/ggsql/issues
+ repo-url: https://github.com/posit-dev/ggsql
+ issue-url: https://github.com/posit-dev/ggsql/issues
repo-branch: gh-pages
image: assets/logo.png
image-alt: |
@@ -60,6 +60,7 @@ website:
title: Syntax
style: "floating"
search: true
+ logo: false
contents:
- text: Overview
href: syntax/index.qmd
diff --git a/doc/assets/logos/jupyter.svg b/doc/assets/logos/jupyter.svg
new file mode 100644
index 00000000..ab255087
--- /dev/null
+++ b/doc/assets/logos/jupyter.svg
@@ -0,0 +1,90 @@
+
diff --git a/doc/assets/logos/positron.svg b/doc/assets/logos/positron.svg
new file mode 100644
index 00000000..590372e4
--- /dev/null
+++ b/doc/assets/logos/positron.svg
@@ -0,0 +1,12 @@
+
+
diff --git a/doc/assets/logos/quarto.svg b/doc/assets/logos/quarto.svg
new file mode 100644
index 00000000..45a9af0f
--- /dev/null
+++ b/doc/assets/logos/quarto.svg
@@ -0,0 +1,14 @@
+
+
+
diff --git a/doc/assets/logos/vscode.svg b/doc/assets/logos/vscode.svg
new file mode 100644
index 00000000..c453e633
--- /dev/null
+++ b/doc/assets/logos/vscode.svg
@@ -0,0 +1,41 @@
+
diff --git a/doc/index.qmd b/doc/index.qmd
index d1c883df..b636cecb 100644
--- a/doc/index.qmd
+++ b/doc/index.qmd
@@ -3,6 +3,8 @@ pagetitle: "ggsql"
page-layout: custom
section-divs: false
toc: false
+lightbox: false
+repo-actions: false
---
::: {.hero-banner}
@@ -15,7 +17,7 @@ A declarative visualization language that extends SQL with powerful data visuali
::: {.hero-buttons}
[Get Started](installation.qmd){.btn .btn-secondary .btn-lg}
-[View Examples](examples.qmd){.btn .btn-outline-secondary .btn-lg}
+[View Examples](examples.qmd){.btn .btn-outline-light .btn-lg}
:::
:::
@@ -27,7 +29,7 @@ A declarative visualization language that extends SQL with powerful data visuali
::: {.features}
::: {.feature}
-### Pure SQL Foundation
+### Familiar Syntax
Write standard SQL queries and seamlessly extend them with visualization clauses. Your existing SQL knowledge transfers directly.
@@ -43,127 +45,48 @@ DRAW line
::: {.feature}
### Grammar of Graphics
-Compose visualizations from independent layers, scales, and coordinates. Mix and match geoms, facets, and themes for precise control.
+Compose visualizations from independent layers, scales, and coordinates. Mix and match components for powerful custom visuals.
```{.ggsql .code-example}
-DRAW line
- MAPPING date AS x, value AS y
-DRAW point
- MAPPING date AS x, value AS y
-SCALE x
- SETTING type => 'date'
+VISUALISE date AS x FROM sales
+DRAW bar
+SCALE BINNED x
+ SETTING breaks => 'weeks'
FACET region
```
:::
::: {.feature}
-### Pluggable Architecture
+### Built for Humans _and_ AI
-Connect to DuckDB, PostgreSQL, or SQLite. Output to Vega-Lite, ggplot2, or render directly to PNG.
-
-```{.ggsql .code-example}
--- Use any data source
-ggsql exec "SELECT ..."
- --reader duckdb://data.db
- --writer vegalite
- --output viz.json
-```
-:::
-
-:::
+The structured syntax makes it easy for AI agents to write, and for you to read, adjust, and verify.
+You also avoid needing agents to launch full programming languages like Python or R to create powerful visualizations, so you can rest assured that the agent doesn't accidentally alter your environment in unwanted ways.
:::
-::: {.content-block .alt-bg}
-
-## Built for Modern Workflows
-
-::: {.workflow-grid}
-
-::: {.workflow-item}
-
-### Jupyter Kernel
+::: {.feature}
+### There where you need it
-Interactive notebooks with inline Vega-Lite visualizations. Persistent database sessions across cells.
+ggsql is available where you do your data analysis:
-[Learn more →](installation.qmd#jupyter-kernel)
+::: {.tool-grid}
+::: {.tool-item}
+{.tool-logo}
+Positron
:::
-
-::: {.workflow-item}
-
-### VS Code Extension
-
-Syntax highlighting for `.ggsql` files with full SQL and visualization clause support.
-
-[Learn more →](installation.qmd#vs-code-extension)
+::: {.tool-item}
+{.tool-logo}
+Quarto
:::
-
-::: {.workflow-item}
-
-### REST API
-
-Build dashboards and web applications with the `ggsql-rest` server. CORS-enabled with sample data loading.
-
-[Learn more →](installation.qmd#rest-api)
+::: {.tool-item}
+{.tool-logo}
+Jupyter
:::
-
-::: {.workflow-item}
-
-### CLI Tool
-
-Parse, validate, and execute queries from the command line. Perfect for automation and CI pipelines.
-
-[Learn more →](installation.qmd#cli)
-:::
-
+::: {.tool-item}
+{.tool-logo}
+VS Code
:::
-
-:::
-
-::: {.content-block}
-
-## Quick Example
-
-::: {.example-container}
-
-::: {.example-code}
-```{.ggsql}
--- Create a multi-layer visualization
-SELECT date, revenue, region
-FROM sales
-WHERE year >= 2023
-
-VISUALISE date AS x, revenue AS y, region AS color
-
-DRAW line
-DRAW point
- SETTING size => 3
-
-SCALE x
- SETTING type => 'date'
-SCALE y
- SETTING type => 'linear', limits => [0, 100000]
-
-FACET region SETTING scales => 'free_y'
-
-LABEL
- title => 'Revenue Trends by Region',
- x => 'Date',
- y => 'Revenue (USD)'
-```
:::
-
-::: {.example-description}
-### What's happening here?
-
-1. **SQL Query** retrieves sales data filtered by year
-2. **VISUALISE** maps columns to visual aesthetics
-3. **DRAW** creates line and point layers
-4. **SCALE** configures the x-axis as temporal
-5. **FACET** creates small multiples by region
-6. **LABEL** adds descriptive titles
-
-The output is a Vega-Lite specification that renders as an interactive chart.
:::
:::
@@ -179,9 +102,9 @@ The output is a Vega-Lite specification that renders as an interactive chart.
Install ggsql and start creating visualizations in minutes.
::: {.cta-buttons}
-[Installation Guide](installation.qmd){.btn .btn-primary .btn-lg}
-[Syntax Reference](syntax/index.qmd){.btn .btn-outline-primary .btn-lg}
-[GitHub](https://github.com/georgestagg/ggsql){.btn .btn-outline-secondary .btn-lg}
+[Installation](installation.qmd){.btn .btn-primary .btn-lg}
+[Documentation](syntax/index.qmd){.btn .btn-outline-primary .btn-lg}
+[Examples](examples.qmd){.btn .btn-outline-secondary .btn-lg}
:::
:::
diff --git a/doc/styles.scss b/doc/styles.scss
index 8848bfbb..b429fbfb 100644
--- a/doc/styles.scss
+++ b/doc/styles.scss
@@ -1,5 +1,12 @@
/*-- scss:rules --*/
+// Override Quarto's default padding-top on narrow screens for content after hero
+@media (max-width: 991.98px) {
+ #quarto-content > .hero-banner + .content-block {
+ padding-top: 1rem;
+ }
+}
+
.navbar {
.navbar-brand-logo {
width: 20px;
@@ -69,6 +76,80 @@ code {
justify-content: center;
flex-wrap: wrap;
}
+
+
+ // Wide layout: content box to the right of image
+ @media (min-width: 1200px) {
+ flex-direction: row;
+ align-items: center;
+ justify-content: flex-end;
+ min-height: 400px;
+ overflow: hidden;
+
+ // Constrain total width to match content-blocks
+ &>p, .hero-content {
+ max-width: 1200px;
+ }
+
+ &>p {
+ flex: 1 1 auto;
+ display: flex;
+ justify-content: flex-end;
+ align-items: center;
+ margin: 0;
+ }
+
+ .hero-image {
+ max-width: 100%;
+ max-height: 100%;
+ object-fit: contain;
+ object-position: center;
+ mask-image: linear-gradient(
+ to right,
+ transparent 0%,
+ black 15%,
+ black 85%,
+ transparent 100%
+ );
+ -webkit-mask-image: linear-gradient(
+ to right,
+ transparent 0%,
+ black 15%,
+ black 85%,
+ transparent 100%
+ );
+ }
+
+ .hero-content {
+ flex: 0 0 auto;
+ width: auto;
+ max-width: 400px;
+ padding: 0rem 1rem 1rem;
+ margin: 4rem calc((100vw - 1200px) / 2) 2rem -80px;
+ border-radius: 12px;
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
+ position: relative;
+ z-index: 1;
+
+ h1 {
+ font-size: 1.5rem;
+ }
+
+ p {
+ font-size: 1rem;
+ margin-bottom: 1rem;
+ }
+ }
+
+ .hero-buttons {
+ gap: 0.75rem;
+
+ .btn.btn-lg {
+ padding: 0.6rem 1.25rem;
+ font-size: 0.95rem;
+ }
+ }
+ }
}
@@ -105,10 +186,6 @@ code {
color: var(--brand-darkteal);
border-bottom-color: var(--brand-darkteal);
}
-
- a {
- color: var(--brand-teal);
- }
}
}
@@ -116,6 +193,12 @@ code {
display: flex;
flex-direction: column;
gap: 2rem;
+
+ // 2-column layout on large screens
+ @media (min-width: 1000px) {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ }
}
.feature {
@@ -163,23 +246,49 @@ code {
}
}
- &:nth-of-type(even) {
+ // Full width text when no code cell - use flexbox for natural flow
+ &:not(:has(.code-copy-outer-scaffold)) {
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+
h3 {
- grid-column: 2;
+ grid-column: unset;
+ grid-row: unset;
}
> p {
- grid-column: 2;
+ grid-column: unset;
+ grid-row: unset;
+ }
+ }
+
+ // Single-column internal layout on small screens
+ @media (max-width: 768px) {
+ grid-template-columns: 1fr;
+ grid-template-rows: auto auto auto;
+
+ h3 {
+ grid-column: 1;
+ grid-row: 1;
+ }
+
+ > p {
+ grid-column: 1;
+ grid-row: 2;
}
.code-copy-outer-scaffold {
grid-column: 1;
+ grid-row: 3;
+ padding-top: 0;
}
}
- @media (max-width: 768px) {
+ // Single-column internal layout when features are in 2-column grid
+ @media (min-width: 1000px) {
grid-template-columns: 1fr;
- grid-template-rows: auto auto auto;
+ grid-template-rows: auto auto 1fr;
h3 {
grid-column: 1;
@@ -194,7 +303,7 @@ code {
.code-copy-outer-scaffold {
grid-column: 1;
grid-row: 3;
- padding-top: 0;
+ padding-top: 1rem;
}
&:nth-of-type(even) {
@@ -205,84 +314,37 @@ code {
}
}
-.workflow-grid {
+.tool-grid {
display: grid;
- grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
- gap: 2rem;
-}
-
-.workflow-item {
- text-align: center;
- padding: 1.5rem;
- background: white;
- border-radius: 8px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
- border-top: 3px solid var(--brand-teal, #0A9396);
+ grid-template-columns: repeat(2, 1fr);
+ gap: 1rem;
+ margin-top: 1rem;
- h3 {
- font-size: 1.1rem;
- color: var(--brand-darkteal, #005F73);
- margin-bottom: 0.75rem;
- }
-
- p {
- font-size: 0.95rem;
- color: var(--brand-black, #001219);
- line-height: 1.5;
- margin-bottom: 0.75rem;
- }
-
- a {
- color: var(--brand-teal, #0A9396);
- font-weight: 500;
- text-decoration: none;
-
- &:hover {
- text-decoration: underline;
- }
+ // Single row when box is wide
+ @media (min-width: 769px) and (max-width: 999px) {
+ grid-template-columns: repeat(4, 1fr);
}
}
-.example-container {
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 2rem;
- align-items: start;
-
- @media (max-width: 768px) {
- grid-template-columns: 1fr;
- }
-}
+.tool-item {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.5rem;
+ font-size: 1.5rem;
+ font-weight: 500;
+ color: var(--brand-darkteal, #005F73);
-.example-code {
- pre {
+ > p {
margin: 0;
- border-radius: 8px;
- max-height: 500px;
- overflow-y: auto;
}
}
-.example-description {
- h3 {
- color: var(--brand-darkteal, #005F73);
- margin-bottom: 1rem;
- }
-
- ol {
- padding-left: 1.25rem;
-
- li {
- margin-bottom: 0.5rem;
- line-height: 1.5;
- }
- }
-
- p {
- margin-top: 1rem;
- color: var(--brand-teal, #0A9396);
- font-style: italic;
- }
+.tool-logo {
+ width: 48px;
+ height: 48px;
+ object-fit: contain;
}
.cta-section {