From d68904fec061c9c11812ae953aafcdd4f8896e8c Mon Sep 17 00:00:00 2001 From: natsoni Date: Mon, 8 Apr 2024 15:01:38 +0900 Subject: [PATCH] More contrast theme fixes --- frontend/src/app/app.constants.ts | 16 +- .../block-overview-graph.component.ts | 32 +- .../block-overview-graph/block-scene.ts | 14 +- .../block-overview-graph/tx-view.ts | 10 +- .../components/block-overview-graph/utils.ts | 82 +- .../clock-face/clock-face.component.scss | 2 +- .../lbtc-pegs-graph.component.ts | 8 +- frontend/src/theme-contrast.scss | 1151 ----------------- 8 files changed, 106 insertions(+), 1209 deletions(-) diff --git a/frontend/src/app/app.constants.ts b/frontend/src/app/app.constants.ts index a8ba96ed4..bd81d02c0 100644 --- a/frontend/src/app/app.constants.ts +++ b/frontend/src/app/app.constants.ts @@ -70,14 +70,14 @@ export const contrastMempoolFeeColors = [ 'edac31', 'f6ad2b', 'ffaf24', - 'ffaf24', - 'ffaf24', - 'ffaf24', - 'ffaf24', - 'ffaf24', - 'ffaf24', - 'ffaf24', - 'ffaf24', + 'ffb01e', + 'ffb118', + 'ffb212', + 'ffb30c', + 'ffb406', + 'ffb500', + 'ffb600', + 'ffb700', ]; export const chartColors = [ diff --git a/frontend/src/app/components/block-overview-graph/block-overview-graph.component.ts b/frontend/src/app/components/block-overview-graph/block-overview-graph.component.ts index f6847c93a..d8b57e72d 100644 --- a/frontend/src/app/components/block-overview-graph/block-overview-graph.component.ts +++ b/frontend/src/app/components/block-overview-graph/block-overview-graph.component.ts @@ -9,7 +9,7 @@ import { Price } from '../../services/price.service'; import { StateService } from '../../services/state.service'; import { ThemeService } from 'src/app/services/theme.service'; import { Subscription } from 'rxjs'; -import { defaultColorFunction, setOpacity, defaultFeeColors, defaultAuditFeeColors, defaultMarginalFeeColors, defaultAuditColors } from './utils'; +import { defaultColorFunction, setOpacity, defaultAuditColors, defaultColors, ageColorFunction, contrastColorFunction, contrastAuditColors, contrastColors } from './utils'; import { ActiveFilter, FilterMode, toFlags } from '../../shared/filters.utils'; import { detectWebGL } from '../../shared/graphs.utils'; @@ -21,9 +21,6 @@ const unmatchedAuditColors = { prioritized: setOpacity(defaultAuditColors.prioritized, unmatchedOpacity), accelerated: setOpacity(defaultAuditColors.accelerated, unmatchedOpacity), }; -const unmatchedContrastFeeColors = contrastFeeColors.map(c => setOpacity(c, unmatchedOpacity)); -const unmatchedContrastAuditFeeColors = contrastAuditFeeColors.map(c => setOpacity(c, unmatchedOpacity)); -const unmatchedContrastMarginalFeeColors = contrastMarginalFeeColors.map(c => setOpacity(c, unmatchedOpacity)); const unmatchedContrastAuditColors = { censored: setOpacity(contrastAuditColors.censored, unmatchedOpacity), missing: setOpacity(contrastAuditColors.missing, unmatchedOpacity), @@ -580,14 +577,27 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On getFilterColorFunction(flags: bigint, gradient: 'fee' | 'age'): ((tx: TxView) => Color) { return (tx: TxView) => { if ((this.filterMode === 'and' && (tx.bigintFlags & flags) === flags) || (this.filterMode === 'or' && (flags === 0n || (tx.bigintFlags & flags) > 0n))) { - return defaultColorFunction(tx); + if (this.themeService.theme !== 'contrast') { + return (gradient === 'age') ? ageColorFunction(tx, defaultColors.fee, defaultAuditColors, this.relativeTime || (Date.now() / 1000)) : defaultColorFunction(tx, defaultColors.fee, defaultAuditColors, this.relativeTime || (Date.now() / 1000)); + } else { + return (gradient === 'age') ? ageColorFunction(tx, contrastColors.fee, contrastAuditColors, this.relativeTime || (Date.now() / 1000)) : contrastColorFunction(tx, contrastColors.fee, contrastAuditColors, this.relativeTime || (Date.now() / 1000)); + } } else { - return defaultColorFunction( - tx, - defaultColors.unmatchedfee, - unmatchedAuditColors, - this.relativeTime || (Date.now() / 1000) - ); + if (this.themeService.theme !== 'contrast') { + return (gradient === 'age') ? { r: 1, g: 1, b: 1, a: 0.05 } : defaultColorFunction( + tx, + defaultColors.unmatchedfee, + unmatchedAuditColors, + this.relativeTime || (Date.now() / 1000) + ); + } else { + return (gradient === 'age') ? { r: 1, g: 1, b: 1, a: 0.05 } : contrastColorFunction( + tx, + contrastColors.unmatchedfee, + unmatchedContrastAuditColors, + this.relativeTime || (Date.now() / 1000) + ); + } } }; } diff --git a/frontend/src/app/components/block-overview-graph/block-scene.ts b/frontend/src/app/components/block-overview-graph/block-scene.ts index 4651cea34..05abddb03 100644 --- a/frontend/src/app/components/block-overview-graph/block-scene.ts +++ b/frontend/src/app/components/block-overview-graph/block-scene.ts @@ -69,7 +69,11 @@ export default class BlockScene { } setColorFunction(colorFunction: ((tx: TxView) => Color) | null): void { - this.getColor = colorFunction || defaultColorFunction; + this.theme.theme !== 'default' ? this.getColor = colorFunction || contrastColorFunction : this.getColor = colorFunction || defaultColorFunction; + this.updateAllColors(); + } + + updateAllColors(): void { this.dirty = true; if (this.initialised && this.scene) { this.updateColors(performance.now(), 50); @@ -92,7 +96,7 @@ export default class BlockScene { }); this.layout = new BlockLayout({ width: this.gridWidth, height: this.gridHeight }); txs.forEach(tx => { - const txView = new TxView(tx, this, this.theme); + const txView = new TxView(tx, this); this.txs[tx.txid] = txView; this.place(txView); this.saveGridToScreenPosition(txView); @@ -138,7 +142,7 @@ export default class BlockScene { }); txs.forEach(tx => { if (!this.txs[tx.txid]) { - this.txs[tx.txid] = new TxView(tx, this, this.theme); + this.txs[tx.txid] = new TxView(tx, this); } }); @@ -180,7 +184,7 @@ export default class BlockScene { if (resetLayout) { add.forEach(tx => { if (!this.txs[tx.txid]) { - this.txs[tx.txid] = new TxView(tx, this, this.theme); + this.txs[tx.txid] = new TxView(tx, this); } }); this.layout = new BlockLayout({ width: this.gridWidth, height: this.gridHeight }); @@ -200,7 +204,7 @@ export default class BlockScene { // try to insert new txs directly const remaining = []; - add.map(tx => new TxView(tx, this, this.theme)).sort(feeRateDescending).forEach(tx => { + add.map(tx => new TxView(tx, this)).sort(feeRateDescending).forEach(tx => { if (!this.tryInsertByFee(tx)) { remaining.push(tx); } diff --git a/frontend/src/app/components/block-overview-graph/tx-view.ts b/frontend/src/app/components/block-overview-graph/tx-view.ts index 0317d7cbf..742c305f5 100644 --- a/frontend/src/app/components/block-overview-graph/tx-view.ts +++ b/frontend/src/app/components/block-overview-graph/tx-view.ts @@ -5,8 +5,6 @@ import { hexToColor } from './utils'; import BlockScene from './block-scene'; import { TransactionStripped } from '../../interfaces/node-api.interface'; import { TransactionFlags } from '../../shared/filters.utils'; -import { feeLevels } from '../../app.constants'; -import { ThemeService } from 'src/app/services/theme.service'; const hoverTransitionTime = 300; const defaultHoverColor = hexToColor('1bd8f4'); @@ -38,7 +36,6 @@ export default class TxView implements TransactionStripped { status?: 'found' | 'missing' | 'sigop' | 'fresh' | 'freshcpfp' | 'added' | 'prioritized' | 'censored' | 'selected' | 'rbf' | 'accelerated'; context?: 'projected' | 'actual'; scene?: BlockScene; - theme: ThemeService; initialised: boolean; vertexArray: FastVertexArray; @@ -53,7 +50,7 @@ export default class TxView implements TransactionStripped { dirty: boolean; - constructor(tx: TransactionStripped, scene: BlockScene, theme: ThemeService) { + constructor(tx: TransactionStripped, scene: BlockScene) { this.scene = scene; this.context = tx.context; this.txid = tx.txid; @@ -69,7 +66,6 @@ export default class TxView implements TransactionStripped { this.bigintFlags = tx.flags ? (BigInt(tx.flags) | (this.acc ? TransactionFlags.acceleration : 0n)): 0n; this.initialised = false; this.vertexArray = scene.vertexArray; - this.theme = theme; this.hover = false; @@ -142,10 +138,10 @@ export default class TxView implements TransactionStripped { // Temporarily override the tx color // returns minimum transition end time - setHover(hoverOn: boolean, color: Color | void): number { + setHover(hoverOn: boolean, color: Color | void = defaultHoverColor): number { if (hoverOn) { this.hover = true; - this.hoverColor = color || defaultHoverColor; + this.hoverColor = color; this.sprite.update({ ...this.hoverColor, diff --git a/frontend/src/app/components/block-overview-graph/utils.ts b/frontend/src/app/components/block-overview-graph/utils.ts index 62fbe5e8e..ec6181853 100644 --- a/frontend/src/app/components/block-overview-graph/utils.ts +++ b/frontend/src/app/components/block-overview-graph/utils.ts @@ -45,9 +45,28 @@ interface ColorPalette { } // precomputed colors -export const defaultFeeColors = mempoolFeeColors.map(hexToColor); -export const defaultAuditFeeColors = defaultFeeColors.map((color) => darken(desaturate(color, 0.3), 0.9)); -export const defaultMarginalFeeColors = defaultFeeColors.map((color) => darken(desaturate(color, 0.8), 1.1)); +const defaultColors: { [key: string]: ColorPalette } = { + fee: { + base: defaultMempoolFeeColors.map(hexToColor), + audit: [], + marginal: [], + baseLevel: (tx: TxView, rate: number) => feeLevels.findIndex((feeLvl) => Math.max(1, rate) < feeLvl) - 1 + }, +} +for (const key in defaultColors) { + const base = defaultColors[key].base; + defaultColors[key].audit = base.map((color) => darken(desaturate(color, 0.3), 0.9)); + defaultColors[key].marginal = base.map((color) => darken(desaturate(color, 0.8), 1.1)); + defaultColors['unmatched' + key] = { + base: defaultColors[key].base.map(c => setOpacity(c, 0.2)), + audit: defaultColors[key].audit.map(c => setOpacity(c, 0.2)), + marginal: defaultColors[key].marginal.map(c => setOpacity(c, 0.2)), + baseLevel: defaultColors[key].baseLevel, + }; +} + +export { defaultColors as defaultColors }; + export const defaultAuditColors = { censored: hexToColor('f344df'), missing: darken(desaturate(hexToColor('f344df'), 0.3), 0.7), @@ -56,9 +75,28 @@ export const defaultAuditColors = { accelerated: hexToColor('8f5ff6'), }; -export const contrastFeeColors = contrastMempoolFeeColors.map(hexToColor); -export const contrastAuditFeeColors = contrastFeeColors.map((color) => darken(desaturate(color, 0.3), 0.9)); -export const contrastMarginalFeeColors = contrastFeeColors.map((color) => darken(desaturate(color, 0.8), 1.1)); +const contrastColors: { [key: string]: ColorPalette } = { + fee: { + base: contrastMempoolFeeColors.map(hexToColor), + audit: [], + marginal: [], + baseLevel: (tx: TxView, rate: number) => feeLevels.findIndex((feeLvl) => Math.max(1, rate) < feeLvl) - 1 + }, +} +for (const key in contrastColors) { + const base = contrastColors[key].base; + contrastColors[key].audit = base.map((color) => darken(desaturate(color, 0.3), 0.9)); + contrastColors[key].marginal = base.map((color) => darken(desaturate(color, 0.8), 1.1)); + contrastColors['unmatched' + key] = { + base: contrastColors[key].base.map(c => setOpacity(c, 0.2)), + audit: contrastColors[key].audit.map(c => setOpacity(c, 0.2)), + marginal: contrastColors[key].marginal.map(c => setOpacity(c, 0.2)), + baseLevel: contrastColors[key].baseLevel, + }; +} + +export { contrastColors as contrastColors }; + export const contrastAuditColors = { censored: hexToColor('ffa8ff'), missing: darken(desaturate(hexToColor('ffa8ff'), 0.3), 0.7), @@ -74,8 +112,8 @@ export function defaultColorFunction( relativeTime?: number, ): Color { const rate = tx.fee / tx.vsize; // color by simple single-tx fee rate - const feeLevelIndex = feeLevels.findIndex((feeLvl) => Math.max(1, rate) < feeLvl) - 1; - const feeLevelColor = feeColors[feeLevelIndex] || feeColors[mempoolFeeColors.length - 1]; + const levelIndex = colors.baseLevel(tx, rate, relativeTime || (Date.now() / 1000)); + const levelColor = colors.base[levelIndex] || colors.base[defaultMempoolFeeColors.length - 1]; // Normal mode if (!tx.scene?.highlightingEnabled) { if (tx.acc) { @@ -92,7 +130,7 @@ export function defaultColorFunction( case 'missing': case 'sigop': case 'rbf': - return marginalFeeColors[feeLevelIndex] || marginalFeeColors[mempoolFeeColors.length - 1]; + return colors.marginal[levelIndex] || colors.marginal[defaultMempoolFeeColors.length - 1]; case 'fresh': case 'freshcpfp': return auditColors.missing; @@ -101,12 +139,12 @@ export function defaultColorFunction( case 'prioritized': return auditColors.prioritized; case 'selected': - return marginalFeeColors[feeLevelIndex] || marginalFeeColors[mempoolFeeColors.length - 1]; + return colors.marginal[levelIndex] || colors.marginal[defaultMempoolFeeColors.length - 1]; case 'accelerated': return auditColors.accelerated; case 'found': if (tx.context === 'projected') { - return auditFeeColors[feeLevelIndex] || auditFeeColors[mempoolFeeColors.length - 1]; + return colors.audit[levelIndex] || colors.audit[defaultMempoolFeeColors.length - 1]; } else { return levelColor; } @@ -119,17 +157,27 @@ export function defaultColorFunction( } } +export function contrastColorFunction( + tx: TxView, + colors: { base: Color[], audit: Color[], marginal: Color[], baseLevel: (tx: TxView, rate: number, time: number) => number } = contrastColors.fee, + auditColors: { [status: string]: Color } = contrastAuditColors, + relativeTime?: number, +): Color { + return defaultColorFunction(tx, colors, auditColors, relativeTime); +} + export function ageColorFunction( tx: TxView, colors: { base: Color[], audit: Color[], marginal: Color[], baseLevel: (tx: TxView, rate: number, time: number) => number } = defaultColors.fee, auditColors: { [status: string]: Color } = defaultAuditColors, relativeTime?: number, + theme?: string, ): Color { if (tx.acc || tx.status === 'accelerated') { return auditColors.accelerated; } - const color = defaultColorFunction(tx, colors, auditColors, relativeTime); + const color = theme !== 'contrast' ? defaultColorFunction(tx, colors, auditColors, relativeTime) : contrastColorFunction(tx, colors, auditColors, relativeTime); const ageLevel = (!tx.time ? 0 : (0.8 * Math.tanh((1 / 15) * Math.log2((Math.max(1, 0.6 * ((relativeTime - tx.time) - 60))))))); return { @@ -139,13 +187,3 @@ export function ageColorFunction( a: color.a * (1 - ageLevel) }; } - -export function contrastColorFunction( - tx: TxView, - feeColors: Color[] = contrastFeeColors, - auditFeeColors: Color[] = contrastAuditFeeColors, - marginalFeeColors: Color[] = contrastMarginalFeeColors, - auditColors: { [status: string]: Color } = contrastAuditColors -): Color { - return defaultColorFunction(tx, feeColors, auditFeeColors, marginalFeeColors, auditColors); -} \ No newline at end of file diff --git a/frontend/src/app/components/clock-face/clock-face.component.scss b/frontend/src/app/components/clock-face/clock-face.component.scss index 904de9d96..e2bb215d4 100644 --- a/frontend/src/app/components/clock-face/clock-face.component.scss +++ b/frontend/src/app/components/clock-face/clock-face.component.scss @@ -14,7 +14,7 @@ height: 100%; .face { - fill: #11131f; + fill: var(--active-bg); } } diff --git a/frontend/src/app/components/lbtc-pegs-graph/lbtc-pegs-graph.component.ts b/frontend/src/app/components/lbtc-pegs-graph/lbtc-pegs-graph.component.ts index f6ecb950e..4359d8fa3 100644 --- a/frontend/src/app/components/lbtc-pegs-graph/lbtc-pegs-graph.component.ts +++ b/frontend/src/app/components/lbtc-pegs-graph/lbtc-pegs-graph.component.ts @@ -104,7 +104,7 @@ export class LbtcPegsGraphComponent implements OnInit, OnChanges { type: 'line', }, formatter: (params: any) => { - const colorSpan = (color: string) => ``; + const colorSpan = (color: string) => ``; let itemFormatted = '
' + params[0].axisValue + '
'; for (let index = params.length - 1; index >= 0; index--) { const item = params[index]; @@ -137,7 +137,7 @@ export class LbtcPegsGraphComponent implements OnInit, OnChanges { splitLine: { lineStyle: { type: 'dotted', - color: 'var(--transparent-fg)', + color: '#ffffff66', opacity: 0.25, } } @@ -153,11 +153,11 @@ export class LbtcPegsGraphComponent implements OnInit, OnChanges { showSymbol: false, areaStyle: { opacity: 0.2, - color: 'var(--liquid)', + color: '#116761', }, lineStyle: { width: 2, - color: 'var(--liquid)', + color: '#116761', }, }, { diff --git a/frontend/src/theme-contrast.scss b/frontend/src/theme-contrast.scss index 24d365789..6c5023466 100644 --- a/frontend/src/theme-contrast.scss +++ b/frontend/src/theme-contrast.scss @@ -56,8 +56,6 @@ $dropdown-link-hover-bg: $active-bg; $dropdown-link-active-color: $fg; $dropdown-link-active-bg: $active-bg; -@import "bootstrap/scss/bootstrap"; - :root { --bg: #{$bg}; --active-bg: #{$active-bg}; @@ -100,1152 +98,3 @@ $dropdown-link-active-bg: $active-bg; --grey: #7e7e7e; --tooltip-grey: #b1b1b1; } - -html, body { - height: 100%; -} - -body { - background-color: var(--active-bg); - min-width: 375px; - padding-bottom: 60px; -} - -.container { - position: relative; -} - -main { - margin-top: 24px; -} - -.full-height { - @media (max-width: 767.98px) { - min-height: 100vh; - } -} - -:focus { - outline: none !important; -} - -.box { - min-height: 1px; - padding: 1.25rem; - position: relative; - min-width: 0; - word-wrap: break-word; - background-color: var(--box-bg); - background-clip: border-box; - border: 1px solid rgba(0,0,0,.125); - box-shadow: 0.125rem 0.125rem 0.25rem rgba(0,0,0,0.075); -} - -.preview-box { - min-height: 520px; - padding: 1rem 3rem 1.5rem; -} - -@media (max-width: 767.98px) { - .box { - padding: 0.75rem; - } -} - -.navbar-nav.liquid > .active { - background-color: var(--liquid) !important; -} - -.navbar-nav.testnet > .active { - background-color: var(--testnet) !important; -} - -.navbar-nav.signet > .active { - background-color: var(--signet) !important; -} - -.navbar-nav.liquidtestnet > .active { - background-color: var(--liquidtestnet) !important; -} - -.form-control { - color: #fff; - background-color: var(--secondary); - border: 1px solid rgba(17, 19, 31, 0.2); -} - -.form-control:focus { - color: #fff; - background-color: var(--secondary); -} - -.btn-purple { - background-color: var(--tertiary); - border-color: var(--tertiary); -} - -.btn-purple:not(:disabled):not(.disabled):active, .btn-purple:not(:disabled):not(.disabled).active, .show > .btn-purple.dropdown-toggle { - color: #fff; - background-color: #4d2d77; - border-color: #472a6e; -} - -.btn-purple:focus, .btn-purple.focus { - color: #fff; - background-color: #533180; - border-color: #4d2d77; - box-shadow: 0 0 0 0.2rem rgb(124 88 171 / 50%); -} - -.btn-purple:hover { - color: #fff; - background-color: #533180; - border-color: #4d2d77; -} - -.form-control.form-control-secondary { - color: var(--fg); - background-color: var(--secondary); - border: 1px solid var(--secondary); -} -.form-control.form-control-secondary:focus { - color: var(--fg); -} - -.h2-match-table { - padding-left: .65rem; -} - -.skeleton-loader { - box-sizing: border-box; - /** - * `overflow` and `position` are required steps to make sure - * the component respects the specified dimensions - * given via `theme` object @Input attribute - */ - overflow: hidden; - position: relative; - - animation: progress 2s ease-in-out infinite; - background: #2e324e no-repeat; - background-image: linear-gradient( - 90deg, - rgba(255, 255, 255, 0), - #5d6182, - rgba(255, 255, 255, 0) - ); - background-size: 200px 100%; - border-radius: 4px; - width: 100%; - height: 14px; - display: inline-block; - - &:after, - &:before { - box-sizing: border-box; - } - - &.circle { - width: 40px; - height: 40px; - margin: 5px; - border-radius: 50%; - } -} - -@keyframes progress { - 0% { - background-position: -200px 0; - } - 100% { - background-position: calc(200px + 100%) 0; - } -} - -.symbol { - color: var(--transparent-fg); - font-size: 12px; -} - -.progress-text { - span { - color: var(--fg) !important; - } -} - -.block-size, .blocks-container { - .symbol { - font-size: 16px; - color: var(--fg) !important; - } -} - -.break-all { - white-space: normal; - word-break: break-all; -} - -.title-block { - color: var(--fg); - padding-top: 20px; - padding-bottom: 10px; - border-top: 3px solid var(--fg); - display: flex; - flex-direction: row; - justify-content: space-between; -} - -.title-address, .title-asset { - color: var(--fg); - padding-bottom: 10px; - display: flex; - flex-direction: column; - margin-bottom: 7px; - @media (min-width: 576px) { - flex-direction: row; - margin-bottom: 0px; - } - h1 { - line-height: 1; - } -} - -.smaller-text { - font-size: 14px; -} - -.nowrap { - white-space: nowrap; -} - -.table-xs th, .table-xs td { - padding: 0.1rem; -} - -.table { - margin-bottom: 0; - font-size: 0.9rem; - @media (min-width: 576px) { - font-size: 1rem; - } -} - -.table-fixed { - table-layout: fixed; -} - -.close { - color: var(--fg); -} - -.close:hover { - color: var(--fg); -} - -.white-color { - color: white; -} - -.green-color { - color: var(--green); -} - -.red-color { - color: var(--red); -} - -.yellow-color { - color: var(--yellow); -} - -.table-striped tbody tr:nth-of-type(odd) { - background-color: var(--stat-box-bg); -} - -.bordertop { - border-top: 1px solid #4c4c4c; -} - -.smaller-text { - font-size: 14px; -} - -html:lang(ru) .card-title { - font-size: 0.9rem; -} - -/* MEMPOOL CHARTS - start */ - -.mempool-wrapper-tooltip-chart { - height: 250px; -} - -.echarts { - height: 100%; - min-height: 180px; -} - -.tx-wrapper-tooltip-chart, -.fees-wrapper-tooltip-chart { - background: rgba($active-bg, 0.95); - border-radius: 4px; - box-shadow: 1px 1px 10px rgba(0,0,0,0.5); - color: var(--tooltip-grey); - display: flex; - flex-direction: column; - justify-content: space-between; - padding: 10px 15px; - text-align: left; - width: 200px; - thead { - th { - font-size: 9px; - color: var(--tooltip-grey); - text-align: right; - &:first-child { - text-align: left; - left: -1px; - position: relative; - } - &:nth-child(4) { - display: none; - } - } - } - .title { - font-size: 12px; - font-weight: 700; - margin-bottom: 2px; - color: var(--fg); - .total-value { - float: right; - } - } - .active { - color: yellow !important; - .value, - .total-partial { - color: yellow !important; - .symbol { - color: yellow !important; - } - } - } - .item { - line-height: 0.8; - .indicator-container { - .indicator { - display: inline-block; - margin-right: 5px; - border-radius: 2px; - margin-top: 5px; - width: 9px; - height: 9px; - } - } - .value { - text-align: right; - .symbol { - color: #7e7e7e; - font-size: 9px !important; - } - } - .symbol { - font-size: 9px; - } - .total-partial { - font-size: 10px; - width: 58px; - text-align: right; - } - .total-percentage-bar { - padding-left: 8px; - } - .total-progress-percentage { - width: 45px; - height: 5px; - text-align: right; - display: none; - } - .total-progress-sum { - width: 58px; - text-align: right; - } - } - .total-label { - width: 100%; - text-align: left; - color: var(--fg); - margin-top: 5px; - font-size: 14px; - span { - float: right; - } - .symbol { - margin-left: 3px; - font-size: 9px; - position: relative; - top: 2px; - } - } - thead { - th { - font-size: 9px; - color: var(--tooltip-grey); - text-align: right; - &:first-child { - text-align: left; - left: -1px; - position: relative; - } - &:nth-child(4) { - display: none; - } - &:nth-child(5) { - display: none; - } - } - } - .total-percentage-bar { - margin: auto; - width: 35px; - position: relative; - span { - display: block; - background: #282d47; - height: 5px; - border-radius: 2px; - } - } - .total-parcial-active { - text-align: right; - margin: 5px auto 5px; - padding-left: 0px; - span { - font-size: 10px; - } - .symbol { - font-size: 9px; - } - .total-percentage-bar { - width: 100%; - span { - transition: 1000 all ease-in-out; - } - } - .progress-percentage { - float: left; - } - } -} - -.tx-wrapper-tooltip-chart { - width: 115px; - .item { - display: flex; - } - .value { - margin-top: 5px; - } - .indicator-container { - border-radius: 2px; - } -} - -.fee-distribution-chart { - height: 265px; -} - -.fees-wrapper-tooltip-chart { - .item { - font-size: 9px; - line-height: 0.8; - margin: 0px; - } - .indicator { - margin-right: 5px !important; - border-radius: 1px !important; - margin-top: 0px !important; - } -} - -.fees-wrapper-tooltip-chart-advanced, -.tx-wrapper-tooltip-chart-advanced { - width: 300px; - background: rgba($bg, 0.98); - - thead { - th { - &:nth-child(4) { - display: table-cell; - } - &:nth-child(5) { - display: table-cell; - } - } - } - .title { - font-size: 15px; - margin-bottom: 5px; - } - .item { - line-height: 1.25; - font-size: 11px; - .value { - width: 60px; - .symbol { - font-size: 9px !important; - } - } - .total-partial { - font-size: 10px; - width: 58px; - text-align: right; - } - .total-progress-percentage { - width: 65px; - height: 4px; - padding: 0px 5px; - display: table-cell !important; - border-radius: 4px; - } - .total-progress-sum { - width: 65px; - height: 4px; - padding: 0px 5px; - border-radius: 4px; - } - .total-progress-percentage-bar, - .total-progress-sum-bar { - width: 35px; - height: 4px; - div { - width: 100%; - border-radius: 4px; - display: block; - background: #29324c94; - } - span { - height: 4px; - border-radius: 4px; - display: block; - } - } - } - .total-label { - margin-top: 5px; - font-size: 14px; - span { - float: right; - } - } - .total-parcial-active { - text-align: right; - margin: 5px auto 5px; - span { - font-size: 10px; - } - .total-percentage-bar { - width: 100%; - left: 0; - span { - transition: 1000 all ease-in-out; - } - } - } - .total-percentage-bar-background { - background-color: #282d47; - } -} - -.tx-wrapper-tooltip-chart-advanced { - .indicator-container { - .indicator { - margin-right: 5px; - border-radius: 0px; - margin-top: 5px; - width: 9px; - height: 9px; - } - } -} - - -/* MEMPOOL CHARTS - end */ - -.grow { - flex-grow: 1; -} - -hr { - border-top: 1px solid rgba(255, 255, 255, 0.1); -} - -tr { - white-space: nowrap; -} - -h1, h2, h3 { - margin-bottom: 1rem; -} - -@media (max-width: 767.98px) { - h1 { - font-size: 2rem; - } - h2 { - font-size: 1.50rem; - } -} - -@media (min-width: 992px) { - .lg-inline { - display: inline-block; - } -} - -@media (min-width: 768px) { - .d-md-inline { - display: inline-block; - } -} - -.header-bg { - font-size: 14px; -} - -.progress { - position: relative; -} - -.progress-text { - position: absolute; - top: 8.5px; - width: 100%; - text-align: center; -} - -.progress-mempool { - background: repeating-linear-gradient(to right, $secondary, $secondary 0%, $primary 0%, var(--mainnet-alt) 100%); -} - -.progress-mempool.testnet { - background: repeating-linear-gradient(to right, $secondary, $secondary 0%, var(--testnet) 0%, var(--testnet-alt) 100%); -} - -.progress-mempool.signet { - background: repeating-linear-gradient(to right, $secondary, $secondary 0%, var(--signet) 0%, var(--signet-alt) 100%); -} - -.progress-mempool.liquid { - background: repeating-linear-gradient(to right, $secondary, $secondary 0%, var(--liquid) 0%, var(--testnet-alt) 100%); -} - -.progress-dark { - background-color: var(--stat-box-bg); -} - -.progress-darklight { - background-color: var(--box-bg); -} - -.progress-light { - background-color: #2e324e; -} - -.progress.progress-health { - background: repeating-linear-gradient(to right, $secondary, $secondary 0%, $primary 0%, $success 100%); - justify-content: flex-end; -} - -.progress-bar.progress-bar-health { - background: var(--secondary); -} - -.mt-2-5, .my-2-5 { - margin-top: 0.75rem !important; -} - -.alert-mempool { - color: var(--fg); - background-color: var(--tertiary); - border-color: var(--alert-bg); - width: 100%; - display: inline-flex; - flex-direction: column; - justify-content: space-between; - @media (min-width: 676px){ - flex-direction: row; - } -} - -.flex { - display: flex; -} - -th { - white-space: nowrap; -} - -// ASM opcode colors - -.constants { color: #ff8c00 } -.control { color: #87ceeb } -.stack { color: #ffa500 } -.splice { color: #46b5e2 } -.logic { color: #46b5e2 } -.arithmetic { color: #cae8d0 } -.crypto { color: #fa3d3d } -.locktime { color: #ff8c00 } -.reserved { color: #ff8c00 } - -.shortable-address { - font-family: monospace; -} - -.full-container .card-header .formRadioGroup { - margin-top: 6px; - display: flex; - flex-direction: column; - @media (min-width: 991px) { - position: relative; - top: -100px; - } - @media (min-width: 830px) and (max-width: 991px) { - position: relative; - top: 0px; - } - @media (min-width: 830px) { - flex-direction: row; - float: right; - margin-top: 0px; - } - .btn-sm { - font-size: 9px; - @media (min-width: 830px) { - font-size: 14px; - } - } -} - -.direction-ltr { - direction: ltr; -} - -.rtl-layout { - text-align: start; - - .navbar-brand { - margin-right: 0px; - text-align: right; - } - - .nav-pills { - @extend .nav-pills; - display: inline-block; - } - - .description { - direction: rtl; - } - - .dropdown { - margin-right: 1rem; - margin-left: 0; - @media (min-width: 576px) { - margin-left: 1rem; - } - @media (min-width: 768px) { - margin-left: 0; - } - } - .dropdown-menu-right { - left: 0px; - right: auto; - } - .fa-circle-right { - @extend .fa-circle-right; - -webkit-transform: scaleX(-1); - transform: scaleX(-1); - } - - .btn.ml-2 { - margin-right: 0.5rem !important; - } - - .pool-name { - @extend .pool-name; - padding-right: 10px; - } - - .endpoint-container { - @extend .endpoint-container; - .section-header { - @extend .section-header; - text-align: left; - } - } - - .table td { - text-align: right; - .fiat { - @extend .fiat; - margin-left: 0px !important; - margin-right: 15px; - } - } - - .table th { - text-align: right; - } - - .title-block { - text-align: right; - } - - .mr-3 { - @extend .ml-3; - margin-right: 0 !important; - } - - .mr-1 { - @extend .ml-1; - } - - .float-left { - float: right !important; - } - - .float-right { - float: left !important; - } - - .text-left { - text-align: right !important; - } - - .text-right { - text-align: left !important; - } - - .bitcoin-block { - direction: rtl; - } - - .next-previous-blocks { - @extend .next-previous-blocks; - direction: ltr; - } - - .tx-link { - @extend .tx-link; - margin-left: 0px; - margin-right: 10px; - } - - .pagination-container { - @extend .pagination-container; - ul { - @extend ul; - padding-left: 0px; - padding-right: 5px; - } - } - - .search-box-container { - @extend .search-box-container; - margin-right: 0 !important; - margin-left: 0.5rem !important; - } - - .code { - @extend .code; - text-align: left !important; - direction: ltr; - .subtitle { - @extend .subtitle; - direction: rtl; - text-align: right !important; - } - } - - .chart { - direction: ltr; - } - - .formRadioGroup { - @media (min-width: 830px) { - float: left; - } - } - - .container-graph, .full-container, .toggle-holder { - @extend .container-graph; - .formRadioGroup { - @extend .formRadioGroup; - direction: ltr; - } - - .card-header, h1, h2, h3 { - direction: rtl; - } - } - - .fee-progress-bar { - @extend .fee-progress-bar; - &.priority { - @media (767px < width < 992px), (width < 576px) { - width: 100%; - } - width: 75%; - border-radius: 10px 0px 0px 10px !important; - } - } - - .fees-wrapper-tooltip-chart { - @extend .fees-wrapper-tooltip-chart; - .title { - direction: rtl; - } - } - - .btn-link { - padding: 0.1rem 0.5rem 0.25rem 0 !important; - } - - .shortable-address { - direction: ltr; - font-family: monospace; - } - - .lastest-blocks-table { - @extend .lastest-blocks-table; - .table-cell-mined { - @extend .table-cell-mined; - text-align: right !important; - } - } - - .mempool-graph { - @extend .mempool-graph; - direction: ltr; - } - .title-block { - .title { - float: right; - } - } - .container-buttons { - float: left !important; - width: auto !important; - } - .tx-link { - margin-right: 0px; - @media (min-width: 768px) { - margin-right: 10px; - } - } - - .btn-audit { - margin-left: .5em; - } - - .sidenav { - @extend .sidenav; - margin-left: 0px !important; - margin-right: -250px; - } - - .sidenav.open { - margin-right: 0px; - } - - .profile_image_container { - @extend .profile_image_container; - margin-right: 0px !important; - margin-left: 15px; - } - - #blockchain-container.with-menu { - width: calc(100% + 120px); - left: 120px; - } -} - -.scriptmessage { - overflow: hidden; - display: inline-block; - text-overflow: ellipsis; - vertical-align: middle; - max-width: 50px; - width: auto; - text-align: left; - @media (min-width: 376px) { - max-width: 90px; - } - @media (min-width: 476px) { - max-width: 180px; - } - @media (min-width: 576px) { - max-width: 260px; - } - @media (min-width: 768px) { - max-width: 400px; - } - @media (min-width: 850px) { - max-width: 522px; - } - @media (min-width: 992px) { - max-width: 190px; - } - @media (min-width: 1200px) { - max-width: 250px; - } -} - -.scriptmessage.longer { - max-width: 230px; - @media (min-width: 376px) { - max-width: 290px; - } - @media (min-width: 476px) { - max-width: 380px; - } - @media (min-width: 576px) { - max-width: 470px; - } - @media (min-width: 768px) { - max-width: 850px; - } - @media (min-width: 992px) { - max-width: 410px; - } - @media (min-width: 1200px) { - max-width: 480px; - } -} - -.tab-pane { - .card { - background-color: transparent; - padding: 0; - - button { - text-align: left; - display: block; - width: 100%; - padding: 1rem 2rem; - color: var(--fg); - font-weight: bold; - &:focus, &:hover, &:active { - text-decoration: none; - outline: none; - box-shadow: none; - } - } - - .card-header { - padding: 0; - } - - .collapsed { - background-color: var(--secondary); - color: var(--info); - } - } - - .subtitle { - font-weight: bold; - margin-bottom: 3px; - button { - padding: 0px !important; - } - } -} - - -.pagination-container { - display: inline-block; - width: 100%; - justify-content: space-between; - background: var(--bg); - margin: 0; - @media (min-width: 550px) { - width: auto; - } - ul { - justify-content: space-evenly !important; - margin: 0; - @media (min-width: 400px) { - width: auto; - padding-left: 5px; - } - } -} - -.fee-estimation-wrapper { - .tooltip.show { - width: 220px; - } -} - - - -// Blinking block -@keyframes shadowyBackground { - 0% { - box-shadow: -10px -15px 75px rgba($taproot, 1); - } - 50% { - box-shadow: -10px -15px 75px rgba($taproot, .3); - } - 100% { - box-shadow: -10px -15px 75px rgba($taproot, 1); - } -} - -.blink-bg { - color: var(--fg); - background: repeating-linear-gradient($taproot-dark, $taproot-dark 0.163525%, $taproot-light 100%) !important; - animation: shadowyBackground 1s infinite; - box-shadow: -10px -15px 75px rgba($taproot, 1); - transition: 100ms all ease-in; -} - -.page-item { - font-family: monospace; -} - -#divider { - background-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='104%25' height='100%25' fill='none' stroke='white' stroke-width='4' stroke-dasharray='10%2c17' stroke-dashoffset='18' stroke-linecap='square'/%3e%3c/svg%3e"); -} - -.visually-hidden { - display: none; -} - -app-master-page, app-liquid-master-page { - display: flex; - flex-direction: column; - min-height: 100vh; - padding-bottom: 60px; - @media (min-width: 992px) { - padding-bottom: 0px; - } -} - -app-global-footer { - margin-top: auto; -} - -.btn-xs { - padding: 0.25rem 0.5rem; - font-size: 0.875rem; - line-height: 0.5; - border-radius: 0.2rem; -} - -.info-link fa-icon { - color: rgba(255, 255, 255, 0.4); - margin-left: 5px; -}