/* =============================================================================
   ANNOUNCEMENT CARDS
   -----------------------------------------------------------------------------
   The toast system LAB DMT works in, extracted so audio.html and chess.html can
   share one implementation instead of carrying two that drift. DMT itself is a
   standalone file outside this tree and keeps its own inline copy — this is a
   port of its behaviour, not a refactor of it.

   Set as the rest of the site is: hairline card, eyebrow label, value
   underneath. The one departure is a shadow. A floating layer has to separate
   itself from whatever it is covering, and on paper a border alone does not do
   that.

   WHY A CARD AND NOT A LINE OF TEXT. Both pages already answer every input by
   changing something on screen, and on both of them most of those changes are
   one word inside a dense strip — a chip that lights, a number that ticks over,
   a status line that rewrites itself faster than you can read it. The card says
   what the control was and what value it arrived at, which is the part the
   screen does not say.

   OFF BY DEFAULT, on both pages. The status line is enough for most people, and
   a page that narrates itself uninvited is a page that is talking over you. The
   exceptions are marked `always` at the call site: outcomes with no other
   surface anywhere on the page, where silence would be a bug rather than calm.

   Bottom-right on a desktop, so it never sits over the middle of a chessboard
   or a spectrum; hugging the right along the bottom on a phone, where there is
   no side to spare.

   THE TOKENS. Every value below is a --tst-* custom property so the two
   editions can repoint them without a second copy of the layout. Dark is the
   default set; paper overrides them at the end of this file.
   ========================================================================== */

:root {
    --tst-bg:      #14161a;
    --tst-line:    rgba(255, 255, 255, .15);
    --tst-line-soft: rgba(255, 255, 255, .08);
    --tst-ink:     #e9ebee;
    --tst-dim:     rgba(233, 235, 238, .58);
    --tst-faint:   rgba(233, 235, 238, .34);
    --tst-accent:  #ff8800;
    --tst-shadow:  0 12px 34px rgba(0, 0, 0, .55), 0 2px 8px rgba(0, 0, 0, .40);
    --tst-mono:    'Roboto Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    --tst-ease:    cubic-bezier(.22, .61, .36, 1);
}

#toast-host {
    position: fixed; right: 22px; bottom: 22px; z-index: 9999;
    display: flex; flex-direction: column; align-items: flex-end; gap: 8px;
    pointer-events: none;
    max-width: min(340px, calc(100vw - 44px));
}
.toast {
    pointer-events: auto;
    background: var(--tst-bg);
    border: 1px solid var(--tst-line);
    border-radius: 12px;
    box-shadow: var(--tst-shadow);
    padding: 11px 14px;
    min-width: 172px; max-width: 100%;
    /* THE RESTING STATE IS VISIBLE, and the entrance is the exception. It was
       the other way round — opacity:0 with an .is-in class fading it up — which
       makes a card's visibility depend on a transition actually running. CSS
       transitions do not tick in a hidden or backgrounded tab, so a card raised
       while the reader was in another tab was appended at opacity 0, sat there
       invisible, and was swept by its own timer having never been painted. The
       engine finishing a move you are not watching is exactly that case. Now
       the worst a stalled transition can do is skip the fade. */
    opacity: 1; transform: none;
    transition: opacity .22s var(--tst-ease), transform .22s var(--tst-ease);
}
.toast.is-new { opacity: 0; transform: translateY(6px); transition: none; }
.toast.is-out { opacity: 0; transform: translateY(-4px); }

.toast__k {
    display: flex; align-items: center; gap: .5rem;
    font-size: .55rem; font-weight: 700; letter-spacing: .17em;
    text-transform: uppercase; color: var(--tst-dim);
}
/* The rule before the label is the same mark the section eyebrows use across
   the site; it is what makes a floating card read as part of the page. */
.toast__k::before {
    content: ''; width: 12px; height: 1px; background: var(--tst-accent); flex: 0 0 auto;
}
.toast__v {
    margin-top: .3rem;
    font-size: .84rem; font-weight: 500; letter-spacing: -.015em;
    color: var(--tst-ink); line-height: 1.35;
}
/* A figure inside a sentence stays monospaced and lines up — timings, depths,
   pixel sizes, clock readings. */
.toast__v em {
    font-style: normal; font-family: var(--tst-mono); font-size: .78rem;
    font-variant-numeric: tabular-nums; color: var(--tst-dim);
}

/* The one state worth flagging in colour: something that is still running
   whether or not the tab is being watched. */
.toast.is-live { border-color: var(--tst-accent); }
.toast.is-live .toast__k { color: var(--tst-accent); }

/* THE GROUPED CARD. One press that changes four things is one card with four
   lines, not four cards — a list reads in a single glance and takes about a
   third of the room the stack did. */
.toast__list { margin: .35rem 0 0; padding: 0; list-style: none; }
.toast__list li {
    display: grid; grid-template-columns: 74px 1fr; gap: .55rem;
    align-items: baseline; padding: 2px 0;
}
.toast__list li + li { border-top: 1px solid var(--tst-line-soft); }
.toast__list b {
    font-size: .5rem; font-weight: 700; letter-spacing: .13em;
    text-transform: uppercase; color: var(--tst-faint);
}
.toast__list span {
    font-size: .76rem; font-weight: 500; color: var(--tst-ink);
    line-height: 1.3; letter-spacing: -.01em;
}
.toast__list em {
    font-style: normal; font-family: var(--tst-mono); font-size: .7rem;
    font-variant-numeric: tabular-nums; color: var(--tst-dim);
}
.toast--group .toast__v { margin-top: 0; }

@media (max-width: 720px) {
    /* Along the bottom, but only as much of it as is needed: the cards hug the
       right so the left of the board or the plate stays visible behind them,
       and the stack can never grow past 42% of the screen. */
    #toast-host {
        left: auto; right: 10px; bottom: 10px;
        max-width: min(300px, calc(100vw - 20px));
        gap: 6px; max-height: 42vh; overflow: hidden;
    }
    .toast { min-width: 0; padding: 9px 11px; border-radius: 10px; }
    .toast__v { font-size: .78rem; }
    .toast__list li { grid-template-columns: 64px 1fr; gap: .45rem; }
}

@media (prefers-reduced-motion: reduce) {
    .toast { transition: none; }
}

/* -----------------------------------------------------------------------------
   THE PAPER EDITION
   Same layout, inked. The tokens come from paper-edition.css, which every page
   carrying this file already loads, so the cards land on the same white and the
   same rule weight as the sheet behind them. A card on paper is a slip laid on
   the page: panel-white against the stock, a hairline, and a soft drop — the
   only elevation shadow the paper editions allow, because a floating layer that
   does not separate from what it covers is unreadable at any ink weight.
   -------------------------------------------------------------------------- */
html[data-edition="paper"] {
    --tst-bg:        #ffffff;
    --tst-line:      rgba(30, 38, 43, .16);
    --tst-line-soft: rgba(30, 38, 43, .07);
    --tst-ink:       #1E262B;
    --tst-dim:       rgba(30, 38, 43, .60);
    --tst-faint:     rgba(30, 38, 43, .42);
    --tst-accent:    #C2410C;
    --tst-shadow:    0 10px 30px rgba(30, 38, 43, .13), 0 2px 6px rgba(30, 38, 43, .07);
}
/* Square the corners the way every other box on a paper page is squared. */
html[data-edition="paper"] .toast { border-radius: 5px; }
