Merge fix/cache-bust-and-source-leak
This commit is contained in:
commit
a6b17ff88d
24 changed files with 68 additions and 45 deletions
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
5
build.sh
5
build.sh
|
|
@ -6,3 +6,8 @@ for f in components tweaks-panel app; do
|
|||
npx -y esbuild@0.24 "$f.jsx" --loader:.jsx=jsx --jsx=transform --minify --target=es2020 --outfile="$f.min.js" --log-level=warning
|
||||
done
|
||||
node build-pages.mjs
|
||||
# Cache-bust: Cloudflare caches assets 4h; stamp content hashes into HTML refs.
|
||||
for a in components.min.js tweaks-panel.min.js app.min.js styles.css; do
|
||||
h=$(md5sum "$a" | cut -c1-8)
|
||||
find . -name index.html -not -path './node_modules/*' -exec sed -i -E "s#(\"/$a)(\?v=[0-9a-f]+)?\"#\1?v=$h\"#g" {} +
|
||||
done
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
<link rel="dns-prefetch" href="//vimeo.com" />
|
||||
<link rel="preload" as="image" href="/images/photos/production-switcher.jpg" fetchpriority="high" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
|
||||
<!-- Structured data -->
|
||||
|
|
@ -276,9 +276,9 @@
|
|||
|
||||
<script src="/data.js"></script>
|
||||
<script src="/projects-data.js"></script>
|
||||
<script src="/components.min.js"></script>
|
||||
<script src="/tweaks-panel.min.js"></script>
|
||||
<script src="/app.min.js"></script>
|
||||
<script src="/components.min.js?v=8bda577a"></script>
|
||||
<script src="/tweaks-panel.min.js?v=fe3876ca"></script>
|
||||
<script src="/app.min.js?v=41713656"></script>
|
||||
|
||||
<style>
|
||||
/* image treatments */
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
58
nginx.conf
58
nginx.conf
|
|
@ -1,6 +1,5 @@
|
|||
server {
|
||||
listen 43036 default_server;
|
||||
listen [::]:43036 default_server;
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
|
|
@ -9,33 +8,52 @@ server {
|
|||
charset utf-8;
|
||||
|
||||
gzip on;
|
||||
gzip_types text/plain text/css text/javascript application/javascript application/json image/svg+xml;
|
||||
gzip_types text/plain text/css text/javascript application/javascript application/json application/xml image/svg+xml;
|
||||
gzip_min_length 1024;
|
||||
gzip_comp_level 6;
|
||||
gzip_vary on;
|
||||
|
||||
# Long cache for static assets — they're content-addressed by path,
|
||||
# bust via filename when they change.
|
||||
location ~* \.(png|jpg|jpeg|gif|webp|svg|ico|woff2?|ttf)$ {
|
||||
expires 30d;
|
||||
# Security headers
|
||||
add_header X-Frame-Options SAMEORIGIN always;
|
||||
add_header X-Content-Type-Options nosniff always;
|
||||
add_header Referrer-Policy strict-origin-when-cross-origin always;
|
||||
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
||||
|
||||
# Vendored libs — versioned, cache hard
|
||||
location /vendor/ {
|
||||
expires 365d;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
# Short cache for the HTML/JS that drive the SPA so edits show up fast.
|
||||
location ~* \.(html|css|js|jsx)$ {
|
||||
expires 5m;
|
||||
# Images/fonts — long cache
|
||||
location ~* \.(png|jpg|jpeg|gif|webp|avif|svg|ico|woff2?|ttf)$ {
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, no-transform";
|
||||
}
|
||||
|
||||
# App JS/CSS — short cache so edits show fast
|
||||
location ~* \.(css|js)$ {
|
||||
expires 10m;
|
||||
add_header Cache-Control "public, must-revalidate";
|
||||
}
|
||||
|
||||
# Single-page app — unknown paths fall back to index.html, which
|
||||
# handles routing via location.hash (#/projects/<slug>).
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
# Never serve build sources, docs, or deploy config
|
||||
location ~* (\.(jsx|mjs|py|sh|md|ya?ml|conf|tgz)|/Dockerfile)$ { return 404; }
|
||||
location ~ /\. { return 404; }
|
||||
location /scripts/ { return 404; }
|
||||
|
||||
# Crawler files.
|
||||
location = /llms.txt { default_type text/plain; }
|
||||
location = /robots.txt { default_type text/plain; }
|
||||
location = /robots.txt { default_type text/plain; }
|
||||
location = /llms.txt { default_type text/plain; }
|
||||
location = /sitemap.xml { default_type application/xml; }
|
||||
|
||||
# Source maps / raw sources aren't shipped; keep vendor un-listed.
|
||||
location /vendor/ { autoindex off; }
|
||||
# HTML — no stale cache
|
||||
location = /index.html {
|
||||
add_header Cache-Control "no-cache, must-revalidate";
|
||||
}
|
||||
|
||||
# Real 404s for unknown paths (SPA routes via location.hash, so / covers them).
|
||||
# ponytail: plain nginx 404 page; add a branded 404.html if traffic warrants it
|
||||
location / {
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<link rel="icon" href="/images/dragon-mark.png" type="image/png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<link rel="stylesheet" href="/styles.css?v=01730c57">
|
||||
<style>:root{--font-inter:"Inter";--font-mono-stack:"JetBrains Mono"}</style>
|
||||
<style>
|
||||
.sp-nav{background:var(--color-primary);padding:1.1rem 0}.sp-nav-inner{display:flex;align-items:center;justify-content:space-between}
|
||||
|
|
|
|||
Loading…
Reference in a new issue