/* revoker.css — The Great Revoker.
 *
 * Modeled on multisend.css: same dark-panel/gold-glow/Comic-Sans identity, same
 * .stats-style panel, .wallet-btn, sr-only/skip-link pattern — copied rather than
 * shared, same reasoning nav.css documents for itself: this file must be
 * self-sufficient, since it is the only stylesheet revoker.html links besides
 * nav.css. Keep the four nav tokens below — nav.css CONSUMES them and an
 * unresolved var() fails SILENTLY, rendering the navbar invisible. That already
 * happened once on nftviewer.html.
 */

* , *::before, *::after { box-sizing: border-box; }

:root {
    --nav-h: 80px;
    --touch: 44px;
    /* --navbar-bg and --glow deliberately match nav.css's OWN fallback
       values (rgba(0,0,0,0.95) / 0 0 10px rgba(255,69,0,0.7)) byte-for-byte
       rather than a page-specific tone: nav.css loads first, but a later
       :root still wins on source order, so redefining these here to a
       "terminal" black/gold theme (an earlier draft did: rgba(10,6,0,0.92) /
       0 0 12px rgba(255,207,72,0.45)) made THIS page's navbar bar visibly
       diverge from every other page's — caught by
       tests/nav-appearance.spec.js once revoker.html joined its page list
       (Task 6).

       --c-orange is one of the four, and it was #ff7a18 here while all 13 other
       pages use `orange` (#ffa500). It is NOT page-local: nav.css builds the
       SHARED .navbar-link::after ember underline out of it, so this page's navbar
       hover was a different colour from every other page's. Nothing catches that
       — nav-appearance.spec.js only compares the bar and a resting link, never a
       hover state. So --c-orange matches the site, and the page's own warmer
       accent moved to --rev-accent, which nav.css does not consume and cannot
       leak into. */
    --navbar-bg: rgba(0, 0, 0, 0.95);
    --glow: 0 0 10px rgba(255, 69, 0, 0.7);
    --c-gold: #ffcf48;
    --c-orange: orange;
    --rev-accent: #ff7a18;
    --c-dim: #c9b48a;
    --c-red: #ff4500;
}

body {
    margin: 0;
    padding: 0;
    font-family: var(--font-body, "Comic Sans MS", system-ui, sans-serif);
    /* The site background, same art as every other page. This page shipped with
       a bare #0a0600 body — the only page without BlazeitBG — and the owner
       read the result as "background missing and more red-ish than the rest of
       the site": nothing but dark brown + orange glows, no light-blue art
       anywhere. The terminal identity lives in the PANELS, not the page.
       `cover` (not multisend's `100% auto`) — the width-scaled variant leaves a
       dead #b0e8f7 zone below the art on tall pages, the exact defect fixed on
       the faucet the same day. */
    background: url('images/BlazeitBG.png') no-repeat center center;
    background-size: cover;
    background-attachment: fixed;
    background-color: #b0e8f7;
    color: var(--c-gold);
    display: flex;
    flex-direction: column;
    align-items: center;
    min-height: 100vh;
    width: 100%;
    overflow-x: hidden;
    padding-top: calc(var(--nav-h) + 24px);
}

@media screen and (max-width: 768px) {
    body { padding-top: calc(var(--nav-h) + 16px); }
}

.container {
    padding: 2rem;
    width: 100%;
    max-width: 900px;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    text-align: center;
    flex: 1 0 auto;
    /* The Multisender/Viewer box (owner, 2026-08-10): one 0.75 layer the site
       art glows through and shows around, with the real text protection on the
       0.92 .rev-panel surfaces inside. */
    background: rgba(0, 0, 0, 0.75);
    border-radius: 20px;
    box-shadow: 0 0 10px rgba(255, 69, 0, 0.6);
    margin-bottom: 24px;
}

/* The centre column and the right rail are plain stacks; they only become grid
   CELLS at the three-column breakpoint below. Their children keep their own
   margins, so neither needs a gap of its own. */
.rev-center,
.rev-rail-right {
    display: flex;
    flex-direction: column;
    align-items: stretch;
}

/* ---- Three-column reading layout (wide screens only) ----
 *
 * Education on the left; audit log and the BLAZE contract roster on the right;
 * the scan controls and everything-else-on-Sonic centred. Placement is explicit
 * (grid-column/grid-row) rather than source order, which is what lets the two
 * rails stay LAST in the HTML: below this breakpoint the container is still a
 * flex column and everything stacks in DOM order, so a phone gets
 * connect → results → log → BLAZE contracts → explainer, not explainer first.
 *
 * All three tracks are FRACTIONAL, not capped. An earlier pass gave the rails
 * fixed maxima (270px / 340px) and let the centre take the remainder; that was
 * right while the BLAZE roster still sat in the centre, but the roster now
 * lives in the right rail, so the caps pinned both rails narrow on a wide
 * screen while the centre carried the empty space. Fractions keep the ratio
 * instead, so a bigger monitor makes the rails genuinely bigger.
 *
 * Do not "simplify" these back to fixed maxima. A grid resolves fixed/minmax
 * tracks BEFORE the flexible one, so a capped rail always wins its width first
 * and whichever track holds `1fr` absorbs every shortfall — measured at a
 * 1200px viewport, that collapsed the centre to 428px. The min values below are
 * floors for the narrow end of the range, never targets.
 *
 * The right rail is the widest: it carries approval rows with full
 * 42-character contract addresses, which must never be truncated on a page
 * whose whole job is letting you verify what you approved. The left rail is
 * prose. Below 1360 it stays one column.
 */
@media screen and (min-width: 1360px) {
    .container {
        display: grid;
        max-width: 1800px;
        grid-template-columns: minmax(260px, 1.15fr) minmax(0, 2fr) minmax(300px, 1.35fr);
        column-gap: 20px;
        /* start, not stretch: the three columns are independent stacks and must
           each end where their own content does, rather than every panel
           growing to the height of the tallest column. */
        align-items: start;
    }

    h1,
    .rev-dek {
        grid-column: 1 / -1;
    }

    #revLearnPanel  { grid-column: 1; grid-row: 3; }
    .rev-center     { grid-column: 2; grid-row: 3; }
    .rev-rail-right { grid-column: 3; grid-row: 3; }

    /* Deliberately NOT sticky. An earlier pass pinned both rails with their own
       overflow-y; that was fine when the right rail was just a log, but it now
       carries the BLAZE roster with its tick-boxes and 🧹 buttons, and putting
       interactive rows inside a short nested scroller means a revoke control can
       be scrolled out of its own rail while the page looks unmoved. The whole
       page scrolls as one instead. The log keeps its own inner scroll — that one
       is a fixed-height terminal by design, not a container of controls. */

    /* Narrower than the stacked layout allowed: the roster sits directly under
       the log here, so a tall log would push the contracts off the fold. */
    .rev-console-lines {
        max-height: min(38vh, 320px);
    }
}

h1 {
    font-size: 2rem;
    margin: 0 0 5px;
    color: var(--c-gold, #ffcf48);
    text-shadow: 0 0 6px #ff8c00, 0 0 10px #ff4500;
    font-weight: bold;
}

.rev-dek {
    font-size: 1.05rem;
    color: rgba(255, 255, 255, 0.85);
    margin: 0 0 20px;
}

.rev-panel {
    /* 0.92, not the 0.6 this shipped with: the body now carries the site art,
       and at 0.6 the "BLAZE IT" letters would read through behind addresses —
       the exact defect the faucet redesign fixed on its own panels. */
    background-color: rgba(0, 0, 0, 0.92);
    border: 1px solid rgba(255, 207, 72, 0.25);
    border-radius: 15px;
    padding: 20px;
    margin-bottom: 20px;
    box-shadow: 0 0 10px rgba(255, 69, 0, 0.5);
    text-align: left;
}
.rev-panel h2 {
    margin: 0 0 8px;
    color: var(--c-gold, #ffcf48);
}
.rev-note {
    margin: 0 0 12px;
    font-size: 0.85rem;
    color: rgba(255, 255, 255, 0.7);
}

#revConnectPanel {
    text-align: center;
}
.rev-or {
    margin: 12px 0 8px;
    font-size: 0.9rem;
    color: rgba(255, 255, 255, 0.7);
}
#revAddrInput {
  min-height: var(--touch, 44px);
    font-family: inherit;
    font-size: 0.95rem;
    padding: 10px 12px;
    border-radius: 10px;
    border: 1px solid rgba(255, 207, 72, 0.5);
    background: rgba(0, 0, 0, 0.45);
    color: var(--c-gold);
    width: 100%;
    max-width: 420px;
    margin-bottom: 10px;
}
#revAddrInput::placeholder { color: rgba(255, 207, 72, 0.4); }

.wallet-btn,
#revScanBtn {
    padding: 10px 20px;
    border-radius: 10px;
    background-color: orange;
    color: black;
    font-weight: bold;
    border: none;
    cursor: pointer;
    min-height: var(--touch);
    transition: background-color 0.2s, opacity 0.2s;
    font-family: inherit;
    font-size: 1rem;
}
.wallet-btn:hover:not(:disabled),
#revScanBtn:hover:not(:disabled) { background-color: darkorange; }
.wallet-btn:disabled,
#revScanBtn:disabled { opacity: 0.5; cursor: not-allowed; }
.wallet-btn:focus-visible,
#revScanBtn:focus-visible { outline: 3px solid var(--c-gold); outline-offset: 2px; }

/* Secondary and deliberately quiet — the same treatment wallet.js gives its own
   .blaze-wallet-disconnect link, for the same reason: switching wallets is a rare
   deliberate act, not the thing the panel is for. Only ever visible while
   connected (revoker.js toggles the `hidden` property in renderAll).
   No `display` of its own: a class-level `display:inline-block` would OUTWEIGH the
   UA's `[hidden]{display:none}` and leave the button permanently on screen. The
   explicit rule below is the belt to that brace. */
.rev-switch-btn {
    margin-left: 10px;
    font-family: inherit;
    font-size: 0.85rem;
    padding: 8px 12px;
    min-height: var(--touch);
    background: none;
    border: none;
    color: rgba(255, 255, 255, 0.7);
    text-decoration: underline;
    cursor: pointer;
}
.rev-switch-btn[hidden] { display: none; }
.rev-switch-btn:hover:not(:disabled) { color: var(--c-gold); }
.rev-switch-btn:disabled { opacity: 0.5; cursor: not-allowed; }

/* Whose approvals are these? Stated above the lists, in full, always. */
.rev-scanned {
    margin: 0 0 8px;
    font-size: 0.95rem;
    font-weight: bold;
    color: var(--c-gold);
    word-break: break-all;
}
/* Viewing an address that is not the connected wallet. The ticks and the 🧹
   buttons are not rendered at all in this state, so this banner is the whole
   explanation for their absence — it has to be loud and it has to be specific. */
.rev-readonly {
    background: rgba(255, 207, 72, 0.1);
    border: 1px solid rgba(255, 207, 72, 0.55);
    border-radius: 10px;
    padding: 10px 14px;
    margin: 0 0 12px;
    color: var(--c-gold);
    font-size: 0.9rem;
    line-height: 1.5;
    word-break: break-word;
}

.rev-partial {
    background: rgba(255, 69, 0, 0.18);
    border: 1px solid var(--rev-accent);
    border-radius: 10px;
    padding: 10px 14px;
    color: var(--rev-accent);
    font-weight: bold;
}
.rev-summary {
    font-size: 0.95rem;
    color: rgba(255, 255, 255, 0.85);
}

.rev-queue {
    text-align: center;
}
#revRevokeSelectedBtn {
    padding: 10px 20px;
    border-radius: 10px;
    background-color: var(--c-red);
    color: white;
    font-weight: bold;
    border: none;
    cursor: pointer;
    min-height: var(--touch);
    font-family: inherit;
    font-size: 1rem;
}
#revRevokeSelectedBtn:hover:not(:disabled) { background-color: #cc3700; }
#revRevokeSelectedBtn:focus-visible { outline: 3px solid var(--c-gold); outline-offset: 2px; }
#revRevokeSelectedBtn:disabled { opacity: 0.5; cursor: not-allowed; }

/* ---- Result rows: BLAZE box + everything-else box ---- */
#revBlazeRows, #revOtherRows {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.rev-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 10px;
    padding: 10px 12px;
    border-radius: 10px;
    background: rgba(0, 0, 0, 0.4);
    border: 1px solid rgba(255, 207, 72, 0.18);
    font-size: 0.9rem;
}
.rev-row-clean {
    opacity: 0.8;
}
.rev-tick {
    width: 20px;
    height: 20px;
    min-height: 0;
    accent-color: var(--rev-accent);
    cursor: pointer;
    flex: 0 0 auto;
}
.rev-row-name {
    font-weight: bold;
    color: var(--c-gold, #ffcf48);
}
.rev-row-note {
    color: rgba(255, 255, 255, 0.55);
    font-size: 0.8rem;
}
.rev-row-status {
    color: #b8ffcf;
    font-weight: bold;
    margin-left: auto;
}
/* symbol() is capped and stripped at the data layer (revoker-scan.js), which is
   the real fix — but a row must not be wreckable by one long string even if that
   cap is ever loosened, so neither of these two can overflow their row either. */
.rev-row-amount {
    color: var(--c-gold);
    max-width: 100%;
    overflow-wrap: anywhere;
}
/* WHICH token the approval is on. Same monospace treatment as the spender: these
   are the two facts a suspicious row is checked against. */
.rev-row-token,
.rev-row-spender {
    color: rgba(255, 255, 255, 0.75);
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    font-size: 0.82rem;
    word-break: break-all;
}
.rev-row-risk {
    color: var(--rev-accent);
    font-size: 0.85rem;
    flex-basis: 100%;
    max-width: 100%;
    overflow-wrap: anywhere;
}
.rev-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: bold;
    white-space: nowrap;
}
/* The two full-width badges must override .rev-badge's nowrap. They carry
   sentences, not one-word labels, and nowrap on a flex-basis:100% child does
   not wrap — it overflows the row and pushes the whole page sideways. That was
   invisible while the rows were 836px wide and appeared the moment they moved
   into a ~310px rail; body{overflow-x:hidden} was CLIPPING it rather than
   preventing it, so the text simply ran off the panel. */
.rev-badge-dead {
    background: rgba(255, 69, 0, 0.25);
    color: var(--c-red);
    flex-basis: 100%;
    white-space: normal;
}
.rev-badge-unlimited {
    background: rgba(255, 207, 72, 0.2);
    color: var(--c-gold);
}
.rev-badge-blaze {
    background: rgba(255, 122, 24, 0.2);
    color: var(--rev-accent);
}
/* Permit2's blind spot, said ON the row it applies to. The education panel says
   it too, but that is far below the fold and this is the row it is about. */
.rev-badge-permit2 {
    background: rgba(255, 207, 72, 0.14);
    color: var(--c-gold);
    flex-basis: 100%;
    white-space: normal;
}
.rev-row-link {
    color: var(--c-gold);
    font-size: 0.8rem;
    text-decoration: underline;
}
.rev-row-revoke {
    margin-left: auto;
    padding: 6px 14px;
    border-radius: 8px;
    border: none;
    background-color: var(--c-red);
    color: white;
    font-weight: bold;
    font-family: inherit;
    font-size: 0.85rem;
    min-height: var(--touch);
    cursor: pointer;
}
.rev-row-revoke:hover:not(:disabled) { background-color: #cc3700; }
.rev-row-revoke:focus-visible { outline: 3px solid var(--c-gold); outline-offset: 2px; }
.rev-row-revoke:disabled { opacity: 0.5; cursor: not-allowed; }
.rev-empty {
    margin: 0;
    color: rgba(255, 255, 255, 0.6);
    font-style: italic;
}

/* ---- Education panel ---- */
#revLearnPanel p {
    margin: 0 0 12px;
    font-size: 0.9rem;
    color: rgba(255, 255, 255, 0.85);
    line-height: 1.5;
}
#revLearnPanel p:last-child { margin-bottom: 0; }
.rev-blindspot {
    background: rgba(255, 207, 72, 0.08);
    border: 1px solid rgba(255, 207, 72, 0.3);
    border-radius: 10px;
    padding: 10px 12px;
}

/* ---- The audit console ---- */
.rev-console-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 8px;
}
.rev-console-head h2 { margin: 0; }
#revCopyLogBtn {
    font-family: inherit;
    font-weight: bold;
    font-size: 0.85rem;
    padding: 6px 12px;
    min-height: var(--touch);
    border-radius: 8px;
    border: 1px solid rgba(255, 207, 72, 0.5);
    background: rgba(0, 0, 0, 0.45);
    color: var(--c-gold);
    cursor: pointer;
}
#revCopyLogBtn:hover { background: rgba(255, 122, 24, 0.18); border-color: rgba(255, 207, 72, 0.95); }
#revCopyLogBtn:focus-visible { outline: 3px solid var(--c-gold); outline-offset: 2px; }

.rev-console-lines {
    max-height: 260px;
    overflow-y: auto;
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    font-size: 0.85rem;
    line-height: 1.5;
    background: rgba(0, 0, 0, 0.6);
    border: 1px solid rgba(255, 207, 72, 0.25);
    border-radius: 8px;
    padding: 10px 12px;
    text-align: left;
}
.rev-line { white-space: pre-wrap; word-break: break-word; animation: revFadeIn 160ms ease-out; }
.rev-line-info { color: var(--c-dim); }
.rev-line-ok   { color: #b8ffcf; }
.rev-line-warn { color: var(--rev-accent); }
.rev-line-risk { color: var(--c-gold); font-weight: bold; }
.rev-console-lines::after { content: "▊"; color: var(--c-gold); animation: revBlink 1s step-end infinite; }

@keyframes revFadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes revBlink { 50% { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
    .rev-line { animation: none; }
    .rev-console-lines::after { animation: none; }
}

/* ---- Shared a11y helpers ---- */
.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible {
    outline: 3px solid var(--c-gold);
    outline-offset: 2px;
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    background: #000;
    color: var(--c-gold);
    padding: 10px 16px;
    z-index: 2000;
    border-radius: 0 0 8px 0;
}
.skip-link:focus {
    left: 0;
}

/* Footer — matches the canonical strip (arena.css/nftviewer.css/stats.css):
   a full-width DARK band so the text never sits on the pale-blue body. This
   page shipped with a transparent footer, which read as "wrong" against the
   other pages (owner report 2026-08-11). */
.footer {
    width: 100%;
    text-align: center;
    padding: 10px 0;
    background: rgba(0, 0, 0, 0.8);
    color: #fff;
    font-size: 14px;
    margin-top: 20px;
    flex-shrink: 0;
    box-sizing: border-box;
}
.footer p { margin: 0; }
.trust-strip {
    margin-top: 6px;
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    justify-content: center;
    align-items: baseline;
    padding: 0 12px;
    font-size: 12px;
    color: #ded6c6; /* opaque: translucent text over a translucent panel has no contrast ratio (READABILITY rule) */
}
.trust-strip a { color: var(--c-gold); text-decoration: none; }
.trust-strip a:hover, .trust-strip a:focus-visible { color: var(--c-orange); text-decoration: underline; }
.trust-sep { opacity: 0.5; }

@media screen and (max-width: 768px) {
    .container { padding: 1rem; }
}
