ui/revivehud.razor.scss
// THE REVIVE MARKER — badge, bar and countdown over a downed teammate.
//
// ⚠️ NO ANIMATION ON THE ROOT. Position and opacity are written per frame from
// code because the anchor is a WORLD point; a keyframe cannot know where that
// lands on screen. The stylesheet carries appearance only — the one exception is
// the badge pulse, which is time-based rather than position-based and so is
// expressible here.

.revive-markers {
    position: absolute;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

.marker {
    position: absolute;

    // ⚠️ Centred ON the projected point, then lifted clear of it — Left/Top are
    // the body's world anchor, so without the pull-back every marker sits
    // down-right of the player it belongs to.
    transform: translateX(-50%) translateY(-100%);

    flex-direction: column;
    align-items: center;
    pointer-events: none;
}

// ── the badge ────────────────────────────────────────────────────────────────

.marker .badge {
    width: 38px;
    height: 38px;
    border-radius: 19px;

    // Dark disc behind the cross: this is drawn THROUGH walls, over anything,
    // and a bare white cross on a snow map is invisible.
    background-color: rgba(0, 0, 0, 0.62);
    border: 2px solid rgba(255, 255, 255, 0.92);

    align-items: center;
    justify-content: center;

    // The cross is positioned inside, so the badge is the frame of reference.
    position: relative;
}

// ⚠️ TWO RECTANGLES RATHER THAN A GLYPH — a "✚" depends on the shipped UI font
// carrying that codepoint, and a missing one draws a blank box rather than
// failing loudly.
.marker .cross-v {
    position: absolute;
    width: 6px;
    height: 20px;
    border-radius: 1px;
    background-color: rgba(255, 255, 255, 0.95);
}

.marker .cross-h {
    position: absolute;
    width: 20px;
    height: 6px;
    border-radius: 1px;
    background-color: rgba(255, 255, 255, 0.95);
}

// Running out of time. Red is the only colour on this marker that is not
// white — it has to mean one thing.
.marker .badge.urgent {
    border-color: rgba(235, 64, 52, 0.95);
    background-color: rgba(60, 6, 2, 0.72);

    animation-name: revive-pulse;
    animation-duration: 0.8s;
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
}

.marker .badge.urgent .cross-v,
.marker .badge.urgent .cross-h {
    background-color: rgba(255, 205, 200, 0.98);
}

// Somebody is on it. Green reads as "handled" at a glance across a map.
.marker .badge.helping {
    border-color: rgba(96, 214, 122, 0.95);
    animation-name: none;
}

@keyframes revive-pulse {
    0%   { opacity: 1; }
    50%  { opacity: 0.45; }
    100% { opacity: 1; }
}

// ── the bar ──────────────────────────────────────────────────────────────────

.marker .bar {
    width: 54px;
    height: 6px;
    margin-top: 5px;

    background-color: rgba(0, 0, 0, 0.65);
    border: 1px solid rgba(255, 255, 255, 0.55);
    border-radius: 3px;

    // ⚠️ The fill is a fraction of this, so the track must not let it spill past
    // the rounded ends while it is short.
    overflow: hidden;
}

.marker .bar .fill {
    height: 100%;
    width: 0%;
    background-color: rgba(96, 214, 122, 0.95);
}

// ── the countdown ────────────────────────────────────────────────────────────

.marker .secs {
    margin-top: 3px;

    font-family: Inter;   // ⚠️ The one face this project ships — see DamageNumbersHud.
    font-weight: bold;
    font-size: 15px;
    color: rgba(255, 255, 255, 0.92);

    // Hard shadow rather than an outline: read against snow, blood and muzzle
    // flash, thin type disappears into all three.
    text-shadow: 2px 2px 0px rgba(0, 0, 0, 0.85);
}

// ═══ BASALT (`HudTheme`) — the map's face, Cinzel on the revive markers ═══
//
// *"i want the font for this map to affect … all hud messages that appear on screen"* (2026-09-27). The class is put on from `OnUpdate` (`HudTheme.Wear`), because this
// tree is built once and a class in its razor would keep the theme it was built under.
// ⛔ ON INTER'S LINE BOX, so no row grows taller: 0.898 of Cinzel's own line, which is Inter's 1.211 of the size. See
// `.round` in SurvivalHud.razor.scss for why it is not 1.211. It is wider on mixed-case text, which it sets in small capitals. Cinzel-Bold is the one face shipped,
// so every weight draws bold.
.revive-markers.theme-basalt,
.revive-markers.theme-basalt .marker .secs
{
    font-family: Cinzel;
    line-height: 0.898;
}