@font-face {
    font-family: ggFont;
    src: url(/fonts/ggFont.ttf) format("truetype");
    font-display: swap;
    font-weight: 400;
    font-style: normal
}

@font-face {
    font-family: ggFont;
    src: url(/fonts/ggFont_Italic.ttf) format("truetype");
    font-display: swap;
    font-weight: 400;
    font-style: italic
}

@font-face {
    font-family: ggFont;
    src: url(/fonts/ggFont_Bold.ttf) format("truetype");
    font-display: swap;
    font-weight: 700;
    font-style: normal
}

@font-face {
    font-family: ggFont;
    src: url(/fonts/ggFont_Bold_Italic.ttf) format("truetype");
    font-display: swap;
    font-weight: 700;
    font-style: italic
}

@font-face {
    font-family: ggFont;
    src: url(/fonts/ggFont_Black.ttf) format("truetype");
    font-display: swap;
    font-weight: 900;
    font-style: normal
}

@font-face {
    font-family: ggFont;
    src: url(/fonts/ggFont_Black_Italic.ttf) format("truetype");
    font-display: swap;
    font-weight: 900;
    font-style: italic
}

:root {
    color: white;
    text-align: center;
    --deafult-font: ggFont;
    /* The event logo, in one place. url() in a stylesheet resolves
       against the stylesheet, not the page — so it needs the leading
       slash, or it would look for public/css/img/. */
    --deafult-logo: url("/img/LOGO-TTP.png");
    --ds-color-brand-30: oklch(from #a685ff l c h);
    --ds-color-brand-50: oklch(from #7950e5 l c h);
    --ds-color-brand-70: oklch(from #4a2399 l c h);
    --ds-color-brand-90: oklch(from #351370 l c h);
    --ds-color-purple-10: oklch(from #d9d7f0 l c h);
    --ds-color-purple-20: oklch(from #bdb5ff l c h);
    --ds-color-purple-30: oklch(from #8f86e6 l c h);
    --ds-color-purple-70: oklch(from #5d51b6 l c h);
    --ds-color-purple-80: oklch(from #393273 l c h);
    --ds-color-purple-90: oklch(from #211a4c l c h);
    --ds-color-purple-100: oklch(from #171235 l c h);
    --ds-color-white-5: oklch(from #fff l c h / 5%);
    --ds-color-white-10: oklch(from #fff l c h / 10%);
    --ds-color-white-20: oklch(from #fff l c h / 20%);
    --ds-color-white-40: oklch(from #fff l c h / 40%);
    --ds-color-white-60: oklch(from #fff l c h / 60%);
    --ds-color-white-80: oklch(from #fff l c h / 80%);
    --ds-color-white-100: oklch(from #fff l c h);
    --ds-color-black-10: oklch(from #10101c l c h / 10%);
    --ds-color-black-20: oklch(from #10101c l c h / 20%);
    --ds-color-black-30: oklch(from #10101c l c h / 30%);
    --ds-color-black-40: oklch(from #10101c l c h / 40%);
    --ds-color-black-50: oklch(from #10101c l c h / 50%);
    --ds-color-black-60: oklch(from #10101c l c h / 60%);
    --ds-color-black-70: oklch(from #10101c l c h / 70%);
    --ds-color-black-80: oklch(from #10101c l c h / 80%);
    --ds-color-black-90: oklch(from #10101c l c h / 90%);
    --ds-color-black-100: oklch(from #10101c l c h);
    --ds-color-turquoise-20: oklch(from #7cffde l c h);
    --ds-color-turquoise-50: oklch(from #3ae8bd l c h);
    --ds-color-turquoise-70: oklch(from #0fb3a2 l c h);
    --ds-color-turquoise-80: oklch(from #0d7a7a l c h);
    --ds-color-blue-20: oklch(from #42c0ff l c h);
    --ds-color-blue-50: oklch(from #00a2fe l c h);
    --ds-color-blue-70: oklch(from #08f l c h);
    --ds-color-blue-80: oklch(from #0f5cad l c h);
    --ds-color-green-20: oklch(from #c9f75d l c h);
    --ds-color-green-50: oklch(from #97e851 l c h);
    --ds-color-green-70: oklch(from #68c045 l c h);
    --ds-color-green-80: oklch(from #479440 l c h);
    --ds-color-yellow-20: oklch(from #ffcf4a l c h);
    --ds-color-yellow-50: oklch(from #ffc628 l c h);
    --ds-color-yellow-70: oklch(from #ffae05 l c h);
    --ds-color-yellow-80: oklch(from #ffa00c l c h);
    --ds-color-orange-20: oklch(from #ffae53 l c h);
    --ds-color-orange-50: oklch(from #ffa43d l c h);
    --ds-color-orange-70: oklch(from #e9802b l c h);
    --ds-color-orange-80: oklch(from #d06429 l c h);
    --ds-color-red-20: oklch(from #f75c5f l c h);
    --ds-color-red-50: oklch(from #e94555 l c h);
    --ds-color-red-70: oklch(from #c9333a l c h);
    --ds-color-red-80: oklch(from #a52330 l c h);

    --text-shadow-blue-10: 0 .0728125rem 0 var(--ds-color-black-40),
        .036375rem .036375rem .1455625rem var(--ds-color-blue-50),
        0 -.0728125rem .1455625rem var(--ds-color-brand-50),
        -.0728125rem .1455625rem .1455625rem var(--ds-color-turquoise-50),
        0 .1091875rem .582375rem var(--ds-color-brand-50),
        0 0 0 var(--ds-color-purple-10),
        0 0 .43675rem rgba(161, 155, 217, .65),
        .0728125rem .0728125rem .2911875rem var(--ds-color-purple-20);
    --text-shadow-blue-50: 0 .25rem 0 var(--ds-color-black-50),
        .125rem .125rem .5rem var(--ds-color-blue-50),
        0 -.25rem .5rem var(--ds-color-brand-50),
        -.25rem .5rem .5rem var(--ds-color-turquoise-50),
        0 .375rem 2rem var(--ds-color-brand-50),
        0 0 0 var(--ds-color-purple-10),
        0 0 1.5rem rgba(161, 155, 217, .65),
        .25rem .25rem 1rem var(--ds-color-purple-20);
    --text-shadow-blue-80: 0 .25rem 0 var(--ds-color-black-50),
        .1755rem .1755rem .702rem var(--ds-color-blue-50),
        0 -.351rem 1.13rem var(--ds-color-brand-50),
        -.351rem .576875rem 1.25rem rgba(58, 232, 189, .7),
        0 .5265rem 3.75rem var(--ds-color-brand-50),
        0 0 1.875rem rgba(161, 155, 217, .65),
        .351rem .351rem 1.875rem var(--ds-color-purple-20);
    --text-shadow-blue-100: 0 0 1.25rem var(--ds-color-blue-50),
        0 0 .625rem var(--ds-color-blue-50),
        .3125rem .3125rem 3rem var(--ds-color-blue-50);

    --text-shadow-orange-10: 0 .045625rem 0 var(--ds-color-orange-80),
        .0228125rem .0228125rem .0913125rem var(--ds-color-red-50),
        0 -.045625rem .0913125rem var(--ds-color-orange-50),
        -.045625rem .0913125rem .0913125rem var(--ds-color-yellow-50),
        0 .0685rem .3651875rem var(--ds-color-red-50),
        0 0 0 var(--ds-color-red-50),
        0 0 .273875rem var(--ds-color-red-50),
        .045625rem .045625rem .182625rem var(--ds-color-yellow-50);
    --text-shadow-orange-50: 0 .25rem 0 var(--ds-color-orange-80),
        .125rem .125rem .5rem var(--ds-color-red-50),
        0 -.25rem .5rem var(--ds-color-orange-50),
        -.25rem .5rem .5rem var(--ds-color-yellow-50),
        0 .375rem 2rem var(--ds-color-red-50),
        0 0 0 var(--ds-color-red-50),
        0 0 1.5rem var(--ds-color-red-50),
        .25rem .25rem 1rem var(--ds-color-yellow-50);
    --text-shadow-orange-80: 0 .25rem 0 var(--ds-color-black-50),
        .1755rem .1755rem .702rem var(--ds-color-orange-80),
        0 -.351rem 1.13rem var(--ds-color-red-50),
        -.351rem .576875rem 1.25rem var(--ds-color-orange-50),
        0 .5265rem 3.75rem var(--ds-color-yellow-50),
        0 0 1.875rem var(--ds-color-red-50),
        .351rem .351rem 1.875rem var(--ds-color-yellow-50);

    --text-shadow-green-10: 0 .0625rem 0 var(--ds-color-black-60),
        .125rem .125rem .5rem var(--ds-color-green-80),
        0 -.125rem .25rem var(--ds-color-turquoise-50),
        -.125rem .125rem .25rem var(--ds-color-turquoise-50),
        0 .125rem 1rem var(--ds-color-green-50),
        .125rem .25rem .5rem var(--ds-color-green-50);
    --text-shadow-green-50: 0 .25rem 0 var(--ds-color-black-50),
        .125rem .125rem .5rem var(--ds-color-green-50),
        0 -.25rem .5rem var(--ds-color-green-50),
        -.25rem .5rem .5rem #77df9b,
        0 0.375rem 2rem var(--ds-color-green-50),
        0 0 0 var(--ds-color-green-50),
        0 0 1.5rem rgba(161, 155, 217, .65),
        .25rem .25rem 1rem var(--ds-color-green-50);

    --text-shadow-red-50: 0 .25rem 0 var(--ds-color-black-50),
        .125rem .125rem .5rem var(--ds-color-red-50),
        0 -.25rem .5rem var(--ds-color-red-50),
        -.25rem .5rem .5rem #b45862,
        0 0.375rem 2rem var(--ds-color-red-50),
        0 0 0 var(--ds-color-red-50),
        0 0 1.5rem rgba(161, 155, 217, .65),
        .25rem .25rem 1rem var(--ds-color-red-50);
    --text-shadow-red-100: 0 0 1.25rem var(--ds-color-red-50),
        0 0 .625rem var(--ds-color-red-50),
        .3125rem .3125rem 3rem var(--ds-color-red-50);

    --text-shadow-black-50: 0 .125rem .25rem rgba(0, 0, 0, .5);
    --text-shadow-white-80: 0 0 1.25rem var(--ds-color-purple-20),
        0 0 .625rem var(--ds-color-purple-20),
        .3125rem .3125rem 3rem var(--ds-color-purple-20);

    --box-shadow-glass: inset 0 .0625rem .625rem 0 hsla(0, 0%, 100%, .2),
        inset 0 .125rem 0 0 #fff,
        inset 0 -.125rem 0 0 var(--ds-color-white-20),
        inset .125rem 0 0 0 var(--ds-color-white-20),
        inset -.125rem 0 0 0 var(--ds-color-white-20);

    font-family: var(--deafult-font);

}

* {
    box-sizing: border-box;
}

body {
    overflow: hidden;
}

.header {
    display: flex;
    width: 100%;
    padding: 16px;
    padding-bottom: 0;
    justify-content: space-between;
    /* gap: 20px; */
    background: linear-gradient(in oklch, var(--ds-color-black-100) 10%, transparent);
}

.player-hud {
    margin-top: 24px;
    display: flex;
    width: 420px;
    flex-direction: column;
    align-items: flex-start;
}

.player-hud.player-right {
    align-items: flex-end;
}

.player-info {
    height: 100%;
    display: flex;
}

.player-info.player-right {
    flex-direction: row-reverse;
}

/* 🧍 Lobby avatars — character.js renders a canvas into each of these and
   sizes itself from the box, so they need real dimensions. Portrait, to
   match the framing of the character camera. */
#lobby {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    gap: 40px;
    /* anchor for the centre box below */
    position: relative;
}

/* Lifted out of the flex row so it overlays the two models instead of
   sitting between them — that's what lets the characters meet in the
   middle. Centred on #lobby, not on the flow. */
.lobby-center-box {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;

    &.lobby-top-center {
        top: 10vh;
        transform: translate(-50%, 0);
        width: 100%;
    }

    &.lobby-bottom-center {
        top: auto;
        bottom: 10vh;
        transform: translate(-50%, 0);
        width: 100%;
    }
}

.lobby-content {
    position: absolute;
    top: 0;
    left: 0;
    /* The individual `translate` property, not transform: translate().
       These items are scaled by the mount/unmount keyframes, and the
       individual properties apply in the order translate → rotate →
       scale → transform — so a centring `transform` sits *inside* the
       scale, and shrinking to .9 pulled the item 5% of its own size
       down-right instead of shrinking in place. As `translate` it wraps
       the scale instead, and the centre stays put. */
    translate: -50% -50%;
    animation: section-mount .5s ease;

    &.unmounting {
        animation: section-unmount .5s ease forwards;
    }
}

.lobby-non-rules {
    animation: section-mount .5s ease;

    &.unmounting {
        animation: section-unmount .5s ease forwards;
    }
}

/* Was resolving against the viewport (no positioned ancestor); the centre
   box is one now, so pin it to the screen explicitly to keep it put. */
.game-title {
    position: fixed;
    top: 50%;
    left: 50%;
    /* see .lobby-content — scaled by the same keyframes */
    translate: -50% -50%;
    text-align: center;
    line-height: .3;
    font-style: italic;

    h2 {
        font-weight: 700;
        font-size: 2.5rem;
        color: var(--ds-color-white-60);
    }

    h1 {
        font-weight: 900;
        font-size: 5rem;
        text-shadow: var(--text-shadow-white-80);
    }
}

.game-rules {
    position: fixed;
    top: 50%;
    left: 50%;
    /* see .lobby-content — scaled by the same keyframes */
    translate: -50% -50%;
    text-align: center;
    line-height: .3;
    font-style: italic;
    width: 50rem;

    h2 {
        font-weight: 700;
        font-size: 5rem;
        color: var(--ds-color-white-60);
    }

    h1 {
        font-weight: 900;
        font-size: 10rem;
        text-shadow: var(--text-shadow-white-80);
    }
}

.three-character {
    overflow: visible;
    height: 100%;
    flex: none;
    width: 60%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    transition: .5s cubic-bezier(0.645, 0.045, 0.355, 1);
    &.three-focus {
        transform: translateY(36vh) scale(2.4);
        margin: 0 8vh;
    }
}

.three-character canvas {
    display: block;
}

/* 🧍 Stand-in for a character that wouldn't build. Sits in the same box
   the canvas would have, and is contained rather than cropped so the
   whole figure reads at either size — the lobby box is tall, the cam
   corner is square.

   The artwork faces the way red stands, so blue is mirrored to turn it
   inward the same way BASE_YAW does for the real models. */
.character-fallback {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
    /* opacity keeps it reading as a placeholder rather than a real skin */
    opacity: .85;
    pointer-events: none;
}

.character-fallback.flipped {
    transform: scaleX(-1);
}

.player-cam {
    width: 280px;
    height: 180px;
    background-color: var(--ds-color-black-100);
    border: var(--ds-color-black-100) 4px solid;
    outline: var(--ds-color-blue-50) 4px solid;
    border-radius: 16px;
    /* the feed fills the frame, the avatar sits on top of it */
    position: relative;
    overflow: hidden;
    /* stays over the result section, which now layers above the header */
    z-index: 1;

    &.player-right {
        outline-color: var(--ds-color-red-50);
    }
}

/* vdo.ninja webcam, edge to edge behind everything else in the frame */
.cam-feed {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
    pointer-events: none;
}

/* 🧍 The player's 3D avatar, tucked in the lower corner of their cam.
   character.js sizes its canvas from this box. Blue bottom-left, red
   bottom-right, so they face inward like they do in the lobby. */
.cam-avatar {
    position: absolute;
    /* lifted off the frame edge so the rounded corner can't clip it */
    bottom: 0;
    left: -36%;
    width: 100%;
    height: 100%;
    z-index: 1;
    pointer-events: none;
}

.player-cam.player-right .cam-avatar {
    left: auto;
    right: -36%;
}

.cam-avatar canvas {
    display: block;
}

/* In the cam corner the stand-in is framed head-and-shoulders like the
   real model is, rather than shrunk to a whole tiny figure. */
.cam-avatar .character-fallback {
    object-fit: cover;
    object-position: top center;
}

.player-name {
    /* box-shadow: var(--box-shadow-glass); */
    font-size: 36px;
    font-weight: 700;
    text-transform: uppercase;
    border-radius: 8px;
    text-shadow: var(--text-shadow-blue-100);
    text-align: left;

    &.lobby-name {
        position: fixed;
        bottom: 20vh;
        text-align: center;
        align-items: center;
        font-size: 4rem;
        font-weight: 900;
    }
}

.player-name.player-right {
    text-align: right;
    text-shadow: var(--text-shadow-red-100);
}

.player-score {
    width: 120px;
    font-size: 7rem;
    font-weight: 900;
    text-shadow: var(--text-shadow-white-80);
    line-height: 1.4;
    border-radius: 8px;

    &.lobby-score {
        font-size: 12rem;
        align-self: center;
    }
}

.player-health {
    width: 100%;
    font-size: 36px;
    padding-top: 8px;
}

.player-health-bar {
    width: 100%;
    background: linear-gradient(to bottom, var(--ds-color-black-40) 0, var(--ds-color-black-20) 100%);
    height: 64px;
    border-radius: 12px;
    transform: skew(-15deg);
    display: flex;
    /* border: var(--ds-color-black-100) 4px solid; */
    padding: 4px;
    box-shadow: var(--box-shadow-glass);
}

.player-health-bar.player-right {
    transform: skew(15deg);
    justify-content: flex-end;
}

.player-health-number {
    transform: translateY(-54px);
    text-shadow: var(--text-shadow-black-50);
    font-weight: 900;
}

@property --health-top {
    syntax: "<color>";
    initial-value: oklch(from #97e851 l c h);
    inherits: false;
}

@property --health-bottom {
    syntax: "<color>";
    initial-value: oklch(from #68c045 l c h);
    inherits: false;
}

.player-health-remain {
    background: linear-gradient(to bottom, var(--health-top) 0%, var(--health-bottom) 100%);
    height: 100%;
    width: 100%;
    transition: .5s, --health-top .5s, --health-bottom .5s;
    border-radius: 8px;
    box-shadow: 0 2px 4px var(--ds-color-white-20) inset,
        0 -2px 4px var(--ds-color-black-20) inset;
}

.player-health-remain.yellow-health {
    --health-top: var(--ds-color-yellow-50);
    --health-bottom: var(--ds-color-yellow-70);
}

.player-health-remain.red-health {
    --health-top: var(--ds-color-red-50);
    --health-bottom: var(--ds-color-red-70);
}

.center-container {
    display: flex;
}

/* Any <img> wearing this takes its picture from --deafult-logo rather than
   its own src, so the logo lives at exactly one address. Still a real <img>,
   so width/height attributes and intrinsic aspect ratio keep working. */
.brand-logo {
    content: var(--deafult-logo);
}

.duel-logo-img {
    width: 160px;
    height: 160px;
}

.duel-logo-img img {
    width: 100%;
    --scale: 1;
    aspect-ratio: 1;
    position: relative;
    object-fit: contain;
    transform: scale(calc(1 * var(--scale)));
}

.center-area {
    animation: section-mount .5s ease;

    &.unmounting {
        animation: section-unmount .5s ease forwards;
    }
}

@keyframes section-mount {
    from {
        scale: 0.9;
        opacity: 0;
        /* filter: blur(10px);  */
    }

    to {
        scale: 1;
        opacity: 1;
    }
}

@keyframes section-unmount {
    from {
        scale: 1;
        opacity: 1;
    }

    to {
        scale: .9;
        opacity: 0;
        /* filter: blur(10px); */
    }
}

@keyframes footer-mount {
    from {
        opacity: 0;
        transform: translateY(100%);
    }

    to {
        opacity: 1;
    }
}

@keyframes footer-unmount {
    from {
        opacity: 1;
    }

    to {
        opacity: 0;
        transform: translateY(100%);
    }
}

#preview-section {
    position: absolute;
    top: 0;
    width: 100%;
    height: 100%;
    z-index: -1;
}

#gameplay-section {
    display: flex;
    width: 100%;
    height: 50vh;
    /* background-color: var(--ds-color-black-10); */
    margin-top: 4vh;
    padding: 0 16px;
    justify-content: space-between;
    gap: 16px;
    transition: .5s;

    &:has(> .guessed) {
        margin-top: -4vh;
        height: 66vh;

        .player-screen:not(.guessed) {
            outline-color: var(--ds-color-yellow-50);
            box-shadow: 0 0 48px var(--ds-color-yellow-50);
        }
    }
}

.player-screen {
    flex-grow: 1;
    transition: .5s;
    height: 100%;
    background-color: var(--ds-color-black-100);
    border: var(--ds-color-black-100) 4px solid;
    outline: var(--ds-color-blue-50) 4px solid;
    border-radius: 16px;

    &.player-right {
        outline-color: var(--ds-color-red-50);
    }

    &.guessed {
        flex-grow: 0.3;
    }

    &#casters-screen {
        outline: none;
        border-color: var(--ds-color-black-100);
        border-radius: 0;
    }

    overflow: hidden;
}

.player-screen>iframe {
    width: 100%;
    height: 100%;
}

.player-screen>.guess-map {
    width: 100%;
    height: 100%;
    position: relative;
    top: calc(-1 * (100% + 4px));
}

.footer {
    position: absolute;
    bottom: 0;
    padding: 16px 0;
    top: auto;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    animation: footer-mount .5s ease;
    background: linear-gradient(to top in oklch, var(--ds-color-black-100) 10%, transparent);
    transition: .5s cubic-bezier(0.68, -0.55, 0.265, 1.55);

    &:has(.guess-first) {
        padding: 0;
    }

    &.unmounting {
        animation: footer-unmount .5s ease forwards;
    }
}

.footer-flex {
    /* background: linear-gradient(in oklch to right, color-mix(in srgb, var(--ds-color-blue-20) 50%, transparent 50%) 0,
            color-mix(in srgb, var(--ds-color-red-20) 50%, transparent 50%) 100%); */
    display: flex;
    justify-content: center;
    align-items: center;
    width: 50%;
    border-radius: 24px;
    padding: 4px 0;
    /* box-shadow: var(--box-shadow-glass); */
    z-index: 2;
    transition: .5s cubic-bezier(0.68, -0.55, 0.265, 1.55);

}

.footer-content {
    flex: 1;
    line-height: 1.2;
    transition: .5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}

.footer-gmode {
    flex: 1.8;
}

.foot-top {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--ds-color-white-60);
    transition: .5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}

.foot-bottom {
    font-size: 3.5rem;
    font-weight: 900;
    font-style: italic;
    text-shadow: var(--text-shadow-white-80);
    transition: .5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}

.footer:has(.guess-first)>.footer-flex {
    width: 30%;

    .foot-top {
        font-size: 0;
    }

    .footer-content.footer-hidable {
        flex: 0;

        .foot-bottom {
            font-size: 0;
        }
    }
}

.footer-left>.foot-bottom {
    text-shadow: var(--text-shadow-blue-100);
}

.footer-right>.foot-bottom {
    text-shadow: var(--text-shadow-red-100);
}

.footer-locked-in {
    font-size: 0;
    font-weight: 900;
    font-style: italic;
    /* background: var(--ds-color-green-50); */
    padding: 12px 48px;
    border-radius: 24px;
    /* margin: 0 -36px; */
    text-shadow: var(--text-shadow-blue-100);
    transition: .5s cubic-bezier(0.68, -0.55, 0.265, 1.55);

    &#red-guessed {
        text-shadow: var(--text-shadow-red-100);
    }
}

.footer-locked-in.guess-first {
    font-size: 3.5rem !important;
}

.timer-container {
    width: 100%;
    font-size: 5rem;
    font-weight: 900;
    font-variant-numeric: tabular-nums;
    display: flex;
    justify-content: center;
    z-index: 100;
}

.timer {
    --timer-hight: 80px;
    --timer-width: 200px;
    --timer-border-radius: 50vh;
    width: var(--timer-width);
    height: var(--timer-hight);
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    top: 0;
    z-index: 100;
    text-shadow: 0 0 48px var(--ds-color-white-100);
    transform: translateY(0) scale(1);
    transition: .5s cubic-bezier(0.77, 0, 0.175, 1), --bg-bottom .5s, --bg-top .5s;
    animation: section-mount .5s ease;

    &.unmounting {
        animation: section-unmount .5s ease forwards;
    }
}

.timer.timer-starting {
    transform: translateY(32vh) scale(2);
}

.timer.guessed-time {
    color: var(--ds-color-yellow-50);
    text-shadow: 0 0 48px var(--ds-color-yellow-50);
    font-size: 10rem;
}

gmp-advanced-marker {
    z-index: 10000 !important;
}

gmp-advanced-marker.gm-marker-top {
    z-index: 10001 !important;
}

.gm-marker {
    width: 0;
    height: 0;
    position: relative;
    background-color: var(--ds-color-blue-50);
    box-shadow: var(--ds-color-black-50) 2px 0px 4px;
    filter: drop-shadow(.1875rem .0625rem .0625rem rgba(0, 0, 0, .4));
}

.gm-marker.polite-pin {
    transform: scale(0);
    animation: polite-pin-show .4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards .4s;
}

.gm-marker-red {
    background-color: var(--ds-color-red-50);
}

.ulser-marker {
    background-image: url("/img/Thumbnails\ \(18\).png");
    background-size: cover;
    width: 128px;
    height: 128px;
}

.gm-marker svg {
    width: 3.75rem;
    height: 3.75rem;
    position: absolute;
    bottom: 0;
    transform: translateX(-50%);
}

.gm-marker-red svg>path:nth-child(3) {
    fill: rgb(233, 69, 85);
}

.gm-marker-circle,
.gm-marker-result {
    border: var(--ds-color-white-100) .1875rem solid;
    border-radius: 60px;
    box-shadow: 0 0.375rem 0.625rem rgb(26 26 26/10%);
    transform: translate(-50%, 50%);
    width: 2rem;
    height: 2rem;
    position: absolute;
    bottom: 0;
}

.gm-marker-result {
    background: url("/img/correct-location.webp") var(--ds-color-black-100);
    background-size: cover;
    transform: translate(-50%, 50%) scale(0);
    animation: result-show .4s cubic-bezier(0.34, 1.56, 0.64, 1) .4s forwards;
}

@keyframes result-show {
    from {
        transform: translate(-50%, 50%) scale(0);
    }

    to {
        transform: translate(-50%, 50%) scale(1);
    }
}

@keyframes polite-pin-show {
    from {
        transform: scale(0);
    }

    to {
        transform: scale(1);
    }
}


#map {
    width: 100%;
    height: 100%;
    animation: section-mount .5s ease;
}

/* Score overlay */
#game-result {
    height: 81.1vh;
    position: absolute;
    top: 17.3vh;
    width: 100%;
    padding: 0 16px;
    border-radius: 16px;
    /* over the header, not under it, so the damage number lands on top of
       the HP bar instead of flying in behind it */
    z-index: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    row-gap: 12px;
}

.scoreboard {
    display: flex;
    gap: 10px;
    padding: 10px 10px;
    /* holds its 8rem; the map below takes the squeeze */
    flex: none;
    color: white;
    font-size: 6rem;
    font-style: italic;
    font-weight: 900;
    z-index: 10;
    height: 8rem;
}

/* Between the two scores, nudged level with them: the distance labels push
   the scores below the middle of the board (--score-dy is measured by
   alignScoreboard). The scores' z-index carries them over it. */
.score-center {
    align-self: center;
    /* translate: 0 var(--score-dy, 0px); */
    width: 8rem;
    margin: 0 2rem;
}

#game-result #map {
    width: 100%;
    height: 100%;
    border-radius: 16px;
}

.player,
.mult {
    text-align: center;
    display: flex;
    flex-direction: column;
    /* background: var(--ds-color-black-20);
    box-shadow: var(--box-shadow-glass); */
    border-radius: 10px;
    color: var(--ds-color-white-100);
    justify-content: center;
    /* transition: background .5s; */
}

.mult {
    transition: font-size .5s ease-in-out, opacity .5s ease-in-out;
    width: 140px;
    text-shadow: var(--text-shadow-blue-100);
    &.red {
        text-shadow: var(--text-shadow-red-100);
    }
    opacity: 0;
    font-size: 1rem;
    &.mult-grow {
        transition: font-size .5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
        font-size: 4rem;
        opacity: 1;
    }
}

small {
    font-size: 24px;
    font-weight: 400;
}

/* Score and ghost share one grid cell, so the ghost sits exactly behind
   the score whatever the font size or line height */
.scoreBox {
    display: grid;
    font-variant-numeric: tabular-nums;
    width: 5ch;

    &>* {
        grid-area: 1 / 1;
    }
}

/* Each side hugs the centre icon. The score shrinks to its digits rather
   than filling the column, so the measured slide and hit are aimed at the
   number itself. */
.player.blue {
    text-align: right;

    & .scoreBox {
        justify-items: end;
    }
}

.player.red {
    text-align: left;

    & .scoreBox {
        justify-items: start;
    }
}

@property --x-pos {
    syntax: "<length>";
    initial-value: 0px;
    inherits: false;
}

@property --y-pos {
    syntax: "<length>";
    initial-value: 0px;
    inherits: false;
}

@property --scale {
    syntax: "<number>";
    initial-value: 1;
    inherits: false;
}

.score {
    position: relative;
    top: 0;
    opacity: 1;
    display: inline-block;
    transform-origin: center;
    transform: translate(var(--x-pos), var(--y-pos)) scale(var(--scale));
    text-shadow: var(--text-shadow-blue-10);
    /* over its ghost, which comes later in the markup */
    z-index: 1;
}

.ghostScore {
    color: var(--ds-color-white-40);
    opacity: 0;
}

.damage {
    /* color: var(--ds-color-red-70); */
    /* straight across onto the loser's score, no dip */
    transition: text-shadow .2s, --x-pos .5s cubic-bezier(0.6, 0, 0.36, -1);
    /* text-shadow: var(--text-shadow-orange-10); */
    z-index: 2;
}

/* the winner lands on the loser's score and bursts: grows as it fades */
.damage-pop {
    transition: opacity .3s ease-out, --scale .3s ease-out;
    opacity: 0;
    --scale: 1.5;
}

.damage-take {
    /* color: var(--ds-color-red-70); */
    animation: damageTake .5s;
    text-shadow: var(--text-shadow-orange-10);
    &#redScore {
        animation: damageTake2 .5s;
    }
}

/* Added by flyDamage() once the number is final; must come after
   .damage-take so this animation wins */
.damage-fly {
    animation: takeDamage .6s cubic-bezier(0.7, -0.28, 0.535, 0.045) forwards !important;
}

/* --slide-x is the measured distance from blue's score to red's (aimSlide),
   so the winner lands exactly on the loser's score */
#blueScore.damage {
    --x-pos: var(--slide-x);
}

#redScore.damage {
    --x-pos: calc(-1 * var(--slide-x));
}

.score-tie {
    transition: --x-pos .5s cubic-bezier(0.6, 0, 0.36, -1), opacity .3s ease-out, --scale .3s ease-out;

    /* both meet halfway */
    &#blueScore {
        --x-pos: calc(var(--slide-x) / 2);
    }

    &#redScore {
        --x-pos: calc(var(--slide-x) / -2);
    }
}

.ghost-show {
    animation: ghostShow .5s ease-in-out 0s forwards;
}

.ghost-show-after {
    animation: ghostShow .5s ease-in-out 2s forwards;
}

/* --hit-x / --hit-y are measured by flyDamage(): from the number to the
   middle of its own HP bar. It just travels there, then fades into it. */
@keyframes takeDamage {
    0% {
        --x-pos: 0;
        --y-pos: 0;
        opacity: 1;
    }

    50% {
        --x-pos: var(--hit-x);
        --y-pos: var(--hit-y);
        opacity: 1;
        animation-timing-function: ease-out;
    }

    100% {
        --x-pos: var(--hit-x);
        --y-pos: var(--hit-y);
        opacity: 0;
        --scale: 1.5;
    }
}

@keyframes ghostShow {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

@keyframes damageTake {
    0% {
        --x-pos: 0;
        animation-timing-function: cubic-bezier(0, 0.55, 0.45, 1);
    }

    33% {
        --x-pos: calc(-0.1 * var(--slide-x));
        animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1);
    }

    100% {
        --x-pos: 0;
    }
}

@keyframes damageTake2 {
    0% {
        --x-pos: 0;
        animation-timing-function: cubic-bezier(0, 0.55, 0.45, 1);
    }

    33% {
        --x-pos: calc(0.1 * var(--slide-x));
        animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1);
    }

    100% {
        --x-pos: 0;
    }
}

.animation-5k {
    --easeOutBack: cubic-bezier(0.34, 1.56, 0.64, 1);
    --megaAggresiveEaseOut: cubic-bezier(0, 0.88, 0.04, 1);
    --ultraAggresiveEaseOut: cubic-bezier(0, 1.02, 0, 0.99);
    position: fixed;
    inset: 0;
    z-index: 1000;
    isolation: isolate;
    pointer-events: none;
    animation: __5k-celebration_fadeOut__lsyoQ 1s var(--easeOutBack) forwards 2s
}

.__5k-celebration_nonBgContent__uiAOW,
.animation-5k {
    display: flex;
    justify-content: center;
    align-items: center;
    will-change: opacity, transform
}

.__5k-celebration_nonBgContent__uiAOW {
    width: 100%;
    height: 100%;
    animation: __5k-celebration_zoomOut__lFKhA .4s var(--easeOutBack) forwards 2s
}

.__5k-celebration_fiveKImage__QChZb,
.__5k-celebration_tenKImage__ylVOO {
    width: 50%;
    height: auto;
    transform: scale(0);
    animation: __5k-celebration_glitterZoomIn__U6pf_ 3s var(--ultraAggresiveEaseOut) forwards;
    will-change: opacity, transform
}

.__5k-celebration_tenKImage__ylVOO {
    width: 40%
}

.__5k-celebration_splashItem__vEJtt {
    position: absolute
}

.__5k-celebration_splashItem__vEJtt img {
    width: 100%;
    height: auto
}

.__5k-celebration_bgImage__c2j1y {
    position: absolute;
    inset: 0;
    opacity: 0;
    width: 100%;
    height: 100%;
    z-index: -3;
    animation: __5k-celebration_backgroundZoomIn__C__Ha 5s var(--megaAggresiveEaseOut) forwards 0s;
    will-change: opacity, transform
}

.__5k-celebration_animationWrapper__e1zZI {
    transform: scale(0);
    animation: __5k-celebration_glitterZoomIn__U6pf_ 3s var(--megaAggresiveEaseOut) forwards;
    will-change: opacity, transform
}

@keyframes __5k-celebration_backgroundZoomIn__C__Ha {
    0% {
        opacity: 0;
        transform: scale(1.5)
    }

    to {
        opacity: .8;
        transform: scale(1)
    }
}

@keyframes __5k-celebration_glitterZoomIn__U6pf_ {
    0% {
        transform: scale(0)
    }

    to {
        transform: scale(1)
    }
}

@keyframes __5k-celebration_zoomOut__lFKhA {
    0% {
        transform: scale(1);
        opacity: 1
    }

    to {
        transform: scale(.8);
        opacity: 0
    }
}

@keyframes __5k-celebration_fadeOut__lsyoQ {
    0% {
        opacity: 1
    }

    to {
        opacity: 0
    }
}

@keyframes __5k-celebration_popIn__FRBc5 {
    0% {
        opacity: 0;
        transform: scale(.5)
    }

    to {
        opacity: 1;
        transform: scale(1)
    }
}

.transition-door {
    --doorCloseEase: cubic-bezier(0.22, 1, 0.36, 1);
    --doorOpenEase: cubic-bezier(0.5, 0, 0.75, 0);
    --doorCloseMs: 300ms;
    --doorOpenMs: 500ms;
    position: absolute;
    inset: 0;
    overflow: hidden;
    z-index: 9999;
}

.doors-cover_half {
    position: absolute;
    inset: 0 -10%;
    width: 120%;
    height: 100%;
}

.doors-cover_leftHalf {
    --doorRestingX: -100%;
}

.doors-cover_rightHalf {
    --doorRestingX: 100%;
}

.doors-cover_svg__S_kmT {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}

.doors-cover_rightFill {
    fill: var(--ds-color-purple-100);
}

.transition-door .doors-cover_half {
    animation: doors-cover_doorsClose var(--doorCloseMs) var(--doorCloseEase) forwards;
}

.transition-door.doors-cover_isOpening .doors-cover_half {
    animation: doors-cover_doorsOpen var(--doorOpenMs) var(--doorOpenEase) forwards;
}


@keyframes doors-cover_doorsClose {
    from {
        transform: translateX(var(--doorRestingX));
        opacity: 0
    }

    to {
        transform: translateX(0);
        opacity: 1
    }
}

@keyframes doors-cover_doorsOpen {
    from {
        transform: translateX(0);
        opacity: 1
    }

    to {
        transform: translateX(var(--doorRestingX));
        opacity: 0
    }
}

.doors-settings_root__L_lsw {
    --chipsDirection: row;
    --chipsGap: 1.6svh;
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    margin-top: 20svh;
    z-index: 0;
    display: flex;
    flex-direction: var(--chipsDirection);
    align-items: center;
    justify-content: center;
    gap: var(--chipsGap);
    padding: 0 6svw
}

.content-front-door {
    z-index: 10000;
    position: absolute;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    animation: low-backdrop-brightness .5s forwards;
    
    > * {
        animation: section-mount .5s;
    }
}

@keyframes low-backdrop-brightness {
    to {
        backdrop-filter: brightness(0.5);
    }
}