diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro
index 03a6f07..b9591bf 100644
--- a/src/layouts/BaseLayout.astro
+++ b/src/layouts/BaseLayout.astro
@@ -143,6 +143,7 @@ const currentYear = new Date().getFullYear();
+
+
diff --git a/src/styles/site.css b/src/styles/site.css
index 926a1f7..ca4f5e3 100644
--- a/src/styles/site.css
+++ b/src/styles/site.css
@@ -2243,6 +2243,165 @@ meting-js {
border-color: rgba(174, 205, 197, 0.2);
}
+.external-redirect {
+ width: min(760px, calc(100% - (var(--page-gutter) * 2)));
+ min-height: calc(100vh - 240px);
+ margin: 42px auto 80px;
+ display: grid;
+ place-items: center;
+}
+
+.external-redirect-panel {
+ width: 100%;
+ overflow: hidden;
+ border: 1px solid rgba(255, 255, 255, 0.58);
+ border-radius: 8px;
+ padding: clamp(26px, 6vw, 48px);
+ background:
+ radial-gradient(circle at 15% 0%, rgba(255, 255, 255, 0.74), transparent 36%),
+ linear-gradient(145deg, rgba(255, 255, 255, 0.7), rgba(226, 248, 241, 0.42)),
+ rgba(255, 253, 248, 0.78);
+ box-shadow:
+ inset 0 1px 0 rgba(255, 255, 255, 0.82),
+ 0 24px 64px rgba(44, 55, 63, 0.16);
+ backdrop-filter: blur(18px) saturate(165%);
+ -webkit-backdrop-filter: blur(18px) saturate(165%);
+}
+
+.external-redirect-eyebrow {
+ margin: 0 0 10px;
+ color: var(--accent);
+ font-size: 0.88rem;
+ font-weight: 800;
+}
+
+.external-redirect h1 {
+ margin: 0;
+ color: #20242a;
+ font-size: clamp(2rem, 6vw, 3.8rem);
+ line-height: 1.08;
+}
+
+.external-redirect-copy {
+ max-width: 620px;
+ margin: 16px 0 0;
+ color: var(--muted);
+ font-size: 1rem;
+}
+
+.external-redirect-target {
+ display: grid;
+ gap: 8px;
+ margin-top: 24px;
+ border: 1px solid rgba(15, 118, 110, 0.16);
+ border-radius: 8px;
+ padding: 14px 16px;
+ background: rgba(236, 253, 245, 0.64);
+}
+
+.external-redirect-target span {
+ color: var(--accent);
+ font-size: 0.84rem;
+ font-weight: 800;
+}
+
+.external-redirect-target code {
+ overflow-wrap: anywhere;
+ color: #33433f;
+ font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace;
+ font-size: 0.92rem;
+}
+
+.external-redirect-countdown {
+ position: relative;
+ width: 112px;
+ height: 112px;
+ margin-top: 26px;
+}
+
+.external-redirect-countdown svg {
+ width: 112px;
+ height: 112px;
+ transform: rotate(-90deg);
+}
+
+.external-redirect-countdown circle {
+ fill: none;
+ stroke: rgba(15, 118, 110, 0.14);
+ stroke-width: 10;
+}
+
+.external-redirect-countdown circle:last-child {
+ stroke: #3eb8be;
+ stroke-linecap: round;
+ transition: stroke-dashoffset 0.9s linear;
+}
+
+.external-redirect-countdown strong {
+ position: absolute;
+ inset: 0;
+ display: grid;
+ place-items: center;
+ color: #2f4358;
+ font-size: 2rem;
+ line-height: 1;
+}
+
+.external-redirect-actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 12px;
+ margin-top: 28px;
+}
+
+.external-redirect-button {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-height: 44px;
+ border: 1px solid rgba(15, 118, 110, 0.2);
+ border-radius: 8px;
+ padding: 9px 16px;
+ color: var(--accent);
+ font-weight: 800;
+ background: rgba(236, 253, 245, 0.68);
+ transition:
+ color 0.2s ease,
+ background-color 0.2s ease,
+ transform 0.2s ease;
+}
+
+.external-redirect-button:hover,
+.external-redirect-button.is-primary {
+ color: #fff;
+ background: #3eb8be;
+ transform: translateY(-1px);
+}
+
+:root[data-theme='dark'] .external-redirect-panel {
+ border-color: rgba(174, 205, 197, 0.18);
+ background:
+ radial-gradient(circle at 14% 0%, rgba(114, 222, 210, 0.1), transparent 34%),
+ linear-gradient(145deg, rgba(28, 43, 47, 0.82), rgba(12, 22, 25, 0.72)),
+ rgba(17, 28, 31, 0.74);
+ box-shadow: var(--shadow);
+}
+
+:root[data-theme='dark'] .external-redirect h1,
+:root[data-theme='dark'] .external-redirect-countdown strong {
+ color: #edf7f5;
+}
+
+:root[data-theme='dark'] .external-redirect-target,
+:root[data-theme='dark'] .external-redirect-button {
+ border-color: rgba(114, 222, 210, 0.22);
+ background: rgba(114, 222, 210, 0.1);
+}
+
+:root[data-theme='dark'] .external-redirect-target code {
+ color: #dce9e6;
+}
+
.site-footer {
position: relative;
margin-top: 64px;
diff --git a/static/js/external-links.js b/static/js/external-links.js
new file mode 100644
index 0000000..3068a67
--- /dev/null
+++ b/static/js/external-links.js
@@ -0,0 +1,45 @@
+(() => {
+ const redirectPath = '/go/';
+ const urlParams = new URLSearchParams(window.location.search);
+
+ if (window.location.pathname === redirectPath || window.location.pathname === '/go') return;
+ if (urlParams.get('noExternalRedirect') === '1') return;
+
+ function getExternalUrl(anchor) {
+ const href = anchor.getAttribute('href');
+ if (!href || href.startsWith('#')) return null;
+
+ let targetUrl;
+ try {
+ targetUrl = new URL(href, window.location.href);
+ } catch {
+ return null;
+ }
+
+ if (!['http:', 'https:'].includes(targetUrl.protocol)) return null;
+ if (targetUrl.origin === window.location.origin) return null;
+
+ return targetUrl.href;
+ }
+
+ document.addEventListener('click', (event) => {
+ const anchor = event.target.closest?.('a[href]');
+ if (!anchor) return;
+ if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
+
+ const externalUrl = getExternalUrl(anchor);
+ if (!externalUrl) return;
+
+ event.preventDefault();
+
+ const redirectUrl = `${redirectPath}?url=${encodeURIComponent(externalUrl)}`;
+ const target = anchor.getAttribute('target');
+
+ if (target && target !== '_self') {
+ window.open(redirectUrl, target, 'noopener,noreferrer');
+ return;
+ }
+
+ window.location.href = redirectUrl;
+ });
+})();