-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
86 lines (86 loc) · 3.99 KB
/
Copy pathindex.html
File metadata and controls
86 lines (86 loc) · 3.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<!--
╔══════════════════════════════════════╗
║ Ryan Wetzstein ║
║ Personal Website ║
║ 2026 ║
╚══════════════════════════════════════╝
-->
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="manifest" href="/manifest.json" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- GitHub Pages cannot set response headers, so policy is delivered via meta.
'unsafe-inline' on style-src is required by the inline-style patterns this app
uses; script-src stays strict (no inline, no eval) - verified: the built
bundles contain no eval/Function constructor.
NOTE: per CSP spec, frame-ancestors is IGNORED when delivered via <meta>. It is
kept here so the policy is correct if this ever moves behind a host/proxy that
can send real headers, but clickjacking is NOT actually blocked on Pages today.
Same caveat applies to report-uri and sandbox. -->
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self';
style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net;
font-src 'self' https://cdn.jsdelivr.net data:;
img-src 'self' data: blob: https://img.youtube.com https://i.ytimg.com https://i1.sndcdn.com https://i.sndcdn.com;
media-src 'self' blob:;
connect-src 'self' blob: https://api.github.com;
frame-src https://www.youtube-nocookie.com https://www.youtube.com https://w.soundcloud.com;
worker-src 'self' blob:;
object-src 'none';
base-uri 'none';
form-action 'none';
frame-ancestors 'none';
upgrade-insecure-requests"
/>
<meta name="referrer" content="strict-origin-when-cross-origin" />
<meta name="theme-color" content="#181d26" />
<title>Ryan Wetzstein</title>
<meta name="description" content="Ryan's personal portfolio — software developer building clean, modern web experiences." />
<meta property="og:title" content="Ryan Wetzstein" />
<meta property="og:description" content="Software developer building clean, modern web experiences." />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://ryanwetzstein.com" />
<meta property="og:image" content="/og-image.png" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Ryan Wetzstein" />
<meta name="twitter:description" content="Software developer building clean, modern web experiences." />
<!-- Pinned + Subresource Integrity: a tampered CDN response is rejected by the browser.
Never use @latest here — it lets upstream change what executes on this origin. -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/devicons/devicon@v2.17.0/devicon.min.css"
integrity="sha384-6iv3tXABd3c9DYulXujJl8n22ahn/12f45MomxoPv6jBX4LBE4gNJjfkx5mAKIqR"
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
<!-- Skip navigation for keyboard users -->
<style>
.skip-nav {
position: absolute;
top: -100%;
left: 1rem;
z-index: 9999;
padding: 0.5rem 1rem;
background: #181d26;
color: #fff;
border-radius: 0 0 0.5rem 0.5rem;
font-size: 0.875rem;
text-decoration: none;
transition: top 0.2s;
}
.skip-nav:focus {
top: 0;
}
</style>
</head>
<body>
<a href="#main-content" class="skip-nav">Skip to main content</a>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>