diff --git a/crates/brk_bindgen/src/generators/javascript/tree.rs b/crates/brk_bindgen/src/generators/javascript/tree.rs index b94b39da8..c8d9568e9 100644 --- a/crates/brk_bindgen/src/generators/javascript/tree.rs +++ b/crates/brk_bindgen/src/generators/javascript/tree.rs @@ -108,15 +108,14 @@ pub fn generate_main_client( writeln!(output, " constructor(options) {{").unwrap(); writeln!(output, " super(options);").unwrap(); writeln!(output, " /** @type {{SeriesTree}} */").unwrap(); - writeln!(output, " this.series = this._buildTree('');").unwrap(); + writeln!(output, " this.series = this._buildTree();").unwrap(); writeln!(output, " }}\n").unwrap(); writeln!(output, " /**").unwrap(); writeln!(output, " * @private").unwrap(); - writeln!(output, " * @param {{string}} basePath").unwrap(); writeln!(output, " * @returns {{SeriesTree}}").unwrap(); writeln!(output, " */").unwrap(); - writeln!(output, " _buildTree(basePath) {{").unwrap(); + writeln!(output, " _buildTree() {{").unwrap(); writeln!(output, " return {{").unwrap(); let mut generated = BTreeSet::new(); generate_tree_initializer( diff --git a/crates/brk_client/src/lib.rs b/crates/brk_client/src/lib.rs index 3e815dc71..b2557903d 100644 --- a/crates/brk_client/src/lib.rs +++ b/crates/brk_client/src/lib.rs @@ -1936,7 +1936,7 @@ impl ActivityOutputsRealizedSupplyUnrealizedPattern2 { /// Pattern struct for repeated tree structure. pub struct BlockChangeCumulativeDeltaSumPattern { pub block: CentsUsdPattern4, - pub change_1m: ToPattern2, + pub change_1m: ToPattern, pub cumulative: CentsUsdPattern, pub delta: AbsoluteRatePattern2, pub sum: _1m1w1y24hPattern5, @@ -1947,7 +1947,7 @@ impl BlockChangeCumulativeDeltaSumPattern { pub fn new(client: Arc, acc: String) -> Self { Self { block: CentsUsdPattern4::new(client.clone(), _m(&acc, "realized_pnl")), - change_1m: ToPattern2::new(client.clone(), _m(&acc, "pnl_change_1m_to")), + change_1m: ToPattern::new(client.clone(), _m(&acc, "pnl_change_1m_to")), cumulative: CentsUsdPattern::new(client.clone(), _m(&acc, "realized_pnl_cumulative")), delta: AbsoluteRatePattern2::new(client.clone(), _m(&acc, "realized_pnl_delta")), sum: _1m1w1y24hPattern5::new(client.clone(), _m(&acc, "realized_pnl_sum")), @@ -3174,16 +3174,16 @@ impl InPattern2 { /// Pattern struct for repeated tree structure. pub struct InPattern { - pub in_loss: ToPattern, - pub in_profit: ToPattern, + pub in_loss: SharePattern, + pub in_profit: SharePattern, } impl InPattern { /// Create a new pattern node with accumulated series name. pub fn new(client: Arc, acc: String) -> Self { Self { - in_loss: ToPattern::new(client.clone(), _m(&acc, "loss_to_own")), - in_profit: ToPattern::new(client.clone(), _m(&acc, "profit_to_own")), + in_loss: SharePattern::new(client.clone(), _m(&acc, "loss_share")), + in_profit: SharePattern::new(client.clone(), _m(&acc, "profit_share")), } } } @@ -3243,12 +3243,12 @@ pub struct SdSmaPattern { } /// Pattern struct for repeated tree structure. -pub struct ToPattern2 { +pub struct ToPattern { pub to_mcap: BpsPercentRatioPattern, pub to_rcap: BpsPercentRatioPattern, } -impl ToPattern2 { +impl ToPattern { /// Create a new pattern node with accumulated series name. pub fn new(client: Arc, acc: String) -> Self { Self { @@ -3301,15 +3301,15 @@ impl PricePattern { } /// Pattern struct for repeated tree structure. -pub struct ToPattern { - pub to_own: BpsPercentRatioPattern2, +pub struct SharePattern { + pub share: BpsPercentRatioPattern2, } -impl ToPattern { +impl SharePattern { /// Create a new pattern node with accumulated series name. pub fn new(client: Arc, acc: String) -> Self { Self { - to_own: BpsPercentRatioPattern2::new(client.clone(), acc.clone()), + share: BpsPercentRatioPattern2::new(client.clone(), acc.clone()), } } } diff --git a/modules/brk-client/index.js b/modules/brk-client/index.js index 9716827d8..021595806 100644 --- a/modules/brk-client/index.js +++ b/modules/brk-client/index.js @@ -3001,7 +3001,7 @@ function createActivityOutputsRealizedSupplyUnrealizedPattern2(client, acc) { /** * @typedef {Object} BlockChangeCumulativeDeltaSumPattern * @property {CentsUsdPattern4} block - * @property {ToPattern2} change1m + * @property {ToPattern} change1m * @property {CentsUsdPattern} cumulative * @property {AbsoluteRatePattern2} delta * @property {_1m1w1y24hPattern5} sum @@ -3016,7 +3016,7 @@ function createActivityOutputsRealizedSupplyUnrealizedPattern2(client, acc) { function createBlockChangeCumulativeDeltaSumPattern(client, acc) { return { block: createCentsUsdPattern4(client, _m(acc, 'realized_pnl')), - change1m: createToPattern2(client, _m(acc, 'pnl_change_1m_to')), + change1m: createToPattern(client, _m(acc, 'pnl_change_1m_to')), cumulative: createCentsUsdPattern(client, _m(acc, 'realized_pnl_cumulative')), delta: createAbsoluteRatePattern2(client, _m(acc, 'realized_pnl_delta')), sum: create_1m1w1y24hPattern5(client, _m(acc, 'realized_pnl_sum')), @@ -4446,8 +4446,8 @@ function createInPattern2(client, acc) { /** * @typedef {Object} InPattern - * @property {ToPattern} inLoss - * @property {ToPattern} inProfit + * @property {SharePattern} inLoss + * @property {SharePattern} inProfit */ /** @@ -4458,8 +4458,8 @@ function createInPattern2(client, acc) { */ function createInPattern(client, acc) { return { - inLoss: createToPattern(client, _m(acc, 'loss_to_own')), - inProfit: createToPattern(client, _m(acc, 'profit_to_own')), + inLoss: createSharePattern(client, _m(acc, 'loss_share')), + inProfit: createSharePattern(client, _m(acc, 'profit_share')), }; } @@ -4528,18 +4528,18 @@ function createRatioValuePattern(client, acc) { */ /** - * @typedef {Object} ToPattern2 + * @typedef {Object} ToPattern * @property {BpsPercentRatioPattern} toMcap * @property {BpsPercentRatioPattern} toRcap */ /** - * Create a ToPattern2 pattern node + * Create a ToPattern pattern node * @param {BrkClientBase} client * @param {string} acc - Accumulated series name - * @returns {ToPattern2} + * @returns {ToPattern} */ -function createToPattern2(client, acc) { +function createToPattern(client, acc) { return { toMcap: createBpsPercentRatioPattern(client, _m(acc, 'mcap')), toRcap: createBpsPercentRatioPattern(client, _m(acc, 'rcap')), @@ -4598,19 +4598,19 @@ function createPricePattern(client, acc) { } /** - * @typedef {Object} ToPattern - * @property {BpsPercentRatioPattern2} toOwn + * @typedef {Object} SharePattern + * @property {BpsPercentRatioPattern2} share */ /** - * Create a ToPattern pattern node + * Create a SharePattern pattern node * @param {BrkClientBase} client * @param {string} acc - Accumulated series name - * @returns {ToPattern} + * @returns {SharePattern} */ -function createToPattern(client, acc) { +function createSharePattern(client, acc) { return { - toOwn: createBpsPercentRatioPattern2(client, acc), + share: createBpsPercentRatioPattern2(client, acc), }; } @@ -8188,15 +8188,14 @@ class BrkClient extends BrkClientBase { constructor(options) { super(options); /** @type {SeriesTree} */ - this.series = this._buildTree(''); + this.series = this._buildTree(); } /** * @private - * @param {string} basePath * @returns {SeriesTree} */ - _buildTree(basePath) { + _buildTree() { return { blocks: { blockhash: createSeriesPattern18(this, 'blockhash'), diff --git a/packages/brk_client/brk_client/__init__.py b/packages/brk_client/brk_client/__init__.py index fc6880024..65f328319 100644 --- a/packages/brk_client/brk_client/__init__.py +++ b/packages/brk_client/brk_client/__init__.py @@ -3054,7 +3054,7 @@ class BlockChangeCumulativeDeltaSumPattern: def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated series name.""" self.block: CentsUsdPattern4 = CentsUsdPattern4(client, _m(acc, 'realized_pnl')) - self.change_1m: ToPattern2 = ToPattern2(client, _m(acc, 'pnl_change_1m_to')) + self.change_1m: ToPattern = ToPattern(client, _m(acc, 'pnl_change_1m_to')) self.cumulative: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'realized_pnl_cumulative')) self.delta: AbsoluteRatePattern2 = AbsoluteRatePattern2(client, _m(acc, 'realized_pnl_delta')) self.sum: _1m1w1y24hPattern5 = _1m1w1y24hPattern5(client, _m(acc, 'realized_pnl_sum')) @@ -3672,8 +3672,8 @@ class InPattern: def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated series name.""" - self.in_loss: ToPattern = ToPattern(client, _m(acc, 'loss_to_own')) - self.in_profit: ToPattern = ToPattern(client, _m(acc, 'profit_to_own')) + self.in_loss: SharePattern = SharePattern(client, _m(acc, 'loss_share')) + self.in_profit: SharePattern = SharePattern(client, _m(acc, 'profit_share')) class PerPattern: """Pattern struct for repeated tree structure.""" @@ -3703,7 +3703,7 @@ class SdSmaPattern: """Pattern struct for repeated tree structure.""" pass -class ToPattern2: +class ToPattern: """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): @@ -3732,12 +3732,12 @@ class PricePattern: """Create pattern node with accumulated series name.""" self.price: BpsCentsPercentilesRatioSatsUsdPattern = BpsCentsPercentilesRatioSatsUsdPattern(client, acc) -class ToPattern: +class SharePattern: """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated series name.""" - self.to_own: BpsPercentRatioPattern2 = BpsPercentRatioPattern2(client, acc) + self.share: BpsPercentRatioPattern2 = BpsPercentRatioPattern2(client, acc) class TransferPattern: """Pattern struct for repeated tree structure.""" diff --git a/website/scripts/_types.js b/website/scripts/_types.js index 06c082833..1694bc10a 100644 --- a/website/scripts/_types.js +++ b/website/scripts/_types.js @@ -81,13 +81,13 @@ * Relative patterns by capability: * Unrealized patterns by capability level * @typedef {Brk.LossNetNuplProfitPattern} BasicRelativePattern - * @typedef {Brk.GrossInvestedInvestorLossNetNuplProfitSentimentPattern2} FullRelativePattern + * @typedef {Brk.CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2} FullRelativePattern * * Profitability bucket pattern (supply + realized_cap + unrealized_pnl + nupl) * @typedef {Brk.NuplRealizedSupplyUnrealizedPattern} RealizedSupplyPattern * * Realized pattern (full: cap + gross + capitalized + loss + mvrv + net + peak + price + profit + sell + sopr) - * @typedef {Brk.CapGrossInvestorLossMvrvNetPeakPriceProfitSellSoprPattern} RealizedPattern + * @typedef {Brk.CapCapitalizedGrossLossMvrvNetPeakPriceProfitSellSoprPattern} RealizedPattern * * Transfer volume pattern (block + cumulative + inProfit/inLoss + sum windows) * @typedef {Brk.AverageBlockCumulativeInSumPattern} TransferVolumePattern @@ -242,19 +242,6 @@ * @typedef {CohortFull | CohortLongTerm} CohortWithNuplPercentiles * @typedef {{ name: string, title: string, list: readonly CohortWithNuplPercentiles[], all: CohortAll }} CohortGroupWithNuplPercentiles * - * Cohorts with RealizedWithExtras (realizedCapRelToOwnMarketCap + realizedProfitToLossRatio) - * @typedef {CohortAll | CohortFull | CohortWithPercentiles} CohortWithRealizedExtras - * - * Cohorts with circulating supply relative series (supplyRelToCirculatingSupply etc.) - * These have GlobalRelativePattern or FullRelativePattern (same as RelativeWithMarketCap/RelativeWithNupl) - * @typedef {CohortFull | CohortLongTerm | CohortWithAdjusted | CohortBasicWithMarketCap} UtxoCohortWithCirculatingSupplyRelative - * - * Address cohorts with circulating supply relative series (all address amount cohorts have these) - * @typedef {AddrCohortObject} AddrCohortWithCirculatingSupplyRelative - * - * All cohorts with circulating supply relative series - * @typedef {UtxoCohortWithCirculatingSupplyRelative | AddrCohortWithCirculatingSupplyRelative} CohortWithCirculatingSupplyRelative - * * Delta patterns with absolute + rate rolling windows * @typedef {Brk.AbsoluteRatePattern} DeltaPattern * @typedef {Brk.AbsoluteRatePattern2} FiatDeltaPattern diff --git a/website/scripts/explorer/chain.js b/website/scripts/explorer/chain.js index 898087717..42c0b781a 100644 --- a/website/scripts/explorer/chain.js +++ b/website/scripts/explorer/chain.js @@ -38,6 +38,7 @@ export function initChain(parent, callbacks) { olderObserver = new IntersectionObserver( (entries) => { + return; // edge fetching disabled for layout debugging if (entries[0].isIntersecting) loadOlder(); }, { root: chainEl }, @@ -46,6 +47,7 @@ export function initChain(parent, callbacks) { chainEl.addEventListener( "scroll", () => { + return; // edge fetching disabled for layout debugging const nearStart = (chainEl.scrollHeight > chainEl.clientHeight && chainEl.scrollTop <= 50) || diff --git a/website/scripts/options/cointime.js b/website/scripts/options/cointime.js index fe12af1ec..682c6e63d 100644 --- a/website/scripts/options/cointime.js +++ b/website/scripts/options/cointime.js @@ -38,32 +38,37 @@ export function createCointimeSection() { }, ]); - const prices = /** @type {const} */ ([ + /** @type {readonly { pattern: PriceRatioPercentilesPattern, name: string, title: (name: string) => string, color: Color, defaultActive: boolean }[]} */ + const prices = [ { pattern: cointimePrices.trueMarketMean, name: "True Market Mean", + title: (name) => name, color: colors.trueMarketMean, defaultActive: true, }, { pattern: cointimePrices.vaulted, name: "Vaulted", + title: (name) => `${name} Price`, color: colors.vaulted, defaultActive: true, }, { pattern: cointimePrices.active, name: "Active", + title: (name) => `${name} Price`, color: colors.active, defaultActive: true, }, { pattern: cointimePrices.cointime, name: "Cointime", + title: (name) => `${name} Price`, color: colors.cointime, defaultActive: true, }, - ]); + ]; const caps = /** @type {const} */ ([ { @@ -187,11 +192,11 @@ export function createCointimeSection() { ), ], }, - ...prices.map(({ pattern, name, color }) => ({ + ...prices.map(({ pattern, name, title, color }) => ({ name, tree: priceRatioPercentilesTree({ pattern, - title: `${name} Price`, + title: title(name), legend: name, color, priceReferences: [ diff --git a/website/scripts/utils/dom.js b/website/scripts/utils/dom.js index 3fe785fb3..663a7b2a1 100644 --- a/website/scripts/utils/dom.js +++ b/website/scripts/utils/dom.js @@ -254,9 +254,6 @@ export function createSelect({ ? unsortedChoices.toSorted((a, b) => toLabel(a).localeCompare(toLabel(b))) : unsortedChoices; - const field = window.document.createElement("div"); - field.classList.add("field"); - const initialKey = toKey(initialValue); /** @param {string} key */ @@ -266,56 +263,59 @@ export function createSelect({ if (choices.length === 1) { const span = window.document.createElement("span"); span.textContent = toLabel(choices[0]); - field.append(span); - } else { - const select = window.document.createElement("select"); - select.id = id ?? ""; - select.name = id ?? ""; - field.append(select); - - /** @param {T} choice */ - const createOption = (choice) => { - const option = window.document.createElement("option"); - option.value = toKey(choice); - option.textContent = toLabel(choice); - if (toKey(choice) === initialKey) { - option.selected = true; - } - return option; - }; - - if (groups) { - groups.forEach(({ label, items }) => { - const optgroup = window.document.createElement("optgroup"); - optgroup.label = label; - items.forEach((choice) => optgroup.append(createOption(choice))); - select.append(optgroup); - }); - } else { - choices.forEach((choice) => select.append(createOption(choice))); - } - - select.addEventListener("change", () => { - onChange?.(fromKey(select.value)); - }); - - const remaining = choices.length - 1; - if (remaining > 0) { - const small = window.document.createElement("small"); - small.textContent = `+${remaining}`; - field.append(small); - const arrow = window.document.createElement("span"); - arrow.textContent = "↓"; - field.append(arrow); - } - - field.addEventListener("click", (e) => { - if (e.target !== select) { - select.showPicker(); - } - }); + return span; } + const field = window.document.createElement("div"); + field.classList.add("field"); + + const select = window.document.createElement("select"); + select.id = id ?? ""; + select.name = id ?? ""; + field.append(select); + + /** @param {T} choice */ + const createOption = (choice) => { + const option = window.document.createElement("option"); + option.value = toKey(choice); + option.textContent = toLabel(choice); + if (toKey(choice) === initialKey) { + option.selected = true; + } + return option; + }; + + if (groups) { + groups.forEach(({ label, items }) => { + const optgroup = window.document.createElement("optgroup"); + optgroup.label = label; + items.forEach((choice) => optgroup.append(createOption(choice))); + select.append(optgroup); + }); + } else { + choices.forEach((choice) => select.append(createOption(choice))); + } + + select.addEventListener("change", () => { + onChange?.(fromKey(select.value)); + }); + + const remaining = choices.length - 1; + if (remaining > 0) { + const small = window.document.createElement("small"); + small.textContent = `+${remaining}`; + field.append(small); + const arrow = window.document.createElement("span"); + arrow.textContent = "↓"; + field.append(arrow); + } + + field.addEventListener("click", (e) => { + if (e.target !== select) { + select.showPicker(); + } + }); + return field; } diff --git a/website/styles/chart.css b/website/styles/chart.css index 8de2d5bc2..cdad03395 100644 --- a/website/styles/chart.css +++ b/website/styles/chart.css @@ -70,7 +70,7 @@ pointer-events: auto; } - > span { + > *:nth-child(2) { color: var(--gray); padding: 0 0.75rem; } @@ -105,7 +105,7 @@ > label { > span { - display: flex !important; + display: flex; } &:has(input:not(:checked)) { @@ -115,11 +115,11 @@ &:hover { * { - color: var(--off-color) !important; + color: var(--off-color); } > span.main > span.name { - text-decoration-color: var(--orange) !important; + text-decoration-color: var(--orange); } } diff --git a/website/styles/elements.css b/website/styles/elements.css index 3ee7f2860..b47572124 100644 --- a/website/styles/elements.css +++ b/website/styles/elements.css @@ -30,18 +30,28 @@ a { text-decoration-color: inherit; } - &[target="_blank"]::after { - color: var(--off-color); - content: "↗"; - font-weight: 400; - font-size: 1rem; + &[target="_blank"] { + &::after { + color: var(--off-color); + content: "↗"; + font-weight: 400; + font-size: 1rem; - margin-top: 0.1rem; - margin-left: 0.375rem; - line-height: 1; + margin-top: 0.1rem; + margin-left: 0.375rem; + line-height: 1; - &:hover { - text-decoration: none; + &:hover { + text-decoration: none; + } + } + + &:hover::after { + color: var(--color); + } + + &:active::after { + color: var(--orange); } } } @@ -55,6 +65,8 @@ aside { z-index: 1; overflow: hidden; background: var(--background-color); + container-type: inline-size; + container-name: aside; html[data-layout="split"] & { grid-column: 2; @@ -208,11 +220,6 @@ select { outline: none; } -summary > small { - margin-left: 0.375rem; - opacity: 0.5; -} - small { color: var(--off-color); font-weight: var(--font-weight-base); @@ -249,28 +256,33 @@ summary { &::-webkit-details-marker { display: none; } + + > small { + margin-left: 0.375rem; + opacity: 0.5; + } + + &:hover > small { + color: var(--color); + } + + &:active > small { + color: var(--orange); + } } :is(a, button, summary) { &:hover { - &, - *, - &::after { - color: var(--color); - } + color: var(--color); } &:active { - &, - *, - &::after { - color: var(--orange); - } + color: var(--orange); } } html[data-layout="split"] .full-only { - display: none !important; + display: none; } #layout-button { diff --git a/website/styles/main.css b/website/styles/main.css index a74cc34fd..ed36f55e7 100644 --- a/website/styles/main.css +++ b/website/styles/main.css @@ -36,7 +36,7 @@ main { } html[data-layout="full"] & { - width: 100% !important; + width: 100%; } html[data-layout="split"] & { diff --git a/website/styles/nav.css b/website/styles/nav.css index c2f1d00e8..3a22b2476 100644 --- a/website/styles/nav.css +++ b/website/styles/nav.css @@ -61,7 +61,6 @@ li[data-highlight] { > a::after, > details:not([open]) > summary::after { - color: var(--orange) !important; content: ""; background-color: var(--orange); width: 0.375rem; diff --git a/website/styles/panes/explorer.css b/website/styles/panes/explorer.css index 1c5a1f69c..6a4bc4d6d 100644 --- a/website/styles/panes/explorer.css +++ b/website/styles/panes/explorer.css @@ -8,7 +8,7 @@ opacity: 0.5; } - @media (max-width: 767px) { + @container aside (max-width: 767px) { overflow-y: auto; padding: var(--main-padding) 0; flex-direction: column; @@ -23,25 +23,58 @@ known source of jank there. Each interaction state gets its own set; the .cube rule below just swaps which set --face-right / --face-left / --face-top / --face-bottom reference. */ - --cube-neutral-right: light-dark(oklch(from var(--light-gray) calc(l - var(--face-step) * 2) c h), var(--dark-gray)); - --cube-neutral-left: light-dark(oklch(from var(--light-gray) calc(l - var(--face-step)) c h), oklch(from var(--dark-gray) calc(l + var(--face-step)) c h)); - --cube-neutral-top: light-dark(var(--light-gray), oklch(from var(--dark-gray) calc(l + var(--face-step) * 2) c h)); - --cube-neutral-bottom: oklch(from var(--border-color) calc(l - var(--face-step) * 3) c h); + --cube-neutral-right: light-dark( + oklch(from var(--light-gray) calc(l - var(--face-step) * 2) c h), + var(--dark-gray) + ); + --cube-neutral-left: light-dark( + oklch(from var(--light-gray) calc(l - var(--face-step)) c h), + oklch(from var(--dark-gray) calc(l + var(--face-step)) c h) + ); + --cube-neutral-top: light-dark( + var(--light-gray), + oklch(from var(--dark-gray) calc(l + var(--face-step) * 2) c h) + ); + --cube-neutral-bottom: oklch( + from var(--border-color) calc(l - var(--face-step) * 3) c h + ); - --cube-hover-right: light-dark(oklch(from var(--dark-gray) calc(l - var(--face-step) * 2) c h), var(--light-gray)); - --cube-hover-left: light-dark(oklch(from var(--dark-gray) calc(l - var(--face-step)) c h), oklch(from var(--light-gray) calc(l + var(--face-step)) c h)); - --cube-hover-top: light-dark(var(--dark-gray), oklch(from var(--light-gray) calc(l + var(--face-step) * 2) c h)); - --cube-hover-bottom: oklch(from var(--inv-border-color) calc(l - var(--face-step) * 3) c h); + --cube-hover-right: light-dark( + oklch(from var(--dark-gray) calc(l - var(--face-step) * 2) c h), + var(--light-gray) + ); + --cube-hover-left: light-dark( + oklch(from var(--dark-gray) calc(l - var(--face-step)) c h), + oklch(from var(--light-gray) calc(l + var(--face-step)) c h) + ); + --cube-hover-top: light-dark( + var(--dark-gray), + oklch(from var(--light-gray) calc(l + var(--face-step) * 2) c h) + ); + --cube-hover-bottom: oklch( + from var(--inv-border-color) calc(l - var(--face-step) * 3) c h + ); - --cube-selected-right: light-dark(oklch(from var(--orange) calc(l - var(--face-step) * 2) c h), var(--orange)); - --cube-selected-left: light-dark(oklch(from var(--orange) calc(l - var(--face-step)) c h), oklch(from var(--orange) calc(l + var(--face-step)) c h)); - --cube-selected-top: light-dark(var(--orange), oklch(from var(--orange) calc(l + var(--face-step) * 2) c h)); - --cube-selected-bottom: oklch(from var(--orange) calc(l - var(--face-step) * 3) c h); + --cube-selected-right: light-dark( + oklch(from var(--orange) calc(l - var(--face-step) * 2) c h), + var(--orange) + ); + --cube-selected-left: light-dark( + oklch(from var(--orange) calc(l - var(--face-step)) c h), + oklch(from var(--orange) calc(l + var(--face-step)) c h) + ); + --cube-selected-top: light-dark( + var(--orange), + oklch(from var(--orange) calc(l + var(--face-step) * 2) c h) + ); + --cube-selected-bottom: oklch( + from var(--orange) calc(l - var(--face-step) * 3) c h + ); > * { padding: 0 var(--main-padding); - @media (min-width: 768px) { + @container aside (min-width: 768px) { padding: var(--main-padding); } } @@ -49,11 +82,11 @@ #chain { flex-shrink: 0; - @media (max-width: 767px) { + @container aside (max-width: 767px) { overflow-x: auto; } - @media (min-width: 768px) { + @container aside (min-width: 768px) { height: 100%; overflow-y: auto; padding-right: calc(var(--main-padding) / 2); @@ -67,16 +100,16 @@ --min-dt: 0; --max-dt: 10800; margin-right: var(--cube); - margin-top: calc(var(--cube) * -0.25); - @media (max-width: 767px) { - --max-gap: calc(var(--cube) * 1.5); + @container aside (max-width: 767px) { flex-direction: row-reverse; + align-items: center; height: 11.5rem; width: max-content; } - @media (min-width: 768px) { + @container aside (min-width: 768px) { + margin-top: calc(var(--cube) * -0.25); padding-bottom: 6rem; } } @@ -103,9 +136,9 @@ /* Face colors reference the precomputed sets on #explorer (see top of file). Hover / selected rules just switch which set each --face-* points at. */ - --face-right: var(--cube-neutral-right); - --face-left: var(--cube-neutral-left); - --face-top: var(--cube-neutral-top); + --face-right: var(--cube-neutral-right); + --face-left: var(--cube-neutral-left); + --face-top: var(--cube-neutral-top); --face-bottom: var(--cube-neutral-bottom); /* Fill-driven state. --liquid-y is the liquid's vertical scale; @@ -136,25 +169,27 @@ &:hover { color: var(--background-color); - --face-right: var(--cube-hover-right); - --face-left: var(--cube-hover-left); - --face-top: var(--cube-hover-top); + --face-right: var(--cube-hover-right); + --face-left: var(--cube-hover-left); + --face-top: var(--cube-hover-top); --face-bottom: var(--cube-hover-bottom); } &:active, &.selected { color: var(--black); - --face-right: var(--cube-selected-right); - --face-left: var(--cube-selected-left); - --face-top: var(--cube-selected-top); + --face-right: var(--cube-selected-right); + --face-left: var(--cube-selected-left); + --face-top: var(--cube-selected-top); --face-bottom: var(--cube-selected-bottom); } /* Skeleton state (cube painted but data is stale while a new chunk loads): hide text AND the pool logo. Using visibility rather than color:transparent so the raw logo hides too. */ - &.skeleton .face-text { visibility: hidden; } + &.skeleton .face-text { + visibility: hidden; + } /* Shared face-transform template. Each face div sets --orient, --x, --y, --sx, --sy and its role (liquid/glass/face-text) @@ -181,7 +216,8 @@ will-change is on the painted roles only (not .face-text, whose background never changes) so each liquid/glass gets its own compositor layer for snappy hover/select repaints. */ - .liquid, .glass { + .liquid, + .glass { will-change: background-color; transition: background-color var(--state-ease); } @@ -196,7 +232,9 @@ --sy: var(--glass-y); --y-offset: 0; } - .glass.top { opacity: calc(1 - var(--is-full)); } + .glass.top { + opacity: calc(1 - var(--is-full)); + } .face-text { --sy: var(--iso-scale); @@ -214,9 +252,16 @@ align-items: center; text-align: center; } - .face-text.top { justify-content: center; text-transform: uppercase; } - .face-text.right { justify-content: space-between; } - .face-text p { margin: 0; } + .face-text.top { + justify-content: center; + text-transform: uppercase; + } + .face-text.right { + justify-content: space-between; + } + .face-text p { + margin: 0; + } .face-text .height { font-size: var(--font-size-sm); font-weight: normal; @@ -254,12 +299,19 @@ their rear twins share the side-face orients). --sy is only shared on the top/bottom pair (always full iso rhombus); side faces inherit --sy from their role (liquid/glass/face-text). */ - .top, .bottom { + .top, + .bottom { --orient: rotate(30deg) skewX(-30deg); --sy: var(--iso-scale); } - .right, .rear-left { --orient: rotate(-30deg) skewX(-30deg); } - .left, .rear-right { --orient: rotate(30deg) skewX(30deg); } + .right, + .rear-left { + --orient: rotate(-30deg) skewX(-30deg); + } + .left, + .rear-right { + --orient: rotate(30deg) skewX(30deg); + } .bottom { --fc: var(--face-bottom); @@ -268,14 +320,20 @@ } .top { --fc: var(--face-top); - --x: calc(var(--ox) + var(--top-x-shift, 0) + var(--oy) / var(--iso-scale)); + --x: calc( + var(--ox) + var(--top-x-shift, 0) + var(--oy) / var(--iso-scale) + ); --y: calc(var(--oy) - var(--iso-scale) + var(--y-offset)); } - .liquid.top { --top-x-shift: calc(1 - var(--fill)); } + .liquid.top { + --top-x-shift: calc(1 - var(--fill)); + } .right { --fc: var(--face-right); --x: calc(var(--ox) + 1); - --y: calc((var(--ox) + 1) * var(--iso-scale) + var(--oy) + var(--y-offset)); + --y: calc( + (var(--ox) + 1) * var(--iso-scale) + var(--oy) + var(--y-offset) + ); } .left { --fc: var(--face-left); @@ -308,7 +366,7 @@ z-index: -1; } - @media (max-width: 767px) { + @container aside (max-width: 767px) { margin-bottom: 0; margin-right: var(--block-gap); @@ -332,7 +390,7 @@ font-size: var(--font-size-sm); line-height: var(--line-height-sm); - @media (min-width: 768px) { + @container aside (min-width: 768px) { overflow-y: auto; padding-left: calc(var(--main-padding) / 2); } @@ -342,7 +400,7 @@ code { font-size: 1.5rem; - font-weight: 300 !important; + font-weight: 300; font-family: Lilex; color: var(--off-color); letter-spacing: -0.05rem;