website_next: snapshot

This commit is contained in:
nym21
2026-07-04 22:09:40 +02:00
parent a99c06013b
commit 0bf2cd77dc
5 changed files with 295 additions and 180 deletions
+8 -1
View File
@@ -208,6 +208,7 @@ impl Query {
let computer = self.computer(); let computer = self.computer();
let reader = self.reader(); let reader = self.reader();
let all_pools = pools(); let all_pools = pools();
let pool_heights = computer.pools.pool_heights.read();
// Bulk read all indexed data // Bulk read all indexed data
let blockhashes = indexer.vecs.blocks.blockhash.collect_range_at(begin, end); let blockhashes = indexer.vecs.blocks.blockhash.collect_range_at(begin, end);
@@ -398,6 +399,11 @@ impl Query {
let pool_slug = pool_slugs[i]; let pool_slug = pool_slugs[i];
let pool = all_pools.get(pool_slug); let pool = all_pools.get(pool_slug);
let height = begin + i;
let block_number = pool_heights
.get(&pool_slug)
.map(|heights| heights.partition_point(|h| h.to_usize() <= height) as u64)
.unwrap_or(0);
let miner_names = if pool_slug == PoolSlug::Ocean { let miner_names = if pool_slug == PoolSlug::Ocean {
Self::parse_datum_miner_names(&scriptsig_bytes) Self::parse_datum_miner_names(&scriptsig_bytes)
@@ -410,7 +416,7 @@ impl Query {
let info = BlockInfo { let info = BlockInfo {
id: blockhashes[i], id: blockhashes[i],
height: Height::from(begin + i), height: Height::from(height),
version: header.version, version: header.version,
timestamp: timestamps[i], timestamp: timestamps[i],
bits: header.bits, bits: header.bits,
@@ -444,6 +450,7 @@ impl Query {
id: pool.mempool_unique_id(), id: pool.mempool_unique_id(),
name: pool.name.to_string(), name: pool.name.to_string(),
slug: pool_slug, slug: pool_slug,
block_number,
miner_names, miner_names,
}, },
avg_fee: Sats::from(total_fees_u64.checked_div(non_coinbase).unwrap_or(0)), avg_fee: Sats::from(total_fees_u64.checked_div(non_coinbase).unwrap_or(0)),
+4
View File
@@ -18,6 +18,10 @@ pub struct BlockPool {
/// URL-friendly pool identifier /// URL-friendly pool identifier
pub slug: PoolSlug, pub slug: PoolSlug,
/// This block's ordinal among blocks attributed to this pool
#[schemars(example = 215_000)]
pub block_number: u64,
/// Miner name tags found in coinbase scriptsig /// Miner name tags found in coinbase scriptsig
pub miner_names: Option<Vec<String>>, pub miner_names: Option<Vec<String>>,
} }
+1
View File
@@ -259,6 +259,7 @@ Matches mempool.space/bitcoin-cli behavior.
* @property {number} id - Unique pool identifier * @property {number} id - Unique pool identifier
* @property {string} name - Pool name * @property {string} name - Pool name
* @property {PoolSlug} slug - URL-friendly pool identifier * @property {PoolSlug} slug - URL-friendly pool identifier
* @property {number} blockNumber - This block's ordinal among blocks attributed to this pool
* @property {?string[]=} minerNames - Miner name tags found in coinbase scriptsig * @property {?string[]=} minerNames - Miner name tags found in coinbase scriptsig
*/ */
/** /**
+121 -85
View File
@@ -12,6 +12,8 @@ import { createFeeChart } from "./fee-chart.js";
/** @typedef {Awaited<ReturnType<typeof brk.getBlocksV1>>[number]} Block */ /** @typedef {Awaited<ReturnType<typeof brk.getBlocksV1>>[number]} Block */
const MAX_BLOCK_WEIGHT = 4_000_000; const MAX_BLOCK_WEIGHT = 4_000_000;
const DIFFICULTY_EPOCH_BLOCKS = 2_016;
const HALVING_EPOCH_BLOCKS = 210_000;
/** @param {number} bytes */ /** @param {number} bytes */
function formatBytes(bytes) { function formatBytes(bytes) {
@@ -100,54 +102,11 @@ function createRow(term, value) {
return row; return row;
} }
/**
* @param {string} label
* @param {string | Node} value
*/
function createStat(label, value) {
const stat = document.createElement("div");
const name = document.createElement("span");
const amount = document.createElement("strong");
stat.dataset.stat = "";
name.textContent = label;
amount.append(value);
stat.append(name, amount);
return stat;
}
/** @param {[string, string | Node][]} items */
function createStats(items) {
const stats = document.createElement("div");
stats.dataset.stats = "";
stats.append(...items.map(([label, value]) => createStat(label, value)));
return stats;
}
/** @param {string} title */ /** @param {string} title */
function groupName(title) { function groupName(title) {
return title.toLowerCase().replace(/[^a-z0-9]+/g, "-"); return title.toLowerCase().replace(/[^a-z0-9]+/g, "-");
} }
/**
* @param {string} title
* @param {[string, string | Node][]} stats
* @param {Node[]} [children]
*/
function createStatBox(title, stats, children = []) {
const box = document.createElement("div");
const heading = document.createElement("h3");
box.dataset.statBox = groupName(title);
heading.textContent = title;
box.append(heading, createStats(stats), ...children);
return box;
}
/** /**
* @param {string} label * @param {string} label
* @param {(string | Node)[]} values * @param {(string | Node)[]} values
@@ -168,11 +127,12 @@ function createInlineRow(label, values) {
/** /**
* @param {string} label * @param {string} label
* @param {string | Node} value * @param {string | Node} value
* @param {string} [type]
*/ */
function createInlineBox(label, value) { function createInlineBox(label, value, type = "inline") {
const box = document.createElement("div"); const box = document.createElement("div");
box.dataset.blockBox = "inline"; box.dataset.blockBox = type;
box.append(createInlineRow(label, [value])); box.append(createInlineRow(label, [value]));
return box; return box;
@@ -183,21 +143,16 @@ function formatBlockFill(block) {
return `${((block.weight / MAX_BLOCK_WEIGHT) * 100).toFixed(1)}%`; return `${((block.weight / MAX_BLOCK_WEIGHT) * 100).toFixed(1)}%`;
} }
/** @param {number | string} bits */
function formatBits(bits) {
return typeof bits === "number" ? `0x${bits.toString(16)}` : bits;
}
/** /**
* @param {string} label * @param {string} label
* @param {string} value * @param {string} value
*/ */
function createMinerStat(label, value) { function createMetricStat(label, value) {
const stat = document.createElement("div"); const stat = document.createElement("div");
const name = document.createElement("span"); const name = document.createElement("span");
const amount = document.createElement("strong"); const amount = document.createElement("strong");
stat.dataset.minerStat = ""; stat.dataset.metricStat = "";
name.textContent = label; name.textContent = label;
amount.textContent = value; amount.textContent = value;
stat.append(name, amount); stat.append(name, amount);
@@ -205,34 +160,114 @@ function createMinerStat(label, value) {
return stat; return stat;
} }
/** @param {string} raw */
function getCoinbaseMessage(raw) {
return (raw.match(/[\x20-\x7e]{2,}/g) ?? [])
.map((value) => value.trim())
.filter((value) => /[A-Za-z0-9]/.test(value))
.join(" · ");
}
/** @param {string} raw */
function createCoinbaseMessage(raw) {
const message = getCoinbaseMessage(raw);
if (!message) return null;
const element = document.createElement("p");
element.dataset.coinbaseMessage = "";
element.textContent = message;
return element;
}
/**
* @param {string} label
* @param {number} height
* @param {number} length
* @param {string} color
*/
function createEpochProgress(label, height, length, color) {
const progress = (height % length) + 1;
const row = document.createElement("div");
const head = document.createElement("div");
const name = document.createElement("span");
const value = document.createElement("strong");
const bar = document.createElement("div");
const done = document.createElement("span");
const remaining = document.createElement("span");
row.dataset.epoch = "";
head.dataset.epochHead = "";
bar.dataset.epochBar = "";
done.dataset.epochSegment = "done";
remaining.dataset.epochSegment = "remaining";
row.style.setProperty("--epoch-color", color);
done.style.setProperty("--share", `${(progress / length) * 100}%`);
remaining.style.setProperty("--share", `${((length - progress) / length) * 100}%`);
name.textContent = label;
value.textContent = `${((progress / length) * 100).toFixed(1)}%`;
head.append(name, value);
bar.append(done, remaining);
row.append(head, bar);
return row;
}
/** @param {Block} block */ /** @param {Block} block */
function createMinerSummary(block) { function createMinerSummary(block) {
const { pool } = block.extras; const { pool } = block.extras;
const pane = document.createElement("div"); const pane = document.createElement("div");
const head = document.createElement("div"); const head = document.createElement("div");
const identity = document.createElement("div"); const identity = document.createElement("div");
const title = document.createElement("div");
const name = document.createElement("strong"); const name = document.createElement("strong");
const blockNumber = document.createElement("span");
const slug = document.createElement("span"); const slug = document.createElement("span");
const stats = document.createElement("div");
const logo = createPoolLogo(pool); const logo = createPoolLogo(pool);
const coinbaseMessage = createCoinbaseMessage(block.extras.coinbaseSignatureAscii);
pane.dataset.minerPane = ""; pane.dataset.minerPane = "";
head.dataset.minerHead = ""; head.dataset.minerHead = "";
identity.dataset.minerIdentity = ""; identity.dataset.minerIdentity = "";
title.dataset.minerTitle = "";
slug.dataset.minerSlug = ""; slug.dataset.minerSlug = "";
stats.dataset.minerStats = "";
logo.dataset.minerLogo = ""; logo.dataset.minerLogo = "";
name.textContent = pool.name; name.textContent = pool.name;
slug.textContent = `#${pool.slug}`; // TODO: remove fallback after the server includes pool.blockNumber everywhere.
identity.append(name, slug); blockNumber.textContent = `#${(pool.blockNumber || 0).toLocaleString()}`;
slug.textContent = pool.slug;
title.append(name, blockNumber);
identity.append(title, slug);
head.append(identity, logo); head.append(identity, logo);
stats.append( pane.append(head, ...(coinbaseMessage ? [coinbaseMessage] : []));
createMinerStat("Difficulty", block.difficulty.toLocaleString()),
createMinerStat("Bits", formatBits(block.bits)), return pane;
createMinerStat("Nonce", block.nonce.toLocaleString()), }
/** @param {Block} block */
function createDifficultySummary(block) {
const pane = document.createElement("div");
pane.dataset.metricList = "";
pane.append(
createMetricStat("Difficulty", block.difficulty.toLocaleString()),
createEpochProgress(
"Difficulty epoch",
block.height,
DIFFICULTY_EPOCH_BLOCKS,
"var(--orange)",
),
createEpochProgress(
"Halving epoch",
block.height,
HALVING_EPOCH_BLOCKS,
"var(--red)",
),
); );
pane.append(head, stats);
return pane; return pane;
} }
@@ -320,16 +355,19 @@ function createRewardPart(type, label, sats, total, price) {
} }
/** /**
* @param {string} label
* @param {number} sats * @param {number} sats
* @param {number} price * @param {number} price
*/ */
function createRewardTotal(sats, price) { function createRewardTotal(label, sats, price) {
const total = document.createElement("div"); const total = document.createElement("div");
const name = document.createElement("span");
const amount = createBtcAmount("strong", sats); const amount = createBtcAmount("strong", sats);
const usd = createSatsUsdAmount(sats, price); const usd = createSatsUsdAmount(sats, price);
total.dataset.rewardTotal = ""; total.dataset.rewardTotal = "";
total.append(amount, usd); name.textContent = label;
total.append(name, amount, usd);
return total; return total;
} }
@@ -365,18 +403,11 @@ function setRewardPreview(rewards, activeKey) {
/** @param {Block["extras"]} extras */ /** @param {Block["extras"]} extras */
function createRewardSummary(extras) { function createRewardSummary(extras) {
const subsidy = extras.reward - extras.totalFees; const subsidy = extras.reward - extras.totalFees;
const rewards = document.createElement("div");
const bar = document.createElement("div"); const bar = document.createElement("div");
const split = createLegendList({ fill: true }); const split = createLegendList({ fill: true });
const rewards = createStatBox(
"Rewards",
[],
[
createRewardTotal(extras.reward, extras.price),
bar,
split,
],
);
rewards.dataset.statBox = "rewards";
appendLegendListItem( appendLegendListItem(
split, split,
createRewardPart("subsidy", "Subsidy", subsidy, extras.reward, extras.price), createRewardPart("subsidy", "Subsidy", subsidy, extras.reward, extras.price),
@@ -390,6 +421,7 @@ function createRewardSummary(extras) {
createRewardSegment("subsidy", subsidy, extras.reward), createRewardSegment("subsidy", subsidy, extras.reward),
createRewardSegment("fees", extras.totalFees, extras.reward), createRewardSegment("fees", extras.totalFees, extras.reward),
); );
rewards.append(createRewardTotal("Rewards", extras.reward, extras.price), bar, split);
rewards.addEventListener("pointerenter", (event) => { rewards.addEventListener("pointerenter", (event) => {
setRewardPreview(rewards, getRewardKey(event.target)); setRewardPreview(rewards, getRewardKey(event.target));
@@ -415,8 +447,8 @@ function createTransactionSummary(block) {
transactions.dataset.blockBox = "tx"; transactions.dataset.blockBox = "tx";
io.dataset.blockIo = ""; io.dataset.blockIo = "";
io.append( io.append(
createInlineBox("Input", extras.totalInputs.toLocaleString()), createInlineBox("Input", extras.totalInputs.toLocaleString(), "input"),
createInlineBox("Output", extras.totalOutputs.toLocaleString()), createInlineBox("Output", extras.totalOutputs.toLocaleString(), "output"),
); );
transactions.append( transactions.append(
createInlineRow("Tx", [block.txCount.toLocaleString()]), createInlineRow("Tx", [block.txCount.toLocaleString()]),
@@ -466,9 +498,10 @@ export function createBlockDetails() {
const header = document.createElement("header"); const header = document.createElement("header");
const titleRow = document.createElement("div"); const titleRow = document.createElement("div");
const title = document.createElement("h1"); const title = document.createElement("h1");
const summary = document.createElement("p"); const date = document.createElement("time");
const meta = document.createElement("div");
const hash = document.createElement("p");
const price = createUsdAmount("output", 0, { const price = createUsdAmount("output", 0, {
size: "title",
tone: "positive", tone: "positive",
}); });
const content = document.createElement("div"); const content = document.createElement("div");
@@ -476,8 +509,12 @@ export function createBlockDetails() {
element.id = "block-details"; element.id = "block-details";
element.hidden = true; element.hidden = true;
titleRow.dataset.blockTitle = ""; titleRow.dataset.blockTitle = "";
titleRow.append(title, price); date.dataset.blockDate = "";
header.append(titleRow, summary); meta.dataset.blockMeta = "";
hash.dataset.blockHashLine = "";
titleRow.append(title, date);
meta.append(hash, price);
header.append(titleRow, meta);
element.append(header, content); element.append(header, content);
/** @param {Block} block */ /** @param {Block} block */
@@ -486,13 +523,10 @@ export function createBlockDetails() {
element.hidden = false; element.hidden = false;
title.replaceChildren(...createTitle(block.height)); title.replaceChildren(...createTitle(block.height));
summary.replaceChildren( date.dateTime = new Date(block.timestamp * 1_000).toISOString();
createHashElement(block.id), date.textContent = formatDateTime(block.timestamp);
document.createElement("br"), hash.replaceChildren(createHashElement(block.id));
formatDateTime(block.timestamp),
);
renderUsdAmount(price, extras.price, { renderUsdAmount(price, extras.price, {
size: "title",
tone: "positive", tone: "positive",
}); });
@@ -503,13 +537,15 @@ export function createBlockDetails() {
appendGroup(content, "Mining", [], [createMinerSummary(block)], false); appendGroup(content, "Mining", [], [createMinerSummary(block)], false);
appendGroup(content, "Difficulty", [], [createDifficultySummary(block)], false);
appendGroup(content, "Rewards", [], [createRewardSummary(extras)], false); appendGroup(content, "Rewards", [], [createRewardSummary(extras)], false);
appendGroup(content, "Block", [], [createTransactionSummary(block)], false); appendGroup(content, "Block", [], [createTransactionSummary(block)], false);
appendGroup(content, "Fees", [], [ appendGroup(content, "Fees", [], [
createFeeChart(extras.feeRange, extras.avgFeeRate, formatFeeRate), createFeeChart(extras.feeRange, extras.avgFeeRate, formatFeeRate),
]); ], false);
} }
return /** @type {const} */ ({ return /** @type {const} */ ({
+161 -94
View File
@@ -22,12 +22,12 @@
display: grid; display: grid;
padding-bottom: 1.25rem; padding-bottom: 1.25rem;
[data-block-title] { :is([data-block-title], [data-block-meta]) {
display: flex; display: grid;
flex-wrap: wrap; grid-template-columns: minmax(0, 1fr) auto;
align-items: baseline;
justify-content: space-between;
gap: 0.35rem 1rem; gap: 0.35rem 1rem;
align-items: baseline;
min-width: 0;
} }
h1 { h1 {
@@ -56,15 +56,28 @@
line-height: var(--line-height-lg); line-height: var(--line-height-lg);
} }
p { [data-block-date],
[data-block-hash-line] {
color: var(--gray); color: var(--gray);
} }
[data-block-date] {
white-space: nowrap;
text-align: right;
}
[data-block-hash-line] {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
} }
> div { > div {
display: grid; display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 1rem; gap: 2rem;
} }
section { section {
@@ -82,7 +95,7 @@
[data-miner-pane] { [data-miner-pane] {
display: grid; display: grid;
gap: 0.75rem; gap: 1rem;
min-width: 0; min-width: 0;
} }
@@ -90,12 +103,21 @@
display: grid; display: grid;
grid-template-columns: minmax(0, 1fr) auto; grid-template-columns: minmax(0, 1fr) auto;
gap: 1rem; gap: 1rem;
align-items: start; align-items: center;
min-width: 0; min-width: 0;
} }
[data-miner-identity] { [data-miner-identity] {
display: grid; display: grid;
gap: 0.125rem;
min-width: 0;
}
[data-miner-title] {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
align-items: baseline;
min-width: 0; min-width: 0;
> strong { > strong {
@@ -106,29 +128,49 @@
font-weight: 450; font-weight: 450;
line-height: var(--line-height-sm); line-height: var(--line-height-sm);
} }
> span {
color: var(--gray);
font-size: var(--font-size-sm);
line-height: var(--line-height-sm);
}
} }
[data-miner-slug] { [data-miner-slug] {
min-width: 0; min-width: 0;
overflow-wrap: anywhere; overflow-wrap: anywhere;
color: var(--gray); color: var(--gray);
font-size: var(--font-size-xs); font-size: var(--font-size-sm);
line-height: var(--line-height-xs); line-height: var(--line-height-sm);
} }
[data-miner-logo] { [data-miner-logo] {
width: 2rem; width: 1.25rem;
height: 2rem; height: 1.25rem;
object-fit: contain; object-fit: contain;
} }
[data-miner-stats] { [data-coinbase-message] {
min-width: 0;
overflow: hidden;
color: var(--white);
font-size: var(--font-size-sm);
font-style: italic;
line-height: var(--line-height-sm);
text-overflow: ellipsis;
white-space: nowrap;
}
}
&:is([data-group="mining"], [data-group="difficulty"]) {
[data-metric-list] {
display: grid; display: grid;
gap: 0.35rem; gap: 0.5rem;
min-width: 0; min-width: 0;
} }
[data-miner-stat] { [data-metric-stat] {
display: grid; display: grid;
grid-template-columns: minmax(5.5rem, auto) minmax(0, 1fr); grid-template-columns: minmax(5.5rem, auto) minmax(0, 1fr);
gap: 0.75rem; gap: 0.75rem;
@@ -152,6 +194,61 @@
text-align: right; text-align: right;
} }
} }
[data-epoch] {
display: grid;
gap: 0.25rem;
min-width: 0;
}
[data-epoch-head] {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 0.75rem;
align-items: center;
min-width: 0;
> span {
min-width: 0;
overflow-wrap: anywhere;
color: var(--epoch-color);
font-size: var(--font-size-xs);
line-height: var(--line-height-xs);
text-transform: uppercase;
}
strong {
color: var(--white);
font-size: var(--font-size-sm);
font-weight: 450;
line-height: var(--line-height-sm);
text-align: right;
}
}
[data-epoch-bar] {
display: flex;
gap: 0.125rem;
height: 0.5rem;
min-width: 0;
}
[data-epoch-segment] {
width: var(--share);
border-radius: 0.125rem;
&[data-epoch-segment="done"] {
background: var(--epoch-color);
}
&[data-epoch-segment="remaining"] {
background: color-mix(in oklch, var(--gray) 35%, transparent);
}
}
}
&[data-group="difficulty"] {
--section-color: var(--orange);
} }
&[data-group="block"] { &[data-group="block"] {
@@ -169,59 +266,9 @@
&[data-group="rewards"] { &[data-group="rewards"] {
[data-stat-box] { [data-stat-box] {
display: grid; display: grid;
gap: 0.75rem;
min-width: 0;
border: 1px solid
color-mix(in oklch, var(--section-color) 28%, transparent);
border-radius: 0.25rem;
padding: 0.75rem;
h3 {
color: var(--section-color);
font-family: var(--font-mono);
font-size: var(--font-size-xs);
font-weight: 450;
line-height: var(--line-height-xs);
text-transform: uppercase;
}
[data-stat-box] {
border-color: color-mix(
in oklch,
var(--section-color) 18%,
transparent
);
}
}
[data-stats] {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 0.5rem; gap: 0.5rem;
min-width: 0; min-width: 0;
} }
[data-stat] {
display: grid;
gap: 0.25rem;
min-width: 0;
> span {
color: var(--section-color);
font-size: var(--font-size-xs);
line-height: var(--line-height-xs);
text-transform: uppercase;
}
strong {
min-width: 0;
overflow-wrap: anywhere;
color: var(--white);
font-size: var(--font-size-sm);
font-weight: 450;
line-height: var(--line-height-sm);
}
}
} }
&[data-group="block"] { &[data-group="block"] {
@@ -230,16 +277,20 @@
gap: 0.5rem; gap: 0.5rem;
min-width: 0; min-width: 0;
border: 1px solid border: 1px solid
color-mix(in oklch, var(--section-color) 28%, transparent); color-mix(in oklch, var(--section-color) 35%, transparent);
border-radius: 0.25rem; border-radius: 0.25rem;
padding: 0.75rem; padding: 0.75rem;
[data-block-box] { &[data-block-box="tx"] {
border-color: color-mix( border-color: color-mix(in oklch, var(--orange) 35%, transparent);
in oklch, }
var(--section-color) 18%,
transparent &[data-block-box="input"] {
); border-color: color-mix(in oklch, var(--yellow) 55%, transparent);
}
&[data-block-box="output"] {
border-color: color-mix(in oklch, var(--red) 55%, transparent);
} }
} }
@@ -263,7 +314,7 @@
align-items: center; align-items: center;
justify-content: flex-end; justify-content: flex-end;
min-width: 0; min-width: 0;
color: var(--white); color: var(--section-color);
font-size: var(--font-size-sm); font-size: var(--font-size-sm);
font-weight: 450; font-weight: 450;
line-height: var(--line-height-sm); line-height: var(--line-height-sm);
@@ -274,38 +325,55 @@
[data-block-io] { [data-block-io] {
display: grid; display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
gap: 0.5rem; gap: 0.75rem;
min-width: 0; min-width: 0;
[data-block-box] { [data-block-box] {
aspect-ratio: 1 / 1; align-content: center;
place-content: center;
padding: 0.5rem; padding: 0.5rem;
} }
[data-inline-row] { [data-inline-row] {
grid-template-columns: minmax(0, 1fr); grid-template-columns: auto auto;
justify-items: center; justify-content: space-between;
gap: 0.25rem; gap: 0.5rem;
width: 100%;
strong {
justify-content: center;
text-align: center;
}
} }
} }
[data-block-box="tx"] > [data-inline-row] {
> span,
strong {
color: var(--orange);
}
}
:is([data-block-box="input"], [data-block-box="output"]) > [data-inline-row] {
> span,
strong {
color: var(--block-box-color);
}
}
[data-block-box="input"] {
--block-box-color: var(--yellow);
}
[data-block-box="output"] {
--block-box-color: var(--red);
}
} }
&[data-group="rewards"] { &[data-group="rewards"] {
[data-reward-total] { [data-reward-total] {
display: grid; display: grid;
gap: 0.25rem; gap: 0.125rem;
justify-items: center; justify-items: start;
min-width: 0; min-width: 0;
color: var(--gray); color: var(--gray);
font-size: var(--font-size-xs); font-size: var(--font-size-xs);
line-height: var(--line-height-xs); line-height: var(--line-height-xs);
text-align: center; text-align: left;
strong { strong {
min-width: 0; min-width: 0;
@@ -315,6 +383,11 @@
font-weight: 450; font-weight: 450;
line-height: var(--line-height-sm); line-height: var(--line-height-sm);
} }
> span:first-child {
color: var(--section-color);
text-transform: uppercase;
}
} }
[data-reward-bar] { [data-reward-bar] {
@@ -416,12 +489,6 @@
grid-column: auto; grid-column: auto;
} }
section[data-group="rewards"] {
[data-stats] {
grid-template-columns: minmax(0, 1fr);
}
}
dl > div { dl > div {
grid-template-columns: minmax(0, 1fr); grid-template-columns: minmax(0, 1fr);
gap: 0.15rem; gap: 0.15rem;