Improve responsive design sizing for website

This commit is contained in:
Keavon Chambers 2023-08-12 12:48:45 -07:00
parent c9d3453e46
commit 2412a3def6
25 changed files with 766 additions and 590 deletions

View File

@ -24,7 +24,7 @@ Launch the latest alpha release of the [Graphite editor](https://editor.graphite
## Building/contributing
We need Rust and web developers! See [instructions here](https://graphite.rs/contribute/) for setting up the project and getting started.
We need Rust and web developers! See [instructions here](https://graphite.rs/volunteer/guide/) for setting up the project and getting started.
We are also in search of artists to create beautiful sample work in Graphite and illustrations for the website and social media. Please [get in touch](https://graphite.rs/contact/) if you are able to help out.
@ -36,4 +36,4 @@ By submitting code for inclusion in the project, you are agreeing to license you
## Support the project
Please consider pledging a monthly donation using the "♥ Sponsor" button to the right part of this project repository page. Your contribution helps sustain this volunteer-run open source project and brings powerful, free creative tools to the masses.
Please consider [pledging a monthly donation](https://graphite.rs/donate/). Your contribution helps sustain this volunteer-run open source project and brings powerful, free creative tools to the masses.

View File

@ -1,21 +1,26 @@
+++
title = "Web-based vector graphics editor and design tool"
template = "section.html" # Avoids needing a separate `index.html` template that's identical to `section.html`
template = "section.html"
[extra]
css = ["/index.css"]
js = ["/image-interaction.js", "/fundraising.js"]
+++
<!-- ▛ LOGO ▜ -->
<section id="logo">
<img src="https://static.graphite.rs/logos/graphite-logotype-color.svg" alt="Graphite Logo" />
</section>
<!-- ▙ LOGO ▟ -->
<img class="pencil-texture" src="https://static.graphite.rs/textures/pencil-texture.png" alt="" />
<!-- ▛ QUICK LINKS ▜ -->
<section id="quick-links">
<div>
<a href="#community" class="button arrow">Subscribe to the newsletter</a>
<a href="/donate" class="button arrow">&hearts; Support the mission</a>
</div>
<div>
<a href="https://github.com/GraphiteEditor/Graphite" target="_blank">
<img src="https://static.graphite.rs/icons/github.svg" alt="GitHub" />
@ -26,19 +31,25 @@ js = ["/image-interaction.js", "/fundraising.js"]
<a href="https://twitter.com/graphiteeditor" target="_blank">
<img src="https://static.graphite.rs/icons/twitter.svg" alt="Twitter" />
</a>
<a href="https://www.youtube.com/@GraphiteEditor" target="_blank">
<img src="https://static.graphite.rs/icons/youtube.svg" alt="YouTube" />
</a>
<a href="https://discord.graphite.rs" target="_blank">
<img src="https://static.graphite.rs/icons/discord.svg" alt="Discord" />
</a>
</div>
</section>
<!-- ▙ QUICK LINKS ▟ -->
<!-- -->
<!-- ▛ TAGLINE ▜ -->
<section id="tagline">
<section id="hero-message">
# Redefining state-of-the-art graphics editing
<h1 class="balance-text">Redefining state&#8209;of&#8209;the&#8209;art graphics editing</h1>
<p class="balance-text"><strong>Graphite</strong> is an in-development raster and vector graphics package that's free and open source. It is powered by a node graph compositing engine that fuses layers with nodes, providing a fully nondestructive editing experience.</p>
</section>
<!-- ▙ TAGLINE ▟ -->
<div class="hexagons">
<div>
@ -52,6 +63,7 @@ js = ["/image-interaction.js", "/fundraising.js"]
</div>
</div>
<!-- ▛ SCREENSHOTS ▜ -->
<section id="screenshots" class="carousel window-size-1" data-carousel>
<div class="carousel-slide">
<img src="https://static.graphite.rs/content/index/gui-demo-valley-of-spires.png" alt="Graphite UI image #1" data-carousel-image />
@ -100,10 +112,13 @@ js = ["/image-interaction.js", "/fundraising.js"]
</div>
</section>
<section class="section-row">
<!-- ▙ SCREENSHOTS ▟ -->
<!-- -->
<!-- ▛ TODAY AND TOMORROW ▜ -->
<section id="today-and-tomorrow">
<div class="diptych">
<div id="graphite-today" class="section">
<div class="section">
# Graphite today
@ -129,7 +144,7 @@ js = ["/image-interaction.js", "/fundraising.js"]
Graphite is a lightweight vector graphics editor that runs in your browser. Its node-based compositor lets you apply image effects and co-create art with generative AI.
</div>
<div id="graphite-tomorrow" class="section">
<div class="section">
# Graphite tomorrow
@ -158,10 +173,11 @@ Graphite is a lightweight vector graphics editor that runs in your browser. Its
</div>
</section>
<!-- ▙ TODAY AND TOMORROW ▟ -->
<!-- -->
<!-- ▛ COMMUNITY ▜ -->
<section id="community" class="feature-box">
<div class="box">
<section class="section-row">
<div class="diptych">
<div id="newsletter" class="section">
@ -199,13 +215,10 @@ You'll receive your first newsletter email with the next major Graphite news.
</form>
</div>
<div id="social" class="section">
# Follow along
<!-- High-quality open source software is a community endeavor. Hang out with hundreds of friendly Graphite users and developers. -->
<div class="social-links">
<div class="column">
<a href="https://discord.graphite.rs" target="_blank">
@ -232,11 +245,12 @@ You'll receive your first newsletter email with the next major Graphite news.
</div>
</div>
</section>
</div>
</section>
<section id="vector-art" class="section-row">
<!-- ▙ COMMUNITY ▟ -->
<!-- -->
<!-- ▛ VECTOR ART ▜ -->
<section id="vector-art">
<div class="section">
# Art takes shape
@ -245,12 +259,11 @@ Make vector art out of shapes ranging from simple geometric primitives to comple
Style your shapes with strokes, fills, and gradients. Mix your layers with blend modes. Then export as SVG.
<div class="background-video">
<div class="video-background">
<video loop muted playsinline disablepictureinpicture disableremoteplayback data-auto-play>
<source src="https://static.graphite.rs/content/index/just-a-potted-cactus-timelapse.mp4" type="video/mp4" />
</video>
</div>
<div class="download-artwork">
<img src="https://static.graphite.rs/content/index/just-a-potted-cactus-thumbnail.png" alt="Vector art of Just of Potted Cactus" />
<p>
@ -268,44 +281,11 @@ Style your shapes with strokes, fills, and gradients. Mix your layers with blend
</div>
</section>
<!-- <section id="node-graph">
<section id="node-graph-intro" class="section-row">
<div class="section">
# The power of nodes
At Graphite's core is its **node graph**, a compositing engine and artist-friendly visual scripting environment that simplifies laborious steps in your design process.
</div>
</section>
<section id="node-graph-adjustment-layers" class="section-row feature-explainer">
<div class="diptych">
<div class="section">
## Adjust layers with<br />nondestructive effects
Apply effects directly in the layer stack to modify the artwork underneath. Combine them in unique ways by connecting the effect nodes to one another.
- Per-pixel color adjustments: levels, curves, exposure, contrast, saturation
- Image-wide creative filters: blur/sharpen, high pass, flood fill, warp, fresco
- Alpha-aware image styles: color overlay, drop shadow, inner/outer glow
- Effort-saving modifiers: transform, mirror, tile, scatter, linear/radial repeat
- Procedural generators: solid color, gradient, pattern, coherent/white noise
</div>
</div>
</section>
</section> -->
<!-- ▙ VECTOR ART ▟ -->
<!-- -->
<!-- ▛ IMAGINATE ▜ -->
<section id="imaginate">
<section id="imaginate-intro" class="section-row">
<div class="section">
<h1><span class="alternating-text"><span>Co-create</span><span>Ideate</span><span>Illustrate</span><span>Generate</span><span>Iterate</span></span> with Imaginate</h1>
@ -314,9 +294,6 @@ Apply effects directly in the layer stack to modify the artwork underneath. Comb
<!-- [Learn how](/learn/node-graph/imaginate) it works. -->
</div>
</section>
<section id="imaginate-vector-art" class="section-row feature-explainer">
<div class="diptych">
<div class="section">
@ -348,7 +325,6 @@ Apply effects directly in the layer stack to modify the artwork underneath. Comb
<blockquote class="balance-text require-polyfill"><strong>Watercolor painting</strong> of a light bulb gleaming with an exclamation mark inside</blockquote>
</div>
<div class="section">
## Work fast, be sloppy
@ -380,13 +356,14 @@ Apply effects directly in the layer stack to modify the artwork underneath. Comb
</div>
</div>
</section>
</section>
<!-- ▙ IMAGINATE ▟ -->
<!-- -->
<!-- ▛ FUNDRAISING ▜ -->
<section id="fundraising" class="feature-box">
<div class="box">
<div class="section-row">
<div>
<div class="section">
@ -422,9 +399,42 @@ Graphite is built by a small, dedicated crew of volunteers in need of resources
</div>
</div>
</section>
<!-- ▙ FUNDRAISING ▟ -->
<!-- -->
<!-- ▛ PROCEDURALISM ▜ -->
<section id="proceduralism">
<div class="section">
<section class="section-row">
<div id="disciplines" class="section">
# Powerful proceduralism
The data-driven approach to design affords unique capabilities that are presently in-development.
<div class="informational-group features four-wide">
<div class="informational">
<img class="atlas" style="--atlas-index: 8" src="https://static.graphite.rs/icons/icon-atlas-features.png" alt="" />
<span class="balance-text">Fully nondestructive editing with node-driven layers</span>
</div>
<div class="informational">
<img class="atlas" style="--atlas-index: 9" src="https://static.graphite.rs/icons/icon-atlas-features.png" alt="" />
<span class="balance-text">Infinitely scalable raster content with no pixelation</span>
</div>
<div class="informational">
<img class="atlas" style="--atlas-index: 10" src="https://static.graphite.rs/icons/icon-atlas-features.png" alt="" />
<span class="balance-text">Integrates generative AI models and graphics algorithms</span>
</div>
<div class="informational">
<img class="atlas" style="--atlas-index: 11" src="https://static.graphite.rs/icons/icon-atlas-features.png" alt="" />
<span class="balance-text">Procedural pipelines for studio production environments</span>
</div>
</div>
</div>
</section>
<!-- ▙ PROCEDURALISM ▟ -->
<!-- -->
<!-- ▛ DISCIPLINES ▜ -->
<section id="disciplines">
<div class="section">
# One app to rule them all
@ -459,37 +469,10 @@ Stop jumping between programs. Planned features will make Graphite a first-class
</div>
</section>
<section id="vector-art" class="section-row">
<div class="section">
# Powerful proceduralism
The data-driven approach to design affords unique capabilities that are presently in-development.
<div class="informational-group features four-wide">
<div class="informational">
<img class="atlas" style="--atlas-index: 8" src="https://static.graphite.rs/icons/icon-atlas-features.png" alt="" />
<span class="balance-text">Fully nondestructive editing with node-driven layers</span>
</div>
<div class="informational">
<img class="atlas" style="--atlas-index: 9" src="https://static.graphite.rs/icons/icon-atlas-features.png" alt="" />
<span class="balance-text">Infinitely scalable raster content with no pixelation</span>
</div>
<div class="informational">
<img class="atlas" style="--atlas-index: 10" src="https://static.graphite.rs/icons/icon-atlas-features.png" alt="" />
<span class="balance-text">Integrates generative AI models and graphics algorithms</span>
</div>
<div class="informational">
<img class="atlas" style="--atlas-index: 11" src="https://static.graphite.rs/icons/icon-atlas-features.png" alt="" />
<span class="balance-text">Procedural pipelines for studio production environments</span>
</div>
</div>
</div>
</section>
<section id="demo-video" class="section-row">
<!-- ▙ DISCIPLINES ▟ -->
<!-- -->
<!-- ▛ DEMO VIDEO ▜ -->
<section id="demo-video">
<div class="section">
<div class="video-embed aspect-16x9">
<iframe width="1280" height="720" src="https://www.youtube.com/embed/JgJvAHQLnXA" title="Graphite Vector Editing: &quot;Commander Basstronaut&quot; Artwork (25x Timelapse)" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
@ -497,7 +480,9 @@ The data-driven approach to design affords unique capabilities that are presentl
<!-- <a href="/blog/mission-statement" class="link arrow">Mission Statement</a> -->
</div>
</section>
<!-- ▙ DEMO VIDEO ▟ -->
<!-- -->
<!-- ▛ GET INVOLVED ▜ -->
<section id="get-involved-box" class="feature-box">
<div class="box">
<div class="diptych">
@ -518,3 +503,4 @@ The data-driven approach to design affords unique capabilities that are presentl
</div>
</div>
</section>
<!-- ▙ GET INVOLVED ▟ -->

View File

@ -5,7 +5,7 @@ title = "About Graphite"
css = ["/about.css"]
+++
<section class="section-row">
<section>
<div class="section">
# About Graphite
@ -15,7 +15,7 @@ Graphite is a community-built, open source software project that is free to use
</div>
</section>
<section class="section-row">
<section>
<div class="section">
## Project
@ -25,7 +25,7 @@ The idea for Graphite began with a desire to create artwork and edit photos usin
</div>
</section>
<section class="section-row">
<section>
<div class="diptych">
@ -90,7 +90,7 @@ As an independent community-driven software project, Graphite will always remain
})();
</script> -->
<!-- <section id="opener-message" class="section-row">
<!-- <section id="opener-message">
<div class="section">
## A 2D creative tool made for everyone
@ -168,7 +168,7 @@ Dennis is a mix between a mathematician and a mad scientist. While still enjoyin
</section>
<section class="section-row">
<section>
<div class="triptych">

View File

@ -6,7 +6,7 @@ sort_by = "date"
generate_feed = true
+++
<section id="intro" class="section-row">
<section id="intro">
<div class="section">
# Blog

View File

@ -2,7 +2,7 @@
title = "Contact the team"
+++
<section class="section-row reading-material">
<section class="reading-material">
<div class="section">
# Contact the team

View File

@ -6,7 +6,7 @@ css = ["/donate.css"]
js = ["/fundraising.js"]
+++
<section class="section-row">
<section>
<div class="section">
# Donate
@ -18,7 +18,7 @@ js = ["/fundraising.js"]
<section id="fundraising" class="feature-box">
<div class="box">
<div class="section-row">
<div>
<div class="section">

View File

@ -5,7 +5,7 @@ title = "Graphite features"
css = ["/features.css"]
+++
<section class="section-row">
<section>
<div class="section">
# Graphite features
@ -15,7 +15,7 @@ The current version of Graphite provides tools for designing vector art and grap
</div>
</section>
<section class="section-row">
<section>
<div class="diptych">
@ -43,7 +43,7 @@ Always on the bleeding edge and built to last— Graphite is written on a robust
</section>
<section class="section-row">
<section>
<div class="diptych">
@ -76,7 +76,7 @@ Marrying vector and raster under one roof enables both art forms to complement e
</section>
<section class="section-row">
<section>
<div class="section">
## Roadmap

View File

@ -5,7 +5,7 @@ title = "Imaginate"
order = 2
+++
<!-- <section id="imaginate-creative-concepts" class="section-row feature-explainer">
<!-- <section id="imaginate-creative-concepts">
<div class="diptych">
<div class="section">

View File

@ -2,7 +2,7 @@
title = "Graphite license"
+++
<section class="section-row reading-material">
<section class="reading-material">
<div class="section">
# Graphite license

View File

@ -5,7 +5,7 @@ title = "Graphite logo"
css = ["/logo.css"]
+++
<section class="section-row reading-material">
<section class="reading-material">
<div class="section">
# Graphite logo
@ -48,7 +48,7 @@ Download the complete [logo kit](https://static.graphite.rs/logos/graphite-logo-
<a href="https://static.graphite.rs/logos/graphite-logotype-color-480x1874.png" download>Download (PNG 480x1874)</a>
</div>
<div>
<img src="https://static.graphite.rs/logos/graphite-logo-color.svg" height="160" />
<img src="https://static.graphite.rs/logos/graphite-logo-color.svg" width="160" height="160" />
<span>Graphite Icon (Color)</span>
<a href="https://static.graphite.rs/logos/graphite-logo-color.svg" download>Download (SVG)</a>
<a href="https://static.graphite.rs/logos/graphite-logo-color-240x240.png" download>Download (PNG 240x240)</a>
@ -67,7 +67,7 @@ Download the complete [logo kit](https://static.graphite.rs/logos/graphite-logo-
<a href="https://static.graphite.rs/logos/graphite-logotype-solid-480x1874.png" download>Download (PNG 480x1874)</a>
</div>
<div>
<img src="https://static.graphite.rs/logos/graphite-logo-solid.svg" height="160" />
<img src="https://static.graphite.rs/logos/graphite-logo-solid.svg" width="160" height="160" />
<span>Graphite Icon (Solid)</span>
<a href="https://static.graphite.rs/logos/graphite-logo-solid.svg" download>Download (SVG)</a>
<a href="https://static.graphite.rs/logos/graphite-logo-solid-240x240.png" download>Download (PNG 240x240)</a>
@ -86,7 +86,7 @@ Download the complete [logo kit](https://static.graphite.rs/logos/graphite-logo-
<a href="https://static.graphite.rs/logos/graphite-logotype-solid-white-480x1874.png" download>Download (PNG 480x1874)</a>
</div>
<div>
<img src="https://static.graphite.rs/logos/graphite-logo-solid-white.svg" height="160" />
<img src="https://static.graphite.rs/logos/graphite-logo-solid-white.svg" width="160" height="160" />
<span>Graphite Icon (Solid, White)</span>
<a href="https://static.graphite.rs/logos/graphite-logo-solid-white.svg" download>Download (SVG)</a>
<a href="https://static.graphite.rs/logos/graphite-logo-solid-white-240x240.png" download>Download (PNG 240x240)</a>

View File

@ -2,7 +2,7 @@
title = "Press resources"
+++
<section class="section-row reading-material">
<section class="reading-material">
<div class="section">
# Press resources

View File

@ -5,7 +5,7 @@ title = "Volunteer"
css = ["/volunteer.css"]
+++
<section class="section-row">
<section>
<div class="section">
# Volunteer
@ -15,7 +15,7 @@ Graphite is built by volunteers. Join the effort to bring great, free creative s
</div>
</section>
<section class="section-row">
<section>
<div class="diptych">
@ -36,8 +36,7 @@ Use your artistic talents to plan and produce ambitious open art projects publis
### PUBLICITY TEAM
Become the author of feature announcements, [blog](/blog) posts, website content, the user manual, press releases, social media posts, and industry outreach.
<!-- Become the author of feature announcements, [blog](/blog) posts, website content, the [user manual](/learn), press releases, social media posts, and industry outreach. -->
Become the author of release notes, feature announcements, blog posts, website content, the user manual, press releases, social media posts, and industry outreach.
</div>

View File

@ -44,4 +44,4 @@ Once you begin writing code, please open a pull request immediately and mark it
Open a new PR as a draft / convert an existing PR to a draft:
![Screenhots showing GitHub's "Create pull request (arrow) > Create draft pull request" and "Still in progress? Convert to draft" buttons](https://static.graphite.rs/content/contribute/draft-pr.png)
![Screenhots showing GitHub's "Create pull request (arrow) > Create draft pull request" and "Still in progress? Convert to draft" buttons](https://static.graphite.rs/content/volunteer/guide/draft-pr.png)

View File

@ -18,7 +18,7 @@
--color-sage: #739c7e;
--color-seaside-rgb: 165, 213, 200;
--font-size-intro-heading: 60px;
--font-size-intro-heading: calc(var(--font-size-heading-h1) * 1.25);
--font-size-intro-body: 22px;
--font-size-link: 24px;
--font-size-heading-h1: 48px;
@ -45,6 +45,7 @@
--font-size-body: 16px;
--page-edge-padding: 28px;
--border-thickness: 1px;
}
@media screen and (max-width: 500px) {
@ -56,7 +57,6 @@
--font-size-body: 16px;
--page-edge-padding: 20px;
--border-thickness: 1px;
}
@media screen and (max-width: 400px) {
@ -162,28 +162,28 @@ p ~ p {
margin-top: 1.5em;
}
h1 ~ p,
h2 ~ p,
h3 ~ p,
h1 ~ ol li p,
h2 ~ ol li p,
h3 ~ ol li p,
h1 ~ img,
h2 ~ img,
h3 ~ img,
h1 + .section-row,
h1,
h2,
h3 {
& ~ p,
& ~ ol li p,
& ~ img {
margin-top: 20px;
}
}
h1 ~ .informational-group,
.video-embed + p,
p ~ h1,
p ~ h2,
p ~ h3,
p ~ details summary,
p ~ blockquote,
p ~ video,
p ~ .video-embed,
p ~ .informational-group,
p ~ .image-comparison,
p + .link,
p ~ .video-background,
p ~ .video-embed,
.video-embed + p,
.video-embed + .link,
.video-embed + .button,
img + .link {
@ -216,6 +216,8 @@ code {
}
pre {
display: flex;
max-width: 100%;
color: var(--color-fog);
// This zero transform sets this element as the root for `position: fixed`
transform: translate(0);
@ -241,6 +243,8 @@ pre {
display: block;
overflow-x: auto;
padding: 20px;
width: 0;
flex: 1 1 auto;
}
// Language name in top right corner
@ -338,7 +342,6 @@ summary {
.reading-material.reading-material.reading-material {
max-width: 800px;
flex: 0 1 auto;
hr {
margin-top: 40px;
@ -396,6 +399,24 @@ summary {
}
}
.video-background {
position: relative;
font-size: 0;
video {
max-width: Min(100%, 1280px);
}
// Uses a white border over the video to cover up the edges of the video which, due to a Chrome rendering bug, displays black edges sometimes when scrolling
&::after {
content: "";
position: absolute;
inset: 0;
border: 2px solid white;
pointer-events: none;
}
}
.image-comparison {
position: relative;
touch-action: pan-y pinch-zoom;
@ -793,23 +814,6 @@ hr,
}
}
.section-row {
display: flex;
align-items: stretch;
gap: calc(40 * var(--variable-px)) calc(80 * var(--variable-px));
&.vertical {
flex-direction: column;
}
@media screen and (max-width: 800px) {
&.section-row {
flex-direction: column;
align-items: center;
}
}
}
.info-box {
margin-top: calc(40 * var(--variable-px));
padding: calc(80 * var(--variable-px));
@ -885,11 +889,6 @@ hr,
background: var(--color-crimson);
}
}
+ div,
hr + .section-row + & {
margin-top: calc(80 * var(--variable-px));
}
}
.informational-group {
@ -931,10 +930,21 @@ hr,
&.concepts {
justify-content: space-between;
margin: 0 -10px;
width: calc(100% + 20px);
.informational {
flex-direction: column;
flex: 0 1 auto;
margin: 0 10px;
@media screen and (max-width: 1100px) {
width: calc(100% / 3 - 40px);
}
@media screen and (max-width: 400px) {
width: calc(100% / 2 - 20px);
}
img {
width: 72px;
@ -942,6 +952,10 @@ hr,
object-position: calc(-72px * var(--atlas-index)) 0;
margin-bottom: 8px;
}
span {
text-align: center;
}
}
}
@ -985,22 +999,19 @@ blockquote {
}
}
// Page content
.page {
body > .page {
box-sizing: border-box;
min-width: 320px;
header {
header {
padding: 0 var(--page-edge-padding);
color: var(--color-walnut);
// var(--max-width) + (80px + 32px) * 2
@media screen and (max-width: 1824px) {
.ripple {
width: calc(100% + (40px * 2));
margin-left: -40px;
margin-right: -40px;
width: calc(100% + (var(--page-edge-padding) * 2));
margin-left: calc(-1 * var(--page-edge-padding));
margin-right: calc(-1 * var(--page-edge-padding));
}
hr {
@ -1036,10 +1047,10 @@ blockquote {
text-decoration: none;
--height: 60px;
--button-padding: 24px;
--nav-font-size: 28px;
--nav-font-size: 28px; // Keep up to date with `NAV_BUTTON_INITIAL_FONT_SIZE` in navbar.js
font-size: var(--nav-font-size);
&.button {
&.button.button {
height: var(--height);
padding-left: var(--button-padding);
padding-right: var(--button-padding);
@ -1162,9 +1173,9 @@ blockquote {
hr {
background: none;
}
}
}
main {
main {
padding: 0 var(--page-edge-padding);
.content {
@ -1186,7 +1197,6 @@ blockquote {
}
pre {
max-width: 100%;
box-sizing: border-box;
overflow: auto;
}
@ -1196,9 +1206,9 @@ blockquote {
}
}
}
}
}
footer {
footer {
display: flex;
flex-direction: column;
align-items: center;
@ -1233,7 +1243,7 @@ blockquote {
span {
text-align: center;
}
}
}
}
.fundraising {

View File

@ -46,10 +46,16 @@
@media screen and (max-width: 960px) {
flex-wrap: wrap;
justify-content: center;
flex-direction: column;
.banner.banner {
width: 100%;
max-width: 540px;
background: var(--color-fog);
img {
margin: auto;
max-width: 480px;
}
}
}

View File

@ -1,8 +1,12 @@
.three-column-layout {
position: relative;
display: flex;
gap: 40px;
transform: translate(0);
.reading-material {
width: 800px;
flex: 0 0 auto;
.prev-next {
display: flex;
@ -21,6 +25,130 @@
}
}
@media screen and (max-width: 1320px) {
.contents {
display: none;
}
.reading-material.reading-material {
margin-right: 0;
}
}
.hamburger-menu-button {
display: none;
border: none;
cursor: pointer;
width: 30px;
height: 30px;
}
// Overlaid fold-out menu
@media screen and (max-width: 1080px) {
gap: 0;
.chapters {
position: sticky;
height: 100vh;
width: 0;
margin-top: calc(-120 * var(--variable-px));
overflow: visible;
z-index: 10;
&.open .wrapper-outer {
left: 0;
}
.wrapper-outer {
position: absolute;
background: white;
top: 0;
bottom: 0;
padding-left: var(--page-edge-padding);
margin-left: calc(-1 * var(--page-edge-padding));
padding-bottom: 120px;
margin-bottom: -120px;
border-right: var(--border-thickness) solid var(--color-walnut);
box-sizing: border-box;
width: 300px;
transition: left 0.2s ease-in-out;
left: -310px;
&::after {
content: "";
position: absolute;
top: 0;
bottom: 0;
right: -10px;
width: 10px;
background: linear-gradient(to right, rgba(0, 0, 0, 0.2), transparent);
}
.wrapper-inner {
position: relative;
overflow-y: auto;
height: 100%;
padding-right: var(--page-edge-padding);
padding-bottom: 120px;
ul:first-of-type {
margin-top: calc(120 * var(--variable-px));
}
.hamburger-menu-button.close {
display: inline-block;
background: none;
overflow: hidden;
position: absolute;
top: 20px;
right: 20px;
&::before,
&::after {
content: "";
position: absolute;
background: var(--color-walnut);
width: 36px;
height: 4px;
top: 50%;
left: 50%;
transform: translate(-18px, -2px) rotate(45deg);
}
&::after {
transform: translate(-18px, -2px) rotate(-45deg);
}
}
}
}
}
.reading-material {
margin-left: auto;
margin-right: auto;
width: 100%;
.article-title {
display: flex;
white-space: nowrap;
gap: 20px;
.hamburger-menu-button.open {
flex: 0 0 auto;
position: relative;
display: inline-block;
vertical-align: top;
top: calc(var(--font-size-heading-h1) * 0.25);
background: linear-gradient(to bottom, transparent calc(25% / 3), var(--color-walnut) calc(25% / 3), var(--color-walnut) calc(75% / 3), transparent calc(75% / 3), transparent calc(125% / 3), var(--color-walnut) calc(125% / 3), var(--color-walnut) calc(175% / 3), transparent calc(175% / 3), transparent calc(225% / 3), var(--color-walnut) calc(225% / 3), var(--color-walnut) calc(275% / 3), transparent calc(275% / 3));
}
h1 {
white-space: normal;
}
}
}
}
aside {
position: sticky;
align-self: flex-start;
@ -55,9 +183,12 @@
}
&.chapters li.active a {
&.chapters {
li.active,
li.active a {
color: var(--color-ale);
}
}
&.contents {
li {

View File

@ -2,6 +2,7 @@
overflow: hidden;
}
// LOGO
#logo {
display: flex;
@ -11,6 +12,7 @@
max-height: 240px;
}
}
// LOGO
.pencil-texture {
position: absolute;
@ -26,6 +28,7 @@
}
}
// QUICK LINKS
#quick-links {
margin-top: calc(80 * var(--variable-px));
display: flex;
@ -36,15 +39,18 @@
display: flex;
gap: calc(var(--font-size-link) * 0.8);
flex-direction: row;
flex-wrap: wrap;
img {
width: 48px;
width: calc(var(--font-size-link) * 2);
display: block;
}
}
}
// QUICK LINKS
#hero-message {
// TAGLINE
#tagline {
h1 {
font-size: var(--font-size-intro-heading);
}
@ -57,6 +63,7 @@
}
}
}
// TAGLINE
.hexagons {
max-width: var(--max-width);
@ -90,157 +97,13 @@
}
}
#graphite-tomorrow > img {
margin: 16px 0;
}
#disciplines {
align-items: center;
.informational-group {
margin-top: 0;
.informational {
margin-top: 40px;
}
}
}
// #node-graph {
// #node-graph-intro {
// .section {
// align-items: center;
// }
// ~ section {
// margin-top: calc(80 * var(--variable-px));
// }
// }
// }
#vector-art {
.section {
align-items: center;
.background-video {
position: relative;
font-size: 0;
video {
max-width: Min(100%, 1280px);
}
// Uses a white border over the video to cover up the edges of the video which, due to a Chrome rendering bug, displays black edges sometimes when scrolling
&::after {
content: "";
position: absolute;
inset: 0;
border: 2px solid white;
pointer-events: none;
}
}
.download-artwork {
display: flex;
align-items: center;
img {
width: 128px;
height: 128px;
border: 12px solid var(--color-walnut);
vertical-align: top;
}
p {
display: flex;
flex-direction: column;
max-width: 300px;
margin-left: 40px;
text-align: left;
}
}
}
}
#imaginate {
#imaginate-intro {
.alternating-text {
position: relative;
span {
// Move left by half (since it's centered) the average (half the 74px difference) of the variance in word lengths
margin-left: calc(-1.54em / 2 / 2);
opacity: 0;
$alternate-duration: 15s;
$alternate-words: 5;
animation: $alternate-duration infinite linear 0s fade-word;
// The 1st child is the widest
&:not(:nth-child(1)) {
position: absolute;
right: 0;
}
@for $i from 1 through $alternate-words {
&:nth-child(#{$i}) {
animation-delay: ($alternate-duration / $alternate-words * ($i - 1));
}
}
@keyframes fade-word {
// Fade in at the start (which begins staggered on each item by `animation-delay`)
#{0.0%} { opacity: 0; }
#{2.5%} { opacity: 1; }
// Remain visible for this item's slice of time, then fade out
#{0.0% + 100% / ($alternate-words + 1)} { opacity: 1; }
#{2.5% + 100% / ($alternate-words + 1)} { opacity: 0; }
}
}
}
.section {
align-items: center;
}
~ section {
margin-top: calc(80 * var(--variable-px));
}
}
// #imaginate-creative-concepts-carousel {
// margin-top: 20px;
// .screenshot-details {
// justify-content: center;
// }
// + blockquote {
// margin-top: 0;
// }
// }
}
.feature-explainer {
margin-top: 40px;
.diptych {
width: 100%;
.section {
justify-content: center;
align-items: center;
h2 {
text-align: center;
}
}
}
.section {
flex: 1 1 calc(50% - (80 * var(--variable-px)) / 2);
}
}
// SCREENSHOTS
// SCREENSHOTS
// TODAY AND TOMORROW
// TODAY AND TOMORROW
//
// COMMUNITY
#community {
background-color: var(--color-lime);
@ -273,6 +136,8 @@
display: flex;
gap: 20px;
flex: 100000 1 0;
flex-wrap: wrap;
min-width: Min(100%, calc(240px + 20px + 240px));
div {
min-height: auto;
@ -339,6 +204,7 @@
font-size: calc(var(--font-size-link) * 0.9);
color: inherit;
border: var(--border-thickness) solid currentColor;
border-radius: 0; // Required for iOS Safari
outline: none;
margin: 0;
padding: 0 var(--font-size-link);
@ -355,6 +221,7 @@
background: none;
outline: none;
cursor: pointer;
border-radius: 0; // Required for iOS Safari
&:focus {
border-color: var(--input-focus-color);
@ -394,11 +261,109 @@
}
}
}
// COMMUNITY
#demo-video {
max-width: 1000px;
// VECTOR ART
#vector-art {
.section {
align-items: center;
.download-artwork {
display: flex;
align-items: center;
margin-top: 20px;
img {
width: 128px;
height: 128px;
border: 12px solid var(--color-walnut);
vertical-align: top;
flex: 0 0 auto;
}
p {
display: flex;
flex-direction: column;
max-width: 300px;
margin-left: 40px;
text-align: left;
}
}
}
}
// VECTOR ART
// IMAGINATE
#imaginate {
> .section {
align-items: center;
h1 {
text-align: center;
.alternating-text {
position: relative;
span {
// Move left by half (since it's centered) the average (half the 74px difference) of the variance in word lengths
margin-left: calc(-1.54em / 2 / 2);
opacity: 0;
$alternate-duration: 15s;
$alternate-words: 5;
animation: $alternate-duration infinite linear 0s fade-word;
// The 1st child is the widest
&:not(:nth-child(1)) {
position: absolute;
right: 0;
}
@for $i from 1 through $alternate-words {
&:nth-child(#{$i}) {
animation-delay: ($alternate-duration / $alternate-words * ($i - 1));
}
}
@keyframes fade-word {
// Fade in at the start (which begins staggered on each item by `animation-delay`)
#{0.0%} { opacity: 0; }
#{2.5%} { opacity: 1; }
// Remain visible for this item's slice of time, then fade out
#{0.0% + 100% / ($alternate-words + 1)} { opacity: 1; }
#{2.5% + 100% / ($alternate-words + 1)} { opacity: 0; }
}
}
}
}
}
> .diptych {
margin-top: calc(80 * var(--variable-px));
.section {
align-items: center;
h2 {
text-align: center;
}
}
}
// #imaginate-creative-concepts-carousel {
// margin-top: 20px;
// .screenshot-details {
// justify-content: center;
// }
// + blockquote {
// margin-top: 0;
// }
// }
}
// IMAGINATE
// FUNDRAISING
#fundraising {
background-color: var(--color-seaside);
color: rgba(0, 0, 0, 0.9);
@ -407,8 +372,33 @@
max-width: 400px;
}
}
// FUNDRAISING
// PROCEDURALISM
#proceduralism .section {
align-items: center;
}
// PROCEDURALISM
// DISCIPLINES
#disciplines .section {
align-items: center;
.informational-group .informational {
margin-top: 40px;
}
}
// DISCIPLINES
// DEMO VIDEO
#demo-video {
max-width: 1000px;
}
// DEMO VIDEO
// GET INVOLVED
#get-involved-box {
background-color: var(--color-lemon);
background-blend-mode: color-burn;
}
// GET INVOLVED

View File

@ -17,3 +17,12 @@
background-color: var(--color-ale);
}
}
.creative-contributions,
.code-contributions {
.button.button.button {
height: auto;
text-align: left;
white-space: normal;
}
}

View File

@ -1,4 +1,5 @@
addEventListener("DOMContentLoaded", trackScrollHeadingInTOC);
addEventListener("DOMContentLoaded", listenForClickToOpenTOC);
// Listen for scroll events and update the active section in the table of contents to match the visible content's heading
function trackScrollHeadingInTOC() {
@ -50,3 +51,13 @@ function trackScrollHeadingInTOC() {
addEventListener("scroll", updateVisibleHeading);
updateVisibleHeading();
}
function listenForClickToOpenTOC() {
document.querySelector("[data-hamburger-menu-button-open]")?.addEventListener("click", () => {
document.querySelector("[data-chapters]")?.classList.add("open");
});
document.querySelector("[data-hamburger-menu-button-close]")?.addEventListener("click", () => {
document.querySelector("[data-chapters]")?.classList.remove("open");
});
}

View File

@ -1,6 +1,6 @@
const NAV_BUTTON_INITIAL_FONT_SIZE = 32;
const NAV_BUTTON_INITIAL_FONT_SIZE = 28; // Keep up to date with `--nav-font-size` in base.scss
const RIPPLE_ANIMATION_MILLISECONDS = 100;
const RIPPLE_WIDTH = 120;
const RIPPLE_WIDTH = 100;
const HANDLE_STRETCH = 0.4;
let ripplesInitialized;
@ -84,10 +84,11 @@ function animate(forceRefresh) {
}
function setRipples() {
const rippleStrokeWidth = Number.parseInt(window.getComputedStyle(ripplePath).getPropertyValue("--border-thickness"), 10);
const navButtonFontSize = Number.parseInt(window.getComputedStyle(navButtons[0]).fontSize, 10) || NAV_BUTTON_INITIAL_FONT_SIZE;
const mediaQueryScaleFactor = navButtonFontSize / NAV_BUTTON_INITIAL_FONT_SIZE;
const rippleHeight = fullRippleHeight * (mediaQueryScaleFactor * 0.5 + 0.5);
const rippleHeight = Math.round(fullRippleHeight * mediaQueryScaleFactor) + (rippleStrokeWidth === 2 ? 0 : 0.5);
const rippleSvgRect = rippleSvg.getBoundingClientRect();
const rippleSvgLeft = rippleSvgRect.left;
const rippleSvgWidth = rippleSvgRect.width;

View File

@ -0,0 +1,28 @@
window.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll("section p").forEach((paragraph) => {
// Recursively traverse the DOM tree and modify the text nodes
const recursivelyAddWbr = (node) => {
if (node.nodeType === Node.TEXT_NODE) {
const newNodes = node.textContent.split("/");
for (let i = 0; i < newNodes.length - 1; i++) {
newNodes[i] += "/";
}
const tempSpan = document.createElement("span");
tempSpan.innerHTML = newNodes.join("<wbr>");
const replacementNodes = tempSpan.childNodes;
mutationQueue.push([node, replacementNodes]);
} else {
node.childNodes.forEach(recursivelyAddWbr);
}
};
// Perform the recursive traversal and replace the text nodes
const mutationQueue = [];
recursivelyAddWbr(paragraph);
mutationQueue.forEach(([node, newNodes]) => {
node.replaceWith(...newNodes);
});
});
});

View File

@ -3,7 +3,7 @@
{% block title %}Page not found{% endblock title %}
{% block content %}
<section id="404" class="section-row">
<section id="404">
<div class="section">
<h1>Page not found</h1>
<p>Or as the machines like to say it: <code>404</code>.</p>

View File

@ -14,7 +14,7 @@
{% block content %}
{% set this = section | default(value = page) %}
<section class="section-row reading-material">
<section class="reading-material">
<div class="section">
<div class="details">
<h1 class="headline">{{ this.title }}</h2>

View File

@ -25,6 +25,7 @@
<script src="/js/{{ js | safe }}"></script>
{% endfor %}
{% endif %}
<script src="/js/text-justification.js"></script>
<script src="/js/navbar.js"></script>
<script defer data-domain="graphite.rs" data-api="/visit/event" src="/visit/script.outbound-links.file-downloads.js"></script>
<style>

View File

@ -35,13 +35,16 @@
{% set flat_index_of_this = 0 %}
<section class="three-column-layout">
<aside class="chapters">
<aside class="chapters" data-chapters>
<div class="wrapper-outer">
<div class="wrapper-inner">
<button class="hamburger-menu-button close" data-hamburger-menu-button-close></button>
<ul>
<li class="title {% if current_path == book.path %}active{% endif %}"><a href="{{ book.path }}">{{ book.title }}</a></li>
<li class="title{% if current_path == book.path %} active{% endif %}"><a href="{{ book.path }}" title="{{ book.title }}">{{ book.title }}</a></li>
</ul>
{% for chapter in chapters %}
<ul>
<li class="chapter {% if current_path == chapter.path %}active{% endif %}"><a href="{{ chapter.path }}">&raquo; {{ chapter.title }}</a></li>
<li class="chapter{% if current_path == chapter.path %} active{% endif %}"><a href="{{ chapter.path }}" title="{{ chapter.title }}">&raquo; {{ chapter.title }}</a></li>
{% set_global flat_pages = flat_pages | concat(with = chapter) %}
{% if chapter == this %}{% set_global flat_index_of_this = flat_pages | length - 1 %}{% endif %}
@ -53,18 +56,23 @@
{% set_global flat_pages = flat_pages | concat(with = page) %}
{% if page == this %}{% set_global flat_index_of_this = flat_pages | length - 1 %}{% endif %}
<li {% if current_path == page.path %}class="active"{% endif %}><a href="{{ page.path }}">&raquo; {{ page.title }}</a></li>
<li {% if current_path == page.path %}class="active"{% endif %}><a href="{{ page.path }}" title="{{ page.title }}">&raquo; {{ page.title }}</a></li>
{% endfor %}
{% endif %}
</ul>
{% endfor %}
</div>
</div>
</aside>
<section class="section-row reading-material">
<section class="reading-material">
<div class="section">
<div class="article-title">
<button class="hamburger-menu-button open" data-hamburger-menu-button-open></button>
<h1>{{ this.title }}</h1>
</div>
<article>
{{ this.content | safe }}
</article>
@ -76,7 +84,7 @@
{% set prev = flat_pages | nth(n = flat_index_of_this - 1) %}
{% endif %}
{% if prev %}
<a href="{{ prev.path }}">
<a href="{{ prev.path }}" title="{{ prev.title }}">
<svg width="40" height="40" viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg">
<path d="M20,0C8.95,0,0,8.95,0,20c0,11.05,8.95,20,20,20c11.05,0,20-8.95,20-20C40,8.95,31.05,0,20,0z M20,38c-9.93,0-18-8.07-18-18S10.07,2,20,2s18,8.07,18,18S29.93,38,20,38z" />
<polygon points="24.71,10.71 23.29,9.29 12.59,20 23.29,30.71 24.71,29.29 15.41,20" />
@ -91,7 +99,7 @@
{% set next = flat_pages | nth(n = flat_index_of_this + 1) %}
{% endif %}
{% if next %}
<a href="{{ next.path }}">
<a href="{{ next.path }}" title="{{ next.title }}">
{{ next.title }}
<svg width="40" height="40" viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg">
<path d="M20,0C8.95,0,0,8.95,0,20c0,11.05,8.95,20,20,20c11.05,0,20-8.95,20-20C40,8.95,31.05,0,20,0z M20,38c-9.93,0-18-8.07-18-18S10.07,2,20,2s18,8.07,18,18S29.93,38,20,38z" />
@ -106,33 +114,29 @@
<aside class="contents">
<ul>
<li class="title">
<a href="#">
{% if this.toc | length > 0 %}
Contents<span> (top 🡑)</span>
{% else %}
Back to top 🡑
{% endif %}
<a href="#" title="{% if this.toc | length > 0 %}Contents (top ↑){% else %}Back to top ↑{% endif %}">
{% if this.toc | length > 0 %}Contents<span> (top ↑)</span>{% else %}Back to top ↑{% endif %}
</a>
</li>
</ul>
<ul>
{% for depth_1 in this.toc %}
<li><a href="#{{ depth_1.id }}">{{ depth_1.title }}</a></li>
<li><a href="#{{ depth_1.id }}" title="{{ depth_1.title }}">{{ depth_1.title }}</a></li>
{% for depth_2 in depth_1.children %}
<ul>
<li><a href="#{{ depth_2.id }}">{{ depth_2.title }}</a></li>
<li><a href="#{{ depth_2.id }}" title="{{ depth_2.title }}">{{ depth_2.title }}</a></li>
{% for depth_3 in depth_2.children %}
<ul>
<li><a href="#{{ depth_3.id }}">{{ depth_3.title }}</a></li>
<li><a href="#{{ depth_3.id }}" title="{{ depth_3.title }}">{{ depth_3.title }}</a></li>
{% for depth_4 in depth_3.children %}
<ul>
<li><a href="#{{ depth_4.id }}">{{ depth_4.title }}</a></li>
<li><a href="#{{ depth_4.id }}" title="{{ depth_4.title }}">{{ depth_4.title }}</a></li>
{% for depth_5 in depth_4.children %}
<ul>
<li><a href="#{{ depth_5.id }}">{{ depth_5.title }}</a></li>
<li><a href="#{{ depth_5.id }}" title="{{ depth_5.title }}">{{ depth_5.title }}</a></li>
{% for depth_6 in depth_5.children %}
<ul>
<li><a href="#{{ depth_6.id }}">{{ depth_6.title }}</a></li>
<li><a href="#{{ depth_6.id }}" title="{{ depth_6.title }}">{{ depth_6.title }}</a></li>
</ul>
{% endfor %}
</ul>