0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-16 21:46:22 -05:00

WIP: Launch Post (#333)

* feat: add blog to `www`

* feat: add BlogHeader

* wip: add heroImage support

* feat: update hero image styling

* finalize blog post

* use site index instead of blog index

* fix: don't use float

* chore: copy cleanup

* fix: scroll issue on landing page

Co-authored-by: Fred K. Schott <fkschott@gmail.com>
This commit is contained in:
Nate Moore 2021-06-08 14:01:46 -05:00 committed by GitHub
parent 9ca9b4e69a
commit 8af8b86f0b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 1310 additions and 22 deletions

View file

@ -10,7 +10,7 @@ const error = Astro.request.url.searchParams.get('error');
<head>
<title>Error 500</title>
<link rel="preconnect"href="https://fonts.gstatic.com">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&family=IBM+Plex+Sans&display=swap">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&family=IBM+Plex+Sans:wght@400;700&display=swap">
<link rel="stylesheet" href="http://cdn.skypack.dev/prism-themes/themes/prism-material-dark.css">
<style>

View file

@ -6,7 +6,7 @@ const onceMessages = ['Ready!', 'watching for file changes'].map((str) => new Re
const neverWarn = new RegExp(
'(' +
/(run "snowpack init" to create a project config file.)|/.source +
/(astro\/dist\/internal\/__astro_component.js: Unscannable package import found.)|/.source +
/(Unscannable package import found.)|/.source +
/(Cannot call a namespace \('loadLanguages'\))|/.source +
/('default' is imported from external module 'node-fetch' but never used)/.source +
')'

6
www/astro.config.mjs Normal file
View file

@ -0,0 +1,6 @@
export default {
buildOptions: {
sitemap: true,
site: 'https://astro.build/'
},
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

155
www/public/blog/code.css Normal file
View file

@ -0,0 +1,155 @@
.language-css > code,
.language-sass > code,
.language-scss > code {
color: #fd9170;
}
[class*="language-"] .namespace {
opacity: 0.7;
}
.token.atrule {
color: #c792ea;
}
.token.attr-name {
color: #ffcb6b;
}
.token.attr-value {
color: #a5e844;
}
.token.attribute {
color: #a5e844;
}
.token.boolean {
color: #c792ea;
}
.token.builtin {
color: #ffcb6b;
}
.token.cdata {
color: #80cbc4;
}
.token.char {
color: #80cbc4;
}
.token.class {
color: #ffcb6b;
}
.token.class-name {
color: #f2ff00;
}
.token.comment {
color: #616161;
}
.token.constant {
color: #c792ea;
}
.token.deleted {
color: #ff6666;
}
.token.doctype {
color: #616161;
}
.token.entity {
color: #ff6666;
}
.token.function {
color: #c792ea;
}
.token.hexcode {
color: #f2ff00;
}
.token.id {
color: #c792ea;
font-weight: bold;
}
.token.important {
color: #c792ea;
font-weight: bold;
}
.token.inserted {
color: #80cbc4;
}
.token.keyword {
color: #c792ea;
}
.token.number {
color: #fd9170;
}
.token.operator {
color: #89ddff;
}
.token.prolog {
color: #616161;
}
.token.property {
color: #80cbc4;
}
.token.pseudo-class {
color: #a5e844;
}
.token.pseudo-element {
color: #a5e844;
}
.token.punctuation {
color: #89ddff;
}
.token.regex {
color: #f2ff00;
}
.token.selector {
color: #ff6666;
}
.token.string {
color: #a5e844;
}
.token.symbol {
color: #c792ea;
}
.token.tag {
color: #ff6666;
}
.token.unit {
color: #fd9170;
}
.token.url {
color: #ff6666;
}
.token.variable {
color: #ff6666;
}

198
www/public/blog/index.css Normal file
View file

@ -0,0 +1,198 @@
@import './theme';
@import './code';
* {
box-sizing: border-box;
margin: 0;
}
:root {
--user-font-scale: 1rem - 16px;
--max-width: calc(100% - 2rem);
}
@media (min-width: 50em) {
:root {
--max-width: 40em;
}
}
body {
display: flex;
flex-direction: column;
min-height: 100vh;
font-family: var(--font-body);
font-size: 1rem;
font-size: clamp(0.875rem, 0.4626rem + 1.0309vw + var(--user-font-scale), 1.125rem);
line-height: 1.625;
}
body {
width: 100%;
display: grid;
--gutter: 0.5rem;
--doc-padding: 2rem;
}
.layout {
display: grid;
grid-auto-flow: column;
grid-template-columns: minmax(var(--gutter), 1fr) minmax(0, var(--max-width)) minmax(var(--gutter), 1fr);
gap: 1em;
}
.layout > article {
grid-column: 2;
}
nav ul {
list-style: none;
padding: 0;
}
/* Typography */
:is(h1, h2, h3, h4, h5, h6) {
margin-bottom: 1.38rem;
font-weight: 400;
line-height: 1.3;
}
:is(h1, h2) {
max-width: 40ch;
}
:is(h2, h3):not(:first-child) {
margin-top: 3rem;
}
h1 {
font-size: clamp(2.488rem, 1.9240rem + 1.4100vw, 3.052rem);
}
h2 {
font-size: clamp(2.074rem, 1.7070rem + 0.9175vw, 2.441rem);
}
h3 {
font-size: clamp(1.728rem, 1.5030rem + 0.5625vw, 1.953rem);
}
h4 {
font-size: clamp(1.44rem, 1.3170rem + 0.3075vw, 1.563rem);
}
h5 {
font-size: clamp(1.2rem, 1.1500rem + 0.1250vw, 1.25rem);
}
p {
color: var(--theme-text-light);
}
small, .text_small {
font-size: 0.833rem;
}
a {
color: var(--theme-accent);
font-weight: 400;
text-underline-offset: 0.08em;
text-decoration: none;
align-items: center;
gap: 0.5rem;
}
a > code:not([class*="language"]) {
position: relative;
color: var(--theme-accent);
background: transparent;
text-underline-offset: var(--padding-block);
}
a > code:not([class*="language"])::before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: block;
background: var(--theme-accent);
opacity: var(--theme-accent-opacity);
border-radius: var(--border-radius);
}
a:hover,
a:focus {
text-decoration: underline;
}
a:focus {
outline: 2px solid currentColor;
outline-offset: 0.25em;
}
strong {
font-weight: 600;
color: inherit;
}
/* Supporting Content */
code:not([class*="language"]) {
--border-radius: 3px;
--padding-block: 0.2rem;
--padding-inline: 0.33rem;
font-family: var(--font-mono);
font-size: .85em;
color: inherit;
background-color: var(--theme-code-inline-bg);
padding: var(--padding-block) var(--padding-inline);
margin: calc(var(--padding-block) * -1) -0.125em;
border-radius: var(--border-radius);
}
pre > code:not([class*="language"]) {
background-color: transparent;
padding: 0;
margin: 0;
border-radius: 0;
color: inherit;
}
pre {
position: relative;
background-color: var(--theme-code-bg);
color: var(--theme-code-text);
--padding-block: 1rem;
--padding-inline: 2rem;
padding: var(--padding-block) var(--padding-inline);
padding-right: calc(var(--padding-inline) * 2);
margin-left: calc(50vw - var(--padding-inline));
transform: translateX(-50vw);
line-height: 1.414;
width: calc(100vw + (var(--padding-inline) * 2));
max-width: calc(100% + (var(--padding-inline) * 2));
overflow-y: hidden;
overflow-x: auto;
}
@media (min-width: 37.75em) {
pre {
--padding-inline: 1.25rem;
border-radius: 8px;
}
}
.flex {
display: flex;
align-items: center;
}
img.cover {
width: 100%;
max-height: 50vh;
object-fit: cover;
}

76
www/public/blog/theme.css Normal file
View file

@ -0,0 +1,76 @@
:root {
--font-fallback: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;
--font-body: "IBM Plex Sans", var(--font-fallback);
--font-mono: "IBM Plex Mono", Consolas, "Andale Mono WT", "Andale Mono",
"Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono",
"Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", Monaco,
"Courier New", Courier, monospace;
--color-white: #FFF;
--color-black: #000014;
--color-gray-50: #F9FAFB;
--color-gray-100: #F3F4F6;
--color-gray-200: #E5E7EB;
--color-gray-300: #D1D5DB;
--color-gray-400: #9CA3AF;
--color-gray-500: #6B7280;
--color-gray-600: #4B5563;
--color-gray-700: #374151;
--color-gray-800: #1F2937;
--color-gray-900: #111827;
--color-blue: #3894FF;
--color-blue-rgb: 56,148,255;
--color-green: #17C083;
--color-green-rgb: 23,192,131;
--color-orange: #FF5D01;
--color-orange-rgb: 255,93,1;
--color-purple: #882DE7;
--color-purple-rgb: 136,45,231;
--color-red: #FF1639;
--color-red-rgb: 255,22,57;
--color-yellow: #FFBE2D;
--color-yellow-rgb: 255,190,45;
}
:root {
color-scheme: light;
--theme-accent: var(--color-orange);
--theme-accent-rgb: var(--color-orange-rgb);
--theme-accent-opacity: 0.1;
--theme-divider: var(--color-gray-100);
--theme-text: var(--color-gray-800);
--theme-text-light: var(--color-gray-600);
--theme-text-lighter: var(--color-gray-400);
--theme-bg: var(--color-white);
--theme-bg-offset: var(--color-gray-100);
--theme-bg-accent: rgba(var(--theme-accent-rgb), var(--theme-accent-opacity));
--theme-code-inline-bg: var(--color-gray-100);
--theme-code-text: var(--color-gray-100);
--theme-code-bg: var(--color-gray-700);
}
body {
background: var(--theme-bg);
color: var(--theme-text);
}
:root.theme-dark {
color-scheme: dark;
--theme-accent-opacity: 0.3;
--theme-divider: var(--color-gray-900);
--theme-text: var(--color-gray-200);
--theme-text-light: var(--color-gray-400);
--theme-text-lighter: var(--color-gray-600);
--theme-bg: var(--color-black);
--theme-bg-offset: var(--color-gray-900);
--theme-code-inline-bg: var(--color-gray-800);
--theme-code-text: var(--color-gray-200);
--theme-code-bg: var(--color-gray-900);
}
::selection {
color: var(--theme-accent);
background-color: rgba(var(--theme-accent-rgb), var(--theme-accent-opacity));
}

View file

@ -1,16 +1,11 @@
<svg width="192" height="256" viewBox="0 0 192 256" fill="none"
xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M131.008 18.9288C132.952 21.3419 133.943 24.5981 135.925 31.1105L179.234 173.38C163.221 165.074 145.814 159.083 127.456 155.85L99.258 60.5596C98.7966 59.0005 97.3645 57.9308 95.7386 57.9308C94.1084 57.9308 92.6736 59.006 92.2159 60.5706L64.3591 155.802C45.9158 159.02 28.4293 165.022 12.3483 173.359L55.8695 31.0776L55.8695 31.0776C57.8581 24.5764 58.8524 21.3257 60.7964 18.9171C62.5125 16.7906 64.7447 15.1392 67.2801 14.1201C70.152 12.9657 73.5513 12.9657 80.3499 12.9657H111.435C118.242 12.9657 121.646 12.9657 124.521 14.1225C127.058 15.1437 129.292 16.7985 131.008 18.9288Z" fill="url(#paint0_linear)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M136.19 180.151C129.051 186.256 114.8 190.419 98.3859 190.419C78.2394 190.419 61.3534 184.147 56.8727 175.712C55.2709 180.547 54.9116 186.079 54.9116 189.614C54.9116 189.614 53.8563 206.969 65.9272 219.04C65.9272 212.772 71.0083 207.691 77.2762 207.691C88.0194 207.691 88.0073 217.064 87.9975 224.668C87.9972 224.896 87.9969 225.122 87.9969 225.347C87.9969 236.889 95.051 246.783 105.083 250.953C103.585 247.871 102.744 244.41 102.744 240.753C102.744 229.745 109.207 225.646 116.718 220.883L116.718 220.883C122.694 217.093 129.334 212.882 133.91 204.434C136.297 200.027 137.653 194.979 137.653 189.614C137.653 186.315 137.14 183.135 136.19 180.151Z" fill="#FF5D01"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M136.19 180.151C129.051 186.256 114.8 190.419 98.3859 190.419C78.2394 190.419 61.3534 184.147 56.8727 175.712C55.2709 180.547 54.9116 186.079 54.9116 189.614C54.9116 189.614 53.8563 206.969 65.9272 219.04C65.9272 212.772 71.0083 207.691 77.2762 207.691C88.0194 207.691 88.0073 217.064 87.9975 224.668C87.9972 224.896 87.9969 225.122 87.9969 225.347C87.9969 236.889 95.051 246.783 105.083 250.953C103.585 247.871 102.744 244.41 102.744 240.753C102.744 229.745 109.207 225.646 116.718 220.883L116.718 220.883C122.694 217.093 129.334 212.882 133.91 204.434C136.297 200.027 137.653 194.979 137.653 189.614C137.653 186.315 137.14 183.135 136.19 180.151Z" fill="url(#paint1_linear)"/>
<defs>
<linearGradient id="paint0_linear" x1="144.599" y1="5.42267" x2="95.7911" y2="173.38" gradientUnits="userSpaceOnUse">
<stop stop-color="#000014"/>
<stop offset="1" stop-color="#150426"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="168.336" y1="130.49" x2="126.065" y2="218.982" gradientUnits="userSpaceOnUse">
<stop stop-color="#FF1639"/>
<stop offset="1" stop-color="#FF1639" stop-opacity="0"/>
</linearGradient>
</defs>
<svg width="256" height="256" fill="none" xmlns="http://www.w3.org/2000/svg">
<style>
#flame { fill: #FF5D01; }
#a { fill: #000014; }
@media (prefers-color-scheme: dark) {
#a { fill: #fff; }
}
</style>
<path id="a" fill-rule="evenodd" clip-rule="evenodd" d="M163.008 18.929c1.944 2.413 2.935 5.67 4.917 12.181l43.309 142.27a180.277 180.277 0 00-51.778-17.53l-28.198-95.29a3.67 3.67 0 00-7.042.01l-27.857 95.232a180.225 180.225 0 00-52.01 17.557l43.52-142.281c1.99-6.502 2.983-9.752 4.927-12.16a15.999 15.999 0 016.484-4.798c2.872-1.154 6.271-1.154 13.07-1.154h31.085c6.807 0 10.211 0 13.086 1.157a16.004 16.004 0 016.487 4.806z" />
<path id="flame" fill-rule="evenodd" clip-rule="evenodd" d="M168.19 180.151c-7.139 6.105-21.39 10.268-37.804 10.268-20.147 0-37.033-6.272-41.513-14.707-1.602 4.835-1.961 10.367-1.961 13.902 0 0-1.056 17.355 11.015 29.426 0-6.268 5.081-11.349 11.349-11.349 10.743 0 10.731 9.373 10.721 16.977v.679c0 11.542 7.054 21.436 17.086 25.606a23.27 23.27 0 01-2.339-10.2c0-11.008 6.463-15.107 13.974-19.87 5.976-3.79 12.616-8.001 17.192-16.449a31.024 31.024 0 003.743-14.82c0-3.299-.513-6.479-1.463-9.463z" />
</svg>

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -15,7 +15,7 @@ html {
display: grid;
width: 100%;
max-width: 100vw;
overflow-x: hidden;
overflow: hidden;
height: 100%;
background-color: #000014;
}

View file

@ -0,0 +1,15 @@
---
import AvatarList from './AvatarList.astro';
---
<footer>
<AvatarList />
</footer>
<style>
footer {
margin-top: auto;
padding: 2rem 0;
border-top: 3px solid var(--theme-divider);
}
</style>

View file

@ -0,0 +1,10 @@
---
import authorData from '../data/authors.json';
export let authorId: string;
const author = authorData[authorId];
---
<div class="author">
<p>by {author.name}{' '}<a href={`https://twitter.com/${author.twitter}`}>@{author.twitter}</a></p>
</div>

View file

@ -0,0 +1,74 @@
<!-- Thanks to @5t3ph for https://smolcss.dev/#smol-avatar-list! -->
<ul class="avatar-list">
<li><a href="https://smolcss.dev/#smol-avatar-list"><img alt="Avatar 1" width="64" height="64" src='https://avataaars.io/?avatarStyle=Transparent&topType=LongHairBun&accessoriesType=Blank&hairColor=Auburn&facialHairType=BeardMedium&facialHairColor=Auburn&clotheType=ShirtCrewNeck&clotheColor=Blue01&eyeType=Side&eyebrowType=RaisedExcitedNatural&mouthType=Serious&skinColor=Tanned' /></a></li>
<li><a href="https://smolcss.dev/#smol-avatar-list"><img alt="Avatar 2" width="64" height="64" src='https://avataaars.io/?avatarStyle=Transparent&topType=LongHairDreads&accessoriesType=Blank&hairColor=Brown&facialHairType=Blank&clotheType=ShirtScoopNeck&clotheColor=PastelGreen&eyeType=Default&eyebrowType=DefaultNatural&mouthType=Smile&skinColor=Tanned' /></a></li>
<li><a href="https://smolcss.dev/#smol-avatar-list"><img alt="Avatar 3" width="64" height="64" src='https://avataaars.io/?avatarStyle=Transparent&topType=LongHairCurly&hairColor=BrownDark&facialHairType=Blank&clotheType=GraphicShirt&clotheColor=Pink&graphicType=Diamond&eyeType=Side&eyebrowType=Default&mouthType=Default&skinColor=Brown'/></a></li>
</ul>
<style>
.avatar-list {
--avatar-size: 2.5rem;
--avatar-count: 3;
display: grid;
list-style: none;
/* Default to displaying most of the avatar to
enable easier access on touch devices, ensuring
the WCAG touch target size is met or exceeded */
grid-template-columns: repeat(
var(--avatar-count),
max(44px, calc(var(--avatar-size) / 1.15))
);
/* `padding` matches added visual dimensions of
the `box-shadow` to help create a more accurate
computed component size */
padding: 0.08em;
font-size: var(--avatar-size);
}
@media (any-hover: hover) and (any-pointer: fine) {
.avatar-list {
/* We create 1 extra cell to enable the computed
width to match the final visual width */
grid-template-columns: repeat(
calc(var(--avatar-count) + 1),
calc(var(--avatar-size) / 1.75)
);
}
}
.avatar-list li {
width: var(--avatar-size);
height: var(--avatar-size);
}
.avatar-list li:hover ~ li a,
.avatar-list li:focus-within ~ li a {
transform: translateX(33%);
}
.avatar-list img,
.avatar-list a {
display: block;
border-radius: 50%;
}
.avatar-list a {
transition: transform 180ms ease-in-out;
}
.avatar-list img {
width: 100%;
height: 100%;
object-fit: cover;
background-color: #fff;
box-shadow: 0 0 0 0.05em #fff, 0 0 0 0.08em rgba(0, 0, 0, 0.15);
}
.avatar-list a:focus {
outline: 2px solid transparent;
/* Double-layer trick to work for dark and light backgrounds */
box-shadow: 0 0 0 0.08em var(--theme-accent), 0 0 0 0.12em white;
}
</style>

View file

@ -30,7 +30,4 @@ export let permalink: string;
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&family=IBM+Plex+Sans&display=swap" rel="stylesheet" />
<!-- Styles -->
<link rel="stylesheet" href="/global.css" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&family=IBM+Plex+Sans:wght@400;700&display=swap">

View file

@ -0,0 +1,39 @@
---
export let author: string;
export let source: string;
export let sourceHref: string;
---
<blockquote>
<slot />
<div class="source">
<p>{author}</p>
<a href={sourceHref}>{source}</a>
</div>
</blockquote>
<style>
blockquote {
font-size: 1.5rem;
--padding-block: 1rem;
--padding-inline: 1.25rem;
--color: var(--theme-divider);
display: flex;
flex-direction: column;
padding: var(--padding-block) var(--padding-inline);
margin-left: calc(var(--padding-inline) * -1);
margin-right: calc(var(--padding-inline) * -1);
background: transparent;
border-left: calc(var(--padding-inline) / 2) solid var(--color);
border-radius: 0;
}
blockquote .source {
font-weight: 500;
color: var(--color);
font-size: 1rem;
}
</style>

View file

@ -0,0 +1,93 @@
<header class="layout">
<article>
<h1>
<a href="/">
<svg class="logo" width="32" height="32" viewBox="0 0 256 256" fill="none" xmlns="http://www.w3.org/2000/svg">
<style>
#flame {
fill: #ff5d01;
}
#a {
fill: #000014;
}
</style>
<title>Astro</title>
<path
id="a"
fill-rule="evenodd"
clip-rule="evenodd"
d="M163.008 18.929c1.944 2.413 2.935 5.67 4.917 12.181l43.309 142.27a180.277 180.277 0 00-51.778-17.53l-28.198-95.29a3.67 3.67 0 00-7.042.01l-27.857 95.232a180.225 180.225 0 00-52.01 17.557l43.52-142.281c1.99-6.502 2.983-9.752 4.927-12.16a15.999 15.999 0 016.484-4.798c2.872-1.154 6.271-1.154 13.07-1.154h31.085c6.807 0 10.211 0 13.086 1.157a16.004 16.004 0 016.487 4.806z"
/>
<path
id="flame"
fill-rule="evenodd"
clip-rule="evenodd"
d="M168.19 180.151c-7.139 6.105-21.39 10.268-37.804 10.268-20.147 0-37.033-6.272-41.513-14.707-1.602 4.835-1.961 10.367-1.961 13.902 0 0-1.056 17.355 11.015 29.426 0-6.268 5.081-11.349 11.349-11.349 10.743 0 10.731 9.373 10.721 16.977v.679c0 11.542 7.054 21.436 17.086 25.606a23.27 23.27 0 01-2.339-10.2c0-11.008 6.463-15.107 13.974-19.87 5.976-3.79 12.616-8.001 17.192-16.449a31.024 31.024 0 003.743-14.82c0-3.299-.513-6.479-1.463-9.463z"
/>
</svg>
<span>Astro</span>
</a>
</h1>
<a class="header-subitem" href="https://github.com/snowpackjs/astro" target="_blank">
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
</svg>
View on GitHub →
</a>
</article>
</header>
<style>
header {
padding-top: 1rem;
padding-bottom: 1rem;
height: 4.5rem;
}
article {
display: flex;
align-items: center;
justify-content: space-between;
}
.header-subitem {
display: flex;
gap: 0.5em;
align-items: center;
justify-content: center;
color: var(--theme-text-lighter);
font-size: initial;
padding: 0.5rem;
}
.header-subitem:hover {
color: var(--theme-accent);
}
.header-subitem svg {
width: 1.5rem;
height: 1.5rem;
}
@media (max-width: 32em) {
.header-subitem {
display: none;
}
}
h1 {
margin: 0;
font-size: 1.5rem;
max-width: 100%;
}
.logo {
transform: translateY(0.25rem);
}
svg {
width: 2.5rem;
height: 2.5rem;
}
h1 a {
text-decoration: none;
display: inline-flex;
}
</style>

View file

@ -0,0 +1,75 @@
---
import Author from './Author.astro';
export let title: string;
export let author: string;
export let publishDate: string;
export let heroImage: string;
---
<div class="layout">
<article class="content">
<div>
<header>
{heroImage && <img width="1600" height="480" class="hero-image" loading="lazy" src={heroImage} />}
<p class="publish-date">{publishDate}</p>
<h1 class="title">{title}</h1>
<Author authorId={author} />
</header>
<main>
<slot />
</main>
</article>
</div>
<style>
.hero-image {
width: 100vw;
min-height: 320px;
height: 60vh;
max-height: 480px;
object-position: bottom center;
object-fit: cover;
margin-bottom: 4rem;
}
.content {
margin-top: 2rem;
margin-bottom: 8rem;
}
.content :global(main > * + *) {
margin-top: 1rem;
}
.content :global(h2) {
margin-top: 4rem;
}
header {
display: flex;
flex-direction: column;
text-align: center;
align-items: center;
justify-content: center;
padding-bottom: 2rem;
margin-bottom: 2rem;
border-bottom: 4px solid var(--theme-divider);
}
.title,
.author,
.publish-date {
margin: 0;
}
.publish-date,
.author {
color: var(--theme-text-lighter);
}
.title {
font-size: 2.25rem;
font-weight: 700;
}
</style>

View file

@ -0,0 +1,58 @@
---
import Author from './Author.astro';
export let title: string;
export let publishDate: string;
export let href: string;
---
<article class="post-preview">
<header>
<h3 class="publish-date">{publishDate}</h3>
<a href={href}><h1 class="title">{title}</h1></a>
</header>
<main>
<slot />
<a href={href}>Read more</a>
</main>
</article>
<style>
.content :global(main > * + *) {
margin-top: 1rem;
}
.post-preview {
padding-bottom: 2rem;
margin-bottom: 2rem;
border-bottom: 4px solid var(--theme-divider);
}
header {
display: flex;
flex-direction: column;
text-align: left;
align-items: flex-start;
justify-content: center;
padding-bottom: 2rem;
}
.title,
.author,
.publish-date {
margin: 0;
}
.publish-date,
.author {
font-size: 1.25rem;
color: var(--theme-text-lighter);
}
.title {
font-size: 2.25rem;
font-weight: 700;
color: var(--theme-text);
}
</style>

View file

@ -0,0 +1,45 @@
---
export let type = "tip";
export let title;
---
<aside class={`note type-${type}`}>
{title && <label>{title}</label>}
<slot />
</aside>
<style>
.note {
--padding-block: 1rem;
--padding-inline: 1.25rem;
display: flex;
flex-direction: column;
padding: var(--padding-block) var(--padding-inline);
margin-left: calc(var(--padding-inline) * -1);
margin-right: calc(var(--padding-inline) * -1);
background: var(--theme-bg-offset);
border-left: calc(var(--padding-inline) / 2) solid var(--color);
border-radius: 0;
}
.note label {
font-weight: 500;
color: var(--color);
}
.note.type-tip {
--color: var(--color-green);
--color-rgb: var(--color-green-rgb);
}
.note.type-warning {
--color: var(--color-yellow);
--color-rgb: var(--color-yellow-rgb);
}
.note.type-error {
--color: var(--color-red);
--color-rgb: var(--color-red-rgb);
}
</style>

View file

@ -0,0 +1,22 @@
---
export let code: string;
---
<pre><code>{code.trim().split('\n').map(ln => <span class="line">
{ln.startsWith('#') ? <span class="comment">{ln}</span> : ln}
</span>)}</code></pre>
<style>
pre, code {
white-space: pre;
}
.comment {
color: var(--color-gray-400);
}
.line {
display: block;
}
.line:empty::after {
content: " ";
}
</style>

9
www/src/config.ts Normal file
View file

@ -0,0 +1,9 @@
export const sidebar = [
{
text: 'Introduction',
children: [
{ text: 'Welcome', link: '/' },
{ text: 'Example', link: '/example' },
],
},
];

View file

@ -0,0 +1,6 @@
{
"fred": {
"name": "Fred K. Schott",
"twitter": "FredKSchott"
}
}

211
www/src/layouts/Blog.astro Normal file
View file

@ -0,0 +1,211 @@
---
import ArticleFooter from '../components/ArticleFooter.astro';
import SiteSidebar from '../components/SiteSidebar.astro';
import ThemeToggle from '../components/ThemeToggle.tsx';
import DocSidebar from '../components/DocSidebar.tsx';
export let content;
const headers = content?.astro?.headers;
---
<html>
<head>
<title>{content?.title}</title>
<link rel="stylesheet" href="/blog/index.css" />
<style>
body {
width: 100%;
display: grid;
grid-template-rows: 3.5rem 1fr;
--gutter: 0.5rem;
--doc-padding: 2rem;
}
header {
width: 100%;
height: 100%;
background-color: var(--theme-bg-offset);
display: flex;
align-items: center;
justify-content: center;
}
.layout {
display: grid;
grid-auto-flow: column;
grid-template-columns: minmax(var(--gutter), 1fr) minmax(0, var(--max-width)) minmax(var(--gutter), 1fr);
gap: 1em;
}
.menu-and-logo {
gap: 1em;
}
nav.layout {
justify-content: center;
width: 100%;
}
nav.layout :global(> :nth-child(1)) {
grid-column: 2;
}
#site-title {
display: flex;
align-items: center;
gap: 0.25em;
font-size: 1.5rem;
font-weight: 700;
margin: 0;
line-height: 1;
color: var(--theme-text);
text-decoration: none;
}
#site-title:hover,
#site-title:focus {
color: var(--theme-text-light);
}
#site-title h1 {
font: inherit;
color: inherit;
margin: 0;
}
.nav-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
max-width: 64ch;
margin: 0 auto;
}
.layout :global(> *) {
width: 100%;
height: 100%;
}
.sidebar {
max-height: 100vh;
position: sticky;
top: 0;
padding: var(--doc-padding) 0;
}
#sidebar-nav {
display: none;
max-height: 100vh;
padding: var(--doc-padding) 0;
}
#article {
padding: var(--doc-padding) var(--gutter);
grid-column: 2;
display: flex;
flex-direction: column;
align-items: center;
height: 100%;
}
.content {
max-width: 64ch;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.content > main {
margin-bottom: 4rem;
}
#sidebar-content {
display: none;
}
@media (min-width: 64em) {
.menu-and-logo button {
display: none;
}
.layout {
grid-template-columns: 20rem minmax(0, 1fr);
padding-left: 1rem;
padding-right: 1rem;
}
#article {
grid-column: 2;
}
#sidebar-nav {
display: flex;
}
#sidebar-content {
/* display: flex; */
grid-column: 3;
}
.nav-wrapper {
display: contents;
}
}
@media (min-width: 88em) {
.layout {
grid-template-columns: minmax(var(--gutter), 1fr) 20rem minmax(0, var(--max-width)) 16rem minmax(var(--gutter), 1fr);
padding-left: 0;
padding-right: 0;
}
#sidebar-nav,
.nav-wrapper :global(:nth-child(1)) {
grid-column: 2;
}
#article,
.nav-wrapper :global(:nth-child(2)) {
grid-column: 3;
}
#sidebar-content,
.nav-wrapper :global(:nth-child(3)) {
display: flex;
grid-column: 4;
}
}
</style>
</head>
<body>
<header>
<nav class="layout">
<div class="nav-wrapper">
<div class="menu-and-logo flex">
<a id="site-title" href="/blog">
<svg width="1em" height="1em" viewBox="0 0 340 340" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M320 170C320 170 296.88 171.746 267.428 188.75C237.975 205.754 205.754 237.975 188.75 267.428C171.746 296.88 170 320 170 320C170 320 168.254 296.88 151.25 267.428C134.246 237.975 102.025 205.754 72.5721 188.75C43.1197 171.746 20 170 20 170C20 170 43.1197 168.254 72.5721 151.25C102.025 134.246 134.246 102.025 151.25 72.5721C168.254 43.1197 170 20 170 20C170 20 171.746 43.1197 188.75 72.5721C205.754 102.025 237.975 134.246 267.428 151.25C296.88 168.254 320 170 320 170Z" fill="currentColor"/>
</svg>
<h1>Astro Log</h1>
</a>
</div>
<div />
<div>
<ThemeToggle:idle />
</div>
</div>
</nav>
</header>
<main class="layout">
<div id="article">
<article class="content">
<main>
<slot />
</main>
</article>
</div>
</main>
</body>
</html>

View file

@ -0,0 +1,76 @@
---
import BaseHead from '../../components/BaseHead.astro';
import BlogHeader from '../../components/BlogHeader.astro';
import BlogPostPreview from '../../components/BlogPostPreview.astro';
let title = 'Astro Blog';
let description = 'Everything you need to know about Astro, direct from mission control.';
let permalink = 'https://astro.build/blog';
---
<html>
<head>
<BaseHead title={title} description={description} permalink={permalink} />
<link rel="stylesheet" href="/blog/index.css" />
<style>
body {
width: 100%;
display: grid;
grid-template-rows: 3.5rem 1fr;
--gutter: 0.5rem;
--doc-padding: 2rem;
}
header {
width: 100%;
height: 100%;
background-color: var(--theme-bg-offset);
display: flex;
align-items: center;
justify-content: center;
}
.content {
margin-top: 4rem;
margin-bottom: 8rem;
}
.content :global(main > * + *) {
margin-top: 1rem;
}
.intro {
padding-bottom: 4rem;
margin-bottom: 2rem;
border-bottom: 4px solid var(--theme-divider);
}
.intro > * {
margin: 0;
}
.latest {
font-size: 2.5rem;
font-weight: 700;
}
</style>
</head>
<body>
<BlogHeader />
<div class="layout">
<article class="content">
<section class="intro">
<h1 class="latest">The Astro Blog</h1>
<p>{description}</p>
</section>
<section>
<BlogPostPreview title="Introducing Astro: Ship Less JavaScript" publishDate="Tuesday, June 8 2021" href="/blog/introducing-astro">
<p>We're excited to announce Astro as a new way to build static websites and deliver lightning-fast performance without sacrificing a modern developer experience.</p>
</BlogPostPreview>
</section>
</article>
</div>
</body>
</html>

View file

@ -0,0 +1,120 @@
---
import { Markdown } from 'astro/components';
import BaseHead from '../../components/BaseHead.astro';
import BlogHeader from '../../components/BlogHeader.astro';
import BlogPost from '../../components/BlogPost.astro';
import Shell from '../../components/Shell.astro';
import Note from '../../components/Note.astro';
import BlockQuote from '../../components/BlockQuote.astro';
let title = 'Introducing Astro: Ship Less JavaScript';
let description = `We're excited to announce Astro as a new way to build static websites and deliver lightning-fast performance without sacrificing a modern developer experience.`;
let publishDate = 'Tuesday, June 8 2021';
let author = 'fred';
let heroImage = '/assets/blog/introducing-astro.jpg';
let permalink = 'https://astro.build/blog/introducing-astro';
---
<html>
<head>
<BaseHead title={title} description={description} permalink={permalink} />
<link rel="stylesheet" href="/blog/index.css" />
</head>
<body>
<BlogHeader />
<BlogPost title={title} author={author} heroImage={heroImage} publishDate={publishDate}>
<Markdown>
There's a simple secret to building a faster website — *just ship less*.
Unfortunately, modern web development has been trending in the opposite direction—towards *more.* More JavaScript, more features, more moving parts, and ultimately more complexity needed to keep it all running smoothly.
We're excited to announce Astro as a new way to build static websites and deliver lightning-fast performance without sacrificing your modern developer experience. To build Astro we borrowed the best parts of our favorite web frameworks and then added a few innovations of our own, including:
- **Bring Your Own Framework (BYOF):** Astro supports popular UI frameworks like React, Svelte, Vue, Preact, web components, or plain HTML + JavaScript.
- **100% Static HTML, No JS:** Astro strips out JavaScript from your final build and renders every page to HTML by default.
- **Hydrating Components:** Astro loads components that need interactivity when they enter the browser viewport. If the user never sees it, they never load it.
- **Fully-Featured:** Astro supports TypeScript, Scoped CSS, CSS Modules, Sass, Tailwind, Markdown, MDX, and any of your favorite npm packages.
- **SEO Enabled:** Automatic sitemaps, RSS feeds, pagination and collections take the pain out of SEO and syndication.
This post marks the first public beta release of Astro. **Missing features and bugs are still to be expected at this early stage.** There is still some months to go before an official 1.0 release, but there are already several fast sites built with Astro in production today.
<Note>
To learn more about Astro and start building your first site, check out [the project README.](https://github.com/snowpackjs/astro#-guides)
</Note>
## Getting Started
Starting a new project in Astro is easy:
<Shell code={`
# create your project
mkdir new-project-directory
cd new-project-directory
npm init astro
# install your dependencies
npm install
# start the dev server and open your browser
npm start
`} />
<Note>
To learn more about Astro and start building your first site, check out [the project README.](https://github.com/snowpackjs/astro#-guides)
</Note>
## How Astro Works
Astro works a lot like a static site generator. If you have ever used Eleventy, Hugo, or Jekyll (or even a server-side web framework like Rails, Laravel, or Django) then you should feel right at home with Astro.
In Astro, you compose your website using UI components from your favorite JavaScript web framework (React, Svelte, Vue, etc). Astro renders your entire site to static HTML during the build. The result is a fully static website with all JavaScript removed from the final page. No monolithic JavaScript application required, just static HTML that loads as fast as possible in the browser regardless of how many UI components you used to generate it.
Of course, sometimes client-side JavaScript is inevitable. Image carousels, shopping carts, and auto-complete search bars are just a few examples of things that require some JavaScript to run in the browser. This is where Astro really shines: When a component requires JavaScript, Astro only adds that one component (and any dependencies) to the final browser payload. The rest of your site continues to exist as static, lightweight HTML.
In other full-stack web frameworks this level of per-component optimization would be impossible without loading the entire page in JavaScript, deplaying interactivity. In Astro, this kind of [partial hydration](https://addyosmani.com/blog/rehydration/) is built into the tool itself.
You can even [automatically defer components](https://codepen.io/jonneal/full/ZELvMvw) to only load once they become visible on the page with the `:visible` modifier.
This new approach to web architecture is called [islands architecture](https://jasonformat.com/islands-architecture/). We didn't coin the term, but Astro may have perfected the technique. We are confident that an HTML-first, JavaScript-only-as-needed approach is the best solution for the majority of content-based websites.
<Note>
To learn more about Astro and start building your first site, check out [the project README.](https://github.com/snowpackjs/astro#-guides)
</Note>
## Embracing the Pit of Success
<BlockQuote author="Jeff Atwood" source="Falling Into The Pit of Success" sourceHref="https://blog.codinghorror.com/falling-into-the-pit-of-success/">
A well-designed system makes it easy to do the right things and annoying (but not impossible) to do the wrong things
</BlockQuote>
Poor performance is often framed as a failure of the developer, but we respectfully disagree. In many cases, poor performance is a failure of tooling. It should be difficult to build a slow website.
Astro's main design principle is to lead developers into what [Rico Mariani](https://twitter.com/ricomariani) dubbed "the pit of success". It is our goal to build every site "fast by default" while also delivering a familiar, modern developer experience.
By building your site to static HTML by default, Astro makes it difficult (but never impossible 😉) to build a slow site.
## Long-Term Sustainability
Astro is built by the team of open source developers behind [Snowpack](https://snowpack.dev) and [Skypack](https://skypack.dev), with additional contributions from the community.
**Astro is and always will be free.** It is an open source project released under the [MIT license](https://github.com/snowpackjs/astro/blob/main/LICENSE).
We care deeply about building a more sustainable future for open source software. At the same time, we need to support Astro's development long-term. This requires money (donations alone aren't enough.)
We're inspired by the early success of projects like [Tailwind](https://tailwindcss.com/), [Rome](https://rome.tools/), [Remix](https://remix.run/), [Ionic](https://ionicframework.com/), and others who are experimenting with long-term financial sustainability on top of the Open Source space. Over the next year we'll be exploring how we can create a sustainable business to support a 100% free, open source Astro for years to come.
If your company is as excited about Astro as we are, we'd love to hear from you.
Finally, I'd like to give a **HUGE** thanks to everyone who joined us on day 1 for the private beta. Your feedback has been essential in shaping Astro into the tool it is today. If you're interested in getting involved (or just following along with development) [join us on Discord](https://astro.build/chat).
<Note>
To learn more about Astro and start building your first site, check out [the project README.](https://github.com/snowpackjs/astro#-guides)
</Note>
</Markdown>
</BlogPost>
</body>
</html>

View file

@ -14,6 +14,7 @@ let permalink = 'https://astro.build/';
<html>
<head>
<BaseHead title={title} description={description} permalink={permalink} />
<link rel="stylesheet" href="/global.css" />
</head>
<body>

7
www/vercel.json Normal file
View file

@ -0,0 +1,7 @@
{
"cleanUrls": true,
"trailingSlash": false,
"redirects": [
{ "source": "/chat", "destination": "https://discord.gg/grF4GTXXYm" }
]
}