/* 
Tic Tac Bow
P01 browser game
Version 0.9 - mobile layout and sound pass
Craig
*/

body {
    font-family: "Montserrat", Arial, Helvetica, sans-serif;
    background-color: #111827;
    color: #ffffff;
    margin: 0;
}

/* 
Page layout
The page behaves like a small browser game rather than a scrolling website.
The game is centered and clipped to the visible viewport.
*/
.game-page {
    height: 100dvh;
    width: 100%;
    padding: 0;
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: flex-start;
}

/* Centers the game stage horizontally inside the page. */
.game-shell {
    width: 100%;
    display: flex;
    justify-content: center;
}

/* 
Game stage
The stage keeps the original 631 x 1172 artwork ratio.
The width uses the smaller value between full viewport width and available viewport height,
so the full game fits on mobile without stretching.
*/
.game-stage {
    position: relative;
    /* 631 / 1172 matches the source artwork dimensions. */
    width: min(100vw, calc(100dvh * 631 / 1172));
    aspect-ratio: 631 / 1172;
    overflow: hidden;
    background-color: #000000;
    border: none;
    /* Prevents browser scrolling/gestures from interrupting drag-to-aim gameplay. */
    touch-action: none;

    /* 
    Game movement values.
    JavaScript updates --carriage-speed as the match gets faster.
    */
    --carriage-speed: 3.4s;
    --carriage-up: -14px;
    --carriage-down: 88px;
    --carriage-hidden: 360px;

    --rope-gap-min: 14px;
    --rope-gap-max: 116px;
    --rope-gap-hidden: 360px;
}

/* 
Gameplay playfield
All gameplay layers sit inside this fixed coordinate space.
This keeps CSS layers and JavaScript hit detection aligned.
*/
.game-playfield {
    position: absolute;
    z-index: 1;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
}

/* 
Shared full-canvas image rules.
Every art layer sits in the same coordinate space so the tower, ropes, masks, and targets line up.
*/
.winter-bg,
.scene-layer {
    position: absolute;
    display: block;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    user-select: none;
    pointer-events: none;
}

.winter-bg {
    z-index: 0;
    object-fit: cover;
}

.bg-posts {
    z-index: 1;
}

/* 
Rope gap filler
This repeats a small rope texture downward so the upper ropes stay visually connected
when the target carriage lowers behind the tower.
*/
.rope-gap-strip {
    position: absolute;
    z-index: 2;
    width: 100%;
    height: var(--rope-gap-min);
    left: 0;
    top: 9.6%;
    background-image: url("../images/scene/rope-gap-strip.png");
    background-repeat: repeat-y;
    background-size: 100% auto;
    overflow: hidden;
    pointer-events: none;
}

/* 
Moving target carriage
The target board, hit zones, ownership overlays, and stuck bolt markers move together as one group.
*/
.target-carriage {
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    z-index: 3;

    transform: translateY(0);
}
.target-carriage.is-moving {
    animation: target-carriage-move var(--carriage-speed) ease-in-out infinite alternate;
}

.carriage-ropes {
    z-index: 2;
}
/* 
Gameplay interaction layers
These empty layers are filled by JavaScript during play.
They share the same size as the art so markers and hit zones line up with the targets.
*/
.hit-zone-layer,
.stuck-arrow-layer {
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
}

.hit-zone-layer {
    z-index: 3;
}

/* 
Ownership overlay layer
JavaScript adds large X/O markers here to show which player currently controls each target.
*/
.owner-overlay-layer {
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    z-index: 4;
    pointer-events: none;
}

.target-owner-marker {
    position: absolute;
    width: 19%;
    aspect-ratio: 1 / 1;
    border-radius: 50%;
    transform: translate(-50%, -50%);
    display: grid;
    place-items: center;
    font-size: 4rem;
    font-weight: bold;
    line-height: 1;
    opacity: 0;
    text-shadow: 0 3px 6px #000000;
    transition: opacity 0.2s ease;
    pointer-events: none;
}

.target-owner-marker.is-owned {
    opacity: 0.3;
}

.target-owner-marker.player-x {
    color: #b6ff3b;
}

.target-owner-marker.player-o {
    color: #d06bff;
}

.game-stage.is-aiming .target-owner-marker {
    opacity: 0;
}

.target-hit-zone {
    position: absolute;
    border-radius: 50%;
    transform: translate(-50%, -50%);
    pointer-events: none;
}

.stuck-arrow-layer {
    z-index: 5;
}

/*
Foreground Masks
These layers sit on top of the moving target carriage to create depth.
They are static visual elements with no interactivity.
*/
.fg-pulley-beam {
    z-index: 5;
}

.fg-stone-base {
    z-index: 6;
}

/* 
Crossbow layer
The crossbow is positioned near the bottom of the playfield.
JavaScript rotates it slightly while the player aims.
*/
.crossbow-layer {
    position: absolute;
    z-index: 11;
    width: 305px;
    left: 50%;
    bottom: -64px;
    transform: translateX(-50%) rotate(var(--crossbow-rotation, 0deg));
    transform-origin: 50% 82%;
    pointer-events: none;
    opacity: 0;
    transition: transform 120ms ease-out, opacity 150ms ease;
}

.game-stage.is-playing .crossbow-layer {
    opacity: 1;
}

.crossbow-image {
    display: block;
    width: 100%;
    height: auto;
    user-select: none;
    pointer-events: none;
}

.loaded-bolt {
    position: absolute;
    z-index: 5;
    width: 34px;
    height: auto;
    left: 50%;
    top: -22%;
    transform: translateX(-50%);
    pointer-events: none;
    user-select: none;
}

.crossbow-layer.is-firing .loaded-bolt {
    opacity: 0;
}

.crossbow-layer.is-recoiling {
    transform: translateX(-50%) translateY(8px) rotate(var(--crossbow-rotation, 0deg)) scale(0.98);
}

.flying-bolt {
    position: absolute;
    z-index: 12;
    width: 34px;
    height: auto;
    left: 0;
    top: 0;
    transform-origin: 50% 8%;
    pointer-events: none;
    user-select: none;
}

.stuck-bolt {
    position: absolute;
    z-index: 12;
    width: 30px;
    height: auto;
    left: 0;
    top: 0;
    transform: translate(-50%, -50%);
    pointer-events: none;
    user-select: none;
}

.projectile-layer {
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    z-index: 12;
    pointer-events: none;
}

/* 
Aim guide
This line sits inside the crossbow layer so it rotates with the weapon instead of floating separately.
*/
.aim-line {
    position: absolute;
    z-index: 1;
    height: 5px;
    width: 0;
    left: 50%;
    top: -8%;
    background-image: linear-gradient(
        to right,
        rgba(255, 45, 45, 0.75) 0%,
        rgba(255, 45, 45, 0.55) 35%,
        rgba(255, 45, 45, 0.22) 75%,
        rgba(255, 45, 45, 0) 100%
    );
    filter: drop-shadow(0 0 6px rgba(255, 50, 50, 0.65));
    transform: translateY(-50%) rotate(-90deg);
    transform-origin: left center;
    pointer-events: none;
    opacity: 0;
    border-radius: 999px;
}

.aim-line::after {
    content: "";
    display: none;
}

.aim-line.is-visible {
    opacity: 1;
}

/*
Animated Scene Elements
Visual details like the spinning wheel that are part of the scene
but have their own animations separate from the main target carriage.
*/
.wheel-spin {
    position: absolute;
    z-index: 7;
    display: block;
    width: 45px;
    height: auto;
    left: 49.8%;
    top: 2px;
    transform: translateX(-50%);
    transform-origin: center;
    user-select: none;
    pointer-events: none;
    animation: wheel-spin var(--carriage-speed) ease-in-out infinite alternate;
    animation-play-state: paused;
}

.game-stage.is-playing .wheel-spin {
    animation-play-state: running;
}

/* 
Score display
Scores are positioned over the side banners to make them feel part of the game artwork.
*/
.score {
    position: absolute;
    z-index: 9;
    width: 40px;
    font-weight: bold;
    text-align: center;
    line-height: 1;
    text-shadow: 0 2px 4px #000000;
}

.score-x {
    left: 8.4%;
    top: 25%;
    transform: translateX(-50%);
    color: #b6ff3b;
}

.score-o {
    left: 91.6%;
    top: 25%;
    transform: translateX(-50%);
    color: #d06bff;
}

.score-tallies {
    display: block;
    font-size: 1.8rem;
}

/*
General UI Elements
Base styles for interactive elements like buttons, which are then
specialized for different parts of the UI (start menu, HUD).
*/
button {
    cursor: pointer;
    padding: 8px 12px;
    border: 2px solid #ffffff;
    background-color: #222222;
    color: #ffffff;
    font: inherit;
}

button:hover,
button:focus {
    background-color: #444444;
}

/* 
Start menu overlay
The menu appears inside the game frame so the player never leaves the game screen.
*/
.start-menu {
    position: absolute;
    z-index: 30;
    inset: 0;
    display: grid;
    place-items: center;
    padding: 24px;
    background-color: rgba(0, 0, 0, 0.68);
}

.start-menu.is-hidden {
    display: none;
}

.start-panel {
    display: grid;
    gap: 12px;
    width: min(84%, 300px);
    padding: 22px;
    border: 3px solid #d8b35a;
    border-radius: 4px;
    background:
        linear-gradient(
            180deg,
            rgba(31, 41, 51, 0.96),
            rgba(15, 23, 32, 0.96)
        );
    box-shadow:
        0 0 0 2px rgba(0, 0, 0, 0.85),
        0 10px 28px rgba(0, 0, 0, 0.75),
        inset 0 0 18px rgba(216, 179, 90, 0.12);
    text-align: center;
}

/* 
Decorative title font
Uncial Antiqua is used only for the title/HUD so the main UI text stays readable.
*/
.start-panel h1 {
    margin: 0 0 8px;
    font-family: "Uncial Antiqua", Georgia, "Times New Roman", serif;
    font-size: 2.3rem;
    font-weight: 400;
    color: #f8e7a2;
    letter-spacing: 0.06em;
    text-shadow:
        0 3px 6px #000000,
        0 0 10px rgba(216, 179, 90, 0.55);
}

.start-panel label {
    display: grid;
    gap: 4px;
    text-align: left;
    font-size: 0.9rem;
}

.start-panel select,
.start-panel button,
.hud-reset {
    padding: 8px 10px;
    border: 2px solid #d8b35a;
    border-radius: 2px;
    background-color: #0f1720;
    color: #f8e7a2;
    font: inherit;
    box-shadow:
        inset 0 0 8px rgba(216, 179, 90, 0.12),
        0 3px 8px rgba(0, 0, 0, 0.55);
}

.start-panel select,
.start-panel button {
    width: 100%;
    max-width: 100%;
    min-width: 0;
}

.hud-reset {
    width: auto;
}

.start-panel button:hover,
.start-panel button:focus,
.hud-reset:hover,
.hud-reset:focus {
    background-color: #1f2933;
    color: #ffffff;
}

.aim-help {
    display: grid;
    gap: 3px;
    justify-items: center;
    padding: 8px;
    border: 1px solid rgba(216, 179, 90, 0.65);
    background-color: rgba(0, 0, 0, 0.35);
    color: #d9e7ec;
    font-size: 0.72rem;
    line-height: 1.35;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    box-shadow: inset 0 0 10px rgba(143, 183, 201, 0.12);
}

.aim-help p {
    margin: 0;
}

.aim-help-arrow {
    font-size: 2rem;
    line-height: 1;
}

.keyboard-hint {
    display: grid;
    gap: 3px;
    justify-items: center;
    margin-top: 4px;
}

.key-row {
    display: flex;
    gap: 4px;
    justify-content: center;
}

.key {
    display: inline-grid;
    place-items: center;
    width: 20px;
    height: 18px;
    border: 1px solid rgba(216, 179, 90, 0.8);
    border-radius: 3px;
    background-color: rgba(15, 23, 32, 0.9);
    color: #f8e7a2;
    font-size: 0.7rem;
    line-height: 1;
}

.keyboard-hint p {
    margin-top: 2px;
    font-size: 0.65rem;
}

/* 
In-frame gameplay message
Short feedback messages appear over the playfield without affecting layout.
*/
.hud-message {
    position: absolute;
    z-index: 25;
    left: 50%;
    top: 12%;
    width: 90%;
    transform: translateX(-50%);
    margin: 0;
    text-align: center;
    font-family: "Uncial Antiqua", Georgia, "Times New Roman", serif;
    font-size: clamp(2rem, 9vw, 2.8rem);
    font-weight: 400;
    line-height: 1;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: #f2efe4;
    -webkit-text-stroke: 1px #d8b35a;
    text-stroke: 1px #d8b35a;
    text-shadow:
    0 3px 8px #000000,
    0 0 10px rgba(0, 0, 0, 0.9);
    pointer-events: none;
    white-space: nowrap;
}

/* 
Menu button
This stays inside the game frame so the player can return to the start menu at any time.
*/
.hud-reset {
    position: absolute;
    z-index: 26;
    right: 10px;
    top: 10px;
    font-size: 0.75rem;
}

/* 
Pulley wheel animation
The wheel spins while the target carriage is moving to support the elevator illusion.
*/
@keyframes wheel-spin {
    from {
        transform: translateX(-50%) rotate(0deg);
    }

    to {
        transform: translateX(-50%) rotate(260deg);
    }
}

/* 
Target carriage animation
The board moves up and down to make aiming timing-based instead of static.
*/
@keyframes target-carriage-move {
    from {
        transform: translateY(var(--carriage-up));
    }

    to {
        transform: translateY(var(--carriage-down));
    }
}
.game-stage.is-playing .rope-gap-strip {
    animation: rope-gap-grow var(--carriage-speed) ease-in-out infinite alternate;
}

.game-stage.is-round-resetting .rope-gap-strip {
    animation: none;
}

@keyframes rope-gap-grow {
    from {
        height: var(--rope-gap-min);
    }

    to {
        height: var(--rope-gap-max);
    }
}

/* 
Desktop cap
37.5em = 600px. Larger screens keep the game centered instead of stretching the artwork.
*/
@media (min-width: 37.5em) {
    .game-stage {
        width: min(100vw, 430px);
        margin: 0 auto;
    }
}

/* 
Small-screen menu adjustments
Only the menu gets tighter here; the gameplay stage keeps the same artwork ratio.
*/
@media (max-width: 30em) {
    .start-menu {
        padding: 8px;
    }
    .start-panel {
        width: min(90%, 320px);
        max-height: calc(100% - 16px);
        padding: 14px;
        gap: 8px;
    }

    .start-panel h1 {
        margin-bottom: 2px;
        font-size: 1.85rem;
        line-height: 1;
        letter-spacing: 0.04em;
    }

    .start-panel label {
        gap: 3px;
        font-size: 0.8rem;
    }

    .start-panel select,
    .start-panel button {
        padding: 6px 8px;
        font-size: 0.9rem;
    }

    .aim-help {
    padding: 6px;
    font-size: 0.62rem;
    letter-spacing: 0.055em;
    }

    .key {
        width: 18px;
        height: 16px;
        font-size: 0.65rem;
    }

    .keyboard-hint p {
        font-size: 0.58rem;
    }

    .aim-help-arrow {
        font-size: 1.35rem;
    }
}