/* ==========================================================================
   One Stroke — Single Line Drawing Puzzle Game
   Stylesheet
   ========================================================================== */

:root {
    --bg-1:           #1b2a4a;
    --bg-2:           #2d4373;
    --board:          #f4ead5;
    --board-shadow:   rgba(0, 0, 0, 0.25);
    --line-pending:   #c8b99c;
    --line-drawn:     #ff7849;
    --line-active:    #ffb648;
    --node:           #2c3e63;
    --node-active:    #ff7849;
    --node-done:      #5fb86b;
    --text:           #ffffff;
    --accent:         #ffb648;
    --danger:         #ff5470;
}

* {
    box-sizing: border-box;
    -webkit-tap-highlight-color: transparent;
}

html, body {
    margin: 0;
    padding: 0;
    height: 100%;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    background: linear-gradient(160deg, var(--bg-1), var(--bg-2));
    color: var(--text);
    overflow: hidden;
    user-select: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    -webkit-touch-callout: none;
    overscroll-behavior: none;
    /* Kills pinch-zoom and double-tap-to-zoom. The scrollable panels below
       opt back into vertical panning. */
    touch-action: none;
}

/* Panels that legitimately scroll need their gesture back. */
.level-grid,
.overlay-card { touch-action: pan-y; }

/* ==========================================================================
   Layout
   ========================================================================== */

#app {
    display: flex;
    flex-direction: column;
    height: 100vh;    /* fallback for very old browsers */
    height: 100svh;   /* smallest viewport - stable; never resizes with the URL bar */
    /* KRITRIM_JIGGLE: the dynamic-viewport override was removed here. It tracked the
       mobile URL bar, so the shell resized mid-draw and scaleNodes() repositioned
       every node under the finger. */
    max-width: 720px;
    margin: 0 auto;
    position: relative;
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
}

.topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: max(14px, env(safe-area-inset-top)) 18px 12px;
    flex-shrink: 0;
}

.title { text-align: center; }
.level-label {
    font-size: 10px;
    letter-spacing: 2.5px;
    opacity: 0.55;
}
.level-name {
    font-size: 17px;
    font-weight: 800;
    line-height: 1.1;
    margin-top: 3px;
    letter-spacing: 0.5px;
    text-transform: uppercase;
}

.top-actions {
    display: flex;
    align-items: center;
    gap: 10px;
}

.stage {
    flex: 1 1 auto;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 8px 14px;
    min-height: 0;
    min-width: 0;
}

#board {
    width: 100%;
    height: 100%;
    background: var(--board);
    border-radius: 24px;
    box-shadow: 0 14px 40px var(--board-shadow);
    touch-action: none;
    cursor: pointer;
}

.bottombar {
    padding: 10px 22px max(16px, env(safe-area-inset-bottom));
    display: flex;
    align-items: center;
    gap: 14px;
    flex-shrink: 0;
}

/* ==========================================================================
   Buttons
   ========================================================================== */

.icon-btn {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: none;
    background: rgba(255, 255, 255, 0.08);
    color: var(--text);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background 0.15s, transform 0.1s;
}
.icon-btn:hover  { background: rgba(255, 255, 255, 0.16); }
.icon-btn:active { transform: scale(0.94); }
.icon-btn svg    { width: 22px; height: 22px; }

.preview-btn {
    background: rgba(95, 184, 107, 0.2);
    color: var(--node-done);
}
.preview-btn:hover    { background: rgba(95, 184, 107, 0.32); }
.preview-btn:disabled { opacity: 0.4; cursor: not-allowed; }

.primary-btn {
    background: var(--accent);
    color: #1b2a4a;
    border: none;
    font-weight: 700;
    font-size: 16px;
    padding: 14px 32px;
    border-radius: 999px;
    cursor: pointer;
    transition: transform 0.1s, box-shadow 0.15s;
    box-shadow: 0 6px 16px rgba(255, 182, 72, 0.35);
}
.primary-btn:hover  { box-shadow: 0 8px 22px rgba(255, 182, 72, 0.5); }
.primary-btn:active { transform: scale(0.96); }

.ghost-btn {
    background: transparent;
    color: var(--text);
    border: 1px solid rgba(255, 255, 255, 0.25);
    padding: 10px 24px;
    border-radius: 999px;
    cursor: pointer;
    margin-top: 18px;
    font-size: 13px;
}
.ghost-btn:hover { background: rgba(255, 255, 255, 0.06); }

/* ==========================================================================
   Hint, preview banner, HUD
   ========================================================================== */

.hint {
    position: absolute;
    bottom: 18px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 12px;
    color: rgba(0, 0, 0, 0.45);
    background: rgba(244, 234, 213, 0.85);
    padding: 6px 14px;
    border-radius: 999px;
    white-space: nowrap;
    pointer-events: none;
    transition: opacity 0.4s;
}
.hint.fade { opacity: 0; }

.preview-banner {
    position: absolute;
    top: 14px;
    left: 50%;
    transform: translateX(-50%);
    background: rgba(15, 22, 40, 0.85);
    color: #fff;
    padding: 8px 16px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    z-index: 6;
    display: flex;
    align-items: center;
    gap: 12px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
    animation: popUp 0.25s ease;
}
.preview-banner.hidden { display: none; }
.preview-track {
    width: 80px;
    height: 4px;
    background: rgba(255, 255, 255, 0.15);
    border-radius: 999px;
    overflow: hidden;
}
.preview-bar {
    height: 100%;
    width: 0%;
    background: var(--node-done);
    border-radius: 999px;
}

.progress-track {
    flex: 1;
    height: 8px;
    background: rgba(255, 255, 255, 0.12);
    border-radius: 999px;
    overflow: hidden;
}
.progress-fill {
    height: 100%;
    width: 0%;
    background: linear-gradient(90deg, var(--accent), var(--line-drawn));
    border-radius: 999px;
    transition: width 0.25s ease;
}
.counter {
    font-size: 12px;
    opacity: 0.75;
    min-width: 60px;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   Overlays — win, menu
   ========================================================================== */

.overlay {
    position: absolute;
    inset: 0;
    background: rgba(15, 22, 40, 0.72);
    backdrop-filter: blur(6px);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 10;
    animation: fadeIn 0.25s ease;
}
.overlay.hidden { display: none; }

.overlay-card {
    background: linear-gradient(160deg, #2c3e63, #1b2a4a);
    border-radius: 20px;
    padding: 32px 28px;
    text-align: center;
    width: min(360px, 88%);
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.4);
    animation: pop 0.35s cubic-bezier(.2, 1.4, .4, 1);
}
.overlay-card h2 { margin: 0 0 8px; font-size: 26px; }
.overlay-card p  { margin: 0 0 22px; opacity: 0.7; font-size: 14px; }

.confetti {
    font-size: 44px;
    color: var(--accent);
    margin-bottom: 8px;
    animation: spin 1.4s ease-in-out infinite;
    display: inline-block;
}

/* The win card carries a 300x250 banner, so it needs more usable inner width
   than the default card (which only has to fit text). Compound selector so the
   responsive .overlay-card rules further down cannot override the padding. */
.overlay-card.win-card {
    width: min(372px, calc(100vw - 16px));
    padding: 26px 18px 24px;
    max-height: 100%;
    overflow-y: auto;
}

/* ==========================================================================
   Ad slot — Adsterra 300x250, between levels
   ========================================================================== */

.ad-slot {
    width: 300px;
    height: 250px;
    margin: 4px auto 22px;   /* 22px keeps the banner clear of Next Level so a
                                celebratory tap cannot land on the ad */
    border-radius: 10px;
    overflow: hidden;
    background: rgba(255, 255, 255, 0.05);
    display: flex;
    justify-content: center;
}
.ad-slot iframe { display: block; border: 0; }

/* Collapsed when the banner does not fill (no-fill, blocker, offline) so the
   card never opens with a 250px hole in it. Toggled from game.js. */
.ad-slot.empty { display: none; }

/* Under ~355px the card's padded content box is narrower than the 300px
   banner. Let the slot break out of the card padding to the card's full width
   rather than scaling or clipping it — a partially visible ad is a policy
   problem, and scaling left the iframe cropped at the bottom. */
@media (max-width: 355px) {
    .ad-slot {
        width: auto;
        margin-left: -18px;
        margin-right: -18px;
    }
}

.menu-card { width: min(420px, 92%); }
.level-grid {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 10px;
    margin-top: 8px;
    max-height: 50vh;
    overflow-y: auto;
    padding: 4px;
}
.level-cell {
    aspect-ratio: 1;
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.08);
    border: none;
    color: var(--text);
    font-weight: 700;
    font-size: 16px;
    cursor: pointer;
    transition: background 0.15s, transform 0.1s;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
}
.level-cell:hover  { background: rgba(255, 255, 255, 0.16); }
.level-cell:active { transform: scale(0.94); }
.level-cell.done {
    background: var(--node-done);
    color: #fff;
}
.level-cell.current {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}
.level-cell.locked {
    background: rgba(0, 0, 0, 0.22);
    color: rgba(255, 255, 255, 0.35);
    cursor: not-allowed;
}
.level-cell.locked:hover  { background: rgba(0, 0, 0, 0.22); }
.level-cell.locked:active { transform: none; }
.level-cell .lock-icon { width: 18px; height: 18px; opacity: 0.55; }

/* ==========================================================================
   Animations
   ========================================================================== */

@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes pop {
    0%   { transform: scale(0.7); opacity: 0; }
    100% { transform: scale(1);   opacity: 1; }
}
@keyframes spin {
    0%, 100% { transform: rotate(-12deg) scale(1); }
    50%      { transform: rotate( 12deg) scale(1.15); }
}
@keyframes popUp {
    0%   { transform: translateX(-50%) translateY(-6px); opacity: 0; }
    100% { transform: translateX(-50%) translateY(0);    opacity: 1; }
}

/* ==========================================================================
   Responsive — phones, tablets, desktops, landscape
   ========================================================================== */

@media (max-width: 360px) {
    .topbar      { padding-top: max(10px, env(safe-area-inset-top)); padding-left: 12px; padding-right: 12px; }
    .top-actions { gap: 6px; }
    .icon-btn    { width: 38px; height: 38px; }
    .icon-btn svg { width: 18px; height: 18px; }
    .level-name  { font-size: 14px; }
    .level-label { font-size: 9px; letter-spacing: 2px; }
    .bottombar   { padding-left: 14px; padding-right: 14px; gap: 10px; }
    .hint        { font-size: 10px; padding: 5px 10px; }
    .counter     { font-size: 11px; min-width: 50px; }
}

@media (max-width: 480px) {
    .level-name      { font-size: 15px; }
    .overlay-card    { padding: 26px 22px; }
    .overlay-card h2 { font-size: 22px; }
    .hint            { font-size: 11px; }
}

@media (orientation: landscape) and (max-height: 500px) {
    .topbar          { padding-top: max(6px, env(safe-area-inset-top)); padding-bottom: 6px; }
    .level-label     { font-size: 9px; }
    .level-name      { font-size: 13px; margin-top: 1px; }
    .icon-btn        { width: 36px; height: 36px; }
    .icon-btn svg    { width: 18px; height: 18px; }
    .stage           { padding: 4px 10px; }
    .bottombar       { padding-top: 6px; padding-bottom: max(8px, env(safe-area-inset-bottom)); }
    .hint            { display: none; }
    #board           { border-radius: 18px; }
    .overlay-card    { padding: 20px 24px; }
    .overlay-card h2 { font-size: 20px; margin-bottom: 4px; }
    .overlay-card p  { margin-bottom: 14px; }
    .confetti        { font-size: 32px; margin-bottom: 2px; }

    /* Landscape is too short to stack a 250px banner under the text, so put it
       beside the text instead of dropping it. Card becomes ~278px tall, which
       still fits a ~300px stage on a landscape phone. */
    .overlay-card.win-card {
        width: min(680px, calc(100vw - 20px));
        /* 10px keeps 250px of ad + padding under the ~275px stage height on a
           667x375 landscape phone; 14px overflowed it by 3px. */
        padding: 10px 16px;
        display: grid;
        grid-template-columns: 1fr 300px;
        grid-template-rows: repeat(4, auto);
        column-gap: 18px;
        /* align-content keeps the four text rows at their natural heights and
           centres the group; without it they stretch to fill the 250px ad and
           push the button out of the card. */
        align-content: center;
        align-items: center;
        text-align: left;
    }
    .win-card .confetti    { grid-column: 1; grid-row: 1; font-size: 26px; margin: 0; }
    .win-card h2           { grid-column: 1; grid-row: 2; }
    .win-card #winSubtitle { grid-column: 1; grid-row: 3; }
    .win-card #nextBtn     { grid-column: 1; grid-row: 4; justify-self: start; }
    .ad-slot               { grid-column: 2; grid-row: 1 / -1; margin: 0; align-self: center; }
}

/* Below ~360px of height even the side-by-side card will not fit — this is the
   one case where the banner has to go. */
@media (orientation: landscape) and (max-height: 360px) {
    .overlay-card.win-card {
        grid-template-columns: 1fr;
        width: min(372px, calc(100vw - 16px));
        text-align: center;
    }
    .win-card #nextBtn { justify-self: center; }
    .ad-slot           { display: none; }
}

@media (min-width: 600px) {
    #app          { max-width: 640px; }
    .topbar       { padding-top: max(18px, env(safe-area-inset-top)); padding-left: 22px; padding-right: 22px; }
    .level-name   { font-size: 18px; }
    .icon-btn     { width: 46px; height: 46px; }
    .icon-btn svg { width: 24px; height: 24px; }
    .bottombar    { padding-left: 26px; padding-right: 26px; }
}

@media (min-width: 1024px) {
    #app        { max-width: 680px; }
    .level-name { font-size: 19px; }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
    .confetti { animation: none; }
}

@media (hover: none) {
    .icon-btn:hover    { background: rgba(255, 255, 255, 0.08); }
    .preview-btn:hover { background: rgba(95, 184, 107, 0.2); }
}

/* ---- KRITRIM: scrollable SEO content + extra ad units below the game ---- */
html { height: auto !important; overflow-x: hidden !important; overflow-y: auto !important; touch-action: pan-y !important; }
body { height: auto !important; min-height: 100%; overflow-x: hidden !important; overflow-y: visible !important; touch-action: pan-y !important; }
/* the About text/ads area explicitly allows vertical touch panning to scroll */
.about, .side-rail { touch-action: pan-y; }
/* the game shell fills the first screen; the About content scrolls in below it.
   #board keeps touch-action:none so drawing still works; you scroll by dragging
   on the header, the margins around the board, or anywhere in the content below. */
#app { height: 100svh; }   /* KRITRIM_JIGGLE: dynamic-viewport override removed */
.about { max-width: 750px; margin: 0 auto; padding: 22px 18px 52px; line-height: 1.65; font-size: 16px; }
.about h2 { font-size: 1.5rem; margin: .2em 0 .45em; color: #fff; }
.about h3 { font-size: 1.15rem; margin: 1.3em 0 .45em; color: #ffb488; }
.about p  { margin: .4em 0 1.1em; color: #c7d1e6; }
/* Content ad slots SIZE TO THEIR AD (no fixed 300x250 square, no grey box, no
   clipping) so a 728x90 banner shows as a banner and a 300x250 box as a box —
   fixes the "square blank space around a long banner" problem. */
.about .ad-slot {
  width: auto; height: auto; max-width: 100%;
  margin: 24px auto; padding: 0;
  background: transparent; overflow: visible;
  display: flex; justify-content: center; align-items: center;
}
.about .ad-slot iframe { max-width: 100%; display: block; }
.side-rail { position: fixed; top: 50%; transform: translateY(-50%); z-index: 40; }
#ad-rail-left { left: 10px; } #ad-rail-right { right: 10px; }
@media (max-width: 1099px) { .side-rail { display: none; } }
@media (max-width: 767px)  { .ad-box2-wrap { display: none; } }

/* KRITRIM_OVERLAY_VIEWPORT
   The between-level card was unusable at two of three sizes: "Next Level" was scrolled
   out of sight and the 300px banner was squeezed to 256.

   Cause: .overlay is position:absolute inside main.stage, so inset:0 meant the BOARD, not
   the screen. main.stage measured 307x430 on a 1440x900 desktop, so the card inherited a
   430px ceiling from `max-height:100%` while its content needs 536 - it then scrolled
   internally with `overflow-y:auto` and hid the primary button. The same 307px width
   crushed the 300x250 unit. Tablet only escaped because its stage happened to be big
   enough. Making the overlay viewport-sized gives the card the full screen to measure
   against, so max-height:100% and width:min(372px, 100vw - 16px) mean what they say.
   z-index clears the old side-rail layer (40) as well as the topbar. */
.overlay { position: fixed; z-index: 50; }
