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 @@ + +Group.svg +Created using Figma 0.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} +![](assets/logos/positron.svg){.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} +![](assets/logos/quarto.svg){.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} +![](assets/logos/jupyter.svg){.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} +![](assets/logos/vscode.svg){.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 {