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;
}