Boostrap project

This commit is contained in:
Kevin Kandlbinder 2023-04-06 17:13:42 +02:00
commit c2500c85e7
Signed by: kevin
GPG key ID: 1460B586646E180D
38 changed files with 4149 additions and 0 deletions

13
.eslintignore Normal file
View file

@ -0,0 +1,13 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock

20
.eslintrc.cjs Normal file
View file

@ -0,0 +1,20 @@
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
plugins: ['svelte3', '@typescript-eslint'],
ignorePatterns: ['*.cjs'],
overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
settings: {
'svelte3/typescript': () => require('typescript')
},
parserOptions: {
sourceType: 'module',
ecmaVersion: 2020
},
env: {
browser: true,
es2017: true,
node: true
}
};

10
.gitignore vendored Normal file
View file

@ -0,0 +1,10 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
vite.config.js.timestamp-*
vite.config.ts.timestamp-*

1
.npmrc Normal file
View file

@ -0,0 +1 @@
engine-strict=true

13
.prettierignore Normal file
View file

@ -0,0 +1,13 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock

9
.prettierrc Normal file
View file

@ -0,0 +1,9 @@
{
"useTabs": true,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100,
"plugins": ["prettier-plugin-svelte"],
"pluginSearchDirs": ["."],
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
}

26
README.md Normal file
View file

@ -0,0 +1,26 @@
# public-spaces.de
This is the code for Public Spaces e.V. website, built on [SvelteKit](https://kit.svelte.dev/) and [Ghost](https://ghost.org/).
## Developing
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
```bash
npm run dev
# or start the server and open the app in a new browser tab
npm run dev -- --open
```
## Building
To create a production version of your app:
```bash
npm run build
```
You can preview the production build with `npm run preview`.
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.

44
package.json Normal file
View file

@ -0,0 +1,44 @@
{
"name": "public-spaces.de",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --plugin-search-dir . --check . && eslint .",
"format": "prettier --plugin-search-dir . --write ."
},
"devDependencies": {
"@sveltejs/adapter-auto": "^2.0.0",
"@sveltejs/adapter-static": "^2.0.1",
"@sveltejs/kit": "^1.5.0",
"@types/luxon": "^3.2.0",
"@typescript-eslint/eslint-plugin": "^5.45.0",
"@typescript-eslint/parser": "^5.45.0",
"eslint": "^8.28.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-svelte3": "^4.0.0",
"prettier": "^2.8.0",
"prettier-plugin-svelte": "^2.8.1",
"svelte": "^3.54.0",
"svelte-check": "^3.0.1",
"tslib": "^2.4.1",
"typescript": "^5.0.0",
"vite": "^4.2.0"
},
"type": "module",
"dependencies": {
"@fontsource/roboto-flex": "^4.5.5",
"@tryghost/content-api": "^1.11.7",
"@types/tryghost__content-api": "^1.3.11",
"feed": "^4.2.2",
"lucide-svelte": "^0.130.0",
"luxon": "^3.3.0",
"sass": "^1.60.0",
"simple-icons": "^8.9.0",
"svelte-preprocess": "^5.0.3"
}
}

12
src/app.d.ts vendored Normal file
View file

@ -0,0 +1,12 @@
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface Platform {}
}
}
export {};

12
src/app.html Normal file
View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

85
src/app.scss Normal file
View file

@ -0,0 +1,85 @@
@import '@fontsource/roboto-flex/variable-full.css';
* {
box-sizing: border-box;
}
html,
body {
font-family: 'Roboto FlexVariable', 'Roboto Flex', 'RobotoVariable', 'Roboto', 'Segoe UI', Tahoma,
Geneva, Verdana, sans-serif;
margin: 0;
padding: 0;
font-stretch: 120%;
//font-size: 1.1em;
@include formatting;
}
:root {
@include variables;
}
/*
Improved screen reader only CSS class
@author Gaël Poupard
@note Based on Yahoo!'s technique
@author Thierry Koblentz
@see https://developer.yahoo.com/blogs/ydn/clip-hidden-content-better-accessibility-53456.html
* 1.
@note `clip` is deprecated but works everywhere
@see https://developer.mozilla.org/en-US/docs/Web/CSS/clip
* 2.
@note `clip-path` is the future-proof version, but not very well supported yet
@see https://developer.mozilla.org/en-US/docs/Web/CSS/clip-path
@see http://caniuse.com/#search=clip-path
@author Yvain Liechti
@see https://twitter.com/ryuran78/status/778943389819604992
* 3.
@note preventing text to be condensed
author J. Renée Beach
@see https://medium.com/@jessebeach/beware-smushed-off-screen-accessible-text-5952a4c2cbfe
@note Drupal 8 goes with word-wrap: normal instead
@see https://www.drupal.org/node/2045151
@see http://cgit.drupalcode.org/drupal/commit/?id=5b847ea
* 4.
@note !important is important
@note Obviously you wanna hide something
@author Harry Roberts
@see https://csswizardry.com/2016/05/the-importance-of-important/
*/
.sr-only {
border: 0 !important;
clip: rect(1px, 1px, 1px, 1px) !important; /* 1 */
-webkit-clip-path: inset(50%) !important;
clip-path: inset(50%) !important; /* 2 */
height: 1px !important;
margin: -1px !important;
overflow: hidden !important;
padding: 0 !important;
position: absolute !important;
width: 1px !important;
white-space: nowrap !important; /* 3 */
}
/*
Use in conjunction with .sr-only to only display content when it's focused.
@note Useful for skip links
@see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
@note Based on a HTML5 Boilerplate technique, included in Bootstrap
@note Fixed a bug with position: static on iOS 10.0.2 + VoiceOver
@author Sylvain Pigeard
@see https://github.com/twbs/bootstrap/issues/20732
*/
.sr-only-focusable:focus,
.sr-only-focusable:active {
clip: auto !important;
-webkit-clip-path: none !important;
clip-path: none !important;
height: auto !important;
margin: auto !important;
overflow: visible !important;
width: auto !important;
white-space: normal !important;
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 20 KiB

View file

@ -0,0 +1,408 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg18"
width="1234.8944"
height="1099.8466"
viewBox="0 0 1234.8944 1099.8465"
sodipodi:docname="hwf_logo.pdf"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs22">
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath46">
<path
d="M 0,841.89 H 1190.551 V 0 H 0 Z"
id="path44" />
</clipPath>
</defs>
<sodipodi:namedview
id="namedview20"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false" />
<g
id="g26"
inkscape:groupmode="layer"
inkscape:label="Page 1"
transform="matrix(1.3333333,0,0,-1.3333333,-162.32346,1118.6181)">
<g
id="g28"
transform="matrix(1.2994364,0,0,1.2994364,438.44801,204.74473)">
<path
d="M 0,0 H 7.436 V -41.606 H 0 v 18.058 H -21.305 V -41.606 H -28.8 V 0 h 7.495 V -17.41 H 0 Z"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path30" />
</g>
<g
id="g32"
transform="matrix(1.2994364,0,0,1.2994364,471.0393,171.00252)">
<path
d="M 0,0 H 15.226 L 7.613,17.704 Z m 21.954,-15.64 -4.19,9.738 H -2.479 l -4.19,-9.738 h -7.672 L 4.485,25.967 h 6.197 L 29.508,-15.64 Z"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path34" />
</g>
<g
id="g36"
transform="matrix(1.2994364,0,0,1.2994364,558.61546,204.74473)">
<path
d="m 0,0 h 5.96 v -41.606 h -6.727 v 27.501 l -10.977,-20.774 h -5.075 l -11.036,20.479 0.059,-27.206 h -6.728 V 0 h 6.02 l 14.281,-27.207 z"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path38" />
</g>
<g
id="g40">
<g
id="g42"
clip-path="url(#clipPath46)">
<g
id="g48"
transform="matrix(1.2994364,0,0,1.2994364,607.84747,160.26567)">
<path
d="m 0,0 c 1.259,0.983 1.889,2.518 1.889,4.604 0,2.084 -0.64,3.638 -1.918,4.662 -1.28,1.022 -3.276,1.534 -5.991,1.534 H -16.642 V -1.476 H -6.02 c 2.754,0 4.76,0.493 6.02,1.476 m -16.642,16.701 h 9.62 c 5.231,0 7.848,1.948 7.848,5.843 0,1.967 -0.648,3.423 -1.947,4.367 -1.299,0.944 -3.267,1.417 -5.901,1.417 h -9.62 z M 7.111,10.446 C 8.43,8.676 9.089,6.511 9.089,3.954 c 0,-3.541 -1.27,-6.314 -3.807,-8.321 -2.538,-2.007 -6.03,-3.01 -10.475,-3.01 h -18.885 v 41.606 h 18.295 c 4.327,0 7.72,-0.955 10.179,-2.862 2.459,-1.909 3.689,-4.574 3.689,-7.997 0,-2.204 -0.58,-4.111 -1.74,-5.724 -1.161,-1.614 -2.765,-2.794 -4.811,-3.542 2.4,-0.668 4.259,-1.887 5.577,-3.658"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path50" />
</g>
<g
id="g52"
transform="matrix(1.2994364,0,0,1.2994364,632.84759,155.74181)">
<path
d="M 0,0 C -2.951,2.95 -4.427,7.259 -4.427,12.924 V 37.711 H 3.01 v -25.2 c 0,-3.58 0.844,-6.285 2.537,-8.115 1.691,-1.83 4.17,-2.744 7.436,-2.744 3.226,0 5.685,0.924 7.377,2.774 1.691,1.848 2.537,4.544 2.537,8.085 v 25.2 h 7.437 V 12.924 C 30.334,7.297 28.858,2.999 25.907,0.029 22.957,-2.942 18.648,-4.427 12.983,-4.427 7.278,-4.427 2.95,-2.951 0,0"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path54" />
</g>
<g
id="g56"
transform="matrix(1.2994364,0,0,1.2994364,712.83153,182.08333)">
<path
d="m 0,0 c 1.337,1.082 2.007,2.744 2.007,4.987 0,2.282 -0.67,3.944 -2.007,4.987 -1.338,1.042 -3.443,1.564 -6.314,1.564 h -9.915 V -1.623 h 9.915 c 2.871,0 4.976,0.54 6.314,1.623 M 11.213,-24.167 H 2.951 l -7.141,13.278 c -0.669,1.259 -1.496,2.145 -2.479,2.657 -0.983,0.51 -2.223,0.766 -3.718,0.766 h -5.783 v -16.701 h -7.495 v 41.606 h 18.413 c 4.721,0 8.311,-1.053 10.771,-3.157 C 7.977,12.177 9.207,9.138 9.207,5.164 9.207,1.977 8.312,-0.649 6.521,-2.715 4.73,-4.78 2.203,-6.129 -1.062,-6.757 1.141,-7.348 2.911,-8.902 4.249,-11.42 Z"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path58" />
</g>
<g
id="g60"
transform="matrix(1.2994364,0,0,1.2994364,778.55326,179.89807)">
<path
d="m 0,0 v -19.947 c -1.889,-0.945 -4.181,-1.693 -6.875,-2.243 -2.695,-0.551 -5.439,-0.827 -8.233,-0.827 -4.288,0 -8.007,0.856 -11.154,2.568 -3.148,1.711 -5.557,4.17 -7.229,7.377 -1.673,3.206 -2.509,7.012 -2.509,11.42 0,4.367 0.836,8.153 2.509,11.36 1.672,3.206 4.052,5.665 7.14,7.377 3.088,1.711 6.718,2.567 10.889,2.567 2.911,0 5.645,-0.423 8.203,-1.269 2.557,-0.846 4.682,-2.056 6.374,-3.629 L -3.423,9.266 c -1.928,1.494 -3.827,2.566 -5.695,3.215 -1.869,0.65 -3.925,0.974 -6.167,0.974 -4.289,0 -7.525,-1.268 -9.708,-3.807 -2.184,-2.537 -3.276,-6.304 -3.276,-11.3 0,-10.231 4.486,-15.345 13.456,-15.345 2.675,0 5.35,0.374 8.026,1.121 V -5.43 h -8.97 V 0 Z"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path62" />
</g>
<g
id="g64"
transform="matrix(1.2994364,0,0,1.2994364,273.49132,128.63388)">
<path
d="m 0,0 h 15.244 l -30.859,-87.373 h -13.013 l -21.936,62.834 -22.061,-62.834 H -85.638 L -116.373,0 h 16.111 L -78.574,-65.065 -55.77,0 h 11.278 l 22.184,-65.437 z"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path66" />
</g>
<g
id="g68"
transform="matrix(1.2994364,0,0,1.2994364,309.72389,15.098095)">
<path
d="M 0,0 V 87.373 H 58.497 V 74.731 H 15.616 V 50.688 H 56.018 V 38.172 H 15.616 V 12.642 H 58.497 V 0 Z"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path70" />
</g>
<g
id="g72"
transform="matrix(1.2994364,0,0,1.2994364,470.9269,81.04579)">
<path
d="m 0,0 c 2.808,2.271 4.214,5.763 4.214,10.472 0,4.791 -1.406,8.282 -4.214,10.472 -2.81,2.189 -7.231,3.285 -13.261,3.285 H -34.082 V -3.408 h 20.821 C -7.231,-3.408 -2.81,-2.273 0,0 M 23.547,-50.751 H 6.197 l -14.996,27.885 c -1.406,2.643 -3.141,4.503 -5.205,5.577 -2.067,1.073 -4.669,1.611 -7.808,1.611 h -12.146 v -35.073 h -15.739 v 87.373 h 38.667 c 9.915,0 17.453,-2.212 22.618,-6.631 5.162,-4.421 7.745,-10.803 7.745,-19.147 0,-6.693 -1.88,-12.207 -5.638,-16.545 -3.761,-4.338 -9.069,-7.169 -15.926,-8.489 4.627,-1.24 8.344,-4.505 11.154,-9.791 z"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path74" />
</g>
<g
id="g76"
transform="matrix(1.2994364,0,0,1.2994364,583.65625,35.227924)">
<path
d="m 0,0 c 2.643,2.064 3.966,5.287 3.966,9.667 0,4.379 -1.344,7.642 -4.028,9.791 -2.686,2.147 -6.878,3.223 -12.579,3.223 H -34.949 V -3.098 h 22.308 C -6.859,-3.098 -2.646,-2.065 0,0 m -34.949,35.073 h 20.201 c 10.987,0 16.483,4.09 16.483,12.27 0,4.131 -1.363,7.188 -4.09,9.171 -2.727,1.983 -6.859,2.974 -12.393,2.974 H -34.949 Z M 14.934,21.937 c 2.767,-3.718 4.151,-8.263 4.151,-13.633 0,-7.436 -2.664,-13.261 -7.993,-17.475 -5.329,-4.214 -12.663,-6.32 -21.998,-6.32 h -39.659 v 87.373 h 38.419 c 9.088,0 16.214,-2.004 21.379,-6.011 5.162,-4.009 7.746,-9.604 7.746,-16.793 0,-4.628 -1.221,-8.635 -3.656,-12.021 C 10.885,33.668 7.517,31.189 3.222,29.62 8.261,28.215 12.165,25.654 14.934,21.937"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path78" />
</g>
<g
id="g80"
transform="matrix(1.2994364,0,0,1.2994364,628.42521,15.098095)">
<path
d="M 0,0 V 87.373 H 58.496 V 74.731 H 15.615 V 50.688 H 56.018 V 38.172 H 15.615 V 12.642 H 58.496 V 0 Z"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path82" />
</g>
<g
id="g84"
transform="matrix(1.2994364,0,0,1.2994364,725.05052,15.098095)">
<path
d="M 0,0 V 87.373 H 57.257 V 74.607 H 15.739 V 50.813 H 54.778 V 38.048 H 15.739 V 0 Z"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path86" />
</g>
<g
id="g88"
transform="matrix(1.2994364,0,0,1.2994364,881.90536,81.04579)">
<path
d="m 0,0 c 2.808,2.271 4.214,5.763 4.214,10.472 0,4.791 -1.406,8.282 -4.214,10.472 -2.81,2.189 -7.23,3.285 -13.261,3.285 H -34.082 V -3.408 h 20.821 C -7.23,-3.408 -2.81,-2.273 0,0 M 23.547,-50.751 H 6.196 l -14.995,27.885 c -1.406,2.643 -3.141,4.503 -5.206,5.577 -2.065,1.073 -4.668,1.611 -7.807,1.611 h -12.146 v -35.073 h -15.739 v 87.373 h 38.667 c 9.915,0 17.453,-2.212 22.618,-6.631 5.162,-4.421 7.746,-10.803 7.746,-19.147 0,-6.693 -1.881,-12.207 -5.64,-16.545 -3.76,-4.338 -9.068,-7.169 -15.924,-8.489 4.626,-1.24 8.343,-4.505 11.153,-9.791 z"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path90" />
</g>
<g
id="g92"
transform="matrix(1.2994364,0,0,1.2994364,930.37797,15.098095)">
<path
d="M 0,0 V 87.373 H 58.496 V 74.731 H 15.615 V 50.688 H 56.018 V 38.172 H 15.615 V 12.642 H 58.496 V 0 Z"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path94" />
</g>
<path
d="m 1026.3586,128.63375 h 20.7741 V 15.098095 h -20.7741 z"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29944"
id="path96" />
<g
id="g98"
transform="matrix(1.2994364,0,0,1.2994364,465.18534,384.28252)">
<path
d="m 0,0 c -2.719,-40.258 -11.772,-80.677 -25.435,-118.405 h 92.799 l -0.05,50.42 c 0,15.392 12.482,27.866 27.866,27.866 h 0.034 c 15.384,0 27.867,-12.474 27.867,-27.866 l -0.051,-50.42 h 92.8 C 202.166,-80.677 193.113,-40.258 190.394,0 Z"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path100" />
</g>
<g
id="g102"
transform="matrix(1.2994364,0,0,1.2994364,491.16185,540.93152)">
<path
d="M 0,0 4.269,-7.393 8.546,0 h 8.539 l -4.27,7.4 4.27,7.393 H 8.546 L 4.269,22.186 0,14.793 H -8.539 L -4.27,7.4 -8.539,0 Z"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path104" />
</g>
<g
id="g106"
transform="matrix(1.2994364,0,0,1.2994364,675.51016,540.93152)">
<path
d="M 0,0 4.277,-7.393 8.546,0 h 8.539 l -4.269,7.4 4.269,7.393 H 8.546 L 4.277,22.186 0,14.793 H -8.539 L -4.27,7.4 -8.539,0 Z"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path108" />
</g>
<g
id="g110"
transform="matrix(1.2994364,0,0,1.2994364,458.15344,523.9271)">
<path
d="m 0,0 v -6.89 -6.89 -6.89 h 59.35 v 6.89 6.89 V 0 H 45.57 V -6.89 H 36.565 V 0 H 22.785 V -6.89 H 13.78 V 0 Z"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path112" />
</g>
<g
id="g114"
transform="matrix(1.2994364,0,0,1.2994364,446.70034,388.84835)">
<path
d="M 0,0 H 218.845 V 13.78 H 203.566 V 79.957 H 157.148 V 13.78 H 132.562 V 79.957 H 86.144 V 13.78 H 61.698 V 79.957 H 15.28 V 13.78 H 0 Z"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path116" />
</g>
<g
id="g118"
transform="matrix(1.2994364,0,0,1.2994364,642.50162,523.9271)">
<path
d="m 0,0 v -6.89 -6.89 -6.89 h 59.35 v 6.89 6.89 V 0 H 45.57 V -6.89 H 36.565 V 0 H 22.785 V -6.89 H 13.78 V 0 Z"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path120" />
</g>
<g
id="g122"
transform="matrix(1.2994364,0,0,1.2994364,782.75914,618.09829)">
<path
d="m 0,0 c -0.934,1.608 -2.235,3.749 -3.956,6.345 -1.461,2.203 -3.2,4.695 -5.259,7.432 -2.581,3.434 -5.654,7.221 -9.216,11.202 -5.096,5.697 -11.211,11.773 -18.428,17.777 -2.892,2.406 -5.974,4.791 -9.221,7.138 -2.928,2.117 -5.995,4.191 -9.219,6.213 -5.679,3.56 -11.811,6.939 -18.436,10.009 -2.965,1.375 -6.05,2.668 -9.21,3.91 -2.985,1.172 -6.057,2.277 -9.22,3.31 -5.845,1.911 -11.973,3.583 -18.433,4.928 -3.009,0.626 -6.078,1.19 -9.222,1.675 -3.008,0.463 -6.08,0.859 -9.215,1.182 -2.051,0.212 -4.16,0.351 -6.265,0.498 -2.949,0.208 -5.955,0.346 -9.011,0.421 -0.07,0.036 -0.128,0.072 -0.204,0.107 -0.706,0.32 -1.693,0.609 -2.788,0.773 h 0.019 l -0.831,12.469 c -0.528,0.196 -1.492,0.291 -2.109,-0.043 l -0.677,-12.391 c -1.47,-0.192 -2.743,-0.571 -3.449,-0.919 -0.777,-0.023 -1.565,-0.023 -2.335,-0.058 -3.12,-0.14 -6.196,-0.354 -9.215,-0.664 -3.134,-0.32 -6.195,-0.752 -9.22,-1.241 -3.133,-0.507 -6.201,-1.11 -9.217,-1.785 -6.403,-1.429 -12.561,-3.187 -18.432,-5.263 -6.468,-2.288 -12.614,-4.92 -18.435,-7.811 -3.18,-1.579 -6.239,-3.246 -9.224,-4.959 -3.553,-2.04 -6.965,-4.164 -10.25,-6.343 -2.829,-1.876 -5.567,-3.791 -8.186,-5.743 -0.352,-0.263 -0.684,-0.531 -1.033,-0.795 -2.844,-2.149 -5.585,-4.323 -8.182,-6.51 -0.285,-0.24 -0.546,-0.48 -0.828,-0.721 -2.956,-2.518 -5.758,-5.041 -8.39,-7.54 -3.604,-3.423 -6.888,-6.789 -9.881,-10.025 -3.2,-3.462 -6.064,-6.773 -8.553,-9.815 -0.104,-0.127 -0.191,-0.241 -0.294,-0.367 -3.838,-4.714 -6.813,-8.77 -8.923,-11.782 -0.108,-0.155 -0.191,-0.278 -0.296,-0.427 -0.868,-1.248 -1.615,-2.344 -2.162,-3.162 -0.94,-1.407 -1.411,-2.187 -1.411,-2.187 0,0 1.532,0.906 3.869,2.175 0.7,0.382 1.454,0.784 2.285,1.219 5.929,3.094 14.738,7.195 19.893,7.262 17.891,0.259 29.909,-13.446 29.909,-13.446 0,0 15.316,14.841 34.208,14.33 18.892,-0.504 27.194,-12.549 27.194,-12.549 0,0 11.034,13.137 30.845,13.299 0.007,-6.489 0.027,-26.038 0.041,-38.164 h -3.658 v -9.07 h -7.945 v -8.818 h 7.945 v -7.822 c -10.378,-2.302 -18.144,-11.545 -18.144,-22.615 h -6.496 v -13.78 h 59.35 v 13.78 h -6.496 c 0,11.068 -7.764,20.309 -18.138,22.613 v 7.824 h 7.938 v 8.818 h -7.938 v 9.07 h -3.696 V 7.043 c 18.275,-1.016 25.926,-13.214 25.926,-13.214 0,0 17.034,12.685 33.06,12.172 16.035,-0.507 28.204,-12.172 28.204,-12.172 0,0 11.293,12.938 31.908,12.938 11.79,0 20.052,-3.237 24.978,-6.009 C -2.157,-0.154 -0.9,-1.009 0,-1.687 1.15,-2.555 1.735,-3.134 1.735,-3.134 1.735,-3.134 1.15,-1.98 0,0"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path124" />
</g>
<path
d="M 363.39529,150.89829 H 375.3748 V 838.46775 H 363.39529 Z"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29944"
id="path126" />
<path
d="m 334.54131,150.89829 h 11.9795 v 687.56946 h -11.9795 z"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29944"
id="path128" />
<g
id="g130"
transform="matrix(1.2994364,0,0,1.2994364,222.33641,838.46763)">
<path
d="M 0,0 V -529.129 H 18.237 L 18.434,0 Z"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path132" />
</g>
<g
id="g134"
transform="matrix(1.2994364,0,0,1.2994364,299.09216,838.46763)">
<path
d="M 0,0 V -529.129 H 18.237 L 18.434,0 Z"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path136" />
</g>
<path
d="m 157.64644,150.89829 h 11.9808 v 687.56946 h -11.9808 z"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29944"
id="path138" />
<path
d="m 186.62127,150.89829 h 11.9808 v 687.56946 h -11.9808 z"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29944"
id="path140" />
<path
d="m 263.38287,150.89829 h 11.97561 v 687.56946 h -11.97561 z"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29944"
id="path142" />
<path
d="m 122.26928,150.89829 h 23.95381 v 687.56946 h -23.95381 z"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29944"
id="path144" />
<path
d="m 904.53647,150.89829 h 23.95381 v 687.56946 h -23.95381 z"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29944"
id="path146" />
<path
d="m 1009.9156,150.89829 h 11.9795 v 687.56946 h -11.9795 z"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29944"
id="path148" />
<path
d="M 829.09509,150.89829 H 841.0746 V 838.46775 H 829.09509 Z"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29944"
id="path150" />
<path
d="m 800.0228,150.89829 h 11.97951 V 838.46775 H 800.0228 Z"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29944"
id="path152" />
<path
d="m 852.38879,150.89829 h 11.9795 v 687.56946 h -11.9795 z"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29944"
id="path154" />
<path
d="m 881.13362,150.89829 h 11.9795 v 687.56946 h -11.9795 z"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29944"
id="path156" />
<path
d="m 974.20315,150.89829 h 11.97951 v 687.56946 h -11.97951 z"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29944"
id="path158" />
<path
d="m 945.34917,150.89829 h 11.9795 v 687.56946 h -11.9795 z"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29944"
id="path160" />
<path
d="m 1033.4276,150.89829 h 11.9795 v 687.56946 h -11.9795 z"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29944"
id="path162" />
<g
id="g164"
transform="matrix(1.2994364,0,0,1.2994364,567.18291,723.76027)">
<path
d="M 0,0 C 2.436,0.25 4.934,0.399 7.439,0.536 V 88.275 H -10.995 V -1.584 c 0.599,0.104 1.172,0.246 1.775,0.343 C -6.195,-0.752 -3.134,-0.32 0,0"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path166" />
</g>
<g
id="g168"
transform="matrix(1.2994364,0,0,1.2994364,700.41295,697.16614)">
<path
d="M 0,0 V 108.741 H -18.434 V 8.714 c 2.758,-1.102 5.466,-2.239 8.07,-3.446 C -6.762,3.598 -3.317,1.832 0,0"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path170" />
</g>
<g
id="g172"
transform="matrix(1.2994364,0,0,1.2994364,612.77948,723.69296)">
<path
d="M 0,0 V 88.327 H -9.219 V 0.578 C -7.64,0.507 -6.037,0.466 -4.49,0.357 -2.981,0.252 -1.49,0.127 0,0"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path174" />
</g>
<g
id="g176"
transform="matrix(1.2994364,0,0,1.2994364,636.18168,720.31676)">
<path
d="M 0,0 V 90.925 H -9.219 V 1.557 C -8.493,1.455 -7.737,1.386 -7.019,1.275 -4.626,0.906 -2.313,0.453 0,0"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path178" />
</g>
<g
id="g180"
transform="matrix(1.2994364,0,0,1.2994364,659.58388,838.46775)">
<path
d="m 0,0 h -9.219 v -92.895 c 3.15,-0.789 6.224,-1.646 9.219,-2.575 z"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path182" />
</g>
<g
id="g184"
transform="matrix(1.2994364,0,0,1.2994364,758.80962,650.55717)">
<path
d="M 0,0 C 0.249,-0.278 0.476,-0.547 0.72,-0.823 V 144.609 H -8.498 V 8.848 C -5.401,5.841 -2.569,2.872 0,0"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path186" />
</g>
<g
id="g188"
transform="matrix(1.2994364,0,0,1.2994364,782.75901,618.09829)">
<path
d="M 0,0 C 0.114,-0.196 0.196,-0.345 0.299,-0.524 V 169.589 H -8.919 V 13.371 C -6.998,10.799 -5.341,8.434 -3.956,6.345 -2.235,3.749 -0.933,1.608 0,0"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path190" />
</g>
<g
id="g192"
transform="matrix(1.2994364,0,0,1.2994364,723.81515,682.23405)">
<path
d="M 0,0 V 120.232 H -9.219 V 6.282 C -6.263,4.407 -3.424,2.493 -0.719,0.537 -0.473,0.359 -0.244,0.178 0,0"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path194" />
</g>
<g
id="g196"
transform="matrix(1.2994364,0,0,1.2994364,500.08989,705.03643)">
<path
d="M 0,0 C 1.382,0.646 2.808,1.251 4.218,1.871 V 102.684 H -5.001 V -2.387 c 0.448,0.229 0.876,0.472 1.329,0.697 C -2.481,-1.099 -1.218,-0.569 0,0"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path198" />
</g>
<g
id="g200"
transform="matrix(1.2994364,0,0,1.2994364,524.0411,714.50906)">
<path
d="M 0,0 C 1.245,0.405 2.55,0.736 3.817,1.112 V 95.394 H -5.401 V -1.839 c 0.584,0.216 1.141,0.46 1.732,0.669 C -2.474,-0.747 -1.218,-0.396 0,0"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path202" />
</g>
<g
id="g204"
transform="matrix(1.2994364,0,0,1.2994364,411.08786,634.20597)">
<path
d="M 0,0 V 157.193 H -9.219 V -12.209 c 0.105,0.15 0.188,0.272 0.296,0.427 C -6.813,-8.77 -3.838,-4.714 0,0"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path206" />
</g>
<g
id="g208"
transform="matrix(1.2994364,0,0,1.2994364,435.42331,660.4633)">
<path
d="M 0,0 C 2.632,2.499 5.434,5.023 8.39,7.541 L 8.554,136.986 H -9.88 V -10.025 C -6.888,-6.789 -3.603,-3.422 0,0"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path210" />
</g>
<g
id="g212"
transform="matrix(1.2994364,0,0,1.2994364,470.01288,688.15337)">
<path
d="M 0,0 V 115.677 H -9.219 V -6.538 c 0.35,0.265 0.681,0.532 1.034,0.795 C -5.567,-3.791 -2.829,-1.876 0,0"
style="fill:#444141;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path214" />
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

10
src/lib/server/secrets.ts Normal file
View file

@ -0,0 +1,10 @@
import { env } from '$env/dynamic/private';
const Secrets = {
ghost: {
url: env.GHOST_URL || 'https://demo.ghost.io',
key: env.GHOST_CONTENT_TOKEN || '22444f78447824223cefc48062'
}
};
export default Secrets;

9
src/lib/variables.ts Normal file
View file

@ -0,0 +1,9 @@
import { env } from '$env/dynamic/public';
const Variables = {
/*calapi: {
query_url: env.PUBLIC_CALAPI_QUERY_URL || 'http://localhost:8080/query'
}*/
};
export default Variables;

View file

@ -0,0 +1,82 @@
import Secrets from '$lib/server/secrets';
import type { RequestHandler } from './$types';
import GhostContentAPI from '@tryghost/content-api';
import { Feed } from 'feed';
import { DateTime } from 'luxon';
import { error } from '@sveltejs/kit';
export const trailingSlash = 'never';
export const prerender = true;
export const GET: RequestHandler = async (request) => {
//const siteBase = `${request.url.protocol}//${request.url.host}/`
const siteBase = `https://public-spaces-preview.pages.dev/`; // TODO: Change!
const api = new GhostContentAPI({
url: Secrets.ghost.url,
key: Secrets.ghost.key,
version: 'v5.0'
});
const posts = await api.posts.browse({
limit: 100,
include: ['authors', 'tags']
});
const feed = new Feed({
title: 'Public Spaces e.V.',
generator: 'Public Spaces e.V. Web',
description: 'Die neusten Beiträge von Public Spaces e.V.',
language: 'de-DE',
link: siteBase,
feedLinks: {
rss: `${siteBase}posts.rss`,
json: `${siteBase}posts.json`,
atom: `${siteBase}posts.atom`
},
id: siteBase,
copyright: ''
});
posts.forEach((post) => {
const date = DateTime.fromISO(post.updated_at || post.published_at || post.created_at || '');
const datePublished = DateTime.fromISO(post.published_at || post.created_at || '');
feed.addItem({
id: `${siteBase}post/${post.slug}`,
title: post.title || '',
link: `${siteBase}post/${post.slug}`,
date: date.toJSDate(),
published: datePublished.toJSDate(),
description: post.excerpt || '',
content: post.html || undefined,
author: post.authors?.map((author) => {
return {
name: author.name
};
})
});
});
switch (request.params.format) {
case 'rss':
return new Response(feed.rss2(), {
headers: {
'Content-Type': 'application/rss+xml'
}
});
case 'atom':
return new Response(feed.atom1(), {
headers: {
'Content-Type': 'application/atom+xml'
}
});
case 'json':
return new Response(feed.json1(), {
headers: {
'Content-Type': 'application/feed+json'
}
});
}
throw error(404, 'Ungültiges Format');
};

View file

@ -0,0 +1,26 @@
import Secrets from '$lib/server/secrets';
import { error } from '@sveltejs/kit';
import GhostContentAPI from '@tryghost/content-api';
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ params }) => {
const api = new GhostContentAPI({
url: Secrets.ghost.url,
key: Secrets.ghost.key,
version: 'v5.0'
});
let page = null;
try {
page = await api.pages.read({
slug: params.slug
});
} catch (e) {
throw error(404, 'Seite Nicht Gefunden');
}
return {
page
};
};

View file

@ -0,0 +1,31 @@
<script lang="ts">
import type { PageData } from './$types';
export let data: PageData;
</script>
<svelte:head>
<title>{data.page?.title}</title>
</svelte:head>
<div class="container">
<div class="header">
<h1>{data.page?.title}</h1>
</div>
<div class="page">
{@html data.page?.html}
</div>
</div>
<style lang="scss">
.page {
:global {
@include ghostContentContainer;
}
}
.header {
@include contentGrid;
}
</style>

24
src/routes/+error.svelte Normal file
View file

@ -0,0 +1,24 @@
<script lang="ts">
import { page } from '$app/stores';
const texts: { [key: number]: string } = {
0: 'Ein unbekannter Fehler ist aufgetreten',
404: 'Die angeforderte Seite wurde leider nicht gefunden.',
500: 'Es ist ein interner Serverfehler aufgetreten.'
};
</script>
<div class="container">
<h1>{$page.status}: {$page.error?.message}</h1>
<p>
{texts[$page.status] ?? texts[0]}
Bitte versuche es später erneut, oder gehe zurück zur <a href="/">Startseite</a>.
</p>
</div>
<style lang="scss">
.container {
@include contentGrid;
}
</style>

298
src/routes/+layout.svelte Normal file
View file

@ -0,0 +1,298 @@
<script lang="ts">
import { siTwitter, siInstagram, siTelegram } from 'simple-icons';
import { Menu, X } from 'lucide-svelte';
import Logo from '../assets/logo/LOGO-public-spaces.svg';
import { getContext } from 'svelte';
import '../app.scss';
import type { LayoutData } from './$types';
export let data: LayoutData;
let menuOpen = false;
</script>
<a href="#navigation" class="sr-only sr-only-focusable a11y-jump">Zur Navigation Springen</a>
<a href="#content" class="sr-only sr-only-focusable a11y-jump">Zum Inhalt Springen</a>
<div class="primary">
<nav id="navigation">
<div>
<div class="logo-container">
<a href="/" class="logo-link" title="Public Spaces e.V.">
<img src={Logo} alt="Public Spaces Logo" style={data.isHome ? "opacity: 0; transform: translate(20%, 50%)":""} />
<span class="sr-only">Public Spaces e.V.</span>
</a>
</div>
<div class={'offscreen-nav' + (menuOpen ? ' active' : '')}>
<a
href="/posts"
on:click={() => {
menuOpen = false;
}}>Beiträge</a
>
<a
href="/about"
on:click={() => {
menuOpen = false;
}}>Über Uns</a
>
<a
href="/contact"
on:click={() => {
menuOpen = false;
}}>Kontakt</a
>
</div>
<div class="offscreen-nav-button">
<button
on:click={() => {
menuOpen = !menuOpen;
}}
>
{#if !menuOpen}
<Menu size={35} />
{/if}
{#if menuOpen}
<X size={35} />
{/if}
</button>
</div>
</div>
</nav>
<div class="main" role="main" id="content">
<slot />
</div>
<footer>
<div class="grid">
<div class="primary-links">
<a href="/imprint">Impressum</a>
<a href="/data_protection">Datenschutz</a>
<a href="/disclaimer">Disclaimer</a>
</div>
<div class="border" />
<div class="socials">
<!--<a
href="https://twitter.com/TODO"
target="_blank"
rel="noreferrer"
title="Twitter"
>
{@html siTwitter.svg}
<span class="sr-only">Twitter @TODO</span>
</a>
<a
href="https://t.me/TODO"
target="_blank"
rel="noreferrer"
title="Telegram"
>
{@html siTelegram.svg}
<span class="sr-only">Telegram @TODO</span>
</a>-->
</div>
<div class="border" />
<div class="supporters">
<span class="title">Unterstützer des Vereins</span>
</div>
</div>
<div class="copy-notice">
CC-BY-4.0 {new Date().getFullYear()}, Public Spaces e.V.
</div>
</footer>
</div>
<style lang="scss">
.primary {
@include contentGrid;
padding-top: var(--nav-space);
.main {
grid-column: full-start/full-end;
min-height: calc(100vh - 200px);
}
footer {
margin-top: 4em;
background-color: var(--color-dark-surface);
color: var(--color-dark-surface-text);
grid-column: full-start/full-end;
@include contentGrid;
.grid {
grid-column: wide-start/wide-end;
display: grid;
grid-template-columns: 1fr 1px 1fr 1px 1fr;
gap: var(--gap);
@media (max-width: 700px) {
grid-template-columns: 1fr;
}
> .border {
width: 1px;
margin: 10px 0;
background-color: currentColor;
opacity: 0.25;
}
> :not(.border) {
padding: var(--gap);
}
.primary-links {
display: flex;
flex-direction: column;
align-items: center;
> a {
color: var(--color-dark-surface-text-dim);
}
}
.supporters {
.title {
color: var(--color-dark-surface-text-dim);
}
}
.socials {
display: flex;
justify-content: center;
a {
padding: var(--padding);
text-decoration: none;
background-color: var(--color-surface);
margin: var(--padding);
border-radius: var(--border-radius);
display: flex;
align-items: center;
justify-content: center;
:global(svg) {
width: 32px;
height: 32px;
fill: currentColor;
}
}
}
}
.copy-notice {
text-align: center;
padding: var(--gap);
}
}
nav {
@include contentGrid;
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 200;
overflow: visible;
@include glassSurface;
> div {
display: flex;
.logo-container {
margin-right: auto;
.logo-placeholder,
img {
transition: opacity .25s, transform .25s;
width: 100px;
height: 45px;
//background-color: var(--color-placeholder);
//border-radius: var(--border-radius);
}
}
.offscreen-nav-button {
width: 0;
pointer-events: none;
opacity: 0;
transition: width 0.25s, opacity 0.25s;
> button {
height: 100%;
padding: 0 var(--gap);
font: inherit;
color: inherit;
border: none;
cursor: pointer;
background-color: transparent;
}
}
@media (max-width: 700px) {
.offscreen-nav-button {
display: block;
z-index: 300;
pointer-events: auto;
width: fit-content;
opacity: 1;
}
.offscreen-nav {
//display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 195;
display: flex;
flex-direction: column;
padding-top: 110px;
font-size: 1.5em;
overflow: hidden;
pointer-events: none;
height: 0;
opacity: 0;
transition: height 0.25s, opacity 0.25s;
@include glassSurface;
&.active {
overflow: auto;
pointer-events: auto;
height: 100vh;
opacity: 1;
}
> a {
display: flex;
justify-content: center;
}
}
}
> div {
display: flex;
> a {
display: flex;
align-items: center;
padding: var(--padding);
text-decoration: none;
&.logo-link {
margin-right: auto;
}
}
}
}
}
}
.a11y-jump:focus,
.a11y-jump:active {
padding: var(--gap) !important;
background-color: var(--color-background);
z-index: 9999;
}
</style>

9
src/routes/+layout.ts Normal file
View file

@ -0,0 +1,9 @@
import type { LayoutLoad } from './$types';
export const load = (async ({url}) => {
return {
isHome: url.pathname == "/"
};
}) satisfies LayoutLoad;
export const prerender = true;

View file

@ -0,0 +1,24 @@
import type { PageServerLoad } from './$types';
import GhostContentAPI from '@tryghost/content-api';
import Secrets from '$lib/server/secrets';
export const load: PageServerLoad = async () => {
const api = new GhostContentAPI({
url: Secrets.ghost.url,
key: Secrets.ghost.key,
version: 'v5.0'
});
const posts = await api.posts.browse({
limit: 3,
include: ['authors', 'tags']
});
const about = await api.pages.read({
slug: 'about'
});
return { posts, about };
};

230
src/routes/+page.svelte Normal file
View file

@ -0,0 +1,230 @@
<script lang="ts">
import type { PageData } from './$types';
import { ChevronRight } from 'lucide-svelte';
import { DateTime } from 'luxon';
import { onDestroy, setContext, onMount, tick } from 'svelte';
import Logo from '../assets/logo/LOGO-public-spaces.svg';
import HWFLogo from '../assets/logo/LOGO-hamburg-werbefrei.svg';
import BWFLogo from '../assets/logo/LOGO-berlin-werbefrei.svg';
export let data: PageData;
</script>
<svelte:head>
<title>Public Spaces e.V.</title>
<meta name="title" content={'Public Spaces e.V.'} />
<meta
name="description"
content={'Public Spaces ist Trägerin zweier Voksinitiativen, die sich gegen ein Übermaß von Werbung im öffentlichen Raum richten.'}
/>
</svelte:head>
<div class="home-runner">
<div class="hero">
<div class="hero-runner">
<img src={Logo} alt="Public Spaces Logo" />
<div class="sub-logo-split">
<img src={BWFLogo} alt="Berlin Werbefrei Logo" />
<img src={HWFLogo} alt="Hamburg Werbefrei Logo" />
</div>
</div>
</div>
<h2>Über Public Spaces e.V.</h2>
<p>
Hier entsteht die Webseite des Vereins Public Spaces e.V.
</p>
<p>
Public Spaces ist Trägerin zweier Volksinitiativen, die sich gegen ein Übermaß von Werbung im öffentlichen Raum richten.
</p>
<a href="/about" class="more-cta">Mehr über uns <ChevronRight /></a>
<hr />
<h2>Neuste Beiträge</h2>
<div class="posts">
{#each data.posts as post}
<a href={`/posts/${post.slug}`}>
{#if !post.feature_image}
<div class="image-placeholder">?</div>
{/if}
{#if post.feature_image}
<img
src={post.feature_image}
alt={post.feature_image_alt || post.feature_image_caption || 'Article'}
/>
{/if}
<span class="title">{post.title}</span>
<p>{post.excerpt}</p>
</a>
{/each}
</div>
<a href="/posts" class="kg-btn">Alle Beiträge sehen</a>
<!--<a href="/about" class="more-cta">Alle Beiträge <ChevronRight/></a>-->
</div>
<style lang="scss">
.home-runner {
@include contentGrid;
margin-top: calc(0px - var(--nav-space));
}
.kg-btn {
margin: 20px auto;
}
.more-cta {
margin: var(--gap) var(--gap) var(--gap) auto;
display: flex;
justify-content: center;
align-items: center;
gap: var(--padding);
font-size: 1.2em;
text-decoration: none;
}
.posts {
grid-column: wide-start/wide-end;
display: flex;
gap: var(--gap);
margin-top: 1em;
> * {
flex-basis: 0;
flex-grow: 1;
width: 100px;
}
@media (max-width: 800px) {
flex-direction: column;
> * {
width: 100%;
}
}
> a {
text-decoration: none;
display: flex;
flex-direction: column;
img,
.image-placeholder {
width: 100%;
height: 230px;
background-color: var(--color-dark-surface);
border-radius: var(--border-radius);
}
.image-placeholder {
display: flex;
justify-content: center;
align-items: center;
font-size: 3em;
font-weight: 600;
color: grey;
}
.title {
font-size: 1.75em;
margin-top: 0.8em;
font-weight: 700;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
height: 40px;
}
p {
display: -webkit-box;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 4;
-webkit-box-orient: vertical;
overflow: hidden;
color: black;
}
}
}
.hero {
grid-column: full-start/full-end;
max-height: max(70vmin, 500px);
min-height: 100px;
height: 40vmax;
position: relative;
.hero-runner {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding-top: 50px;
z-index: 2;
display: flex;
flex-direction: column;
font-weight: 800;
text-transform: uppercase;
color: white;
align-items: center;
overflow: hidden;
> img {
flex-grow: 1;
flex-basis: 0;
object-fit: contain;
object-position: center;
max-height: 100%;
max-width: 100%;
height: 90%;
opacity: 1;
transform: translate(0, 0);
animation-name: homeLogoIn;
animation-duration: .25s;
}
.sub-logo-split {
margin-top: 20px;
height: 30%;
width: 100%;
margin: 0 auto;
max-width: var(--layout-width);
display: flex;
gap: var(--gap);
justify-content: space-around;
> img {
height: 100%;
object-fit: contain;
}
@media(max-width: 350px) {
flex-direction: column;
height: 50%;
}
}
}
}
@keyframes homeLogoIn {
0% {transform: translate(-10%, -25%); opacity: 0}
100% {transform: translate(0, 0); opacity: 1}
}
</style>

View file

@ -0,0 +1,18 @@
import type { PageServerLoad } from './$types';
import GhostContentAPI from '@tryghost/content-api';
import Secrets from '$lib/server/secrets';
export const load: PageServerLoad = async () => {
const api = new GhostContentAPI({
url: Secrets.ghost.url,
key: Secrets.ghost.key,
version: 'v5.0'
});
const posts = await api.posts.browse({
limit: 100,
include: ['authors', 'tags']
});
return { posts };
};

View file

@ -0,0 +1,127 @@
<script lang="ts">
import type { PageData } from './$types';
import { DateTime } from 'luxon';
export let data: PageData;
</script>
<svelte:head>
<title>Beiträge | Public Spaces e.V.</title>
<meta name="title" content={'Beiträge'} />
<meta
name="description"
content={'Lies die neusten Beiträge von Public Spaces e.V. Hier findest du Pressemitteilungen, Artikel und andere Inhalte.'}
/>
</svelte:head>
<div class="container">
<h1>Beiträge</h1>
<div class="posts">
{#each data.posts as post}
<a href={`/posts/` + post.slug}>
<div class="feature-image">
{#if post.feature_image}
<img
src={post.feature_image}
alt={post.feature_image_alt ||
post.feature_image_caption ||
post.title ||
'Feature Image'}
/>
{/if}
</div>
<div class="details">
<span class="title">{post.title}</span>
<span class="meta">
{#each post.authors || [] as author, i}
{i > 0 ? ' & ' : ''}<span>{author.name}</span>
{/each} &middot;
<span
>{DateTime.fromISO(post.published_at || post.created_at || '2001-11-03')
.setLocale('de-DE')
.toLocaleString(DateTime.DATE_FULL)}</span
>
&middot;
<span
>Ca. {post.reading_time || post.reading_time === 0
? Math.max(1, post.reading_time) + ' Min.'
: 'Unbekannte'} Lesezeit</span
>
</span>
{#if post.custom_excerpt || post.excerpt}
<p class="excerpt">
{(post.custom_excerpt || post.excerpt)?.replaceAll('\n', ' ')}
</p>
{/if}
</div>
</a>
{/each}
</div>
</div>
<style lang="scss">
.container {
@include contentGrid;
}
.posts {
> a {
display: flex;
gap: var(--gap);
padding: var(--gap) 0;
color: inherit;
text-decoration: none;
position: relative;
&::after {
position: absolute;
content: '';
display: block;
width: 90%;
margin: 0 auto;
bottom: 0;
left: 50%;
transform: translate(-50%, 0);
border-bottom: thin solid var(--color-border);
}
> .feature-image {
--size: 150px;
width: var(--size);
height: var(--size);
flex-shrink: 0;
> img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
}
}
> .details {
display: flex;
flex-direction: column;
> .title {
font-size: 1.6em;
font-weight: 600;
color: var(--color-accent);
}
> .meta {
opacity: 0.75;
margin-top: 5px;
font-weight: 300;
}
> .excerpt {
margin-bottom: 0;
}
}
}
}
</style>

View file

@ -0,0 +1,29 @@
import type { PageServerLoad } from './$types';
import GhostContentAPI from '@tryghost/content-api';
import Secrets from '$lib/server/secrets';
import { error } from '@sveltejs/kit';
export const load: PageServerLoad = async ({ params }) => {
const api = new GhostContentAPI({
url: Secrets.ghost.url,
key: Secrets.ghost.key,
version: 'v5.0'
});
let post = null;
try {
post = await api.posts.read(
{
slug: params.slug
},
{ include: ['tags', 'authors'] }
);
} catch (e) {
throw error(404, 'Artikel Nicht Gefunden');
}
return {
post
};
};

View file

@ -0,0 +1,216 @@
<script lang="ts">
import type { PageData } from './$types';
import { DateTime } from 'luxon';
import { Globe } from 'lucide-svelte';
import { siTwitter } from 'simple-icons';
export let data: PageData;
$: publishTime = DateTime.fromISO(data.post.published_at || data.post.created_at || '2001-11-03');
</script>
<svelte:head>
<title>{data.post.title}</title>
<meta name="title" content={data.post.meta_title || data.post.title} />
<meta
name="description"
content={data.post.meta_description || data.post.custom_excerpt || data.post.excerpt}
/>
<meta name="twitter:card" content="summary" />
<meta name="twitter:site" content="@todo" /> <!-- TODO: Change me. -->
<meta
name="twitter:title"
content={data.post.twitter_title || data.post.meta_title || data.post.title}
/>
<meta
name="twitter:description"
content={data.post.twitter_description ||
data.post.meta_description ||
data.post.custom_excerpt ||
data.post.excerpt}
/>
<meta name="twitter:image" content={data.post.twitter_image || data.post.feature_image} />
<meta property="og:type" content="article" />
<meta
property="og:title"
content={data.post.og_title || data.post.meta_title || data.post.title}
/>
<meta
property="og:description"
content={data.post.og_description ||
data.post.meta_description ||
data.post.custom_excerpt ||
data.post.excerpt}
/>
<meta
property="og:image"
content={data.post.og_image || data.post.twitter_image || data.post.feature_image}
/>
<meta property="article:published_time" content={data.post.published_at} />
{#if data.post.updated_at}
<meta property="article:modified_time" content={data.post.updated_at} />
{/if}
{#if data.post.primary_tag}
<meta
property="article:section"
content={data.post.primary_tag.og_title || data.post.primary_tag.name}
/>
{/if}
{@html `<script type="application/ld+json">${JSON.stringify({
'@context': 'https://schema.org',
'@type': 'Article',
headline: data.post.title,
image: data.post.feature_image,
datePublished: data.post.published_at,
dateModified: data.post.updated_at,
author: data.post.authors?.map((author) => {
return {
'@type': 'Person',
name: author.name
};
})
})}</script>`}
</svelte:head>
<div class="container">
<div class="header">
<h1>{data.post?.title}</h1>
<span class="meta">
<span>{publishTime.setLocale('de-DE').toLocaleString(DateTime.DATE_FULL)}</span> &middot;
<span
>Ca. {data.post.reading_time || data.post.reading_time === 0
? Math.max(1, data.post.reading_time) + ' Min.'
: 'Unbekannte'} Lesezeit</span
>
&middot;
<span>
{#each data.post.tags || [] as tag, i}
{i > 0 ? ', ' : ''}<span>{tag.name}</span><!--href={`/posts/` + tag.slug}-->
{/each}
</span>
</span>
{#if data.post.feature_image}
<div class="feature-image">
<figure>
<img src={data.post.feature_image} alt={data.post.feature_image_alt || 'Feature Image'} />
<figcaption>{@html data.post.feature_image_caption||""}</figcaption>
</figure>
</div>
{/if}
</div>
<div class="article">
{@html data.post?.html}
<!--<pre>{JSON.stringify(data.post, null, 2)}</pre>-->
</div>
<div class="authors">
<hr />
{#each data.post.authors || [] as author}
<div class="author">
<div class="pic">
{#if author.profile_image}
<img src={author.profile_image} alt={'Profilbild von ' + author.name} />
{/if}
{#if !author.profile_image}
<div class="photo-placeholder" />
{/if}
</div>
<div class="meta">
<span class="name">{author.name}</span>
<p>{author.bio || ''}</p>
<div class="links">
{#if author.website}
<a href={author.website}><Globe /> {new URL(author.website).host}</a>
{/if}
{#if author.twitter}
<a href={'https://twitter.com/' + author.twitter} class="twitter"
>{@html siTwitter.svg} {author.twitter}</a
>
{/if}
</div>
</div>
</div>
{/each}
</div>
</div>
<style lang="scss">
.article {
:global {
@include ghostContentContainer;
}
}
.authors {
@include contentGrid;
.author {
display: flex;
gap: var(--gap);
margin-bottom: var(--gap);
> * {
flex-grow: 0;
flex-shrink: 0;
}
.pic {
width: 125px;
img,
.photo-placeholder {
width: 125px;
height: 125px;
object-fit: cover;
object-position: center;
background-color: var(--color-dark-surface);
}
}
.meta {
width: 0;
flex-grow: 1;
padding: var(--padding);
.name {
font-size: 2em;
font-weight: 700;
}
p {
width: 100%;
}
.links {
display: flex;
gap: var(--gap);
a {
display: flex;
justify-content: center;
align-items: center;
:global(svg) {
width: 25px;
height: 25px;
margin-right: var(--padding);
}
&.twitter {
:global(svg) {
fill: currentColor;
}
}
}
}
}
}
}
.header {
@include articleHeader;
}
</style>

668
src/variables.scss Normal file
View file

@ -0,0 +1,668 @@
/* Variables and mixins declared here will be available in all other SCSS files */
@mixin ghostContentContainer {
@include contentGrid;
@include formatting;
}
@mixin glassSurface {
background-color: var(--color-background);
@supports (backdrop-filter: blur(10px)) {
backdrop-filter: blur(10px);
background-color: var(--color-glass-surface);
}
}
@mixin articleHeader {
@include contentGrid;
h1 {
text-align: center;
}
.meta {
text-align: center;
opacity: 0.75;
margin-bottom: 2em;
}
.feature-image {
//grid-column: wide-start/wide-end;
}
}
@mixin variables {
--nav-space: 120px;
--color-placeholder: gray;
--color-glass-surface: rgba(255, 255, 255, 0.75);
--color-background: white;
--color-text: #1c1c1c;
--color-accent: #1c1c1c;
--color-accent-contrast: white;
--color-border: rgba(0, 0, 0, 0.2);
--color-surface: rgba(127, 127, 127, 0.15);
--color-dark-surface: rgba(0, 0, 0, 0.9);
--color-dark-surface-text: white;
--color-dark-surface-text-dim: #808080;
--color-light-surface: rgba(255, 255, 255, 0.9);
--color-light-surface-text: var(--color-text);
--color-accent-surface: var(--color-accent);
--color-accent-surface-text: white;
--color-highlight-blue: rgba(10, 10, 255, 0.2);
--color-highlight-white: rgba(200, 200, 200, 0.2);
--color-highlight-grey: rgba(100, 100, 100, 0.2);
--color-highlight-yellow: rgba(255, 230, 10, 0.2);
--color-highlight-green: rgba(10, 255, 10, 0.2);
--color-highlight-red: rgba(255, 10, 10, 0.2);
--color-highlight-pink: rgba(255, 128, 255, 0.2);
--color-highlight-purple: rgba(204, 30, 152, 0.2);
--border-radius: 5px;
--gap: 20px;
--padding: 10px;
--layout-width: 720px;
--shadow-elevated: 4px 6px 20px rgba(0, 0, 0, 0.2);
}
@mixin contentGrid {
display: grid;
max-width: 100vw;
overflow: hidden;
> * {
max-width: min(100vw, 100%);
}
grid-template-columns:
[full-start] minmax(max(4vmin, var(--gap)), auto)
[wide-start] minmax(auto, 240px)
[main-start] min(var(--layout-width), calc(100% - max(8vmin, calc(var(--gap) * 2))))
[main-end] minmax(auto, 240px)
[wide-end] minmax(max(4vmin, var(--gap)), auto)
[full-end];
> :global(*) {
grid-column: main-start/main-end;
}
}
@mixin button {
text-decoration: none;
background-color: var(--color-dark-surface);
color: var(--color-dark-surface-text);
display: inline-block;
width: fit-content;
margin: 0 auto;
padding: 10px 20px;
border-radius: var(--border-radius);
}
@mixin formatting {
color: var(--color-text);
a,
abbr,
acronym,
address,
applet,
article,
aside,
audio,
big,
blockquote,
body,
canvas,
caption,
cite,
code,
dd,
del,
details,
dfn,
div,
dl,
dt,
em,
embed,
fieldset,
figcaption,
figure,
footer,
form,
h1,
h2,
h3,
h4,
h5,
h6,
header,
hgroup,
html,
iframe,
img,
ins,
kbd,
label,
legend,
li,
mark,
menu,
nav,
object,
ol,
output,
p,
pre,
q,
ruby,
s,
samp,
section,
small,
span,
strike,
strong,
sub,
summary,
sup,
table,
tbody,
td,
tfoot,
th,
thead,
time,
tr,
tt,
ul,
var,
video {
border: 0;
font: inherit;
font-size: 100%;
margin: 0;
padding: 0;
vertical-align: baseline;
}
pre {
overflow-x: auto;
}
p {
line-height: 1.7em;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 400;
margin-bottom: 0.5em;
margin-top: 1em;
}
h1 {
font-size: 3em;
&:first-child {
margin-top: 0;
}
}
h2 {
font-size: 2em;
}
h3 {
font-size: 1.7em;
}
h4 {
font-size: 1.4em;
}
h5 {
font-size: 1.25em;
}
h6 {
font-size: 1.15em;
}
hr {
border: 0;
border-bottom: thin dotted var(--color-border);
margin: 40px;
}
p {
margin: 20px 0;
}
img {
max-width: 100%;
object-fit: cover;
object-position: center;
border-radius: var(--border-radius);
}
a {
color: var(--color-accent);
text-decoration: underline dotted currentColor;
}
em {
font-style: italic;
}
dl {
padding: 0 20px;
dt {
color: var(--color-accent);
font-weight: 600;
margin-top: 10px;
}
dd {
margin-top: 10px;
margin-bottom: 20px;
}
}
li {
margin: 20px 10px;
}
table {
border-collapse: collapse;
border-spacing: 0;
display: inline-block;
overflow-x: auto;
max-width: 100%;
white-space: nowrap;
width: auto;
tr th {
border: 1px solid var(--color-border);
padding: 10px 16px;
background-color: var(--color-surface);
}
tr td {
border: 1px solid var(--color-border);
padding: 10px 16px;
}
}
code,
kbd,
pre,
samp {
font-size: 1em;
font-family: monospace;
}
pre {
background-color: var(--color-dark-surface);
color: var(--color-dark-surface-text);
border-radius: var(--border-radius);
padding: 2em;
}
:not(pre) > code,
kbd {
padding: 0.48em 0.5em;
line-height: 1em;
display: inline-block;
background-color: var(--color-surface);
border: thin solid var(--color-border);
border-radius: var(--border-radius);
}
kbd {
font-weight: 200;
font-family: monospace;
}
:not(pre) > code {
background-color: var(--color-surface);
border: thin solid var(--color-border);
border-radius: var(--border-radius);
}
blockquote:not([class]) {
font-style: italic;
padding: 0.5em 2em;
position: relative;
margin: 1em 0;
cite {
display: block;
margin-top: 0.75em;
padding-left: 1em;
}
&::before {
content: '';
position: absolute;
top: 0;
bottom: 0;
background: var(--color-accent);
left: -1em;
width: 0.2em;
}
}
mark {
position: relative;
background-color: transparent;
&::before {
content: '';
position: absolute;
top: -0.2em;
left: -0.2em;
right: -0.2em;
bottom: -0.2em;
background-color: var(--color-accent);
opacity: 0.25;
transform: skew(-6deg);
}
}
small {
font-size: 0.8em;
}
strong {
font-weight: 800;
}
sub,
sup {
font-size: 0.5;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25rem;
}
sup {
top: -0.25rem;
}
figure {
max-width: 100%;
img {
max-width: 100%;
height: auto;
}
> figcaption {
color: rgba(0, 0, 0, 0.5);
font-size: 0.9rem;
line-height: 1.4em;
padding: 1.1em 1.5em 1em;
text-align: center;
}
.kg-gallery-container {
.kg-gallery-row {
display: flex;
flex-direction: row;
justify-content: center;
gap: var(--gap);
margin: var(--gap) 0;
.kg-gallery-image {
> img {
height: 100%;
}
}
}
}
}
.kg-embed-card {
iframe {
width: 100%;
min-height: 400px;
}
}
.kg-card {
&.kg-style-dark {
background-color: var(--color-dark-surface);
color: var(--color-dark-surface-text);
}
&.kg-style-light {
background-color: var(--color-light-surface);
color: var(--color-light-surface-text);
}
&.kg-style-accent {
background-color: var(--color-accent-surface);
color: var(--color-accent-surface-text);
}
&.kg-style-image {
color: white;
text-shadow: 0 0 10px black;
}
}
.kg-align-center {
display: flex;
justify-content: center;
}
.kg-align-left {
display: flex;
justify-content: flex-start;
}
.kg-align-right {
display: flex;
justify-content: flex-end;
}
.kg-callout-card {
display: flex;
border-radius: var(--border-radius);
margin: 2em 0;
overflow: hidden;
background-color: var(--bg);
.kg-callout-emoji {
display: flex;
align-items: center;
padding: var(--gap);
font-size: 2em;
background-color: var(--bg);
}
.kg-callout-text {
//display: flex;
padding: var(--gap);
/*align-items: center;*/
align-self: center;
}
&.kg-callout-card-blue {
--bg: var(--color-highlight-blue);
}
&.kg-callout-card-white {
--bg: var(--color-highlight-white);
}
&.kg-callout-card-grey {
--bg: var(--color-highlight-grey);
}
&.kg-callout-card-yellow {
--bg: var(--color-highlight-yellow);
}
&.kg-callout-card-green {
--bg: var(--color-highlight-green);
}
&.kg-callout-card-red {
--bg: var(--color-highlight-red);
}
&.kg-callout-card-pink {
--bg: var(--color-highlight-pink);
}
&.kg-callout-card-purple {
--bg: var(--color-highlight-purple);
}
&.kg-callout-card-accent {
--bg: var(--color-accent-surface);
color: var(--color-accent-surface-text);
}
}
.kg-btn {
@include button;
background-color: var(--color-accent-surface);
color: var(--color-accent-surface-text);
margin: 1em 0;
}
.kg-header-card-button {
@include button;
}
.kg-header-card {
width: 100%;
text-align: center;
padding: 7em 0;
margin: 5em 0;
background-position: center;
background-size: cover;
display: flex;
flex-direction: column;
gap: var(--gap);
.kg-header-card-header {
font-size: 4em;
font-weight: 800;
margin: 0;
}
.kg-header-card-subheader {
margin: 0;
}
}
.kg-width-full {
grid-column: full-start/full-end;
img {
border-radius: 0;
}
}
.kg-width-wide {
grid-column: wide-start/wide-end;
}
figure.kg-bookmark-card {
a {
display: flex;
border-radius: var(--border-radius);
border: thin solid var(--color-border);
overflow: hidden;
color: inherit;
text-decoration: none;
.kg-bookmark-content {
display: flex;
flex-direction: column;
flex-grow: 1;
flex-basis: 100%;
align-items: flex-start;
justify-content: flex-start;
padding: var(--gap);
overflow: hidden;
.kg-bookmark-title {
font-size: 1.1rem;
line-height: 1.4em;
font-weight: 600;
}
.kg-bookmark-description {
display: -webkit-box;
line-height: 1.5em;
margin-top: 3px;
font-weight: 400;
max-height: 44px;
overflow-y: hidden;
opacity: 0.7;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.kg-bookmark-metadata {
display: flex;
margin-top: 2em;
white-space: nowrap;
> img {
width: 20px;
height: 20px;
margin-right: 6px;
}
> span {
opacity: 0.7;
text-overflow: ellipsis;
overflow: hidden;
max-width: 240px;
white-space: nowrap;
}
.kg-bookmark-publisher::before {
content: '';
margin: 0 6px;
}
}
}
.kg-bookmark-thumbnail {
position: relative;
flex-grow: 1;
min-width: 33%;
> img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
position: absolute;
top: 0;
left: 0;
}
}
}
}
}

BIN
static/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

33
svelte.config.js Normal file
View file

@ -0,0 +1,33 @@
//import adapter from '@sveltejs/adapter-auto';
import adapter from '@sveltejs/adapter-static';
import { vitePreprocess } from '@sveltejs/kit/vite';
import preprocess from 'svelte-preprocess';
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
// for more information about preprocessors
preprocess: [
vitePreprocess(),
preprocess({
scss: {
prependData: '@use "src/variables.scss" as *;'
},
preserve: ['ld+json']
})
],
kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter({
}),
prerender: {
entries: ['*', '/posts.rss', '/posts.atom', '/posts.json']
}
}
};
export default config;

17
tsconfig.json Normal file
View file

@ -0,0 +1,17 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true
}
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
//
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in
}

13
vite.config.ts Normal file
View file

@ -0,0 +1,13 @@
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [sveltekit()],
css: {
preprocessorOptions: {
scss: {
additionalData: '@use "src/variables.scss" as *;'
}
}
}
});

1629
yarn.lock Normal file

File diff suppressed because it is too large Load diff