The Sirius.X / Theseus.X / Ariadne.X / Hephaestus.X links in the family topnavs and body copy were written as full https URLs — href="https://sirius.x/". In Theseus's own browser (where the current page is served over the bns:// scheme) that absolute URL triggers the gateway-fallback path on top of the current host, producing URLs like bns://theseus.x/bns/sirius.x/ that then accumulate segments as the user clicks around. Switched 56 cross-family link hrefs to protocol-relative (href="//sirius.x/" etc.). Protocol-relative URLs inherit the scheme of the current page, so: - In Theseus on bns://theseus.x/ the link resolves to bns://sirius.x/ — direct BCNR, no gateway rewrite, no URL accumulation. - On the silentmode.st ICANN mirror it resolves to https://sirius.x/ — unchanged from the previous behaviour. Only the four sibling .X hosts were swapped; silentmode.st, dl.silentmode.st, code.silentmode.st, navigate.st, and every forge or API URL still carry their explicit scheme.
353 lines
20 KiB
HTML
353 lines
20 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>Brand — Theseus.X</title>
|
||
<meta name="description" content="Theseus.X brand kit — compass mark, wordmark, avatar, banner, favicon, colour palette, and usage guidance. All assets served as SVG so they stay crisp at any size.">
|
||
<link rel="icon" href="./favicon.svg" type="image/svg+xml">
|
||
<link rel="mask-icon" href="./favicon.svg" color="#d6ff3d">
|
||
<meta property="og:type" content="website">
|
||
<meta property="og:site_name" content="Theseus.X">
|
||
<meta property="og:title" content="Theseus.X brand kit">
|
||
<meta property="og:description" content="Compass mark, wordmark, avatar, banner, favicon, colour palette. All SVG, downloadable. The marks are reserved: use them to refer to Theseus, not as your own.">
|
||
<meta property="og:url" content="https://theseus.x/brand/">
|
||
<meta property="og:image" content="https://theseus.x/brand/banner.svg">
|
||
<meta name="twitter:card" content="summary_large_image">
|
||
<style>
|
||
:root{
|
||
--bg:#0b0e14; --panel:#141a24; --panel2:#18202c; --line:rgba(255,255,255,.09);
|
||
--ink:#e7eaf1; --mut:#8b98a9; --dim:#5e6678; --acid:#d6ff3d;
|
||
--bearing:#e04e4e;
|
||
}
|
||
*{box-sizing:border-box}
|
||
html{scroll-behavior:smooth}
|
||
body{margin:0;background:radial-gradient(1100px 560px at 50% -12%,#16202e,var(--bg));
|
||
color:var(--ink);font:16px/1.65 system-ui,-apple-system,Segoe UI,Roboto,sans-serif;min-height:100vh}
|
||
a{color:var(--acid)}
|
||
.wrap{max-width:1040px;margin:0 auto;padding:0 1.2rem}
|
||
|
||
.topnav{position:fixed;top:0;left:0;right:0;z-index:20;display:flex;gap:2px;align-items:center;flex-wrap:wrap;
|
||
padding:10px 1.2rem;background:rgba(11,14,20,.88);backdrop-filter:blur(10px)}
|
||
.topnav .brand{font-weight:600;color:var(--ink);text-decoration:none;margin-right:14px;font-size:15px;letter-spacing:.2px;display:flex;align-items:center;gap:8px}
|
||
.topnav .brand .g{color:var(--acid)}
|
||
.topnav .brand svg{width:20px;height:20px}
|
||
.topnav a{color:var(--mut);text-decoration:none;padding:6px 12px;border-radius:8px;font-size:14px;
|
||
display:inline-flex;align-items:center;gap:6px}
|
||
.topnav a:hover{color:var(--ink);background:var(--panel)}
|
||
.topnav a.here{color:var(--acid);background:rgba(214,255,61,.08)}
|
||
.topnav a.get{margin-left:auto;background:rgba(214,255,61,.10);color:var(--acid);font-weight:500}
|
||
.topnav a.get:hover{background:rgba(214,255,61,.18)}
|
||
.topnav a .g{color:var(--acid)}
|
||
.topnav a svg.tabicon{width:15px;height:15px;flex:none}
|
||
|
||
/* Mobile hamburger — matches the home-page pattern. */
|
||
.topnav .menu{display:none}
|
||
@media (max-width:720px){
|
||
.topnav{flex-wrap:nowrap;padding:10px 1rem}
|
||
.topnav .brand{margin-right:0}
|
||
.topnav > a:not(.brand){display:none}
|
||
.topnav .menu{display:block;margin-left:auto;position:relative}
|
||
.topnav .menu > summary{list-style:none;cursor:pointer;padding:8px 10px;
|
||
border-radius:8px;color:var(--mut);display:inline-flex;align-items:center;gap:6px}
|
||
.topnav .menu > summary::-webkit-details-marker{display:none}
|
||
.topnav .menu > summary svg{width:22px;height:22px;display:block}
|
||
.topnav .menu > summary:hover,
|
||
.topnav .menu[open] > summary{color:var(--ink);background:var(--panel)}
|
||
.topnav .menu .menu-panel{position:absolute;top:calc(100% + 6px);right:0;
|
||
background:var(--bg);border:1px solid var(--line);border-radius:12px;
|
||
padding:6px;min-width:220px;display:flex;flex-direction:column;gap:2px;
|
||
box-shadow:0 10px 32px rgba(0,0,0,.55)}
|
||
.topnav .menu .menu-panel a{padding:10px 14px;border-radius:8px;font-size:14.5px;
|
||
color:var(--mut);text-decoration:none;display:flex;align-items:center;gap:8px}
|
||
.topnav .menu .menu-panel a:hover{color:var(--ink);background:var(--panel)}
|
||
}
|
||
|
||
/* Sidebar overlay — same shape as index.html */
|
||
:root{--sn-w:200px;--tn-h:52px}
|
||
body{padding-top:var(--tn-h)}
|
||
.sidenav{position:fixed;top:var(--tn-h);left:0;bottom:0;width:var(--sn-w);z-index:15;
|
||
background:transparent;padding:32px 12px 22px 18px;
|
||
overflow-y:auto;pointer-events:none;transition:width .15s ease}
|
||
.sidenav a{display:flex;align-items:center;gap:14px;color:var(--mut);text-decoration:none;
|
||
padding:9px 12px;border-radius:10px;
|
||
font-size:14.5px;font-weight:500;opacity:.35;pointer-events:auto;
|
||
transition:opacity .12s,color .12s,background .12s,backdrop-filter .12s}
|
||
.sidenav a .ic{flex:none;width:22px;font-size:18px;line-height:1;text-align:center;
|
||
display:none;justify-content:center;align-items:center}
|
||
.sidenav a .lb{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.sidenav a:hover{opacity:1;color:var(--ink);background:rgba(11,14,20,.72);backdrop-filter:blur(8px)}
|
||
.sidenav a.active{opacity:.85;color:var(--acid)}
|
||
.sidenav a.active:hover{opacity:1}
|
||
section{scroll-margin-top:70px}
|
||
@media (max-width:1180px){
|
||
:root{--sn-w:64px}
|
||
.sidenav{padding:22px 6px}
|
||
.sidenav a{justify-content:center;padding:12px 4px;gap:0}
|
||
.sidenav a .ic{display:inline-flex}
|
||
.sidenav a .lb{display:none}
|
||
}
|
||
@media (max-width:720px){
|
||
:root{--sn-w:0}
|
||
body{padding-bottom:64px}
|
||
.sidenav{top:auto;bottom:0;left:0;right:0;width:100%;height:auto;
|
||
padding:4px;flex-direction:row;background:rgba(11,14,20,.94);backdrop-filter:blur(12px);
|
||
display:flex;justify-content:space-around;overflow-x:auto;
|
||
scrollbar-width:none;-ms-overflow-style:none}
|
||
.sidenav::-webkit-scrollbar{display:none;width:0;height:0}
|
||
.sidenav a{flex:1;min-width:44px;padding:8px 4px;justify-content:center;gap:0;opacity:.5;font-size:15px}
|
||
.sidenav a .ic{display:inline-flex}
|
||
.sidenav a .lb{display:none}
|
||
}
|
||
|
||
header.hero{text-align:center;padding:3.5rem 1.2rem 1rem}
|
||
.mark{font-size:44px;line-height:1}
|
||
h1{font-size:clamp(1.7rem,4.6vw,2.3rem);margin:.3rem 0 .3rem}
|
||
h1 .g{color:var(--acid)}
|
||
.tag{color:var(--mut);font-size:1.02rem;max-width:640px;margin:0 auto}
|
||
section{padding:2.2rem 0;border-top:1px solid var(--line);margin-top:2rem}
|
||
section:first-of-type{border-top:none;margin-top:1.2rem}
|
||
h2{font-size:1.35rem;margin:0 0 .35rem}
|
||
h3{font-size:1rem;margin:0 0 .3rem}
|
||
.lede{color:var(--mut);margin:0 0 1.4rem;max-width:720px}
|
||
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:14px}
|
||
.asset{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:14px 16px 16px;display:flex;flex-direction:column}
|
||
.asset .preview{background:var(--panel2);border:1px solid var(--line);border-radius:10px;padding:20px;
|
||
margin-bottom:12px;min-height:130px;display:flex;align-items:center;justify-content:center}
|
||
.asset .preview.wide{padding:0}
|
||
.asset .preview.wide img{width:100%;height:auto;display:block;border-radius:9px}
|
||
.asset .preview.avatar{padding:0}
|
||
.asset .preview.avatar img{width:104px;height:104px;display:block;border-radius:20px}
|
||
.asset .preview.favicon img{width:64px;height:64px;display:block}
|
||
.asset .preview.mono{background:#eef1f7;color:#0b0e14}
|
||
.asset h3{display:flex;align-items:center;justify-content:space-between;gap:10px}
|
||
.asset .meta{color:var(--dim);font-size:12.5px;margin:2px 0 10px;font-family:ui-monospace,monospace}
|
||
.asset .row{display:flex;gap:8px;flex-wrap:wrap;margin-top:auto}
|
||
.btn{display:inline-block;text-decoration:none;padding:6px 12px;border-radius:8px;background:transparent;
|
||
border:1px solid var(--line);color:var(--ink);font-size:12.5px;font-family:inherit;cursor:pointer}
|
||
.btn:hover{background:var(--panel2)}
|
||
.btn.acid{background:var(--acid);color:#0b0e14;border-color:var(--acid);font-weight:600}
|
||
.btn.acid:hover{filter:brightness(1.1)}
|
||
.swatches{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;margin-top:1rem}
|
||
.sw{border:1px solid var(--line);border-radius:10px;overflow:hidden}
|
||
.sw .chip{height:70px}
|
||
.sw .info{padding:10px 12px;font-size:12.5px;font-family:ui-monospace,monospace;color:var(--mut)}
|
||
.sw .info b{color:var(--ink);display:block;font-family:inherit}
|
||
.note{background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--acid);
|
||
border-radius:10px;padding:12px 15px;color:var(--mut);font-size:13.5px;margin-top:1.2rem}
|
||
.note b{color:var(--ink)}
|
||
code{background:#0e131b;border:1px solid var(--line);border-radius:6px;padding:1px 6px;font-family:ui-monospace,monospace;font-size:12.5px;word-break:break-all}
|
||
footer{border-top:1px solid var(--line);padding:2rem 0 3rem;color:var(--dim);font-size:13px;text-align:center;margin-top:2.5rem}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<nav class="topnav">
|
||
<a class="brand" href="../">
|
||
<svg viewBox="0 0 64 64" aria-hidden="true">
|
||
<rect width="64" height="64" rx="12" fill="#0b0e14"/>
|
||
<path d="M32 6 L38 32 L26 32 Z" fill="#e04e4e"/>
|
||
<path d="M38 32 L32 58 L26 32 Z" fill="#d6ff3d"/>
|
||
<path d="M6 32 L32 27 L58 32 L32 37 Z" fill="#d6ff3d" opacity=".55"/>
|
||
<circle cx="32" cy="32" r="3" fill="#0b0e14"/>
|
||
</svg>
|
||
<span>Theseus<span class="g">.X</span></span>
|
||
</a>
|
||
<a href="../plug-ins/">Plug-ins</a>
|
||
<a href="../extensions/">Extensions</a>
|
||
<a href="../dev/">Developers</a>
|
||
<a href="//sirius.x/" title="Register a BCNR name"><svg class="tabicon" viewBox="0 0 64 64" aria-hidden="true"><rect width="64" height="64" rx="12" fill="#0b0e14"/><path d="M32 4 L36.4 27.6 L60 32 L36.4 36.4 L32 60 L27.6 36.4 L4 32 L27.6 27.6 Z" fill="#d6ff3d"/></svg><span>Sirius<span class="g">.X</span></span></a>
|
||
<a class="get" href="../#download">Get Theseus</a>
|
||
<details class="menu">
|
||
<summary aria-label="Open menu">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M4 7h16M4 12h16M4 17h16"/></svg>
|
||
</summary>
|
||
<div class="menu-panel">
|
||
<a href="../plug-ins/">Plug-ins</a>
|
||
<a href="../extensions/">Extensions</a>
|
||
<a href="../dev/">Developers</a>
|
||
<a href="//sirius.x/">Sirius.X</a>
|
||
</div>
|
||
</details>
|
||
</nav>
|
||
|
||
<aside class="sidenav" aria-label="On this page">
|
||
<a href="#logo" title="Compass mark & wordmark"><span class="ic" aria-hidden="true">🧭</span><span class="lb">Logo</span></a>
|
||
<a href="#avatar" title="Avatar & favicon" ><span class="ic" aria-hidden="true">🎭</span><span class="lb">Avatar</span></a>
|
||
<a href="#banner" title="Social banner" ><span class="ic" aria-hidden="true">🖼</span><span class="lb">Banner</span></a>
|
||
<a href="#palette" title="Colour palette" ><span class="ic" aria-hidden="true">🎨</span><span class="lb">Palette</span></a>
|
||
<a href="#typography" title="Typography" ><span class="ic" aria-hidden="true">🅰️</span><span class="lb">Typography</span></a>
|
||
<a href="#usage" title="Usage & trademark" ><span class="ic" aria-hidden="true">📜</span><span class="lb">Usage</span></a>
|
||
</aside>
|
||
|
||
<header class="hero">
|
||
<div class="mark">🎨</div>
|
||
<h1>Theseus.X <span class="g">brand kit</span></h1>
|
||
<p class="tag">The Navigator compass mark, wordmark, avatar, banner, favicon, and colour palette.
|
||
Every asset ships as SVG so it stays crisp at any size and reads correctly in light and dark
|
||
contexts. Free to reuse with attribution.</p>
|
||
</header>
|
||
|
||
<div class="wrap">
|
||
|
||
<section id="logo">
|
||
<h2>Compass mark & wordmark</h2>
|
||
<p class="lede">A rounded dark square with a compass rose — north half in bearing red like every
|
||
real compass needle, south half in Silent Mode acid green, softened east-west arm so the N-S
|
||
bearing dominates. Plus <b>theseus.x</b> with the <code>.x</code> TLD picked out in acid. The
|
||
mark alone works when you have no room for the wordmark; the full lockup is the default choice
|
||
everywhere else.</p>
|
||
<div class="grid">
|
||
<div class="asset">
|
||
<div class="preview"><img src="./logo.svg" alt="theseus.x logo" style="max-width:100%;height:auto"></div>
|
||
<h3>Wordmark <span class="meta">SVG · 320×64</span></h3>
|
||
<p class="lede" style="margin-bottom:.6rem">Full colour, dark backgrounds. Use this by default.</p>
|
||
<div class="row">
|
||
<a class="btn acid" href="./logo.svg" download>Download SVG</a>
|
||
<a class="btn" href="./logo.svg" target="_blank">Open</a>
|
||
</div>
|
||
</div>
|
||
<div class="asset">
|
||
<div class="preview mono" style="color:#0b0e14"><img src="./logo-mono.svg" alt="theseus.x mono" style="max-width:100%;height:auto;color:inherit"></div>
|
||
<h3>Wordmark, monochrome <span class="meta">SVG · currentColor</span></h3>
|
||
<p class="lede" style="margin-bottom:.6rem">Uses <code>currentColor</code>, inherits from the
|
||
surrounding text. Print, embossing, single-colour merch.</p>
|
||
<div class="row">
|
||
<a class="btn acid" href="./logo-mono.svg" download>Download SVG</a>
|
||
<a class="btn" href="./logo-mono.svg" target="_blank">Open</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="avatar">
|
||
<h2>Avatar & favicon</h2>
|
||
<p class="lede">Square icons for social profiles, Nostr, GitHub, and browser tabs.</p>
|
||
<div class="grid">
|
||
<div class="asset">
|
||
<div class="preview avatar"><img src="./avatar.svg" alt="theseus.x avatar"></div>
|
||
<h3>Avatar <span class="meta">SVG · 512×512</span></h3>
|
||
<p class="lede" style="margin-bottom:.6rem">Square profile picture. Social platforms apply
|
||
their own round mask; the corner radius keeps the compass intact when clipped.</p>
|
||
<div class="row">
|
||
<a class="btn acid" href="./avatar.svg" download>Download SVG</a>
|
||
<a class="btn" href="./avatar.svg" target="_blank">Open</a>
|
||
</div>
|
||
</div>
|
||
<div class="asset">
|
||
<div class="preview favicon"><img src="./favicon.svg" alt="theseus.x favicon"></div>
|
||
<h3>Favicon <span class="meta">SVG · 64×64, 12px radius</span></h3>
|
||
<p class="lede" style="margin-bottom:.6rem">Rounded browser-tab icon. Scales down to 16×16
|
||
cleanly; used on every Theseus.X page.</p>
|
||
<div class="row">
|
||
<a class="btn acid" href="./favicon.svg" download>Download SVG</a>
|
||
<a class="btn" href="./favicon.svg" target="_blank">Open</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="banner">
|
||
<h2>Social banner</h2>
|
||
<p class="lede">1200×630 (OpenGraph / Twitter Card canonical). Composition survives aggressive
|
||
centre-cropping — the compass mark and tagline both stay visible even after Facebook and Discord
|
||
chop the sides.</p>
|
||
<div class="asset">
|
||
<div class="preview wide"><img src="./banner.svg" alt="theseus.x banner"></div>
|
||
<div class="row">
|
||
<a class="btn acid" href="./banner.svg" download>Download SVG</a>
|
||
<a class="btn" href="./banner.svg" target="_blank">Open</a>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="palette">
|
||
<h2>Colour palette</h2>
|
||
<p class="lede">Silent Mode family colours. Dark chromes are the default; acid green is the
|
||
accent that signals "this is Theseus.X", and bearing red is reserved for the compass mark's
|
||
north triangle — never used for links, buttons, or generic UI accents.</p>
|
||
<div class="swatches">
|
||
<div class="sw"><div class="chip" style="background:#d6ff3d"></div><div class="info"><b>Acid</b>#d6ff3d — accent, links, active nav</div></div>
|
||
<div class="sw"><div class="chip" style="background:#e04e4e"></div><div class="info"><b>Bearing</b>#e04e4e — compass north, mark only</div></div>
|
||
<div class="sw"><div class="chip" style="background:#0b0e14"></div><div class="info"><b>Background</b>#0b0e14 — page canvas</div></div>
|
||
<div class="sw"><div class="chip" style="background:#141a24"></div><div class="info"><b>Panel</b>#141a24 — cards, elevated surfaces</div></div>
|
||
<div class="sw"><div class="chip" style="background:#18202c"></div><div class="info"><b>Panel 2</b>#18202c — nested / step items</div></div>
|
||
<div class="sw"><div class="chip" style="background:#e7eaf1"></div><div class="info"><b>Ink</b>#e7eaf1 — body text on dark</div></div>
|
||
<div class="sw"><div class="chip" style="background:#8b98a9"></div><div class="info"><b>Muted</b>#8b98a9 — secondary text</div></div>
|
||
<div class="sw"><div class="chip" style="background:#5e6678"></div><div class="info"><b>Dim</b>#5e6678 — tertiary text, dividers</div></div>
|
||
<div class="sw"><div class="chip" style="background:#4fd1a5"></div><div class="info"><b>OK</b>#4fd1a5 — success / verified chain</div></div>
|
||
<div class="sw"><div class="chip" style="background:#ffc75f"></div><div class="info"><b>Warn</b>#ffc75f — caution, holds</div></div>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="typography">
|
||
<h2>Typography</h2>
|
||
<p class="lede">System font stack, so nothing needs to load and every OS renders the wordmark in
|
||
the same family the reader is used to.</p>
|
||
<div class="asset" style="max-width:640px">
|
||
<p style="margin:0;font-family:system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
|
||
font-size:36px;font-weight:600;letter-spacing:-.5px">The quick brown fox</p>
|
||
<p style="margin:.4rem 0 0;color:var(--mut);font-family:system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
|
||
font-size:16px">jumps over the lazy dog · 0123456789 · theseus.x</p>
|
||
<div class="meta" style="margin-top:12px">system-ui, -apple-system, Segoe UI, Roboto, sans-serif</div>
|
||
</div>
|
||
<div class="note">The wordmark's <code>.x</code> is a <code><tspan fill="#d6ff3d"></code> —
|
||
don't render the whole word in acid. The compass north triangle is the only place
|
||
<b>bearing red</b> appears; don't add red anywhere else in the chrome.</div>
|
||
</section>
|
||
|
||
<section id="usage">
|
||
<h2>Usage & trademark</h2>
|
||
<p class="lede">These files are the marks of Theseus and Silent Mode, not open-licensed artwork:
|
||
the code is MPL-2.0, the name and the compass are reserved, and the
|
||
<a href="https://code.silentmode.st/silentmode/theseus/src/branch/master/TRADEMARKS.md">trademark note</a> says what that allows. Use them to refer to Theseus in
|
||
third-party tools that integrate with Theseus.X (BCNR name explorers, wallet bridges, blog
|
||
posts, review sites), never as your own mark. Keep the compass proportions intact and don't
|
||
recolour the acid to a similar-but-different green — palette drift is what makes brands look
|
||
untrustworthy over time.</p>
|
||
<ul style="color:var(--mut);font-size:14px;padding-left:1.2rem">
|
||
<li><b style="color:var(--ink)">Do</b> use the mark to indicate "opens in Theseus" or "supports BCNR".</li>
|
||
<li><b style="color:var(--ink)">Do</b> shrink to the favicon at 16×16 — the SVG scales cleanly.</li>
|
||
<li><b style="color:var(--ink)">Do</b> use the monochrome logo where the acid green would clash.</li>
|
||
<li><b style="color:var(--ink)">Don't</b> imply endorsement of a specific product without asking.</li>
|
||
<li><b style="color:var(--ink)">Don't</b> ship a fork, a product or a name under this name or mark — a fork is welcome under its own.</li>
|
||
<li><b style="color:var(--ink)">Don't</b> stretch, skew, or re-tint the compass.</li>
|
||
<li><b style="color:var(--ink)">Don't</b> introduce a second accent colour — acid green is the only one.</li>
|
||
</ul>
|
||
</section>
|
||
|
||
</div>
|
||
|
||
<footer>
|
||
Sibling brand kits: <a href="//sirius.x/brand/">sirius.x/brand</a> ·
|
||
<a href="//ariadne.x/brand/">ariadne.x/brand</a>
|
||
</footer>
|
||
|
||
<script>
|
||
// Sidenav scroll-spy: highlight the section currently in view.
|
||
(() => {
|
||
const links = document.querySelectorAll(".sidenav a[href^='#']");
|
||
if (!links.length) return;
|
||
const entries = [];
|
||
links.forEach((a) => { const el = document.querySelector(a.getAttribute("href")); if (el) entries.push({ el, link: a }); });
|
||
if (!entries.length) return;
|
||
const setActive = (link) => { links.forEach((l) => l.classList.remove("active")); link.classList.add("active"); };
|
||
const update = () => {
|
||
const doc = document.documentElement;
|
||
const scrollBottom = window.scrollY + window.innerHeight;
|
||
if (scrollBottom >= (doc.scrollHeight - 4)) { setActive(entries[entries.length - 1].link); return; }
|
||
const line = window.scrollY + window.innerHeight * 0.35;
|
||
let active = entries[0].link;
|
||
for (const e of entries) {
|
||
if (e.el.getBoundingClientRect().top + window.scrollY <= line) active = e.link;
|
||
else break;
|
||
}
|
||
setActive(active);
|
||
};
|
||
window.addEventListener("scroll", update, { passive: true });
|
||
window.addEventListener("resize", update);
|
||
update();
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|