/* Ancient Duel — directional-input UI (gamepad, TV remote, keyboard).
 *
 * Shared by the web app, the Windows/Steam build, the macOS build and the
 * Smart TV browsers. Gated on classes that assets/js/gamepad.js sets:
 *
 *   html.ad-nav-on    directional input is driving (pad OR remote/keyboard)
 *   html.ad-gp-on     a gamepad is connected and enabled
 *   html.ad-tv-mode   TV readability (detected, or forced in settings)
 *   html.ad-input-mouse   the player went back to the mouse
 *
 * Mouse and touch players see none of it, so this costs the existing UI
 * nothing. Written for old TV browsers too: no rule mixes :focus with
 * :focus-visible (an unknown selector in a list drops the WHOLE rule on
 * Tizen 2.x / webOS 3), and every min()/max()/gap has a plain fallback
 * declared before it.
 */

/* ------------------------------------------------------------------ */
/*  Focus ring                                                         */
/* ------------------------------------------------------------------ */

/* With no cursor on screen, the focused element IS the cursor — it has to be
   unmistakable at couch distance, hence the double ring plus glow rather than
   a hairline outline. Kept as its own rule: see the :focus-visible note above.
   
   The outline is !important because the app deliberately kills outlines on its
   own buttons (`body:not(.page-game) .ancient-btn:focus-visible { outline:
   none }` and the board's equivalent) to keep the mouse UI clean — those
   selectors are more specific than anything sane to write here, and without
   the override a controller or remote player gets NO visible selection at all.
   Only the outline is forced; the buttons keep their own shading. */
.ad-nav-on :focus {
    outline: 3px solid #f3d68b !important;
    outline-offset: 2px !important;
    box-shadow: 0 0 0 5px rgba(20, 12, 5, .75), 0 0 18px 4px rgba(243, 214, 139, .55);
    border-radius: 6px;
    scroll-margin: 24px;
}
.ad-nav-on :focus-visible {
    outline: 3px solid #f3d68b !important;
    outline-offset: 2px !important;
    box-shadow: 0 0 0 5px rgba(20, 12, 5, .75), 0 0 18px 4px rgba(243, 214, 139, .55);
}

/* Round controls keep their shape. The rule above gives the ring a 6px radius
   so it reads on the app's rectangular buttons, and that squared off every
   circular close button the moment the selection reached it — most visibly on
   the card preview in the deck builder. Only actual circles belong here: the
   account badge is a rectangle and was briefly given a round ring. */
.ad-nav-on .btn-close:focus,
.ad-nav-on .gm-close:focus,
.ad-nav-on .cpo-close:focus,
.ad-nav-on .db-card-detail-panel-float:focus {
    border-radius: 50%;
}

/* A field opened for editing: the ring turns solid so it is obvious the arrows
   now belong to the field and are no longer moving the selection. */
.ad-nav-on .ad-field-editing {
    outline: 3px solid #8fae7a !important;
    outline-offset: 2px !important;
    box-shadow: 0 0 0 5px rgba(20, 12, 5, .8), 0 0 20px 5px rgba(143, 174, 122, .5);
}
.ad-tv-mode.ad-nav-on .ad-field-editing { outline-width: 5px !important; }

/* Back on the mouse: drop the ring immediately, no reload, no mode lock. */
.ad-input-mouse :focus { outline: none !important; box-shadow: none; }

/* Cards carry their own frame art, so the ring hugs the card shape instead of
   painting a rectangle over the artwork. */
.ad-nav-on .card:focus,
.ad-nav-on .slot:focus,
.ad-nav-on .choice-card:focus,
.ad-nav-on .fp-card:focus,
.ad-nav-on .discard-option:focus,
.ad-nav-on .response-trap:focus,
.ad-nav-on .board-pile:focus,
.ad-nav-on .terrain-slot:focus {
    outline-offset: 4px;
    border-radius: 10px;
}

/* Raising the focused element is only needed where elements overlap, and
   `position` is the wrong tool everywhere else on this board — twice over.
   The piles and terrain slots are laid out `position: absolute`, so `relative`
   here drops them back into the flow (the graveyard and the terrain both slid
   left across the deck). And several of these own an absolutely positioned
   ::after: the slot's band is offset `left/right: -12%` against the row on
   purpose, so positioning the slot would re-resolve those percentages against
   the slot and snap the decoration narrower on focus. */
.ad-nav-on .board-pile:focus,
.ad-nav-on .terrain-slot:focus {
    z-index: 40;
}

/* The hand is the one place the ring could not simply be drawn around the card.
   Measured on a real board, an outside ring came out at full strength on the
   top and right edges and at roughly 60% on the left and bottom, where it is
   clipped against the neighbouring card in the fan; and the outer cards of the
   fan dip below the fold by design (the board is fixed and the body cannot
   scroll), so the bottom of the ring fell outside the viewport entirely.

   Drawing it just inside the card's own edge solves both: nothing can clip a
   ring that never leaves the card, and the lift clears the bottom of the
   screen. Straightening the card out of the fan while it is focused is what
   the app already does on hover, so it reads as the same gesture.

   Numbers from tests/e2e/full-match.e2e.mjs, peak ring brightness per side
   (243 is the ring's own colour):
       before   left 150   right 243   top 243   bottom 191
       after    left 221   right 216   top 221   bottom 220  */
.ad-nav-on .player-hand .card:focus {
    position: relative;
    z-index: 40;
    transform: translateY(-20px);
    transition: transform .08s linear;
    outline-offset: -4px !important;
}

.ad-nav-on .ancient-btn:focus,
.ad-nav-on .gm-btn:focus,
.ad-nav-on .cpo-action-btn:focus {
    filter: brightness(1.12);
}

/* ------------------------------------------------------------------ */
/*  Button hint bar                                                    */
/* ------------------------------------------------------------------ */

.ad-gp-hints {
    position: fixed;
    left: 50%;
    bottom: 10px;
    bottom: max(10px, env(safe-area-inset-bottom));
    transform: translateX(-50%);
    z-index: 9500;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    max-width: 60rem;
    max-width: min(96vw, 60rem);
    padding: .4rem .8rem;
    border-radius: 999px;
    border: 1px solid rgba(231, 199, 111, .45);
    background: linear-gradient(180deg, rgba(40, 29, 13, .92), rgba(24, 17, 8, .92));
    box-shadow: 0 4px 18px rgba(0, 0, 0, .5);
    /* A reminder, not a control: it says what the four keys do and is read once.
       Kept faint so it stops competing with the board it sits over. */
    opacity: .3;
    pointer-events: none;      /* purely informational — never eats a click */
    user-select: none;
}
.ad-gp-hints[hidden] { display: none; }

/* Centred, it sits under the middle of whatever is on screen. There is room in
   a corner on anything desktop-sized, so it moves out of the way there and only
   takes the middle when the screen is too narrow for a corner to be out of the
   way at all. */
@media (min-width: 768px) {
    .ad-gp-hints {
        left: 12px;
        transform: none;
    }
}

.ad-gp-hint {
    display: inline-flex;
    align-items: center;
    /* margin, not gap: flex gap is Chrome 84+, well past the TV browsers. */
    margin: .18rem .45rem;
    font-size: .8rem;
    line-height: 1;
    color: #f0e2bb;
    letter-spacing: .04em;
    white-space: nowrap;
}
.ad-gp-hint b {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.5rem;
    height: 1.5rem;
    margin-right: .35rem;
    padding: 0 .35rem;
    border-radius: 999px;
    border: 1px solid rgba(231, 199, 111, .7);
    background: rgba(231, 199, 111, .16);
    color: #f3d68b;
    font-family: 'Cinzel', serif;
    font-size: .72rem;
    font-weight: 700;
}

/* The board is dense; keep the bar out of the player's hand area. */
.page-game .ad-gp-hints { bottom: 4px; bottom: max(4px, env(safe-area-inset-bottom)); }

/* ------------------------------------------------------------------ */
/*  A screen nobody is using                                           */
/* ------------------------------------------------------------------ */

/* Dimmed, not covered: the game is still there and still running, and the
   first press of anything takes this away. It never receives a press itself —
   whatever is underneath has to stay clickable for a player who reaches for a
   mouse instead. */
.ad-idle-dim {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 9600;
    pointer-events: none;
    background: rgba(0, 0, 0, .55);
    transition: opacity .4s ease;
}

/* ------------------------------------------------------------------ */
/*  Leaving the game                                                   */
/* ------------------------------------------------------------------ */

/* Only ever raised where Back closes the application. The native build has its
   own papyrus dialog for this and keeps it; this is the fallback for a shell
   that ships without one, so it is deliberately plain. */
.ad-exit-ask {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 9750;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    background: rgba(8, 6, 4, .82);
}

.ad-exit-box {
    max-width: 24rem;
    padding: 1.5rem 1.7rem;
    text-align: center;
    border: 1px solid rgba(231, 199, 111, .45);
    border-radius: 14px;
    background: linear-gradient(180deg, rgba(40, 29, 13, .96), rgba(24, 17, 8, .96));
    box-shadow: 0 10px 40px rgba(0, 0, 0, .6);
    color: #f0e2bb;
}

.ad-exit-title {
    margin: 0 0 1rem;
    font-size: 1.15rem;
    letter-spacing: .04em;
}

.ad-exit-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
}

.ad-exit-btn {
    margin: .25rem;
    min-width: 8rem;
    min-height: 2.6rem;
    padding: .5rem 1rem;
    border: 1px solid rgba(231, 199, 111, .4);
    border-radius: 10px;
    background: rgba(255, 255, 255, .08);
    color: #f0e2bb;
    font-size: .95rem;
    cursor: pointer;
}

.ad-exit-btn:hover { background: rgba(255, 255, 255, .18); }

.ad-exit-leave {
    border-color: rgba(168, 90, 82, .7);
    background: rgba(139, 58, 50, .45);
}

/* ------------------------------------------------------------------ */
/*  Title-safe margin (overscan)                                       */
/* ------------------------------------------------------------------ */

/* A television crops the edges of the picture. Older sets lose as much as 5%
   on every side and say nothing about it — the surrender button and the piles
   are simply not on screen. Consoles answer this by keeping everything inside
   a title-safe box.
   
   The board is scaled rather than inset: its sizes are derived from the
   viewport (slot heights in vh, the 3D perspective in vh), so cropping the
   container would leave the pieces at their old size inside a smaller box.
   A uniform scale keeps every proportion the layout was built on, and the
   background stays full-bleed behind it — the band it leaves is exactly the
   part a TV was going to cut anyway. */
.ad-safe-area {
    --ad-safe: 4%;
    --ad-safe-scale: 0.92;   /* 1 - 2 x 4% */
}

.ad-safe-area .game-board {
    transform: scale(0.92);
    transform: scale(var(--ad-safe-scale));
    transform-origin: center center;
}

/* Pages that scroll keep their content off the edge instead, since there is
   nothing full-bleed to scale. */
.ad-safe-area body:not(.page-game) {
    padding-left: 4%;
    padding-left: var(--ad-safe);
    padding-right: 4%;
    padding-right: var(--ad-safe);
    box-sizing: border-box;
}

.ad-safe-area .ad-gp-hints {
    bottom: 4%;
    bottom: max(var(--ad-safe), env(safe-area-inset-bottom));
}

@media (min-width: 768px) {
    .ad-safe-area .ad-gp-hints { left: 4%; left: var(--ad-safe); }
}

/* ------------------------------------------------------------------ */
/*  On-screen keyboard                                                 */
/* ------------------------------------------------------------------ */

/* Only ever raised for a source that has no letters on it, so it is never in a
   keyboard player's way. The keys are ordinary buttons and the ring that lands
   on them is the same one used everywhere else. */
.ad-osk {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 9700;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background: rgba(8, 6, 4, .7);
}

/* The sheet itself comes from the shared papyrus block in styles.css, which
   this box is listed in — three-slice art on its own pseudo-elements. Only the
   room to breathe is set here, in the same terms the other sheets use: a
   percentage top and bottom to clear the torn caps, 2em at the sides. */
.ad-osk-box {
    width: 100%;
    max-width: 44rem;
    padding: 6% 2em 5%;
    color: #2b1d0e;
}

.ad-osk-title {
    font-size: .82rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: #4a3214;
    margin-bottom: .35rem;
}

/* What has been typed so far, spelled out: on a television the field itself is
   often behind this panel and too small to read from the sofa. */
.ad-osk-preview {
    min-height: 2rem;
    margin-bottom: .7rem;
    padding: .4rem .6rem;
    border-radius: 8px;
    border: 1px solid rgba(74, 50, 20, .35);
    background: rgba(255, 255, 255, .3);
    color: #2b1d0e;
    font-size: 1.15rem;
    line-height: 1.4;
    word-break: break-word;
}

.ad-osk-row {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
}

.ad-osk-key {
    /* margin, not gap: flex gap is Chrome 84+, past the older TV browsers. */
    margin: 3px;
    min-width: 2.6rem;
    min-height: 2.6rem;
    padding: .3rem .5rem;
    border: 1px solid rgba(74, 50, 20, .35);
    border-radius: 8px;
    background: rgba(255, 255, 255, .32);
    color: #2b1d0e;
    font-size: 1.05rem;
    line-height: 1;
    cursor: pointer;
}

.ad-osk-key:hover { background: rgba(255, 255, 255, .55); }

.ad-osk-wide { min-width: 5rem; font-size: .85rem; }
.ad-osk-space { min-width: 12rem; font-size: .85rem; }

.ad-osk-done {
    border-color: rgba(63, 122, 56, .55);
    background: rgba(126, 168, 106, .38);
}

/* Bigger targets and bigger type at viewing distance, same as the rest of TV
   mode. */
.ad-tv-mode .ad-osk-key {
    min-width: 3.4rem;
    min-height: 3.4rem;
    font-size: 1.3rem;
}

.ad-tv-mode .ad-osk-wide { min-width: 6.5rem; }
.ad-tv-mode .ad-osk-space { min-width: 15rem; }
.ad-tv-mode .ad-osk-preview { font-size: 1.5rem; }

/* ------------------------------------------------------------------ */
/*  Controller lost                                                    */
/* ------------------------------------------------------------------ */

/* Not gated on .ad-nav-on: it appears precisely because the device that was
   driving the navigation has gone, and it has to be visible whatever state the
   page was left in. */
.ad-pad-lost {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 9800;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    background: rgba(8, 6, 4, .82);
}

.ad-pad-lost-box {
    max-width: 26rem;
    padding: 1.6rem 1.8rem;
    text-align: center;
    border: 1px solid rgba(231, 199, 111, .45);
    border-radius: 14px;
    background: linear-gradient(180deg, rgba(40, 29, 13, .96), rgba(24, 17, 8, .96));
    box-shadow: 0 10px 40px rgba(0, 0, 0, .6);
    color: #f0e2bb;
}

.ad-pad-lost-glyph {
    font-size: 2rem;
    line-height: 1;
    margin-bottom: .6rem;
    color: #e7c76f;
}

.ad-pad-lost-title {
    margin: 0 0 .5rem;
    font-size: 1.15rem;
    letter-spacing: .04em;
}

.ad-pad-lost-hint {
    margin: 0;
    font-size: .9rem;
    opacity: .82;
}

/* ------------------------------------------------------------------ */
/*  TV mode — viewing distance, not a redesign                         */
/* ------------------------------------------------------------------ */

/* A TV player sits metres away, so the ring gets thicker and the small print
   grows. Nothing here changes layout, colours or the game's identity. */
.ad-tv-mode.ad-nav-on :focus,
.ad-tv-mode.ad-nav-on :focus-visible {
    outline-width: 5px !important;
    outline-offset: 3px !important;
    box-shadow: 0 0 0 7px rgba(20, 12, 5, .8), 0 0 26px 8px rgba(243, 214, 139, .65);
}

.ad-tv-mode .ad-gp-hint { font-size: 1rem; }
.ad-tv-mode .ad-gp-hint b { min-width: 2rem; height: 2rem; font-size: .9rem; }

/* Dialogs and the action menu carry the words a TV player must read. */
.ad-tv-mode .gm-btn,
.ad-tv-mode .cpo-action-btn { font-size: 1.05rem; padding: .6rem 1.1rem; }
.ad-tv-mode .gm-title { font-size: 1.35rem; }
.ad-tv-mode .gm-cd-effect { font-size: 1.05em; line-height: 1.45; }
.ad-tv-mode .log-entry { font-size: .95rem; }

/* Card preview: the one screen that must be readable from the sofa. */
.ad-tv-mode .cpo-stage { width: 92vw; width: min(520px, 92vw); }
.ad-tv-mode .cpo-card-host { font-size: 17px; }

.ad-tv-mode .gp-box { width: 36rem; width: min(36rem, 100%); }
.ad-tv-mode .gp-row label,
.ad-tv-mode .gp-row select,
.ad-tv-mode .gp-map dl { font-size: 1rem; }

/* ------------------------------------------------------------------ */
/*  Settings panel                                                     */
/* ------------------------------------------------------------------ */

.gp-overlay {
    position: fixed;
    inset: 0;
    top: 0; right: 0; bottom: 0; left: 0;   /* inset shorthand is newer */
    z-index: 9600;
    display: none;                 /* gamepad.js flips this to flex */
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background: rgba(10, 7, 3, .78);
}

.gp-box {
    position: relative;
    width: 30rem;
    width: min(30rem, 100%);
    max-height: 86vh;
    overflow-y: auto;
    padding: 1.1rem 1.2rem 1.3rem;
    border-radius: 12px;
    border: 1px solid rgba(231, 199, 111, .5);
    background: linear-gradient(180deg, rgba(58, 42, 18, .97), rgba(32, 23, 11, .97));
    box-shadow: 0 10px 40px rgba(0, 0, 0, .6);
    color: #f0e2bb;
}

.gp-title {
    margin: 0 0 .2rem;
    font-family: 'Cinzel', serif;
    font-size: 1.15rem;
    font-weight: 700;
    color: #e7c76f;
    text-align: center;
}

.gp-sub {
    margin: 0 0 1rem;
    font-size: .82rem;
    line-height: 1.4;
    text-align: center;
    color: #cbb98f;
}

.gp-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: .55rem 0;
    border-top: 1px solid rgba(231, 199, 111, .18);
}
.gp-row:first-of-type { border-top: 0; }

.gp-row label { font-size: .9rem; margin-right: .8rem; }
.gp-row .gp-note { display: block; font-size: .74rem; color: #b7a67c; margin-top: .1rem; }

.gp-row select,
.gp-row input[type="range"] {
    flex: 0 0 11rem;
    max-width: 11rem;
}

.gp-row select {
    padding: .3rem .5rem;
    border-radius: 6px;
    border: 1px solid rgba(231, 199, 111, .5);
    background: rgba(24, 17, 8, .9);
    color: #f0e2bb;
    font-size: .85rem;
}

.gp-row input[type="checkbox"] {
    width: 1.15rem;
    height: 1.15rem;
    accent-color: #c8a068;
}

.gp-deadzone-value {
    flex: 0 0 3rem;
    margin-left: .5rem;
    text-align: right;
    font-size: .85rem;
    color: #e7c76f;
}

.gp-map {
    margin-top: .9rem;
    padding-top: .7rem;
    border-top: 1px solid rgba(231, 199, 111, .18);
}
.gp-map h4 {
    margin: 0 0 .45rem;
    font-family: 'Cinzel', serif;
    font-size: .82rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: #cbb98f;
}
.gp-map dl {
    display: grid;
    grid-template-columns: 5.5rem 1fr;
    grid-gap: .3rem .7rem;
    margin: 0;
    font-size: .82rem;
}
.gp-map dt { color: #e7c76f; font-weight: 700; }
.gp-map dd { margin: 0; color: #d9c9a1; }

.gp-close {
    position: absolute;
    top: .4rem;
    right: .55rem;
    width: 2rem;
    height: 2rem;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: #e7c76f;
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
}
.gp-close:hover { color: #fff; }

/* ------------------------------------------------------------------ */
/*  Debug readout (opt-in: ?input-debug=1)                             */
/* ------------------------------------------------------------------ */

.ad-input-debug {
    position: fixed;
    top: 8px;
    left: 8px;
    z-index: 9700;
    padding: .4rem .6rem;
    border-radius: 6px;
    border: 1px solid rgba(231, 199, 111, .5);
    background: rgba(10, 7, 3, .88);
    color: #f0e2bb;
    font-family: monospace;
    font-size: 11px;
    line-height: 1.5;
    pointer-events: none;
    white-space: nowrap;
}

@media (max-width: 480px) {
    .gp-row { flex-direction: column; align-items: stretch; }
    .gp-row label { margin-right: 0; margin-bottom: .3rem; }
    .gp-row select, .gp-row input[type="range"] { flex: 1 1 auto; max-width: none; }
    .gp-map dl { grid-template-columns: 4.5rem 1fr; }
}
