UI/Player/OutOfBoundsUI.razor
@using Sandbox.UI
@inherits Panel

<style>
    OutOfBoundsUI {
        position: absolute;
        width: 100%;
        height: 100%;
        justify-content: center;
        align-items: center;
        align-content: center;
        transition: all 0.1s sin-ease-in-out;
        opacity: 0;
        flex-direction: column;

        .text {
            text-align: center;
            font-family: "Wallpoet-";
            font-size: 54px;
            color: rgba(255, 0, 0, 1);
        }

        .redscreen {
            position: absolute;
            background-color: rgba(255, 0, 0, 0.5);
            height: 100%;
            width: 100%;
        }

        &.open {
            opacity: 1;
        }
    }
</style>

<root class="@(Open ? "open" : "closed")">
    <label class="text">- - -[TURN BACK]- - -</label>
    <label class="text">@_timerString</label>
    <label class="redscreen" style="opacity: @(_timeLeft.Remap(0, 4, 0.85f, 0))"></label>
</root>

@code
{
    public static OutOfBoundsUI Current;
    public bool Open { get; set; }

    private float _timeLeft = 4f;
    private string _timerString => TimeSpan.FromSeconds( _timeLeft ).ToString( @"s\.ff" );

    public OutOfBoundsUI()
    {
        Current = this;
    }

    public override void Tick()
    {
        base.Tick();

        if ( Open )
        {
            _timeLeft -= Time.Delta;
            if ( _timeLeft <= 0f )
            {
                LocalPlayer.Pawn?.SetOutOfBounds( true );
                Open = false;
            }
        }

        _timeLeft = _timeLeft.Clamp( 0f, 4f );
    }

    public void StartTimer() => _timeLeft = 4f;

    public void ResetTimer()
    {
        _timeLeft = 4f;
        LocalPlayer.Pawn?.SetOutOfBounds( false );
    }

    protected override int BuildHash() => HashCode.Combine( Open, _timeLeft );
}