/* Blacklist Watcher site styles.
   Layered on top of the vendored Bootstrap: this file only defines what
   Bootstrap does not, plus the chain/event colour vocabulary the templates
   reference by class name. It is served under a URL carrying a hash of these
   bytes, so editing it is all that is needed for the change to reach people:
   the cache key follows the content by itself. */

:root {
    --bw-shell: 1400px;
    --bw-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
    --bw-surface: #fff;
    --bw-line: rgba(0, 0, 0, .09);
    --bw-line-strong: rgba(0, 0, 0, .16);
    --bw-muted: #5c636a;
    --bw-hover: rgba(13, 110, 253, .05);
    --bw-accent: #0d6efd;
}

[data-bs-theme="dark"] {
    --bw-surface: #16181c;
    --bw-line: rgba(255, 255, 255, .11);
    --bw-line-strong: rgba(255, 255, 255, .2);
    --bw-muted: #9aa3ad;
    --bw-hover: rgba(110, 168, 254, .07);
    --bw-accent: #6ea8fe;
}

body {
    font-size: .95rem;
    -webkit-font-smoothing: antialiased;
}

.bw-shell {
    max-width: var(--bw-shell);
    margin: 0 auto;
    padding: 0 1rem;
}

/* Focus rings: Bootstrap styles its own controls, but plain links and the
   table's anchors were left with only the browser default, which disappears
   entirely against the dark theme. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
.btn:focus-visible {
    outline: 2px solid var(--bw-accent);
    outline-offset: 2px;
    box-shadow: none;
}

/* ---------- header / footer ---------- */

.bw-header {
    border-bottom: 1px solid var(--bw-line);
    background: var(--bw-surface);
}

.bw-brand {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    font-weight: 650;
    letter-spacing: -.01em;
    color: inherit;
    text-decoration: none;
    white-space: nowrap;
}

.bw-brand:hover {
    color: var(--bw-accent);
}

.bw-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 7px;
    background: linear-gradient(135deg, #dc3545, #6f1d24);
    color: #fff;
    font-size: 14px;
    line-height: 1;
    flex: 0 0 auto;
}

.bw-search {
    max-width: 22rem;
    flex: 1 1 14rem;
}

.bw-search .form-control {
    font-family: var(--bw-mono);
    font-size: .8rem;
}

.bw-footer {
    border-top: 1px solid var(--bw-line);
    margin-top: 2rem;
    padding: 1.25rem 0 2rem;
    color: var(--bw-muted);
    font-size: .85rem;
}

.bw-footer a {
    color: inherit;
}

.bw-donate code {
    font-family: var(--bw-mono);
    font-size: .8rem;
    color: inherit;
    background: transparent;
    padding: 0;
    word-break: break-all;
}

.bw-donate-addr {
    display: inline-flex;
    align-items: baseline;
    gap: .1rem;
    padding: .1rem .4rem;
    border: 1px solid var(--bw-line-strong);
    border-radius: 6px;
    max-width: 100%;
}

.bw-crumbs {
    font-size: .85rem;
    color: var(--bw-muted);
}

.bw-crumbs a {
    color: inherit;
    text-decoration: none;
}

.bw-crumbs a:hover {
    text-decoration: underline;
}

h1.bw-title {
    font-size: clamp(1.25rem, 1rem + 1.4vw, 1.7rem);
    font-weight: 650;
    letter-spacing: -.02em;
    margin: 0;
}

/* ---------- chain icons ---------- */

.chain-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
    flex: 0 0 auto;
}

.chain-eth { background: #627eea; }
.chain-arb { background: #28a0f0; }
.chain-base { background: #0052ff; }
.chain-op { background: #ff0420; }
.chain-avax { background: #e84142; }
.chain-poly { background: #8247e5; }
.chain-zksync { background: #7d3cff; }
.chain-linea { background: #121212; box-shadow: inset 0 0 0 1px var(--bw-line-strong); }
.chain-celo { background: #fcff52; color: #000; }
.chain-uni { background: #f50db4; }
.chain-sonic { background: #fe9a4d; color: #000; }
.chain-codex { background: #1652f0; }
.chain-hyperevm { background: #97fce4; color: #000; }
.chain-ink { background: #4b2ec9; }
.chain-plasma { background: #00c48c; }
.chain-morph { background: #0aa5a5; }
.chain-world { background: #3c3c3c; }
.chain-cronos { background: #002d74; }
.chain-tron { background: #c2171f; }

/* ---------- chain filter ---------- */

.chain-filters {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
}

.chain-filters .chain-pill {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .25rem .55rem;
    border: 1px solid var(--bw-line-strong);
    border-radius: 999px;
    font-size: .8rem;
    line-height: 1.4;
    color: inherit;
    text-decoration: none;
    white-space: nowrap;
    background: var(--bw-surface);
}

.chain-filters .chain-pill:hover {
    border-color: var(--bw-accent);
}

/* The active chain is tinted with its own brand colour, set inline from the
   registry, so the filter row reads as "you are on Base" and not merely as
   "some button is pressed". */
.chain-filters .chain-pill.active {
    border-color: var(--bw-chain, var(--bw-accent));
    box-shadow: inset 0 0 0 1px var(--bw-chain, var(--bw-accent));
    background: color-mix(in srgb, var(--bw-chain, var(--bw-accent)) 12%, transparent);
    font-weight: 600;
}

.chain-filters .chain-pill.all.active {
    background: color-mix(in srgb, var(--bw-accent) 12%, transparent);
}

/* Below the md breakpoint the 20 pills stacked into five rows and pushed the
   table off the screen; one scrolling row keeps the events above the fold. */
@media (max-width: 767.98px) {
    .chain-filters {
        flex-wrap: nowrap;
        overflow-x: auto;
        scrollbar-width: thin;
        padding-bottom: .35rem;
        -webkit-overflow-scrolling: touch;
    }

    .chain-filters .chain-label {
        display: none;
    }

    .chain-filters .chain-pill.all .chain-label {
        display: inline;
    }
}

/* ---------- badges ---------- */

.ev-badge,
.tok-badge {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .15rem .45rem;
    border-radius: 6px;
    font-size: .75rem;
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
}

.ev-add { background: rgba(220, 53, 69, .13); color: #b02a37; box-shadow: inset 0 0 0 1px rgba(220, 53, 69, .25); }
.ev-remove { background: rgba(25, 135, 84, .13); color: #146c43; box-shadow: inset 0 0 0 1px rgba(25, 135, 84, .25); }
.ev-destroy { background: rgba(255, 145, 0, .15); color: #a35200; box-shadow: inset 0 0 0 1px rgba(255, 145, 0, .3); }
.ev-submit { background: rgba(108, 117, 125, .14); color: #495057; box-shadow: inset 0 0 0 1px rgba(108, 117, 125, .25); }

[data-bs-theme="dark"] .ev-add { color: #ff8b96; }
[data-bs-theme="dark"] .ev-remove { color: #6ee7a8; }
[data-bs-theme="dark"] .ev-destroy { color: #ffb257; }
[data-bs-theme="dark"] .ev-submit { color: #adb5bd; }

.tok-badge {
    font-family: var(--bw-mono);
    font-weight: 600;
    letter-spacing: -.02em;
    background: transparent;
    box-shadow: inset 0 0 0 1px var(--bw-line-strong);
    color: var(--bw-muted);
}

.tok-usdt { color: #009393; box-shadow: inset 0 0 0 1px rgba(0, 147, 147, .4); }
.tok-usdc { color: #2775ca; box-shadow: inset 0 0 0 1px rgba(39, 117, 202, .4); }

[data-bs-theme="dark"] .tok-usdt { color: #37d9d9; }
[data-bs-theme="dark"] .tok-usdc { color: #6ea8fe; }

.age-badge {
    margin-left: .4rem;
    padding: .05rem .35rem;
    border-radius: 5px;
    font-size: .68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    vertical-align: middle;
}

.age-new { background: #dc3545; color: #fff; }
.age-recent { background: rgba(255, 193, 7, .25); color: #7a5b00; box-shadow: inset 0 0 0 1px rgba(255, 193, 7, .5); }

[data-bs-theme="dark"] .age-recent { color: #ffd867; }

/* ---------- event table ---------- */

.event-table {
    width: 100%;
    margin: 0;
    border-collapse: separate;
    border-spacing: 0;
    /* Fixed layout, so the columns are what this stylesheet says rather than
       what the longest cell asks for. The address is the reason: it is folded
       to fit by site.js, and under automatic layout that fold would narrow
       its own column, which would fold it further. */
    table-layout: fixed;
}

/* Sized to the widest thing each column ever holds - "31 Aug 2026 00:00" with
   a badge, "Funds destroyed", "USDT-MS" - leaving the rest to the address,
   which is the only column that can use more room than it needs. */
.event-table .col-date { width: 15rem; }
.event-table .col-chain { width: 8.5rem; }
.event-table .col-token { width: 5.5rem; }
.event-table .col-event { width: 9.5rem; }
.event-table .col-tx { width: 7rem; }

/* The chain's name is hidden below this width, so the column only has to
   hold the icon. */
@media (max-width: 1199.98px) {
    .event-table .col-chain {
        width: 3.75rem;
    }
}

.event-table thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--bw-surface);
    border-bottom: 1px solid var(--bw-line-strong);
    padding: .55rem .6rem;
    font-size: .72rem;
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--bw-muted);
    white-space: nowrap;
}

.event-table td {
    padding: .45rem .6rem;
    border-bottom: 1px solid var(--bw-line);
    vertical-align: middle;
}

.event-table tbody tr:hover td {
    background: var(--bw-hover);
}

.event-table .col-date {
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum";
}

.event-table .col-chain {
    white-space: nowrap;
}

.chain-cell {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
}

.chain-cell .chain-name {
    font-size: .8rem;
    color: var(--bw-muted);
}

@media (max-width: 1199.98px) {
    .chain-cell .chain-name {
        display: none;
    }
}

/* Hex is unreadable in a proportional face, and a full 42-character address
   is the widest thing on the page. The whole value stays in the DOM - for
   copy, search and crawlers - and site.js decides how much of the middle to
   fold away for the width the column actually got. */
.addr {
    display: inline-flex;
    flex: 0 1 auto;
    min-width: 0;
    max-width: 100%;
    font-family: var(--bw-mono);
    font-size: .8rem;
    vertical-align: bottom;
}

/* The head is cut by the script on an exact character boundary, so the clip
   here only has to catch the moment between a resize and the next frame -
   and it must be a clip rather than an ellipsis, whose leftover slack is what
   put a gap in front of the tail. */
.addr-head {
    flex: 0 1 auto;
    overflow: hidden;
    text-overflow: clip;
    white-space: nowrap;
    min-width: 0;
}

.addr-tail {
    flex: 0 0 auto;
    white-space: nowrap;
}

/* Only a folded address gets the ellipsis: one shown in full has nothing
   missing from its middle. */
.addr.is-clipped .addr-tail::before {
    content: "…";
}

/* 200 underlined hex strings per page is a lot of texture; the monospace face
   and the colour already read as links. */
.addr,
.tx-link {
    text-decoration: none;
}

.addr:hover,
.tx-link:hover {
    text-decoration: underline;
}

/* The chains an address appears on, as icons rather than a paragraph of
   nineteen names. */
.chain-set {
    display: flex;
    flex-wrap: wrap;
    gap: .3rem;
    align-items: center;
}

.date-val,
.addr-val {
    display: inline-flex;
    align-items: center;
    min-width: 0;
    max-width: 100%;
}

/* The address asks for enough room to show all 42 characters and gives way
   from there when the window cannot spare it. The width is stated rather
   than left to the text, which is what keeps the script and the table from
   chasing each other: were the column sized by its content, folding an
   address would narrow the column, which would fold it further. It sits on
   this wrapper rather than the cell because a width on a table cell is
   treated as a floor - the column would refuse to shrink and push the page
   into a sideways scroll. */
.addr-val {
    width: 100%;
}

.date-val {
    gap: .1rem;
}

.tz {
    margin-left: .3em;
    font-size: .8em;
    color: var(--bw-muted);
    letter-spacing: .02em;
}

.tx-link {
    font-family: var(--bw-mono);
    font-size: .8rem;
    white-space: nowrap;
}

.tx-link::after {
    content: "↗";
    margin-left: .2rem;
    font-size: .75em;
    opacity: .55;
}

.copy-btn {
    border: 0;
    background: none;
    padding: 0 .25rem;
    color: var(--bw-muted);
    font-size: .8rem;
    line-height: 1;
    cursor: pointer;
    opacity: .65;
}

.copy-btn:hover {
    opacity: 1;
    color: var(--bw-accent);
}

.copy-btn.copied {
    color: #198754;
    opacity: 1;
}

/* The six columns need about 800px to lay out without the page scrolling
   sideways - which is what it used to do, showing nothing but the date. Below
   that each row becomes a card instead, labelled from the header it no longer
   has. */
@media (max-width: 899.98px) {
    .event-table,
    .event-table tbody,
    .event-table tr,
    .event-table td {
        display: block;
    }

    .event-table thead {
        display: none;
    }

    .event-table tbody tr {
        border: 1px solid var(--bw-line);
        border-radius: 10px;
        padding: .35rem .15rem;
        margin-bottom: .5rem;
        background: var(--bw-surface);
    }

    .event-table tbody tr:hover td {
        background: transparent;
    }

    .event-table td {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: .75rem;
        border: 0;
        padding: .2rem .6rem;
        min-width: 0;
    }

    .event-table td::before {
        content: attr(data-label);
        flex: 0 0 auto;
        font-size: .7rem;
        font-weight: 650;
        text-transform: uppercase;
        letter-spacing: .05em;
        color: var(--bw-muted);
    }

    .event-table .col-date {
        border-bottom: 1px solid var(--bw-line);
        padding-bottom: .35rem;
        margin-bottom: .2rem;
    }

    .chain-cell .chain-name {
        display: inline;
    }

    .addr-val {
        flex: 1 1 auto;
        width: auto;
        justify-content: flex-end;
    }
}

/* ---------- address summary ---------- */

.bw-summary {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    gap: .75rem 1.5rem;
    border: 1px solid var(--bw-line);
    border-radius: 12px;
    padding: .9rem 1rem;
    background: var(--bw-surface);
}

.bw-summary dt {
    font-size: .7rem;
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--bw-muted);
    margin-bottom: .15rem;
}

.bw-summary dd {
    margin: 0;
    font-size: .9rem;
    font-variant-numeric: tabular-nums;
}

/* The event count is the one figure worth reading from across the room, and
   the chain icons beside it leave the cell tall enough to carry it. */
.bw-summary .bw-figure {
    font-size: clamp(1.75rem, 1.3rem + 1.4vw, 2.6rem);
    font-weight: 650;
    line-height: 1.05;
    letter-spacing: -.03em;
}

.bw-lede {
    color: var(--bw-muted);
    max-width: 70ch;
    /* The sentence opens with a 42-character address, which is one unbreakable
       word on a narrow phone. */
    overflow-wrap: anywhere;
}

.bw-addr-head {
    font-family: var(--bw-mono);
    font-size: clamp(.85rem, .6rem + 1.1vw, 1.15rem);
    word-break: break-all;
    letter-spacing: -.02em;
}

/* ---------- parser status ---------- */

/* The status table reuses .event-table for its frame and its narrow-screen
   card layout, and redeclares only what is its own. Five short columns have
   no use for the full 1400px shell: stretched that wide, each value sits
   alone at the left of an empty stripe and the row stops reading as a row. */
.status-table {
    max-width: 58rem;
}

.status-table .col-chain { width: 12rem; }
.status-table .col-tokens { width: 11rem; }
.status-table .col-block { width: 10rem; }
.status-table .col-heard { width: 11rem; }
.status-table .col-state { width: 8rem; }

/* Neither a block height nor "20 minutes ago" means anything broken across
   three lines, which is what the card layout does to them otherwise. */
.status-table .col-block,
.status-table .col-heard {
    white-space: nowrap;
}

/* Here the chain is the subject of the row rather than a label attached to an
   event, so its name is written out at every width the table survives, and in
   the body colour rather than the muted one the event table uses. */
.status-table .chain-cell .chain-name {
    color: inherit;
    font-size: .875rem;
}

@media (max-width: 1199.98px) {
    .status-table .chain-cell .chain-name {
        display: inline;
    }
}

/* In the card layout the first cell heads the card, the way the date does on
   an event card. */
@media (max-width: 899.98px) {
    .status-table .col-chain {
        border-bottom: 1px solid var(--bw-line);
        padding-bottom: .35rem;
        margin-bottom: .2rem;
    }
}

.st-chain {
    color: inherit;
    text-decoration: none;
}

.st-chain:hover {
    color: var(--bw-accent);
}

.block-num {
    font-family: var(--bw-mono);
    font-variant-numeric: tabular-nums;
    font-size: .85rem;
}

.st-badge {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .15rem .45rem;
    border-radius: 6px;
    font-size: .75rem;
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
}

.st-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: currentColor;
    flex: 0 0 auto;
}

/* The dot repeats what the word already says, in colour. A live parser also
   pulses, so that a page left open on a second monitor reads as running
   without being read at all. */
.st-online .st-dot {
    animation: st-pulse 2.4s ease-in-out infinite;
}

@keyframes st-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: .35; }
}

/* Respect a reader who has asked for less motion: the colour and the word
   carry the state on their own. */
@media (prefers-reduced-motion: reduce) {
    .st-online .st-dot {
        animation: none;
    }
}

.st-online { background: rgba(25, 135, 84, .13); color: #146c43; box-shadow: inset 0 0 0 1px rgba(25, 135, 84, .25); }
.st-degraded { background: rgba(255, 193, 7, .18); color: #8a6100; box-shadow: inset 0 0 0 1px rgba(255, 193, 7, .45); }
.st-offline { background: rgba(220, 53, 69, .13); color: #b02a37; box-shadow: inset 0 0 0 1px rgba(220, 53, 69, .25); }
.st-unknown { background: rgba(108, 117, 125, .14); color: #495057; box-shadow: inset 0 0 0 1px rgba(108, 117, 125, .25); }

[data-bs-theme="dark"] .st-online { color: #6ee7a8; }
[data-bs-theme="dark"] .st-degraded { color: #ffd867; }
[data-bs-theme="dark"] .st-offline { color: #ff8b96; }
[data-bs-theme="dark"] .st-unknown { color: #adb5bd; }

/* Footnote prose: the thresholds behind the badges, set below the table for
   the reader who wants to know what "degraded" was measured against. */
.bw-note {
    color: var(--bw-muted);
    font-size: .85rem;
    max-width: 80ch;
}

/* ---------- pagination ---------- */

.bw-pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    font-size: .85rem;
}

.bw-pager .page-state {
    color: var(--bw-muted);
    padding: 0 .5rem;
    font-variant-numeric: tabular-nums;
}

/* ---------- sticky ad ---------- */

/* The unit is A-ADS 2455094. Their snippet shipped as a block of inline
   styles with a hardcoded near-white close button, which reads as a bright
   sticker on the dark theme; everything here is the same layout drawn in this
   file's colour vocabulary instead. */

/* Not hidden, only invisible: hidden takes the checkbox out of the tab order
   and the close control with it, since a <label> is not focusable on its own.
   Fixed rather than absolute, and so pinned to the corner the bar occupies:
   clicking the label focuses this input, and a browser scrolls a newly
   focused element into view. Left in flow it sits at the end of the document,
   which is the last element on the page - so dismissing the ad threw the
   reader to the bottom of a four-thousand-pixel page. A fixed element is
   never out of view, so there is nothing to scroll to. */
.bw-ad-toggle {
    position: fixed;
    right: 0;
    bottom: 0;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

/* One number, in one place: the frame, the bar around it and the space given
   back below the page are all derived from these. A-ADS' Adaptive unit draws
   to whatever box it is given, and their snippet gave it none - which leaves
   an iframe at its 150px default, a sixth of a laptop screen spent on an ad.
   This is a leaderboard's height instead; change it here and the bar and the
   spacer follow. */
:root {
    --bw-ad-height: 90px;
    --bw-ad-pad: .35rem;
}

.bw-ad-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1030;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    padding: var(--bw-ad-pad) 1rem;
    background: var(--bw-surface);
    border-top: 1px solid var(--bw-line);
}

/* The page ends behind the bar, so the bar's full height - frame, padding and
   border - is given back below the footer. It is a sibling of the bar rather
   than padding on <body>, so that dismissing the ad returns the space in the
   same rule that removes the bar. */
.bw-ad-spacer {
    height: calc(var(--bw-ad-height) + 2 * var(--bw-ad-pad) + 1px);
}

.bw-ad-frame {
    /* An iframe's intrinsic width is 300px, and a flex item will not shrink
       below its content unless told to - which pushed the close button off the
       right edge of a phone. min-width: 0 is what lets the frame give way. */
    flex: 1 1 auto;
    min-width: 0;
    max-width: 728px;
    height: var(--bw-ad-height);
    border: 0;
    padding: 0;
    overflow: hidden;
    /* An ad that has not loaded should look like nothing, not like a hole. */
    background: transparent;
}

@media (max-width: 767.98px) {
    :root {
        --bw-ad-height: 60px;
        --bw-ad-pad: .25rem;
    }

    .bw-ad-bar {
        padding-left: .5rem;
        padding-right: .5rem;
    }
}

.bw-ad-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 24px;
    height: 24px;
    border: 1px solid var(--bw-line-strong);
    border-radius: 4px;
    background: var(--bw-surface);
    color: var(--bw-muted);
    cursor: pointer;
}

.bw-ad-close:hover {
    color: var(--bw-accent);
    border-color: var(--bw-accent);
}

/* The checkbox carries the focus but is invisible, so the ring is drawn on
   the label the reader can actually see. */
.bw-ad-toggle:focus-visible + .bw-ad-slot .bw-ad-close {
    outline: 2px solid var(--bw-accent);
    outline-offset: 2px;
}

/* Dismissal: the bar and the space it was reserving go together. It lasts as
   long as the page does - nothing is stored, so the next page brings it back. */
.bw-ad-toggle:checked + .bw-ad-slot {
    display: none;
}

/* Printing a fixed banner puts it across whatever paragraph it lands on. */
@media print {
    .bw-ad {
        display: none;
    }
}
