Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added dist/openaq-1.1.0-py3-none-any.whl
Binary file not shown.
Binary file added dist/openaq-1.1.0.tar.gz
Binary file not shown.
1 change: 1 addition & 0 deletions docs/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export default defineConfig({
components: {
Hero: './src/components/Hero.astro',
Footer: './src/components/Footer.astro',
SocialIcons: './src/components/SocialIcons.astro',
},
customCss: ['./src/assets/landing.css'],
sidebar: [
Expand Down
3 changes: 1 addition & 2 deletions docs/src/components/Footer.astro
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
---
// src/components/Footer.astro
import Pagination from '@astrojs/starlight/components/Pagination.astro';
---

Expand All @@ -8,7 +7,7 @@ import Pagination from '@astrojs/starlight/components/Pagination.astro';
<footer class="license-notice">
<p>
&copy; {new Date().getFullYear()} OpenAQ.
Documentation licensed under
<span>Documentation licensed under </span>
<a
href="https://creativecommons.org/licenses/by-nc-sa/4.0/"
target="_blank"
Expand Down
8 changes: 8 additions & 0 deletions docs/src/components/Header.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
import Default from '@astrojs/starlight/components/Header.astro';
import VersionBadge from './VersionBadge.astro';
---
<div style="display: flex; align-items: center; gap: 1rem;">
<Default {...Astro.props} />
<VersionBadge />
</div>
335 changes: 188 additions & 147 deletions docs/src/components/Hero.astro
Original file line number Diff line number Diff line change
@@ -1,174 +1,215 @@
---

import { Picture } from 'astro:assets';
import LinkButton from './vendor/starlight/LinkButton.astro'
import LinkButton from './vendor/starlight/LinkButton.astro';

const { data } = Astro.locals.starlightRoute.entry;
const { title = data.title, tagline, image, actions = [] } = data.hero || {};

const PAGE_TITLE_ID = "_top"

const PAGE_TITLE_ID = '_top';

const imageAttrs = {
loading: 'eager' as const,
decoding: 'async' as const,
formats: ['avif', 'webp', 'png'] as const,
width: 800,
height: 800,
alt: image?.alt || '',
loading: 'eager' as const,
decoding: 'async' as const,
formats: ['avif', 'webp', 'png'] as const,
width: 800,
height: 800,
alt: image?.alt || '',
};

let darkImage: ImageMetadata | undefined;
let lightImage: ImageMetadata | undefined;
let rawHtml: string | undefined;
if (image) {
if ('file' in image) {
darkImage = image.file;
} else if ('dark' in image) {
darkImage = image.dark;
lightImage = image.light;
} else {
rawHtml = image.html;
}
if ('file' in image) {
darkImage = image.file;
} else if ('dark' in image) {
darkImage = image.dark;
lightImage = image.light;
} else {
rawHtml = image.html;
}
}
---

<div class="hero">
{
darkImage && (
<Picture
src={darkImage}
formats={imageAttrs.formats}
width={imageAttrs.width}
height={imageAttrs.height}
alt={imageAttrs.alt}
loading={imageAttrs.loading}
decoding={imageAttrs.decoding}
pictureAttributes={{ class: lightImage ? 'light:sl-hidden' : undefined }}
/>
)
}
{lightImage && <Picture
src={lightImage}
formats={imageAttrs.formats}
width={imageAttrs.width}
height={imageAttrs.height}
alt={imageAttrs.alt}
loading={imageAttrs.loading}
decoding={imageAttrs.decoding}
{
darkImage && (
<Picture
src={darkImage}
formats={imageAttrs.formats}
width={imageAttrs.width}
height={imageAttrs.height}
alt={imageAttrs.alt}
loading={imageAttrs.loading}
decoding={imageAttrs.decoding}
pictureAttributes={{
class: lightImage ? 'light:sl-hidden' : undefined,
}}
/>
)
}
{
lightImage && (
<Picture
src={lightImage}
formats={imageAttrs.formats}
width={imageAttrs.width}
height={imageAttrs.height}
alt={imageAttrs.alt}
loading={imageAttrs.loading}
decoding={imageAttrs.decoding}
pictureAttributes={{ class: 'dark:sl-hidden' }}
/>}
{rawHtml && <div class="hero-html sl-flex" set:html={rawHtml} />}
<div class="sl-flex stack">
<div class="sl-flex copy">
<h1 id={PAGE_TITLE_ID} data-page-title set:html={title} />
{tagline && <div class="tagline" set:html={tagline} />}
</div>
{
actions.length > 0 && (
<div class="sl-flex actions">
{actions.map(
({ attrs: { class: className, ...attrs } = {}, icon, link: href, text, variant }) => (
<LinkButton {href} {variant} icon={icon?.name} class:list={[className]} {...attrs}>
{text}
{icon?.html && <Fragment set:html={icon.html} />}
</LinkButton>
)
)}
</div>
)
}
</div>
/>
)
}
{rawHtml && <div class="hero-html sl-flex" set:html={rawHtml} />}
<div class="sl-flex stack">
<div class="sl-flex copy">
<h1 id={PAGE_TITLE_ID} data-page-title set:html={title} />
{tagline && <div class="tagline" set:html={tagline} />}
</div>
{
actions.length > 0 && (
<div class="sl-flex actions">
{actions.map(
({
attrs: { class: className, ...attrs } = {},
icon,
link: href,
text,
variant,
}) => (
<LinkButton
{href}
{variant}
icon={icon?.name}
class:list={[className]}
{...attrs}
>
{text}
{icon?.html && <Fragment set:html={icon.html} />}
</LinkButton>
),
)}
</div>
)
}
</div>
</div>

<style>
.hero {
display: grid;
align-items: center;
gap: 1rem;
padding-bottom: 1rem;
}

.hero > picture img,
.hero > img,
.hero > .hero-html {
object-fit: contain;
width: min(70%, 20rem);
height: auto;
margin-inline: auto;
transform: perspective(300px) rotateY(-10deg);
transition: transform 1s ease-in-out 0s;
}

.hero > picture img {
width: 100%;
height: auto;
object-fit: contain;
}
.hero {
display: grid;
align-items: center;
gap: 1rem;
padding-bottom: 1rem;
}

.hero > picture img,
.hero > img,
.hero > .hero-html {
object-fit: contain;
width: min(70%, 20rem);
height: auto;
margin-inline: auto;
transform: perspective(300px) rotateY(-10deg);
transition: transform 1s ease-in-out 0s;
}

.hero > picture img {
width: 100%;
height: auto;
object-fit: contain;
}

.hero > img:hover,
.hero > picture:hover img {
transform: perspective(300px) rotateY(10deg);
}

@media (max-width: 768px) {
.hero > picture img,
.hero > img,
.hero > .hero-html {
display: block;
transform: none;
transition: none;
width: min(80%, 14rem);
margin-inline: auto;
}

.hero > img:hover,
.hero > picture:hover img {
transform: perspective(300px) rotateY(10deg);
.hero > picture:hover img {
transform: none;
}
}

.stack {
flex-direction: column;
gap: clamp(1.5rem, calc(1.5rem + 1vw), 2rem);
text-align: center;
}

.copy {
flex-direction: column;
gap: 1rem;
align-items: center;
}

.copy > * {
max-width: 50ch;
}

h1 {
font-size: clamp(
var(--sl-text-3xl),
calc(0.25rem + 5vw),
var(--sl-text-6xl)
);
line-height: var(--sl-line-height-headings);
font-weight: 600;
color: var(--sl-color-white);
}

.tagline {
font-size: clamp(
var(--sl-text-base),
calc(0.0625rem + 2vw),
var(--sl-text-xl)
);
color: var(--sl-color-gray-2);
}

.actions {
gap: 1rem 2rem;
flex-wrap: wrap;
justify-content: center;
}

@media (min-width: 50rem) {
.hero {
grid-template-columns: 7fr 4fr;
gap: 3%;
padding-block: clamp(2.5rem, calc(1rem + 10vmin), 10rem);
}

.hero > picture,
.hero > img,
.hero > .hero-html {
order: 2;
width: min(100%, 25rem);
}

.stack {
text-align: start;
}

.stack {
flex-direction: column;
gap: clamp(1.5rem, calc(1.5rem + 1vw), 2rem);
text-align: center;
}

.copy {
flex-direction: column;
gap: 1rem;
align-items: center;
}

.copy > * {
max-width: 50ch;
}

h1 {
font-size: clamp(var(--sl-text-3xl), calc(0.25rem + 5vw), var(--sl-text-6xl));
line-height: var(--sl-line-height-headings);
font-weight: 600;
color: var(--sl-color-white);
}

.tagline {
font-size: clamp(var(--sl-text-base), calc(0.0625rem + 2vw), var(--sl-text-xl));
color: var(--sl-color-gray-2);
}

.actions {
gap: 1rem 2rem;
flex-wrap: wrap;
justify-content: center;
}

@media (min-width: 50rem) {
.hero {
grid-template-columns: 7fr 4fr;
gap: 3%;
padding-block: clamp(2.5rem, calc(1rem + 10vmin), 10rem);
}

.hero > picture,
.hero > img,
.hero > .hero-html {
order: 2;
width: min(100%, 25rem);
}

.stack {
text-align: start;
}

.copy {
align-items: flex-start;
}

.actions {
justify-content: flex-start;
}
}
.copy {
align-items: flex-start;
}

.actions {
justify-content: flex-start;
}
}
</style>
Loading