website: redesign part 6

This commit is contained in:
nym21
2026-06-03 18:07:11 +02:00
parent 98bbfec525
commit f41874f438
6 changed files with 255 additions and 23 deletions
+145
View File
@@ -144,4 +144,149 @@ export const sections = [
},
],
},
{
title: "Ownership",
description:
"How coins are held across balances, entities, custody patterns, and long-term cohorts.",
chart: "Ownership overview",
children: [
{
title: "Balances",
description:
"Address and entity balances grouped by size, concentration, and historical change.",
chart: "Balance cohorts",
children: [],
},
{
title: "Entities",
description:
"Estimated ownership clusters and how their behavior changes through market regimes.",
chart: "Entity supply",
children: [],
},
{
title: "Custody",
description:
"Coins associated with exchanges, funds, miners, and other observable custody groups.",
chart: "Custody balances",
children: [],
},
],
},
{
title: "Liquidity",
description:
"How available supply changes as coins move between liquid, illiquid, and exchange venues.",
chart: "Liquidity overview",
children: [
{
title: "Liquid Supply",
description:
"Coins held by entities that tend to spend, trade, or redistribute frequently.",
chart: "Liquid supply",
children: [],
},
{
title: "Illiquid Supply",
description:
"Coins held by entities with low spending history and stronger accumulation behavior.",
chart: "Illiquid supply",
children: [],
},
{
title: "Exchange Flow",
description:
"Deposits, withdrawals, and balance changes across known exchange clusters.",
chart: "Exchange netflow",
children: [],
},
],
},
{
title: "Risk",
description:
"Stress, leverage, drawdown, and valuation conditions that shape market fragility.",
chart: "Risk overview",
children: [
{
title: "Drawdown",
description:
"Distance from prior highs and the depth of cycle retracements over time.",
chart: "Drawdown",
children: [],
},
{
title: "Stress",
description:
"Periods where losses, volatility, and fee pressure concentrate together.",
chart: "Network stress",
children: [],
},
{
title: "Leverage",
description:
"Market conditions that indicate amplified exposure and forced positioning risk.",
chart: "Leverage proxy",
children: [],
},
],
},
{
title: "Cycles",
description:
"How Bitcoin behaves across halvings, adoption waves, liquidity regimes, and market phases.",
chart: "Cycle overview",
children: [
{
title: "Halvings",
description:
"Supply issuance changes and their relationship to market and miner behavior.",
chart: "Halving cycles",
children: [],
},
{
title: "Phases",
description:
"Bull, bear, recovery, and transition periods described through on-chain behavior.",
chart: "Cycle phases",
children: [],
},
{
title: "Comparisons",
description:
"Cycle-to-cycle comparisons normalized by time, price, drawdown, or supply behavior.",
chart: "Cycle comparison",
children: [],
},
],
},
{
title: "Cohorts",
description:
"Groups of market participants organized by age, balance, cost basis, and observed behavior.",
chart: "Cohort overview",
children: [
{
title: "Short Term",
description:
"Recently moved coins and holders more sensitive to price, volatility, and liquidity.",
chart: "Short-term holder supply",
children: [],
},
{
title: "Long Term",
description:
"Older coins and holders with stronger dormancy, conviction, or lower spend frequency.",
chart: "Long-term holder supply",
children: [],
},
{
title: "Cost Basis",
description:
"Estimated acquisition prices across cohorts and how they frame profit and loss.",
chart: "Cohort cost basis",
children: [],
},
],
},
];
+19 -13
View File
@@ -81,9 +81,12 @@ function createContents() {
return nav;
}
/** @param {HTMLElement} main */
function initScrollSpy(main) {
const titles = [...main.querySelectorAll("h1[id], h2[id]")];
/**
* @param {HTMLElement} main
* @param {HTMLElement} article
*/
function initScrollSpy(main, article) {
const titles = [...article.querySelectorAll("h1[id], h2[id]")];
const visible = new Set();
const links = new Map(
[...main.querySelectorAll('nav a[href^="#"]')].map((link) => [
@@ -108,16 +111,19 @@ function initScrollSpy(main) {
current = hash;
}
const observer = new IntersectionObserver((entries) => {
for (const entry of entries) {
if (entry.isIntersecting) {
visible.add(entry.target.id);
} else {
visible.delete(entry.target.id);
const observer = new IntersectionObserver(
(entries) => {
for (const entry of entries) {
if (entry.isIntersecting) {
visible.add(entry.target.id);
} else {
visible.delete(entry.target.id);
}
}
}
update();
});
update();
},
{ root: article },
);
for (const title of titles) {
observer.observe(title);
@@ -134,7 +140,7 @@ export function createLearnPage() {
}
main.append(article, createContents());
initScrollSpy(main);
initScrollSpy(main, article);
return main;
}
+89 -9
View File
@@ -1,27 +1,59 @@
main.learn {
--sticky-h: 5rem;
--sidebar-top: 6rem;
--sidebar-bottom: 1rem;
display: grid;
grid-template-columns: minmax(0, 1fr) 14rem;
grid-template-rows: minmax(0, 1fr);
gap: 4rem;
padding: 8rem 2rem 6rem;
overflow: hidden;
article {
width: min(100%, 52rem);
justify-self: center;
position: relative;
counter-reset: theme;
min-width: 0;
min-height: 0;
overflow: auto;
scroll-behavior: smooth;
scrollbar-gutter: stable;
&::before {
content: "";
position: sticky;
top: 0;
z-index: 2;
display: block;
width: min(100%, 52rem);
height: var(--sticky-h);
margin-inline: auto;
margin-bottom: calc(-1 * var(--sticky-h));
background: var(--black);
pointer-events: none;
}
> section {
counter-increment: theme;
counter-reset: topic;
width: min(100%, 52rem);
margin-inline: auto;
}
> section + section {
margin-top: 8rem;
}
section section {
counter-increment: topic;
margin-top: 4rem;
}
}
h1,
h2 {
font-weight: 400;
position: sticky;
background: var(--black);
line-height: 1;
scroll-margin-top: 6rem;
a {
position: relative;
@@ -30,7 +62,6 @@ main.learn {
text-decoration: none;
&::before {
content: "#";
position: absolute;
top: 50%;
right: 100%;
@@ -57,11 +88,30 @@ main.learn {
}
h1 {
z-index: 3;
top: var(--sticky-h);
scroll-margin-top: var(--sticky-h);
padding-bottom: 0.5rem;
border-bottom: 1px solid var(--dark-gray);
font-size: 2.75rem;
a::before {
content: counter(theme, upper-roman) ". ";
}
}
h2 {
z-index: 1;
top: var(--sticky-h);
scroll-margin-top: var(--sticky-h);
padding-top: 3.5rem;
padding-bottom: 0.5rem;
border-bottom: 1px dashed var(--dark-gray);
font-size: 1.5rem;
a::before {
content: counter(topic) ". ";
}
}
p {
@@ -89,9 +139,12 @@ main.learn {
}
> nav {
position: sticky;
top: 6rem;
align-self: start;
counter-reset: content-theme;
min-height: 0;
overflow: auto;
scrollbar-gutter: stable;
padding-top: var(--sidebar-top);
padding-bottom: var(--sidebar-bottom);
font-size: var(--font-size-xs);
line-height: var(--line-height-sm);
text-transform: uppercase;
@@ -102,12 +155,21 @@ main.learn {
padding: 0;
}
> ol > li {
counter-increment: content-theme;
counter-reset: content-topic;
}
ol ol {
margin-top: 0.5rem;
margin-left: 1rem;
color: var(--gray);
}
ol ol > li {
counter-increment: content-topic;
}
li + li {
margin-top: 0.5rem;
}
@@ -116,9 +178,27 @@ main.learn {
color: inherit;
text-decoration: none;
&::before {
opacity: 0.5;
}
&:hover {
color: var(--orange);
}
}
> ol > li > a::before {
content: counter(content-theme, upper-roman) ". ";
}
ol ol > li > a::before {
content: counter(content-topic) ". ";
}
}
}
@media (prefers-reduced-motion: reduce) {
main.learn article {
scroll-behavior: auto;
}
}
+1 -1
View File
@@ -27,7 +27,7 @@ function normalizePath(pathname) {
function updateCurrentLink(pathname) {
const currentPath = normalizePath(pathname);
for (const link of document.querySelectorAll("nav a")) {
for (const link of document.querySelectorAll("body > header > nav a")) {
const linkPath = new URL(/** @type {HTMLAnchorElement} */ (link).href)
.pathname;
+1
View File
@@ -46,6 +46,7 @@ h1,
h2,
h3 {
font-family: var(--font-serif);
font-weight: 400;
}
code {