Compare commits

..

89 commits

Author SHA1 Message Date
993c085952 expose file url to markdown renderer 2023-10-11 11:46:58 -05:00
Alexander Niebuhr
3f231cefed
port https://github.com/withastro/docs/pull/4980 (#8799) 2023-10-11 07:06:20 +02:00
lilnasy
a8b979ef40 [ci] format 2023-10-10 16:40:46 +00:00
Arsh
bd5aa1cd35
fix(transitions router): no-op on the server (#8771)
* fix(transitions router): no-op on the server

* factor out onPopState

* add e2e test case

* Apply suggestions from code review

Co-authored-by: Martin Trapp <94928215+martrapp@users.noreply.github.com>

* use supportsViewTransitions

* add changeset

* warn on navigate() use during ssr

* switch supportsViewTransitions to import.meta.env

* correct typo

* bring back import.meta.env

* !import.meta.env.SSR -> inBrowser

* Apply suggestions from code review

Co-authored-by: Martin Trapp <94928215+martrapp@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Martin Trapp <94928215+martrapp@users.noreply.github.com>

---------

Co-authored-by: Martin Trapp <94928215+martrapp@users.noreply.github.com>
2023-10-10 22:08:35 +05:30
alexanderniebuhr
03e6979c28 [ci] format 2023-10-10 16:11:20 +00:00
Mikkel Ricafrente
75781643a2
fix(cloudflare): runtime types for Cloudflare caches (#8782)
* fix cachestorage reference in cloudflare integration

* add cachestorage to serverdirectorymode

* add changeset

* remove global caches type

* update unlucky-avocados-brake.md
2023-10-10 18:08:17 +02:00
Houston (Bot)
9cd6a6657b
[ci] release (#8768)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-10-10 22:30:52 +08:00
Arsh
c071458257
chore: removed adapters cleanup (#8726)
* update ci, readme, comments, remote workspaces

* fix hosted test fixture

* keep adapter config typedocs
2023-10-10 19:36:35 +05:30
Alexander Niebuhr
0ab6bad7df
fix(cloudflare): esbuild settings for cloudflare (#8788)
---------

Co-authored-by: Jonathan Dunlap <595843+jadbox@users.noreply.github.com>
2023-10-10 09:16:32 +02:00
alexanderniebuhr
90d70eb7c4 [ci] format 2023-10-09 17:16:02 +00:00
Jonathan Dunlap
054c5c6447
fix(cloudflare): support for 'cloudflare:*' imports (#8766)
* chore: add 'cloudflare:sockets' to external list

* chore: add Changeset

* patch: wildcard cloudflare packages

* chore: updated Readme for cloudflare module support

* Update .changeset/heavy-elephants-tan.md

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>

* Update packages/integrations/cloudflare/README.md

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>

---------

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
Co-authored-by: Alexander Niebuhr <alexander@nbhr.io>
2023-10-09 19:13:46 +02:00
ematipico
7ea27f6319 [ci] format 2023-10-09 16:00:28 +00:00
Arsh
c4a7ec4255
fix(windows): ensure drive letter is uppercase (#8741) 2023-10-09 16:58:09 +01:00
bluwy
a0dc79b946 [ci] format 2023-10-09 14:23:53 +00:00
Florian Lefebvre
160d1cd755
feat(tailwind): create a tailwind.config.mjs file by default (#8638) 2023-10-09 22:21:26 +08:00
Martin Trapp
29cdfa0248
Fix transition attributes on islands (#8776)
* Fix transition attributes on islands

* Incorporate comments from review
2023-10-09 16:19:46 +02:00
Martin Trapp
c24f70d916
Fix flickering during view transitions (#8772)
* Fix for #8711

* more descriptive changeset

* chores, while we are at it ...
2023-10-09 16:15:23 +02:00
Bjorn Lu
33d0be50be
Fix snapshot release permissions (#8777) 2023-10-09 20:47:06 +08:00
Bjorn Lu
93b092266f
Make CSS chunk names less confusing (#8754) 2023-10-09 17:29:28 +08:00
Makito
eaed844ea8
fix(assets): add the missing await to getHTMLAttributes (#8773) 2023-10-07 21:22:47 +02:00
Martin Trapp
30de324361
Revert fix #8472 (#8767) 2023-10-06 23:17:27 +02:00
Matthew Phillips
2262814a92 Give snapshot releases the issues: write permission 2023-10-06 16:11:29 -04:00
Matthew Phillips
f9131003d7 Give the snapshot release the right permissions 2023-10-06 16:00:29 -04:00
Matthew Phillips
d51cf5e707 Snapshot release: prevent setting output 2023-10-06 15:50:36 -04:00
Matthew Phillips
e5e6cf16eb Add debugging information on preview releases 2023-10-05 14:14:05 -04:00
Matthew Phillips
41f93e0ccb Print the publish output when it fails 2023-10-05 13:58:03 -04:00
Bjorn Lu
4e5cafa5d2
Fix git tag release (#8752) 2023-10-05 18:45:41 +08:00
Bjorn Lu
ec82e73efa
Fix provenance release (#8749) 2023-10-05 18:29:36 +08:00
Houston (Bot)
584d6f0680
[ci] release (#8738)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-10-05 11:10:06 +01:00
Jacob Lamb
78adbc4433
Update Netlify SSR link (#8700) 2023-10-05 07:18:45 +01:00
Nate Moore
d78806dfe0
fix(#8746): improve error message for dynamic component usage (#8747) 2023-10-04 15:07:21 -05:00
Bjorn Lu
aa265d7302
Remove unused CSS output files when inlined (#8743) 2023-10-04 21:18:39 +08:00
bluwy
b18d4bf3b1 [ci] format 2023-10-04 10:31:04 +00:00
Arsh
21e0757ea2
chore: remove undici polyfill (#8729) 2023-10-04 18:28:36 +08:00
bluwy
272ad45958 [ci] format 2023-10-04 10:26:21 +00:00
Chris
21f4826576
Fixes: Shiki syntax highlighting adds is:raw attribute to the HTML output (#8715)
Co-authored-by: Emanuele Stoppa <my.burning@gmail.com>
2023-10-04 18:23:58 +08:00
Kobe Ruado
71618f4074
Fix markdown rehype plugin example (#8733) 2023-10-04 17:55:02 +08:00
natemoo-re
240d8ff7c9 [ci] format 2023-10-03 21:00:07 +00:00
Nate Moore
357270f2a3
Improve astro info compatability (#8730)
* Improve `astro info` compatability

* Update packages/astro/src/cli/info/index.ts

Co-authored-by: Arsh <69170106+lilnasy@users.noreply.github.com>

* chore: add changeset

* feat(info): add copy to clipboard support on Unix machines with xclip installed

---------

Co-authored-by: Arsh <69170106+lilnasy@users.noreply.github.com>
2023-10-03 15:57:31 -05:00
Florian Lefebvre
f277ba8b70
feat: expose partytown types (close #8723) (#8740) 2023-10-03 23:16:49 +08:00
Emanuele Stoppa
6f60da805e
feat: add provenance to packages (#8737) 2023-10-03 15:25:25 +01:00
Bjorn Lu
d1c75fe158
Fix tsconfig.json update causing the server to crash (#8736) 2023-10-03 14:36:38 +01:00
Genteure
f9477aade1
fix: typo in error deprecation message (#8708)
Co-authored-by: Alexander Niebuhr <alexander@nbhr.io>
2023-10-02 18:36:15 +02:00
Houston (Bot)
78fda5c3ec
[ci] release (#8722)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-10-02 23:55:56 +08:00
Bjorn Lu
455af3235b
Fix CSS styles on windows (#8724) 2023-10-02 23:17:34 +08:00
Ray
6db2687ef0
fix(deno): link to adapter repo (#8712) 2023-10-02 16:33:24 +02:00
alexanderniebuhr
5fb6a266f8 [ci] format 2023-10-02 14:08:47 +00:00
Alexander Niebuhr
3dd65bf889
feat(cloudflare): add local mockings for CF bindings (#8655)
* feat(cloudflare): add D1 database binding

* feat(cloudflare): add local mocking for R2 bindings (#8656)

* feat(cloudflare): add local mocking for KV bindings (#8657)

* feat(cloudflare): add local mocking for Caches bindings (#8664)

* feat(cloudflare): add local mocking for DO bindings (#8690)

---------

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
2023-10-02 16:04:57 +02:00
matthewp
22fae5211a [ci] format 2023-10-02 12:54:01 +00:00
Matthew Phillips
4c2bec681b
Fixes View transition styles being missing when component used multiple times (#8710) 2023-10-02 08:51:53 -04:00
Houston (Bot)
a067c2a2c7
[ci] release (#8699)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-10-02 16:34:57 +08:00
Alexander Niebuhr
0b22bb9af4
fix(cloudflare): broken link in docs (#8709) 2023-09-30 06:49:04 +02:00
Erika
47ea310f01
feat: resolve images through the file systems on applicable runtimes (#8698)
* feat: add a node image endpoint

* test: fix
2023-09-29 23:14:40 +02:00
Erika
db83237dd3
refactor(markdown): Move astro:assets-specific code out of the main Vite plugin (#8704) 2023-09-29 23:14:09 +02:00
Martin Trapp
148b5b8769
Fix preloading stylesheets in view transitions (#8707)
* Fix preload of stylesheets (VT)

* Fix preload of stylesheets (VT)
2023-09-29 20:03:19 +02:00
Bjorn Lu
345808170f
Fix duplicated Astro and Vite injected styles (#8706) 2023-09-29 21:55:46 +08:00
Bjorn Lu
31c59ad8b6
Fix hydration on slow connection (#8680) 2023-09-29 21:54:46 +08:00
Dario Piotrowicz
c3572fd5e0
fix(cloudflare): target es2022 instead of es2020 to fix esbuild incompatibility issues (#8682)
* fix(cloudflare): target es2022 instead of es2020 to fix esbuild incompatibility issues

* add changeset

* update changeset

* fix(cloudflare): change build target to es2022

---------

Co-authored-by: Alexander Niebuhr <alexander@nbhr.io>
2023-09-28 20:56:01 +02:00
Alexander Niebuhr
77d37853cb
fix(cloudflare): sneaky docs (#8694)
* fix(cloudflare): sneaky docs

* resolve docs review comments

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>

* resolve docs review comments

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>

---------

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
2023-09-28 20:26:47 +02:00
Matthew Phillips
eb530e9b61
Remove the Deno example (#8697) 2023-09-28 14:17:46 -04:00
Houston (Bot)
2d33b9362d
[ci] release (#8695)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-09-28 14:12:22 -04:00
Matthew Phillips
2167ffd72f
Revert "[ci] release (#8671)" (#8696)
This reverts commit eada8ab8fa.
2023-09-28 13:57:54 -04:00
Matthew Phillips
0ba32e4402 Adds a stub version number for the old netlify adapter 2023-09-28 13:27:57 -04:00
lilnasy
c4c616c0a5 [ci] format 2023-09-28 17:19:21 +00:00
Arsh
cfd895d877
fix(rerouting): check that the new route is different (#8648)
* fix(rerouting): check that the new route is different

* add tests

* changeset grammar
2023-09-28 22:46:15 +05:30
Houston (Bot)
eada8ab8fa
[ci] release (#8671)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Matthew Phillips <matthew@skypack.dev>
2023-09-28 13:14:13 -04:00
matthewp
3c93476078 [ci] format 2023-09-28 16:23:05 +00:00
Matthew Phillips
824dd4670a
Support content collections with % in filename (#8684)
* Support content collections with % in filename

* Add changeset

* Unused eslint thing

* Update packages/astro/src/core/build/static-build.ts

Co-authored-by: Alexander Niebuhr <alexander@nbhr.io>

---------

Co-authored-by: Alexander Niebuhr <alexander@nbhr.io>
2023-09-28 12:20:25 -04:00
alexanderniebuhr
0e35457c0f [ci] format 2023-09-28 16:07:09 +00:00
Alexander Niebuhr
f6ba533df6
chore(cloudflare): refactor structure, optimize patterns (#8654)
---------

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
Co-authored-by: 100gle <loogle.space@gmail.com>
2023-09-28 18:04:49 +02:00
Arsh
23e7b259eb
chore(ci): pin CI Node version to 18.17.1 (#8693)
* chore(ci): pin E2E Node version to 18.17.1

* pin for the "test" as well

* ...for windows, not ubuntu

* ...for windows, not macos
2023-09-28 20:49:45 +05:30
ElianCodes
8617259fc9 [ci] format 2023-09-28 13:50:31 +00:00
Elian ☕️
ec249f7a98
update all the readme's for expressive code (#8691)
Co-authored-by: HiDeoo <HiDeoo@users.noreply.github.com>
Co-authored-by: Genteure <Genteure@users.noreply.github.com>
Co-authored-by: Bryce Russell <brycetrussell@gmail.com>
Co-authored-by: Reuben Tier <TheOtterlord@users.noreply.github.com>
Co-authored-by: Hippo <hippotastic@users.noreply.github.com>
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
Co-authored-by: Kevin Zuniga Cuellar <kevinzunigacuellar@users.noreply.github.com>
2023-09-28 15:48:03 +02:00
ElianCodes
0ab19ba615 [ci] format 2023-09-28 12:43:03 +00:00
Elian ☕️
e9b77cbf19
Update codesample for Alpine README (#8689)
Co-authored-by: HiDeoo <HiDeoo@users.noreply.github.com>
Co-authored-by: Genteure <Genteure@users.noreply.github.com>
Co-authored-by: Bryce Russell <brycetrussell@gmail.com>
Co-authored-by: Reuben Tier <TheOtterlord@users.noreply.github.com>
Co-authored-by: Hippo <hippotastic@users.noreply.github.com>
2023-09-28 14:40:08 +02:00
Adit Sachde
f5c617e3a3
Match the .well-known directory when generating routes.json (#7776)
* Match the .well-known directory when generating routes.json

* add changeset

* Update .changeset/clean-planets-retire.md

---------

Co-authored-by: Emanuele Stoppa <my.burning@gmail.com>
Co-authored-by: Erika <3019731+Princesseuh@users.noreply.github.com>
2023-09-27 18:34:29 -04:00
matthewp
c0708c921c [ci] format 2023-09-27 22:21:43 +00:00
Arsh
408b50c5ea
fix(redirects): attempt to get only params in dev mode (#8647)
* fix(redirects): attempt to get only params in dev mode

* fixtures/ssr-redirect => fixtures/redirects

* add tests

* Update pnpm-lock.yaml
2023-09-27 18:19:06 -04:00
Michaili K
e797b68160
Fix assets not getting optimized when outDir is outside the CWD (#8670)
* Fix assets not getting optimized when `outDir` is outside the CWD

* Add missing import

* Add changeset

* Fix import, again.

* Use getOutDirWithinCwd in the serverRoot declaration
2023-09-27 18:18:36 -04:00
Matthew Phillips
87d5b841af
New code (#8559) 2023-09-27 17:06:11 -04:00
Matthew Phillips
4ed410db50
Remove Netlify adapter from core (#8574)
* New link

* More explicit

* Add placeholder package.json

* lockfile

* add keyworkds
2023-09-27 16:48:26 -04:00
matthewp
a10a798c18 [ci] format 2023-09-27 19:25:02 +00:00
Matthew Phillips
e6be2d8146
Add View Transitions announcer (#8621)
* Add View Transitions announcer

* fix astro check

* Append the text in a setTimeout

* Use 60 for the timeout

* Add comment on magic number

* Add a changeset

* Update .changeset/small-rules-relax.md

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>

* Bring back announce logic

* Remove mention of env file

---------

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
2023-09-27 15:21:56 -04:00
delucis
5121740de7 [ci] format 2023-09-27 19:19:41 +00:00
Chris Swithinbank
9b0114c7d3
Support integrations added in updateConfig() in astro:config:setup (#8672)
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
2023-09-27 21:17:27 +02:00
Bjorn Lu
e8495c853b
Fix logLevel passed to Vite build (#8678) 2023-09-27 22:30:30 +08:00
martrapp
aad756297c [ci] format 2023-09-27 13:33:07 +00:00
Martin Trapp
63bc37f2b6
API for clientside router (#8571)
* refactored CSR into goto() function

* first refectoring for router API

* added test

* added comments to fixture

* rename + preliminary changeset

* changeset: now 'minor' and featuring Mathew's example from the docs

* moved for simpler diff

* update after #8617

* fixed ts-errors

* more comprehensible handling of intra-page state

* sync with main

* synch from next_tm
2023-09-27 15:30:13 +02:00
Nolan Lawson
9fe4b95969
fix: print image path for NoImageMetadata (#8666) 2023-09-26 21:51:57 +08:00
413 changed files with 87459 additions and 8365 deletions

View file

@ -1,8 +0,0 @@
FROM gitpod/workspace-node
# Install latest pnpm
RUN curl -fsSL https://get.pnpm.io/install.sh | SHELL=`which bash` bash -
# Install deno in gitpod
RUN curl -fsSL https://deno.land/x/install/install.sh | sh
RUN /home/gitpod/.deno/bin/deno completions bash > /home/gitpod/.bashrc.d/90-deno && echo 'export DENO_INSTALL="/home/gitpod/.deno"' >> /home/gitpod/.bashrc.d/90-deno && echo 'export PATH="$DENO_INSTALL/bin:$PATH"' >> /home/gitpod/.bashrc.d/90-deno

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Fixed an issue where the transitions router did not work within framework components.

View file

@ -0,0 +1,5 @@
---
'@astrojs/cloudflare': patch
---
fixes `AdvancedRuntime` & `DirectoryRuntime` types to work woth Cloudflare caches

View file

@ -6,10 +6,6 @@ RUN npm install -g @playwright/test
# Install latest pnpm
RUN npm install -g pnpm
# Install deno
ENV DENO_INSTALL=/usr/local
RUN curl -fsSL https://deno.land/x/install/install.sh | sh
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& curl -sSL https://dl.google.com/linux/direct/google-chrome-stable_current_$(dpkg --print-architecture).deb -o /tmp/chrome.deb \
&& apt-get -y install /tmp/chrome.deb

View file

@ -1,34 +0,0 @@
{
"name": "Deno",
"build": {
"dockerfile": "../examples.deno.Dockerfile"
},
"workspaceFolder": "/workspaces/astro/examples/deno",
"portsAttributes": {
"4321": {
"label": "Application",
"onAutoForward": "openPreview"
}
},
"forwardPorts": [4321],
"postCreateCommand": "pnpm install && cd /workspaces/astro && pnpm run build",
"waitFor": "postCreateCommand",
"postAttachCommand": {
"Server": "pnpm start --host"
},
"customizations": {
"codespaces": {
"openFiles": ["src/pages/index.astro"]
},
"vscode": {
"extensions": ["astro-build.astro-vscode", "esbenp.prettier-vscode"]
}
}
}

View file

@ -1,10 +0,0 @@
FROM mcr.microsoft.com/devcontainers/javascript-node:0-18
# Install latest pnpm
RUN npm install -g pnpm
# Install deno
ENV DENO_INSTALL=/usr/local
RUN curl -fsSL https://deno.land/x/install/install.sh | sh
COPY example-welcome-message.txt /usr/local/etc/vscode-dev-containers/first-run-notice.txt

View file

@ -113,7 +113,7 @@ jobs:
- os: macos-latest
NODE_VERSION: 18
- os: windows-latest
NODE_VERSION: 18
NODE_VERSION: 18.17.1
fail-fast: false
env:
NODE_VERSION: ${{ matrix.NODE_VERSION }}
@ -133,11 +133,6 @@ jobs:
node-version: ${{ matrix.NODE_VERSION }}
cache: "pnpm"
- name: Use Deno
uses: denoland/setup-deno@v1
with:
deno-version: v1.35.0
- name: Install dependencies
run: pnpm install
@ -155,7 +150,7 @@ jobs:
strategy:
matrix:
OS: [ubuntu-latest, windows-latest]
NODE_VERSION: [18]
NODE_VERSION: [18.17.1]
fail-fast: false
env:
NODE_VERSION: ${{ matrix.NODE_VERSION }}

View file

@ -22,6 +22,9 @@ jobs:
name: Changelog PR or Release
if: ${{ github.repository_owner == 'withastro' }}
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- uses: actions/checkout@v3

View file

@ -19,6 +19,11 @@ jobs:
name: Create a snapshot release of a pull request
if: ${{ github.repository_owner == 'withastro' && github.event.issue.pull_request && startsWith(github.event.comment.body, '!preview') }}
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
issues: write
pull-requests: write
steps:
- name: "Check if user has admin access (only admins can publish snapshot releases)."
uses: "lannonbr/repo-permission-check-action@2.0.0"
@ -81,6 +86,8 @@ jobs:
id: publish
run: |
pnpm run release --tag next--${{ steps.getSnapshotName.outputs.result }} > publish.output.txt 2>&1
echo "Release complete"
cat publish.output.txt
echo ::set-output name=result::`cat publish.output.txt`
env:
# Needs access to publish to npm

View file

@ -11,8 +11,6 @@ env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEST_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_TEST_PROJECT_ID }}
VERCEL_TOKEN: ${{ secrets.VERCEL_TEST_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_TEST_SITE_ID }}
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_TEST_AUTH_TOKEN }}
FORCE_COLOR: true
jobs:
@ -35,21 +33,19 @@ jobs:
- name: Install dependencies
run: pnpm install
- name: Install Hosts CLIs
run: pnpm install --global netlify-cli vercel
- name: Build Astro
run: pnpm turbo build --filter astro --filter @astrojs/vercel
- name: Deploy Vercel
- name: Build test project
working-directory: ./packages/integrations/vercel/test/hosted/hosted-astro-project
run:
pnpm run build
vercel --prod --prebuilt
- name: Deploy Netlify
working-directory: ./packages/integrations/netlify/test/hosted/hosted-astro-project
- name: Deploy to Vercel
working-directory: ./packages/integrations/vercel/test/hosted/hosted-astro-project
run:
pnpm run build
netlify deploy --prod
pnpm dlx vercel --prod --prebuilt
- name: Test both hosts
- name: Test
run:
pnpm run test:e2e:hosts

View file

@ -1,6 +1,4 @@
---
image:
file: .Dockerfile
# Commands to start on workspace startup
tasks:
- before: |

View file

@ -3,6 +3,9 @@
# Convert context URL to an array
mapfile -t CONTEXT_URL_ITEMS < <(echo "$GITPOD_WORKSPACE_CONTEXT_URL" | tr '/' '\n')
# Install latest pnpm
curl -fsSL https://get.pnpm.io/install.sh | SHELL=`which bash` bash -
# Check if Gitpod started from a specific example directory in the repository
if [ "${CONTEXT_URL_ITEMS[7]}" = "examples" ]; then
EXAMPLE_PROJECT=${CONTEXT_URL_ITEMS[8]}

View file

@ -52,8 +52,6 @@ Join us on [Discord](https://astro.build/chat) to meet other maintainers. We'll
| [@astrojs/svelte](packages/integrations/svelte) | [![astro version](https://img.shields.io/npm/v/@astrojs/svelte.svg?label=%20)](packages/integrations/svelte/CHANGELOG.md) |
| [@astrojs/vue](packages/integrations/vue) | [![astro version](https://img.shields.io/npm/v/@astrojs/vue.svg?label=%20)](packages/integrations/vue/CHANGELOG.md) |
| [@astrojs/lit](packages/integrations/lit) | [![astro version](https://img.shields.io/npm/v/@astrojs/lit.svg?label=%20)](packages/integrations/lit/CHANGELOG.md) |
| [@astrojs/deno](packages/integrations/deno) | [![astro version](https://img.shields.io/npm/v/@astrojs/deno.svg?label=%20)](packages/integrations/deno/CHANGELOG.md) |
| [@astrojs/netlify](packages/integrations/netlify) | [![astro version](https://img.shields.io/npm/v/@astrojs/netlify.svg?label=%20)](packages/integrations/netlify/CHANGELOG.md) |
| [@astrojs/node](packages/integrations/node) | [![astro version](https://img.shields.io/npm/v/@astrojs/node.svg?label=%20)](packages/integrations/node/CHANGELOG.md) |
| [@astrojs/vercel](packages/integrations/vercel) | [![astro version](https://img.shields.io/npm/v/@astrojs/vercel.svg?label=%20)](packages/integrations/vercel/CHANGELOG.md) |
| [@astrojs/cloudflare](packages/integrations/cloudflare) | [![astro version](https://img.shields.io/npm/v/@astrojs/cloudflare.svg?label=%20)](packages/integrations/cloudflare/CHANGELOG.md) |

View file

@ -11,6 +11,6 @@
"astro": "astro"
},
"dependencies": {
"astro": "^3.1.4"
"astro": "^3.2.4"
}
}

View file

@ -11,9 +11,9 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/mdx": "^1.1.0",
"@astrojs/mdx": "^1.1.1",
"@astrojs/rss": "^3.0.0",
"@astrojs/sitemap": "^3.0.0",
"astro": "^3.1.4"
"@astrojs/sitemap": "^3.0.1",
"astro": "^3.2.4"
}
}

View file

@ -15,7 +15,7 @@
],
"scripts": {},
"devDependencies": {
"astro": "^3.1.4"
"astro": "^3.2.4"
},
"peerDependencies": {
"astro": "^2.0.0-beta.0"

View file

@ -1 +0,0 @@
FROM node:18-bullseye

View file

@ -1,4 +0,0 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}

View file

@ -1,11 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}

View file

@ -1,54 +0,0 @@
# Astro Starter Kit: Deno
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/deno)
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/deno)
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/deno/devcontainer.json)
```sh
npm create astro@latest -- --template deno
```
> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
![basics](https://user-images.githubusercontent.com/4677417/186188965-73453154-fdec-4d6b-9c34-cb35c248ae5b.png)
## 🚀 Project Structure
Inside of your Astro project, you'll see the following folders and files:
```text
/
├── public/
│ └── favicon.svg
├── src/
│ ├── components/
│ │ └── Layout.astro
│ └── pages/
│ └── index.astro
├── package.json
└── tsconfig.json
```
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
Any static assets, like images, can be placed in the `public/` directory.
## 🧞 Commands
All commands are run from the root of the project, from a terminal:
| Command | Action |
| :------------------------ | :----------------------------------------------- |
| `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:4321` |
| `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying |
| | (preview uses Deno CLI) |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more?
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).

View file

@ -1,9 +0,0 @@
import { defineConfig } from 'astro/config';
import deno from '@astrojs/deno';
// https://astro.build/config
export default defineConfig({
output: 'server',
adapter: deno(),
});

View file

@ -1,18 +0,0 @@
{
"name": "@example/deno",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro build",
"preview": "deno run --allow-net --allow-read --allow-env ./dist/server/entry.mjs",
"astro": "astro"
},
"dependencies": {
"astro": "^3.1.4"
},
"devDependencies": {
"@astrojs/deno": "^5.0.1"
}
}

View file

@ -1,9 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
<style>
path { fill: #000; }
@media (prefers-color-scheme: dark) {
path { fill: #FFF; }
}
</style>
</svg>

Before

Width:  |  Height:  |  Size: 749 B

View file

@ -1,61 +0,0 @@
---
interface Props {
title: string;
}
const { title } = Astro.props as Props;
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<title>{title}</title>
</head>
<body>
<slot />
<style>
:root {
--font-size-base: clamp(1rem, 0.34vw + 0.91rem, 1.19rem);
--font-size-lg: clamp(1.2rem, 0.7vw + 1.2rem, 1.5rem);
--font-size-xl: clamp(2.44rem, 2.38vw + 1.85rem, 3rem);
--color-text: hsl(12, 5%, 4%);
--color-bg: hsl(10, 21%, 95%);
}
html {
font-family: system-ui, sans-serif;
font-size: var(--font-size-base);
color: var(--color-text);
background-color: var(--color-bg);
}
body {
margin: 0;
}
:global(h1) {
font-size: var(--font-size-xl);
}
:global(h2) {
font-size: var(--font-size-lg);
}
:global(code) {
font-family:
Menlo,
Monaco,
Lucida Console,
Liberation Mono,
DejaVu Sans Mono,
Bitstream Vera Sans Mono,
Courier New,
monospace;
}
</style>
</body>
</html>

View file

@ -1,188 +0,0 @@
---
import Layout from '../components/Layout.astro';
export const prerender = true;
---
<Layout title="Welcome to Astro (on Deno).">
<main>
<h1>Welcome to <span class="text-gradient">Astro</span> on Deno</h1>
<p class="instructions">
<strong>Your first mission:</strong> tweak this message to try our hot module reloading. Check
the <code>src/pages</code> directory!
</p>
<ul role="list" class="link-card-grid">
<li class="link-card">
<a href="https://astro.build/integrations/">
<h2>Integrations <span>&rarr;</span></h2>
<p>Add component frameworks, Tailwind, Partytown, and more!</p>
</a>
</li>
<li class="link-card">
<a href="https://astro.build/themes/">
<h2>Themes <span>&rarr;</span></h2>
<p>Explore a galaxy of community-built starters.</p>
</a>
</li>
<li class="link-card">
<a href="https://docs.astro.build/">
<h2>Docs <span>&rarr;</span></h2>
<p>Learn our complete feature set and explore the API.</p>
</a>
</li>
<li class="link-card">
<a href="https://astro.build/chat/">
<h2>Chat <span>&rarr;</span></h2>
<p>
Ask, contribute, and have fun on our community Discord
<svg
class="heart"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
width="16"
height="16"
fill="currentColor"
>
<title>heart</title>
<path
d="M256 448l-30.164-27.211C118.718 322.442 48 258.61 48 179.095 48 114.221 97.918 64 162.4 64c36.399 0 70.717 16.742 93.6 43.947C278.882 80.742 313.199 64 349.6 64 414.082 64 464 114.221 464 179.095c0 79.516-70.719 143.348-177.836 241.694L256 448z"
></path>
</svg>
</p>
</a>
</li>
</ul>
</main>
</Layout>
<style>
:root {
--color-border: hsl(17, 24%, 90%);
--astro-gradient: linear-gradient(0deg, #4f39fa, #da62c4);
--link-gradient: linear-gradient(45deg, #4f39fa, #da62c4 30%, var(--color-border) 60%);
--night-sky-gradient: linear-gradient(
0deg,
#392362 -33%,
#431f69 10%,
#30216b 50%,
#1f1638 100%
);
}
h2 {
margin: 0;
transition: color 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
h2 span {
display: inline-block;
transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}
code {
font-size: 0.875em;
border: 0.1em solid var(--color-border);
border-radius: 4px;
padding: 0.15em 0.25em;
}
main {
margin: auto;
padding: 1em;
max-width: 60ch;
}
.text-gradient {
font-weight: 900;
background-image: var(--astro-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-size: 100% 200%;
background-position-y: 100%;
border-radius: 0.4rem;
animation: pulse 4s ease-in-out infinite;
}
@keyframes pulse {
0%,
100% {
background-position-y: 0%;
}
50% {
background-position-y: 80%;
}
}
.instructions {
line-height: 1.8;
margin-bottom: 2rem;
background-image: var(--night-sky-gradient);
padding: 1.5rem;
border-radius: 0.4rem;
color: var(--color-bg);
}
.link-card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
gap: 1rem;
padding: 0;
}
.link-card {
list-style: none;
display: flex;
padding: 0.15rem;
background-image: var(--link-gradient);
background-size: 400%;
border-radius: 0.5rem;
background-position: 100%;
transition: background-position 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
.link-card > a {
width: 100%;
text-decoration: none;
line-height: 1.4;
padding: 1em 1.3em;
border-radius: 0.35rem;
color: var(--text-color);
background-color: white;
opacity: 0.8;
}
.link-card:is(:hover, :focus-within) {
background-position: 0;
}
.link-card:is(:hover, :focus-within) h2 {
color: #4f39fa;
}
.link-card:is(:hover, :focus-within) h2 span {
transform: translateX(2px);
}
.heart {
display: inline-block;
color: #da62c4;
animation: heartbeat 3s ease-in-out infinite;
}
@keyframes heartbeat {
0%,
50%,
100% {
transform: scale(1);
}
5% {
transform: scale(1.125);
}
10% {
transform: scale(1.05);
}
15% {
transform: scale(1.25);
}
}
</style>

View file

@ -1,3 +0,0 @@
{
"extends": "astro/tsconfigs/base"
}

View file

@ -11,9 +11,9 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/alpinejs": "^0.3.0",
"@astrojs/alpinejs": "^0.3.1",
"@types/alpinejs": "^3.7.2",
"alpinejs": "^3.12.3",
"astro": "^3.1.4"
"astro": "^3.2.4"
}
}

View file

@ -11,9 +11,9 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/lit": "^3.0.0",
"@astrojs/lit": "^3.0.1",
"@webcomponents/template-shadowroot": "^0.2.1",
"astro": "^3.1.4",
"astro": "^3.2.4",
"lit": "^2.8.0"
}
}

View file

@ -11,12 +11,12 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/preact": "^3.0.0",
"@astrojs/react": "^3.0.2",
"@astrojs/solid-js": "^3.0.1",
"@astrojs/svelte": "^4.0.2",
"@astrojs/vue": "^3.0.0",
"astro": "^3.1.4",
"@astrojs/preact": "^3.0.1",
"@astrojs/react": "^3.0.3",
"@astrojs/solid-js": "^3.0.2",
"@astrojs/svelte": "^4.0.3",
"@astrojs/vue": "^3.0.1",
"astro": "^3.2.4",
"preact": "^10.17.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",

View file

@ -11,9 +11,9 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/preact": "^3.0.0",
"@astrojs/preact": "^3.0.1",
"@preact/signals": "^1.2.1",
"astro": "^3.1.4",
"astro": "^3.2.4",
"preact": "^10.17.1"
}
}

View file

@ -11,10 +11,10 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/react": "^3.0.2",
"@astrojs/react": "^3.0.3",
"@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7",
"astro": "^3.1.4",
"astro": "^3.2.4",
"react": "^18.2.0",
"react-dom": "^18.2.0"
}

View file

@ -11,8 +11,8 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/solid-js": "^3.0.1",
"astro": "^3.1.4",
"@astrojs/solid-js": "^3.0.2",
"astro": "^3.2.4",
"solid-js": "^1.7.11"
}
}

View file

@ -11,8 +11,8 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/svelte": "^4.0.2",
"astro": "^3.1.4",
"@astrojs/svelte": "^4.0.3",
"astro": "^3.2.4",
"svelte": "^4.2.0"
}
}

View file

@ -11,8 +11,8 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/vue": "^3.0.0",
"astro": "^3.1.4",
"@astrojs/vue": "^3.0.1",
"astro": "^3.2.4",
"vue": "^3.3.4"
}
}

View file

@ -11,7 +11,7 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/node": "^6.0.1",
"astro": "^3.1.4"
"@astrojs/node": "^6.0.3",
"astro": "^3.2.4"
}
}

View file

@ -10,9 +10,9 @@ export default function createIntegration(): AstroIntegration {
// See the @astrojs/react integration for an example
// https://github.com/withastro/astro/blob/main/packages/integrations/react/src/index.ts
},
'astro:build:setup': ({ config, updateConfig }) => {
// See the @astrojs/netlify integration for an example
// https://github.com/withastro/astro/blob/main/packages/integrations/netlify/src/integration-functions.ts
'astro:build:setup': ({ pages, updateConfig }) => {
// See the @astrojs/lit integration for an example
// https://github.com/withastro/astro/blob/main/packages/integrations/lit/src/index.ts
},
'astro:build:done': ({ dir, routes }) => {
// See the @astrojs/partytown integration for an example

View file

@ -15,7 +15,7 @@
],
"scripts": {},
"devDependencies": {
"astro": "^3.1.4"
"astro": "^3.2.4"
},
"peerDependencies": {
"astro": "^2.0.0-beta.0"

View file

@ -12,8 +12,8 @@
"server": "node dist/server/entry.mjs"
},
"dependencies": {
"@astrojs/node": "^6.0.1",
"astro": "^3.1.4",
"@astrojs/node": "^6.0.3",
"astro": "^3.2.4",
"html-minifier": "^4.0.0"
}
}

View file

@ -11,6 +11,6 @@
"astro": "astro"
},
"dependencies": {
"astro": "^3.1.4"
"astro": "^3.2.4"
}
}

View file

@ -11,6 +11,6 @@
"astro": "astro"
},
"dependencies": {
"astro": "^3.1.4"
"astro": "^3.2.4"
}
}

View file

@ -11,6 +11,6 @@
"astro": "astro"
},
"dependencies": {
"astro": "^3.1.4"
"astro": "^3.2.4"
}
}

View file

@ -1,21 +0,0 @@
# build output
dist/
# generated types
.astro/
# dependencies
node_modules/
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store

View file

@ -1,4 +0,0 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}

View file

@ -1,11 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}

View file

@ -1,46 +0,0 @@
# Astro Starter Kit: Social Feed
```
npm create astro@latest -- --template social-feed
```
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/social-feed)
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/s/github/withastro/astro/tree/latest/examples/social-feed)
> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
## 🚀 Project Structure
Inside of your Astro project, you'll see the following folders and files:
```
/
├── public/
├── src/
│ └── pages/
│ └── index.astro
└── package.json
```
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
Any static assets, like images, can be placed in the `public/` directory.
## 🧞 Commands
All commands are run from the root of the project, from a terminal:
| Command | Action |
| :--------------------- | :----------------------------------------------- |
| `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:3000` |
| `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro --help` | Get help using the Astro CLI |
## 👀 Want to learn more?
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).

View file

@ -1,13 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 36 36">
<path fill="#000" d="M22.25 4h-8.5a1 1 0 0 0-.96.73l-5.54 19.4a.5.5 0 0 0 .62.62l5.05-1.44a2 2 0 0 0 1.38-1.4l3.22-11.66a.5.5 0 0 1 .96 0l3.22 11.67a2 2 0 0 0 1.38 1.39l5.05 1.44a.5.5 0 0 0 .62-.62l-5.54-19.4a1 1 0 0 0-.96-.73Z"/>
<path fill="url(#gradient)" d="M18 28a7.63 7.63 0 0 1-5-2c-1.4 2.1-.35 4.35.6 5.55.14.17.41.07.47-.15.44-1.8 2.93-1.22 2.93.6 0 2.28.87 3.4 1.72 3.81.34.16.59-.2.49-.56-.31-1.05-.29-2.46 1.29-3.25 3-1.5 3.17-4.83 2.5-6-.67.67-2.6 2-5 2Z"/>
<defs>
<linearGradient id="gradient" x1="16" x2="16" y1="32" y2="24" gradientUnits="userSpaceOnUse">
<stop stop-color="#000"/>
<stop offset="1" stop-color="#000" stop-opacity="0"/>
</linearGradient>
</defs>
<style>
@media (prefers-color-scheme:dark){:root{filter:invert(100%)}}
</style>
</svg>

Before

Width:  |  Height:  |  Size: 873 B

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View file

@ -1,58 +0,0 @@
---
import ArticleHeader from './ArticleHeader.astro';
import type { Article } from '../content/config.js';
export interface Props {
article: Article;
}
const { article } = Astro.props;
const { Content } = await article.render();
---
<article>
<ArticleHeader {article} class="header" />
<div class="e-content">
<Content />
</div>
</article>
<style>
article {
display: flex;
flex-direction: column;
gap: var(--theme-space-lg);
padding-block: var(--theme-space-md);
width: 100%;
max-width: var(--theme-size-content-3);
margin-inline: auto;
}
.e-content {
max-width: var(--theme-size-content-3);
margin-inline: auto;
}
.e-content > :global(* + *) {
margin-block-start: 1em;
}
.e-content > :global(p:first-child::first-letter) {
float: left;
font-size: 3.5rem;
padding-inline-end: 0.5rem;
padding-block-start: 0.35rem;
font-weight: bold;
}
.e-content :global(img, video, figure) {
margin-inline: auto;
}
@media (min-width: 50em) {
.e-content > :global(* + *) {
margin-block-start: 1.5em;
}
}
</style>

View file

@ -1,132 +0,0 @@
---
import type { HTMLAttributes } from 'astro/types';
import { Image } from 'astro:assets';
import getReadingTime from 'reading-time';
import FormattedDate from './FormattedDate.astro';
import Icon from './Icon.astro';
import TagList from './TagList.astro';
import settings from '../settings.js';
import type { Article } from '../content/config.js';
interface Props extends HTMLAttributes<'header'> {
article: Article;
}
const { article, ...attrs } = Astro.props;
const { text: readingTime } = await getReadingTime(article.body);
---
<header {...attrs}>
<div class="cover">
{
article.data.cover && (
<Image src={article.data.cover.src} alt={article.data.cover.alt} class="u-photo" />
)
}
<div class="p-author h-card">
<Image src={settings.avatar.src} alt={settings.avatar.alt} width={80} class="u-photo" />
<p class="p-name">{settings.name}</p>
<p class="p-nickname">{settings.username}</p>
</div>
</div>
<div class="meta">
<FormattedDate date={article.data.pubDate} class="dt-published" />
<span>•</span>
<p>
<Icon icon="clock" size="1rem" />
<span>{readingTime}</span>
</p>
</div>
<h1 class="p-name">article.data.title}</h1>
{article.data.categories?.length > 0 && <TagList tags={article.data.categories} />}
</header>
<style>
header {
display: flex;
flex-direction: column;
gap: var(--theme-space-sm);
}
.cover {
display: grid;
width: 100%;
min-height: 150px;
background: var(--theme-gradient-main);
border-radius: var(--theme-radius-xl);
margin-block-end: var(--theme-space-md);
}
.cover > img {
grid-column: 1;
grid-row: 1;
width: 100%;
min-height: inherit;
height: 100%;
aspect-ratio: 2.777;
object-fit: cover;
border-radius: inherit;
}
.p-author {
grid-column: 1;
grid-row: 1;
display: flex;
align-items: center;
gap: var(--theme-space-2xs);
width: fit-content;
height: fit-content;
align-self: end;
justify-self: center;
transform: translateY(50%);
box-shadow: var(--theme-shadow-md);
background-color: var(--theme-accent-light);
padding: var(--theme-space-3xs) var(--theme-space-md);
border-radius: var(--theme-radius-xl);
border: 3px solid var(--theme-accent-dark);
}
@media (min-width: 640px) {
.cover {
margin-block-end: var(--theme-space-sm);
}
.p-author {
justify-self: end;
margin-inline-end: var(--theme-space-xl);
}
}
.p-author img {
width: var(--theme-space-lg);
height: var(--theme-space-lg);
}
.p-author .p-name {
font-family: var(--font-brand);
font-weight: bold;
}
.p-author .p-nickname {
color: var(--theme-gray-300);
font-size: var(--theme-text-sm);
font-weight: 600;
}
.meta {
display: flex;
align-items: center;
gap: 1rem;
font-size: var(--theme-text-sm);
color: var(--theme-gray-200);
}
.meta svg {
margin-block-end: var(--theme-space-3xs);
}
</style>

View file

@ -1,132 +0,0 @@
---
import type { HTMLAttributes } from 'astro/types';
import { Image } from 'astro:assets';
import FormattedDate from './FormattedDate.astro';
import Icon from './Icon.astro';
import TagList from './TagList.astro';
import settings from '../settings.js';
import { isArticle, type Post } from '../content/config.js';
export interface Props extends HTMLAttributes<'article'> {
post: Post;
}
const { post, class: className, ...attrs } = Astro.props;
const { pubDate, categories = [] } = post.data;
const cover = 'cover' in post.data && post.data.cover;
const title = 'title' in post.data && post.data.title;
const postUrl = `/post/${post.slug}/`;
---
<article class:list={['h-entry', className]} transition:name={`card-${post.slug}`} {...attrs}>
<header class="p-author h-card">
<Image {...settings.avatar} width={120} class="u-photo" />
<strong class="p-name">{settings.name}</strong>
<div class="p-nickname">
{settings.username}
<FormattedDate date={pubDate} class="dt-published" />
</div>
{categories.length > 0 && <TagList tags={categories} class="tags" />}
</header>
{cover && <Image {...cover} width={1060} class="u-photo" />}
{title && <h3 class="p-name">{title}</h3>}
{
isArticle(post) ? (
<p class="p-summary">{post.data.description}</p>
) : (
post.render().then(({ Content }) => (
<div class="e-content">
<Content />
</div>
))
)
}
<footer>
{
Astro.url.pathname !== postUrl && (
<a href={`/post/${post.slug}/`} class="u-url">
Full {post.collection === 'articles' ? 'article' : 'note'}
</a>
)
}
<a
href={`javascript: navigator.clipboard.writeText(window.location.href + "post/${post.slug}/");`}
>
<Icon icon="share" size="1.5rem" />
<span class="sr-only">Share this post</span>
</a>
</footer>
</article>
<style>
article {
max-width: var(--theme-size-content-2);
padding: var(--theme-space-sm) var(--theme-space-sm) var(--theme-space-md);
background-color: var(--theme-bg-accent);
border-radius: var(--theme-radius-xl);
box-shadow: var(--theme-shadow-md);
}
article > :global(* + *) {
margin-block-start: var(--theme-space-sm);
}
header {
display: grid;
grid-template-columns: auto auto 1fr;
grid-template-areas: 'avatar name' 'avatar nickname' 'tags tags';
align-items: center;
row-gap: var(--theme-space-3xs);
column-gap: var(--theme-space-sm);
}
.h-card .u-photo {
grid-area: avatar;
width: var(--theme-space-xl);
height: var(--theme-space-xl);
border-radius: var(--theme-radius-full);
background-color: var(--theme-shade-subtle);
}
.p-name {
grid-area: name;
font-family: var(--font-brand);
font-weight: bold;
}
.p-nickname {
grid-area: nickname;
font-size: var(--theme-text-sm);
color: var(--theme-gray-300);
}
.tags {
grid-area: tags;
margin-block-start: var(--theme-space-2xs);
}
article > .u-photo {
aspect-ratio: 21/9;
object-fit: cover;
border-radius: var(--theme-radius-lg);
}
.e-content > :global(* + *) {
margin-block-start: 1em;
}
.e-content :global(:where(img, picture, video)) {
width: 100%;
}
footer {
display: flex;
align-items: center;
justify-content: space-between;
}
footer > *:only-child {
margin-inline-start: auto;
}
@media (min-width: 50em) {
header {
grid-template-areas: 'avatar name nickname' 'avatar tags tags';
}
.tags {
margin-block-start: 0;
}
}
</style>

View file

@ -1,30 +0,0 @@
---
import settings from '../settings';
import Icon from './Icon.astro';
---
<footer>
<p>
{settings.name} © {new Date().getFullYear()}
</p>
<p>
Designed & Developed with ♥
</p>
</footer>
<style>
footer {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
margin-top: auto;
border-top: 3px solid var(--theme-shade-subtle);
border-radius: var(--theme-radius-xl);
padding: var(--theme-space-md);
row-gap: var(--theme-space-sm);
column-gap: var(--theme-space-lg);
color: var(--theme-gray-200);
font-size: var(--theme-text-sm);
}
</style>

View file

@ -1,19 +0,0 @@
---
import type { HTMLAttributes } from 'astro/types';
interface Props extends HTMLAttributes<'time'> {
date: Date;
}
const { date } = Astro.props;
---
<time datetime={date.toISOString()}>
{
date.toLocaleDateString('en-us', {
year: 'numeric',
month: 'short',
day: 'numeric',
})
}
</time>

View file

@ -1,33 +0,0 @@
---
import type { HTMLAttributes } from 'astro/types';
import settings from '../settings';
import ThemeToggle from './ThemeToggle.astro';
export interface Props extends HTMLAttributes<'header'> {}
---
<header {...Astro.props}>
<a class="site-name" href="/">{settings.username}</a>
<ThemeToggle />
</header>
<style>
header {
display: flex;
justify-content: space-between;
align-items: center;
padding-block: var(--theme-space-md);
}
.site-name {
font-size: var(--theme-text-lg);
font-weight: 700;
font-family: var(--theme-font-brand);
text-decoration: none;
color: var(--theme-accent-dark);
}
.site-name:hover {
text-decoration: 1px solid underline var(--theme-accent-dark);
}
</style>

View file

@ -1,32 +0,0 @@
---
import { iconPaths } from './IconPaths';
export interface Props {
icon: keyof typeof iconPaths;
color?: string;
size?: string;
}
const { icon, color, size } = Astro.props;
const iconPath = iconPaths[icon];
---
<svg
xmlns="http://www.w3.org/2000/svg"
width="40"
height="40"
viewBox="0 0 256 256"
aria-hidden="true"
stroke="currentcolor"
fill="currentcolor"
set:html={iconPath}
/>
<style define:vars={{ color, size }}>
svg {
color: var(--color, inherit);
vertical-align: middle;
width: var(--size, 1em);
height: var(--size, 1em);
}
</style>

View file

@ -1,36 +0,0 @@
/**
* Want to add more icons?
* 1. Find the icon you want as an SVG.
* 2. Scale it to 256×256px.
* 3. Paste the SVG code in your editor.
* 4. Remove the `<svg>` wrapper so you only have elements like `<path>`, `<circle>`, `<rect>` etc.
* 5. Remove any `stroke="{color}"` attributes
* 6. Replace any `fill="{color}"` attributes with `stroke="none"`
* (or add `stroke="none"` on shapes with no `fill` or `stroke` specified).
*/
export const iconPaths = {
'arrow-right': `<path d="m117.5 69.6 7-7c2.9-3 7.6-3 10.6 0l60.7 60.7c3 3 3 7.7 0 10.6L135 194.6c-3 3-7.7 3-10.6 0l-7-6.9c-3-3-2.9-7.8.2-10.7l37.6-35.9H65.5a7.5 7.5 0 0 1-7.5-7.5v-10c0-4.1 3.4-7.5 7.5-7.5h89.8l-37.6-35.8a7.4 7.4 0 0 1-.2-10.7Z"/>`,
'arrow-left': `<path d="m138.5 187-7 7c-2.9 3-7.6 3-10.6 0l-60.7-60.7c-3-3-3-7.7 0-10.6L121 62c3-3 7.7-3 10.6 0l7 7c3 2.9 2.9 7.7-.2 10.6l-37.6 35.9h89.8c4.1 0 7.5 3.3 7.5 7.5v10c0 4.2-3.4 7.5-7.5 7.5h-89.8l37.6 35.9a7.4 7.4 0 0 1 .2 10.7Z"/>`,
'rss-alt': `<path d="M71.8 153.01a28.65 28.65 0 1 0 40.49 40.5 28.65 28.65 0 0 0 0-40.5 29.41 29.41 0 0 0-40.49 0Zm27.02 27.03a9.55 9.55 0 0 1-13.56 0 9.55 9.55 0 0 1 0-13.56 9.55 9.55 0 0 1 13.56 0 9.54 9.54 0 0 1 0 13.56Zm-6.78-73.62a9.55 9.55 0 1 0 0 19.1 47.74 47.74 0 0 1 47.75 47.74 9.55 9.55 0 1 0 19.1 0 66.84 66.84 0 0 0-66.85-66.84Zm0-38.2a9.55 9.55 0 1 0 0 19.1 85.94 85.94 0 0 1 85.94 85.94 9.55 9.55 0 1 0 19.1 0A105.04 105.04 0 0 0 92.04 68.22Z"/>`,
'link-h': `<path d="M96.9 128.25a7.78 7.78 0 0 0 7.77 7.77h46.66a7.78 7.78 0 1 0 0-15.55h-46.66a7.77 7.77 0 0 0-7.78 7.78Zm15.55 23.32H89.12a23.33 23.33 0 0 1 0-46.65h23.33a7.78 7.78 0 1 0 0-15.55H89.12a38.88 38.88 0 0 0 0 77.76h23.33a7.78 7.78 0 1 0 0-15.56Zm54.43-62.2h-23.33a7.78 7.78 0 1 0 0 15.55h23.33a23.33 23.33 0 0 1 0 46.65h-23.33a7.77 7.77 0 1 0 0 15.56h23.33a38.88 38.88 0 1 0 0-77.76Z"/>`,
'location-point': `<path d="M193.8 110.2a66.1 66.1 0 1 0-112.5 53.1l41.3 41.3a7.8 7.8 0 0 0 11 0l41-41.3a65.8 65.8 0 0 0 19.2-53.1Zm-30 42.1L128 188.1l-35.8-35.8a50.5 50.5 0 0 1-7.5-61.9A51 51 0 0 1 128 65.8a50.3 50.3 0 0 1 50.3 45.8 50.5 50.5 0 0 1-14.5 40.7ZM128 82a35 35 0 1 0 0 70 35 35 0 0 0 0-70Zm0 54.4a19.4 19.4 0 1 1 0-38.9 19.4 19.4 0 0 1 0 38.9Z"/>`,
clock: `<path d="M158 118H138V78C138 75.3478 136.946 72.8043 135.071 70.929C133.196 69.0536 130.652 68 128 68C125.348 68 122.804 69.0536 120.929 70.929C119.054 72.8043 118 75.3478 118 78V128C118 130.652 119.054 133.196 120.929 135.071C122.804 136.946 125.348 138 128 138H158C160.653 138 163.195 136.946 165.07 135.071C166.947 133.196 168 130.652 168 128C168 125.348 166.947 122.804 165.07 120.929C163.195 119.054 160.653 118 158 118ZM128 28C108.222 28 88.8878 33.865 72.443 44.853C55.9981 55.8411 43.1808 71.459 35.612 89.7317C28.0434 108.004 26.063 128.111 29.9214 147.509C33.78 166.907 43.3042 184.725 57.2893 198.71C71.2746 212.696 89.093 222.221 108.491 226.078C127.889 229.938 147.996 227.957 166.269 220.387C184.541 212.819 200.158 200.002 211.147 183.557C222.134 167.112 228 147.778 228 128C228 114.868 225.413 101.864 220.387 89.7317C215.363 77.599 207.997 66.5752 198.71 57.2893C189.426 48.0035 178.402 40.6374 166.269 35.612C154.136 30.5866 141.132 28 128 28ZM128 208C112.177 208 96.7104 203.309 83.5544 194.517C70.3984 185.726 60.1446 173.232 54.0896 158.615C48.0347 143.997 46.4504 127.911 49.5371 112.393C52.624 96.8742 60.2432 82.6197 71.4315 71.4315C82.6197 60.2432 96.8742 52.624 112.393 49.5371C127.911 46.4504 143.997 48.0346 158.615 54.0896C173.232 60.1446 185.726 70.3984 194.517 83.5544C203.309 96.7102 208 112.177 208 128C208 149.217 199.571 169.566 184.568 184.568C169.566 199.571 149.217 208 128 208Z" fill="currentColor"/>`,
share: `<path d="M192 149.333C185.698 149.375 179.483 150.812 173.803 153.541C168.123 156.271 163.117 160.225 159.147 165.12L104.747 140.053C107.305 132.221 107.305 123.778 104.747 115.947L159.147 90.8799C165.564 98.6235 174.51 103.851 184.406 105.641C194.304 107.43 204.514 105.666 213.236 100.66C221.96 95.654 228.634 87.7276 232.08 78.2799C235.528 68.832 235.526 58.47 232.078 49.0229C228.629 39.5756 221.953 31.6505 213.23 26.6459C204.507 21.6415 194.296 19.8793 184.399 21.6706C174.504 23.4618 165.557 28.6913 159.141 36.4361C152.725 44.1809 149.252 53.9431 149.333 63.9999C149.365 66.541 149.615 69.0747 150.08 71.5732L93.76 97.4932C87.7556 91.622 80.1519 87.6534 71.9019 86.0844C63.6519 84.5155 55.1224 85.4161 47.3819 88.6732C39.6414 91.9305 33.0343 97.3995 28.3883 104.395C23.7423 111.391 21.264 119.602 21.264 128C21.264 136.398 23.7423 144.609 28.3883 151.604C33.0343 158.6 39.6414 164.069 47.3819 167.327C55.1224 170.583 63.6519 171.485 71.9019 169.916C80.1519 168.347 87.7556 164.378 93.76 158.507L150.08 184.427C149.615 186.925 149.365 189.459 149.333 192C149.333 200.438 151.836 208.688 156.524 215.704C161.212 222.721 167.876 228.19 175.673 231.419C183.469 234.648 192.047 235.493 200.324 233.846C208.601 232.2 216.203 228.136 222.17 222.17C228.137 216.203 232.201 208.6 233.846 200.324C235.493 192.047 234.649 183.469 231.419 175.672C228.19 167.876 222.721 161.212 215.705 156.524C208.688 151.836 200.438 149.333 192 149.333ZM192 42.6665C196.22 42.6665 200.344 43.9177 203.852 46.2618C207.36 48.606 210.095 51.9378 211.71 55.836C213.324 59.7341 213.746 64.0235 212.924 68.1618C212.1 72.3 210.068 76.1013 207.085 79.0849C204.101 82.0683 200.3 84.1001 196.162 84.9233C192.024 85.7464 187.734 85.324 183.836 83.7093C179.938 82.0947 176.606 79.3603 174.262 75.852C171.918 72.3437 170.667 68.2193 170.667 63.9999C170.667 58.3419 172.914 52.9157 176.915 48.9149C180.916 44.9142 186.342 42.6665 192 42.6665ZM64 149.333C59.7806 149.333 55.6561 148.082 52.1479 145.738C48.6396 143.394 45.9052 140.062 44.2906 136.164C42.6759 132.266 42.2535 127.976 43.0766 123.838C43.8998 119.699 45.9316 115.899 48.915 112.915C51.8986 109.932 55.6998 107.9 59.8381 107.076C63.9764 106.253 68.2657 106.676 72.1639 108.29C76.0621 109.905 79.3939 112.64 81.7381 116.148C84.0822 119.656 85.3334 123.78 85.3334 128C85.3334 133.658 83.0857 139.084 79.0849 143.085C75.0842 147.086 69.658 149.333 64 149.333ZM192 213.333C187.78 213.333 183.657 212.082 180.148 209.738C176.64 207.394 173.905 204.062 172.29 200.164C170.676 196.266 170.254 191.977 171.076 187.838C171.9 183.699 173.932 179.899 176.915 176.915C179.899 173.932 183.7 171.9 187.838 171.076C191.977 170.254 196.266 170.676 200.164 172.29C204.062 173.905 207.394 176.64 209.738 180.148C212.082 183.655 213.333 187.78 213.333 192C213.333 197.658 211.086 203.084 207.085 207.085C203.084 211.086 197.658 213.333 192 213.333Z" fill="currentColor"/>`,
user: `<path d="M156.9 133.5a46.7 46.7 0 1 0-57.7 0 77.8 77.8 0 0 0-48.4 63.6 7.8 7.8 0 0 0 15.5 1.7 62.2 62.2 0 0 1 123.7 0 7.8 7.8 0 0 0 7.8 7h.8a7.8 7.8 0 0 0 6.9-8.6 77.8 77.8 0 0 0-48.6-63.7ZM128 128a31.1 31.1 0 1 1 0-62.2 31.1 31.1 0 0 1 0 62.2Z"/>`,
heart: `<path d="M187.84 74.61A46.17 46.17 0 0 0 128 70.16a46.17 46.17 0 0 0-62.29 6.86 45.56 45.56 0 0 0 2.45 62.27l54.63 54.32a7.32 7.32 0 0 0 8.03 1.6c.9-.37 1.7-.92 2.39-1.6l54.63-54.32a45.68 45.68 0 0 0 13.48-32.34 45.48 45.48 0 0 0-13.48-32.34Zm-10.34 54.4L128 178.15l-49.5-49.14a31.15 31.15 0 0 1-6.8-33.89 31.24 31.24 0 0 1 11.47-14 31.51 31.51 0 0 1 17.33-5.34c8.26.02 16.17 3.3 22 9.11a7.34 7.34 0 0 0 10.41 0 31.42 31.42 0 0 1 42.74 1.6 31.05 31.05 0 0 1 1.26 42.52h.59Z"/>`,
'moon-stars': `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="20" d="M216 112V64m24 24h-48m-24-64v32m16-16h-32m65 113A92 92 0 0 1 103 39h0a92 92 0 1 0 114 114Z"/>`,
sun: `<circle cx="128" cy="128" r="60" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="20"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="20" d="M128 36V16M63 63 49 49m-13 79H16m47 65-14 14m79 13v20m65-47 14 14m13-79h20m-47-65 14-14"/>`,
twitter: `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M128 88c0-22 18.5-40.3 40.5-40a40 40 0 0 1 36.2 24H240l-32.3 32.3A127.9 127.9 0 0 1 80 224c-32 0-40-12-40-12s32-12 48-36c0 0-64-32-48-120 0 0 40 40 88 48Z"/>`,
codepen: `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="m232 101-104 59-104-59 100.1-56.8a8.3 8.3 0 0 1 7.8 0Z"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="m232 165-100.1 56.8a8.3 8.3 0 0 1-7.8 0L24 165l104-59Zm0-64v64M24 101v64m104-5v62.8m0-179.6V106"/>`,
github: `<g stroke-linecap="round" stroke-linejoin="round"><path fill="none" stroke-width="14.7" d="M55.7 167.2c13.9 1 21.3 13.1 22.2 14.6 4.2 7.2 10.4 9.6 18.3 7.1l1.1-3.4a60.3 60.3 0 0 1-25.8-11.9c-12-10.1-18-25.6-18-46.3"/><path fill="none" stroke-width="16" d="M61.4 205.1a24.5 24.5 0 0 1-3-6.1c-3.2-7.9-7.1-10.6-7.8-11.1l-1-.6c-2.4-1.6-9.5-6.5-7.2-13.9 1.4-4.5 6-7.2 12.3-7.2h.8c4 .3 7.6 1.5 10.7 3.2-9.1-10.1-13.6-24.3-13.6-42.3 0-11.3 3.5-21.7 10.1-30.4A46.7 46.7 0 0 1 65 67.3a8.3 8.3 0 0 1 5-4.7c2.8-.9 13.3-2.7 33.2 9.9a105 105 0 0 1 50.5 0c19.9-12.6 30.4-10.8 33.2-9.9 2.3.7 4.1 2.4 5 4.7 5 12.7 4 23.2 2.6 29.4 6.7 8.7 10 18.9 10 30.4 0 42.6-25.8 54.7-43.6 58.7 1.4 4.1 2.2 8.8 2.2 13.7l-.1 23.4v2.3"/><path fill="none" stroke-width="16" d="M160.9 185.7c1.4 4.1 2.2 8.8 2.2 13.7l-.1 23.4v2.3A98.6 98.6 0 1 0 61.4 205c-1.4-2.1-11.3-17.5-11.8-17.8-2.4-1.6-9.5-6.5-7.2-13.9 1.4-4.5 6-7.2 12.3-7.2h.8c4 .3 7.6 1.5 10.7 3.2-9.1-10.1-13.6-24.3-13.6-42.3 0-11.3 3.5-21.7 10.1-30.4A46.4 46.4 0 0 1 65 67.3a8.3 8.3 0 0 1 5-4.7c2.8-.9 13.3-2.7 33.2 9.9a105 105 0 0 1 50.5 0c19.9-12.6 30.4-10.8 33.2-9.9 2.3.7 4.1 2.4 5 4.7 5 12.7 4 23.2 2.6 29.4 6.7 8.7 10 18.9 10 30.4.1 42.6-25.8 54.7-43.6 58.6z"/><path fill="none" stroke-width="18.7" d="m170.1 203.3 17.3-12 17.2-18.7 9.5-26.6v-27.9l-9.5-27.5" /><path fill="none" stroke-width="22.7" d="m92.1 57.3 23.3-4.6 18.7-1.4 29.3 5.4m-110 32.6-8 16-4 21.4.6 20.3 3.4 13" /><path fill="none" stroke-width="13.3" d="M28.8 133a100 100 0 0 0 66.9 94.4v-8.7c-22.4 1.8-33-11.5-35.6-19.8-3.4-8.6-7.8-11.4-8.5-11.8"/></g>`,
twitch: `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M165 200h-42a8 8 0 0 0-5 2l-46 38v-40H48a8 8 0 0 1-8-8V48a8 8 0 0 1 8-8h160a8 8 0 0 1 8 8v108a8 8 0 0 1-3 6l-43 36a8 8 0 0 1-5 2Zm3-112v48m-48-48v48"/>`,
youtube: `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="m160 128-48-32v64l48-32z"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M24 128c0 30 3 47 5 56a16 16 0 0 0 10 11c34 13 89 13 89 13s56 0 89-13a16 16 0 0 0 10-11c2-9 5-26 5-56s-3-47-5-56a16 16 0 0 0-10-11c-33-13-89-13-89-13s-55 0-89 13a16 16 0 0 0-10 11c-2 9-5 26-5 56Z"/>`,
dribbble: `<circle cx="128" cy="128" r="96" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M71 205a160 160 0 0 1 137-77l16 1m-36-76a160 160 0 0 1-124 59 165 165 0 0 1-30-3"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M86 42a161 161 0 0 1 74 177"/>`,
discord: `<circle stroke="none" cx="96" cy="144" r="12"/><circle stroke="none" cx="160" cy="144" r="12"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M74 80a175 175 0 0 1 54-8 175 175 0 0 1 54 8m0 96a175 175 0 0 1-54 8 175 175 0 0 1-54-8"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="m155 182 12 24a8 8 0 0 0 9 4c25-6 46-16 61-30a8 8 0 0 0 3-8L206 59a8 8 0 0 0-5-5 176 176 0 0 0-30-9 8 8 0 0 0-9 5l-8 24m-53 108-12 24a8 8 0 0 1-9 4c-25-6-46-16-61-30a8 8 0 0 1-3-8L50 59a8 8 0 0 1 5-5 176 176 0 0 1 30-9 8 8 0 0 1 9 5l8 24"/>`,
linkedin: `<rect width="184" height="184" x="36" y="36" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" rx="8"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M120 112v64m-32-64v64m32-36a28 28 0 0 1 56 0v36"/><circle stroke="none" cx="88" cy="80" r="12"/>`,
instagram: `<circle cx="128" cy="128" r="40" fill="none" stroke-miterlimit="10" stroke-width="16"/><rect width="184" height="184" x="36" y="36" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" rx="48"/><circle cx="180" cy="76" r="12" stroke="none" />`,
tiktok: `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M168 106a96 96 0 0 0 56 18V84a56 56 0 0 1-56-56h-40v128a28 28 0 1 1-40-25V89a68 68 0 1 0 80 67Z"/>`,
devto: `<path fill-rule="evenodd" d="M37 33c-2.2.5-4 2-4.7 4.2l-.3.8v181.8l.3.8c.7 2 2 3.3 4 4l.8.3H219l.7-.3c2-.7 3.3-2 4-4l.3-.8V38l-.3-.8c-.7-2-2-3.3-4-4l-.8-.3H37Zm43.6 58.3A20.7 20.7 0 0 1 98 109.6c.3 1.9.3 36.7 0 38.6a20.5 20.5 0 0 1-16 17.9c-2.6.5-1.8.5-14.9.6h-12V91h12.2c11 0 12.4 0 13.2.2Zm63.6 6.5v6.8H120v17.6h14.8v13.4H120v17.5h24.2v13.6h-30l-.8-.3a9.3 9.3 0 0 1-6.7-6.7l-.2-.9v-60l.2-.8c1-3.4 3.6-6 7-6.7.8-.2 1.8-.2 15.7-.2h14.8v6.7Zm27 8.6a268210 268210 0 0 1 9.5 36.4 5274.6 5274.6 0 0 0 13.5-51.6H209l-8.8 33a527.2 527.2 0 0 1-9.3 34.2 15 15 0 0 1-6.5 7.5c-1.3.6-2 .7-3.7.7-1.2 0-1.6 0-2.2-.2-3.2-.8-5.8-3.3-8-7.7l-.7-1.5-8.7-32.9-8.7-33c0-.2.3-.2 7.4-.2h7.4l4 15.3ZM68.7 128.8v24.3h9.5l.8-.3a9 9 0 0 0 4.7-3.4 7 7 0 0 0 1-2.4v-35.7l-.1-.8c-.6-2.3-1.9-3.8-4.3-5-1.8-.9-1.9-.9-7-1h-4.6v24.3Z" clip-rule="evenodd"/>`,
mastodon: `<path d="M219.3 74.8a49.7 49.7 0 0 0-43-40.4c-3.7-.6-17.6-2.5-49.8-2.5h-.3c-32.2 0-39.1 2-42.8 2.5-21.1 3-40.5 17.8-45.2 39a132.2 132.2 0 0 0-2 32.4c.6 15.1.7 30.3 2 45.3 1 10 2.7 20 5 29.8 4.5 18 22.6 33.1 40.3 39.2a108.8 108.8 0 0 0 65.1 1.4c4.7-1.5 10.3-3.2 14.4-6a.5.5 0 0 0 .2-.4v-14.7a.4.4 0 0 0-.4-.4h-.2a158 158 0 0 1-38.1 4.4c-22.1 0-28-10.3-29.8-14.7a45.1 45.1 0 0 1-2.4-12 .4.4 0 0 1 .4 0c12.3 3 24.9 4.4 37.5 4.4h9.1c12.7-.4 26.1-1 38.6-3.5.3 0 .6 0 .9-.2 19.7-3.7 38.5-15.5 40.4-45.3l.3-13.5c0-4 1.3-29.3-.2-44.8Zm-30.4 74.3h-20.7V99c0-10.6-4.5-16-13.6-16-10 0-15 6.4-15 19v27.5h-20.5V102c0-12.6-5-19-15-19-9 0-13.5 5.4-13.5 16v50H69.9V97.4A37 37 0 0 1 78 72c5.6-6.2 13-9.4 22.1-9.4 10.7 0 18.7 4 24 12.1l5.2 8.6 5.2-8.6c5.3-8 13.3-12 24-12 9 0 16.5 3.1 22.1 9.3a36.9 36.9 0 0 1 8.2 25.3V149Z"/>`,
};

View file

@ -1,128 +0,0 @@
---
import type { Page as Props } from 'astro';
import Icon from './Icon.astro';
const { currentPage, lastPage, url } = Astro.props;
const firstPage = 1;
interface Item {
page: number;
url: string;
current: boolean;
}
const makeItem = (page: number): Item => ({
page,
url: page === 1 ? '/' : `/${page}`,
current: page === currentPage,
});
const items: (Item | null)[] = [];
/** The number of pages to show before/after the current page. */
const beforeAfter = 1;
// Get range of pages around current page.
const min = Math.max(
Math.min(currentPage - beforeAfter, lastPage - 2 * beforeAfter - 1),
firstPage
);
const max = Math.min(Math.max(min + 2 * beforeAfter, firstPage + 2 * beforeAfter + 1), lastPage);
// Always include first page.
if (min > firstPage) items.push(makeItem(firstPage));
// Show “…” if the range starts at page 4 or higher.
if (min > firstPage + 2) items.push(null);
// Show page 2 if the range starts at page 3.
if (min === firstPage + 2) items.push(makeItem(firstPage + 1));
// Show an item for pages in range around current page.
for (let i = min; i <= max; i++) items.push(makeItem(i));
// Show “…” if the range ends more than 2 pages before the last page.
if (max < lastPage - 2) items.push(null);
// Show the penultimate page if the range ends 2 pages before the last page.
if (max === lastPage - 2) items.push(makeItem(lastPage - 1));
// Always include last page.
if (max < lastPage) items.push(makeItem(lastPage));
---
{
lastPage > 1 && (
<nav>
<ul>
<li class="pagination-arrow">
{url.prev === undefined ? (
<span>
<Icon icon="arrow-left" />
<span class="sr-only">Previous</span>
</span>
) : (
<a href={url.prev} rel="prev">
<Icon icon="arrow-left" />
<span class="sr-only">Previous</span>
</a>
)}
</li>
{items.map((item) => (
<li class="pagination-item">
{item ? (
<a href={item.url} aria-current={item.current}>
{item.page}
</a>
) : (
<span>…</span>
)}
</li>
))}
<li class="pagination-arrow">
{url.next === undefined ? (
<span>
<span class="sr-only">Next</span>
<Icon icon="arrow-right" />
</span>
) : (
<a href={url.next} rel="next">
<span class="sr-only">Next</span>
<Icon icon="arrow-right" />
</a>
)}
</li>
</ul>
</nav>
)
}
<style>
ul {
display: flex;
justify-content: center;
list-style: none;
gap: var(--theme-space-2xs);
padding: 0;
}
a {
text-decoration: none;
color: var(--theme-text);
}
.pagination-item > * {
border: 1.5px solid var(--theme-accent-dark);
border-radius: var(--theme-radius-base);
padding: 0.375rem 0.75rem;
background-color: var(--theme-bg-accent);
font-size: var(--theme-text-sm);
font-weight: 700;
box-shadow: var(--theme-shadow-sm);
}
.pagination-item > [aria-current='true'] {
background-color: var(--theme-accent-dark);
color: var(--theme-text-invert);
}
.pagination-arrow > * {
color: var(--theme-accent-dark);
opacity: 0.35;
font-size: var(--theme-text-xl);
display: flex;
}
.pagination-arrow > a {
opacity: 1;
}
</style>

View file

@ -1,32 +0,0 @@
---
import type { HTMLAttributes } from 'astro/types';
export interface Props extends HTMLAttributes<'div'> {
reverse?: boolean;
}
const { reverse = false, class: className, ...attrs } = Astro.props;
---
<div class:list={[className, { reverse }]} {...attrs}>
<slot />
</div>
<style>
div {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--theme-space-lg);
margin: 0 auto;
width: 100%;
max-width: var(--theme-size-content-3);
}
@media (min-width: 50em) {
div {
flex-direction: row;
align-items: initial;
}
}
</style>

View file

@ -1,41 +0,0 @@
---
import type { HTMLAttributes } from 'astro/types';
interface Props extends HTMLAttributes<'ul'> {
tags: string[];
}
const { tags, ...attrs } = Astro.props;
---
<ul {...attrs}>
{
tags.map((tag) => (
<li>
<a href={`/category/${tag}/`} rel="category tag" class="p-category">
{tag}
</a>
</li>
))
}
</ul>
<style>
ul {
list-style: none;
padding: 0;
display: flex;
gap: var(--theme-space-3xs);
}
.p-category {
padding: var(--theme-space-3xs) var(--theme-space-2xs);
border-radius: var(--theme-radius-full);
background-color: var(--theme-accent-dark);
color: var(--theme-text-invert);
font-size: var(--theme-text-sm);
font-weight: 500;
}
.p-category::before {
content: '#';
}
</style>

View file

@ -1,107 +0,0 @@
---
import Icon from './Icon.astro';
---
<theme-toggle>
<button>
<span class="sr-only">Dark theme</span>
<span class="icon light"><Icon icon="sun" /></span>
<span class="icon dark"><Icon icon="moon-stars" /></span>
</button>
</theme-toggle>
<style>
button {
position: relative;
display: flex;
gap: 0.25rem;
border: 0;
border-radius: var(--theme-radius-full);
padding: 0.1875rem;
background-color: var(--theme-accent-light);
box-shadow: var(--theme-shadow-lg);
cursor: pointer;
}
button::before {
position: absolute;
inset: -0.125rem;
content: '';
border-radius: var(--theme-radius-full);
background: var(--theme-gradient-main);
z-index: -1;
}
.icon {
z-index: 1;
position: relative;
display: flex;
padding: 0.3125rem;
width: 1.625rem;
height: 1.625rem;
font-size: 1rem;
color: var(--theme-accent-dark);
}
.icon.light::before {
content: '';
z-index: -1;
position: absolute;
inset: 0;
background-color: var(--theme-accent-dark);
border-radius: 999rem;
}
:global(.theme-dark) .icon.light::before {
transform: translateX(calc(100% + 0.25rem));
}
:global(.theme-dark) .icon.dark,
:global(html:not(.theme-dark)) .icon.light,
button[aria-pressed='false'] .icon.light {
color: var(--theme-text-invert);
}
@media (prefers-reduced-motion: no-preference) {
.icon,
.icon.light::before {
transition: transform var(--theme-transition),
color var(--theme-transition);
}
}
@media (forced-colors: active) {
.icon.light::before {
background-color: SelectedItem;
}
}
</style>
<script>
class ThemeToggle extends HTMLElement {
constructor() {
super();
const button = this.querySelector('button')!;
/** Set the theme to dark/light mode. */
const setTheme = (dark: boolean) => {
document.documentElement.classList[dark ? 'add' : 'remove'](
'theme-dark'
);
button.setAttribute('aria-pressed', String(dark));
};
// Toggle the theme when a user clicks the button.
button.addEventListener('click', () => setTheme(!this.isDark()));
// Initialize button state to reflect current theme.
setTheme(this.isDark());
}
isDark() {
return document.documentElement.classList.contains('theme-dark');
}
}
customElements.define('theme-toggle', ThemeToggle);
</script>

View file

@ -1,164 +0,0 @@
---
import { Image } from 'astro:assets';
import settings from '../settings';
import Icon from './Icon.astro';
const socialLinks = Object.entries(settings.social);
---
<div class="h-card">
<div>
<div class="u-photo">
<Image {...settings.avatar} width={220} />
</div>
<h1>
<span class="p-name">{settings.name}</span>
<small class="p-nickname">{settings.username}</small>
</h1>
</div>
<div class="bio-sections">
<div class="bio">
<p>🚀 <a href="https://astro.build/">Astro</a> Mascot</p>
<p>😊 The cutest</p>
<p>🎨 Whimsical Speedy Web</p>
</div>
<div class="bio">
{
settings.pronouns && (
<p>
<Icon icon="user" color="var(--theme-accent-dark)" size="1.75rem" />
<span class="sr-only">Pronouns</span>
{settings.pronouns}
</p>
)
}
{
settings.location && (
<p>
<Icon icon="location-point" color="var(--theme-accent-dark)" size="1.75rem" />
<span class="sr-only">Location</span>
<span class="p-locality">{settings.location}</span>
</p>
)
}
{
settings.homepage && (
<p>
<Icon icon="link-h" color="var(--theme-accent-dark)" size="1.75rem" />
<span class="sr-only">Homepage</span>
<a href={settings.homepage} class="u-url">{settings.homepage.replace(/^https?:\/\/(www\.)?/, '')}</a>
</p>
)
}
<p>
<Icon icon="rss-alt" color="var(--theme-accent-dark)" size="1.75rem" />
<a href="/rss.xml">RSS Feed</a>
</p>
</div>
<ul class="social">
{
socialLinks.map(([key, { url, title }]) => (
<li>
<a href={url} rel="me">
<span class="sr-only">{title}</span>
<Icon icon={`${key}`} size="1.75rem" />
</a>
</li>
))
}
</ul>
</div>
</div>
<style>
.h-card {
display: flex;
flex-direction: column;
gap: var(--theme-space-md);
}
.u-photo {
display: inline-block;
position: relative;
}
.u-photo::after {
border-radius: var(--theme-radius-full);
position: absolute;
content: '';
inset: 0;
border: 3px solid var(--theme-text);
}
.u-photo img {
width: 110px;
height: 110px;
}
h1 {
display: flex;
flex-direction: column;
font-size: var(--theme-text-xl);
}
small {
font-size: var(--theme-text-base);
font-family: var(--theme-font-body);
color: var(--theme-gray-200);
}
.bio-sections {
display: grid;
grid-template-columns: 1fr;
align-items: flex-start;
gap: var(--theme-space-sm) var(--theme-space-md);
}
.bio-sections > :nth-child(2) {
grid-row: span 2;
}
.bio {
font-size: var(--theme-text-sm);
font-weight: 500;
}
.bio > * + * {
margin-top: var(--theme-space-xs);
}
.bio :global(svg) {
/* Slightly hacky way to avoid the icon height being included in the box calculation. */
margin: -50% 0;
}
.social {
display: flex;
flex-wrap: wrap;
gap: var(--theme-space-3xs);
list-style: none;
padding: 0;
grid-row: 2;
}
.social a {
color: var(--theme-accent-dark);
}
@media (min-width: 35em) {
.bio-sections {
grid-template-columns: 1fr 1fr;
}
.social {
grid-row: unset;
}
}
@media (min-width: 50em) {
.bio-sections {
display: flex;
flex-direction: column;
}
}
</style>

View file

@ -1,29 +0,0 @@
---
title: First post on my new site!
description: Dignissim eu sagittis aliquet magna sagittis. Eu etiam faucibus quis non. Laoreet amet aliquam enim sapien. Cras ac enim nulla morbi ultrices elementum metus neque nulla. Quis mi consectetur donec tempor habitant.
pubDate: 2023-01-01
categories: [keyboards, thoughts]
cover:
src: ../../assets/stock-1.jpg
alt: A laptop with a code editor open
---
Dignissim eu sagittis aliquet magna sagittis. Eu etiam faucibus quis non. Laoreet amet aliquam enim sapien. Cras ac enim nulla morbi ultrices elementum metus neque nulla. Quis mi consectetur donec tempor habitant.
Id at orci nulla nunc. Habitant a amet turpis facilisi purus cursus dui imperdiet. Integer fermentum amet nunc tristique scelerisque feugiat pellentesque phasellus. Feugiat euismod id varius id mattis ac ut. Donec aliquet fusce ut egestas vehicula sagittis.
Mauris vulputate tristique porttitor sed integer felis. In eget sodales lobortis laoreet molestie aliquet est aliquet tortor. Sodales erat rhoncus tellus mattis etiam nunc ornare. Nisi ut tellus elementum gravida dictum diam porta. Nulla porttitor magna duis pretium egestas nisl ornare.
## Heading One
Suscipit id porttitor laoreet purus semper fermentum libero cras magna. Non hendrerit lectus tincidunt condimentum. Sollicitudin pretium at vel nibh tempus proin faucibus donec sed. Habitant et risus auctor platea viverra tellus. Faucibus dapibus neque enim metus porttitor pulvinar pharetra amet sem. Nibh a facilisis pellentesque ut pellentesque. Amet semper ultrices est lacus facilisis pulvinar viverra. Quis velit cursus viverra varius vestibulum. Ultricies interdum id dapibus nunc bibendum vitae varius in. Lorem vel congue in amet et pellentesque sed facilisis. Id amet sed suspendisse tincidunt lacinia sit. Ut libero id ornare cursus porttitor elementum.
## Heading Number Two
Sagittis fames arcu tempor morbi sed mauris eu blandit cras. Risus amet nec auctor nunc pretium commodo. Dictum duis nascetur est molestie ullamcorper sit tempor. Vestibulum dictumst magna cursus aenean vitae ornare amet non.
Dui tortor viverra eu montes. Elit pretium pharetra aliquam pellentesque congue id morbi maecenas. Donec a egestas ipsum sit a ipsum. Quis vestibulum feugiat tincidunt justo tellus turpis. Luctus dignissim porta dictumst ut auctor neque in.
![Close-up of a mechanical keyboard with LED backlighting](../../assets/mechanical-keyboard.png)
Pellentesque faucibus faucibus magna tempus proin amet in viverra. Eros non ipsum justo pellentesque vestibulum morbi proin euismod. Sagittis in amet at aliquet facilisis.

View file

@ -1,9 +0,0 @@
---
title: Second time lucky
description: Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
pubDate: 2023-01-02
---
Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

View file

@ -1,10 +0,0 @@
---
title: Three is a magic number
description: Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
pubDate: 2023-01-03
cover:
src: ../../assets/stock-2.jpg
alt: A backlit multicolored mechanical keyboard
---
Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.

View file

@ -1,48 +0,0 @@
import { rssSchema } from '@astrojs/rss';
import { defineCollection, z, type CollectionEntry } from 'astro:content';
const articles = defineCollection({
schema: ({ image }) => rssSchema
.extend({
cover: z
.object({
src: image().refine(
(img) => img.width >= 885,
'Cover image must be at least 885px wide.'
),
alt: z.string(),
})
.optional(),
})
.required({
// requiring the description for articles, this will be shown as the short preview text on cards
title: true,
description: true
})
.strict(),
})
const notes = defineCollection({
schema: rssSchema
.omit({
// notes are short, self-contained content without unique titles or descriptions
description: true,
title: true
})
.strict()
})
export const collections = { articles, notes };
export type Article = CollectionEntry<'articles'>;
export type Note = CollectionEntry<'notes'>;
// eslint-disable-next-line @typescript-eslint/no-duplicate-type-constituents
export type Post = Article | Note;
export function isArticle(post: Post): post is Article {
return post.collection === 'articles'
}
export function isNote(post: Post): post is Note {
return post.collection === 'notes'
}

View file

@ -1,7 +0,0 @@
---
pubDate: 2023-01-10
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis commodo odio aenean sed. Enim nulla aliquet porttitor lacus luctus accumsan tortor posuere ac.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Aenean vel elit scelerisque mauris. Sapien eget mi proin sed libero enim sed.

View file

@ -1,5 +0,0 @@
---
pubDate: 2023-01-04
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Adipiscing elit ut aliquam purus sit amet luctus. Rhoncus aenean vel elit scelerisque mauris. Nulla pellentesque dignissim enim sit amet venenatis urna cursus.

View file

@ -1,7 +0,0 @@
---
pubDate: 2023-01-05
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Pellentesque habitant morbi tristique senectus et netus et.
![Mechanical keyboard with LED backlighting](../../assets/mechanical-keyboard.png)

View file

@ -1,5 +0,0 @@
---
pubDate: 2023-01-06
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Donec adipiscing tristique risus nec feugiat in fermentum posuere. Mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus et netus. Cursus sit amet dictum sit amet justo donec.

View file

@ -1,7 +0,0 @@
---
pubDate: 2023-01-07
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Volutpat maecenas volutpat blandit aliquam etiam erat velit.
Read more in [the docs](https://docs.astro.build)

View file

@ -1,7 +0,0 @@
---
pubDate: 2023-01-08
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Adipiscing bibendum est ultricies integer quis auctor.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Semper viverra nam libero justo laoreet sit amet cursus sit.

View file

@ -1,5 +0,0 @@
---
pubDate: 2023-01-09
---
ultrices neque ornare aenean euismod elementum

View file

@ -1,24 +0,0 @@
import { getCollection } from 'astro:content';
import type { Article, Note } from '../content/config';
export function sortPosts(order: 'asc' | 'desc' = 'desc') {
return function(a: Article | Note, b: Article | Note) {
return order === 'asc'
? a.data.pubDate.getTime() - b.data.pubDate.getTime()
: b.data.pubDate.getTime() - a.data.pubDate.getTime()
}
}
/** Get everything in your posts collection, sorted by date. */
export async function getSortedPosts(order: 'asc' | 'desc' = 'desc') {
const posts = await Promise.all([
getCollection('articles'),
getCollection('notes'),
])
.then((collections) => collections
.flat()
.sort(sortPosts(order)
));
return posts;
}

View file

@ -1,89 +0,0 @@
---
import settings from '../settings';
import '../style/theme.css';
import '../style/global.css';
import '../style/utilities.css';
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
export interface Props {
title?: string;
}
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
const { title = settings.name } = Astro.props;
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
<!-- Canonical URL -->
<link rel="canonical" href={canonicalURL} />
<!-- RSS Feed Discovery -->
<link rel="alternate" type="application/rss+xml" title="RSS" href="/rss.xml" />
<link
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@500;700&display=swap"
rel="stylesheet"
/>
<script is:inline>
// This code is inlined in the head to make dark mode instant & blocking.
const getThemePreference = () => {
if (typeof localStorage !== 'undefined' && localStorage.getItem('theme')) {
return localStorage.getItem('theme');
}
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
};
const isDark = getThemePreference() === 'dark';
document.documentElement.classList[isDark ? 'add' : 'remove']('theme-dark');
if (typeof localStorage !== 'undefined') {
// Watch the document element and persist user preference when it changes.
const observer = new MutationObserver(() => {
const isDark = document.documentElement.classList.contains('theme-dark');
localStorage.setItem('theme', isDark ? 'dark' : 'light');
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class'],
});
}
</script>
</head>
<body>
<Header class="header" />
<main>
<slot />
</main>
<Footer />
<style>
html {
scrollbar-gutter: stable;
}
body {
display: flex;
flex-direction: column;
gap: var(--theme-space-lg);
}
.header,
main {
padding-inline: var(--theme-space-sm-lg);
}
main {
width: 100%;
max-width: 55rem;
margin-inline: auto;
}
</style>
</body>
</html>

View file

@ -1,16 +0,0 @@
---
import Layout, { type Props as LayoutProps } from './Base.astro';
import UserProfile from '../components/UserProfile.astro';
import SplitLayout from '../components/SplitLayout.astro';
export interface Props extends LayoutProps {}
---
<Layout {...Astro.props}>
<SplitLayout>
<UserProfile />
<div>
<slot />
</div>
</SplitLayout>
</Layout>

View file

@ -1,48 +0,0 @@
---
import type { GetStaticPathsOptions, Page } from 'astro';
import Card from '../components/Card.astro';
import Pagination from '../components/Pagination.astro';
import { getSortedPosts } from '../helpers/getSortedPosts';
import Layout from '../layouts/Feed.astro';
import type { Post } from '../content/config.js';
export async function getStaticPaths({ paginate }: GetStaticPathsOptions) {
return paginate(await getSortedPosts(), { pageSize: 3 });
}
interface Props {
page: Page<Post>;
}
const { page } = Astro.props;
---
<Layout>
<div class="stack">
<ol>
{
page.data.map((post) => (
<li>
<Card {post} />
</li>
))
}
</ol>
<Pagination {...page} />
</div>
</Layout>
<style>
.stack {
display: flex;
flex-direction: column;
gap: 2.5rem;
}
ol {
list-style: none;
padding: 0;
display: flex;
flex-direction: column;
gap: 1.25rem;
}
</style>

View file

@ -1,102 +0,0 @@
---
import Article from '../../components/Article.astro';
import Card from '../../components/Card.astro';
import Icon from '../../components/Icon.astro';
import { getSortedPosts } from '../../helpers/getSortedPosts';
import Layout from '../../layouts/Base.astro';
import { isArticle, type Post } from '../../content/config';
export async function getStaticPaths() {
const posts = await getSortedPosts();
return posts.map((post, idx) => ({
params: { slug: post.slug },
props: { post, prev: posts[idx - 1], next: posts[idx + 1] },
}));
}
interface Props {
post: Post;
prev?: Post;
next?: Post;
}
const { post, prev, next } = Astro.props;
const { title } = isArticle(post) && post.data;
---
<Layout {title}>
<a href="/" class="back">
<Icon icon="arrow-left" color="var(--theme-accent-dark)" size="var(--theme-space-md)" />
<span>Back to feed</span>
</a>
{isArticle(post) ? <Article article={post} /> : <Card {post} class="card" />}
{
(next || prev) && (
<footer>
{prev && (
<a href={`/post/${prev.slug}`} class="prev">
<Icon icon="arrow-left" size="var(--theme-space-md)" color="var(--theme-accent-dark)" />
<span>Previous post</span>
</a>
)}
{next && (
<a href={`/post/${next.slug}`} class="next">
<span>Next post</span>
<Icon
icon="arrow-right"
size="var(--theme-space-md)"
color="var(--theme-accent-dark)"
/>
</a>
)}
</footer>
)
}
</Layout>
<style>
.back {
text-decoration: none;
font-weight: bold;
}
.back {
display: flex;
align-items: center;
gap: var(--theme-space-2xs);
margin-inline-start: -4px;
}
.card {
width: 100%;
margin: var(--theme-space-md) auto;
}
.center {
margin-inline: auto;
}
.prev,
.next {
display: flex;
align-items: center;
gap: 0.5rem;
}
footer {
display: flex;
justify-content: space-between;
margin-inline: -4px;
}
footer a {
font-weight: 700;
text-decoration: none;
}
.next:first-child {
margin-inline-start: auto;
}
</style>

View file

@ -1,27 +0,0 @@
import rss from '@astrojs/rss';
import type { APIContext } from 'astro';
import { sortPosts } from '../helpers/getSortedPosts';
import settings from '../settings';
import { getCollection } from 'astro:content';
const { title, description } = settings.rss;
export async function GET(context: APIContext) {
const posts = await getCollection('articles');
return rss({
// `<title>` field in output xml
title,
// `<description>` field in output xml
description,
// Pull in your project "site" from the endpoint context
// https://docs.astro.build/en/reference/api-reference/#contextsite
site: context.site!.href,
// Array of `<item>`s in output xml
// See "Generating items" section for examples using content collections and glob imports
items: posts
.sort(sortPosts())
.map(({ data, slug }) => ({ ...data, link: `/post/${slug}` })),
stylesheet: '/rss/styles.xsl',
});
}

View file

@ -1,66 +0,0 @@
import { iconPaths } from './components/IconPaths.js'
import avatar from './assets/avatar.webp'
export interface Image {
src: ImageMetadata
alt: string
}
export interface Settings {
name: string
username: string
avatar: Image
rss: {
title: string,
description: string
},
pronouns?: string | undefined
location?: string | undefined
homepage?: string | undefined
social: Partial<{
[icon in keyof typeof iconPaths]: {
url: string,
title: string,
}
}>
}
const settings: Settings = {
name: 'Houston Astro',
username: '@houston',
avatar: {
src: avatar,
alt: 'Astro mascot Houston smiling',
},
rss: {
title: 'Houston Astros Feed',
description: 'Stay up-to-date with the latest posts from Houston Astro!',
},
pronouns: 'They/Them',
location: 'Space',
homepage: 'https://astro.build',
social: {
twitter: {
url: 'https://twitter.com/astrodotbuild',
title: 'Twitter'
},
github: {
url: 'https://github.com/withastro',
title: 'GitHub',
},
mastodon: {
url: 'https://m.webtoo.ls/@astro',
title: 'Mastodon'
},
youtube: {
url: 'https://www.youtube.com/@astrodotbuild',
title: 'YouTube',
},
discord: {
url: 'https://astro.build/chat',
title: 'Discord'
}
},
};
export default settings;

View file

@ -1,45 +0,0 @@
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
}
html,
body {
height: 100%;
}
body {
background-color: var(--theme-bg);
color: var(--theme-text);
font-size: var(--theme-text-base);
font-family: var(--theme-font-body);
-webkit-font-smoothing: antialiased;
line-height: 1.5;
}
img,
picture,
video,
canvas {
display: block;
max-width: 100%;
}
img {
height: auto;
}
a {
color: var(--theme-text);
}
h1,
h2,
h3,
h4,
h5 {
line-height: 1.2;
font-family: var(--theme-font-brand);
}

View file

@ -1,120 +0,0 @@
:root {
/* Colors */
--theme-bg: #eceaf5;
--theme-bg-accent: #f6f5fb;
--theme-text: #171b26;
--theme-text-invert: #fdfdfd;
--theme-gray-200: #505d84;
--theme-gray-400: #505d84;
--theme-gray-700: #505d84;
--theme-accent-light: #ddd6fc;
--theme-accent-medium: #8577eb;
--theme-accent-dark: #5a48d9;
--theme-shade-subtle: var(--theme-accent-light);
/* Gradients */
--theme-gradient-main: linear-gradient(83.21deg, var(--theme-accent-dark) 6.77%, #c561f6 93.75%);
--theme-gradient-text: linear-gradient(
83.21deg,
var(--theme-accent-dark) 10.42%,
#7a4fe2 76.04%,
#c561f6 100%
);
/* Shadows */
--theme-shadow-sm: 1px 1px 5px rgba(0, 0, 0, 0.1);
--theme-shadow-md: 2px 2px 10px rgba(0, 0, 0, 0.1);
--theme-shadow-lg: 2px 2px 20px rgba(0, 0, 0, 0.2);
/* Content Sizes */
--theme-size-content-1: 30ch;
--theme-size-content-2: 45ch;
--theme-size-content-3: 65ch;
/* Type Scale */
/* @link https://utopia.fyi/type/calculator?c=320,16,1.2,1240,20,1.2,5,2,&s=0.75|0.5|0.25,1.5|2|3|4|6,s-l&g=s,l,xl,12 */
--theme-text-sm: clamp(0.83rem, calc(0.76rem + 0.36vw), 1.04rem);
--theme-text-base: clamp(1.00rem, calc(0.91rem + 0.43vw), 1.25rem);
--theme-text-lg: clamp(1.20rem, calc(1.10rem + 0.52vw), 1.50rem);
--theme-text-xl: clamp(1.44rem, calc(1.31rem + 0.63vw), 1.80rem);
--theme-text-2xl: clamp(1.73rem, calc(1.58rem + 0.75vw), 2.16rem);
--theme-text-3xl: clamp(2.07rem, calc(1.89rem + 0.90vw), 2.59rem);
--theme-text-4xl: clamp(2.49rem, calc(2.27rem + 1.08vw), 3.11rem);
/* @link https://utopia.fyi/type/calculator?c=320,16,1.2,1240,18,1.2,5,2,&s=0.75|0.5|0.25,1.5|2|3|4|6,s-l&g=s,l,xl,12 */
--theme-text-sm: clamp(0.83rem, calc(0.80rem + 0.18vw), 0.94rem);
--theme-text-base: clamp(1.00rem, calc(0.96rem + 0.22vw), 1.13rem);
--theme-text-lg: clamp(1.20rem, calc(1.15rem + 0.26vw), 1.35rem);
--theme-text-xl: clamp(1.44rem, calc(1.38rem + 0.31vw), 1.62rem);
--theme-text-2xl: clamp(1.73rem, calc(1.65rem + 0.38vw), 1.94rem);
--theme-text-3xl: clamp(2.07rem, calc(1.98rem + 0.45vw), 2.33rem);
--theme-text-4xl: clamp(2.49rem, calc(2.38rem + 0.54vw), 2.80rem);
/* Fonts */
--__font-system: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
--theme-font-body: var(--__font-system);
--theme-font-brand: 'Montserrat', var(--__font-system);
/* Corners */
--theme-radius-base: 0.3125rem;
--theme-radius-lg: 0.625rem;
--theme-radius-xl: 1.25rem;
--theme-radius-full: 999rem;
/* Transitions */
--theme-transition: 0.2s ease-in-out;
/* Spacing */
/* @link https://utopia.fyi/space/calculator?c=320,16,1.2,1240,18,1.2,5,2,&s=0.75|0.5|0.25,1.5|2|3|4|6,s-l&g=s,l,xl,12 */
--theme-space-3xs: clamp(0.25rem, calc(0.23rem + 0.11vw), 0.31rem);
--theme-space-2xs: clamp(0.50rem, calc(0.48rem + 0.11vw), 0.56rem);
--theme-space-xs: clamp(0.75rem, calc(0.71rem + 0.22vw), 0.88rem);
--theme-space-sm: clamp(1.00rem, calc(0.96rem + 0.22vw), 1.13rem);
--theme-space-md: clamp(1.50rem, calc(1.43rem + 0.33vw), 1.69rem);
--theme-space-lg: clamp(2.00rem, calc(1.91rem + 0.43vw), 2.25rem);
--theme-space-xl: clamp(3.00rem, calc(2.87rem + 0.65vw), 3.38rem);
--theme-space-2xl: clamp(4.00rem, calc(3.83rem + 0.87vw), 4.50rem);
--theme-space-3xl: clamp(6.00rem, calc(5.74rem + 1.30vw), 6.75rem);
/* One-up pairs */
--theme-space-3xs-2xs: clamp(0.25rem, calc(0.14rem + 0.54vw), 0.56rem);
--theme-space-2xs-xs: clamp(0.50rem, calc(0.37rem + 0.65vw), 0.88rem);
--theme-space-xs-sm: clamp(0.75rem, calc(0.62rem + 0.65vw), 1.13rem);
--theme-space-sm-md: clamp(1.00rem, calc(0.76rem + 1.20vw), 1.69rem);
--theme-space-md-lg: clamp(1.50rem, calc(1.24rem + 1.30vw), 2.25rem);
--theme-space-lg-xl: clamp(2.00rem, calc(1.52rem + 2.39vw), 3.38rem);
--theme-space-xl-2xl: clamp(3.00rem, calc(2.48rem + 2.61vw), 4.50rem);
--theme-space-2xl-3xl: clamp(4.00rem, calc(3.04rem + 4.78vw), 6.75rem);
/* Custom pairs */
--theme-space-sm-lg: clamp(1.00rem, calc(0.57rem + 2.17vw), 2.25rem);
}
:root.theme-dark {
/* Colors (dark) */
--theme-bg: #141925;
--theme-bg-accent: #202c49;
--theme-text: #fdfdfd;
--theme-text-invert: #171b26;
--theme-gray-200: #c3cadb;
--theme-gray-400: #8490b5;
--theme-gray-700: #3d4663;
--theme-accent-light: #ebd2f8;
--theme-accent-medium: #c779ed;
--theme-accent-dark: #c561f6;
--theme-shade-subtle: var(--theme-bg-accent);
/* Gradients (dark) */
--theme-gradient-main: linear-gradient(83.21deg, var(--theme-accent-dark) 6.25%, #5a48d9 100%);
--theme-gradient-text: linear-gradient(
83.21deg,
var(--theme-accent-dark) 6.25%,
#b45df1 75.52%,
#5a48d9 100%
);
/* Shadows (dark) */
--theme-shadow-sm: 1px 1px 5px rgba(0, 0, 0, 0.1);
--theme-shadow-md: 4px 4px 10px rgba(9, 11, 17, 0.2);
--theme-shadow-lg: 4px 4px 30px rgba(0, 0, 0, 0.6);
}

View file

@ -1,11 +0,0 @@
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}

View file

@ -1,3 +0,0 @@
{
"extends": "astro/tsconfigs/base"
}

View file

@ -12,9 +12,9 @@
"server": "node dist/server/entry.mjs"
},
"dependencies": {
"@astrojs/node": "^6.0.1",
"@astrojs/svelte": "^4.0.2",
"astro": "^3.1.4",
"@astrojs/node": "^6.0.3",
"@astrojs/svelte": "^4.0.3",
"astro": "^3.2.4",
"svelte": "^4.2.0"
}
}

View file

@ -0,0 +1,30 @@
# Astro Movies View Transitions Demo
### 👉🏽 [Live Demo](https://astro-movies.pages.dev/)
![Screenshot](./screenshot.png)
## 🚀 Getting Started
1. Clone this repository and install dependencies with `npm install`.
2. Start the project locally with npm run dev, or deploy it to your favorite server.
3. Have fun! ✨
## 🧞 Commands
All commands are run from the root of the project, from a terminal:
| Command | Action |
| :--------------------- | :----------------------------------------------- |
| `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:3000` |
| `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro --help` | Get help using the Astro CLI |
## 👀 Want to learn more?
Check out [Astro's documentation](https://docs.astro.build) or jump into their [Discord server](https://astro.build/chat).
You can also reach out to [Maxi on Twitter](https://twitter.com/charca).

View file

@ -0,0 +1,15 @@
import { defineConfig } from 'astro/config';
import tailwind from '@astrojs/tailwind';
import nodejs from '@astrojs/node';
// https://astro.build/config
export default defineConfig({
integrations: [tailwind()],
output: 'server',
adapter: nodejs({ mode: 'standalone' }),
vite: {
define: {
'process.env.TMDB_API_KEY': JSON.stringify(process.env.TMDB_API_KEY),
},
},
});

View file

@ -1,6 +1,5 @@
{
"name": "@example/social-feed",
"type": "module",
"name": "@example/view-transitions",
"version": "0.0.1",
"private": true,
"scripts": {
@ -10,9 +9,9 @@
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/rss": "^3.0.0",
"astro": "^3.0.1",
"reading-time": "^1.5.0"
"devDependencies": {
"@astrojs/tailwind": "^5.0.2",
"@astrojs/node": "^6.0.3",
"astro": "^3.2.4"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -0,0 +1,17 @@
<footer class="border border-t border-gray-800">
<div class="container mx-auto text-sm px-4 py-6">
Made with ❤️ by <a
href="https://www.twitter.com/charca"
target="_blank"
class="underline hover:text-gray-300">Maxi Ferreira</a
> — Powered by <a
href="https://astro.build"
target="_blank"
class="underline hover:text-gray-300">Astro</a
> and <a
href="https://www.themoviedb.org/documentation/api"
target="_blank"
class="underline hover:text-gray-300">TMDb API</a
>.
</div>
</footer>

View file

@ -0,0 +1,31 @@
---
const { movie } = Astro.props;
---
<div class="mt-8">
<a href={`/movies/${movie.id}`}>
<img
src={`https://image.tmdb.org/t/p/w500${movie.poster_path}`}
alt={`${movie.title} Poster`}
class="thumbnail hover:opacity-75 transition ease-in-out duration-150"
id={`movie-poster-${movie.id}`}
transition:name={`poster-${movie.id}`}
/>
</a>
<div class="mt-2">
<a href={`/movies/${movie.id}`} class="text-lg mt-2 hover:text-gray-300">{movie.title}</a>
<div class="flex items-center text-gray-400 text-sm mt-1">
<svg class="fill-current text-orange-500 w-4" viewBox="0 0 24 24"
><g data-name="Layer 2"
><path
d="M17.56 21a1 1 0 01-.46-.11L12 18.22l-5.1 2.67a1 1 0 01-1.45-1.06l1-5.63-4.12-4a1 1 0 01-.25-1 1 1 0 01.81-.68l5.7-.83 2.51-5.13a1 1 0 011.8 0l2.54 5.12 5.7.83a1 1 0 01.81.68 1 1 0 01-.25 1l-4.12 4 1 5.63a1 1 0 01-.4 1 1 1 0 01-.62.18z"
data-name="star"></path></g
></svg
>
<span class="ml-1">{movie.vote_average}</span>
<span class="mx-2">|</span>
<span>{movie.release_date}</span>
</div>
<div class="text-gray-400 text-sm">{movie.genres}</div>
</div>
</div>

View file

@ -0,0 +1,125 @@
---
const { data } = Astro.props;
const movie = {
...data,
poster_path: data.poster_path
? 'https://image.tmdb.org/t/p/w500/' + data.poster_path
: 'https://via.placeholder.com/500x750',
vote_average: (data.vote_average * 10).toFixed(2) + '%',
release_date: new Date(data.release_date).toLocaleDateString('en-us', {
year: 'numeric',
month: 'long',
day: 'numeric',
}),
genres: data.genres.map((g: any) => g.name).join(', '),
crew: data.credits.crew.slice(0, 3),
cast: data.credits.cast.slice(0, 5).map((c: any) => ({
...c,
profile_path: c.profile_path
? 'https://image.tmdb.org/t/p/w300/' + c.profile_path
: 'https://via.placeholder.com/300x450',
})),
images: data.images.backdrops.slice(0, 9),
};
---
<div class="movie-info border-b border-gray-800">
<div class="container mx-auto px-4 py-16 flex flex-col md:flex-row">
<div class="flex-none">
<img
src={movie.poster_path}
alt={`${movie.title} Poster`}
class="movie-poster w-64 lg:w-96"
id="movie-poster"
transition:name={`poster-${movie.id}`}
/>
</div>
<div class="md:ml-24">
<h2 class="text-4xl mt-4 md:mt-0 mb-2 font-semibold">{movie.title}</h2>
<div class="flex flex-wrap items-center text-gray-400 text-sm">
<svg class="fill-current text-orange-500 w-4" viewBox="0 0 24 24"
><g data-name="Layer 2"
><path
d="M17.56 21a1 1 0 01-.46-.11L12 18.22l-5.1 2.67a1 1 0 01-1.45-1.06l1-5.63-4.12-4a1 1 0 01-.25-1 1 1 0 01.81-.68l5.7-.83 2.51-5.13a1 1 0 011.8 0l2.54 5.12 5.7.83a1 1 0 01.81.68 1 1 0 01-.25 1l-4.12 4 1 5.63a1 1 0 01-.4 1 1 1 0 01-.62.18z"
data-name="star"></path></g
></svg
>
<span class="ml-1">{movie.vote_average}</span>
<span class="mx-2">|</span>
<span>{movie.release_date}</span>
<span class="mx-2">|</span>
<span>{movie.genres}</span>
</div>
<p class="text-gray-300 mt-8">
{movie.overview}
</p>
<div class="mt-12">
<h4 class="text-white font-semibold">Featured Crew</h4>
<div class="flex mt-4">
{
movie.crew.map((crew: any) => (
<div class="mr-8">
<div>{crew.name}</div>
<div class="text-gray-400 text-sm">{crew.job}</div>
</div>
))
}
</div>
</div>
</div>
</div>
</div>
<!-- end movie-info -->
<div class="movie-cast border-b border-gray-800">
<div class="container mx-auto px-4 py-16">
<h2 class="text-4xl font-semibold">Cast</h2>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-8">
{
movie.cast.map((cast: any) => (
<div class="mt-8">
<span>
<img
id={`person-photo-${cast.id}`}
src={cast.profile_path}
alt={cast.name}
class="thumbnail hover:opacity-75 transition ease-in-out duration-150"
/>
</span>
<div class="mt-2">
<span class="text-lg mt-2 hover:text-gray:300">{cast.name}</span>
<div class="text-sm text-gray-400">{cast.character}</div>
</div>
</div>
))
}
</div>
</div>
</div>
<!-- end movie-cast -->
<div class="movie-images">
<div class="container mx-auto px-4 py-16">
<h2 class="text-4xl font-semibold">Images</h2>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-8">
{
movie.images.map((image: any) => (
<div class="mt-8">
<span>
<img
src={`https://image.tmdb.org/t/p/w500${image.file_path}`}
loading="lazy"
alt={movie.name}
class="hover:opacity-75 transition ease-in-out duration-150"
/>
</span>
</div>
))
}
</div>
</div>
</div>
<!-- end movie-images -->

View file

@ -0,0 +1,15 @@
---
import MovieCard from './MovieCard.astro';
import movies from '../popular-movies.json';
const popularMovies = movies.results;
---
<div class="container mx-auto px-4 pt-16 mb-16">
<div class="popular-movies">
<h2 class="uppercase tracking-wider text-orange-500 text-lg font-semibold">Popular Movies</h2>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-8">
{popularMovies.map((movie) => <MovieCard movie={movie} />)}
</div>
</div>
<!-- end pouplar-movies -->
</div>

View file

@ -0,0 +1,18 @@
<nav class="nav border-b border-gray-800 sticky top-0 z-30 bg-gray-900">
<div
class="container mx-auto px-4 flex flex-col md:flex-row items-center justify-between px-4 py-6"
>
<ul class="flex flex-col md:flex-row items-center">
<li>
<a href="/" class="flex items-center font-bold text-xl">
<span>Movies</span>
&nbsp;
<span class="text-orange-500">List</span>
</a>
</li>
<li class="md:ml-16 mt-3 md:mt-0">
<a href="/" class="hover:text-gray-300">Movies</a>
</li>
</ul>
</div>
</nav>

View file

@ -0,0 +1,12 @@
import { z, defineCollection } from 'astro:content';
const movies = defineCollection({
type: 'data',
schema: z.object({
data: z.any(),
}),
});
// Expose your defined collection to Astro
// with the `collections` export
export const collections = { movies };

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,345 @@
{
"data": {
"adult": false,
"backdrop_path": "/e8FyMnifoN5BMuRFE97fS1lJZ6S.jpg",
"belongs_to_collection": {
"id": 1153632,
"name": "Darkland Collection",
"poster_path": null,
"backdrop_path": null
},
"budget": 0,
"genres": [
{ "id": 28, "name": "Action" },
{ "id": 53, "name": "Thriller" }
],
"homepage": "",
"id": 1085218,
"imdb_id": "tt20204996",
"original_language": "da",
"original_title": "Underverden 2",
"overview": "Seven years ago, Zaid went to war against the Copenhagen underworld to avenge his dead brother. His identity as a respected doctor of cardiology and life as a family man is but a fading dream, and in prison Zaid suffers the loss of his son Noah, whom he barely knows. When a police agent approaches Zaid and offers him a deal to be released in exchange for infiltrating the Copenhagen underworld, he sees his chance to reclaim the remnants of the family life he left behind. But everything has a price, and Zaid realizes that he has now seriously endangered his son's life. After all, once you become part of the underworld, is there any way out?",
"popularity": 524.476,
"poster_path": "/c8B4DsVcFVDLVmbpHMHU3RjLNAV.jpg",
"production_companies": [
{
"id": 64293,
"logo_path": "/lbYGnir9KeY8NyQZrUFZbf3QDej.png",
"name": "Profile Pictures",
"origin_country": "DK"
}
],
"production_countries": [{ "iso_3166_1": "DK", "name": "Denmark" }],
"release_date": "2023-04-13",
"revenue": 0,
"runtime": 110,
"spoken_languages": [
{ "english_name": "Arabic", "iso_639_1": "ar", "name": "العربية" },
{ "english_name": "Danish", "iso_639_1": "da", "name": "Dansk" }
],
"status": "Released",
"tagline": "",
"title": "Darkland: The Return",
"video": false,
"vote_average": 6.32,
"vote_count": 64,
"credits": {
"cast": [
{
"adult": false,
"gender": 2,
"id": 234907,
"known_for_department": "Acting",
"name": "Dar Salim",
"original_name": "Dar Salim",
"popularity": 16.442,
"profile_path": "/oTYCqdF6nfZTsvt1fbypi54ydI.jpg",
"cast_id": 1,
"character": "Zaid",
"credit_id": "6429b39701b1ca0113cc2840",
"order": 0
},
{
"adult": false,
"gender": 1,
"id": 90514,
"known_for_department": "Acting",
"name": "Birgitte Hjort Sørensen",
"original_name": "Birgitte Hjort Sørensen",
"popularity": 9.741,
"profile_path": "/uPak0FlCPdsc9B1pw4bBkuaMLXT.jpg",
"cast_id": 2,
"character": "Helle",
"credit_id": "6429b3d101b1ca00d5e8507e",
"order": 1
},
{
"adult": false,
"gender": 1,
"id": 32682,
"known_for_department": "Acting",
"name": "Stine Fischer Christensen",
"original_name": "Stine Fischer Christensen",
"popularity": 3.87,
"profile_path": "/6MYODCa28L1IzfhcYTUZUYThoF2.jpg",
"cast_id": 3,
"character": "Stine",
"credit_id": "6429b42c9cc67b05796bcdcc",
"order": 2
},
{
"adult": false,
"gender": 0,
"id": 1178394,
"known_for_department": "Acting",
"name": "Henrik Vestergaard",
"original_name": "Henrik Vestergaard",
"popularity": 0.766,
"profile_path": "/1Opgkbdkyt1x5iEOLgV3VJ29ZpA.jpg",
"cast_id": 4,
"character": "Lars",
"credit_id": "6429b45401b1ca0097fdfb0f",
"order": 3
},
{
"adult": false,
"gender": 0,
"id": 3236472,
"known_for_department": "Acting",
"name": "Soheil Bavi",
"original_name": "Soheil Bavi",
"popularity": 0.6,
"profile_path": null,
"cast_id": 5,
"character": "Muhdir",
"credit_id": "6429b4828de0ae00b65514de",
"order": 4
},
{
"adult": false,
"gender": 0,
"id": 3991209,
"known_for_department": "Acting",
"name": "Jack Pedersen",
"original_name": "Jack Pedersen",
"popularity": 0.648,
"profile_path": null,
"cast_id": 6,
"character": "Shahin",
"credit_id": "6429b4f4ac8e6b00d32aa4eb",
"order": 5
},
{
"adult": false,
"gender": 0,
"id": 2595279,
"known_for_department": "Acting",
"name": "Mohamed Djeziri",
"original_name": "Mohamed Djeziri",
"popularity": 0.84,
"profile_path": null,
"cast_id": 11,
"character": "",
"credit_id": "64c14243871b340101072cf6",
"order": 6
},
{
"adult": false,
"gender": 0,
"id": 4188787,
"known_for_department": "Acting",
"name": "Abud Mustafa",
"original_name": "Abud Mustafa",
"popularity": 0.98,
"profile_path": null,
"cast_id": 12,
"character": "",
"credit_id": "64c6c269db8a0000e3286594",
"order": 7
},
{
"adult": false,
"gender": 0,
"id": 4188788,
"known_for_department": "Acting",
"name": "Ahmad Ayman",
"original_name": "Ahmad Ayman",
"popularity": 0.6,
"profile_path": null,
"cast_id": 13,
"character": "",
"credit_id": "64c6c27f63aad20209a58505",
"order": 8
},
{
"adult": false,
"gender": 0,
"id": 4188789,
"known_for_department": "Acting",
"name": "Sebastian Nørgaard",
"original_name": "Sebastian Nørgaard",
"popularity": 0.6,
"profile_path": null,
"cast_id": 14,
"character": "",
"credit_id": "64c6c298db8a0000e32865ab",
"order": 9
},
{
"adult": false,
"gender": 0,
"id": 4188791,
"known_for_department": "Acting",
"name": "Hamed \"Baloosh\" Balosha",
"original_name": "Hamed \"Baloosh\" Balosha",
"popularity": 0.6,
"profile_path": null,
"cast_id": 15,
"character": "",
"credit_id": "64c6c2a3eec5b500ff5262cb",
"order": 10
},
{
"adult": false,
"gender": 0,
"id": 3549264,
"known_for_department": "Acting",
"name": "Noah Carter",
"original_name": "Noah Carter",
"popularity": 0.6,
"profile_path": null,
"cast_id": 16,
"character": "",
"credit_id": "64c6c2b0cadb6b00c82a2404",
"order": 11
},
{
"adult": false,
"gender": 0,
"id": 4188792,
"known_for_department": "Acting",
"name": "Asgar Hansen",
"original_name": "Asgar Hansen",
"popularity": 0.6,
"profile_path": null,
"cast_id": 17,
"character": "",
"credit_id": "64c6c2bc30f79c00c781a97c",
"order": 12
}
],
"crew": [
{
"adult": false,
"gender": 0,
"id": 1183636,
"known_for_department": "Directing",
"name": "Fenar Ahmad",
"original_name": "Fenar Ahmad",
"popularity": 1.646,
"profile_path": null,
"credit_id": "6429b673c04429026b13a94a",
"department": "Directing",
"job": "Director"
},
{
"adult": false,
"gender": 0,
"id": 1183636,
"known_for_department": "Directing",
"name": "Fenar Ahmad",
"original_name": "Fenar Ahmad",
"popularity": 1.646,
"profile_path": null,
"credit_id": "642ed070158c8501263ad755",
"department": "Writing",
"job": "Writer"
},
{
"adult": false,
"gender": 0,
"id": 2405913,
"known_for_department": "Directing",
"name": "Behrouz Bigdeli",
"original_name": "Behrouz Bigdeli",
"popularity": 0.6,
"profile_path": null,
"credit_id": "642ed08058361b00f2f13338",
"department": "Writing",
"job": "Writer"
}
]
},
"videos": { "results": [] },
"images": {
"backdrops": [
{
"aspect_ratio": 1.778,
"height": 1080,
"iso_639_1": "da",
"file_path": "/4wVFtesa5YEWuAUHRcxoCN1Y1uN.jpg",
"vote_average": 5.172,
"vote_count": 1,
"width": 1920
},
{
"aspect_ratio": 1.778,
"height": 720,
"iso_639_1": null,
"file_path": "/e8FyMnifoN5BMuRFE97fS1lJZ6S.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1280
},
{
"aspect_ratio": 1.778,
"height": 1116,
"iso_639_1": null,
"file_path": "/tDT465D3JZiABgz2uug9jCgOUlw.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1984
}
],
"logos": [],
"posters": [
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "da",
"file_path": "/A8EPXv3SV9qiNCIttIM4ezJRmhW.jpg",
"vote_average": 5.312,
"vote_count": 1,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 1200,
"iso_639_1": "da",
"file_path": "/A0cxUcMWBruPknr5ZSePIYFfe7z.jpg",
"vote_average": 5.172,
"vote_count": 1,
"width": 800
},
{
"aspect_ratio": 0.7,
"height": 2834,
"iso_639_1": "en",
"file_path": "/c8B4DsVcFVDLVmbpHMHU3RjLNAV.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1984
},
{
"aspect_ratio": 0.7,
"height": 2834,
"iso_639_1": "en",
"file_path": "/my1ve6HKygOVNYJBi3A0pRpPm2l.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1984
}
]
}
}
}

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more